X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-bus%2Fbus-creds.c;h=886e212fbfbeb4b8ef5eaf89d5bbfc45a4c19559;hb=412c18f10c9df3f0a02358d8c0e707ed2e5fa186;hp=02a73725c65fdfbafee427d8ea4e65fe6bdd1c7c;hpb=705a415f684f8e9ee19983e5859de00bbb1477cb;p=elogind.git diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c index 02a73725c..886e212fb 100644 --- a/src/libsystemd/sd-bus/bus-creds.c +++ b/src/libsystemd/sd-bus/bus-creds.c @@ -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); @@ -530,6 +551,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 +723,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 +780,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 +1034,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; @@ -1031,11 +1111,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 +1131,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 */