summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schneider <asn@samba.org>2015-10-30 13:39:02 +0100
committerAndreas Schneider <asn@cryptomilk.org>2015-11-05 09:23:16 +0100
commit56970b467b65ac00001132b499ab61b40ba1efa3 (patch)
treeb0de102e90a44d39ad677084cc0cb764bdc3d492
parent253f42c83721085ceb19a7f1efd5810a36ca122a (diff)
downloadsamba-56970b467b65ac00001132b499ab61b40ba1efa3.tar.gz
uwrap: Allow setuid 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.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 da8a2759f09..e0d84beb7ea 100644
--- a/lib/uid_wrapper/uid_wrapper.c
+++ b/lib/uid_wrapper/uid_wrapper.c
@@ -1184,6 +1184,61 @@ static int uwrap_setreuid(uid_t ruid, uid_t euid)
}
#endif
+static int uwrap_setuid_args(uid_t uid,
+ uid_t *new_ruid,
+ uid_t *new_euid,
+ uid_t *new_suid)
+{
+ struct uwrap_thread *id = uwrap_tls_id;
+
+ UWRAP_LOG(UWRAP_LOG_TRACE,
+ "uid %d -> %d",
+ id->ruid, uid);
+
+ if (uid == (uid_t)-1) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if (id->euid == 0) {
+ *new_suid = *new_ruid = uid;
+ } else if (uid != id->ruid &&
+ uid != id->suid) {
+ errno = EPERM;
+ return -1;
+ }
+
+ *new_euid = uid;
+
+ return 0;
+}
+
+static int uwrap_setuid_thread(uid_t uid)
+{
+ uid_t new_ruid = -1, new_euid = -1, new_suid = -1;
+ int rc;
+
+ rc = uwrap_setuid_args(uid, &new_ruid, &new_euid, &new_suid);
+ if (rc != 0) {
+ return rc;
+ }
+
+ return uwrap_setresuid_thread(new_ruid, new_euid, new_suid);
+}
+
+static int uwrap_setuid(uid_t uid)
+{
+ uid_t new_ruid = -1, new_euid = -1, new_suid = -1;
+ int rc;
+
+ rc = uwrap_setuid_args(uid, &new_ruid, &new_euid, &new_suid);
+ if (rc != 0) {
+ return rc;
+ }
+
+ return uwrap_setresuid(new_ruid, new_euid, new_suid);
+}
+
/*
* UWRAP_GETxUID FUNCTIONS
*/
@@ -1232,7 +1287,7 @@ int setuid(uid_t uid)
}
uwrap_init();
- return uwrap_setresuid(uid, -1, -1);
+ return uwrap_setuid(uid);
}
#ifdef HAVE_SETEUID
@@ -1728,7 +1783,7 @@ static long int uwrap_syscall (long int sysno, va_list vp)
{
uid_t uid = (uid_t) va_arg(vp, uid_t);
- rc = uwrap_setresuid_thread(uid, -1, -1);
+ rc = uwrap_setuid_thread(uid);
}
break;
case SYS_setreuid: