chiark / gitweb /
util: introduce our own gperf based capability list
[elogind.git] / src / libsystemd / sd-bus / bus-creds.c
index 02a73725c65fdfbafee427d8ea4e65fe6bdd1c7c..9978ddfa3836918417185d7361798f8549d914ad 100644 (file)
@@ -51,8 +51,14 @@ void bus_creds_done(sd_bus_creds *c) {
         free(c->slice);
         free(c->unescaped_description);
 
+        free(c->well_known_names); /* note that this is an strv, but
+                                    * we only free the array, not the
+                                    * strings the array points to. The
+                                    * full strv we only free if
+                                    * c->allocated is set, see
+                                    * below. */
+
         strv_free(c->cmdline_array);
-        strv_free(c->well_known_names);
 }
 
 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
@@ -83,8 +89,6 @@ _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
                 c->n_ref--;
 
                 if (c->n_ref == 0) {
-                        bus_creds_done(c);
-
                         free(c->comm);
                         free(c->tid_comm);
                         free(c->exe);
@@ -95,6 +99,13 @@ _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
                         free(c->unique_name);
                         free(c->cgroup_root);
                         free(c->description);
+                        free(c->supplementary_gids);
+
+                        strv_free(c->well_known_names);
+                        c->well_known_names = NULL;
+
+                        bus_creds_done(c);
+
                         free(c);
                 }
         } else {
@@ -237,7 +248,6 @@ _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
         return 0;
 }
 
-
 _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
         assert_return(c, -EINVAL);
         assert_return(fsgid, -EINVAL);
@@ -249,6 +259,17 @@ _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
         return 0;
 }
 
+_public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) {
+        assert_return(c, -EINVAL);
+        assert_return(gids, -EINVAL);
+
+        if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
+                return -ENODATA;
+
+        *gids = c->supplementary_gids;
+        return (int) c->n_supplementary_gids;
+}
+
 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
         assert_return(c, -EINVAL);
         assert_return(pid, -EINVAL);
@@ -273,18 +294,6 @@ _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) {
         return 0;
 }
 
-_public_ int sd_bus_creds_get_pid_starttime(sd_bus_creds *c, uint64_t *usec) {
-        assert_return(c, -EINVAL);
-        assert_return(usec, -EINVAL);
-
-        if (!(c->mask & SD_BUS_CREDS_PID_STARTTIME))
-                return -ENODATA;
-
-        assert(c->pid_starttime > 0);
-        *usec = c->pid_starttime;
-        return 0;
-}
-
 _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
         assert_return(c, -EINVAL);
 
@@ -530,6 +539,28 @@ _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_kno
         if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
                 return -ENODATA;
 
+        /* As a special hack we return the bus driver as well-known
+         * names list when this is requested. */
+        if (c->well_known_names_driver) {
+                static const char* const wkn[] = {
+                        "org.freedesktop.DBus",
+                        NULL
+                };
+
+                *well_known_names = (char**) wkn;
+                return 0;
+        }
+
+        if (c->well_known_names_local) {
+                static const char* const wkn[] = {
+                        "org.freedesktop.DBus.Local",
+                        NULL
+                };
+
+                *well_known_names = (char**) wkn;
+                return 0;
+        }
+
         *well_known_names = c->well_known_names;
         return 0;
 }
@@ -680,6 +711,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
 
         if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
                        SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
+                       SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
                        SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
                        SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
 
@@ -736,6 +768,34 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
                                         }
                                 }
 
+                                if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
+                                        p = startswith(line, "Groups:");
+                                        if (p) {
+                                                size_t allocated = 0;
+
+                                                for (;;) {
+                                                        unsigned long g;
+                                                        int n = 0;
+
+                                                        p += strspn(p, WHITESPACE);
+                                                        if (*p == 0)
+                                                                break;
+
+                                                        if (sscanf(p, "%lu%n", &g, &n) != 1)
+                                                                return -EIO;
+
+                                                        if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
+                                                                return -ENOMEM;
+
+                                                        c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
+                                                        p += n;
+                                                }
+
+                                                c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
+                                                continue;
+                                        }
+                                }
+
                                 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
                                         p = startswith(line, "CapEff:");
                                         if (p) {
@@ -787,19 +847,6 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
                 }
         }
 
-        if (missing & (SD_BUS_CREDS_PID_STARTTIME)) {
-                unsigned long long st;
-
-                r = get_starttime_of_pid(pid, &st);
-                if (r < 0) {
-                        if (r != -EPERM && r != -EACCES)
-                                return r;
-                } else {
-                        c->pid_starttime = ((usec_t) st * USEC_PER_SEC) / (usec_t) sysconf(_SC_CLK_TCK);
-                        c->mask |= SD_BUS_CREDS_PID_STARTTIME;
-                }
-        }
-
         if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
                 const char *p;
 
@@ -962,6 +1009,14 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret)
                 n->mask |= SD_BUS_CREDS_FSGID;
         }
 
+        if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
+                n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
+                if (!n->supplementary_gids)
+                        return -ENOMEM;
+                n->n_supplementary_gids = c->n_supplementary_gids;
+                n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
+        }
+
         if (c->mask & mask & SD_BUS_CREDS_PID) {
                 n->pid = c->pid;
                 n->mask |= SD_BUS_CREDS_PID;
@@ -972,11 +1027,6 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret)
                 n->mask |= SD_BUS_CREDS_TID;
         }
 
-        if (c->mask & mask & SD_BUS_CREDS_PID_STARTTIME) {
-                n->pid_starttime = c->pid_starttime;
-                n->mask |= SD_BUS_CREDS_PID_STARTTIME;
-        }
-
         if (c->mask & mask & SD_BUS_CREDS_COMM) {
                 n->comm = strdup(c->comm);
                 if (!n->comm)
@@ -1031,11 +1081,17 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret)
                 n->mask |= c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS);
         }
 
+        if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
+                n->label = strdup(c->label);
+                if (!n->label)
+                        return -ENOMEM;
+                n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
+        }
+
         if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
                 n->audit_session_id = c->audit_session_id;
                 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
         }
-
         if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
                 n->audit_login_uid = c->audit_login_uid;
                 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
@@ -1045,12 +1101,21 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret)
                 n->unique_name = strdup(c->unique_name);
                 if (!n->unique_name)
                         return -ENOMEM;
+                n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
         }
 
         if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
                 n->well_known_names = strv_copy(c->well_known_names);
                 if (!n->well_known_names)
                         return -ENOMEM;
+                n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
+        }
+
+        if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
+                n->description = strdup(c->description);
+                if (!n->description)
+                        return -ENOMEM;
+                n->mask |= SD_BUS_CREDS_DESCRIPTION;
         }
 
         /* Get more data */