X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibsystemd-bus%2Fbus-creds.c;h=b2cf687377ef2141e0fc4322132c0cd56bbbae1c;hp=454aeffb51a6d8d802e69326421d5fd26ee36151;hb=6206f4b49db2de55ee335d6108f474b715b21ae4;hpb=76037baee04c262f5d02a9c43ec9110c82196f36 diff --git a/src/libsystemd-bus/bus-creds.c b/src/libsystemd-bus/bus-creds.c index 454aeffb5..b2cf68737 100644 --- a/src/libsystemd-bus/bus-creds.c +++ b/src/libsystemd-bus/bus-creds.c @@ -28,6 +28,7 @@ #include "bus-message.h" #include "bus-util.h" #include "time-util.h" +#include "strv.h" #include "bus-creds.h" enum { @@ -48,7 +49,8 @@ void bus_creds_done(sd_bus_creds *c) { free(c->user_unit); free(c->slice); - free(c->cmdline_array); + strv_free(c->cmdline_array); + strv_free(c->well_known_names); } _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) { @@ -70,7 +72,9 @@ _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) { } _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) { - assert_return(c, NULL); + + if (!c) + return NULL; if (c->allocated) { assert(c->n_ref > 0); @@ -86,6 +90,8 @@ _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) { free(c->cgroup); free(c->capability); free(c->label); + free(c->unique_name); + free(c->cgroup_root); free(c); } } else { @@ -122,7 +128,7 @@ _public_ int sd_bus_creds_new_from_pid(pid_t pid, uint64_t mask, sd_bus_creds ** int r; assert_return(pid >= 0, -EINVAL); - assert_return(mask <= _SD_BUS_CREDS_MAX, -ENOTSUP); + assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP); assert_return(ret, -EINVAL); if (pid == 0) @@ -152,7 +158,9 @@ _public_ int sd_bus_creds_new_from_pid(pid_t pid, uint64_t mask, sd_bus_creds ** _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) { assert_return(c, -EINVAL); assert_return(uid, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_UID, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_UID)) + return -ENODATA; *uid = c->uid; return 0; @@ -161,7 +169,9 @@ _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) { _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) { assert_return(c, -EINVAL); assert_return(gid, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_UID, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_UID)) + return -ENODATA; *gid = c->gid; return 0; @@ -170,7 +180,9 @@ _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) { _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) { assert_return(c, -EINVAL); assert_return(pid, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_PID, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_PID)) + return -ENODATA; assert(c->pid > 0); *pid = c->pid; @@ -180,7 +192,9 @@ _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) { _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) { assert_return(c, -EINVAL); assert_return(tid, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_TID, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_TID)) + return -ENODATA; assert(c->tid > 0); *tid = c->tid; @@ -190,7 +204,9 @@ _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) { _public_ int sd_bus_creds_get_pid_starttime(sd_bus_creds *c, uint64_t *usec) { assert_return(c, -EINVAL); assert_return(usec, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_PID_STARTTIME, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_PID_STARTTIME)) + return -ENODATA; assert(c->pid_starttime > 0); *usec = c->pid_starttime; @@ -199,7 +215,9 @@ _public_ int sd_bus_creds_get_pid_starttime(sd_bus_creds *c, uint64_t *usec) { _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) { assert_return(c, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT)) + return -ENODATA; assert(c->label); *ret = c->label; @@ -209,7 +227,9 @@ _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) _public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) { assert_return(c, -EINVAL); assert_return(ret, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_COMM, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_COMM)) + return -ENODATA; assert(c->comm); *ret = c->comm; @@ -219,7 +239,9 @@ _public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) { _public_ int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **ret) { assert_return(c, -EINVAL); assert_return(ret, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_TID_COMM, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_TID_COMM)) + return -ENODATA; assert(c->tid_comm); *ret = c->tid_comm; @@ -229,7 +251,9 @@ _public_ int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **ret) { _public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) { assert_return(c, -EINVAL); assert_return(ret, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_EXE, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_EXE)) + return -ENODATA; assert(c->exe); *ret = c->exe; @@ -239,7 +263,9 @@ _public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) { _public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) { assert_return(c, -EINVAL); assert_return(ret, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_CGROUP, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_CGROUP)) + return -ENODATA; assert(c->cgroup); *ret = c->cgroup; @@ -251,12 +277,20 @@ _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) { assert_return(c, -EINVAL); assert_return(ret, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_UNIT, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_UNIT)) + return -ENODATA; assert(c->cgroup); if (!c->unit) { - r = cg_path_get_unit(c->cgroup, (char**) &c->unit); + const char *shifted; + + r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted); + if (r < 0) + return r; + + r = cg_path_get_unit(shifted, (char**) &c->unit); if (r < 0) return r; } @@ -270,12 +304,20 @@ _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) { assert_return(c, -EINVAL); assert_return(ret, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_USER_UNIT, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_USER_UNIT)) + return -ENODATA; assert(c->cgroup); if (!c->user_unit) { - r = cg_path_get_user_unit(c->cgroup, (char**) &c->user_unit); + const char *shifted; + + r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted); + if (r < 0) + return r; + + r = cg_path_get_user_unit(shifted, (char**) &c->user_unit); if (r < 0) return r; } @@ -289,12 +331,20 @@ _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) { assert_return(c, -EINVAL); assert_return(ret, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_SLICE, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_SLICE)) + return -ENODATA; assert(c->cgroup); if (!c->slice) { - r = cg_path_get_slice(c->cgroup, (char**) &c->slice); + const char *shifted; + + r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted); + if (r < 0) + return r; + + r = cg_path_get_slice(shifted, (char**) &c->slice); if (r < 0) return r; } @@ -308,12 +358,20 @@ _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) { assert_return(c, -EINVAL); assert_return(ret, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_SESSION, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_SESSION)) + return -ENODATA; assert(c->cgroup); if (!c->session) { - r = cg_path_get_session(c->cgroup, (char**) &c->session); + const char *shifted; + + r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted); + if (r < 0) + return r; + + r = cg_path_get_session(shifted, (char**) &c->session); if (r < 0) return r; } @@ -323,51 +381,49 @@ _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) { } _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) { + const char *shifted; + int r; + assert_return(c, -EINVAL); assert_return(uid, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_OWNER_UID, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_OWNER_UID)) + return -ENODATA; assert(c->cgroup); - return cg_path_get_owner_uid(c->cgroup, uid); + r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted); + if (r < 0) + return r; + + return cg_path_get_owner_uid(shifted, uid); } _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) { - size_t n, i; - const char *p; - bool first; - assert_return(c, -EINVAL); - assert_return(c->cmdline, -ESRCH); - assert_return(c->mask & SD_BUS_CREDS_CMDLINE, -ENODATA); - - assert(c->cmdline); - for (p = c->cmdline, n = 0; p < c->cmdline + c->cmdline_length; p++) - if (*p == 0) - n++; + if (!(c->mask & SD_BUS_CREDS_CMDLINE)) + return -ENODATA; - *(char***) &c->cmdline_array = new(char*, n + 1); - if (!c->cmdline_array) - return -ENOMEM; - - for (p = c->cmdline, i = 0, first = true; p < c->cmdline + c->cmdline_length; p++) { - if (first) - c->cmdline_array[i++] = (char*) p; + assert_return(c->cmdline, -ESRCH); + assert(c->cmdline); - first = *p == 0; + if (!c->cmdline_array) { + c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size); + if (!c->cmdline_array) + return -ENOMEM; } - c->cmdline_array[i] = NULL; *cmdline = c->cmdline_array; - return 0; } _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) { assert_return(c, -EINVAL); assert_return(sessionid, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID)) + return -ENODATA; *sessionid = c->audit_session_id; return 0; @@ -376,12 +432,36 @@ _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessio _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) { assert_return(c, -EINVAL); assert_return(uid, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID)) + return -ENODATA; *uid = c->audit_login_uid; return 0; } +_public_ int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **unique_name) { + assert_return(c, -EINVAL); + assert_return(unique_name, -EINVAL); + + if (!(c->mask & SD_BUS_CREDS_UNIQUE_NAME)) + return -ENODATA; + + *unique_name = c->unique_name; + return 0; +} + +_public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) { + assert_return(c, -EINVAL); + assert_return(well_known_names, -EINVAL); + + if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES)) + return -ENODATA; + + *well_known_names = c->well_known_names; + return 0; +} + static int has_cap(sd_bus_creds *c, unsigned offset, int capability) { size_t sz; @@ -398,7 +478,9 @@ static int has_cap(sd_bus_creds *c, unsigned offset, int capability) { _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) { assert_return(c, -EINVAL); assert_return(capability >= 0, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS)) + return -ENODATA; return has_cap(c, CAP_OFFSET_EFFECTIVE, capability); } @@ -406,7 +488,9 @@ _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) { _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) { assert_return(c, -EINVAL); assert_return(capability >= 0, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_PERMITTED_CAPS, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS)) + return -ENODATA; return has_cap(c, CAP_OFFSET_PERMITTED, capability); } @@ -414,7 +498,9 @@ _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) { _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) { assert_return(c, -EINVAL); assert_return(capability >= 0, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS)) + return -ENODATA; return has_cap(c, CAP_OFFSET_INHERITABLE, capability); } @@ -422,7 +508,9 @@ _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) { _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) { assert_return(c, -EINVAL); assert_return(capability >= 0, -EINVAL); - assert_return(c->mask & SD_BUS_CREDS_BOUNDING_CAPS, -ENODATA); + + if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS)) + return -ENODATA; return has_cap(c, CAP_OFFSET_BOUNDING, capability); } @@ -625,11 +713,11 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { const char *p; p = procfs_file_alloca(pid, "cmdline"); - r = read_full_file(p, &c->cmdline, &c->cmdline_length); + r = read_full_file(p, &c->cmdline, &c->cmdline_size); if (r < 0) return r; - if (c->cmdline_length == 0) { + if (c->cmdline_size == 0) { free(c->cmdline); c->cmdline = NULL; } else @@ -655,12 +743,16 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { if (r < 0) return r; + r = cg_get_root_path(&c->cgroup_root); + if (r < 0) + return r; + c->mask |= missing & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID); } if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) { r = audit_session_from_pid(pid, &c->audit_session_id); - if (r < 0 && r != -ENOTSUP && r != -ENXIO && r != ENOENT) + if (r < 0 && r != -ENOTSUP && r != -ENXIO && r != -ENOENT) return r; else if (r >= 0) c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID; @@ -668,7 +760,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 && r != -ENOTSUP && r != -ENXIO && r != ENOENT) + if (r < 0 && r != -ENOTSUP && r != -ENXIO && r != -ENOENT) return r; else if (r >= 0) c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID; @@ -677,12 +769,12 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { return 0; } -_public_ int sd_bus_creds_extend(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) { +int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) { _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL; int r; - assert_return(c, -EINVAL); - assert_return(ret, -EINVAL); + assert(c); + assert(ret); if ((mask & ~c->mask) == 0) { /* There's already all data we need. */ @@ -747,11 +839,11 @@ _public_ int sd_bus_creds_extend(sd_bus_creds *c, uint64_t mask, sd_bus_creds ** } if (c->mask & mask & SD_BUS_CREDS_CMDLINE) { - n->cmdline = memdup(c->cmdline, c->cmdline_length); + n->cmdline = memdup(c->cmdline, c->cmdline_size); if (!n->cmdline) return -ENOMEM; - n->cmdline_length = c->cmdline_length; + n->cmdline_size = c->cmdline_size; n->mask |= SD_BUS_CREDS_CMDLINE; } @@ -760,6 +852,10 @@ _public_ int sd_bus_creds_extend(sd_bus_creds *c, uint64_t mask, sd_bus_creds ** if (!n->cgroup) return -ENOMEM; + n->cgroup_root = strdup(c->cgroup_root); + if (!n->cgroup_root) + return -ENOMEM; + n->mask |= mask & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_OWNER_UID); } @@ -782,6 +878,18 @@ _public_ int sd_bus_creds_extend(sd_bus_creds *c, uint64_t mask, sd_bus_creds ** n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID; } + if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) { + n->unique_name = strdup(c->unique_name); + if (!n->unique_name) + return -ENOMEM; + } + + 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; + } + /* Get more data */ r = bus_creds_add_more(n, mask,