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 "capability.h"
28 #include "cgroup-util.h"
31 #include "bus-message.h"
34 #include "bus-creds.h"
35 #include "bus-label.h"
38 CAP_OFFSET_INHERITABLE = 0,
39 CAP_OFFSET_PERMITTED = 1,
40 CAP_OFFSET_EFFECTIVE = 2,
41 CAP_OFFSET_BOUNDING = 3
44 void bus_creds_done(sd_bus_creds *c) {
47 /* For internal bus cred structures that are allocated by
54 free(c->unescaped_description);
55 free(c->supplementary_gids);
57 free(c->well_known_names); /* note that this is an strv, but
58 * we only free the array, not the
59 * strings the array points to. The
60 * full strv we only free if
61 * c->allocated is set, see
64 strv_free(c->cmdline_array);
67 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
68 assert_return(c, NULL);
76 /* If this is an embedded creds structure, then
77 * forward ref counting to the message */
78 m = container_of(c, sd_bus_message, creds);
79 sd_bus_message_ref(m);
85 _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
102 free(c->unique_name);
103 free(c->cgroup_root);
104 free(c->description);
106 free(c->supplementary_gids);
107 c->supplementary_gids = NULL;
109 strv_free(c->well_known_names);
110 c->well_known_names = NULL;
119 m = container_of(c, sd_bus_message, creds);
120 sd_bus_message_unref(m);
127 _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
133 _public_ uint64_t sd_bus_creds_get_augmented_mask(const sd_bus_creds *c) {
139 sd_bus_creds* bus_creds_new(void) {
142 c = new0(sd_bus_creds, 1);
151 _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
155 assert_return(pid >= 0, -EINVAL);
156 assert_return(mask <= _SD_BUS_CREDS_ALL, -EOPNOTSUPP);
157 assert_return(ret, -EINVAL);
166 r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
168 sd_bus_creds_unref(c);
172 /* Check if the process existed at all, in case we haven't
173 * figured that out already */
174 if (!pid_is_alive(pid)) {
175 sd_bus_creds_unref(c);
183 _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) {
184 assert_return(c, -EINVAL);
185 assert_return(uid, -EINVAL);
187 if (!(c->mask & SD_BUS_CREDS_UID))
194 _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) {
195 assert_return(c, -EINVAL);
196 assert_return(euid, -EINVAL);
198 if (!(c->mask & SD_BUS_CREDS_EUID))
205 _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) {
206 assert_return(c, -EINVAL);
207 assert_return(suid, -EINVAL);
209 if (!(c->mask & SD_BUS_CREDS_SUID))
217 _public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) {
218 assert_return(c, -EINVAL);
219 assert_return(fsuid, -EINVAL);
221 if (!(c->mask & SD_BUS_CREDS_FSUID))
228 _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
229 assert_return(c, -EINVAL);
230 assert_return(gid, -EINVAL);
232 if (!(c->mask & SD_BUS_CREDS_GID))
239 _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) {
240 assert_return(c, -EINVAL);
241 assert_return(egid, -EINVAL);
243 if (!(c->mask & SD_BUS_CREDS_EGID))
250 _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
251 assert_return(c, -EINVAL);
252 assert_return(sgid, -EINVAL);
254 if (!(c->mask & SD_BUS_CREDS_SGID))
261 _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
262 assert_return(c, -EINVAL);
263 assert_return(fsgid, -EINVAL);
265 if (!(c->mask & SD_BUS_CREDS_FSGID))
272 _public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) {
273 assert_return(c, -EINVAL);
274 assert_return(gids, -EINVAL);
276 if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
279 *gids = c->supplementary_gids;
280 return (int) c->n_supplementary_gids;
283 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
284 assert_return(c, -EINVAL);
285 assert_return(pid, -EINVAL);
287 if (!(c->mask & SD_BUS_CREDS_PID))
295 _public_ int sd_bus_creds_get_ppid(sd_bus_creds *c, pid_t *ppid) {
296 assert_return(c, -EINVAL);
297 assert_return(ppid, -EINVAL);
299 if (!(c->mask & SD_BUS_CREDS_PPID))
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))
365 _public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) {
366 assert_return(c, -EINVAL);
367 assert_return(ret, -EINVAL);
369 if (!(c->mask & SD_BUS_CREDS_CGROUP))
377 _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {
378 assert_return(c, -EINVAL);
379 assert_return(ret, -EINVAL);
381 if (!(c->mask & SD_BUS_CREDS_UNIT))
393 _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
394 assert_return(c, -EINVAL);
395 assert_return(ret, -EINVAL);
397 if (!(c->mask & SD_BUS_CREDS_USER_UNIT))
409 _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
410 assert_return(c, -EINVAL);
411 assert_return(ret, -EINVAL);
413 if (!(c->mask & SD_BUS_CREDS_SLICE))
425 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
428 assert_return(c, -EINVAL);
429 assert_return(ret, -EINVAL);
431 if (!(c->mask & SD_BUS_CREDS_SESSION))
439 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
443 r = cg_path_get_session(shifted, (char**) &c->session);
452 _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
456 assert_return(c, -EINVAL);
457 assert_return(uid, -EINVAL);
459 if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
464 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
471 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
472 assert_return(c, -EINVAL);
474 if (!(c->mask & SD_BUS_CREDS_CMDLINE))
477 assert_return(c->cmdline, -ESRCH);
480 if (!c->cmdline_array) {
481 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
482 if (!c->cmdline_array)
486 *cmdline = c->cmdline_array;
490 _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
491 assert_return(c, -EINVAL);
492 assert_return(sessionid, -EINVAL);
494 if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
497 *sessionid = c->audit_session_id;
501 _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
502 assert_return(c, -EINVAL);
503 assert_return(uid, -EINVAL);
505 if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID))
508 *uid = c->audit_login_uid;
512 _public_ int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **unique_name) {
513 assert_return(c, -EINVAL);
514 assert_return(unique_name, -EINVAL);
516 if (!(c->mask & SD_BUS_CREDS_UNIQUE_NAME))
519 *unique_name = c->unique_name;
523 _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) {
524 assert_return(c, -EINVAL);
525 assert_return(well_known_names, -EINVAL);
527 if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
530 /* As a special hack we return the bus driver as well-known
531 * names list when this is requested. */
532 if (c->well_known_names_driver) {
533 static const char* const wkn[] = {
534 "org.freedesktop.DBus",
538 *well_known_names = (char**) wkn;
542 if (c->well_known_names_local) {
543 static const char* const wkn[] = {
544 "org.freedesktop.DBus.Local",
548 *well_known_names = (char**) wkn;
552 *well_known_names = c->well_known_names;
556 _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) {
557 assert_return(c, -EINVAL);
558 assert_return(ret, -EINVAL);
560 if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
563 assert(c->description);
565 if (!c->unescaped_description) {
566 c->unescaped_description = bus_label_unescape(c->description);
567 if (!c->unescaped_description)
571 *ret = c->unescaped_description;
575 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
579 assert(capability >= 0);
580 assert(c->capability);
582 if ((unsigned) capability > cap_last_cap())
585 sz = DIV_ROUND_UP(cap_last_cap(), 32U);
587 return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability));
590 _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
591 assert_return(c, -EINVAL);
592 assert_return(capability >= 0, -EINVAL);
594 if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS))
597 return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
600 _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
601 assert_return(c, -EINVAL);
602 assert_return(capability >= 0, -EINVAL);
604 if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS))
607 return has_cap(c, CAP_OFFSET_PERMITTED, capability);
610 _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
611 assert_return(c, -EINVAL);
612 assert_return(capability >= 0, -EINVAL);
614 if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS))
617 return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
620 _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) {
621 assert_return(c, -EINVAL);
622 assert_return(capability >= 0, -EINVAL);
624 if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS))
627 return has_cap(c, CAP_OFFSET_BOUNDING, capability);
630 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
637 max = DIV_ROUND_UP(cap_last_cap(), 32U);
638 p += strspn(p, WHITESPACE);
648 if (!c->capability) {
649 c->capability = new0(uint32_t, max * 4);
654 for (i = 0; i < sz; i ++) {
657 for (j = 0; j < 8; ++j) {
667 c->capability[offset * max + (sz - i - 1)] = v;
673 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
678 assert(c->allocated);
680 if (!(mask & SD_BUS_CREDS_AUGMENT))
683 /* Try to retrieve PID from creds if it wasn't passed to us */
684 if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
687 /* Without pid we cannot do much... */
691 /* Try to retrieve TID from creds if it wasn't passed to us */
692 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
695 /* Calculate what we shall and can add */
696 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);
701 c->mask |= SD_BUS_CREDS_PID;
705 c->mask |= SD_BUS_CREDS_TID;
708 if (missing & (SD_BUS_CREDS_PPID |
709 SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
710 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
711 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
712 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
713 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
715 _cleanup_fclose_ FILE *f = NULL;
718 p = procfs_file_alloca(pid, "status");
724 else if (errno != EPERM && errno != EACCES)
729 FOREACH_LINE(line, f, return -errno) {
732 if (missing & SD_BUS_CREDS_PPID) {
733 p = startswith(line, "PPid:");
735 p += strspn(p, WHITESPACE);
737 /* Explicitly check for PPID 0 (which is the case for PID 1) */
738 if (!streq(p, "0")) {
739 r = parse_pid(p, &c->ppid);
743 c->mask |= SD_BUS_CREDS_PPID;
749 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
750 p = startswith(line, "Uid:");
752 unsigned long uid, euid, suid, fsuid;
754 p += strspn(p, WHITESPACE);
755 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
758 if (missing & SD_BUS_CREDS_UID)
759 c->uid = (uid_t) uid;
760 if (missing & SD_BUS_CREDS_EUID)
761 c->euid = (uid_t) euid;
762 if (missing & SD_BUS_CREDS_SUID)
763 c->suid = (uid_t) suid;
764 if (missing & SD_BUS_CREDS_FSUID)
765 c->fsuid = (uid_t) fsuid;
767 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
772 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
773 p = startswith(line, "Gid:");
775 unsigned long gid, egid, sgid, fsgid;
777 p += strspn(p, WHITESPACE);
778 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
781 if (missing & SD_BUS_CREDS_GID)
782 c->gid = (gid_t) gid;
783 if (missing & SD_BUS_CREDS_EGID)
784 c->egid = (gid_t) egid;
785 if (missing & SD_BUS_CREDS_SGID)
786 c->sgid = (gid_t) sgid;
787 if (missing & SD_BUS_CREDS_FSGID)
788 c->fsgid = (gid_t) fsgid;
790 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
795 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
796 p = startswith(line, "Groups:");
798 size_t allocated = 0;
804 p += strspn(p, WHITESPACE);
808 if (sscanf(p, "%lu%n", &g, &n) != 1)
811 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
814 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
818 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
823 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
824 p = startswith(line, "CapEff:");
826 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
830 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
835 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
836 p = startswith(line, "CapPrm:");
838 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
842 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
847 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
848 p = startswith(line, "CapInh:");
850 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
854 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
859 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
860 p = startswith(line, "CapBnd:");
862 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
866 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
874 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
877 p = procfs_file_alloca(pid, "attr/current");
878 r = read_one_line_file(p, &c->label);
880 if (r != -ENOENT && r != -EINVAL && r != -EPERM && r != -EACCES)
883 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
886 if (missing & SD_BUS_CREDS_COMM) {
887 r = get_process_comm(pid, &c->comm);
889 if (r != -EPERM && r != -EACCES)
892 c->mask |= SD_BUS_CREDS_COMM;
895 if (missing & SD_BUS_CREDS_EXE) {
896 r = get_process_exe(pid, &c->exe);
898 if (r != -EPERM && r != -EACCES)
901 c->mask |= SD_BUS_CREDS_EXE;
904 if (missing & SD_BUS_CREDS_CMDLINE) {
907 p = procfs_file_alloca(pid, "cmdline");
908 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
912 if (r != -EPERM && r != -EACCES)
915 if (c->cmdline_size == 0) {
919 c->mask |= SD_BUS_CREDS_CMDLINE;
923 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
924 _cleanup_free_ char *p = NULL;
926 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
929 r = read_one_line_file(p, &c->tid_comm);
933 if (r != -EPERM && r != -EACCES)
936 c->mask |= SD_BUS_CREDS_TID_COMM;
939 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)) {
942 r = cg_pid_get_path(NULL, pid, &c->cgroup);
944 if (r != -EPERM && r != -EACCES)
949 if (!c->cgroup_root) {
950 r = cg_get_root_path(&c->cgroup_root);
956 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);
959 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
960 r = audit_session_from_pid(pid, &c->audit_session_id);
962 if (r != -EOPNOTSUPP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
965 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
968 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
969 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
971 if (r != -EOPNOTSUPP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
974 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
977 c->augmented = missing & c->mask;
982 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
983 _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL;
989 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
990 /* There's already all data we need, or augmentation
991 * wasn't turned on. */
993 *ret = sd_bus_creds_ref(c);
1001 /* Copy the original data over */
1003 if (c->mask & mask & SD_BUS_CREDS_PID) {
1005 n->mask |= SD_BUS_CREDS_PID;
1008 if (c->mask & mask & SD_BUS_CREDS_TID) {
1010 n->mask |= SD_BUS_CREDS_TID;
1013 if (c->mask & mask & SD_BUS_CREDS_PPID) {
1015 n->mask |= SD_BUS_CREDS_PPID;
1018 if (c->mask & mask & SD_BUS_CREDS_UID) {
1020 n->mask |= SD_BUS_CREDS_UID;
1023 if (c->mask & mask & SD_BUS_CREDS_EUID) {
1025 n->mask |= SD_BUS_CREDS_EUID;
1028 if (c->mask & mask & SD_BUS_CREDS_SUID) {
1030 n->mask |= SD_BUS_CREDS_SUID;
1033 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
1034 n->fsuid = c->fsuid;
1035 n->mask |= SD_BUS_CREDS_FSUID;
1038 if (c->mask & mask & SD_BUS_CREDS_GID) {
1040 n->mask |= SD_BUS_CREDS_GID;
1043 if (c->mask & mask & SD_BUS_CREDS_EGID) {
1045 n->mask |= SD_BUS_CREDS_EGID;
1048 if (c->mask & mask & SD_BUS_CREDS_SGID) {
1050 n->mask |= SD_BUS_CREDS_SGID;
1053 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
1054 n->fsgid = c->fsgid;
1055 n->mask |= SD_BUS_CREDS_FSGID;
1058 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
1059 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
1060 if (!n->supplementary_gids)
1062 n->n_supplementary_gids = c->n_supplementary_gids;
1063 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
1066 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1067 n->comm = strdup(c->comm);
1071 n->mask |= SD_BUS_CREDS_COMM;
1074 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1075 n->tid_comm = strdup(c->tid_comm);
1079 n->mask |= SD_BUS_CREDS_TID_COMM;
1082 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1083 n->exe = strdup(c->exe);
1087 n->mask |= SD_BUS_CREDS_EXE;
1090 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1091 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1095 n->cmdline_size = c->cmdline_size;
1096 n->mask |= SD_BUS_CREDS_CMDLINE;
1099 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)) {
1100 n->cgroup = strdup(c->cgroup);
1104 n->cgroup_root = strdup(c->cgroup_root);
1105 if (!n->cgroup_root)
1108 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);
1111 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1112 n->capability = memdup(c->capability, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4);
1116 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);
1119 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1120 n->label = strdup(c->label);
1123 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1126 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1127 n->audit_session_id = c->audit_session_id;
1128 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1130 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1131 n->audit_login_uid = c->audit_login_uid;
1132 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1135 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1136 n->unique_name = strdup(c->unique_name);
1137 if (!n->unique_name)
1139 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1142 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1143 n->well_known_names = strv_copy(c->well_known_names);
1144 if (!n->well_known_names)
1146 n->well_known_names_driver = c->well_known_names_driver;
1147 n->well_known_names_local = c->well_known_names_local;
1148 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1151 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1152 n->description = strdup(c->description);
1153 if (!n->description)
1155 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1158 n->augmented = c->augmented & n->mask;
1162 r = bus_creds_add_more(n, mask, 0, 0);