chiark / gitweb /
tests: clarify test_path_startswith return value (#4508)
[elogind.git] / src / basic / user-util.c
index 0d199cf..893790f 100644 (file)
@@ -463,9 +463,11 @@ int get_shell(char **_s) {
 #endif // 0
 
 int reset_uid_gid(void) {
+        int r;
 
-        if (setgroups(0, NULL) < 0)
-                return -errno;
+        r = maybe_setgroups(0, NULL);
+        if (r < 0)
+                return r;
 
         if (setresgid(0, 0, 0) < 0)
                 return -errno;
@@ -608,3 +610,32 @@ bool valid_home(const char *p) {
 
         return true;
 }
+
+int maybe_setgroups(size_t size, const gid_t *list) {
+        int r;
+
+        /* Check if setgroups is allowed before we try to drop all the auxiliary groups */
+        if (size == 0) { /* Dropping all aux groups? */
+                _cleanup_free_ char *setgroups_content = NULL;
+                bool can_setgroups;
+
+                r = read_one_line_file("/proc/self/setgroups", &setgroups_content);
+                if (r == -ENOENT)
+                        /* Old kernels don't have /proc/self/setgroups, so assume we can use setgroups */
+                        can_setgroups = true;
+                else if (r < 0)
+                        return r;
+                else
+                        can_setgroups = streq(setgroups_content, "allow");
+
+                if (!can_setgroups) {
+                        log_debug("Skipping setgroups(), /proc/self/setgroups is set to 'deny'");
+                        return 0;
+                }
+        }
+
+        if (setgroups(size, list) < 0)
+                return -errno;
+
+        return 0;
+}