X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibelogind%2Fsd-bus%2Fbus-creds.c;h=3cb996171ec78d529a286e44edcd57a565fb69cc;hb=ec82d020534270d1979da2d0b27f84e1846b2851;hp=ab48aafccc8653adb4aa7091e5265f27fd0519d8;hpb=c16e820c0af4ce234a53c72789248c3dc8c4d69d;p=elogind.git diff --git a/src/libelogind/sd-bus/bus-creds.c b/src/libelogind/sd-bus/bus-creds.c index ab48aafcc..3cb996171 100644 --- a/src/libelogind/sd-bus/bus-creds.c +++ b/src/libelogind/sd-bus/bus-creds.c @@ -1,5 +1,3 @@ -/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ - /*** This file is part of systemd. @@ -19,20 +17,28 @@ along with systemd; If not, see . ***/ -#include #include +#include -#include "util.h" -#include "formats-util.h" -#include "capability.h" -#include "cgroup-util.h" -#include "fileio.h" -#include "audit.h" +#include "alloc-util.h" +#include "audit-util.h" +#include "bus-creds.h" +#include "bus-label.h" #include "bus-message.h" #include "bus-util.h" +#include "capability-util.h" +#include "cgroup-util.h" +#include "fd-util.h" +#include "fileio.h" +#include "format-util.h" +#include "hexdecoct.h" +#include "parse-util.h" +#include "process-util.h" +#include "string-util.h" #include "strv.h" -#include "bus-creds.h" -#include "bus-label.h" +#include "terminal-util.h" +#include "user-util.h" +#include "util.h" enum { CAP_OFFSET_INHERITABLE = 0, @@ -51,8 +57,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 @@ -65,7 +73,9 @@ void bus_creds_done(sd_bus_creds *c) { } _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) { - assert_return(c, NULL); + + if (!c) + return NULL; if (c->allocated) { assert(c->n_ref > 0); @@ -103,11 +113,9 @@ _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; + c->well_known_names = strv_free(c->well_known_names); bus_creds_done(c); @@ -124,11 +132,13 @@ _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) { return NULL; } +#if 0 /// UNNEEDED by elogind _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); @@ -148,6 +158,7 @@ sd_bus_creds* bus_creds_new(void) { return c; } +#if 0 /// UNNEEDED by elogind _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) { sd_bus_creds *c; int r; @@ -179,6 +190,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); @@ -202,6 +214,7 @@ _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) { return 0; } +#if 0 /// UNNEEDED by elogind _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) { assert_return(c, -EINVAL); assert_return(suid, -EINVAL); @@ -235,6 +248,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); @@ -247,6 +261,7 @@ _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) { return 0; } +#if 0 /// UNNEEDED by elogind _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) { assert_return(c, -EINVAL); assert_return(sgid, -EINVAL); @@ -279,6 +294,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); @@ -292,6 +308,7 @@ _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) { return 0; } +#if 0 /// UNNEEDED by elogind _public_ int sd_bus_creds_get_ppid(sd_bus_creds *c, pid_t *ppid) { assert_return(c, -EINVAL); assert_return(ppid, -EINVAL); @@ -299,9 +316,16 @@ _public_ int sd_bus_creds_get_ppid(sd_bus_creds *c, pid_t *ppid) { 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); @@ -326,6 +350,7 @@ _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) return 0; } +#if 0 /// UNNEEDED by elogind _public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) { assert_return(c, -EINVAL); assert_return(ret, -EINVAL); @@ -357,7 +382,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; } @@ -375,6 +402,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); @@ -383,14 +412,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); @@ -399,14 +439,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); @@ -415,13 +466,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; @@ -436,10 +524,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; @@ -465,7 +556,12 @@ _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) { if (r < 0) return r; - return -ESRCH; +#if 0 /// elogind does not support systemd slices + 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) { @@ -474,8 +570,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); @@ -494,6 +590,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; } @@ -505,10 +604,28 @@ _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; +} + +#if 0 /// UNNEEDED by elogind _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); @@ -571,6 +688,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; @@ -597,6 +715,7 @@ _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) { return has_cap(c, CAP_OFFSET_EFFECTIVE, capability); } +#if 0 /// UNNEEDED by elogind _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) { assert_return(c, -EINVAL); assert_return(capability >= 0, -EINVAL); @@ -626,6 +745,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; @@ -681,11 +801,13 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { 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; - - /* Without pid we cannot do much... */ - if (pid <= 0) + else + /* Without pid we cannot do much... */ return 0; /* Try to retrieve TID from creds if it wasn't passed to us */ @@ -697,9 +819,6 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { if (missing == 0) return 0; - c->pid = pid; - c->mask |= SD_BUS_CREDS_PID; - if (tid > 0) { c->tid = tid; c->mask |= SD_BUS_CREDS_TID; @@ -734,9 +853,14 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { if (p) { p += strspn(p, WHITESPACE); - r = parse_pid(p, &c->ppid); - if (r < 0) - return r; + /* 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; @@ -891,7 +1015,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 @@ -903,17 +1037,16 @@ 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; + if (c->cmdline_size == 0) + c->cmdline = mfree(c->cmdline); + + c->mask |= SD_BUS_CREDS_CMDLINE; } } @@ -924,16 +1057,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); @@ -950,13 +1083,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; @@ -964,20 +1101,48 @@ 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; } 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; + _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *n = NULL; int r; assert(c); @@ -1053,14 +1218,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; @@ -1069,6 +1242,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; @@ -1077,23 +1252,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; @@ -1102,10 +1288,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; @@ -1114,6 +1302,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; @@ -1129,7 +1319,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; @@ -1137,15 +1339,20 @@ 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;