1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
#include "sysincludes.h"
#include "msdos.h"
#include "mtools.h"
#include "patchlevel.h"
/*#define PRIV_DEBUG*/
#if 0
#undef HAVE_SETEUID
#define HAVE_SETRESUID
#include <asm/unistd.h>
int setresuid(int a, int b, int c)
{
syscall(164, a, b, c);
}
#endif
static inline void print_privs(const char *message)
{
#ifdef PRIV_DEBUG
/* for debugging purposes only */
fprintf(stderr,"%s egid=%d rgid=%d\n", message, getegid(), getgid());
fprintf(stderr,"%s euid=%d ruid=%d\n", message, geteuid(), getuid());
#endif
}
static int rgid, egid, ruid, euid;
/* privilege management routines for SunOS and Solaris. These are
* needed in order to issue raw SCSI read/write ioctls. Mtools drops
* its privileges at the beginning, and reclaims them just for the
* above-mentioned ioctl's. Before popen(), exec() or system, it
* drops its privileges completely, and issues a warning.
*/
/* group id handling is lots easyer, as long as we don't use group 0.
* If you want to use group id's, create a *new* group mtools or
* floppy. Chgrp any devices that you only want to be accessible to
* mtools to this group, and give them the appropriate privs. Make
* sure this group doesn't own any other files: be aware that any user
* with access to mtools may mformat these files!
*/
static inline void Setuid(int uid)
{
#if defined HAVE_SETEUID || defined HAVE_SETRESUID
if(euid == 0) {
#ifdef HAVE_SETEUID
seteuid(uid);
#else
setresuid(ruid, uid, euid);
#endif
} else
#endif
setuid(uid);
}
/* In reclaim_privs and drop privs, we have to manipulate group privileges
* when having no root privileges, else we might lose them */
void reclaim_privs(void)
{
setgid(egid);
Setuid(euid);
print_privs("after reclaim privs, both uids should be 0 ");
}
void drop_privs(void)
{
Setuid(ruid);
setgid(rgid);
print_privs("after drop_privs, real should be 0, effective should not ");
}
void destroy_privs(void)
{
#if defined HAVE_SETEUID || defined HAVE_SETRESUID
if(euid == 0) {
#ifdef HAVE_SETEUID
setuid(0); /* get the necessary privs to drop real root id */
setuid(ruid); /* this should be enough to get rid of the three
* ids */
seteuid(ruid); /* for good measure... just in case we came
* accross a system which implemented sane
* semantics instead of POSIXly broken
* semantics for setuid */
#else
setresuid(ruid, ruid, ruid);
#endif
}
#endif
/* we also destroy group privileges */
drop_privs();
/* saved set [ug]id will go away by itself on exec */
print_privs("destroy_privs, no uid should be zero ");
}
void init_privs(void)
{
euid = geteuid();
ruid = getuid();
egid = getegid();
rgid = getgid();
#ifndef FD_CLOEXEC
if(euid != ruid) {
fprintf(stderr,
"Setuid installation not supported on this platform\n");
fprintf(stderr,
"Missing FD_CLOEXEC");
exit(1);
}
#endif
if(euid == 0 && ruid != 0) {
#ifdef HAVE_SETEUID
setuid(0); /* set real uid to 0 */
#else
#ifndef HAVE_SETRESUID
/* on this machine, it is not possible to reversibly drop
* root privileges. We print an error and quit */
/* BEOS is no longer a special case, as both euid and ruid
* return 0, and thus we do not get any longer into this
* branch */
fprintf(stderr,
"Seteuid call not supported on this architecture.\n");
fprintf(stderr,
"Mtools cannot be installed setuid root.\n");
fprintf(stderr,
"However, it can be installed setuid to a non root");
fprintf(stderr,
"user or setgid to any id.\n");
exit(1);
#endif
#endif
}
drop_privs();
print_privs("after init, real should be 0, effective should not ");
}
void closeExec(int fd)
{
#ifdef FD_CLOEXEC
fcntl(fd, F_SETFL, FD_CLOEXEC);
#endif
}
|