From: Lennart Poettering Date: Tue, 25 Nov 2014 12:21:23 +0000 (+0100) Subject: sd-bus: add supplementary groups list to creds object X-Git-Tag: v218~362 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=0258159049d5b381c6097533a69a1b29c3ba7ce2 sd-bus: add supplementary groups list to creds object --- diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c index 0027ad36c..23fb0e700 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 02a73725c..7a73387fb 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 15821a57d..882110bb6 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 d6e554605..2ddf016a9 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 79d29dc11..e66a263c4 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; } diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h index 21d693b4b..cb53a323c 100644 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -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);