diff options
Diffstat (limited to 'src/libsystemd')
-rw-r--r-- | src/libsystemd/sd-bus/bus-control.c | 24 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-creds.c | 51 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-creds.h | 3 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-dump.c | 12 | ||||
-rw-r--r-- | src/libsystemd/sd-bus/bus-kernel.c | 26 |
5 files changed, 112 insertions, 4 deletions
diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c index 0027ad36c4..23fb0e7003 100644 --- a/src/libsystemd/sd-bus/bus-control.c +++ b/src/libsystemd/sd-bus/bus-control.c @@ -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; } } diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c index 02a73725c6..7a73387fb6 100644 --- a/src/libsystemd/sd-bus/bus-creds.c +++ b/src/libsystemd/sd-bus/bus-creds.c @@ -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; diff --git a/src/libsystemd/sd-bus/bus-creds.h b/src/libsystemd/sd-bus/bus-creds.h index 15821a57d2..882110bb69 100644 --- a/src/libsystemd/sd-bus/bus-creds.h +++ b/src/libsystemd/sd-bus/bus-creds.h @@ -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; diff --git a/src/libsystemd/sd-bus/bus-dump.c b/src/libsystemd/sd-bus/bus-dump.c index d6e5546053..2ddf016a95 100644 --- a/src/libsystemd/sd-bus/bus-dump.c +++ b/src/libsystemd/sd-bus/bus-dump.c @@ -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) diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index 79d29dc119..e66a263c48 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -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; } |