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);
58 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
59 assert_return(c, NULL);
67 /* If this is an embedded creds structure, then
68 * forward ref counting to the message */
69 m = container_of(c, sd_bus_message, creds);
70 sd_bus_message_ref(m);
76 _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
98 free(c->supplementary_gids);
104 m = container_of(c, sd_bus_message, creds);
105 sd_bus_message_unref(m);
112 _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
118 sd_bus_creds* bus_creds_new(void) {
121 c = new0(sd_bus_creds, 1);
130 _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
134 assert_return(pid >= 0, -EINVAL);
135 assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
136 assert_return(ret, -EINVAL);
145 r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
147 sd_bus_creds_unref(c);
151 /* Check if the process existed at all, in case we haven't
152 * figured that out already */
153 if (!pid_is_alive(pid)) {
154 sd_bus_creds_unref(c);
162 _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) {
163 assert_return(c, -EINVAL);
164 assert_return(uid, -EINVAL);
166 if (!(c->mask & SD_BUS_CREDS_UID))
173 _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) {
174 assert_return(c, -EINVAL);
175 assert_return(euid, -EINVAL);
177 if (!(c->mask & SD_BUS_CREDS_EUID))
184 _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) {
185 assert_return(c, -EINVAL);
186 assert_return(suid, -EINVAL);
188 if (!(c->mask & SD_BUS_CREDS_SUID))
196 _public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) {
197 assert_return(c, -EINVAL);
198 assert_return(fsuid, -EINVAL);
200 if (!(c->mask & SD_BUS_CREDS_FSUID))
207 _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
208 assert_return(c, -EINVAL);
209 assert_return(gid, -EINVAL);
211 if (!(c->mask & SD_BUS_CREDS_UID))
219 _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) {
220 assert_return(c, -EINVAL);
221 assert_return(egid, -EINVAL);
223 if (!(c->mask & SD_BUS_CREDS_EGID))
230 _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
231 assert_return(c, -EINVAL);
232 assert_return(sgid, -EINVAL);
234 if (!(c->mask & SD_BUS_CREDS_SGID))
241 _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
242 assert_return(c, -EINVAL);
243 assert_return(fsgid, -EINVAL);
245 if (!(c->mask & SD_BUS_CREDS_FSGID))
252 _public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) {
253 assert_return(c, -EINVAL);
254 assert_return(gids, -EINVAL);
256 if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
259 *gids = c->supplementary_gids;
260 return (int) c->n_supplementary_gids;
263 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
264 assert_return(c, -EINVAL);
265 assert_return(pid, -EINVAL);
267 if (!(c->mask & SD_BUS_CREDS_PID))
275 _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) {
276 assert_return(c, -EINVAL);
277 assert_return(tid, -EINVAL);
279 if (!(c->mask & SD_BUS_CREDS_TID))
287 _public_ int sd_bus_creds_get_pid_starttime(sd_bus_creds *c, uint64_t *usec) {
288 assert_return(c, -EINVAL);
289 assert_return(usec, -EINVAL);
291 if (!(c->mask & SD_BUS_CREDS_PID_STARTTIME))
294 assert(c->pid_starttime > 0);
295 *usec = c->pid_starttime;
299 _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
300 assert_return(c, -EINVAL);
302 if (!(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT))
310 _public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) {
311 assert_return(c, -EINVAL);
312 assert_return(ret, -EINVAL);
314 if (!(c->mask & SD_BUS_CREDS_COMM))
322 _public_ int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **ret) {
323 assert_return(c, -EINVAL);
324 assert_return(ret, -EINVAL);
326 if (!(c->mask & SD_BUS_CREDS_TID_COMM))
334 _public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) {
335 assert_return(c, -EINVAL);
336 assert_return(ret, -EINVAL);
338 if (!(c->mask & SD_BUS_CREDS_EXE))
346 _public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) {
347 assert_return(c, -EINVAL);
348 assert_return(ret, -EINVAL);
350 if (!(c->mask & SD_BUS_CREDS_CGROUP))
358 _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {
361 assert_return(c, -EINVAL);
362 assert_return(ret, -EINVAL);
364 if (!(c->mask & SD_BUS_CREDS_UNIT))
372 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
376 r = cg_path_get_unit(shifted, (char**) &c->unit);
385 _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
388 assert_return(c, -EINVAL);
389 assert_return(ret, -EINVAL);
391 if (!(c->mask & SD_BUS_CREDS_USER_UNIT))
399 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
403 r = cg_path_get_user_unit(shifted, (char**) &c->user_unit);
412 _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
415 assert_return(c, -EINVAL);
416 assert_return(ret, -EINVAL);
418 if (!(c->mask & SD_BUS_CREDS_SLICE))
426 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
430 r = cg_path_get_slice(shifted, (char**) &c->slice);
439 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
442 assert_return(c, -EINVAL);
443 assert_return(ret, -EINVAL);
445 if (!(c->mask & SD_BUS_CREDS_SESSION))
453 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
457 r = cg_path_get_session(shifted, (char**) &c->session);
466 _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
470 assert_return(c, -EINVAL);
471 assert_return(uid, -EINVAL);
473 if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
478 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
482 return cg_path_get_owner_uid(shifted, uid);
485 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
486 assert_return(c, -EINVAL);
488 if (!(c->mask & SD_BUS_CREDS_CMDLINE))
491 assert_return(c->cmdline, -ESRCH);
494 if (!c->cmdline_array) {
495 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
496 if (!c->cmdline_array)
500 *cmdline = c->cmdline_array;
504 _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
505 assert_return(c, -EINVAL);
506 assert_return(sessionid, -EINVAL);
508 if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
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 *uid = c->audit_login_uid;
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 *well_known_names = c->well_known_names;
548 _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) {
549 assert_return(c, -EINVAL);
550 assert_return(ret, -EINVAL);
552 if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
555 assert(c->description);
557 if (!c->unescaped_description) {
558 c->unescaped_description = bus_label_unescape(c->description);
559 if (!c->unescaped_description)
563 *ret = c->unescaped_description;
567 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
571 assert(c->capability);
573 sz = c->capability_size / 4;
574 if ((size_t) capability >= sz*8)
577 return !!(c->capability[offset * sz + (capability / 8)] & (1 << (capability % 8)));
580 _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
581 assert_return(c, -EINVAL);
582 assert_return(capability >= 0, -EINVAL);
584 if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS))
587 return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
590 _public_ int sd_bus_creds_has_permitted_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_PERMITTED_CAPS))
597 return has_cap(c, CAP_OFFSET_PERMITTED, capability);
600 _public_ int sd_bus_creds_has_inheritable_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_INHERITABLE_CAPS))
607 return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
610 _public_ int sd_bus_creds_has_bounding_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_BOUNDING_CAPS))
617 return has_cap(c, CAP_OFFSET_BOUNDING, capability);
620 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
627 p += strspn(p, WHITESPACE);
634 if (!c->capability) {
635 c->capability = new0(uint8_t, sz * 4);
639 c->capability_size = sz * 4;
642 for (i = 0; i < sz; i ++) {
645 x = unhexchar(p[i*2]);
646 y = unhexchar(p[i*2+1]);
651 c->capability[offset * sz + (sz - i - 1)] = (uint8_t) x << 4 | (uint8_t) y;
657 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
662 assert(c->allocated);
664 if (!(mask & SD_BUS_CREDS_AUGMENT))
667 missing = mask & ~c->mask;
671 /* Try to retrieve PID from creds if it wasn't passed to us */
672 if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
675 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
678 /* Without pid we cannot do much... */
684 c->mask |= SD_BUS_CREDS_PID;
689 c->mask |= SD_BUS_CREDS_TID;
692 if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
693 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
694 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
695 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
696 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
698 _cleanup_fclose_ FILE *f = NULL;
701 p = procfs_file_alloca(pid, "status");
707 else if (errno != EPERM && errno != EACCES)
712 FOREACH_LINE(line, f, return -errno) {
715 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
716 p = startswith(line, "Uid:");
718 unsigned long uid, euid, suid, fsuid;
720 p += strspn(p, WHITESPACE);
721 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
724 c->uid = (uid_t) uid;
725 c->euid = (uid_t) euid;
726 c->suid = (uid_t) suid;
727 c->fsuid = (uid_t) fsuid;
728 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
733 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
734 p = startswith(line, "Gid:");
736 unsigned long gid, egid, sgid, fsgid;
738 p += strspn(p, WHITESPACE);
739 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
742 c->gid = (gid_t) gid;
743 c->egid = (gid_t) egid;
744 c->sgid = (gid_t) sgid;
745 c->fsgid = (gid_t) fsgid;
746 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
751 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
752 p = startswith(line, "Groups:");
754 size_t allocated = 0;
760 p += strspn(p, WHITESPACE);
764 if (sscanf(p, "%lu%n", &g, &n) != 1)
767 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
770 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
774 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
779 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
780 p = startswith(line, "CapEff:");
782 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
786 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
791 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
792 p = startswith(line, "CapPrm:");
794 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
798 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
803 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
804 p = startswith(line, "CapInh:");
806 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
810 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
815 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
816 p = startswith(line, "CapBnd:");
818 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
822 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
830 if (missing & (SD_BUS_CREDS_PID_STARTTIME)) {
831 unsigned long long st;
833 r = get_starttime_of_pid(pid, &st);
835 if (r != -EPERM && r != -EACCES)
838 c->pid_starttime = ((usec_t) st * USEC_PER_SEC) / (usec_t) sysconf(_SC_CLK_TCK);
839 c->mask |= SD_BUS_CREDS_PID_STARTTIME;
843 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
846 p = procfs_file_alloca(pid, "attr/current");
847 r = read_one_line_file(p, &c->label);
849 if (r != -ENOENT && r != -EINVAL && r != -EPERM && r != -EACCES)
852 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
855 if (missing & SD_BUS_CREDS_COMM) {
856 r = get_process_comm(pid, &c->comm);
858 if (r != -EPERM && r != -EACCES)
861 c->mask |= SD_BUS_CREDS_COMM;
864 if (missing & SD_BUS_CREDS_EXE) {
865 r = get_process_exe(pid, &c->exe);
867 if (r != -EPERM && r != -EACCES)
870 c->mask |= SD_BUS_CREDS_EXE;
873 if (missing & SD_BUS_CREDS_CMDLINE) {
876 p = procfs_file_alloca(pid, "cmdline");
877 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
881 if (r != -EPERM && r != -EACCES)
884 if (c->cmdline_size == 0) {
888 c->mask |= SD_BUS_CREDS_CMDLINE;
892 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
893 _cleanup_free_ char *p = NULL;
895 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
898 r = read_one_line_file(p, &c->tid_comm);
902 if (r != -EPERM && r != -EACCES)
905 c->mask |= SD_BUS_CREDS_TID_COMM;
908 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)) {
910 r = cg_pid_get_path(NULL, pid, &c->cgroup);
912 if (r != -EPERM && r != -EACCES)
915 r = cg_get_root_path(&c->cgroup_root);
919 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);
923 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
924 r = audit_session_from_pid(pid, &c->audit_session_id);
926 if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
929 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
932 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
933 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
935 if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
938 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
944 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
945 _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL;
951 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
952 /* There's already all data we need, or augmentation
953 * wasn't turned on. */
955 *ret = sd_bus_creds_ref(c);
963 /* Copy the original data over */
965 if (c->mask & mask & SD_BUS_CREDS_UID) {
967 n->mask |= SD_BUS_CREDS_UID;
970 if (c->mask & mask & SD_BUS_CREDS_EUID) {
972 n->mask |= SD_BUS_CREDS_EUID;
975 if (c->mask & mask & SD_BUS_CREDS_SUID) {
977 n->mask |= SD_BUS_CREDS_SUID;
980 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
982 n->mask |= SD_BUS_CREDS_FSUID;
985 if (c->mask & mask & SD_BUS_CREDS_GID) {
987 n->mask |= SD_BUS_CREDS_GID;
990 if (c->mask & mask & SD_BUS_CREDS_EGID) {
992 n->mask |= SD_BUS_CREDS_EGID;
995 if (c->mask & mask & SD_BUS_CREDS_SGID) {
997 n->mask |= SD_BUS_CREDS_SGID;
1000 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
1001 n->fsgid = c->fsgid;
1002 n->mask |= SD_BUS_CREDS_FSGID;
1005 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
1006 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
1007 if (!n->supplementary_gids)
1009 n->n_supplementary_gids = c->n_supplementary_gids;
1010 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
1013 if (c->mask & mask & SD_BUS_CREDS_PID) {
1015 n->mask |= SD_BUS_CREDS_PID;
1018 if (c->mask & mask & SD_BUS_CREDS_TID) {
1020 n->mask |= SD_BUS_CREDS_TID;
1023 if (c->mask & mask & SD_BUS_CREDS_PID_STARTTIME) {
1024 n->pid_starttime = c->pid_starttime;
1025 n->mask |= SD_BUS_CREDS_PID_STARTTIME;
1028 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1029 n->comm = strdup(c->comm);
1033 n->mask |= SD_BUS_CREDS_COMM;
1036 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1037 n->tid_comm = strdup(c->tid_comm);
1041 n->mask |= SD_BUS_CREDS_TID_COMM;
1044 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1045 n->exe = strdup(c->exe);
1049 n->mask |= SD_BUS_CREDS_EXE;
1052 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1053 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1057 n->cmdline_size = c->cmdline_size;
1058 n->mask |= SD_BUS_CREDS_CMDLINE;
1061 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)) {
1062 n->cgroup = strdup(c->cgroup);
1066 n->cgroup_root = strdup(c->cgroup_root);
1067 if (!n->cgroup_root)
1070 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);
1073 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1074 n->capability = memdup(c->capability, c->capability_size);
1078 n->capability_size = c->capability_size;
1079 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);
1082 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1083 n->label = strdup(c->label);
1086 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1089 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1090 n->audit_session_id = c->audit_session_id;
1091 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1093 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1094 n->audit_login_uid = c->audit_login_uid;
1095 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1098 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1099 n->unique_name = strdup(c->unique_name);
1100 if (!n->unique_name)
1102 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1105 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1106 n->well_known_names = strv_copy(c->well_known_names);
1107 if (!n->well_known_names)
1109 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1112 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1113 n->description = strdup(c->description);
1114 if (!n->description)
1116 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1121 r = bus_creds_add_more(n, mask,
1122 c->mask & SD_BUS_CREDS_PID ? c->pid : 0,
1123 c->mask & SD_BUS_CREDS_TID ? c->tid : 0);