- If you have Gnome installed on solaris, the GETRES support wouldn't build. I don't have access to a solaris system with Gnome installed, but hacked unixconf.h to force the GETRES code itself to be compiled. So, I believe the unixres.c change will work for folks really using Gnome on Solaris. Whether the rest of the gnome code will build there is beyond me. - I accidentally left TIMED_DELAY defined and the Solaris build failed. While solaris has usleep(), this is not part of SVR4 as far as I can tell. But, SysV does have poll, so I implemented msleep() for SysV systems in terms of poll. So, you can now define TIMED_DELAY on any SYSV build.
210 lines
3.8 KiB
C
210 lines
3.8 KiB
C
/* 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 */
|
|
#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 */
|