X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Flibelogind%2Fsd-bus%2Fbus-creds.c;h=4fccae5034406c277273df513602a4f625a79e17;hp=0f13d66508fe0771f0178ef86d3f87640d904e81;hb=d76bb3c179b7a32b109e39aa87ff09c8f5a8c178;hpb=3cabab2f099377b2e82a09c822a9f781a61b875b diff --git a/src/libelogind/sd-bus/bus-creds.c b/src/libelogind/sd-bus/bus-creds.c index 0f13d6650..4fccae503 100644 --- a/src/libelogind/sd-bus/bus-creds.c +++ b/src/libelogind/sd-bus/bus-creds.c @@ -24,6 +24,8 @@ #include "util.h" #include "formats-util.h" +#include "process-util.h" +#include "terminal-util.h" #include "capability.h" #include "cgroup-util.h" #include "fileio.h" @@ -51,8 +53,10 @@ void bus_creds_done(sd_bus_creds *c) { free(c->unit); free(c->user_unit); free(c->slice); + free(c->user_slice); free(c->unescaped_description); free(c->supplementary_gids); + free(c->tty); free(c->well_known_names); /* note that this is an strv, but * we only free the array, not the @@ -103,8 +107,7 @@ _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) { free(c->cgroup_root); free(c->description); - free(c->supplementary_gids); - c->supplementary_gids = NULL; + c->supplementary_gids = mfree(c->supplementary_gids); strv_free(c->well_known_names); c->well_known_names = NULL; @@ -124,11 +127,20 @@ _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) { return NULL; } +/// UNNEEDED by elogind +#if 0 _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) { assert_return(c, 0); return c->mask; } +#endif // 0 + +_public_ uint64_t sd_bus_creds_get_augmented_mask(const sd_bus_creds *c) { + assert_return(c, 0); + + return c->augmented; +} sd_bus_creds* bus_creds_new(void) { sd_bus_creds *c; @@ -142,6 +154,8 @@ sd_bus_creds* bus_creds_new(void) { return c; } +/// UNNEEDED by elogind +#if 0 _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) { sd_bus_creds *c; int r; @@ -173,6 +187,7 @@ _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t m *ret = c; return 0; } +#endif // 0 _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) { assert_return(c, -EINVAL); @@ -196,6 +211,8 @@ _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) { return 0; } +/// UNNEEDED by elogind +#if 0 _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) { assert_return(c, -EINVAL); assert_return(suid, -EINVAL); @@ -229,6 +246,7 @@ _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) { *gid = c->gid; return 0; } +#endif // 0 _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) { assert_return(c, -EINVAL); @@ -241,6 +259,8 @@ _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) { return 0; } +/// UNNEEDED by elogind +#if 0 _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) { assert_return(c, -EINVAL); assert_return(sgid, -EINVAL); @@ -273,6 +293,7 @@ _public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t ** *gids = c->supplementary_gids; return (int) c->n_supplementary_gids; } +#endif // 0 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) { assert_return(c, -EINVAL); @@ -286,6 +307,26 @@ _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) { return 0; } +/// UNNEEDED by elogind +#if 0 +_public_ int sd_bus_creds_get_ppid(sd_bus_creds *c, pid_t *ppid) { + assert_return(c, -EINVAL); + assert_return(ppid, -EINVAL); + + if (!(c->mask & SD_BUS_CREDS_PPID)) + return -ENODATA; + + /* PID 1 has no parent process. Let's distinguish the case of + * not knowing and not having a parent process by the returned + * error code. */ + if (c->ppid == 0) + return -ENXIO; + + *ppid = c->ppid; + return 0; +} +#endif // 0 + _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) { assert_return(c, -EINVAL); assert_return(tid, -EINVAL); @@ -309,6 +350,8 @@ _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) return 0; } +/// UNNEEDED by elogind +#if 0 _public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) { assert_return(c, -EINVAL); assert_return(ret, -EINVAL); @@ -340,7 +383,9 @@ _public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) { if (!(c->mask & SD_BUS_CREDS_EXE)) return -ENODATA; - assert(c->exe); + if (!c->exe) + return -ENXIO; + *ret = c->exe; return 0; } @@ -358,6 +403,8 @@ _public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) { } _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) { + int r; + assert_return(c, -EINVAL); assert_return(ret, -EINVAL); @@ -366,14 +413,25 @@ _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) { assert(c->cgroup); - if (!c->unit) - return -ESRCH; + if (!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; + } *ret = c->unit; return 0; } _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) { + int r; + assert_return(c, -EINVAL); assert_return(ret, -EINVAL); @@ -382,14 +440,25 @@ _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) { assert(c->cgroup); - if (!c->user_unit) - return -ESRCH; + if (!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; + } *ret = c->user_unit; return 0; } _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) { + int r; + assert_return(c, -EINVAL); assert_return(ret, -EINVAL); @@ -398,13 +467,50 @@ _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) { assert(c->cgroup); - if (!c->slice) - return -ESRCH; + if (!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; + } *ret = c->slice; return 0; } +_public_ int sd_bus_creds_get_user_slice(sd_bus_creds *c, const char **ret) { + int r; + + assert_return(c, -EINVAL); + assert_return(ret, -EINVAL); + + if (!(c->mask & SD_BUS_CREDS_USER_SLICE)) + return -ENODATA; + + assert(c->cgroup); + + if (!c->user_slice) { + const char *shifted; + + r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted); + if (r < 0) + return r; + + r = cg_path_get_user_slice(shifted, (char**) &c->user_slice); + if (r < 0) + return r; + } + + *ret = c->user_slice; + return 0; +} +#endif // 0 + _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) { int r; @@ -419,10 +525,13 @@ _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) { if (!c->session) { const char *shifted; + log_debug_elogind("Shifting cgroup \"%s\", root \"%s\"", + c->cgroup, c->cgroup_root ? c->cgroup_root : "NULL"); r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted); if (r < 0) return r; + log_debug_elogind("Shifted: \"%s\"", shifted); r = cg_path_get_session(shifted, (char**) &c->session); if (r < 0) return r; @@ -448,7 +557,13 @@ _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) { if (r < 0) return r; - return -ESRCH; +/// elogind does not support systemd slices +#if 0 + return cg_path_get_owner_uid(shifted, uid); +#else + *uid = c->uid; + return 0; +#endif // 0 } _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) { @@ -457,8 +572,8 @@ _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) { if (!(c->mask & SD_BUS_CREDS_CMDLINE)) return -ENODATA; - assert_return(c->cmdline, -ESRCH); - assert(c->cmdline); + if (!c->cmdline) + return -ENXIO; if (!c->cmdline_array) { c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size); @@ -477,6 +592,9 @@ _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessio if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID)) return -ENODATA; + if (c->audit_session_id == AUDIT_SESSION_INVALID) + return -ENXIO; + *sessionid = c->audit_session_id; return 0; } @@ -488,10 +606,29 @@ _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) { if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID)) return -ENODATA; + if (c->audit_login_uid == UID_INVALID) + return -ENXIO; + *uid = c->audit_login_uid; return 0; } +_public_ int sd_bus_creds_get_tty(sd_bus_creds *c, const char **ret) { + assert_return(c, -EINVAL); + assert_return(ret, -EINVAL); + + if (!(c->mask & SD_BUS_CREDS_TTY)) + return -ENODATA; + + if (!c->tty) + return -ENXIO; + + *ret = c->tty; + return 0; +} + +/// UNNEEDED by elogind +#if 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); @@ -554,6 +691,7 @@ _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) { *ret = c->unescaped_description; return 0; } +#endif // 0 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) { size_t sz; @@ -580,6 +718,8 @@ _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) { return has_cap(c, CAP_OFFSET_EFFECTIVE, capability); } +/// UNNEEDED by elogind +#if 0 _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) { assert_return(c, -EINVAL); assert_return(capability >= 0, -EINVAL); @@ -609,6 +749,7 @@ _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) { return has_cap(c, CAP_OFFSET_BOUNDING, capability); } +#endif // 0 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) { size_t sz, max; @@ -663,32 +804,32 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { if (!(mask & SD_BUS_CREDS_AUGMENT)) return 0; - missing = mask & ~c->mask; - if (missing == 0) - return 0; - /* Try to retrieve PID from creds if it wasn't passed to us */ - if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID)) + if (pid > 0) { + c->pid = pid; + c->mask |= SD_BUS_CREDS_PID; + } else if (c->mask & SD_BUS_CREDS_PID) pid = c->pid; + else + /* Without pid we cannot do much... */ + return 0; + /* Try to retrieve TID from creds if it wasn't passed to us */ if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID)) - tid = c->pid; + tid = c->tid; - /* Without pid we cannot do much... */ - if (pid <= 0) + /* Calculate what we shall and can add */ + missing = mask & ~(c->mask|SD_BUS_CREDS_PID|SD_BUS_CREDS_TID|SD_BUS_CREDS_UNIQUE_NAME|SD_BUS_CREDS_WELL_KNOWN_NAMES|SD_BUS_CREDS_DESCRIPTION|SD_BUS_CREDS_AUGMENT); + if (missing == 0) return 0; - if (pid > 0) { - c->pid = pid; - c->mask |= SD_BUS_CREDS_PID; - } - if (tid > 0) { c->tid = tid; c->mask |= SD_BUS_CREDS_TID; } - if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID | + if (missing & (SD_BUS_CREDS_PPID | + 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 | @@ -711,6 +852,25 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { FOREACH_LINE(line, f, return -errno) { truncate_nl(line); + if (missing & SD_BUS_CREDS_PPID) { + p = startswith(line, "PPid:"); + if (p) { + p += strspn(p, WHITESPACE); + + /* Explicitly check for PPID 0 (which is the case for PID 1) */ + if (!streq(p, "0")) { + r = parse_pid(p, &c->ppid); + if (r < 0) + return r; + + } else + c->ppid = 0; + + c->mask |= SD_BUS_CREDS_PPID; + continue; + } + } + if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) { p = startswith(line, "Uid:"); if (p) { @@ -859,7 +1019,17 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { if (missing & SD_BUS_CREDS_EXE) { r = get_process_exe(pid, &c->exe); - if (r < 0) { + if (r == -ESRCH) { + /* Unfortunately we cannot really distinguish + * the case here where the process does not + * exist, and /proc/$PID/exe being unreadable + * because $PID is a kernel thread. Hence, + * assume it is a kernel thread, and rely on + * that this case is caught with a later + * call. */ + c->exe = NULL; + c->mask |= SD_BUS_CREDS_EXE; + } else if (r < 0) { if (r != -EPERM && r != -EACCES) return r; } else @@ -871,17 +1041,17 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { p = procfs_file_alloca(pid, "cmdline"); r = read_full_file(p, &c->cmdline, &c->cmdline_size); + if (r == -ENOENT) + return -ESRCH; if (r < 0) { - if (r == -ENOENT) - return -ESRCH; if (r != -EPERM && r != -EACCES) return r; } else { if (c->cmdline_size == 0) { - free(c->cmdline); - c->cmdline = NULL; - } else - c->mask |= SD_BUS_CREDS_CMDLINE; + c->cmdline = mfree(c->cmdline); + } + + c->mask |= SD_BUS_CREDS_CMDLINE; } } @@ -892,16 +1062,16 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { return -ENOMEM; r = read_one_line_file(p, &c->tid_comm); + if (r == -ENOENT) + return -ESRCH; if (r < 0) { - if (r == -ENOENT) - return -ESRCH; if (r != -EPERM && r != -EACCES) return r; } else c->mask |= SD_BUS_CREDS_TID_COMM; } - if (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_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_USER_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID)) { if (!c->cgroup) { r = cg_pid_get_path(NULL, pid, &c->cgroup); @@ -918,13 +1088,17 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { } if (c->cgroup) - 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); + c->mask |= missing & (SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_USER_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) { - if (r != -EOPNOTSUPP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES) + if (r == -ENODATA) { + /* ENODATA means: no audit session id assigned */ + c->audit_session_id = AUDIT_SESSION_INVALID; + c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID; + } else if (r < 0) { + if (r != -EOPNOTSUPP && r != -ENOENT && r != -EPERM && r != -EACCES) return r; } else c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID; @@ -932,13 +1106,43 @@ 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 != -EOPNOTSUPP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES) + if (r == -ENODATA) { + /* ENODATA means: no audit login uid assigned */ + c->audit_login_uid = UID_INVALID; + c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID; + } else if (r < 0) { + if (r != -EOPNOTSUPP && r != -ENOENT && r != -EPERM && r != -EACCES) return r; } else c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID; } + if (missing & SD_BUS_CREDS_TTY) { + r = get_ctty(pid, NULL, &c->tty); + if (r == -ENXIO) { + /* ENXIO means: process has no controlling TTY */ + c->tty = NULL; + c->mask |= SD_BUS_CREDS_TTY; + } else if (r < 0) { + if (r != -EPERM && r != -EACCES && r != -ENOENT) + return r; + } else + c->mask |= SD_BUS_CREDS_TTY; + } + + /* In case only the exe path was to be read we cannot + * distinguish the case where the exe path was unreadable + * because the process was a kernel thread, or when the + * process didn't exist at all. Hence, let's do a final check, + * to be sure. */ + if (!pid_is_alive(pid)) + return -ESRCH; + + if (tid > 0 && tid != pid && !pid_is_unwaited(tid)) + return -ESRCH; + + c->augmented = missing & c->mask; + return 0; } @@ -973,6 +1177,11 @@ 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_PPID) { + n->ppid = c->ppid; + n->mask |= SD_BUS_CREDS_PPID; + } + if (c->mask & mask & SD_BUS_CREDS_UID) { n->uid = c->uid; n->mask |= SD_BUS_CREDS_UID; @@ -1014,14 +1223,22 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) } 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; + if (c->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; + } else { + n->supplementary_gids = NULL; + n->n_supplementary_gids = 0; + } + n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS; } if (c->mask & mask & SD_BUS_CREDS_COMM) { + assert(c->comm); + n->comm = strdup(c->comm); if (!n->comm) return -ENOMEM; @@ -1030,6 +1247,8 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) } if (c->mask & mask & SD_BUS_CREDS_TID_COMM) { + assert(c->tid_comm); + n->tid_comm = strdup(c->tid_comm); if (!n->tid_comm) return -ENOMEM; @@ -1038,23 +1257,34 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) } if (c->mask & mask & SD_BUS_CREDS_EXE) { - n->exe = strdup(c->exe); - if (!n->exe) - return -ENOMEM; + if (c->exe) { + n->exe = strdup(c->exe); + if (!n->exe) + return -ENOMEM; + } else + n->exe = NULL; n->mask |= SD_BUS_CREDS_EXE; } if (c->mask & mask & SD_BUS_CREDS_CMDLINE) { - n->cmdline = memdup(c->cmdline, c->cmdline_size); - if (!n->cmdline) - return -ENOMEM; + if (c->cmdline) { + n->cmdline = memdup(c->cmdline, c->cmdline_size); + if (!n->cmdline) + return -ENOMEM; + + n->cmdline_size = c->cmdline_size; + } else { + n->cmdline = NULL; + n->cmdline_size = 0; + } - n->cmdline_size = c->cmdline_size; n->mask |= SD_BUS_CREDS_CMDLINE; } - if (c->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)) { + if (c->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_USER_SLICE|SD_BUS_CREDS_OWNER_UID)) { + assert(c->cgroup); + n->cgroup = strdup(c->cgroup); if (!n->cgroup) return -ENOMEM; @@ -1063,10 +1293,12 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) 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); + 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_USER_SLICE|SD_BUS_CREDS_OWNER_UID); } if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) { + assert(c->capability); + n->capability = memdup(c->capability, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4); if (!n->capability) return -ENOMEM; @@ -1075,6 +1307,8 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) } if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) { + assert(c->label); + n->label = strdup(c->label); if (!n->label) return -ENOMEM; @@ -1090,7 +1324,19 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID; } + if (c->mask & mask & SD_BUS_CREDS_TTY) { + if (c->tty) { + n->tty = strdup(c->tty); + if (!n->tty) + return -ENOMEM; + } else + n->tty = NULL; + n->mask |= SD_BUS_CREDS_TTY; + } + if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) { + assert(c->unique_name); + n->unique_name = strdup(c->unique_name); if (!n->unique_name) return -ENOMEM; @@ -1098,26 +1344,31 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) } 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; + if (strv_isempty(c->well_known_names)) + n->well_known_names = NULL; + else { + n->well_known_names = strv_copy(c->well_known_names); + if (!n->well_known_names) + return -ENOMEM; + } n->well_known_names_driver = c->well_known_names_driver; n->well_known_names_local = c->well_known_names_local; n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES; } if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) { + assert(c->description); n->description = strdup(c->description); if (!n->description) return -ENOMEM; n->mask |= SD_BUS_CREDS_DESCRIPTION; } + n->augmented = c->augmented & n->mask; + /* Get more data */ - r = bus_creds_add_more(n, mask, - c->mask & SD_BUS_CREDS_PID ? c->pid : 0, - c->mask & SD_BUS_CREDS_TID ? c->tid : 0); + r = bus_creds_add_more(n, mask, 0, 0); if (r < 0) return r;