*** empty log message ***
This commit is contained in:
209
sys/unix/unixres.c
Normal file
209
sys/unix/unixres.c
Normal file
@@ -0,0 +1,209 @@
|
||||
/* SCCS Id: @(#)unixres.c 3.3 01/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)
|
||||
|
||||
static _syscall3(int, getresuid, unsigned short *, ruid, \
|
||||
unsigned short *, euid, unsigned short *, suid)
|
||||
static _syscall3(int, getresgid, unsigned short *, rgid, \
|
||||
unsigned short *, egid, unsigned short *, sgid)
|
||||
|
||||
static int
|
||||
real_getresuid(ruid, euid, suid)
|
||||
uid_t *ruid, *euid, *suid;
|
||||
{
|
||||
int retval;
|
||||
unsigned short r, e, s;
|
||||
retval = getresuid(&r, &e, &s);
|
||||
if (!retval) {
|
||||
*ruid = r;
|
||||
*euid = e;
|
||||
*suid = s;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int
|
||||
real_getresgid(rgid, egid, sgid)
|
||||
gid_t *rgid, *egid, *sgid;
|
||||
{
|
||||
int retval;
|
||||
unsigned short r, e, s;
|
||||
retval = getresgid(&r, &e, &s);
|
||||
if (!retval) {
|
||||
*rgid = r;
|
||||
*egid = e;
|
||||
*sgid = s;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
#elif 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 */
|
||||
|
||||
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 /* LINUX || BSD || SVR4 */
|
||||
|
||||
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 */
|
||||
|
||||
int
|
||||
hide_privileges(flag)
|
||||
boolean flag;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* GETRES_SUPPORT */
|
||||
Reference in New Issue
Block a user