1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 #include <linux/capability.h>
8 #include "alloc-util.h"
9 #include "audit-util.h"
10 #include "bus-creds.h"
11 #include "bus-label.h"
12 #include "bus-message.h"
14 #include "capability-util.h"
15 #include "cgroup-util.h"
18 #include "format-util.h"
19 #include "hexdecoct.h"
20 #include "parse-util.h"
21 #include "process-util.h"
22 #include "string-util.h"
24 #include "terminal-util.h"
25 #include "user-util.h"
29 CAP_OFFSET_INHERITABLE = 0,
30 CAP_OFFSET_PERMITTED = 1,
31 CAP_OFFSET_EFFECTIVE = 2,
32 CAP_OFFSET_BOUNDING = 3
35 void bus_creds_done(sd_bus_creds *c) {
38 /* For internal bus cred structures that are allocated by
46 free(c->unescaped_description);
47 free(c->supplementary_gids);
50 free(c->well_known_names); /* note that this is an strv, but
51 * we only free the array, not the
52 * strings the array points to. The
53 * full strv we only free if
54 * c->allocated is set, see
57 strv_free(c->cmdline_array);
60 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
71 /* If this is an embedded creds structure, then
72 * forward ref counting to the message */
73 m = container_of(c, sd_bus_message, creds);
74 sd_bus_message_ref(m);
80 _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
101 c->supplementary_gids = mfree(c->supplementary_gids);
103 c->well_known_names = strv_free(c->well_known_names);
112 m = container_of(c, sd_bus_message, creds);
113 sd_bus_message_unref(m);
119 _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
125 _public_ uint64_t sd_bus_creds_get_augmented_mask(const sd_bus_creds *c) {
131 sd_bus_creds* bus_creds_new(void) {
134 c = new0(sd_bus_creds, 1);
143 _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
147 assert_return(pid >= 0, -EINVAL);
148 assert_return(mask <= _SD_BUS_CREDS_ALL, -EOPNOTSUPP);
149 assert_return(ret, -EINVAL);
152 pid = getpid_cached();
158 r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
160 sd_bus_creds_unref(c);
164 /* Check if the process existed at all, in case we haven't
165 * figured that out already */
166 if (!pid_is_alive(pid)) {
167 sd_bus_creds_unref(c);
175 _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) {
176 assert_return(c, -EINVAL);
177 assert_return(uid, -EINVAL);
179 if (!(c->mask & SD_BUS_CREDS_UID))
186 _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) {
187 assert_return(c, -EINVAL);
188 assert_return(euid, -EINVAL);
190 if (!(c->mask & SD_BUS_CREDS_EUID))
197 _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) {
198 assert_return(c, -EINVAL);
199 assert_return(suid, -EINVAL);
201 if (!(c->mask & SD_BUS_CREDS_SUID))
208 _public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) {
209 assert_return(c, -EINVAL);
210 assert_return(fsuid, -EINVAL);
212 if (!(c->mask & SD_BUS_CREDS_FSUID))
219 _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
220 assert_return(c, -EINVAL);
221 assert_return(gid, -EINVAL);
223 if (!(c->mask & SD_BUS_CREDS_GID))
230 _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) {
231 assert_return(c, -EINVAL);
232 assert_return(egid, -EINVAL);
234 if (!(c->mask & SD_BUS_CREDS_EGID))
241 _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
242 assert_return(c, -EINVAL);
243 assert_return(sgid, -EINVAL);
245 if (!(c->mask & SD_BUS_CREDS_SGID))
252 _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
253 assert_return(c, -EINVAL);
254 assert_return(fsgid, -EINVAL);
256 if (!(c->mask & SD_BUS_CREDS_FSGID))
263 _public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) {
264 assert_return(c, -EINVAL);
265 assert_return(gids, -EINVAL);
267 if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
270 *gids = c->supplementary_gids;
271 return (int) c->n_supplementary_gids;
274 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
275 assert_return(c, -EINVAL);
276 assert_return(pid, -EINVAL);
278 if (!(c->mask & SD_BUS_CREDS_PID))
286 _public_ int sd_bus_creds_get_ppid(sd_bus_creds *c, pid_t *ppid) {
287 assert_return(c, -EINVAL);
288 assert_return(ppid, -EINVAL);
290 if (!(c->mask & SD_BUS_CREDS_PPID))
293 /* PID 1 has no parent process. Let's distinguish the case of
294 * not knowing and not having a parent process by the returned
303 _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) {
304 assert_return(c, -EINVAL);
305 assert_return(tid, -EINVAL);
307 if (!(c->mask & SD_BUS_CREDS_TID))
315 _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
316 assert_return(c, -EINVAL);
318 if (!(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT))
326 _public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) {
327 assert_return(c, -EINVAL);
328 assert_return(ret, -EINVAL);
330 if (!(c->mask & SD_BUS_CREDS_COMM))
338 _public_ int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **ret) {
339 assert_return(c, -EINVAL);
340 assert_return(ret, -EINVAL);
342 if (!(c->mask & SD_BUS_CREDS_TID_COMM))
350 _public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) {
351 assert_return(c, -EINVAL);
352 assert_return(ret, -EINVAL);
354 if (!(c->mask & SD_BUS_CREDS_EXE))
364 _public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) {
365 assert_return(c, -EINVAL);
366 assert_return(ret, -EINVAL);
368 if (!(c->mask & SD_BUS_CREDS_CGROUP))
376 #if 0 /// UNNEEDED by elogind
377 _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {
380 assert_return(c, -EINVAL);
381 assert_return(ret, -EINVAL);
383 if (!(c->mask & SD_BUS_CREDS_UNIT))
391 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
395 r = cg_path_get_unit(shifted, (char**) &c->unit);
404 _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
407 assert_return(c, -EINVAL);
408 assert_return(ret, -EINVAL);
410 if (!(c->mask & SD_BUS_CREDS_USER_UNIT))
418 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
422 r = cg_path_get_user_unit(shifted, (char**) &c->user_unit);
432 _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
435 assert_return(c, -EINVAL);
436 assert_return(ret, -EINVAL);
438 if (!(c->mask & SD_BUS_CREDS_SLICE))
446 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
450 r = cg_path_get_slice(shifted, (char**) &c->slice);
459 _public_ int sd_bus_creds_get_user_slice(sd_bus_creds *c, const char **ret) {
462 assert_return(c, -EINVAL);
463 assert_return(ret, -EINVAL);
465 if (!(c->mask & SD_BUS_CREDS_USER_SLICE))
470 if (!c->user_slice) {
473 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
477 r = cg_path_get_user_slice(shifted, (char**) &c->user_slice);
482 *ret = c->user_slice;
486 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
489 assert_return(c, -EINVAL);
490 assert_return(ret, -EINVAL);
492 if (!(c->mask & SD_BUS_CREDS_SESSION))
500 log_debug_elogind("Shifting cgroup \"%s\", root \"%s\"",
501 c->cgroup, c->cgroup_root ? c->cgroup_root : "NULL");
502 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
506 log_debug_elogind("Shifted: \"%s\"", shifted);
507 r = cg_path_get_session(shifted, (char**) &c->session);
516 _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
520 assert_return(c, -EINVAL);
521 assert_return(uid, -EINVAL);
523 if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
528 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
529 log_debug_elogind("Shifted to %s from %s/%s for c->uid %u (result %d)",
530 shifted, c->cgroup_root, c->cgroup, c->uid, r);
534 return cg_path_get_owner_uid(shifted, uid);
537 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
538 assert_return(c, -EINVAL);
540 if (!(c->mask & SD_BUS_CREDS_CMDLINE))
546 if (!c->cmdline_array) {
547 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
548 if (!c->cmdline_array)
552 *cmdline = c->cmdline_array;
556 _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
557 assert_return(c, -EINVAL);
558 assert_return(sessionid, -EINVAL);
560 if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
563 if (!audit_session_is_valid(c->audit_session_id))
566 *sessionid = c->audit_session_id;
570 _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
571 assert_return(c, -EINVAL);
572 assert_return(uid, -EINVAL);
574 if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID))
577 if (!uid_is_valid(c->audit_login_uid))
580 *uid = c->audit_login_uid;
584 _public_ int sd_bus_creds_get_tty(sd_bus_creds *c, const char **ret) {
585 assert_return(c, -EINVAL);
586 assert_return(ret, -EINVAL);
588 if (!(c->mask & SD_BUS_CREDS_TTY))
598 _public_ int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **unique_name) {
599 assert_return(c, -EINVAL);
600 assert_return(unique_name, -EINVAL);
602 if (!(c->mask & SD_BUS_CREDS_UNIQUE_NAME))
605 *unique_name = c->unique_name;
609 _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) {
610 assert_return(c, -EINVAL);
611 assert_return(well_known_names, -EINVAL);
613 if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
616 /* As a special hack we return the bus driver as well-known
617 * names list when this is requested. */
618 if (c->well_known_names_driver) {
619 static const char* const wkn[] = {
620 "org.freedesktop.DBus",
624 *well_known_names = (char**) wkn;
628 if (c->well_known_names_local) {
629 static const char* const wkn[] = {
630 "org.freedesktop.DBus.Local",
634 *well_known_names = (char**) wkn;
638 *well_known_names = c->well_known_names;
642 _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) {
643 assert_return(c, -EINVAL);
644 assert_return(ret, -EINVAL);
646 if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
649 assert(c->description);
651 if (!c->unescaped_description) {
652 c->unescaped_description = bus_label_unescape(c->description);
653 if (!c->unescaped_description)
657 *ret = c->unescaped_description;
661 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
665 assert(capability >= 0);
666 assert(c->capability);
668 if ((unsigned) capability > cap_last_cap())
671 sz = DIV_ROUND_UP(cap_last_cap(), 32U);
673 return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability));
676 _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
677 assert_return(c, -EINVAL);
678 assert_return(capability >= 0, -EINVAL);
680 if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS))
683 return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
686 _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
687 assert_return(c, -EINVAL);
688 assert_return(capability >= 0, -EINVAL);
690 if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS))
693 return has_cap(c, CAP_OFFSET_PERMITTED, capability);
696 _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
697 assert_return(c, -EINVAL);
698 assert_return(capability >= 0, -EINVAL);
700 if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS))
703 return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
706 _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) {
707 assert_return(c, -EINVAL);
708 assert_return(capability >= 0, -EINVAL);
710 if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS))
713 return has_cap(c, CAP_OFFSET_BOUNDING, capability);
716 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
723 max = DIV_ROUND_UP(cap_last_cap(), 32U);
724 p += strspn(p, WHITESPACE);
734 if (!c->capability) {
735 c->capability = new0(uint32_t, max * 4);
740 for (i = 0; i < sz; i ++) {
743 for (j = 0; j < 8; ++j) {
753 c->capability[offset * max + (sz - i - 1)] = v;
759 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
764 assert(c->allocated);
766 if (!(mask & SD_BUS_CREDS_AUGMENT))
769 /* Try to retrieve PID from creds if it wasn't passed to us */
772 c->mask |= SD_BUS_CREDS_PID;
773 } else if (c->mask & SD_BUS_CREDS_PID)
776 /* Without pid we cannot do much... */
779 /* Try to retrieve TID from creds if it wasn't passed to us */
780 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
783 /* Calculate what we shall and can add */
784 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);
790 c->mask |= SD_BUS_CREDS_TID;
793 if (missing & (SD_BUS_CREDS_PPID |
794 SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
795 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
796 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
797 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
798 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
800 _cleanup_fclose_ FILE *f = NULL;
803 p = procfs_file_alloca(pid, "status");
809 else if (!IN_SET(errno, EPERM, EACCES))
814 FOREACH_LINE(line, f, return -errno) {
817 if (missing & SD_BUS_CREDS_PPID) {
818 p = startswith(line, "PPid:");
820 p += strspn(p, WHITESPACE);
822 /* Explicitly check for PPID 0 (which is the case for PID 1) */
823 if (!streq(p, "0")) {
824 r = parse_pid(p, &c->ppid);
831 c->mask |= SD_BUS_CREDS_PPID;
836 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
837 p = startswith(line, "Uid:");
839 unsigned long uid, euid, suid, fsuid;
841 p += strspn(p, WHITESPACE);
842 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
845 if (missing & SD_BUS_CREDS_UID)
846 c->uid = (uid_t) uid;
847 if (missing & SD_BUS_CREDS_EUID)
848 c->euid = (uid_t) euid;
849 if (missing & SD_BUS_CREDS_SUID)
850 c->suid = (uid_t) suid;
851 if (missing & SD_BUS_CREDS_FSUID)
852 c->fsuid = (uid_t) fsuid;
854 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
859 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
860 p = startswith(line, "Gid:");
862 unsigned long gid, egid, sgid, fsgid;
864 p += strspn(p, WHITESPACE);
865 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
868 if (missing & SD_BUS_CREDS_GID)
869 c->gid = (gid_t) gid;
870 if (missing & SD_BUS_CREDS_EGID)
871 c->egid = (gid_t) egid;
872 if (missing & SD_BUS_CREDS_SGID)
873 c->sgid = (gid_t) sgid;
874 if (missing & SD_BUS_CREDS_FSGID)
875 c->fsgid = (gid_t) fsgid;
877 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
882 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
883 p = startswith(line, "Groups:");
885 size_t allocated = 0;
891 p += strspn(p, WHITESPACE);
895 if (sscanf(p, "%lu%n", &g, &n) != 1)
898 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
901 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
905 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
910 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
911 p = startswith(line, "CapEff:");
913 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
917 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
922 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
923 p = startswith(line, "CapPrm:");
925 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
929 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
934 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
935 p = startswith(line, "CapInh:");
937 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
941 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
946 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
947 p = startswith(line, "CapBnd:");
949 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
953 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
961 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
964 p = procfs_file_alloca(pid, "attr/current");
965 r = read_one_line_file(p, &c->label);
967 if (!IN_SET(r, -ENOENT, -EINVAL, -EPERM, -EACCES))
970 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
973 if (missing & SD_BUS_CREDS_COMM) {
974 r = get_process_comm(pid, &c->comm);
976 if (!IN_SET(r, -EPERM, -EACCES))
979 c->mask |= SD_BUS_CREDS_COMM;
982 if (missing & SD_BUS_CREDS_EXE) {
983 r = get_process_exe(pid, &c->exe);
985 /* Unfortunately we cannot really distinguish
986 * the case here where the process does not
987 * exist, and /proc/$PID/exe being unreadable
988 * because $PID is a kernel thread. Hence,
989 * assume it is a kernel thread, and rely on
990 * that this case is caught with a later
993 c->mask |= SD_BUS_CREDS_EXE;
995 if (!IN_SET(r, -EPERM, -EACCES))
998 c->mask |= SD_BUS_CREDS_EXE;
1001 if (missing & SD_BUS_CREDS_CMDLINE) {
1004 p = procfs_file_alloca(pid, "cmdline");
1005 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
1009 if (!IN_SET(r, -EPERM, -EACCES))
1012 if (c->cmdline_size == 0)
1013 c->cmdline = mfree(c->cmdline);
1015 c->mask |= SD_BUS_CREDS_CMDLINE;
1019 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
1020 _cleanup_free_ char *p = NULL;
1022 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
1025 r = read_one_line_file(p, &c->tid_comm);
1029 if (!IN_SET(r, -EPERM, -EACCES))
1032 c->mask |= SD_BUS_CREDS_TID_COMM;
1035 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)) {
1038 r = cg_pid_get_path(NULL, pid, &c->cgroup);
1040 if (!IN_SET(r, -EPERM, -EACCES))
1045 if (!c->cgroup_root) {
1046 r = cg_get_root_path(&c->cgroup_root);
1052 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);
1055 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1056 r = audit_session_from_pid(pid, &c->audit_session_id);
1057 if (r == -ENODATA) {
1058 /* ENODATA means: no audit session id assigned */
1059 c->audit_session_id = AUDIT_SESSION_INVALID;
1060 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1062 if (!IN_SET(r, -EOPNOTSUPP, -ENOENT, -EPERM, -EACCES))
1065 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1068 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1069 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
1070 if (r == -ENODATA) {
1071 /* ENODATA means: no audit login uid assigned */
1072 c->audit_login_uid = UID_INVALID;
1073 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1075 if (!IN_SET(r, -EOPNOTSUPP, -ENOENT, -EPERM, -EACCES))
1078 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1081 if (missing & SD_BUS_CREDS_TTY) {
1082 r = get_ctty(pid, NULL, &c->tty);
1084 /* ENXIO means: process has no controlling TTY */
1086 c->mask |= SD_BUS_CREDS_TTY;
1088 if (!IN_SET(r, -EPERM, -EACCES, -ENOENT))
1091 c->mask |= SD_BUS_CREDS_TTY;
1094 /* In case only the exe path was to be read we cannot
1095 * distinguish the case where the exe path was unreadable
1096 * because the process was a kernel thread, or when the
1097 * process didn't exist at all. Hence, let's do a final check,
1099 if (!pid_is_alive(pid))
1102 if (tid > 0 && tid != pid && !pid_is_unwaited(tid))
1105 c->augmented = missing & c->mask;
1110 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
1111 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *n = NULL;
1117 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
1118 /* There's already all data we need, or augmentation
1119 * wasn't turned on. */
1121 *ret = sd_bus_creds_ref(c);
1125 n = bus_creds_new();
1129 /* Copy the original data over */
1131 if (c->mask & mask & SD_BUS_CREDS_PID) {
1133 n->mask |= SD_BUS_CREDS_PID;
1136 if (c->mask & mask & SD_BUS_CREDS_TID) {
1138 n->mask |= SD_BUS_CREDS_TID;
1141 if (c->mask & mask & SD_BUS_CREDS_PPID) {
1143 n->mask |= SD_BUS_CREDS_PPID;
1146 if (c->mask & mask & SD_BUS_CREDS_UID) {
1148 n->mask |= SD_BUS_CREDS_UID;
1151 if (c->mask & mask & SD_BUS_CREDS_EUID) {
1153 n->mask |= SD_BUS_CREDS_EUID;
1156 if (c->mask & mask & SD_BUS_CREDS_SUID) {
1158 n->mask |= SD_BUS_CREDS_SUID;
1161 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
1162 n->fsuid = c->fsuid;
1163 n->mask |= SD_BUS_CREDS_FSUID;
1166 if (c->mask & mask & SD_BUS_CREDS_GID) {
1168 n->mask |= SD_BUS_CREDS_GID;
1171 if (c->mask & mask & SD_BUS_CREDS_EGID) {
1173 n->mask |= SD_BUS_CREDS_EGID;
1176 if (c->mask & mask & SD_BUS_CREDS_SGID) {
1178 n->mask |= SD_BUS_CREDS_SGID;
1181 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
1182 n->fsgid = c->fsgid;
1183 n->mask |= SD_BUS_CREDS_FSGID;
1186 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
1187 if (c->supplementary_gids) {
1188 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
1189 if (!n->supplementary_gids)
1191 n->n_supplementary_gids = c->n_supplementary_gids;
1193 n->supplementary_gids = NULL;
1194 n->n_supplementary_gids = 0;
1197 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
1200 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1203 n->comm = strdup(c->comm);
1207 n->mask |= SD_BUS_CREDS_COMM;
1210 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1211 assert(c->tid_comm);
1213 n->tid_comm = strdup(c->tid_comm);
1217 n->mask |= SD_BUS_CREDS_TID_COMM;
1220 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1222 n->exe = strdup(c->exe);
1228 n->mask |= SD_BUS_CREDS_EXE;
1231 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1233 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1237 n->cmdline_size = c->cmdline_size;
1240 n->cmdline_size = 0;
1243 n->mask |= SD_BUS_CREDS_CMDLINE;
1246 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)) {
1249 n->cgroup = strdup(c->cgroup);
1253 n->cgroup_root = strdup(c->cgroup_root);
1254 if (!n->cgroup_root)
1257 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);
1260 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1261 assert(c->capability);
1263 n->capability = memdup(c->capability, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4);
1267 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);
1270 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1273 n->label = strdup(c->label);
1276 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1279 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1280 n->audit_session_id = c->audit_session_id;
1281 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1283 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1284 n->audit_login_uid = c->audit_login_uid;
1285 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1288 if (c->mask & mask & SD_BUS_CREDS_TTY) {
1290 n->tty = strdup(c->tty);
1295 n->mask |= SD_BUS_CREDS_TTY;
1298 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1299 assert(c->unique_name);
1301 n->unique_name = strdup(c->unique_name);
1302 if (!n->unique_name)
1304 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1307 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1308 if (strv_isempty(c->well_known_names))
1309 n->well_known_names = NULL;
1311 n->well_known_names = strv_copy(c->well_known_names);
1312 if (!n->well_known_names)
1315 n->well_known_names_driver = c->well_known_names_driver;
1316 n->well_known_names_local = c->well_known_names_local;
1317 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1320 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1321 assert(c->description);
1322 n->description = strdup(c->description);
1323 if (!n->description)
1325 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1328 n->augmented = c->augmented & n->mask;
1332 r = bus_creds_add_more(n, mask, 0, 0);