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
|
/* SCCS Id: @(#)unixres.c 3.4 2001/07/08 */
/* Copyright (c) Slash'EM development team, 2001. */
/* NetHack may be freely redistributed. See license for details. */
/* [ALI] This module defines nh_xxx functions to replace getuid etc which
* will hide privileges from the caller if so desired.
*
* Currently supported UNIX variants:
* Linux version 2.1.44 and above
* FreeBSD (versions unknown)
*
* Note: SunOS and Solaris have no mechanism for retrieving the saved id,
* so temporarily dropping privileges on these systems is sufficient to
* hide them.
*/
#include "config.h"
#ifdef GETRES_SUPPORT
# if defined(LINUX)
/* requires dynamic linking with libc */
#define _GNU_SOURCE
#include <dlfcn.h>
static int
real_getresuid(ruid, euid, suid)
uid_t *ruid, *euid, *suid;
{
int (*f)(uid_t *, uid_t *, uid_t *); /* getresuid signature */
f = dlsym(RTLD_NEXT, "getresuid");
if (!f) return -1;
return f(ruid, euid, suid);
}
static int
real_getresgid(rgid, egid, sgid)
gid_t *rgid, *egid, *sgid;
{
int (*f)(gid_t *, gid_t *, gid_t *); /* getresgid signature */
f = dlsym(RTLD_NEXT, "getresgid");
if (!f) return -1;
return f(rgid, egid, sgid);
}
# else
# if defined(BSD) || defined(SVR4)
# ifdef SYS_getresuid
static int
real_getresuid(ruid, euid, suid)
uid_t *ruid, *euid, *suid;
{
return syscall(SYS_getresuid, ruid, euid, suid);
}
# else /* SYS_getresuid */
#ifdef SVR4
#include <sys/stat.h>
#endif /* SVR4 */
static int
real_getresuid(ruid, euid, suid)
uid_t *ruid, *euid, *suid;
{
int retval;
int pfd[2];
struct stat st;
if (pipe(pfd))
return -1;
retval = fstat(pfd[0], &st);
close(pfd[0]);
close(pfd[1]);
if (!retval) {
*euid = st.st_uid;
*ruid = syscall(SYS_getuid);
*suid = *ruid; /* Not supported under SVR4 */
}
return retval;
}
# endif /* SYS_getresuid */
# ifdef SYS_getresgid
static int
real_getresgid(rgid, egid, sgid)
gid_t *rgid, *egid, *sgid;
{
return syscall(SYS_getresgid, rgid, egid, sgid);
}
# else /* SYS_getresgid */
static int
real_getresgid(rgid, egid, sgid)
gid_t *rgid, *egid, *sgid;
{
int retval;
int pfd[2];
struct stat st;
if (pipe(pfd))
return -1;
retval = fstat(pfd[0], &st);
close(pfd[0]);
close(pfd[1]);
if (!retval) {
*egid = st.st_gid;
*rgid = syscall(SYS_getgid);
*sgid = *rgid; /* Not supported under SVR4 */
}
return retval;
}
# endif /* SYS_getresgid */
# endif /* BSD || SVR4 */
# endif /* LINUX */
static unsigned int hiding_privileges = 0;
/*
* Note: returns the value _after_ action.
*/
int
hide_privileges(flag)
boolean flag;
{
if (flag)
hiding_privileges++;
else if (hiding_privileges)
hiding_privileges--;
return hiding_privileges;
}
int
nh_getresuid(ruid, euid, suid)
uid_t *ruid, *euid, *suid;
{
int retval = real_getresuid(ruid, euid, suid);
if (!retval && hiding_privileges)
*euid = *suid = *ruid;
return retval;
}
uid_t
nh_getuid()
{
uid_t ruid, euid, suid;
(void) real_getresuid(&ruid, &euid, &suid);
return ruid;
}
uid_t
nh_geteuid()
{
uid_t ruid, euid, suid;
(void) real_getresuid(&ruid, &euid, &suid);
if (hiding_privileges)
euid = ruid;
return euid;
}
int
nh_getresgid(rgid, egid, sgid)
gid_t *rgid, *egid, *sgid;
{
int retval = real_getresgid(rgid, egid, sgid);
if (!retval && hiding_privileges)
*egid = *sgid = *rgid;
return retval;
}
gid_t
nh_getgid()
{
gid_t rgid, egid, sgid;
(void) real_getresgid(&rgid, &egid, &sgid);
return rgid;
}
gid_t
nh_getegid()
{
gid_t rgid, egid, sgid;
(void) real_getresgid(&rgid, &egid, &sgid);
if (hiding_privileges)
egid = rgid;
return egid;
}
#else /* GETRES_SUPPORT */
# ifdef GNOME_GRAPHICS
int
hide_privileges(flag)
boolean flag;
{
return 0;
}
# endif
#endif /* GETRES_SUPPORT */
|