chiark / gitweb /
sd-bus: add supplementary groups list to creds object
authorLennart Poettering <lennart@poettering.net>
Tue, 25 Nov 2014 12:21:23 +0000 (13:21 +0100)
committerLennart Poettering <lennart@poettering.net>
Tue, 25 Nov 2014 13:28:34 +0000 (14:28 +0100)
src/libsystemd/sd-bus/bus-control.c
src/libsystemd/sd-bus/bus-creds.c
src/libsystemd/sd-bus/bus-creds.h
src/libsystemd/sd-bus/bus-dump.c
src/libsystemd/sd-bus/bus-kernel.c
src/systemd/sd-bus.h

index 0027ad3..23fb0e7 100644 (file)
@@ -500,7 +500,7 @@ static int bus_populate_creds_from_items(sd_bus *bus,
 
                 case KDBUS_ITEM_CMDLINE:
                         if (mask & SD_BUS_CREDS_CMDLINE) {
-                                c->cmdline_size = item->size - KDBUS_ITEM_HEADER_SIZE;
+                                c->cmdline_size = item->size - offsetof(struct kdbus_item, data);
                                 c->cmdline = memdup(item->data, c->cmdline_size);
                                 if (!c->cmdline)
                                         return -ENOMEM;
@@ -578,7 +578,7 @@ static int bus_populate_creds_from_items(sd_bus *bus,
                         break;
 
                 case KDBUS_ITEM_CONN_DESCRIPTION:
-                        if ((mask & SD_BUS_CREDS_DESCRIPTION)) {
+                        if (mask & SD_BUS_CREDS_DESCRIPTION) {
                                 c->description = strdup(item->str);
                                 if (!c->description)
                                         return -ENOMEM;
@@ -586,6 +586,26 @@ static int bus_populate_creds_from_items(sd_bus *bus,
                                 c->mask |= SD_BUS_CREDS_DESCRIPTION;
                         }
                         break;
+
+                case KDBUS_ITEM_AUXGROUPS:
+                        if (mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
+                                size_t i, n;
+                                uid_t *u;
+
+                                n = (item->size - offsetof(struct kdbus_item, data64)) / sizeof(uint64_t);
+                                u = new(uid_t, n);
+                                if (!u)
+                                        return -ENOMEM;
+
+                                for (i = 0; i < n; i++)
+                                        u[i] = (uid_t) item->data64[i];
+
+                                c->supplementary_gids = u;
+                                c->n_supplementary_gids = n;
+
+                                c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
+                        }
+                        break;
                 }
         }
 
index 02a7372..7a73387 100644 (file)
@@ -53,6 +53,8 @@ void bus_creds_done(sd_bus_creds *c) {
 
         strv_free(c->cmdline_array);
         strv_free(c->well_known_names);
+
+        free(c->supplementary_gids);
 }
 
 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
@@ -237,7 +239,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 +250,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);
@@ -680,6 +692,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 +749,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) {
@@ -962,6 +1003,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;
index 15821a5..882110b 100644 (file)
@@ -40,6 +40,9 @@ struct sd_bus_creds {
         gid_t sgid;
         gid_t fsgid;
 
+        gid_t *supplementary_gids;
+        unsigned n_supplementary_gids;
+
         pid_t pid;
         usec_t pid_starttime;
         pid_t tid;
index d6e5546..2ddf016 100644 (file)
@@ -384,8 +384,18 @@ int bus_creds_dump(sd_bus_creds *c, FILE *f, bool terse) {
         if (c->mask & SD_BUS_CREDS_FSGID)
                 fprintf(f, "%sFSGID=%s"GID_FMT"%s", prefix, color, c->fsgid, suffix);
 
+        if (c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
+                unsigned i;
+
+                fprintf(f, "%sSupplementaryGIDs=%s", prefix, color);
+                for (i = 0; i < c->n_supplementary_gids; i++)
+                        fprintf(f, "%s" GID_FMT, i > 0 ? " " : "", c->supplementary_gids[i]);
+                fprintf(f, "%s", suffix);
+        }
+
         if (terse && ((c->mask & (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)) || r >= 0))
+                                  SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
+                                  SD_BUS_CREDS_SUPPLEMENTARY_GIDS)) || r >= 0))
                 fputs("\n", f);
 
         if (c->mask & SD_BUS_CREDS_COMM)
