diff options
author | Andreas Schneider <asn@samba.org> | 2015-10-30 13:37:51 +0100 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2015-11-05 09:23:15 +0100 |
commit | 5a9c80da7f4c6a9ab3d9d328dff9eb0568e270b9 (patch) | |
tree | 8115c710e18fd25921221741fe023a718667a682 | |
parent | 656f0db652969bd0cd8faf145479e78356fc7252 (diff) | |
download | samba-5a9c80da7f4c6a9ab3d9d328dff9eb0568e270b9.tar.gz |
uwrap: Allow setresuid calls only for privileged users
Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Andreas Schneider <asn@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
-rw-r--r-- | lib/uid_wrapper/uid_wrapper.c | 122 |
1 files changed, 89 insertions, 33 deletions
diff --git a/lib/uid_wrapper/uid_wrapper.c b/lib/uid_wrapper/uid_wrapper.c index 60477d2b78e..abb0cb364cb 100644 --- a/lib/uid_wrapper/uid_wrapper.c +++ b/lib/uid_wrapper/uid_wrapper.c @@ -994,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; } @@ -1038,33 +1066,22 @@ static int uwrap_setresuid_thread(uid_t ruid, uid_t euid, uid_t suid) return 0; } -#ifdef HAVE_GETRESGID -static int uwrap_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid) +static int uwrap_setresuid(uid_t ruid, uid_t euid, uid_t suid) { struct uwrap_thread *id = uwrap_tls_id; + int rc; - UWRAP_LOCK(uwrap_id); - - *rgid = id->rgid; - *egid = id->egid; - *sgid = id->sgid; - - UWRAP_UNLOCK(uwrap_id); - - return 0; -} -#endif - -static int uwrap_setresuid(uid_t ruid, uid_t euid, uid_t suid) -{ - struct uwrap_thread *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 (ruid == (uid_t)-1 && euid == (uid_t)-1 && suid == (uid_t)-1) { - errno = EINVAL; - return -1; + 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; @@ -1084,6 +1101,45 @@ static int uwrap_setresuid(uid_t ruid, uid_t euid, uid_t suid) return 0; } + +/* + * 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) +{ + struct uwrap_thread *id = uwrap_tls_id; + + UWRAP_LOCK(uwrap_id); + + *rgid = id->rgid; + *egid = id->egid; + *sgid = id->sgid; + + UWRAP_UNLOCK(uwrap_id); + + return 0; +} +#endif + /* * SETUID */ |