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 "capability.h"
27 #include "cgroup-util.h"
30 #include "bus-message.h"
32 #include "time-util.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);
56 free(c->well_known_names); /* note that this is an strv, but
57 * we only free the array, not the
58 * strings the array points to. The
59 * full strv we only free if
60 * c->allocated is set, see
63 strv_free(c->cmdline_array);
66 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
67 assert_return(c, NULL);
75 /* If this is an embedded creds structure, then
76 * forward ref counting to the message */
77 m = container_of(c, sd_bus_message, creds);
78 sd_bus_message_ref(m);
84 _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
101 free(c->unique_name);
102 free(c->cgroup_root);
103 free(c->description);
104 free(c->supplementary_gids);
106 strv_free(c->well_known_names);
107 c->well_known_names = NULL;
116 m = container_of(c, sd_bus_message, creds);
117 sd_bus_message_unref(m);
124 _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
130 sd_bus_creds* bus_creds_new(void) {
133 c = new0(sd_bus_creds, 1);
142 _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
146 assert_return(pid >= 0, -EINVAL);
147 assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
148 assert_return(ret, -EINVAL);
157 r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
159 sd_bus_creds_unref(c);
163 /* Check if the process existed at all, in case we haven't
164 * figured that out already */
165 if (!pid_is_alive(pid)) {
166 sd_bus_creds_unref(c);
174 _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) {
175 assert_return(c, -EINVAL);
176 assert_return(uid, -EINVAL);
178 if (!(c->mask & SD_BUS_CREDS_UID))
185 _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) {
186 assert_return(c, -EINVAL);
187 assert_return(euid, -EINVAL);
189 if (!(c->mask & SD_BUS_CREDS_EUID))
196 _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) {
197 assert_return(c, -EINVAL);
198 assert_return(suid, -EINVAL);
200 if (!(c->mask & SD_BUS_CREDS_SUID))
208 _public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) {
209 assert_return(c, -EINVAL);
210 assert_return(fsuid, -EINVAL);
212 if (!(c->mask & SD_BUS_CREDS_FSUID))
219 _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
220 assert_return(c, -EINVAL);
221 assert_return(gid, -EINVAL);
223 if (!(c->mask & SD_BUS_CREDS_GID))
231 _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) {
232 assert_return(c, -EINVAL);
233 assert_return(egid, -EINVAL);
235 if (!(c->mask & SD_BUS_CREDS_EGID))
242 _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
243 assert_return(c, -EINVAL);
244 assert_return(sgid, -EINVAL);
246 if (!(c->mask & SD_BUS_CREDS_SGID))
253 _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
254 assert_return(c, -EINVAL);
255 assert_return(fsgid, -EINVAL);
257 if (!(c->mask & SD_BUS_CREDS_FSGID))
264 _public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) {
265 assert_return(c, -EINVAL);
266 assert_return(gids, -EINVAL);
268 if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
271 *gids = c->supplementary_gids;
272 return (int) c->n_supplementary_gids;
275 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
276 assert_return(c, -EINVAL);
277 assert_return(pid, -EINVAL);
279 if (!(c->mask & SD_BUS_CREDS_PID))
287 _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) {
288 assert_return(c, -EINVAL);
289 assert_return(tid, -EINVAL);
291 if (!(c->mask & SD_BUS_CREDS_TID))
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 /* 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 sz = DIV_ROUND_UP(cap_last_cap(), 32U);
597 if ((unsigned)capability > cap_last_cap())
600 return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability));
603 _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
604 assert_return(c, -EINVAL);
605 assert_return(capability >= 0, -EINVAL);
607 if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS))
610 return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
613 _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
614 assert_return(c, -EINVAL);
615 assert_return(capability >= 0, -EINVAL);
617 if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS))
620 return has_cap(c, CAP_OFFSET_PERMITTED, capability);
623 _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
624 assert_return(c, -EINVAL);
625 assert_return(capability >= 0, -EINVAL);
627 if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS))
630 return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
633 _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) {
634 assert_return(c, -EINVAL);
635 assert_return(capability >= 0, -EINVAL);
637 if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS))
640 return has_cap(c, CAP_OFFSET_BOUNDING, capability);
643 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
650 max = DIV_ROUND_UP(cap_last_cap(), 32U);
651 p += strspn(p, WHITESPACE);
661 if (!c->capability) {
662 c->capability = new0(uint32_t, max * 4);
667 for (i = 0; i < sz; i ++) {
670 for (j = 0; j < 8; ++j) {
680 c->capability[offset * max + (sz - i - 1)] = v;
686 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
691 assert(c->allocated);
693 if (!(mask & SD_BUS_CREDS_AUGMENT))
696 missing = mask & ~c->mask;
700 /* Try to retrieve PID from creds if it wasn't passed to us */
701 if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
704 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
707 /* Without pid we cannot do much... */
713 c->mask |= SD_BUS_CREDS_PID;
718 c->mask |= SD_BUS_CREDS_TID;
721 if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
722 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
723 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
724 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
725 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
727 _cleanup_fclose_ FILE *f = NULL;
730 p = procfs_file_alloca(pid, "status");
736 else if (errno != EPERM && errno != EACCES)
741 FOREACH_LINE(line, f, return -errno) {
744 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
745 p = startswith(line, "Uid:");
747 unsigned long uid, euid, suid, fsuid;
749 p += strspn(p, WHITESPACE);
750 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
753 c->uid = (uid_t) uid;
754 c->euid = (uid_t) euid;
755 c->suid = (uid_t) suid;
756 c->fsuid = (uid_t) fsuid;
757 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
762 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
763 p = startswith(line, "Gid:");
765 unsigned long gid, egid, sgid, fsgid;
767 p += strspn(p, WHITESPACE);
768 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
771 c->gid = (gid_t) gid;
772 c->egid = (gid_t) egid;
773 c->sgid = (gid_t) sgid;
774 c->fsgid = (gid_t) fsgid;
775 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
780 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
781 p = startswith(line, "Groups:");
783 size_t allocated = 0;
789 p += strspn(p, WHITESPACE);
793 if (sscanf(p, "%lu%n", &g, &n) != 1)
796 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
799 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
803 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
808 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
809 p = startswith(line, "CapEff:");
811 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
815 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
820 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
821 p = startswith(line, "CapPrm:");
823 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
827 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
832 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
833 p = startswith(line, "CapInh:");
835 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
839 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
844 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
845 p = startswith(line, "CapBnd:");
847 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
851 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
859 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
862 p = procfs_file_alloca(pid, "attr/current");
863 r = read_one_line_file(p, &c->label);
865 if (r != -ENOENT && r != -EINVAL && r != -EPERM && r != -EACCES)
868 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
871 if (missing & SD_BUS_CREDS_COMM) {
872 r = get_process_comm(pid, &c->comm);
874 if (r != -EPERM && r != -EACCES)
877 c->mask |= SD_BUS_CREDS_COMM;
880 if (missing & SD_BUS_CREDS_EXE) {
881 r = get_process_exe(pid, &c->exe);
883 if (r != -EPERM && r != -EACCES)
886 c->mask |= SD_BUS_CREDS_EXE;
889 if (missing & SD_BUS_CREDS_CMDLINE) {
892 p = procfs_file_alloca(pid, "cmdline");
893 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
897 if (r != -EPERM && r != -EACCES)
900 if (c->cmdline_size == 0) {
904 c->mask |= SD_BUS_CREDS_CMDLINE;
908 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
909 _cleanup_free_ char *p = NULL;
911 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
914 r = read_one_line_file(p, &c->tid_comm);
918 if (r != -EPERM && r != -EACCES)
921 c->mask |= SD_BUS_CREDS_TID_COMM;
924 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)) {
926 r = cg_pid_get_path(NULL, pid, &c->cgroup);
928 if (r != -EPERM && r != -EACCES)
931 r = cg_get_root_path(&c->cgroup_root);
935 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);
939 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
940 r = audit_session_from_pid(pid, &c->audit_session_id);
942 if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
945 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
948 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
949 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
951 if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
954 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
960 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
961 _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL;
967 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
968 /* There's already all data we need, or augmentation
969 * wasn't turned on. */
971 *ret = sd_bus_creds_ref(c);
979 /* Copy the original data over */
981 if (c->mask & mask & SD_BUS_CREDS_UID) {
983 n->mask |= SD_BUS_CREDS_UID;
986 if (c->mask & mask & SD_BUS_CREDS_EUID) {
988 n->mask |= SD_BUS_CREDS_EUID;
991 if (c->mask & mask & SD_BUS_CREDS_SUID) {
993 n->mask |= SD_BUS_CREDS_SUID;
996 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
998 n->mask |= SD_BUS_CREDS_FSUID;
1001 if (c->mask & mask & SD_BUS_CREDS_GID) {
1003 n->mask |= SD_BUS_CREDS_GID;
1006 if (c->mask & mask & SD_BUS_CREDS_EGID) {
1008 n->mask |= SD_BUS_CREDS_EGID;
1011 if (c->mask & mask & SD_BUS_CREDS_SGID) {
1013 n->mask |= SD_BUS_CREDS_SGID;
1016 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
1017 n->fsgid = c->fsgid;
1018 n->mask |= SD_BUS_CREDS_FSGID;
1021 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
1022 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
1023 if (!n->supplementary_gids)
1025 n->n_supplementary_gids = c->n_supplementary_gids;
1026 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
1029 if (c->mask & mask & SD_BUS_CREDS_PID) {
1031 n->mask |= SD_BUS_CREDS_PID;
1034 if (c->mask & mask & SD_BUS_CREDS_TID) {
1036 n->mask |= SD_BUS_CREDS_TID;
1039 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1040 n->comm = strdup(c->comm);
1044 n->mask |= SD_BUS_CREDS_COMM;
1047 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1048 n->tid_comm = strdup(c->tid_comm);
1052 n->mask |= SD_BUS_CREDS_TID_COMM;
1055 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1056 n->exe = strdup(c->exe);
1060 n->mask |= SD_BUS_CREDS_EXE;
1063 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1064 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1068 n->cmdline_size = c->cmdline_size;
1069 n->mask |= SD_BUS_CREDS_CMDLINE;
1072 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)) {
1073 n->cgroup = strdup(c->cgroup);
1077 n->cgroup_root = strdup(c->cgroup_root);
1078 if (!n->cgroup_root)
1081 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);
1084 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1085 n->capability = memdup(c->capability, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4);
1089 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);
1092 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1093 n->label = strdup(c->label);
1096 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1099 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1100 n->audit_session_id = c->audit_session_id;
1101 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1103 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1104 n->audit_login_uid = c->audit_login_uid;
1105 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1108 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1109 n->unique_name = strdup(c->unique_name);
1110 if (!n->unique_name)
1112 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1115 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1116 n->well_known_names = strv_copy(c->well_known_names);
1117 if (!n->well_known_names)
1119 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1122 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1123 n->description = strdup(c->description);
1124 if (!n->description)
1126 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1131 r = bus_creds_add_more(n, mask,
1132 c->mask & SD_BUS_CREDS_PID ? c->pid : 0,
1133 c->mask & SD_BUS_CREDS_TID ? c->tid : 0);