diff options
author | Andreas Schneider <asn@samba.org> | 2015-10-30 13:39:55 +0100 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2015-11-05 09:23:16 +0100 |
commit | 6b388799e1c834d74584dc6982155c731f56a49a (patch) | |
tree | fed9d3b97cdba2031c83e1e6a45dfc81e6578bf4 | |
parent | 2232db817336787c520ad32a1d3179a628d53e06 (diff) | |
download | samba-6b388799e1c834d74584dc6982155c731f56a49a.tar.gz |
uwrap: Allow setresgid calls only for privileged users
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
-rw-r--r-- | lib/uid_wrapper/uid_wrapper.c | 162 |
1 files changed, 107 insertions, 55 deletions
diff --git a/lib/uid_wrapper/uid_wrapper.c b/lib/uid_wrapper/uid_wrapper.c index dd999ffc114..af3b4328aa5 100644 --- a/lib/uid_wrapper/uid_wrapper.c +++ b/lib/uid_wrapper/uid_wrapper.c @@ -1278,6 +1278,113 @@ static int uwrap_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid) #endif /* + * UWRAP_SETxGID FUNCTIONS + */ + +static int uwrap_setresgid_args(gid_t rgid, gid_t egid, gid_t sgid) +{ + struct uwrap_thread *id = uwrap_tls_id; + + 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 (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; +} + +/* * SETUID */ int setuid(uid_t uid) @@ -1400,61 +1507,6 @@ uid_t geteuid(void) return uwrap_geteuid(); } -static int uwrap_setresgid_thread(gid_t rgid, gid_t egid, gid_t sgid) -{ - struct uwrap_thread *id = uwrap_tls_id; - - if (rgid == (gid_t)-1 && egid == (gid_t)-1 && sgid == (gid_t)-1) { - errno = EINVAL; - return -1; - } - - 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; - - if (rgid == (gid_t)-1 && egid == (gid_t)-1 && sgid == (gid_t)-1) { - errno = EINVAL; - return -1; - } - - UWRAP_LOCK(uwrap_id); - for (id = uwrap.ids; id; id = id->next) { - 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; -} - /* * SETGID */ |