index 79d29dc..e66a263 100644 (file)
@@ -660,6 +660,29 @@ static int bus_kernel_make_message(sd_bus *bus, struct kdbus_msg *k) {
                         m->creds.mask |= SD_BUS_CREDS_DESCRIPTION & bus->creds_mask;
                         break;
 
+                case KDBUS_ITEM_AUXGROUPS:
+
+                        if (bus->creds_mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
+                                size_t i, n;
+                                uid_t *u;
+                                n = (d->size - offsetof(struct kdbus_item, data64)) / sizeof(uint64_t);
+                                u = new(uid_t, n);
+                                if (!u) {
+                                        r = -ENOMEM;
+                                        goto fail;
+                                }
+
+                                for (i = 0; i < n; i++)
+                                        u[i] = (uid_t) d->data64[i];
+
+                                m->creds.supplementary_gids = u;
+                                m->creds.n_supplementary_gids = n;
+
+                                m->creds.mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
+                        }
+
+                        break;
+
                 case KDBUS_ITEM_FDS:
                 case KDBUS_ITEM_SECLABEL:
                         break;
@@ -1332,6 +1355,9 @@ int kdbus_translate_attach_flags(uint64_t mask, uint64_t *kdbus_mask) {
         if (mask & SD_BUS_CREDS_DESCRIPTION)
                 m |= KDBUS_ATTACH_CONN_DESCRIPTION;
 
+        if (mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS)
+                m |= KDBUS_ATTACH_AUXGROUPS;
+
         *kdbus_mask = m;
         return 0;
 }
index 21d693b..cb53a32 100644 (file)
@@ -49,39 +49,40 @@ typedef struct {
 /* Flags */
 
 enum {
-        SD_BUS_CREDS_PID              = 1ULL << 0,
-        SD_BUS_CREDS_PID_STARTTIME    = 1ULL << 1,
-        SD_BUS_CREDS_TID              = 1ULL << 2,
-        SD_BUS_CREDS_UID              = 1ULL << 3,
-        SD_BUS_CREDS_EUID             = 1ULL << 4,
-        SD_BUS_CREDS_SUID             = 1ULL << 5,
-        SD_BUS_CREDS_FSUID            = 1ULL << 6,
-        SD_BUS_CREDS_GID              = 1ULL << 7,
-        SD_BUS_CREDS_EGID             = 1ULL << 8,
-        SD_BUS_CREDS_SGID             = 1ULL << 9,
-        SD_BUS_CREDS_FSGID            = 1ULL << 10,
-        SD_BUS_CREDS_COMM             = 1ULL << 11,
-        SD_BUS_CREDS_TID_COMM         = 1ULL << 12,
-        SD_BUS_CREDS_EXE              = 1ULL << 13,
-        SD_BUS_CREDS_CMDLINE          = 1ULL << 14,
-        SD_BUS_CREDS_CGROUP           = 1ULL << 15,
-        SD_BUS_CREDS_UNIT             = 1ULL << 16,
-        SD_BUS_CREDS_USER_UNIT        = 1ULL << 17,
-        SD_BUS_CREDS_SLICE            = 1ULL << 18,
-        SD_BUS_CREDS_SESSION          = 1ULL << 19,
-        SD_BUS_CREDS_OWNER_UID        = 1ULL << 20,
-        SD_BUS_CREDS_EFFECTIVE_CAPS   = 1ULL << 21,
-        SD_BUS_CREDS_PERMITTED_CAPS   = 1ULL << 22,
-        SD_BUS_CREDS_INHERITABLE_CAPS = 1ULL << 23,
-        SD_BUS_CREDS_BOUNDING_CAPS    = 1ULL << 24,
-        SD_BUS_CREDS_SELINUX_CONTEXT  = 1ULL << 25,
-        SD_BUS_CREDS_AUDIT_SESSION_ID = 1ULL << 26,
-        SD_BUS_CREDS_AUDIT_LOGIN_UID  = 1ULL << 27,
-        SD_BUS_CREDS_UNIQUE_NAME      = 1ULL << 28,
-        SD_BUS_CREDS_WELL_KNOWN_NAMES = 1ULL << 29,
-        SD_BUS_CREDS_DESCRIPTION      = 1ULL << 30,
-        SD_BUS_CREDS_AUGMENT          = 1ULL << 63, /* special flag, if on sd-bus will augment creds struct, in a potentially race-full way. */
-        _SD_BUS_CREDS_ALL             = (1ULL << 31) -1,
+        SD_BUS_CREDS_PID                = 1ULL << 0,
+        SD_BUS_CREDS_PID_STARTTIME      = 1ULL << 1,
+        SD_BUS_CREDS_TID                = 1ULL << 2,
+        SD_BUS_CREDS_UID                = 1ULL << 3,
+        SD_BUS_CREDS_EUID               = 1ULL << 4,
+        SD_BUS_CREDS_SUID               = 1ULL << 5,
+        SD_BUS_CREDS_FSUID              = 1ULL << 6,
+        SD_BUS_CREDS_GID                = 1ULL << 7,
+        SD_BUS_CREDS_EGID               = 1ULL << 8,
+        SD_BUS_CREDS_SGID               = 1ULL << 9,
+        SD_BUS_CREDS_FSGID              = 1ULL << 10,
+        SD_BUS_CREDS_SUPPLEMENTARY_GIDS = 1ULL << 11,
+        SD_BUS_CREDS_COMM               = 1ULL << 12,
+        SD_BUS_CREDS_TID_COMM           = 1ULL << 13,
+        SD_BUS_CREDS_EXE                = 1ULL << 14,
+        SD_BUS_CREDS_CMDLINE            = 1ULL << 15,
+        SD_BUS_CREDS_CGROUP             = 1ULL << 16,
+        SD_BUS_CREDS_UNIT               = 1ULL << 17,
+        SD_BUS_CREDS_USER_UNIT          = 1ULL << 18,
+        SD_BUS_CREDS_SLICE              = 1ULL << 19,
+        SD_BUS_CREDS_SESSION            = 1ULL << 20,
+        SD_BUS_CREDS_OWNER_UID          = 1ULL << 21,
+        SD_BUS_CREDS_EFFECTIVE_CAPS     = 1ULL << 22,
+        SD_BUS_CREDS_PERMITTED_CAPS     = 1ULL << 23,
+        SD_BUS_CREDS_INHERITABLE_CAPS   = 1ULL << 24,
+        SD_BUS_CREDS_BOUNDING_CAPS      = 1ULL << 25,
+        SD_BUS_CREDS_SELINUX_CONTEXT    = 1ULL << 26,
+        SD_BUS_CREDS_AUDIT_SESSION_ID   = 1ULL << 27,
+        SD_BUS_CREDS_AUDIT_LOGIN_UID    = 1ULL << 28,
+        SD_BUS_CREDS_UNIQUE_NAME        = 1ULL << 29,
+        SD_BUS_CREDS_WELL_KNOWN_NAMES   = 1ULL << 30,
+        SD_BUS_CREDS_DESCRIPTION        = 1ULL << 31,
+        SD_BUS_CREDS_AUGMENT            = 1ULL << 63, /* special flag, if on sd-bus will augment creds struct, in a potentially race-full way. */
+        _SD_BUS_CREDS_ALL               = (1ULL << 32) -1,
 };
 
 enum {
@@ -319,6 +320,7 @@ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid);
 int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid);
 int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid);
 int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid);
+int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids);
 int sd_bus_creds_get_comm(sd_bus_creds *c, const char **comm);
 int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **comm);
 int sd_bus_creds_get_exe(sd_bus_creds *c, const char **exe);