X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Flibelogind%2Fsd-bus%2Fbus-creds.c;h=90e37569886adb837a344c18973099931204845b;hb=94c5f7fa9e34517edad75cd63d71dd459ec4f133;hp=44fad0be094e07856d11f6b0b5bbacd90b9251b3;hpb=011da473952eb8c7be67e8238f381fc87d50eb58;p=elogind.git diff --git a/src/libelogind/sd-bus/bus-creds.c b/src/libelogind/sd-bus/bus-creds.c index 44fad0be0..90e375698 100644 --- a/src/libelogind/sd-bus/bus-creds.c +++ b/src/libelogind/sd-bus/bus-creds.c @@ -19,22 +19,28 @@ along with systemd; If not, see . ***/ -#include #include +#include -#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" -#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 "formats-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, @@ -53,6 +59,7 @@ 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); @@ -106,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); @@ -127,11 +132,14 @@ _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); @@ -151,6 +159,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; @@ -182,6 +192,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); @@ -205,6 +216,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); @@ -238,6 +251,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); @@ -250,6 +264,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); @@ -282,6 +298,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); @@ -295,6 +312,8 @@ _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); @@ -302,7 +321,7 @@ _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 distuingish the case of + /* 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) @@ -311,6 +330,7 @@ _public_ int sd_bus_creds_get_ppid(sd_bus_creds *c, pid_t *ppid) { *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); @@ -335,6 +355,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); @@ -386,6 +408,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); @@ -394,14 +418,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); @@ -410,14 +445,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); @@ -426,13 +472,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; @@ -447,10 +530,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; @@ -476,7 +562,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) { @@ -540,6 +632,8 @@ _public_ int sd_bus_creds_get_tty(sd_bus_creds *c, const char **ret) { 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); @@ -602,6 +696,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; @@ -628,6 +723,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); @@ -657,6 +754,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; @@ -712,11 +810,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 */ @@ -728,9 +828,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; @@ -928,7 +1025,7 @@ 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 == -ESRCH) { - /* Unfortunately we cannot really distuingish + /* 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, @@ -955,10 +1052,8 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { if (r != -EPERM && r != -EACCES) return r; } else { - if (c->cmdline_size == 0) { - free(c->cmdline); - c->cmdline = NULL; - } + if (c->cmdline_size == 0) + c->cmdline = mfree(c->cmdline); c->mask |= SD_BUS_CREDS_CMDLINE; } @@ -980,7 +1075,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { 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); @@ -997,13 +1092,13 @@ 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 == -ENXIO) { - /* ENXIO means: no audit session id assigned */ + 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) { @@ -1015,8 +1110,8 @@ 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 == -ENXIO) { - /* ENXIO means: no audit login uid assigned */ + 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) { @@ -1040,7 +1135,7 @@ int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) { } /* In case only the exe path was to be read we cannot - * distuingish the case where the exe path was unreadable + * 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. */ @@ -1191,7 +1286,7 @@ int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) 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); @@ -1202,7 +1297,7 @@ 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)) {