1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <linux/capability.h>
26 #include "formats-util.h"
27 #include "process-util.h"
28 #include "terminal-util.h"
29 #include "capability.h"
30 #include "cgroup-util.h"
33 #include "bus-message.h"
36 #include "bus-creds.h"
37 #include "bus-label.h"
40 CAP_OFFSET_INHERITABLE = 0,
41 CAP_OFFSET_PERMITTED = 1,
42 CAP_OFFSET_EFFECTIVE = 2,
43 CAP_OFFSET_BOUNDING = 3
46 void bus_creds_done(sd_bus_creds *c) {
49 /* For internal bus cred structures that are allocated by
56 free(c->unescaped_description);
57 free(c->supplementary_gids);
60 free(c->well_known_names); /* note that this is an strv, but
61 * we only free the array, not the
62 * strings the array points to. The
63 * full strv we only free if
64 * c->allocated is set, see
67 strv_free(c->cmdline_array);
70 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
71 assert_return(c, NULL);
79 /* If this is an embedded creds structure, then
80 * forward ref counting to the message */
81 m = container_of(c, sd_bus_message, creds);
82 sd_bus_message_ref(m);
88 _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
105 free(c->unique_name);
106 free(c->cgroup_root);
107 free(c->description);
109 free(c->supplementary_gids);
110 c->supplementary_gids = NULL;
112 strv_free(c->well_known_names);
113 c->well_known_names = NULL;
122 m = container_of(c, sd_bus_message, creds);
123 sd_bus_message_unref(m);
130 _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
136 _public_ uint64_t sd_bus_creds_get_augmented_mask(const sd_bus_creds *c) {
142 sd_bus_creds* bus_creds_new(void) {
145 c = new0(sd_bus_creds, 1);
154 _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
158 assert_return(pid >= 0, -EINVAL);
159 assert_return(mask <= _SD_BUS_CREDS_ALL, -EOPNOTSUPP);
160 assert_return(ret, -EINVAL);
169 r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
171 sd_bus_creds_unref(c);
175 /* Check if the process existed at all, in case we haven't
176 * figured that out already */
177 if (!pid_is_alive(pid)) {
178 sd_bus_creds_unref(c);
186 _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) {
187 assert_return(c, -EINVAL);
188 assert_return(uid, -EINVAL);
190 if (!(c->mask & SD_BUS_CREDS_UID))
197 _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) {
198 assert_return(c, -EINVAL);
199 assert_return(euid, -EINVAL);
201 if (!(c->mask & SD_BUS_CREDS_EUID))
208 _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) {
209 assert_return(c, -EINVAL);
210 assert_return(suid, -EINVAL);
212 if (!(c->mask & SD_BUS_CREDS_SUID))
220 _public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) {
221 assert_return(c, -EINVAL);
222 assert_return(fsuid, -EINVAL);
224 if (!(c->mask & SD_BUS_CREDS_FSUID))
231 _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
232 assert_return(c, -EINVAL);
233 assert_return(gid, -EINVAL);
235 if (!(c->mask & SD_BUS_CREDS_GID))
242 _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) {
243 assert_return(c, -EINVAL);
244 assert_return(egid, -EINVAL);
246 if (!(c->mask & SD_BUS_CREDS_EGID))
253 _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
254 assert_return(c, -EINVAL);
255 assert_return(sgid, -EINVAL);
257 if (!(c->mask & SD_BUS_CREDS_SGID))
264 _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
265 assert_return(c, -EINVAL);
266 assert_return(fsgid, -EINVAL);
268 if (!(c->mask & SD_BUS_CREDS_FSGID))
275 _public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) {
276 assert_return(c, -EINVAL);
277 assert_return(gids, -EINVAL);
279 if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
282 *gids = c->supplementary_gids;
283 return (int) c->n_supplementary_gids;
286 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
287 assert_return(c, -EINVAL);
288 assert_return(pid, -EINVAL);
290 if (!(c->mask & SD_BUS_CREDS_PID))
298 _public_ int sd_bus_creds_get_ppid(sd_bus_creds *c, pid_t *ppid) {
299 assert_return(c, -EINVAL);
300 assert_return(ppid, -EINVAL);
302 if (!(c->mask & SD_BUS_CREDS_PPID))
305 /* PID 1 has no parent process. Let's distuingish the case of
306 * not knowing and not having a parent process by the returned
315 _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) {
316 assert_return(c, -EINVAL);
317 assert_return(tid, -EINVAL);
319 if (!(c->mask & SD_BUS_CREDS_TID))
327 _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
328 assert_return(c, -EINVAL);
330 if (!(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT))
338 _public_ int sd_bus_creds_get_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_COMM))
350 _public_ int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **ret) {
351 assert_return(c, -EINVAL);
352 assert_return(ret, -EINVAL);
354 if (!(c->mask & SD_BUS_CREDS_TID_COMM))
362 _public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) {
363 assert_return(c, -EINVAL);
364 assert_return(ret, -EINVAL);
366 if (!(c->mask & SD_BUS_CREDS_EXE))
376 _public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) {
377 assert_return(c, -EINVAL);
378 assert_return(ret, -EINVAL);
380 if (!(c->mask & SD_BUS_CREDS_CGROUP))
388 _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {
389 assert_return(c, -EINVAL);
390 assert_return(ret, -EINVAL);
392 if (!(c->mask & SD_BUS_CREDS_UNIT))
404 _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
405 assert_return(c, -EINVAL);
406 assert_return(ret, -EINVAL);
408 if (!(c->mask & SD_BUS_CREDS_USER_UNIT))
420 _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
421 assert_return(c, -EINVAL);
422 assert_return(ret, -EINVAL);
424 if (!(c->mask & SD_BUS_CREDS_SLICE))
436 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
439 assert_return(c, -EINVAL);
440 assert_return(ret, -EINVAL);
442 if (!(c->mask & SD_BUS_CREDS_SESSION))
450 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
454 r = cg_path_get_session(shifted, (char**) &c->session);
463 _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
467 assert_return(c, -EINVAL);
468 assert_return(uid, -EINVAL);
470 if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
475 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
482 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
483 assert_return(c, -EINVAL);
485 if (!(c->mask & SD_BUS_CREDS_CMDLINE))
491 if (!c->cmdline_array) {
492 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
493 if (!c->cmdline_array)
497 *cmdline = c->cmdline_array;
501 _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
502 assert_return(c, -EINVAL);
503 assert_return(sessionid, -EINVAL);
505 if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
508 if (c->audit_session_id == AUDIT_SESSION_INVALID)
511 *sessionid = c->audit_session_id;
515 _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
516 assert_return(c, -EINVAL);
517 assert_return(uid, -EINVAL);
519 if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID))
522 if (c->audit_login_uid == UID_INVALID)
525 *uid = c->audit_login_uid;
529 _public_ int sd_bus_creds_get_tty(sd_bus_creds *c, const char **ret) {
530 assert_return(c, -EINVAL);
531 assert_return(ret, -EINVAL);
533 if (!(c->mask & SD_BUS_CREDS_TTY))
543 _public_ int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **unique_name) {
544 assert_return(c, -EINVAL);
545 assert_return(unique_name, -EINVAL);
547 if (!(c->mask & SD_BUS_CREDS_UNIQUE_NAME))
550 *unique_name = c->unique_name;
554 _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) {
555 assert_return(c, -EINVAL);
556 assert_return(well_known_names, -EINVAL);
558 if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
561 /* As a special hack we return the bus driver as well-known
562 * names list when this is requested. */
563 if (c->well_known_names_driver) {
564 static const char* const wkn[] = {
565 "org.freedesktop.DBus",
569 *well_known_names = (char**) wkn;
573 if (c->well_known_names_local) {
574 static const char* const wkn[] = {
575 "org.freedesktop.DBus.Local",
579 *well_known_names = (char**) wkn;
583 *well_known_names = c->well_known_names;
587 _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) {
588 assert_return(c, -EINVAL);
589 assert_return(ret, -EINVAL);
591 if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
594 assert(c->description);
596 if (!c->unescaped_description) {
597 c->unescaped_description = bus_label_unescape(c->description);
598 if (!c->unescaped_description)
602 *ret = c->unescaped_description;
606 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
610 assert(capability >= 0);
611 assert(c->capability);
613 if ((unsigned) capability > cap_last_cap())
616 sz = DIV_ROUND_UP(cap_last_cap(), 32U);
618 return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability));
621 _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
622 assert_return(c, -EINVAL);
623 assert_return(capability >= 0, -EINVAL);
625 if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS))
628 return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
631 _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
632 assert_return(c, -EINVAL);
633 assert_return(capability >= 0, -EINVAL);
635 if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS))
638 return has_cap(c, CAP_OFFSET_PERMITTED, capability);
641 _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
642 assert_return(c, -EINVAL);
643 assert_return(capability >= 0, -EINVAL);
645 if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS))
648 return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
651 _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) {
652 assert_return(c, -EINVAL);
653 assert_return(capability >= 0, -EINVAL);
655 if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS))
658 return has_cap(c, CAP_OFFSET_BOUNDING, capability);
661 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
668 max = DIV_ROUND_UP(cap_last_cap(), 32U);
669 p += strspn(p, WHITESPACE);
679 if (!c->capability) {
680 c->capability = new0(uint32_t, max * 4);
685 for (i = 0; i < sz; i ++) {
688 for (j = 0; j < 8; ++j) {
698 c->capability[offset * max + (sz - i - 1)] = v;
704 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
709 assert(c->allocated);
711 if (!(mask & SD_BUS_CREDS_AUGMENT))
714 /* Try to retrieve PID from creds if it wasn't passed to us */
715 if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
718 /* Without pid we cannot do much... */
722 /* Try to retrieve TID from creds if it wasn't passed to us */
723 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
726 /* Calculate what we shall and can add */
727 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);
732 c->mask |= SD_BUS_CREDS_PID;
736 c->mask |= SD_BUS_CREDS_TID;
739 if (missing & (SD_BUS_CREDS_PPID |
740 SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
741 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
742 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
743 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
744 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
746 _cleanup_fclose_ FILE *f = NULL;
749 p = procfs_file_alloca(pid, "status");
755 else if (errno != EPERM && errno != EACCES)
760 FOREACH_LINE(line, f, return -errno) {
763 if (missing & SD_BUS_CREDS_PPID) {
764 p = startswith(line, "PPid:");
766 p += strspn(p, WHITESPACE);
768 /* Explicitly check for PPID 0 (which is the case for PID 1) */
769 if (!streq(p, "0")) {
770 r = parse_pid(p, &c->ppid);
777 c->mask |= SD_BUS_CREDS_PPID;
782 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
783 p = startswith(line, "Uid:");
785 unsigned long uid, euid, suid, fsuid;
787 p += strspn(p, WHITESPACE);
788 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
791 if (missing & SD_BUS_CREDS_UID)
792 c->uid = (uid_t) uid;
793 if (missing & SD_BUS_CREDS_EUID)
794 c->euid = (uid_t) euid;
795 if (missing & SD_BUS_CREDS_SUID)
796 c->suid = (uid_t) suid;
797 if (missing & SD_BUS_CREDS_FSUID)
798 c->fsuid = (uid_t) fsuid;
800 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
805 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
806 p = startswith(line, "Gid:");
808 unsigned long gid, egid, sgid, fsgid;
810 p += strspn(p, WHITESPACE);
811 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
814 if (missing & SD_BUS_CREDS_GID)
815 c->gid = (gid_t) gid;
816 if (missing & SD_BUS_CREDS_EGID)
817 c->egid = (gid_t) egid;
818 if (missing & SD_BUS_CREDS_SGID)
819 c->sgid = (gid_t) sgid;
820 if (missing & SD_BUS_CREDS_FSGID)
821 c->fsgid = (gid_t) fsgid;
823 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
828 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
829 p = startswith(line, "Groups:");
831 size_t allocated = 0;
837 p += strspn(p, WHITESPACE);
841 if (sscanf(p, "%lu%n", &g, &n) != 1)
844 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
847 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
851 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
856 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
857 p = startswith(line, "CapEff:");
859 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
863 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
868 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
869 p = startswith(line, "CapPrm:");
871 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
875 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
880 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
881 p = startswith(line, "CapInh:");
883 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
887 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
892 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
893 p = startswith(line, "CapBnd:");
895 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
899 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
907 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
910 p = procfs_file_alloca(pid, "attr/current");
911 r = read_one_line_file(p, &c->label);
913 if (r != -ENOENT && r != -EINVAL && r != -EPERM && r != -EACCES)
916 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
919 if (missing & SD_BUS_CREDS_COMM) {
920 r = get_process_comm(pid, &c->comm);
922 if (r != -EPERM && r != -EACCES)
925 c->mask |= SD_BUS_CREDS_COMM;
928 if (missing & SD_BUS_CREDS_EXE) {
929 r = get_process_exe(pid, &c->exe);
931 /* Unfortunately we cannot really distuingish
932 * the case here where the process does not
933 * exist, and /proc/$PID/exe being unreadable
934 * because $PID is a kernel thread. Hence,
935 * assume it is a kernel thread, and rely on
936 * that this case is caught with a later
939 c->mask |= SD_BUS_CREDS_EXE;
941 if (r != -EPERM && r != -EACCES)
944 c->mask |= SD_BUS_CREDS_EXE;
947 if (missing & SD_BUS_CREDS_CMDLINE) {
950 p = procfs_file_alloca(pid, "cmdline");
951 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
955 if (r != -EPERM && r != -EACCES)
958 if (c->cmdline_size == 0) {
963 c->mask |= SD_BUS_CREDS_CMDLINE;
967 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
968 _cleanup_free_ char *p = NULL;
970 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
973 r = read_one_line_file(p, &c->tid_comm);
977 if (r != -EPERM && r != -EACCES)
980 c->mask |= SD_BUS_CREDS_TID_COMM;
983 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)) {
986 r = cg_pid_get_path(NULL, pid, &c->cgroup);
988 if (r != -EPERM && r != -EACCES)
993 if (!c->cgroup_root) {
994 r = cg_get_root_path(&c->cgroup_root);
1000 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);
1003 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1004 r = audit_session_from_pid(pid, &c->audit_session_id);
1006 /* ENXIO means: no audit session id assigned */
1007 c->audit_session_id = AUDIT_SESSION_INVALID;
1008 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1010 if (r != -EOPNOTSUPP && r != -ENOENT && r != -EPERM && r != -EACCES)
1013 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1016 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1017 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
1019 /* ENXIO means: no audit login uid assigned */
1020 c->audit_login_uid = UID_INVALID;
1021 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1023 if (r != -EOPNOTSUPP && r != -ENOENT && r != -EPERM && r != -EACCES)
1026 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1029 if (missing & SD_BUS_CREDS_TTY) {
1030 r = get_ctty(pid, NULL, &c->tty);
1032 /* ENXIO means: process has no controlling TTY */
1034 c->mask |= SD_BUS_CREDS_TTY;
1036 if (r != -EPERM && r != -EACCES && r != -ENOENT)
1039 c->mask |= SD_BUS_CREDS_TTY;
1042 /* In case only the exe path was to be read we cannot
1043 * distuingish the case where the exe path was unreadable
1044 * because the process was a kernel thread, or when the
1045 * process didn't exist at all. Hence, let's do a final check,
1047 if (!pid_is_alive(pid))
1050 if (tid > 0 && tid != pid && !pid_is_unwaited(tid))
1053 c->augmented = missing & c->mask;
1058 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
1059 _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL;
1065 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
1066 /* There's already all data we need, or augmentation
1067 * wasn't turned on. */
1069 *ret = sd_bus_creds_ref(c);
1073 n = bus_creds_new();
1077 /* Copy the original data over */
1079 if (c->mask & mask & SD_BUS_CREDS_PID) {
1081 n->mask |= SD_BUS_CREDS_PID;
1084 if (c->mask & mask & SD_BUS_CREDS_TID) {
1086 n->mask |= SD_BUS_CREDS_TID;
1089 if (c->mask & mask & SD_BUS_CREDS_PPID) {
1091 n->mask |= SD_BUS_CREDS_PPID;
1094 if (c->mask & mask & SD_BUS_CREDS_UID) {
1096 n->mask |= SD_BUS_CREDS_UID;
1099 if (c->mask & mask & SD_BUS_CREDS_EUID) {
1101 n->mask |= SD_BUS_CREDS_EUID;
1104 if (c->mask & mask & SD_BUS_CREDS_SUID) {
1106 n->mask |= SD_BUS_CREDS_SUID;
1109 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
1110 n->fsuid = c->fsuid;
1111 n->mask |= SD_BUS_CREDS_FSUID;
1114 if (c->mask & mask & SD_BUS_CREDS_GID) {
1116 n->mask |= SD_BUS_CREDS_GID;
1119 if (c->mask & mask & SD_BUS_CREDS_EGID) {
1121 n->mask |= SD_BUS_CREDS_EGID;
1124 if (c->mask & mask & SD_BUS_CREDS_SGID) {
1126 n->mask |= SD_BUS_CREDS_SGID;
1129 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
1130 n->fsgid = c->fsgid;
1131 n->mask |= SD_BUS_CREDS_FSGID;
1134 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
1135 if (c->supplementary_gids) {
1136 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
1137 if (!n->supplementary_gids)
1139 n->n_supplementary_gids = c->n_supplementary_gids;
1141 n->supplementary_gids = NULL;
1142 n->n_supplementary_gids = 0;
1145 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
1148 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1151 n->comm = strdup(c->comm);
1155 n->mask |= SD_BUS_CREDS_COMM;
1158 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1159 assert(c->tid_comm);
1161 n->tid_comm = strdup(c->tid_comm);
1165 n->mask |= SD_BUS_CREDS_TID_COMM;
1168 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1170 n->exe = strdup(c->exe);
1176 n->mask |= SD_BUS_CREDS_EXE;
1179 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1181 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1185 n->cmdline_size = c->cmdline_size;
1188 n->cmdline_size = 0;
1191 n->mask |= SD_BUS_CREDS_CMDLINE;
1194 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)) {
1197 n->cgroup = strdup(c->cgroup);
1201 n->cgroup_root = strdup(c->cgroup_root);
1202 if (!n->cgroup_root)
1205 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);
1208 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1209 assert(c->capability);
1211 n->capability = memdup(c->capability, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4);
1215 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);
1218 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1221 n->label = strdup(c->label);
1224 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1227 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1228 n->audit_session_id = c->audit_session_id;
1229 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1231 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1232 n->audit_login_uid = c->audit_login_uid;
1233 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1236 if (c->mask & mask & SD_BUS_CREDS_TTY) {
1238 n->tty = strdup(c->tty);
1243 n->mask |= SD_BUS_CREDS_TTY;
1246 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1247 assert(c->unique_name);
1249 n->unique_name = strdup(c->unique_name);
1250 if (!n->unique_name)
1252 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1255 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1256 if (strv_isempty(c->well_known_names))
1257 n->well_known_names = NULL;
1259 n->well_known_names = strv_copy(c->well_known_names);
1260 if (!n->well_known_names)
1263 n->well_known_names_driver = c->well_known_names_driver;
1264 n->well_known_names_local = c->well_known_names_local;
1265 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1268 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1269 assert(c->description);
1270 n->description = strdup(c->description);
1271 if (!n->description)
1273 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1276 n->augmented = c->augmented & n->mask;
1280 r = bus_creds_add_more(n, mask, 0, 0);