The branch, master has been updated via 82ff081 cmake: Run threaded tests also on BSD and Solaris via 35d070c tests: Get the tests working on BSD via 77fdff7 tests: Rename test_gid to test_setgroups via 64505d6 tests: Add setresgid unprivileged user test via 4a0e9d4 tests: Move setresgid test to own executable via 246a94b tests: Move setregid test to own executable via f02727a tests: Move setegid test to own executable via 5d38a57 tests: Move setgid test to own executable via ee7795d tests: Add new test_setuid_euid1 and test_setuid_euid2 via a6eb467 tests: Create a test for threaded SYS_setuid via 0006b60 tests: Fix test_syscall_setuid to work with privilege checks via 7cde22c tests: Create a test for threaded sync SYS_setreuid via 9f45e90 tests: Create a test for threaded SYS_setreuid via 1b9b469 tests: Fix test_syscall_setreuid to work with privilege checks via f3d9e8e tests: Make syscall setresuid test from test_syscall_uid via d113176 tests: Move syscall setreuid test to own executable via 156d99a tests: Add test_getresuid out of test_uid via 2156fd0 tests: Move setresuid test to own executable via f5ddff7 tests: Move setreuid test to own executable via b0e109d tests: Move seteuid test to own executable via e459734 tests: Move setuid test to own executable via a54d1d6 cmake: Always set UID_WRAPPER_ROOT=1 for tests via caff321 uwrap: Add the EINVAL check to setegid() via e89cf7c uwrap: Allow setgid calls only for privileged users via f71da32 uwrap: Allow setregid calls only for privileged users via 38a13d2 uwrap: Allow setresgid calls only for privileged users via 7cd26ff uwrap: Move the EINVAL check down in seteuid() via 1044270 uwrap: Allow setuid calls only for privileged users via 54510cf uwrap: Allow setreuid calls only for privileged users via ac17973 uwrap: Allow setresuid calls only for privileged users via 9e2642c uwrap: Fix a possible null pointer dereference via 199b143 uwrap: Improve debug output via 0353a18 uwrap: Fix debug line in uwrap_init() from 10424ba Bump version to 1.1.1
https://git.samba.org/?p=uid_wrapper.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 82ff0812e4287ba4786c97a1d56ce04d92d3ca6b Author: Andreas Schneider <a...@samba.org> Date: Mon Oct 12 18:41:16 2015 +0200 cmake: Run threaded tests also on BSD and Solaris Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 35d070cb178fe07f1f902eaa5c9d91ea734dc932 Author: Andreas Schneider <a...@samba.org> Date: Thu Oct 8 17:03:48 2015 +0200 tests: Get the tests working on BSD The setuid and seteuid behaviour is different to Linux and Solaris. The setuid euid tests on BSD look like a bug? Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 77fdff705f6e82a923f0b66ea0859bbd1f1358d6 Author: Andreas Schneider <a...@samba.org> Date: Fri Oct 9 13:22:35 2015 +0200 tests: Rename test_gid to test_setgroups Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 64505d6964a52ad636ede36ab3a5f973189a954d Author: Andreas Schneider <a...@samba.org> Date: Tue Oct 27 10:42:35 2015 +0100 tests: Add setresgid unprivileged user test Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 4a0e9d4da9be669755263b68adefba507f5e3ea9 Author: Andreas Schneider <a...@samba.org> Date: Fri Oct 9 13:21:20 2015 +0200 tests: Move setresgid test to own executable Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 246a94bffd8224baa01d6a4f20cf2b58b5ff5a76 Author: Andreas Schneider <a...@samba.org> Date: Fri Oct 9 13:10:23 2015 +0200 tests: Move setregid test to own executable Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit f02727a26dd5a010028057f0ed4b8744b1c5818b Author: Andreas Schneider <a...@samba.org> Date: Fri Oct 9 09:40:14 2015 +0200 tests: Move setegid test to own executable Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 5d38a571daf996f1a181c753403934188fa49c47 Author: Andreas Schneider <a...@samba.org> Date: Fri Oct 9 09:31:10 2015 +0200 tests: Move setgid test to own executable Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit ee7795df63783a787e40dd5dfcf41574a0dfc3a7 Author: Andreas Schneider <a...@samba.org> Date: Thu Oct 8 15:23:24 2015 +0200 tests: Add new test_setuid_euid1 and test_setuid_euid2 Pair-Programmed-With: Stefan Metzmacher <me...@samba.org> Signed-off-by: Andreas Schneider <a...@samba.org> Signed-off-by: Stefan Metzmacher <me...@samba.org> commit a6eb46785f68934376b103796273ffdaf1f6f5a9 Author: Andreas Schneider <a...@samba.org> Date: Tue Oct 27 10:19:57 2015 +0100 tests: Create a test for threaded SYS_setuid Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 0006b60255e5acfe1af6bcc0be76e0a5ff2ef3ff Author: Andreas Schneider <a...@samba.org> Date: Tue Oct 27 10:18:54 2015 +0100 tests: Fix test_syscall_setuid to work with privilege checks Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 7cde22c02c7597ef8bbe29de536037fa6626c477 Author: Andreas Schneider <a...@samba.org> Date: Wed Sep 23 14:06:20 2015 +0200 tests: Create a test for threaded sync SYS_setreuid Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 9f45e90abe37204dadc54458a328c8bea7cfbd96 Author: Andreas Schneider <a...@samba.org> Date: Tue Oct 27 10:21:26 2015 +0100 tests: Create a test for threaded SYS_setreuid Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 1b9b469db765a9b52fa828053b8b0b801d372755 Author: Andreas Schneider <a...@samba.org> Date: Tue Oct 27 10:20:53 2015 +0100 tests: Fix test_syscall_setreuid to work with privilege checks Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit f3d9e8e0ab9d146a4c76ac87690bbec2e3074bd2 Author: Andreas Schneider <a...@samba.org> Date: Tue Sep 22 17:41:04 2015 +0200 tests: Make syscall setresuid test from test_syscall_uid Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit d113176953e0dfc1910ce2bd7a86134778902d68 Author: Andreas Schneider <a...@samba.org> Date: Tue Sep 22 17:33:04 2015 +0200 tests: Move syscall setreuid test to own executable Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 156d99a54f23cb333f058fdaf6eb1ab71d16b88e Author: Andreas Schneider <a...@samba.org> Date: Tue Sep 22 17:21:11 2015 +0200 tests: Add test_getresuid out of test_uid Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 2156fd069496b9f7a768d704f5d0e93116686cf0 Author: Andreas Schneider <a...@samba.org> Date: Tue Sep 22 16:55:43 2015 +0200 tests: Move setresuid test to own executable Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit f5ddff7d2f06c0da1ea8c968968d4efca0936423 Author: Andreas Schneider <a...@samba.org> Date: Tue Sep 22 14:29:49 2015 +0200 tests: Move setreuid test to own executable Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit b0e109d5620d2e830dac7e4453c4a595c9e2c17f Author: Andreas Schneider <a...@samba.org> Date: Tue Sep 22 14:21:17 2015 +0200 tests: Move seteuid test to own executable Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit e4597342390811d60e88626e7c20fda9c97d94fd Author: Andreas Schneider <a...@samba.org> Date: Tue Sep 22 14:17:28 2015 +0200 tests: Move setuid test to own executable Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit a54d1d6999c8bd78cf1f5ff0aeb9d8bd972cd80d Author: Andreas Schneider <a...@samba.org> Date: Fri Sep 18 16:23:17 2015 +0200 cmake: Always set UID_WRAPPER_ROOT=1 for tests Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit caff3210583e798215880b723875acf4bba188dd Author: Andreas Schneider <a...@samba.org> Date: Fri Oct 9 09:14:34 2015 +0200 uwrap: Add the EINVAL check to setegid() Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit e89cf7c45b57b2fba51b5c0112e1b49d90627b5c Author: Andreas Schneider <a...@samba.org> Date: Fri Oct 9 09:17:16 2015 +0200 uwrap: Allow setgid calls only for privileged users Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit f71da3209e97c406c853bdd9a792f9694b366987 Author: Andreas Schneider <a...@samba.org> Date: Fri Oct 9 09:13:27 2015 +0200 uwrap: Allow setregid calls only for privileged users Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 38a13d2fcba2afb167443aa428e5d00e0a33991d Author: Andreas Schneider <a...@samba.org> Date: Fri Oct 9 09:08:21 2015 +0200 uwrap: Allow setresgid calls only for privileged users Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 7cd26ff30f550cd8590251a8477c9b15df3c9a89 Author: Andreas Schneider <a...@samba.org> Date: Thu Oct 8 16:52:00 2015 +0200 uwrap: Move the EINVAL check down in seteuid() Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 10442701fb15ef12b0abb114603329448332537b Author: Andreas Schneider <a...@samba.org> Date: Thu Oct 8 16:55:01 2015 +0200 uwrap: Allow setuid calls only for privileged users Pair-Programmed-With: Stefan Metzmacher <me...@samba.org> Signed-off-by: Andreas Schneider <a...@samba.org> Signed-off-by: Stefan Metzmacher <me...@samba.org> commit 54510cf88a4d0ec51f99584979063a73386f90dd Author: Andreas Schneider <a...@samba.org> Date: Thu Oct 8 16:50:01 2015 +0200 uwrap: Allow setreuid calls only for privileged users Pair-Programmed-With: Stefan Metzmacher <me...@samba.org> Signed-off-by: Andreas Schneider <a...@samba.org> Signed-off-by: Stefan Metzmacher <me...@samba.org> commit ac17973ea840826946be574d53d2121b1f02d530 Author: Andreas Schneider <a...@samba.org> Date: Thu Oct 8 16:46:27 2015 +0200 uwrap: Allow setresuid calls only for privileged users Pair-Programmed-With: Stefan Metzmacher <me...@samba.org> Signed-off-by: Andreas Schneider <a...@samba.org> Signed-off-by: Stefan Metzmacher <me...@samba.org> commit 9e2642cb7b715f6a9aa32615c88e30258ef40f60 Author: Andreas Schneider <a...@samba.org> Date: Tue Oct 20 15:06:02 2015 +0200 uwrap: Fix a possible null pointer dereference If uid_wrapper is loaded but not enabled (UID_WRAPPER environment variable not set), then we dereference a NULL pointer while forking. Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 199b14398a6c0dd655e0ba84f307d90c46997a08 Author: Andreas Schneider <a...@samba.org> Date: Tue Sep 22 17:11:57 2015 +0200 uwrap: Improve debug output Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit 0353a183741c29922552bbaa615445f82379b369 Author: Andreas Schneider <a...@samba.org> Date: Tue Sep 22 17:06:01 2015 +0200 uwrap: Fix debug line in uwrap_init() Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> ----------------------------------------------------------------------- Summary of changes: src/uid_wrapper.c | 628 +++++++++++++++++++++++++++------ tests/CMakeLists.txt | 89 ++++- tests/test_getresuid.c | 48 +++ tests/test_glibc_thread_support.c | 193 ---------- tests/test_setegid.c | 167 +++++++++ tests/test_seteuid.c | 122 +++++++ tests/test_setgid.c | 149 ++++++++ tests/{test_gid.c => test_setgroups.c} | 86 ----- tests/test_setregid.c | 190 ++++++++++ tests/test_setresgid.c | 198 +++++++++++ tests/test_setresgid_unprivileged.c | 147 ++++++++ tests/test_setresuid.c | 256 ++++++++++++++ tests/test_setreuid.c | 99 ++++++ tests/test_setuid.c | 85 +++++ tests/test_setuid_euid1.c | 89 +++++ tests/test_setuid_euid2.c | 99 ++++++ tests/test_syscall_setresuid.c | 62 ++++ tests/test_syscall_setreuid.c | 102 ++++++ tests/test_syscall_setuid.c | 89 +++++ tests/test_syscall_uid.c | 109 ------ tests/test_thread_setreuid.c | 96 +++++ tests/test_thread_setuid.c | 101 ++++++ tests/test_thread_sync_setreuid.c | 156 ++++++++ tests/test_uid.c | 134 ------- 24 files changed, 2846 insertions(+), 648 deletions(-) create mode 100644 tests/test_getresuid.c create mode 100644 tests/test_setegid.c create mode 100644 tests/test_seteuid.c create mode 100644 tests/test_setgid.c rename tests/{test_gid.c => test_setgroups.c} (51%) create mode 100644 tests/test_setregid.c create mode 100644 tests/test_setresgid.c create mode 100644 tests/test_setresgid_unprivileged.c create mode 100644 tests/test_setresuid.c create mode 100644 tests/test_setreuid.c create mode 100644 tests/test_setuid.c create mode 100644 tests/test_setuid_euid1.c create mode 100644 tests/test_setuid_euid2.c create mode 100644 tests/test_syscall_setresuid.c create mode 100644 tests/test_syscall_setreuid.c create mode 100644 tests/test_syscall_setuid.c delete mode 100644 tests/test_syscall_uid.c create mode 100644 tests/test_thread_setreuid.c create mode 100644 tests/test_thread_setuid.c create mode 100644 tests/test_thread_sync_setreuid.c delete mode 100644 tests/test_uid.c Changeset truncated at 500 lines: diff --git a/src/uid_wrapper.c b/src/uid_wrapper.c index 2961b87..2702bd7 100644 --- a/src/uid_wrapper.c +++ b/src/uid_wrapper.c @@ -136,10 +136,10 @@ enum uwrap_dbglvl_e { #ifdef NDEBUG # define UWRAP_LOG(...) #else /* NDEBUG */ -static void uwrap_log(enum uwrap_dbglvl_e dbglvl, const char *format, ...) PRINTF_ATTRIBUTE(2, 3); -# define UWRAP_LOG(dbglvl, ...) uwrap_log((dbglvl), __VA_ARGS__) +static void uwrap_log(enum uwrap_dbglvl_e dbglvl, const char *function, const char *format, ...) PRINTF_ATTRIBUTE(3, 4); +# define UWRAP_LOG(dbglvl, ...) uwrap_log((dbglvl), __func__, __VA_ARGS__) -static void uwrap_log(enum uwrap_dbglvl_e dbglvl, const char *format, ...) +static void uwrap_log(enum uwrap_dbglvl_e dbglvl, const char *function, const char *format, ...) { char buffer[1024]; va_list va; @@ -156,28 +156,28 @@ static void uwrap_log(enum uwrap_dbglvl_e dbglvl, const char *format, ...) va_end(va); if (lvl >= dbglvl) { + const char *prefix; switch (dbglvl) { case UWRAP_LOG_ERROR: - fprintf(stderr, - "UWRAP_ERROR(%d): %s\n", - (int)getpid(), buffer); + prefix = "UWRAP_ERROR"; break; case UWRAP_LOG_WARN: - fprintf(stderr, - "UWRAP_WARN(%d): %s\n", - (int)getpid(), buffer); + prefix = "UWRAP_WARN"; break; case UWRAP_LOG_DEBUG: - fprintf(stderr, - "UWRAP_DEBUG(%d): %s\n", - (int)getpid(), buffer); + prefix = "UWRAP_DEBUG"; break; case UWRAP_LOG_TRACE: - fprintf(stderr, - "UWRAP_TRACE(%d): %s\n", - (int)getpid(), buffer); + prefix = "UWRAP_TRACE"; break; } + + fprintf(stderr, + "%s(%d) - %s: %s\n", + prefix, + (int)getpid(), + function, + buffer); } } #endif /* NDEBUG */ @@ -812,6 +812,11 @@ static void uwrap_thread_prepare(void) { struct uwrap_thread *id = uwrap_tls_id; + /* uid_wrapper is loaded but not enabled */ + if (id == NULL) { + return; + } + UWRAP_LOCK_ALL; /* @@ -826,6 +831,12 @@ static void uwrap_thread_prepare(void) static void uwrap_thread_parent(void) { struct uwrap_thread *id = uwrap_tls_id; + + /* uid_wrapper is loaded but not enabled */ + if (id == NULL) { + return; + } + id->enabled = true; UWRAP_UNLOCK_ALL; @@ -836,6 +847,11 @@ static void uwrap_thread_child(void) struct uwrap_thread *id = uwrap_tls_id; struct uwrap_thread *u = uwrap.ids; + /* uid_wrapper is loaded but not enabled */ + if (id == NULL) { + return; + } + /* * "Garbage collector" - Inspired by DESTRUCTOR. * All threads (except one which called fork()) are dead now.. Dave @@ -952,8 +968,9 @@ static void uwrap_init(void) id->enabled = true; UWRAP_LOG(UWRAP_LOG_DEBUG, - "Enabled uid_wrapper as %s", - uwrap.myuid == 0 ? "root" : "user"); + "Enabled uid_wrapper as %s (real uid=%u)", + id->ruid == 0 ? "root" : "user", + (unsigned int)uwrap.myuid); } UWRAP_UNLOCK(uwrap_id); @@ -977,33 +994,61 @@ bool uid_wrapper_enabled(void) return enabled; } -#ifdef HAVE_GETRESUID -static int uwrap_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid) +/* + * UWRAP_SETxUID FUNCTIONS + */ + +static int uwrap_setresuid_args(uid_t ruid, uid_t euid, uid_t suid) { struct uwrap_thread *id = uwrap_tls_id; - UWRAP_LOCK(uwrap_id); - - *ruid = id->ruid; - *euid = id->euid; - *suid = id->suid; - - UWRAP_UNLOCK(uwrap_id); + UWRAP_LOG(UWRAP_LOG_TRACE, + "ruid %d -> %d, euid %d -> %d, suid %d -> %d", + id->ruid, ruid, id->euid, euid, id->suid, suid); + + if (id->euid != 0) { + if (ruid != (uid_t)-1 && + ruid != id->ruid && + ruid != id->euid && + ruid != id->suid) { + errno = EPERM; + return -1; + } + if (euid != (uid_t)-1 && + euid != id->ruid && + euid != id->euid && + euid != id->suid) { + errno = EPERM; + return -1; + } + if (suid != (uid_t)-1 && + suid != id->ruid && + suid != id->euid && + suid != id->suid) { + errno = EPERM; + return -1; + } + } return 0; } -#endif static int uwrap_setresuid_thread(uid_t ruid, uid_t euid, uid_t suid) { struct uwrap_thread *id = uwrap_tls_id; + int rc; - if (ruid == (uid_t)-1 && euid == (uid_t)-1 && suid == (uid_t)-1) { - errno = EINVAL; - return -1; + UWRAP_LOG(UWRAP_LOG_TRACE, + "ruid %d -> %d, euid %d -> %d, suid %d -> %d", + id->ruid, ruid, id->euid, euid, id->suid, suid); + + rc = uwrap_setresuid_args(ruid, euid, suid); + if (rc != 0) { + return rc; } UWRAP_LOCK(uwrap_id); + if (ruid != (uid_t)-1) { id->ruid = ruid; } @@ -1021,6 +1066,200 @@ static int uwrap_setresuid_thread(uid_t ruid, uid_t euid, uid_t suid) return 0; } +static int uwrap_setresuid(uid_t ruid, uid_t euid, uid_t suid) +{ + struct uwrap_thread *id = uwrap_tls_id; + int rc; + + UWRAP_LOG(UWRAP_LOG_TRACE, + "ruid %d -> %d, euid %d -> %d, suid %d -> %d", + id->ruid, ruid, id->euid, euid, id->suid, suid); + + rc = uwrap_setresuid_args(ruid, euid, suid); + if (rc != 0) { + return rc; + } + + UWRAP_LOCK(uwrap_id); + + for (id = uwrap.ids; id; id = id->next) { + if (ruid != (uid_t)-1) { + id->ruid = ruid; + } + + if (euid != (uid_t)-1) { + id->euid = euid; + } + + if (suid != (uid_t)-1) { + id->suid = suid; + } + } + + UWRAP_UNLOCK(uwrap_id); + + return 0; +} + +static int uwrap_setreuid_args(uid_t ruid, uid_t euid, + uid_t *_new_ruid, + uid_t *_new_euid, + uid_t *_new_suid) +{ + struct uwrap_thread *id = uwrap_tls_id; + uid_t new_ruid = -1, new_euid = -1, new_suid = -1; + + UWRAP_LOG(UWRAP_LOG_TRACE, + "ruid %d -> %d, euid %d -> %d", + id->ruid, ruid, id->euid, euid); + + if (ruid != (uid_t)-1) { + new_ruid = ruid; + if (ruid != id->ruid && + ruid != id->euid && + id->euid != 0) { + errno = EPERM; + return -1; + } + } + + if (euid != (uid_t)-1) { + new_euid = euid; + if (euid != id->ruid && + euid != id->euid && + euid != id->suid && + id->euid != 0) { + errno = EPERM; + return -1; + } + } + + if (ruid != (uid_t) -1 || + (euid != (uid_t)-1 && id->ruid != euid)) { + new_suid = new_euid; + } + + *_new_ruid = new_ruid; + *_new_euid = new_euid; + *_new_suid = new_suid; + + return 0; +} + +static int uwrap_setreuid_thread(uid_t ruid, uid_t euid) +{ + struct uwrap_thread *id = uwrap_tls_id; + uid_t new_ruid = -1, new_euid = -1, new_suid = -1; + int rc; + + UWRAP_LOG(UWRAP_LOG_TRACE, + "ruid %d -> %d, euid %d -> %d", + id->ruid, ruid, id->euid, euid); + + rc = uwrap_setreuid_args(ruid, euid, &new_ruid, &new_euid, &new_suid); + if (rc != 0) { + return rc; + } + + return uwrap_setresuid_thread(new_ruid, new_euid, new_suid); +} + +#ifdef HAVE_SETREUID +static int uwrap_setreuid(uid_t ruid, uid_t euid) +{ + struct uwrap_thread *id = uwrap_tls_id; + uid_t new_ruid = -1, new_euid = -1, new_suid = -1; + int rc; + + UWRAP_LOG(UWRAP_LOG_TRACE, + "ruid %d -> %d, euid %d -> %d", + id->ruid, ruid, id->euid, euid); + + rc = uwrap_setreuid_args(ruid, euid, &new_ruid, &new_euid, &new_suid); + if (rc != 0) { + return rc; + } + + return uwrap_setresuid(new_ruid, new_euid, new_suid); +} +#endif + +static int uwrap_setuid_args(uid_t uid, + uid_t *new_ruid, + uid_t *new_euid, + uid_t *new_suid) +{ + struct uwrap_thread *id = uwrap_tls_id; + + UWRAP_LOG(UWRAP_LOG_TRACE, + "uid %d -> %d", + id->ruid, uid); + + if (uid == (uid_t)-1) { + errno = EINVAL; + return -1; + } + + if (id->euid == 0) { + *new_suid = *new_ruid = uid; + } else if (uid != id->ruid && + uid != id->suid) { + errno = EPERM; + return -1; + } + + *new_euid = uid; + + return 0; +} + +static int uwrap_setuid_thread(uid_t uid) +{ + uid_t new_ruid = -1, new_euid = -1, new_suid = -1; + int rc; + + rc = uwrap_setuid_args(uid, &new_ruid, &new_euid, &new_suid); + if (rc != 0) { + return rc; + } + + return uwrap_setresuid_thread(new_ruid, new_euid, new_suid); +} + +static int uwrap_setuid(uid_t uid) +{ + uid_t new_ruid = -1, new_euid = -1, new_suid = -1; + int rc; + + rc = uwrap_setuid_args(uid, &new_ruid, &new_euid, &new_suid); + if (rc != 0) { + return rc; + } + + return uwrap_setresuid(new_ruid, new_euid, new_suid); +} + +/* + * UWRAP_GETxUID FUNCTIONS + */ + +#ifdef HAVE_GETRESUID +static int uwrap_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid) +{ + struct uwrap_thread *id = uwrap_tls_id; + + UWRAP_LOCK(uwrap_id); + + *ruid = id->ruid; + *euid = id->euid; + *suid = id->suid; + + UWRAP_UNLOCK(uwrap_id); + + return 0; +} +#endif + #ifdef HAVE_GETRESGID static int uwrap_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid) { @@ -1038,27 +1277,105 @@ static int uwrap_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid) } #endif -static int uwrap_setresuid(uid_t ruid, uid_t euid, uid_t suid) +/* + * UWRAP_SETxGID FUNCTIONS + */ + +static int uwrap_setresgid_args(gid_t rgid, gid_t egid, gid_t sgid) { - struct uwrap_thread *id; + struct uwrap_thread *id = uwrap_tls_id; - if (ruid == (uid_t)-1 && euid == (uid_t)-1 && suid == (uid_t)-1) { - errno = EINVAL; - return -1; + UWRAP_LOG(UWRAP_LOG_TRACE, + "rgid %d -> %d, egid %d -> %d, sgid %d -> %d", + id->rgid, rgid, id->egid, egid, id->sgid, sgid); + + if (id->euid != 0) { + if (rgid != (gid_t)-1 && + rgid != id->rgid && + rgid != id->egid && + rgid != id->sgid) { + errno = EPERM; + return -1; + } + if (egid != (gid_t)-1 && + egid != id->rgid && + egid != id->egid && + egid != id->sgid) { + errno = EPERM; + return -1; + } + if (sgid != (gid_t)-1 && + sgid != id->rgid && + sgid != id->egid && + sgid != id->sgid) { + errno = EPERM; + return -1; + } + } + + return 0; +} + +static int uwrap_setresgid_thread(gid_t rgid, gid_t egid, gid_t sgid) +{ + struct uwrap_thread *id = uwrap_tls_id; + int rc; + + UWRAP_LOG(UWRAP_LOG_TRACE, + "rgid %d -> %d, egid %d -> %d, sgid %d -> %d", + id->rgid, rgid, id->egid, egid, id->sgid, sgid); + + rc = uwrap_setresgid_args(rgid, egid, sgid); + if (rc != 0) { + return rc; } UWRAP_LOCK(uwrap_id); + + if (rgid != (gid_t)-1) { + id->rgid = rgid; + } + + if (egid != (gid_t)-1) { + id->egid = egid; + } + + if (sgid != (gid_t)-1) { + id->sgid = sgid; + } + + UWRAP_UNLOCK(uwrap_id); + + return 0; +} + +static int uwrap_setresgid(gid_t rgid, gid_t egid, gid_t sgid) +{ + struct uwrap_thread *id = uwrap_tls_id; + int rc; + + UWRAP_LOG(UWRAP_LOG_TRACE, + "rgid %d -> %d, egid %d -> %d, sgid %d -> %d", + id->rgid, rgid, id->egid, egid, id->sgid, sgid); + + rc = uwrap_setresgid_args(rgid, egid, sgid); + if (rc != 0) { + return rc; + } + + UWRAP_LOCK(uwrap_id); + for (id = uwrap.ids; id; id = id->next) { - if (ruid != (uid_t)-1) { - id->ruid = ruid; + if (rgid != (gid_t)-1) { + id->rgid = rgid; } - if (euid != (uid_t)-1) { - id->euid = euid; + if (egid != (gid_t)-1) { + id->egid = egid; } - if (suid != (uid_t)-1) { - id->suid = suid; + if (sgid != (gid_t)-1) { + id->sgid = sgid; } } -- UID Wrapper Repository