From e080b5acbbe235d3ac32ccaf19826a8fd67e2eaf Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sat, 23 Jan 2016 10:06:53 -0800 Subject: Support setuid operation. * sysif.c (orig_euid, real_uid, repress_called, is_setuid): New static variables. (repress_privilege, drop_privilage, simulate_setuid): New functions. (RC_MAGIC): New preprocessor symbol. * sysif.c (repress_privilege, drop_privilage, simulate_setuid): Declared. * txr.c (txr_main): Call repress_privilege to check and remember whether we are in setuid mode, and temporarily drop the effective uid to the real one. (txr_main): Permanently drop privileges in all cases except script execution. In script execution cases, go through simulate_setuid to either set or preserve the effective user ID, or else drop privs. * txr.1: Documented setuid operation in new section. --- sysif.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'sysif.c') diff --git a/sysif.c b/sysif.c index 18761e59..7b072072 100644 --- a/sysif.c +++ b/sysif.c @@ -861,6 +861,59 @@ static val setegid_wrap(val nval) return t; } +#define RC_MAGIC 0xbe50c001 + +static uid_t orig_euid, real_uid; +static int repress_called = 0, is_setuid = 1; + +void repress_privilege(void) +{ + real_uid = getuid(); + orig_euid = geteuid(); + + if (real_uid != orig_euid) + seteuid(getuid()); + else + is_setuid = 0; + + repress_called = RC_MAGIC; +} + +void drop_privilege(void) +{ + if (repress_called != RC_MAGIC || (is_setuid && setuid(getuid()) != 0)) + abort(); +} + +void simulate_setuid(val open_script) +{ + if (repress_called != RC_MAGIC || (is_setuid && seteuid(orig_euid) != 0)) + abort(); + + if (!is_setuid && orig_euid != 0) + return; + + { + val fdv = stream_get_prop(open_script, fd_k); + + if (fdv) { + struct stat stb; + cnum fd = c_num(fdv); + + if (fstat(fd, &stb) != 0) + abort(); + + if ((stb.st_mode & (S_ISUID | S_IXUSR)) == (S_ISUID | S_IXUSR)) { + seteuid(stb.st_uid); + return; + } + } + } + + if (is_setuid) + setuid(real_uid); +} + #endif #if HAVE_PWUID -- cgit v1.2.3