X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibsystemd%2Fsd-bus%2Fbus-creds.c;h=cd1c5e232ad07a35301d1302623605a658801761;hb=15411c0cb1192799b37ec8f25d6f30e8d7292fc6;hp=8aa53362fba038cf8b14512ac10e4443e40f38c9;hpb=e12d81ae80214ef05ddedafd016bdd604ce17d12;p=elogind.git diff --git a/src/libsystemd/sd-bus/bus-creds.c b/src/libsystemd/sd-bus/bus-creds.c index 8aa53362f..cd1c5e232 100644 --- a/src/libsystemd/sd-bus/bus-creds.c +++ b/src/libsystemd/sd-bus/bus-creds.c @@ -20,14 +20,15 @@ ***/ #include +#include #include "util.h" +#include "capability.h" #include "cgroup-util.h" #include "fileio.h" #include "audit.h" #include "bus-message.h" #include "bus-util.h" -#include "time-util.h" #include "strv.h" #include "bus-creds.h" #include "bus-label.h" @@ -50,9 +51,16 @@ void bus_creds_done(sd_bus_creds *c) { free(c->user_unit); free(c->slice); free(c->unescaped_description); + free(c->supplementary_gids); + + 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 +91,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,7 +101,15 @@ _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); + c->supplementary_gids = NULL; + + strv_free(c->well_known_names); + c->well_known_names = NULL; + + bus_creds_done(c); + free(c); } } else { @@ -132,7 +146,7 @@ _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t m int r; assert_return(pid >= 0, -EINVAL); - assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP); + assert_return(mask <= _SD_BUS_CREDS_ALL, -EOPNOTSUPP); assert_return(ret, -EINVAL); if (pid == 0) @@ -208,7 +222,7 @@ _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) { assert_return(c, -EINVAL); assert_return(gid, -EINVAL); - if (!(c->mask & SD_BUS_CREDS_UID)) + if (!(c->mask & SD_BUS_CREDS_GID)) return -ENODATA; *gid = c->gid; @@ -284,18 +298,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); @@ -541,6 +543,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; } @@ -568,13 +592,14 @@ static int has_cap(sd_bus_creds *c, unsigned offset, int capability) { size_t sz; assert(c); + assert(capability >= 0); assert(c->capability); - sz = c->capability_size / 4; - if ((size_t) capability >= sz*8) + sz = DIV_ROUND_UP(cap_last_cap(), 32U); + if ((unsigned)capability > cap_last_cap()) return 0; - return !!(c->capability[offset * sz + (capability / 8)] & (1 << (capability % 8))); + return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability)); } _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) { @@ -618,37 +643,43 @@ _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) { } static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) { - size_t sz; - unsigned i; + size_t sz, max; + unsigned i, j; assert(c); assert(p); + max = DIV_ROUND_UP(cap_last_cap(), 32U); p += strspn(p, WHITESPACE); sz = strlen(p); - if (sz % 2 != 0) + if (sz % 8 != 0) + return -EINVAL; + + sz /= 8; + if (sz > max) return -EINVAL; - sz /= 2; if (!c->capability) { - c->capability = new0(uint8_t, sz * 4); + c->capability = new0(uint32_t, max * 4); if (!c->capability) return -ENOMEM; - - c->capability_size = sz * 4; } for (i = 0; i < sz; i ++) { - int x, y; + uint32_t v = 0; - x = unhexchar(p[i*2]); - y = unhexchar(p[i*2+1]); + for (j = 0; j < 8; ++j) { + int t; - if (x < 0 || y < 0) - return -EINVAL; + t = unhexchar(*p++); + if (t < 0) + return -EINVAL; + + v = (v << 4) | t; + } - c->capability[offset * sz + (sz - i - 1)] = (uint8_t) x << 4 | (uint8_t) y; + c->capability[offset * max + (sz - i - 1)] = v; } return 0; @@ -827,19 +858,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; @@ -923,7 +941,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) { r = audit_session_from_pid(pid, &c->audit_session_id); if (r < 0) { - if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES) + if (r != -EOPNOTSUPP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES) return r; } else c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID; @@ -932,7 +950,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) { r = audit_loginuid_from_pid(pid, &c->audit_login_uid); if (r < 0) { - if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES) + if (r != -EOPNOTSUPP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES) return r; } else c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID; @@ -1020,11 +1038,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) @@ -1071,11 +1084,10 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) } if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) { - n->capability = memdup(c->capability, c->capability_size); + n->capability = memdup(c->capability, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4); if (!n->capability) return -ENOMEM; - n->capability_size = c->capability_size; 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); }