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 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
|
/* Copyright 1997,1999,2001,2002,2007,2009 Alain Knaff.
* This file is part of mtools.
*
* Mtools is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Mtools is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Mtools. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sysincludes.h"
#include "msdos.h"
#include "mtools.h"
int noPrivileges=0;
#ifdef OS_mingw32msvc
void reclaim_privs(void)
{
}
void drop_privs(void)
{
}
void destroy_privs(void)
{
}
uid_t get_real_uid(void)
{
return 0;
}
void init_privs(void)
{
}
void closeExec(int fd)
{
}
#else
/*#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 gid_t rgid, egid;
static uid_t 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(uid_t 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)
{
if(noPrivileges)
return;
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 ");
}
uid_t get_real_uid(void)
{
return ruid;
}
void init_privs(void)
{
euid = geteuid();
ruid = getuid();
egid = getegid();
rgid = getgid();
#ifndef F_SETFD
if(euid != ruid) {
fprintf(stderr,
"Setuid installation not supported on this platform\n");
fprintf(stderr,
"Missing F_SETFD");
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 F_SETFD
fcntl(fd, F_SETFD, 1);
#endif
}
#endif
|