summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2015-10-30 13:40:45 +0100
committerAndreas Schneider <asn@cryptomilk.org>2015-11-05 09:23:16 +0100
commit6e30b2e63854c9c7067f176c84468aece17641f7 (patch)
treed237afe9cd73e45fff605d7dba9c8cb32b7b1f1c
parentbe0cb8ab4d68680f0c4b1ec1db994781056d61b2 (diff)
downloadsamba-6e30b2e63854c9c7067f176c84468aece17641f7.tar.gz
uwrap: Allow setgid 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.c59
1 files changed, 57 insertions, 2 deletions
diff --git a/lib/uid_wrapper/uid_wrapper.c b/lib/uid_wrapper/uid_wrapper.c
index fe05f0ac258..d720e533e4e 100644
--- a/lib/uid_wrapper/uid_wrapper.c
+++ b/lib/uid_wrapper/uid_wrapper.c
@@ -1467,6 +1467,61 @@ static int uwrap_setregid(gid_t rgid, gid_t egid)
}
#endif
+static int uwrap_setgid_args(gid_t gid,
+ gid_t *new_rgid,
+ gid_t *new_egid,
+ gid_t *new_sgid)
+{
+ struct uwrap_thread *id = uwrap_tls_id;
+
+ UWRAP_LOG(UWRAP_LOG_TRACE,
+ "gid %d -> %d",
+ id->rgid, gid);
+
+ if (gid == (gid_t)-1) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (id->euid == 0) {
+ *new_sgid = *new_rgid = gid;
+ } else if (gid != id->rgid &&
+ gid != id->sgid) {
+ errno = EPERM;
+ return -1;
+ }
+
+ *new_egid = gid;
+
+ return 0;
+}
+
+static int uwrap_setgid_thread(gid_t gid)
+{
+ gid_t new_rgid = -1, new_egid = -1, new_sgid = -1;
+ int rc;
+
+ rc = uwrap_setgid_args(gid, &new_rgid, &new_egid, &new_sgid);
+ if (rc != 0) {
+ return rc;
+ }
+
+ return uwrap_setresgid_thread(new_rgid, new_egid, new_sgid);
+}
+
+static int uwrap_setgid(gid_t gid)
+{
+ gid_t new_rgid = -1, new_egid = -1, new_sgid = -1;
+ int rc;
+
+ rc = uwrap_setgid_args(gid, &new_rgid, &new_egid, &new_sgid);
+ if (rc != 0) {
+ return rc;
+ }
+
+ return uwrap_setresgid(new_rgid, new_egid, new_sgid);
+}
+
/*
* SETUID
*/
@@ -1600,7 +1655,7 @@ int setgid(gid_t gid)
}
uwrap_init();
- return uwrap_setresgid(gid, -1, -1);
+ return uwrap_setgid(gid);
}
#ifdef HAVE_SETEGID
@@ -1850,7 +1905,7 @@ static long int uwrap_syscall (long int sysno, va_list vp)
{
gid_t gid = (gid_t) va_arg(vp, gid_t);
- rc = uwrap_setresgid_thread(gid, -1, -1);
+ rc = uwrap_setgid_thread(gid);
}
break;
case SYS_setregid: