summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2015-10-30 13:38:32 +0100
committerAndreas Schneider <asn@cryptomilk.org>2015-11-05 09:23:16 +0100
commit253f42c83721085ceb19a7f1efd5810a36ca122a (patch)
tree1b0d8ea4211a98941d122bd655fab72375dc99db
parent5a9c80da7f4c6a9ab3d9d328dff9eb0568e270b9 (diff)
downloadsamba-253f42c83721085ceb19a7f1efd5810a36ca122a.tar.gz
uwrap: Allow setreuid 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.c91
1 files changed, 84 insertions, 7 deletions
diff --git a/lib/uid_wrapper/uid_wrapper.c b/lib/uid_wrapper/uid_wrapper.c
index abb0cb364cb..da8a2759f09 100644
--- a/lib/uid_wrapper/uid_wrapper.c
+++ b/lib/uid_wrapper/uid_wrapper.c
@@ -1101,6 +1101,88 @@ static int uwrap_setresuid(uid_t ruid, uid_t euid, uid_t suid)
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
/*
* UWRAP_GETxUID FUNCTIONS
@@ -1173,17 +1255,12 @@ int seteuid(uid_t euid)
#ifdef HAVE_SETREUID
int setreuid(uid_t ruid, uid_t euid)
{
- if (ruid == (uid_t)-1 && euid == (uid_t)-1) {
- errno = EINVAL;
- return -1;
- }
-
if (!uid_wrapper_enabled()) {
return libc_setreuid(ruid, euid);
}
uwrap_init();
- return uwrap_setresuid(ruid, euid, -1);
+ return uwrap_setreuid(ruid, euid);
}
#endif
@@ -1662,7 +1739,7 @@ static long int uwrap_syscall (long int sysno, va_list vp)
uid_t ruid = (uid_t) va_arg(vp, uid_t);
uid_t euid = (uid_t) va_arg(vp, uid_t);
- rc = uwrap_setresuid_thread(ruid, euid, -1);
+ rc = uwrap_setreuid_thread(ruid, euid);
}
break;
#ifdef SYS_setresuid