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))
309 _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) {
310 assert_return(c, -EINVAL);
311 assert_return(tid, -EINVAL);
313 if (!(c->mask & SD_BUS_CREDS_TID))
321 _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
322 assert_return(c, -EINVAL);
324 if (!(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT))
332 _public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) {
333 assert_return(c, -EINVAL);
334 assert_return(ret, -EINVAL);
336 if (!(c->mask & SD_BUS_CREDS_COMM))
344 _public_ int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **ret) {
345 assert_return(c, -EINVAL);
346 assert_return(ret, -EINVAL);
348 if (!(c->mask & SD_BUS_CREDS_TID_COMM))
356 _public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) {
357 assert_return(c, -EINVAL);
358 assert_return(ret, -EINVAL);
360 if (!(c->mask & SD_BUS_CREDS_EXE))
368 _public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) {
369 assert_return(c, -EINVAL);
370 assert_return(ret, -EINVAL);
372 if (!(c->mask & SD_BUS_CREDS_CGROUP))
380 _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {
381 assert_return(c, -EINVAL);
382 assert_return(ret, -EINVAL);
384 if (!(c->mask & SD_BUS_CREDS_UNIT))
396 _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
397 assert_return(c, -EINVAL);
398 assert_return(ret, -EINVAL);
400 if (!(c->mask & SD_BUS_CREDS_USER_UNIT))
412 _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
413 assert_return(c, -EINVAL);
414 assert_return(ret, -EINVAL);
416 if (!(c->mask & SD_BUS_CREDS_SLICE))
428 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
431 assert_return(c, -EINVAL);
432 assert_return(ret, -EINVAL);
434 if (!(c->mask & SD_BUS_CREDS_SESSION))
442 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
446 r = cg_path_get_session(shifted, (char**) &c->session);
455 _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
459 assert_return(c, -EINVAL);
460 assert_return(uid, -EINVAL);
462 if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
467 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
474 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
475 assert_return(c, -EINVAL);
477 if (!(c->mask & SD_BUS_CREDS_CMDLINE))
480 assert_return(c->cmdline, -ESRCH);
483 if (!c->cmdline_array) {
484 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
485 if (!c->cmdline_array)
489 *cmdline = c->cmdline_array;
493 _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
494 assert_return(c, -EINVAL);
495 assert_return(sessionid, -EINVAL);
497 if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
500 *sessionid = c->audit_session_id;
504 _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
505 assert_return(c, -EINVAL);
506 assert_return(uid, -EINVAL);
508 if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID))
511 *uid = c->audit_login_uid;
515 _public_ int sd_bus_creds_get_tty(sd_bus_creds *c, const char **ret) {
516 assert_return(c, -EINVAL);
517 assert_return(ret, -EINVAL);
519 if (!(c->mask & SD_BUS_CREDS_TTY))
526 _public_ int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **unique_name) {
527 assert_return(c, -EINVAL);
528 assert_return(unique_name, -EINVAL);
530 if (!(c->mask & SD_BUS_CREDS_UNIQUE_NAME))
533 *unique_name = c->unique_name;
537 _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) {
538 assert_return(c, -EINVAL);
539 assert_return(well_known_names, -EINVAL);
541 if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
544 /* As a special hack we return the bus driver as well-known
545 * names list when this is requested. */
546 if (c->well_known_names_driver) {
547 static const char* const wkn[] = {
548 "org.freedesktop.DBus",
552 *well_known_names = (char**) wkn;
556 if (c->well_known_names_local) {
557 static const char* const wkn[] = {
558 "org.freedesktop.DBus.Local",
562 *well_known_names = (char**) wkn;
566 *well_known_names = c->well_known_names;
570 _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) {
571 assert_return(c, -EINVAL);
572 assert_return(ret, -EINVAL);
574 if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
577 assert(c->description);
579 if (!c->unescaped_description) {
580 c->unescaped_description = bus_label_unescape(c->description);
581 if (!c->unescaped_description)
585 *ret = c->unescaped_description;
589 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
593 assert(capability >= 0);
594 assert(c->capability);
596 if ((unsigned) capability > cap_last_cap())
599 sz = DIV_ROUND_UP(cap_last_cap(), 32U);
601 return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability));
604 _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
605 assert_return(c, -EINVAL);
606 assert_return(capability >= 0, -EINVAL);
608 if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS))
611 return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
614 _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
615 assert_return(c, -EINVAL);
616 assert_return(capability >= 0, -EINVAL);
618 if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS))
621 return has_cap(c, CAP_OFFSET_PERMITTED, capability);
624 _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
625 assert_return(c, -EINVAL);
626 assert_return(capability >= 0, -EINVAL);
628 if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS))
631 return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
634 _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) {
635 assert_return(c, -EINVAL);
636 assert_return(capability >= 0, -EINVAL);
638 if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS))
641 return has_cap(c, CAP_OFFSET_BOUNDING, capability);
644 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
651 max = DIV_ROUND_UP(cap_last_cap(), 32U);
652 p += strspn(p, WHITESPACE);
662 if (!c->capability) {
663 c->capability = new0(uint32_t, max * 4);
668 for (i = 0; i < sz; i ++) {
671 for (j = 0; j < 8; ++j) {
681 c->capability[offset * max + (sz - i - 1)] = v;
687 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
692 assert(c->allocated);
694 if (!(mask & SD_BUS_CREDS_AUGMENT))
697 /* Try to retrieve PID from creds if it wasn't passed to us */
698 if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
701 /* Without pid we cannot do much... */
705 /* Try to retrieve TID from creds if it wasn't passed to us */
706 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
709 /* Calculate what we shall and can add */
710 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);
715 c->mask |= SD_BUS_CREDS_PID;
719 c->mask |= SD_BUS_CREDS_TID;
722 if (missing & (SD_BUS_CREDS_PPID |
723 SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
724 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
725 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
726 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
727 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
729 _cleanup_fclose_ FILE *f = NULL;
732 p = procfs_file_alloca(pid, "status");
738 else if (errno != EPERM && errno != EACCES)
743 FOREACH_LINE(line, f, return -errno) {
746 if (missing & SD_BUS_CREDS_PPID) {
747 p = startswith(line, "PPid:");
749 p += strspn(p, WHITESPACE);
751 /* Explicitly check for PPID 0 (which is the case for PID 1) */
752 if (!streq(p, "0")) {
753 r = parse_pid(p, &c->ppid);
757 c->mask |= SD_BUS_CREDS_PPID;
763 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
764 p = startswith(line, "Uid:");
766 unsigned long uid, euid, suid, fsuid;
768 p += strspn(p, WHITESPACE);
769 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
772 if (missing & SD_BUS_CREDS_UID)
773 c->uid = (uid_t) uid;
774 if (missing & SD_BUS_CREDS_EUID)
775 c->euid = (uid_t) euid;
776 if (missing & SD_BUS_CREDS_SUID)
777 c->suid = (uid_t) suid;
778 if (missing & SD_BUS_CREDS_FSUID)
779 c->fsuid = (uid_t) fsuid;
781 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
786 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
787 p = startswith(line, "Gid:");
789 unsigned long gid, egid, sgid, fsgid;
791 p += strspn(p, WHITESPACE);
792 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
795 if (missing & SD_BUS_CREDS_GID)
796 c->gid = (gid_t) gid;
797 if (missing & SD_BUS_CREDS_EGID)
798 c->egid = (gid_t) egid;
799 if (missing & SD_BUS_CREDS_SGID)
800 c->sgid = (gid_t) sgid;
801 if (missing & SD_BUS_CREDS_FSGID)
802 c->fsgid = (gid_t) fsgid;
804 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
809 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
810 p = startswith(line, "Groups:");
812 size_t allocated = 0;
818 p += strspn(p, WHITESPACE);
822 if (sscanf(p, "%lu%n", &g, &n) != 1)
825 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
828 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
832 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
837 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
838 p = startswith(line, "CapEff:");
840 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
844 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
849 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
850 p = startswith(line, "CapPrm:");
852 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
856 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
861 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
862 p = startswith(line, "CapInh:");
864 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
868 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
873 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
874 p = startswith(line, "CapBnd:");
876 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
880 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
888 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
891 p = procfs_file_alloca(pid, "attr/current");
892 r = read_one_line_file(p, &c->label);
894 if (r != -ENOENT && r != -EINVAL && r != -EPERM && r != -EACCES)
897 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
900 if (missing & SD_BUS_CREDS_COMM) {
901 r = get_process_comm(pid, &c->comm);
903 if (r != -EPERM && r != -EACCES)
906 c->mask |= SD_BUS_CREDS_COMM;
909 if (missing & SD_BUS_CREDS_EXE) {
910 r = get_process_exe(pid, &c->exe);
912 if (r != -EPERM && r != -EACCES)
915 c->mask |= SD_BUS_CREDS_EXE;
918 if (missing & SD_BUS_CREDS_CMDLINE) {
921 p = procfs_file_alloca(pid, "cmdline");
922 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
926 if (r != -EPERM && r != -EACCES)
929 if (c->cmdline_size == 0) {
933 c->mask |= SD_BUS_CREDS_CMDLINE;
937 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
938 _cleanup_free_ char *p = NULL;
940 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
943 r = read_one_line_file(p, &c->tid_comm);
947 if (r != -EPERM && r != -EACCES)
950 c->mask |= SD_BUS_CREDS_TID_COMM;
953 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)) {
956 r = cg_pid_get_path(NULL, pid, &c->cgroup);
958 if (r != -EPERM && r != -EACCES)
963 if (!c->cgroup_root) {
964 r = cg_get_root_path(&c->cgroup_root);
970 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);
973 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
974 r = audit_session_from_pid(pid, &c->audit_session_id);
976 if (r != -EOPNOTSUPP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
979 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
982 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
983 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
985 if (r != -EOPNOTSUPP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
988 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
991 if (missing & SD_BUS_CREDS_TTY) {
992 r = get_ctty(pid, NULL, &c->tty);
994 if (r != -EPERM && r != -EACCES && r != -ENOENT)
997 c->mask |= SD_BUS_CREDS_TTY;
1000 c->augmented = missing & c->mask;
1005 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
1006 _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL;
1012 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
1013 /* There's already all data we need, or augmentation
1014 * wasn't turned on. */
1016 *ret = sd_bus_creds_ref(c);
1020 n = bus_creds_new();
1024 /* Copy the original data over */
1026 if (c->mask & mask & SD_BUS_CREDS_PID) {
1028 n->mask |= SD_BUS_CREDS_PID;
1031 if (c->mask & mask & SD_BUS_CREDS_TID) {
1033 n->mask |= SD_BUS_CREDS_TID;
1036 if (c->mask & mask & SD_BUS_CREDS_PPID) {
1038 n->mask |= SD_BUS_CREDS_PPID;
1041 if (c->mask & mask & SD_BUS_CREDS_UID) {
1043 n->mask |= SD_BUS_CREDS_UID;
1046 if (c->mask & mask & SD_BUS_CREDS_EUID) {
1048 n->mask |= SD_BUS_CREDS_EUID;
1051 if (c->mask & mask & SD_BUS_CREDS_SUID) {
1053 n->mask |= SD_BUS_CREDS_SUID;
1056 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
1057 n->fsuid = c->fsuid;
1058 n->mask |= SD_BUS_CREDS_FSUID;
1061 if (c->mask & mask & SD_BUS_CREDS_GID) {
1063 n->mask |= SD_BUS_CREDS_GID;
1066 if (c->mask & mask & SD_BUS_CREDS_EGID) {
1068 n->mask |= SD_BUS_CREDS_EGID;
1071 if (c->mask & mask & SD_BUS_CREDS_SGID) {
1073 n->mask |= SD_BUS_CREDS_SGID;
1076 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
1077 n->fsgid = c->fsgid;
1078 n->mask |= SD_BUS_CREDS_FSGID;
1081 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
1082 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
1083 if (!n->supplementary_gids)
1085 n->n_supplementary_gids = c->n_supplementary_gids;
1086 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
1089 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1090 n->comm = strdup(c->comm);
1094 n->mask |= SD_BUS_CREDS_COMM;
1097 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1098 n->tid_comm = strdup(c->tid_comm);
1102 n->mask |= SD_BUS_CREDS_TID_COMM;
1105 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1106 n->exe = strdup(c->exe);
1110 n->mask |= SD_BUS_CREDS_EXE;
1113 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1114 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1118 n->cmdline_size = c->cmdline_size;
1119 n->mask |= SD_BUS_CREDS_CMDLINE;
1122 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)) {
1123 n->cgroup = strdup(c->cgroup);
1127 n->cgroup_root = strdup(c->cgroup_root);
1128 if (!n->cgroup_root)
1131 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);
1134 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1135 n->capability = memdup(c->capability, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4);
1139 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);
1142 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1143 n->label = strdup(c->label);
1146 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1149 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1150 n->audit_session_id = c->audit_session_id;
1151 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1153 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1154 n->audit_login_uid = c->audit_login_uid;
1155 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1158 if (c->mask & mask & SD_BUS_CREDS_TTY) {
1160 n->tty = strdup(c->tty);
1165 n->mask |= SD_BUS_CREDS_TTY;
1168 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1169 n->unique_name = strdup(c->unique_name);
1170 if (!n->unique_name)
1172 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1175 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1176 n->well_known_names = strv_copy(c->well_known_names);
1177 if (!n->well_known_names)
1179 n->well_known_names_driver = c->well_known_names_driver;
1180 n->well_known_names_local = c->well_known_names_local;
1181 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1184 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1185 n->description = strdup(c->description);
1186 if (!n->description)
1188 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1191 n->augmented = c->augmented & n->mask;
1195 r = bus_creds_add_more(n, mask, 0, 0);