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 free(c->well_known_names); /* note that this is an strv, but
55 * we only free the array, not the
56 * strings the array points to. The
57 * full strv we only free if
58 * c->allocated is set, see
61 strv_free(c->cmdline_array);
64 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
65 assert_return(c, NULL);
73 /* If this is an embedded creds structure, then
74 * forward ref counting to the message */
75 m = container_of(c, sd_bus_message, creds);
76 sd_bus_message_ref(m);
82 _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
100 free(c->cgroup_root);
101 free(c->description);
102 free(c->supplementary_gids);
104 strv_free(c->well_known_names);
105 c->well_known_names = NULL;
114 m = container_of(c, sd_bus_message, creds);
115 sd_bus_message_unref(m);
122 _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
128 sd_bus_creds* bus_creds_new(void) {
131 c = new0(sd_bus_creds, 1);
140 _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
144 assert_return(pid >= 0, -EINVAL);
145 assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
146 assert_return(ret, -EINVAL);
155 r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
157 sd_bus_creds_unref(c);
161 /* Check if the process existed at all, in case we haven't
162 * figured that out already */
163 if (!pid_is_alive(pid)) {
164 sd_bus_creds_unref(c);
172 _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) {
173 assert_return(c, -EINVAL);
174 assert_return(uid, -EINVAL);
176 if (!(c->mask & SD_BUS_CREDS_UID))
183 _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) {
184 assert_return(c, -EINVAL);
185 assert_return(euid, -EINVAL);
187 if (!(c->mask & SD_BUS_CREDS_EUID))
194 _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) {
195 assert_return(c, -EINVAL);
196 assert_return(suid, -EINVAL);
198 if (!(c->mask & SD_BUS_CREDS_SUID))
206 _public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) {
207 assert_return(c, -EINVAL);
208 assert_return(fsuid, -EINVAL);
210 if (!(c->mask & SD_BUS_CREDS_FSUID))
217 _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
218 assert_return(c, -EINVAL);
219 assert_return(gid, -EINVAL);
221 if (!(c->mask & SD_BUS_CREDS_UID))
229 _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) {
230 assert_return(c, -EINVAL);
231 assert_return(egid, -EINVAL);
233 if (!(c->mask & SD_BUS_CREDS_EGID))
240 _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
241 assert_return(c, -EINVAL);
242 assert_return(sgid, -EINVAL);
244 if (!(c->mask & SD_BUS_CREDS_SGID))
251 _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
252 assert_return(c, -EINVAL);
253 assert_return(fsgid, -EINVAL);
255 if (!(c->mask & SD_BUS_CREDS_FSGID))
262 _public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) {
263 assert_return(c, -EINVAL);
264 assert_return(gids, -EINVAL);
266 if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
269 *gids = c->supplementary_gids;
270 return (int) c->n_supplementary_gids;
273 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
274 assert_return(c, -EINVAL);
275 assert_return(pid, -EINVAL);
277 if (!(c->mask & SD_BUS_CREDS_PID))
285 _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) {
286 assert_return(c, -EINVAL);
287 assert_return(tid, -EINVAL);
289 if (!(c->mask & SD_BUS_CREDS_TID))
297 _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
298 assert_return(c, -EINVAL);
300 if (!(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT))
308 _public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) {
309 assert_return(c, -EINVAL);
310 assert_return(ret, -EINVAL);
312 if (!(c->mask & SD_BUS_CREDS_COMM))
320 _public_ int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **ret) {
321 assert_return(c, -EINVAL);
322 assert_return(ret, -EINVAL);
324 if (!(c->mask & SD_BUS_CREDS_TID_COMM))
332 _public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) {
333 assert_return(c, -EINVAL);
334 assert_return(ret, -EINVAL);
336 if (!(c->mask & SD_BUS_CREDS_EXE))
344 _public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) {
345 assert_return(c, -EINVAL);
346 assert_return(ret, -EINVAL);
348 if (!(c->mask & SD_BUS_CREDS_CGROUP))
356 _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {
359 assert_return(c, -EINVAL);
360 assert_return(ret, -EINVAL);
362 if (!(c->mask & SD_BUS_CREDS_UNIT))
370 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
374 r = cg_path_get_unit(shifted, (char**) &c->unit);
383 _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
386 assert_return(c, -EINVAL);
387 assert_return(ret, -EINVAL);
389 if (!(c->mask & SD_BUS_CREDS_USER_UNIT))
397 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
401 r = cg_path_get_user_unit(shifted, (char**) &c->user_unit);
410 _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))
424 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
428 r = cg_path_get_slice(shifted, (char**) &c->slice);
437 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
440 assert_return(c, -EINVAL);
441 assert_return(ret, -EINVAL);
443 if (!(c->mask & SD_BUS_CREDS_SESSION))
451 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
455 r = cg_path_get_session(shifted, (char**) &c->session);
464 _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
468 assert_return(c, -EINVAL);
469 assert_return(uid, -EINVAL);
471 if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
476 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
480 return cg_path_get_owner_uid(shifted, uid);
483 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
484 assert_return(c, -EINVAL);
486 if (!(c->mask & SD_BUS_CREDS_CMDLINE))
489 assert_return(c->cmdline, -ESRCH);
492 if (!c->cmdline_array) {
493 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
494 if (!c->cmdline_array)
498 *cmdline = c->cmdline_array;
502 _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
503 assert_return(c, -EINVAL);
504 assert_return(sessionid, -EINVAL);
506 if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
509 *sessionid = c->audit_session_id;
513 _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
514 assert_return(c, -EINVAL);
515 assert_return(uid, -EINVAL);
517 if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID))
520 *uid = c->audit_login_uid;
524 _public_ int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **unique_name) {
525 assert_return(c, -EINVAL);
526 assert_return(unique_name, -EINVAL);
528 if (!(c->mask & SD_BUS_CREDS_UNIQUE_NAME))
531 *unique_name = c->unique_name;
535 _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) {
536 assert_return(c, -EINVAL);
537 assert_return(well_known_names, -EINVAL);
539 if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
542 /* As a special hack we return the bus driver as well-known
543 * names list when this is requested. */
544 if (c->well_known_names_driver) {
545 static const char* const wkn[] = {
546 "org.freedesktop.DBus",
550 *well_known_names = (char**) wkn;
554 if (c->well_known_names_local) {
555 static const char* const wkn[] = {
556 "org.freedesktop.DBus.Local",
560 *well_known_names = (char**) wkn;
564 *well_known_names = c->well_known_names;
568 _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) {
569 assert_return(c, -EINVAL);
570 assert_return(ret, -EINVAL);
572 if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
575 assert(c->description);
577 if (!c->unescaped_description) {
578 c->unescaped_description = bus_label_unescape(c->description);
579 if (!c->unescaped_description)
583 *ret = c->unescaped_description;
587 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
591 assert(c->capability);
593 sz = c->capability_size / 4;
594 if ((size_t) capability >= sz*8)
597 return !!(c->capability[offset * sz + (capability / 8)] & (1 << (capability % 8)));
600 _public_ int sd_bus_creds_has_effective_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_EFFECTIVE_CAPS))
607 return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
610 _public_ int sd_bus_creds_has_permitted_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_PERMITTED_CAPS))
617 return has_cap(c, CAP_OFFSET_PERMITTED, capability);
620 _public_ int sd_bus_creds_has_inheritable_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_INHERITABLE_CAPS))
627 return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
630 _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) {
631 assert_return(c, -EINVAL);
632 assert_return(capability >= 0, -EINVAL);
634 if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS))
637 return has_cap(c, CAP_OFFSET_BOUNDING, capability);
640 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
647 p += strspn(p, WHITESPACE);
654 if (!c->capability) {
655 c->capability = new0(uint8_t, sz * 4);
659 c->capability_size = sz * 4;
662 for (i = 0; i < sz; i ++) {
665 x = unhexchar(p[i*2]);
666 y = unhexchar(p[i*2+1]);
671 c->capability[offset * sz + (sz - i - 1)] = (uint8_t) x << 4 | (uint8_t) y;
677 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
682 assert(c->allocated);
684 if (!(mask & SD_BUS_CREDS_AUGMENT))
687 missing = mask & ~c->mask;
691 /* Try to retrieve PID from creds if it wasn't passed to us */
692 if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
695 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
698 /* Without pid we cannot do much... */
704 c->mask |= SD_BUS_CREDS_PID;
709 c->mask |= SD_BUS_CREDS_TID;
712 if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
713 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
714 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
715 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
716 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
718 _cleanup_fclose_ FILE *f = NULL;
721 p = procfs_file_alloca(pid, "status");
727 else if (errno != EPERM && errno != EACCES)
732 FOREACH_LINE(line, f, return -errno) {
735 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
736 p = startswith(line, "Uid:");
738 unsigned long uid, euid, suid, fsuid;
740 p += strspn(p, WHITESPACE);
741 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
744 c->uid = (uid_t) uid;
745 c->euid = (uid_t) euid;
746 c->suid = (uid_t) suid;
747 c->fsuid = (uid_t) fsuid;
748 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
753 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
754 p = startswith(line, "Gid:");
756 unsigned long gid, egid, sgid, fsgid;
758 p += strspn(p, WHITESPACE);
759 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
762 c->gid = (gid_t) gid;
763 c->egid = (gid_t) egid;
764 c->sgid = (gid_t) sgid;
765 c->fsgid = (gid_t) fsgid;
766 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
771 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
772 p = startswith(line, "Groups:");
774 size_t allocated = 0;
780 p += strspn(p, WHITESPACE);
784 if (sscanf(p, "%lu%n", &g, &n) != 1)
787 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
790 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
794 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
799 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
800 p = startswith(line, "CapEff:");
802 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
806 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
811 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
812 p = startswith(line, "CapPrm:");
814 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
818 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
823 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
824 p = startswith(line, "CapInh:");
826 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
830 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
835 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
836 p = startswith(line, "CapBnd:");
838 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
842 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
850 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
853 p = procfs_file_alloca(pid, "attr/current");
854 r = read_one_line_file(p, &c->label);
856 if (r != -ENOENT && r != -EINVAL && r != -EPERM && r != -EACCES)
859 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
862 if (missing & SD_BUS_CREDS_COMM) {
863 r = get_process_comm(pid, &c->comm);
865 if (r != -EPERM && r != -EACCES)
868 c->mask |= SD_BUS_CREDS_COMM;
871 if (missing & SD_BUS_CREDS_EXE) {
872 r = get_process_exe(pid, &c->exe);
874 if (r != -EPERM && r != -EACCES)
877 c->mask |= SD_BUS_CREDS_EXE;
880 if (missing & SD_BUS_CREDS_CMDLINE) {
883 p = procfs_file_alloca(pid, "cmdline");
884 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
888 if (r != -EPERM && r != -EACCES)
891 if (c->cmdline_size == 0) {
895 c->mask |= SD_BUS_CREDS_CMDLINE;
899 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
900 _cleanup_free_ char *p = NULL;
902 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
905 r = read_one_line_file(p, &c->tid_comm);
909 if (r != -EPERM && r != -EACCES)
912 c->mask |= SD_BUS_CREDS_TID_COMM;
915 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)) {
917 r = cg_pid_get_path(NULL, pid, &c->cgroup);
919 if (r != -EPERM && r != -EACCES)
922 r = cg_get_root_path(&c->cgroup_root);
926 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);
930 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
931 r = audit_session_from_pid(pid, &c->audit_session_id);
933 if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
936 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
939 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
940 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
942 if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
945 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
951 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
952 _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL;
958 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
959 /* There's already all data we need, or augmentation
960 * wasn't turned on. */
962 *ret = sd_bus_creds_ref(c);
970 /* Copy the original data over */
972 if (c->mask & mask & SD_BUS_CREDS_UID) {
974 n->mask |= SD_BUS_CREDS_UID;
977 if (c->mask & mask & SD_BUS_CREDS_EUID) {
979 n->mask |= SD_BUS_CREDS_EUID;
982 if (c->mask & mask & SD_BUS_CREDS_SUID) {
984 n->mask |= SD_BUS_CREDS_SUID;
987 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
989 n->mask |= SD_BUS_CREDS_FSUID;
992 if (c->mask & mask & SD_BUS_CREDS_GID) {
994 n->mask |= SD_BUS_CREDS_GID;
997 if (c->mask & mask & SD_BUS_CREDS_EGID) {
999 n->mask |= SD_BUS_CREDS_EGID;
1002 if (c->mask & mask & SD_BUS_CREDS_SGID) {
1004 n->mask |= SD_BUS_CREDS_SGID;
1007 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
1008 n->fsgid = c->fsgid;
1009 n->mask |= SD_BUS_CREDS_FSGID;
1012 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
1013 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
1014 if (!n->supplementary_gids)
1016 n->n_supplementary_gids = c->n_supplementary_gids;
1017 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
1020 if (c->mask & mask & SD_BUS_CREDS_PID) {
1022 n->mask |= SD_BUS_CREDS_PID;
1025 if (c->mask & mask & SD_BUS_CREDS_TID) {
1027 n->mask |= SD_BUS_CREDS_TID;
1030 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1031 n->comm = strdup(c->comm);
1035 n->mask |= SD_BUS_CREDS_COMM;
1038 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1039 n->tid_comm = strdup(c->tid_comm);
1043 n->mask |= SD_BUS_CREDS_TID_COMM;
1046 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1047 n->exe = strdup(c->exe);
1051 n->mask |= SD_BUS_CREDS_EXE;
1054 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1055 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1059 n->cmdline_size = c->cmdline_size;
1060 n->mask |= SD_BUS_CREDS_CMDLINE;
1063 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)) {
1064 n->cgroup = strdup(c->cgroup);
1068 n->cgroup_root = strdup(c->cgroup_root);
1069 if (!n->cgroup_root)
1072 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);
1075 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1076 n->capability = memdup(c->capability, c->capability_size);
1080 n->capability_size = c->capability_size;
1081 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);
1084 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1085 n->label = strdup(c->label);
1088 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1091 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1092 n->audit_session_id = c->audit_session_id;
1093 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1095 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1096 n->audit_login_uid = c->audit_login_uid;
1097 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1100 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1101 n->unique_name = strdup(c->unique_name);
1102 if (!n->unique_name)
1104 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1107 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1108 n->well_known_names = strv_copy(c->well_known_names);
1109 if (!n->well_known_names)
1111 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1114 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1115 n->description = strdup(c->description);
1116 if (!n->description)
1118 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1123 r = bus_creds_add_more(n, mask,
1124 c->mask & SD_BUS_CREDS_PID ? c->pid : 0,
1125 c->mask & SD_BUS_CREDS_TID ? c->tid : 0);