1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2013 Lennart Poettering
8 #include <linux/capability.h>
11 #include "alloc-util.h"
12 #include "audit-util.h"
13 #include "bus-creds.h"
14 #include "bus-label.h"
15 #include "bus-message.h"
17 #include "capability-util.h"
18 #include "cgroup-util.h"
21 #include "format-util.h"
22 #include "hexdecoct.h"
23 #include "parse-util.h"
24 #include "process-util.h"
25 #include "string-util.h"
27 #include "terminal-util.h"
28 #include "user-util.h"
32 CAP_OFFSET_INHERITABLE = 0,
33 CAP_OFFSET_PERMITTED = 1,
34 CAP_OFFSET_EFFECTIVE = 2,
35 CAP_OFFSET_BOUNDING = 3
38 void bus_creds_done(sd_bus_creds *c) {
41 /* For internal bus cred structures that are allocated by
49 free(c->unescaped_description);
50 free(c->supplementary_gids);
53 free(c->well_known_names); /* note that this is an strv, but
54 * we only free the array, not the
55 * strings the array points to. The
56 * full strv we only free if
57 * c->allocated is set, see
60 strv_free(c->cmdline_array);
63 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
74 /* If this is an embedded creds structure, then
75 * forward ref counting to the message */
76 m = container_of(c, sd_bus_message, creds);
77 sd_bus_message_ref(m);
83 _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
100 free(c->unique_name);
101 free(c->cgroup_root);
102 free(c->description);
104 c->supplementary_gids = mfree(c->supplementary_gids);
106 c->well_known_names = strv_free(c->well_known_names);
115 m = container_of(c, sd_bus_message, creds);
116 sd_bus_message_unref(m);
123 _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
129 _public_ uint64_t sd_bus_creds_get_augmented_mask(const sd_bus_creds *c) {
135 sd_bus_creds* bus_creds_new(void) {
138 c = new0(sd_bus_creds, 1);
147 _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
151 assert_return(pid >= 0, -EINVAL);
152 assert_return(mask <= _SD_BUS_CREDS_ALL, -EOPNOTSUPP);
153 assert_return(ret, -EINVAL);
156 pid = getpid_cached();
162 r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
164 sd_bus_creds_unref(c);
168 /* Check if the process existed at all, in case we haven't
169 * figured that out already */
170 if (!pid_is_alive(pid)) {
171 sd_bus_creds_unref(c);
179 _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) {
180 assert_return(c, -EINVAL);
181 assert_return(uid, -EINVAL);
183 if (!(c->mask & SD_BUS_CREDS_UID))
190 _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) {
191 assert_return(c, -EINVAL);
192 assert_return(euid, -EINVAL);
194 if (!(c->mask & SD_BUS_CREDS_EUID))
201 _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) {
202 assert_return(c, -EINVAL);
203 assert_return(suid, -EINVAL);
205 if (!(c->mask & SD_BUS_CREDS_SUID))
213 _public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) {
214 assert_return(c, -EINVAL);
215 assert_return(fsuid, -EINVAL);
217 if (!(c->mask & SD_BUS_CREDS_FSUID))
224 _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
225 assert_return(c, -EINVAL);
226 assert_return(gid, -EINVAL);
228 if (!(c->mask & SD_BUS_CREDS_GID))
235 _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) {
236 assert_return(c, -EINVAL);
237 assert_return(egid, -EINVAL);
239 if (!(c->mask & SD_BUS_CREDS_EGID))
246 _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
247 assert_return(c, -EINVAL);
248 assert_return(sgid, -EINVAL);
250 if (!(c->mask & SD_BUS_CREDS_SGID))
257 _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
258 assert_return(c, -EINVAL);
259 assert_return(fsgid, -EINVAL);
261 if (!(c->mask & SD_BUS_CREDS_FSGID))
268 _public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) {
269 assert_return(c, -EINVAL);
270 assert_return(gids, -EINVAL);
272 if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
275 *gids = c->supplementary_gids;
276 return (int) c->n_supplementary_gids;
279 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
280 assert_return(c, -EINVAL);
281 assert_return(pid, -EINVAL);
283 if (!(c->mask & SD_BUS_CREDS_PID))
291 _public_ int sd_bus_creds_get_ppid(sd_bus_creds *c, pid_t *ppid) {
292 assert_return(c, -EINVAL);
293 assert_return(ppid, -EINVAL);
295 if (!(c->mask & SD_BUS_CREDS_PPID))
298 /* PID 1 has no parent process. Let's distinguish the case of
299 * not knowing and not having a parent process by the returned
308 _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) {
309 assert_return(c, -EINVAL);
310 assert_return(tid, -EINVAL);
312 if (!(c->mask & SD_BUS_CREDS_TID))
320 _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
321 assert_return(c, -EINVAL);
323 if (!(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT))
331 _public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) {
332 assert_return(c, -EINVAL);
333 assert_return(ret, -EINVAL);
335 if (!(c->mask & SD_BUS_CREDS_COMM))
343 _public_ int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **ret) {
344 assert_return(c, -EINVAL);
345 assert_return(ret, -EINVAL);
347 if (!(c->mask & SD_BUS_CREDS_TID_COMM))
355 _public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) {
356 assert_return(c, -EINVAL);
357 assert_return(ret, -EINVAL);
359 if (!(c->mask & SD_BUS_CREDS_EXE))
369 _public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) {
370 assert_return(c, -EINVAL);
371 assert_return(ret, -EINVAL);
373 if (!(c->mask & SD_BUS_CREDS_CGROUP))
381 #if 0 /// UNNEEDED by elogind
382 _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {
385 assert_return(c, -EINVAL);
386 assert_return(ret, -EINVAL);
388 if (!(c->mask & SD_BUS_CREDS_UNIT))
396 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
400 r = cg_path_get_unit(shifted, (char**) &c->unit);
409 _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
412 assert_return(c, -EINVAL);
413 assert_return(ret, -EINVAL);
415 if (!(c->mask & SD_BUS_CREDS_USER_UNIT))
423 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
427 r = cg_path_get_user_unit(shifted, (char**) &c->user_unit);
437 _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
440 assert_return(c, -EINVAL);
441 assert_return(ret, -EINVAL);
443 if (!(c->mask & SD_BUS_CREDS_SLICE))
451 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
455 r = cg_path_get_slice(shifted, (char**) &c->slice);
464 _public_ int sd_bus_creds_get_user_slice(sd_bus_creds *c, const char **ret) {
467 assert_return(c, -EINVAL);
468 assert_return(ret, -EINVAL);
470 if (!(c->mask & SD_BUS_CREDS_USER_SLICE))
475 if (!c->user_slice) {
478 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
482 r = cg_path_get_user_slice(shifted, (char**) &c->user_slice);
487 *ret = c->user_slice;
491 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
494 assert_return(c, -EINVAL);
495 assert_return(ret, -EINVAL);
497 if (!(c->mask & SD_BUS_CREDS_SESSION))
505 log_debug_elogind("Shifting cgroup \"%s\", root \"%s\"",
506 c->cgroup, c->cgroup_root ? c->cgroup_root : "NULL");
507 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
511 log_debug_elogind("Shifted: \"%s\"", shifted);
512 r = cg_path_get_session(shifted, (char**) &c->session);
521 _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
525 assert_return(c, -EINVAL);
526 assert_return(uid, -EINVAL);
528 if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
533 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
534 log_debug_elogind("Shifted to %s from %s/%s for c->uid %u (result %d)",
535 shifted, c->cgroup_root, c->cgroup, c->uid, r);
539 return cg_path_get_owner_uid(shifted, uid);
542 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
543 assert_return(c, -EINVAL);
545 if (!(c->mask & SD_BUS_CREDS_CMDLINE))
551 if (!c->cmdline_array) {
552 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
553 if (!c->cmdline_array)
557 *cmdline = c->cmdline_array;
561 _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
562 assert_return(c, -EINVAL);
563 assert_return(sessionid, -EINVAL);
565 if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
568 if (!audit_session_is_valid(c->audit_session_id))
571 *sessionid = c->audit_session_id;
575 _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
576 assert_return(c, -EINVAL);
577 assert_return(uid, -EINVAL);
579 if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID))
582 if (!uid_is_valid(c->audit_login_uid))
585 *uid = c->audit_login_uid;
589 _public_ int sd_bus_creds_get_tty(sd_bus_creds *c, const char **ret) {
590 assert_return(c, -EINVAL);
591 assert_return(ret, -EINVAL);
593 if (!(c->mask & SD_BUS_CREDS_TTY))
603 _public_ int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **unique_name) {
604 assert_return(c, -EINVAL);
605 assert_return(unique_name, -EINVAL);
607 if (!(c->mask & SD_BUS_CREDS_UNIQUE_NAME))
610 *unique_name = c->unique_name;
614 _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) {
615 assert_return(c, -EINVAL);
616 assert_return(well_known_names, -EINVAL);
618 if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
621 /* As a special hack we return the bus driver as well-known
622 * names list when this is requested. */
623 if (c->well_known_names_driver) {
624 static const char* const wkn[] = {
625 "org.freedesktop.DBus",
629 *well_known_names = (char**) wkn;
633 if (c->well_known_names_local) {
634 static const char* const wkn[] = {
635 "org.freedesktop.DBus.Local",
639 *well_known_names = (char**) wkn;
643 *well_known_names = c->well_known_names;
647 _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) {
648 assert_return(c, -EINVAL);
649 assert_return(ret, -EINVAL);
651 if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
654 assert(c->description);
656 if (!c->unescaped_description) {
657 c->unescaped_description = bus_label_unescape(c->description);
658 if (!c->unescaped_description)
662 *ret = c->unescaped_description;
666 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
670 assert(capability >= 0);
671 assert(c->capability);
673 if ((unsigned) capability > cap_last_cap())
676 sz = DIV_ROUND_UP(cap_last_cap(), 32U);
678 return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability));
681 _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
682 assert_return(c, -EINVAL);
683 assert_return(capability >= 0, -EINVAL);
685 if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS))
688 return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
691 _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
692 assert_return(c, -EINVAL);
693 assert_return(capability >= 0, -EINVAL);
695 if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS))
698 return has_cap(c, CAP_OFFSET_PERMITTED, capability);
701 _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
702 assert_return(c, -EINVAL);
703 assert_return(capability >= 0, -EINVAL);
705 if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS))
708 return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
711 _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) {
712 assert_return(c, -EINVAL);
713 assert_return(capability >= 0, -EINVAL);
715 if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS))
718 return has_cap(c, CAP_OFFSET_BOUNDING, capability);
721 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
728 max = DIV_ROUND_UP(cap_last_cap(), 32U);
729 p += strspn(p, WHITESPACE);
739 if (!c->capability) {
740 c->capability = new0(uint32_t, max * 4);
745 for (i = 0; i < sz; i ++) {
748 for (j = 0; j < 8; ++j) {
758 c->capability[offset * max + (sz - i - 1)] = v;
764 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
769 assert(c->allocated);
771 if (!(mask & SD_BUS_CREDS_AUGMENT))
774 /* Try to retrieve PID from creds if it wasn't passed to us */
777 c->mask |= SD_BUS_CREDS_PID;
778 } else if (c->mask & SD_BUS_CREDS_PID)
781 /* Without pid we cannot do much... */
784 /* Try to retrieve TID from creds if it wasn't passed to us */
785 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
788 /* Calculate what we shall and can add */
789 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);
795 c->mask |= SD_BUS_CREDS_TID;
798 if (missing & (SD_BUS_CREDS_PPID |
799 SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
800 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
801 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
802 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
803 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
805 _cleanup_fclose_ FILE *f = NULL;
808 p = procfs_file_alloca(pid, "status");
814 else if (!IN_SET(errno, EPERM, EACCES))
819 FOREACH_LINE(line, f, return -errno) {
822 if (missing & SD_BUS_CREDS_PPID) {
823 p = startswith(line, "PPid:");
825 p += strspn(p, WHITESPACE);
827 /* Explicitly check for PPID 0 (which is the case for PID 1) */
828 if (!streq(p, "0")) {
829 r = parse_pid(p, &c->ppid);
836 c->mask |= SD_BUS_CREDS_PPID;
841 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
842 p = startswith(line, "Uid:");
844 unsigned long uid, euid, suid, fsuid;
846 p += strspn(p, WHITESPACE);
847 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
850 if (missing & SD_BUS_CREDS_UID)
851 c->uid = (uid_t) uid;
852 if (missing & SD_BUS_CREDS_EUID)
853 c->euid = (uid_t) euid;
854 if (missing & SD_BUS_CREDS_SUID)
855 c->suid = (uid_t) suid;
856 if (missing & SD_BUS_CREDS_FSUID)
857 c->fsuid = (uid_t) fsuid;
859 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
864 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
865 p = startswith(line, "Gid:");
867 unsigned long gid, egid, sgid, fsgid;
869 p += strspn(p, WHITESPACE);
870 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
873 if (missing & SD_BUS_CREDS_GID)
874 c->gid = (gid_t) gid;
875 if (missing & SD_BUS_CREDS_EGID)
876 c->egid = (gid_t) egid;
877 if (missing & SD_BUS_CREDS_SGID)
878 c->sgid = (gid_t) sgid;
879 if (missing & SD_BUS_CREDS_FSGID)
880 c->fsgid = (gid_t) fsgid;
882 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
887 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
888 p = startswith(line, "Groups:");
890 size_t allocated = 0;
896 p += strspn(p, WHITESPACE);
900 if (sscanf(p, "%lu%n", &g, &n) != 1)
903 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
906 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
910 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
915 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
916 p = startswith(line, "CapEff:");
918 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
922 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
927 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
928 p = startswith(line, "CapPrm:");
930 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
934 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
939 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
940 p = startswith(line, "CapInh:");
942 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
946 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
951 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
952 p = startswith(line, "CapBnd:");
954 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
958 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
966 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
969 p = procfs_file_alloca(pid, "attr/current");
970 r = read_one_line_file(p, &c->label);
972 if (!IN_SET(r, -ENOENT, -EINVAL, -EPERM, -EACCES))
975 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
978 if (missing & SD_BUS_CREDS_COMM) {
979 r = get_process_comm(pid, &c->comm);
981 if (!IN_SET(r, -EPERM, -EACCES))
984 c->mask |= SD_BUS_CREDS_COMM;
987 if (missing & SD_BUS_CREDS_EXE) {
988 r = get_process_exe(pid, &c->exe);
990 /* Unfortunately we cannot really distinguish
991 * the case here where the process does not
992 * exist, and /proc/$PID/exe being unreadable
993 * because $PID is a kernel thread. Hence,
994 * assume it is a kernel thread, and rely on
995 * that this case is caught with a later
998 c->mask |= SD_BUS_CREDS_EXE;
1000 if (!IN_SET(r, -EPERM, -EACCES))
1003 c->mask |= SD_BUS_CREDS_EXE;
1006 if (missing & SD_BUS_CREDS_CMDLINE) {
1009 p = procfs_file_alloca(pid, "cmdline");
1010 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
1014 if (!IN_SET(r, -EPERM, -EACCES))
1017 if (c->cmdline_size == 0)
1018 c->cmdline = mfree(c->cmdline);
1020 c->mask |= SD_BUS_CREDS_CMDLINE;
1024 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
1025 _cleanup_free_ char *p = NULL;
1027 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
1030 r = read_one_line_file(p, &c->tid_comm);
1034 if (!IN_SET(r, -EPERM, -EACCES))
1037 c->mask |= SD_BUS_CREDS_TID_COMM;
1040 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)) {
1043 r = cg_pid_get_path(NULL, pid, &c->cgroup);
1045 if (!IN_SET(r, -EPERM, -EACCES))
1050 if (!c->cgroup_root) {
1051 r = cg_get_root_path(&c->cgroup_root);
1057 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);
1060 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1061 r = audit_session_from_pid(pid, &c->audit_session_id);
1062 if (r == -ENODATA) {
1063 /* ENODATA means: no audit session id assigned */
1064 c->audit_session_id = AUDIT_SESSION_INVALID;
1065 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1067 if (!IN_SET(r, -EOPNOTSUPP, -ENOENT, -EPERM, -EACCES))
1070 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1073 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1074 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
1075 if (r == -ENODATA) {
1076 /* ENODATA means: no audit login uid assigned */
1077 c->audit_login_uid = UID_INVALID;
1078 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1080 if (!IN_SET(r, -EOPNOTSUPP, -ENOENT, -EPERM, -EACCES))
1083 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1086 if (missing & SD_BUS_CREDS_TTY) {
1087 r = get_ctty(pid, NULL, &c->tty);
1089 /* ENXIO means: process has no controlling TTY */
1091 c->mask |= SD_BUS_CREDS_TTY;
1093 if (!IN_SET(r, -EPERM, -EACCES, -ENOENT))
1096 c->mask |= SD_BUS_CREDS_TTY;
1099 /* In case only the exe path was to be read we cannot
1100 * distinguish the case where the exe path was unreadable
1101 * because the process was a kernel thread, or when the
1102 * process didn't exist at all. Hence, let's do a final check,
1104 if (!pid_is_alive(pid))
1107 if (tid > 0 && tid != pid && !pid_is_unwaited(tid))
1110 c->augmented = missing & c->mask;
1115 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
1116 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *n = NULL;
1122 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
1123 /* There's already all data we need, or augmentation
1124 * wasn't turned on. */
1126 *ret = sd_bus_creds_ref(c);
1130 n = bus_creds_new();
1134 /* Copy the original data over */
1136 if (c->mask & mask & SD_BUS_CREDS_PID) {
1138 n->mask |= SD_BUS_CREDS_PID;
1141 if (c->mask & mask & SD_BUS_CREDS_TID) {
1143 n->mask |= SD_BUS_CREDS_TID;
1146 if (c->mask & mask & SD_BUS_CREDS_PPID) {
1148 n->mask |= SD_BUS_CREDS_PPID;
1151 if (c->mask & mask & SD_BUS_CREDS_UID) {
1153 n->mask |= SD_BUS_CREDS_UID;
1156 if (c->mask & mask & SD_BUS_CREDS_EUID) {
1158 n->mask |= SD_BUS_CREDS_EUID;
1161 if (c->mask & mask & SD_BUS_CREDS_SUID) {
1163 n->mask |= SD_BUS_CREDS_SUID;
1166 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
1167 n->fsuid = c->fsuid;
1168 n->mask |= SD_BUS_CREDS_FSUID;
1171 if (c->mask & mask & SD_BUS_CREDS_GID) {
1173 n->mask |= SD_BUS_CREDS_GID;
1176 if (c->mask & mask & SD_BUS_CREDS_EGID) {
1178 n->mask |= SD_BUS_CREDS_EGID;
1181 if (c->mask & mask & SD_BUS_CREDS_SGID) {
1183 n->mask |= SD_BUS_CREDS_SGID;
1186 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
1187 n->fsgid = c->fsgid;
1188 n->mask |= SD_BUS_CREDS_FSGID;
1191 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
1192 if (c->supplementary_gids) {
1193 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
1194 if (!n->supplementary_gids)
1196 n->n_supplementary_gids = c->n_supplementary_gids;
1198 n->supplementary_gids = NULL;
1199 n->n_supplementary_gids = 0;
1202 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
1205 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1208 n->comm = strdup(c->comm);
1212 n->mask |= SD_BUS_CREDS_COMM;
1215 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1216 assert(c->tid_comm);
1218 n->tid_comm = strdup(c->tid_comm);
1222 n->mask |= SD_BUS_CREDS_TID_COMM;
1225 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1227 n->exe = strdup(c->exe);
1233 n->mask |= SD_BUS_CREDS_EXE;
1236 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1238 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1242 n->cmdline_size = c->cmdline_size;
1245 n->cmdline_size = 0;
1248 n->mask |= SD_BUS_CREDS_CMDLINE;
1251 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)) {
1254 n->cgroup = strdup(c->cgroup);
1258 n->cgroup_root = strdup(c->cgroup_root);
1259 if (!n->cgroup_root)
1262 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);
1265 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1266 assert(c->capability);
1268 n->capability = memdup(c->capability, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4);
1272 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);
1275 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1278 n->label = strdup(c->label);
1281 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1284 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1285 n->audit_session_id = c->audit_session_id;
1286 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1288 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1289 n->audit_login_uid = c->audit_login_uid;
1290 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1293 if (c->mask & mask & SD_BUS_CREDS_TTY) {
1295 n->tty = strdup(c->tty);
1300 n->mask |= SD_BUS_CREDS_TTY;
1303 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1304 assert(c->unique_name);
1306 n->unique_name = strdup(c->unique_name);
1307 if (!n->unique_name)
1309 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1312 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1313 if (strv_isempty(c->well_known_names))
1314 n->well_known_names = NULL;
1316 n->well_known_names = strv_copy(c->well_known_names);
1317 if (!n->well_known_names)
1320 n->well_known_names_driver = c->well_known_names_driver;
1321 n->well_known_names_local = c->well_known_names_local;
1322 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1325 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1326 assert(c->description);
1327 n->description = strdup(c->description);
1328 if (!n->description)
1330 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1333 n->augmented = c->augmented & n->mask;
1337 r = bus_creds_add_more(n, mask, 0, 0);