summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2015-10-30 13:39:55 +0100
committerAndreas Schneider <asn@cryptomilk.org>2015-11-05 09:23:16 +0100
commit6b388799e1c834d74584dc6982155c731f56a49a (patch)
treefed9d3b97cdba2031c83e1e6a45dfc81e6578bf4
parent2232db817336787c520ad32a1d3179a628d53e06 (diff)
downloadsamba-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.c162
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
*/