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/>.
25 #include "cgroup-util.h"
28 #include "bus-message.h"
30 #include "time-util.h"
32 #include "bus-creds.h"
33 #include "bus-label.h"
36 CAP_OFFSET_INHERITABLE = 0,
37 CAP_OFFSET_PERMITTED = 1,
38 CAP_OFFSET_EFFECTIVE = 2,
39 CAP_OFFSET_BOUNDING = 3
42 void bus_creds_done(sd_bus_creds *c) {
45 /* For internal bus cred structures that are allocated by
52 free(c->unescaped_description);
54 strv_free(c->cmdline_array);
55 strv_free(c->well_known_names);
57 free(c->supplementary_gids);
60 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
61 assert_return(c, NULL);
69 /* If this is an embedded creds structure, then
70 * forward ref counting to the message */
71 m = container_of(c, sd_bus_message, creds);
72 sd_bus_message_ref(m);
78 _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
105 m = container_of(c, sd_bus_message, creds);
106 sd_bus_message_unref(m);
113 _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
119 sd_bus_creds* bus_creds_new(void) {
122 c = new0(sd_bus_creds, 1);
131 _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
135 assert_return(pid >= 0, -EINVAL);
136 assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
137 assert_return(ret, -EINVAL);
146 r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
148 sd_bus_creds_unref(c);
152 /* Check if the process existed at all, in case we haven't
153 * figured that out already */
154 if (!pid_is_alive(pid)) {
155 sd_bus_creds_unref(c);
163 _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) {
164 assert_return(c, -EINVAL);
165 assert_return(uid, -EINVAL);
167 if (!(c->mask & SD_BUS_CREDS_UID))
174 _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) {
175 assert_return(c, -EINVAL);
176 assert_return(euid, -EINVAL);
178 if (!(c->mask & SD_BUS_CREDS_EUID))
185 _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) {
186 assert_return(c, -EINVAL);
187 assert_return(suid, -EINVAL);
189 if (!(c->mask & SD_BUS_CREDS_SUID))
197 _public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) {
198 assert_return(c, -EINVAL);
199 assert_return(fsuid, -EINVAL);
201 if (!(c->mask & SD_BUS_CREDS_FSUID))
208 _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
209 assert_return(c, -EINVAL);
210 assert_return(gid, -EINVAL);
212 if (!(c->mask & SD_BUS_CREDS_UID))
220 _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) {
221 assert_return(c, -EINVAL);
222 assert_return(egid, -EINVAL);
224 if (!(c->mask & SD_BUS_CREDS_EGID))
231 _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
232 assert_return(c, -EINVAL);
233 assert_return(sgid, -EINVAL);
235 if (!(c->mask & SD_BUS_CREDS_SGID))
242 _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
243 assert_return(c, -EINVAL);
244 assert_return(fsgid, -EINVAL);
246 if (!(c->mask & SD_BUS_CREDS_FSGID))
253 _public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) {
254 assert_return(c, -EINVAL);
255 assert_return(gids, -EINVAL);
257 if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
260 *gids = c->supplementary_gids;
261 return (int) c->n_supplementary_gids;
264 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
265 assert_return(c, -EINVAL);
266 assert_return(pid, -EINVAL);
268 if (!(c->mask & SD_BUS_CREDS_PID))
276 _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) {
277 assert_return(c, -EINVAL);
278 assert_return(tid, -EINVAL);
280 if (!(c->mask & SD_BUS_CREDS_TID))
288 _public_ int sd_bus_creds_get_pid_starttime(sd_bus_creds *c, uint64_t *usec) {
289 assert_return(c, -EINVAL);
290 assert_return(usec, -EINVAL);
292 if (!(c->mask & SD_BUS_CREDS_PID_STARTTIME))
295 assert(c->pid_starttime > 0);
296 *usec = c->pid_starttime;
300 _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
301 assert_return(c, -EINVAL);
303 if (!(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT))
311 _public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) {
312 assert_return(c, -EINVAL);
313 assert_return(ret, -EINVAL);
315 if (!(c->mask & SD_BUS_CREDS_COMM))
323 _public_ int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **ret) {
324 assert_return(c, -EINVAL);
325 assert_return(ret, -EINVAL);
327 if (!(c->mask & SD_BUS_CREDS_TID_COMM))
335 _public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) {
336 assert_return(c, -EINVAL);
337 assert_return(ret, -EINVAL);
339 if (!(c->mask & SD_BUS_CREDS_EXE))
347 _public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) {
348 assert_return(c, -EINVAL);
349 assert_return(ret, -EINVAL);
351 if (!(c->mask & SD_BUS_CREDS_CGROUP))
359 _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {
362 assert_return(c, -EINVAL);
363 assert_return(ret, -EINVAL);
365 if (!(c->mask & SD_BUS_CREDS_UNIT))
373 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
377 r = cg_path_get_unit(shifted, (char**) &c->unit);
386 _public_ int sd_bus_creds_get_user_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_USER_UNIT))
400 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
404 r = cg_path_get_user_unit(shifted, (char**) &c->user_unit);
413 _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
416 assert_return(c, -EINVAL);
417 assert_return(ret, -EINVAL);
419 if (!(c->mask & SD_BUS_CREDS_SLICE))
427 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
431 r = cg_path_get_slice(shifted, (char**) &c->slice);
440 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
443 assert_return(c, -EINVAL);
444 assert_return(ret, -EINVAL);
446 if (!(c->mask & SD_BUS_CREDS_SESSION))
454 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
458 r = cg_path_get_session(shifted, (char**) &c->session);
467 _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
471 assert_return(c, -EINVAL);
472 assert_return(uid, -EINVAL);
474 if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
479 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
483 return cg_path_get_owner_uid(shifted, uid);
486 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
487 assert_return(c, -EINVAL);
489 if (!(c->mask & SD_BUS_CREDS_CMDLINE))
492 assert_return(c->cmdline, -ESRCH);
495 if (!c->cmdline_array) {
496 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
497 if (!c->cmdline_array)
501 *cmdline = c->cmdline_array;
505 _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
506 assert_return(c, -EINVAL);
507 assert_return(sessionid, -EINVAL);
509 if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
512 *sessionid = c->audit_session_id;
516 _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
517 assert_return(c, -EINVAL);
518 assert_return(uid, -EINVAL);
520 if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID))
523 *uid = c->audit_login_uid;
527 _public_ int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **unique_name) {
528 assert_return(c, -EINVAL);
529 assert_return(unique_name, -EINVAL);
531 if (!(c->mask & SD_BUS_CREDS_UNIQUE_NAME))
534 *unique_name = c->unique_name;
538 _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) {
539 assert_return(c, -EINVAL);
540 assert_return(well_known_names, -EINVAL);
542 if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
545 *well_known_names = c->well_known_names;
549 _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) {
550 assert_return(c, -EINVAL);
551 assert_return(ret, -EINVAL);
553 if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
556 assert(c->description);
558 if (!c->unescaped_description) {
559 c->unescaped_description = bus_label_unescape(c->description);
560 if (!c->unescaped_description)
564 *ret = c->unescaped_description;
568 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
572 assert(c->capability);
574 sz = c->capability_size / 4;
575 if ((size_t) capability >= sz*8)
578 return !!(c->capability[offset * sz + (capability / 8)] & (1 << (capability % 8)));
581 _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
582 assert_return(c, -EINVAL);
583 assert_return(capability >= 0, -EINVAL);
585 if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS))
588 return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
591 _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
592 assert_return(c, -EINVAL);
593 assert_return(capability >= 0, -EINVAL);
595 if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS))
598 return has_cap(c, CAP_OFFSET_PERMITTED, capability);
601 _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
602 assert_return(c, -EINVAL);
603 assert_return(capability >= 0, -EINVAL);
605 if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS))
608 return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
611 _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) {
612 assert_return(c, -EINVAL);
613 assert_return(capability >= 0, -EINVAL);
615 if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS))
618 return has_cap(c, CAP_OFFSET_BOUNDING, capability);
621 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
628 p += strspn(p, WHITESPACE);
635 if (!c->capability) {
636 c->capability = new0(uint8_t, sz * 4);
640 c->capability_size = sz * 4;
643 for (i = 0; i < sz; i ++) {
646 x = unhexchar(p[i*2]);
647 y = unhexchar(p[i*2+1]);
652 c->capability[offset * sz + (sz - i - 1)] = (uint8_t) x << 4 | (uint8_t) y;
658 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
663 assert(c->allocated);
665 if (!(mask & SD_BUS_CREDS_AUGMENT))
668 missing = mask & ~c->mask;
672 /* Try to retrieve PID from creds if it wasn't passed to us */
673 if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
676 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
679 /* Without pid we cannot do much... */
685 c->mask |= SD_BUS_CREDS_PID;
690 c->mask |= SD_BUS_CREDS_TID;
693 if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
694 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
695 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
696 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
697 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
699 _cleanup_fclose_ FILE *f = NULL;
702 p = procfs_file_alloca(pid, "status");
708 else if (errno != EPERM && errno != EACCES)
713 FOREACH_LINE(line, f, return -errno) {
716 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
717 p = startswith(line, "Uid:");
719 unsigned long uid, euid, suid, fsuid;
721 p += strspn(p, WHITESPACE);
722 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
725 c->uid = (uid_t) uid;
726 c->euid = (uid_t) euid;
727 c->suid = (uid_t) suid;
728 c->fsuid = (uid_t) fsuid;
729 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
734 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
735 p = startswith(line, "Gid:");
737 unsigned long gid, egid, sgid, fsgid;
739 p += strspn(p, WHITESPACE);
740 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
743 c->gid = (gid_t) gid;
744 c->egid = (gid_t) egid;
745 c->sgid = (gid_t) sgid;
746 c->fsgid = (gid_t) fsgid;
747 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
752 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
753 p = startswith(line, "Groups:");
755 size_t allocated = 0;
761 p += strspn(p, WHITESPACE);
765 if (sscanf(p, "%lu%n", &g, &n) != 1)
768 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
771 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
775 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
780 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
781 p = startswith(line, "CapEff:");
783 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
787 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
792 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
793 p = startswith(line, "CapPrm:");
795 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
799 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
804 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
805 p = startswith(line, "CapInh:");
807 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
811 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
816 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
817 p = startswith(line, "CapBnd:");
819 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
823 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
831 if (missing & (SD_BUS_CREDS_PID_STARTTIME)) {
832 unsigned long long st;
834 r = get_starttime_of_pid(pid, &st);
836 if (r != -EPERM && r != -EACCES)
839 c->pid_starttime = ((usec_t) st * USEC_PER_SEC) / (usec_t) sysconf(_SC_CLK_TCK);
840 c->mask |= SD_BUS_CREDS_PID_STARTTIME;
844 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
847 p = procfs_file_alloca(pid, "attr/current");
848 r = read_one_line_file(p, &c->label);
850 if (r != -ENOENT && r != -EINVAL && r != -EPERM && r != -EACCES)
853 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
856 if (missing & SD_BUS_CREDS_COMM) {
857 r = get_process_comm(pid, &c->comm);
859 if (r != -EPERM && r != -EACCES)
862 c->mask |= SD_BUS_CREDS_COMM;
865 if (missing & SD_BUS_CREDS_EXE) {
866 r = get_process_exe(pid, &c->exe);
868 if (r != -EPERM && r != -EACCES)
871 c->mask |= SD_BUS_CREDS_EXE;
874 if (missing & SD_BUS_CREDS_CMDLINE) {
877 p = procfs_file_alloca(pid, "cmdline");
878 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
882 if (r != -EPERM && r != -EACCES)
885 if (c->cmdline_size == 0) {
889 c->mask |= SD_BUS_CREDS_CMDLINE;
893 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
894 _cleanup_free_ char *p = NULL;
896 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
899 r = read_one_line_file(p, &c->tid_comm);
903 if (r != -EPERM && r != -EACCES)
906 c->mask |= SD_BUS_CREDS_TID_COMM;
909 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)) {
911 r = cg_pid_get_path(NULL, pid, &c->cgroup);
913 if (r != -EPERM && r != -EACCES)
916 r = cg_get_root_path(&c->cgroup_root);
920 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);
924 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
925 r = audit_session_from_pid(pid, &c->audit_session_id);
927 if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
930 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
933 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
934 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
936 if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
939 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
945 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
946 _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL;
952 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
953 /* There's already all data we need, or augmentation
954 * wasn't turned on. */
956 *ret = sd_bus_creds_ref(c);
964 /* Copy the original data over */
966 if (c->mask & mask & SD_BUS_CREDS_UID) {
968 n->mask |= SD_BUS_CREDS_UID;
971 if (c->mask & mask & SD_BUS_CREDS_EUID) {
973 n->mask |= SD_BUS_CREDS_EUID;
976 if (c->mask & mask & SD_BUS_CREDS_SUID) {
978 n->mask |= SD_BUS_CREDS_SUID;
981 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
983 n->mask |= SD_BUS_CREDS_FSUID;
986 if (c->mask & mask & SD_BUS_CREDS_GID) {
988 n->mask |= SD_BUS_CREDS_GID;
991 if (c->mask & mask & SD_BUS_CREDS_EGID) {
993 n->mask |= SD_BUS_CREDS_EGID;
996 if (c->mask & mask & SD_BUS_CREDS_SGID) {
998 n->mask |= SD_BUS_CREDS_SGID;
1001 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
1002 n->fsgid = c->fsgid;
1003 n->mask |= SD_BUS_CREDS_FSGID;
1006 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
1007 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
1008 if (!n->supplementary_gids)
1010 n->n_supplementary_gids = c->n_supplementary_gids;
1011 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
1014 if (c->mask & mask & SD_BUS_CREDS_PID) {
1016 n->mask |= SD_BUS_CREDS_PID;
1019 if (c->mask & mask & SD_BUS_CREDS_TID) {
1021 n->mask |= SD_BUS_CREDS_TID;
1024 if (c->mask & mask & SD_BUS_CREDS_PID_STARTTIME) {
1025 n->pid_starttime = c->pid_starttime;
1026 n->mask |= SD_BUS_CREDS_PID_STARTTIME;
1029 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1030 n->comm = strdup(c->comm);
1034 n->mask |= SD_BUS_CREDS_COMM;
1037 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1038 n->tid_comm = strdup(c->tid_comm);
1042 n->mask |= SD_BUS_CREDS_TID_COMM;
1045 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1046 n->exe = strdup(c->exe);
1050 n->mask |= SD_BUS_CREDS_EXE;
1053 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1054 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1058 n->cmdline_size = c->cmdline_size;
1059 n->mask |= SD_BUS_CREDS_CMDLINE;
1062 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)) {
1063 n->cgroup = strdup(c->cgroup);
1067 n->cgroup_root = strdup(c->cgroup_root);
1068 if (!n->cgroup_root)
1071 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);
1074 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1075 n->capability = memdup(c->capability, c->capability_size);
1079 n->capability_size = c->capability_size;
1080 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);
1083 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1084 n->label = strdup(c->label);
1087 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1090 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1091 n->audit_session_id = c->audit_session_id;
1092 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1094 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1095 n->audit_login_uid = c->audit_login_uid;
1096 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1099 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1100 n->unique_name = strdup(c->unique_name);
1101 if (!n->unique_name)
1103 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1106 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1107 n->well_known_names = strv_copy(c->well_known_names);
1108 if (!n->well_known_names)
1110 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1113 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1114 n->description = strdup(c->description);
1115 if (!n->description)
1117 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1122 r = bus_creds_add_more(n, mask,
1123 c->mask & SD_BUS_CREDS_PID ? c->pid : 0,
1124 c->mask & SD_BUS_CREDS_TID ? c->tid : 0);