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);
122 _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
128 _public_ uint64_t sd_bus_creds_get_augmented_mask(const sd_bus_creds *c) {
134 sd_bus_creds* bus_creds_new(void) {
137 c = new0(sd_bus_creds, 1);
146 _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
150 assert_return(pid >= 0, -EINVAL);
151 assert_return(mask <= _SD_BUS_CREDS_ALL, -EOPNOTSUPP);
152 assert_return(ret, -EINVAL);
155 pid = getpid_cached();
161 r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
163 sd_bus_creds_unref(c);
167 /* Check if the process existed at all, in case we haven't
168 * figured that out already */
169 if (!pid_is_alive(pid)) {
170 sd_bus_creds_unref(c);
178 _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) {
179 assert_return(c, -EINVAL);
180 assert_return(uid, -EINVAL);
182 if (!(c->mask & SD_BUS_CREDS_UID))
189 _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) {
190 assert_return(c, -EINVAL);
191 assert_return(euid, -EINVAL);
193 if (!(c->mask & SD_BUS_CREDS_EUID))
200 _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) {
201 assert_return(c, -EINVAL);
202 assert_return(suid, -EINVAL);
204 if (!(c->mask & SD_BUS_CREDS_SUID))
211 _public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) {
212 assert_return(c, -EINVAL);
213 assert_return(fsuid, -EINVAL);
215 if (!(c->mask & SD_BUS_CREDS_FSUID))
222 _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
223 assert_return(c, -EINVAL);
224 assert_return(gid, -EINVAL);
226 if (!(c->mask & SD_BUS_CREDS_GID))
233 _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) {
234 assert_return(c, -EINVAL);
235 assert_return(egid, -EINVAL);
237 if (!(c->mask & SD_BUS_CREDS_EGID))
244 _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
245 assert_return(c, -EINVAL);
246 assert_return(sgid, -EINVAL);
248 if (!(c->mask & SD_BUS_CREDS_SGID))
255 _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
256 assert_return(c, -EINVAL);
257 assert_return(fsgid, -EINVAL);
259 if (!(c->mask & SD_BUS_CREDS_FSGID))
266 _public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) {
267 assert_return(c, -EINVAL);
268 assert_return(gids, -EINVAL);
270 if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
273 *gids = c->supplementary_gids;
274 return (int) c->n_supplementary_gids;
277 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
278 assert_return(c, -EINVAL);
279 assert_return(pid, -EINVAL);
281 if (!(c->mask & SD_BUS_CREDS_PID))
289 _public_ int sd_bus_creds_get_ppid(sd_bus_creds *c, pid_t *ppid) {
290 assert_return(c, -EINVAL);
291 assert_return(ppid, -EINVAL);
293 if (!(c->mask & SD_BUS_CREDS_PPID))
296 /* PID 1 has no parent process. Let's distinguish the case of
297 * not knowing and not having a parent process by the returned
306 _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) {
307 assert_return(c, -EINVAL);
308 assert_return(tid, -EINVAL);
310 if (!(c->mask & SD_BUS_CREDS_TID))
318 _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
319 assert_return(c, -EINVAL);
321 if (!(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT))
329 _public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) {
330 assert_return(c, -EINVAL);
331 assert_return(ret, -EINVAL);
333 if (!(c->mask & SD_BUS_CREDS_COMM))
341 _public_ int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **ret) {
342 assert_return(c, -EINVAL);
343 assert_return(ret, -EINVAL);
345 if (!(c->mask & SD_BUS_CREDS_TID_COMM))
353 _public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) {
354 assert_return(c, -EINVAL);
355 assert_return(ret, -EINVAL);
357 if (!(c->mask & SD_BUS_CREDS_EXE))
367 _public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) {
368 assert_return(c, -EINVAL);
369 assert_return(ret, -EINVAL);
371 if (!(c->mask & SD_BUS_CREDS_CGROUP))
379 #if 0 /// UNNEEDED by elogind
380 _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {
383 assert_return(c, -EINVAL);
384 assert_return(ret, -EINVAL);
386 if (!(c->mask & SD_BUS_CREDS_UNIT))
394 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
398 r = cg_path_get_unit(shifted, (char**) &c->unit);
407 _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
410 assert_return(c, -EINVAL);
411 assert_return(ret, -EINVAL);
413 if (!(c->mask & SD_BUS_CREDS_USER_UNIT))
421 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
425 r = cg_path_get_user_unit(shifted, (char**) &c->user_unit);
435 _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
438 assert_return(c, -EINVAL);
439 assert_return(ret, -EINVAL);
441 if (!(c->mask & SD_BUS_CREDS_SLICE))
449 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
453 r = cg_path_get_slice(shifted, (char**) &c->slice);
462 _public_ int sd_bus_creds_get_user_slice(sd_bus_creds *c, const char **ret) {
465 assert_return(c, -EINVAL);
466 assert_return(ret, -EINVAL);
468 if (!(c->mask & SD_BUS_CREDS_USER_SLICE))
473 if (!c->user_slice) {
476 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
480 r = cg_path_get_user_slice(shifted, (char**) &c->user_slice);
485 *ret = c->user_slice;
489 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
492 assert_return(c, -EINVAL);
493 assert_return(ret, -EINVAL);
495 if (!(c->mask & SD_BUS_CREDS_SESSION))
503 log_debug_elogind("Shifting cgroup \"%s\", root \"%s\"",
504 c->cgroup, c->cgroup_root ? c->cgroup_root : "NULL");
505 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
509 log_debug_elogind("Shifted: \"%s\"", shifted);
510 r = cg_path_get_session(shifted, (char**) &c->session);
519 _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
523 assert_return(c, -EINVAL);
524 assert_return(uid, -EINVAL);
526 if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
531 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
532 log_debug_elogind("Shifted to %s from %s/%s for c->uid %u (result %d)",
533 shifted, c->cgroup_root, c->cgroup, c->uid, r);
537 return cg_path_get_owner_uid(shifted, uid);
540 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
541 assert_return(c, -EINVAL);
543 if (!(c->mask & SD_BUS_CREDS_CMDLINE))
549 if (!c->cmdline_array) {
550 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
551 if (!c->cmdline_array)
555 *cmdline = c->cmdline_array;
559 _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
560 assert_return(c, -EINVAL);
561 assert_return(sessionid, -EINVAL);
563 if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
566 if (!audit_session_is_valid(c->audit_session_id))
569 *sessionid = c->audit_session_id;
573 _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
574 assert_return(c, -EINVAL);
575 assert_return(uid, -EINVAL);
577 if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID))
580 if (!uid_is_valid(c->audit_login_uid))
583 *uid = c->audit_login_uid;
587 _public_ int sd_bus_creds_get_tty(sd_bus_creds *c, const char **ret) {
588 assert_return(c, -EINVAL);
589 assert_return(ret, -EINVAL);
591 if (!(c->mask & SD_BUS_CREDS_TTY))
601 _public_ int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **unique_name) {
602 assert_return(c, -EINVAL);
603 assert_return(unique_name, -EINVAL);
605 if (!(c->mask & SD_BUS_CREDS_UNIQUE_NAME))
608 *unique_name = c->unique_name;
612 _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) {
613 assert_return(c, -EINVAL);
614 assert_return(well_known_names, -EINVAL);
616 if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
619 /* As a special hack we return the bus driver as well-known
620 * names list when this is requested. */
621 if (c->well_known_names_driver) {
622 static const char* const wkn[] = {
623 "org.freedesktop.DBus",
627 *well_known_names = (char**) wkn;
631 if (c->well_known_names_local) {
632 static const char* const wkn[] = {
633 "org.freedesktop.DBus.Local",
637 *well_known_names = (char**) wkn;
641 *well_known_names = c->well_known_names;
645 _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) {
646 assert_return(c, -EINVAL);
647 assert_return(ret, -EINVAL);
649 if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
652 assert(c->description);
654 if (!c->unescaped_description) {
655 c->unescaped_description = bus_label_unescape(c->description);
656 if (!c->unescaped_description)
660 *ret = c->unescaped_description;
664 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
668 assert(capability >= 0);
669 assert(c->capability);
671 if ((unsigned) capability > cap_last_cap())
674 sz = DIV_ROUND_UP(cap_last_cap(), 32U);
676 return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability));
679 _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
680 assert_return(c, -EINVAL);
681 assert_return(capability >= 0, -EINVAL);
683 if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS))
686 return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
689 _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
690 assert_return(c, -EINVAL);
691 assert_return(capability >= 0, -EINVAL);
693 if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS))
696 return has_cap(c, CAP_OFFSET_PERMITTED, capability);
699 _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
700 assert_return(c, -EINVAL);
701 assert_return(capability >= 0, -EINVAL);
703 if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS))
706 return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
709 _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) {
710 assert_return(c, -EINVAL);
711 assert_return(capability >= 0, -EINVAL);
713 if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS))
716 return has_cap(c, CAP_OFFSET_BOUNDING, capability);
719 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
726 max = DIV_ROUND_UP(cap_last_cap(), 32U);
727 p += strspn(p, WHITESPACE);
737 if (!c->capability) {
738 c->capability = new0(uint32_t, max * 4);
743 for (i = 0; i < sz; i ++) {
746 for (j = 0; j < 8; ++j) {
756 c->capability[offset * max + (sz - i - 1)] = v;
762 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
767 assert(c->allocated);
769 if (!(mask & SD_BUS_CREDS_AUGMENT))
772 /* Try to retrieve PID from creds if it wasn't passed to us */
775 c->mask |= SD_BUS_CREDS_PID;
776 } else if (c->mask & SD_BUS_CREDS_PID)
779 /* Without pid we cannot do much... */
782 /* Try to retrieve TID from creds if it wasn't passed to us */
783 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
786 /* Calculate what we shall and can add */
787 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);
793 c->mask |= SD_BUS_CREDS_TID;
796 if (missing & (SD_BUS_CREDS_PPID |
797 SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
798 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
799 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
800 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
801 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
803 _cleanup_fclose_ FILE *f = NULL;
806 p = procfs_file_alloca(pid, "status");
812 else if (!IN_SET(errno, EPERM, EACCES))
817 FOREACH_LINE(line, f, return -errno) {
820 if (missing & SD_BUS_CREDS_PPID) {
821 p = startswith(line, "PPid:");
823 p += strspn(p, WHITESPACE);
825 /* Explicitly check for PPID 0 (which is the case for PID 1) */
826 if (!streq(p, "0")) {
827 r = parse_pid(p, &c->ppid);
834 c->mask |= SD_BUS_CREDS_PPID;
839 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
840 p = startswith(line, "Uid:");
842 unsigned long uid, euid, suid, fsuid;
844 p += strspn(p, WHITESPACE);
845 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
848 if (missing & SD_BUS_CREDS_UID)
849 c->uid = (uid_t) uid;
850 if (missing & SD_BUS_CREDS_EUID)
851 c->euid = (uid_t) euid;
852 if (missing & SD_BUS_CREDS_SUID)
853 c->suid = (uid_t) suid;
854 if (missing & SD_BUS_CREDS_FSUID)
855 c->fsuid = (uid_t) fsuid;
857 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
862 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
863 p = startswith(line, "Gid:");
865 unsigned long gid, egid, sgid, fsgid;
867 p += strspn(p, WHITESPACE);
868 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
871 if (missing & SD_BUS_CREDS_GID)
872 c->gid = (gid_t) gid;
873 if (missing & SD_BUS_CREDS_EGID)
874 c->egid = (gid_t) egid;
875 if (missing & SD_BUS_CREDS_SGID)
876 c->sgid = (gid_t) sgid;
877 if (missing & SD_BUS_CREDS_FSGID)
878 c->fsgid = (gid_t) fsgid;
880 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
885 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
886 p = startswith(line, "Groups:");
888 size_t allocated = 0;
894 p += strspn(p, WHITESPACE);
898 if (sscanf(p, "%lu%n", &g, &n) != 1)
901 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
904 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
908 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
913 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
914 p = startswith(line, "CapEff:");
916 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
920 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
925 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
926 p = startswith(line, "CapPrm:");
928 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
932 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
937 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
938 p = startswith(line, "CapInh:");
940 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
944 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
949 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
950 p = startswith(line, "CapBnd:");
952 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
956 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
964 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
967 p = procfs_file_alloca(pid, "attr/current");
968 r = read_one_line_file(p, &c->label);
970 if (!IN_SET(r, -ENOENT, -EINVAL, -EPERM, -EACCES))
973 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
976 if (missing & SD_BUS_CREDS_COMM) {
977 r = get_process_comm(pid, &c->comm);
979 if (!IN_SET(r, -EPERM, -EACCES))
982 c->mask |= SD_BUS_CREDS_COMM;
985 if (missing & SD_BUS_CREDS_EXE) {
986 r = get_process_exe(pid, &c->exe);
988 /* Unfortunately we cannot really distinguish
989 * the case here where the process does not
990 * exist, and /proc/$PID/exe being unreadable
991 * because $PID is a kernel thread. Hence,
992 * assume it is a kernel thread, and rely on
993 * that this case is caught with a later
996 c->mask |= SD_BUS_CREDS_EXE;
998 if (!IN_SET(r, -EPERM, -EACCES))
1001 c->mask |= SD_BUS_CREDS_EXE;
1004 if (missing & SD_BUS_CREDS_CMDLINE) {
1007 p = procfs_file_alloca(pid, "cmdline");
1008 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
1012 if (!IN_SET(r, -EPERM, -EACCES))
1015 if (c->cmdline_size == 0)
1016 c->cmdline = mfree(c->cmdline);
1018 c->mask |= SD_BUS_CREDS_CMDLINE;
1022 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
1023 _cleanup_free_ char *p = NULL;
1025 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
1028 r = read_one_line_file(p, &c->tid_comm);
1032 if (!IN_SET(r, -EPERM, -EACCES))
1035 c->mask |= SD_BUS_CREDS_TID_COMM;
1038 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)) {
1041 r = cg_pid_get_path(NULL, pid, &c->cgroup);
1043 if (!IN_SET(r, -EPERM, -EACCES))
1048 if (!c->cgroup_root) {
1049 r = cg_get_root_path(&c->cgroup_root);
1055 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);
1058 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1059 r = audit_session_from_pid(pid, &c->audit_session_id);
1060 if (r == -ENODATA) {
1061 /* ENODATA means: no audit session id assigned */
1062 c->audit_session_id = AUDIT_SESSION_INVALID;
1063 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1065 if (!IN_SET(r, -EOPNOTSUPP, -ENOENT, -EPERM, -EACCES))
1068 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1071 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1072 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
1073 if (r == -ENODATA) {
1074 /* ENODATA means: no audit login uid assigned */
1075 c->audit_login_uid = UID_INVALID;
1076 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1078 if (!IN_SET(r, -EOPNOTSUPP, -ENOENT, -EPERM, -EACCES))
1081 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1084 if (missing & SD_BUS_CREDS_TTY) {
1085 r = get_ctty(pid, NULL, &c->tty);
1087 /* ENXIO means: process has no controlling TTY */
1089 c->mask |= SD_BUS_CREDS_TTY;
1091 if (!IN_SET(r, -EPERM, -EACCES, -ENOENT))
1094 c->mask |= SD_BUS_CREDS_TTY;
1097 /* In case only the exe path was to be read we cannot
1098 * distinguish the case where the exe path was unreadable
1099 * because the process was a kernel thread, or when the
1100 * process didn't exist at all. Hence, let's do a final check,
1102 if (!pid_is_alive(pid))
1105 if (tid > 0 && tid != pid && !pid_is_unwaited(tid))
1108 c->augmented = missing & c->mask;
1113 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
1114 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *n = NULL;
1120 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
1121 /* There's already all data we need, or augmentation
1122 * wasn't turned on. */
1124 *ret = sd_bus_creds_ref(c);
1128 n = bus_creds_new();
1132 /* Copy the original data over */
1134 if (c->mask & mask & SD_BUS_CREDS_PID) {
1136 n->mask |= SD_BUS_CREDS_PID;
1139 if (c->mask & mask & SD_BUS_CREDS_TID) {
1141 n->mask |= SD_BUS_CREDS_TID;
1144 if (c->mask & mask & SD_BUS_CREDS_PPID) {
1146 n->mask |= SD_BUS_CREDS_PPID;
1149 if (c->mask & mask & SD_BUS_CREDS_UID) {
1151 n->mask |= SD_BUS_CREDS_UID;
1154 if (c->mask & mask & SD_BUS_CREDS_EUID) {
1156 n->mask |= SD_BUS_CREDS_EUID;
1159 if (c->mask & mask & SD_BUS_CREDS_SUID) {
1161 n->mask |= SD_BUS_CREDS_SUID;
1164 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
1165 n->fsuid = c->fsuid;
1166 n->mask |= SD_BUS_CREDS_FSUID;
1169 if (c->mask & mask & SD_BUS_CREDS_GID) {
1171 n->mask |= SD_BUS_CREDS_GID;
1174 if (c->mask & mask & SD_BUS_CREDS_EGID) {
1176 n->mask |= SD_BUS_CREDS_EGID;
1179 if (c->mask & mask & SD_BUS_CREDS_SGID) {
1181 n->mask |= SD_BUS_CREDS_SGID;
1184 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
1185 n->fsgid = c->fsgid;
1186 n->mask |= SD_BUS_CREDS_FSGID;
1189 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
1190 if (c->supplementary_gids) {
1191 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
1192 if (!n->supplementary_gids)
1194 n->n_supplementary_gids = c->n_supplementary_gids;
1196 n->supplementary_gids = NULL;
1197 n->n_supplementary_gids = 0;
1200 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
1203 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1206 n->comm = strdup(c->comm);
1210 n->mask |= SD_BUS_CREDS_COMM;
1213 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1214 assert(c->tid_comm);
1216 n->tid_comm = strdup(c->tid_comm);
1220 n->mask |= SD_BUS_CREDS_TID_COMM;
1223 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1225 n->exe = strdup(c->exe);
1231 n->mask |= SD_BUS_CREDS_EXE;
1234 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1236 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1240 n->cmdline_size = c->cmdline_size;
1243 n->cmdline_size = 0;
1246 n->mask |= SD_BUS_CREDS_CMDLINE;
1249 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)) {
1252 n->cgroup = strdup(c->cgroup);
1256 n->cgroup_root = strdup(c->cgroup_root);
1257 if (!n->cgroup_root)
1260 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);
1263 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1264 assert(c->capability);
1266 n->capability = memdup(c->capability, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4);
1270 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);
1273 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1276 n->label = strdup(c->label);
1279 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1282 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1283 n->audit_session_id = c->audit_session_id;
1284 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1286 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1287 n->audit_login_uid = c->audit_login_uid;
1288 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1291 if (c->mask & mask & SD_BUS_CREDS_TTY) {
1293 n->tty = strdup(c->tty);
1298 n->mask |= SD_BUS_CREDS_TTY;
1301 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1302 assert(c->unique_name);
1304 n->unique_name = strdup(c->unique_name);
1305 if (!n->unique_name)
1307 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1310 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1311 if (strv_isempty(c->well_known_names))
1312 n->well_known_names = NULL;
1314 n->well_known_names = strv_copy(c->well_known_names);
1315 if (!n->well_known_names)
1318 n->well_known_names_driver = c->well_known_names_driver;
1319 n->well_known_names_local = c->well_known_names_local;
1320 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1323 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1324 assert(c->description);
1325 n->description = strdup(c->description);
1326 if (!n->description)
1328 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1331 n->augmented = c->augmented & n->mask;
1335 r = bus_creds_add_more(n, mask, 0, 0);