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"
33 #include "bus-creds.h"
34 #include "bus-label.h"
37 CAP_OFFSET_INHERITABLE = 0,
38 CAP_OFFSET_PERMITTED = 1,
39 CAP_OFFSET_EFFECTIVE = 2,
40 CAP_OFFSET_BOUNDING = 3
43 void bus_creds_done(sd_bus_creds *c) {
46 /* For internal bus cred structures that are allocated by
53 free(c->unescaped_description);
55 free(c->well_known_names); /* note that this is an strv, but
56 * we only free the array, not the
57 * strings the array points to. The
58 * full strv we only free if
59 * c->allocated is set, see
62 strv_free(c->cmdline_array);
65 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
66 assert_return(c, NULL);
74 /* If this is an embedded creds structure, then
75 * forward ref counting to the message */
76 m = container_of(c, sd_bus_message, creds);
77 sd_bus_message_ref(m);
83 _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
100 free(c->unique_name);
101 free(c->cgroup_root);
102 free(c->description);
103 free(c->supplementary_gids);
105 strv_free(c->well_known_names);
106 c->well_known_names = NULL;
115 m = container_of(c, sd_bus_message, creds);
116 sd_bus_message_unref(m);
123 _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
129 sd_bus_creds* bus_creds_new(void) {
132 c = new0(sd_bus_creds, 1);
141 _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
145 assert_return(pid >= 0, -EINVAL);
146 assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
147 assert_return(ret, -EINVAL);
156 r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
158 sd_bus_creds_unref(c);
162 /* Check if the process existed at all, in case we haven't
163 * figured that out already */
164 if (!pid_is_alive(pid)) {
165 sd_bus_creds_unref(c);
173 _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) {
174 assert_return(c, -EINVAL);
175 assert_return(uid, -EINVAL);
177 if (!(c->mask & SD_BUS_CREDS_UID))
184 _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) {
185 assert_return(c, -EINVAL);
186 assert_return(euid, -EINVAL);
188 if (!(c->mask & SD_BUS_CREDS_EUID))
195 _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) {
196 assert_return(c, -EINVAL);
197 assert_return(suid, -EINVAL);
199 if (!(c->mask & SD_BUS_CREDS_SUID))
207 _public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) {
208 assert_return(c, -EINVAL);
209 assert_return(fsuid, -EINVAL);
211 if (!(c->mask & SD_BUS_CREDS_FSUID))
218 _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
219 assert_return(c, -EINVAL);
220 assert_return(gid, -EINVAL);
222 if (!(c->mask & SD_BUS_CREDS_GID))
230 _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) {
231 assert_return(c, -EINVAL);
232 assert_return(egid, -EINVAL);
234 if (!(c->mask & SD_BUS_CREDS_EGID))
241 _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
242 assert_return(c, -EINVAL);
243 assert_return(sgid, -EINVAL);
245 if (!(c->mask & SD_BUS_CREDS_SGID))
252 _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
253 assert_return(c, -EINVAL);
254 assert_return(fsgid, -EINVAL);
256 if (!(c->mask & SD_BUS_CREDS_FSGID))
263 _public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) {
264 assert_return(c, -EINVAL);
265 assert_return(gids, -EINVAL);
267 if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
270 *gids = c->supplementary_gids;
271 return (int) c->n_supplementary_gids;
274 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
275 assert_return(c, -EINVAL);
276 assert_return(pid, -EINVAL);
278 if (!(c->mask & SD_BUS_CREDS_PID))
286 _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) {
287 assert_return(c, -EINVAL);
288 assert_return(tid, -EINVAL);
290 if (!(c->mask & SD_BUS_CREDS_TID))
298 _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
299 assert_return(c, -EINVAL);
301 if (!(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT))
309 _public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) {
310 assert_return(c, -EINVAL);
311 assert_return(ret, -EINVAL);
313 if (!(c->mask & SD_BUS_CREDS_COMM))
321 _public_ int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **ret) {
322 assert_return(c, -EINVAL);
323 assert_return(ret, -EINVAL);
325 if (!(c->mask & SD_BUS_CREDS_TID_COMM))
333 _public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) {
334 assert_return(c, -EINVAL);
335 assert_return(ret, -EINVAL);
337 if (!(c->mask & SD_BUS_CREDS_EXE))
345 _public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) {
346 assert_return(c, -EINVAL);
347 assert_return(ret, -EINVAL);
349 if (!(c->mask & SD_BUS_CREDS_CGROUP))
357 _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {
360 assert_return(c, -EINVAL);
361 assert_return(ret, -EINVAL);
363 if (!(c->mask & SD_BUS_CREDS_UNIT))
371 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
375 r = cg_path_get_unit(shifted, (char**) &c->unit);
384 _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
387 assert_return(c, -EINVAL);
388 assert_return(ret, -EINVAL);
390 if (!(c->mask & SD_BUS_CREDS_USER_UNIT))
398 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
402 r = cg_path_get_user_unit(shifted, (char**) &c->user_unit);
411 _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
414 assert_return(c, -EINVAL);
415 assert_return(ret, -EINVAL);
417 if (!(c->mask & SD_BUS_CREDS_SLICE))
425 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
429 r = cg_path_get_slice(shifted, (char**) &c->slice);
438 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
441 assert_return(c, -EINVAL);
442 assert_return(ret, -EINVAL);
444 if (!(c->mask & SD_BUS_CREDS_SESSION))
452 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
456 r = cg_path_get_session(shifted, (char**) &c->session);
465 _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
469 assert_return(c, -EINVAL);
470 assert_return(uid, -EINVAL);
472 if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
477 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
481 return cg_path_get_owner_uid(shifted, uid);
484 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
485 assert_return(c, -EINVAL);
487 if (!(c->mask & SD_BUS_CREDS_CMDLINE))
490 assert_return(c->cmdline, -ESRCH);
493 if (!c->cmdline_array) {
494 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
495 if (!c->cmdline_array)
499 *cmdline = c->cmdline_array;
503 _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
504 assert_return(c, -EINVAL);
505 assert_return(sessionid, -EINVAL);
507 if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
510 *sessionid = c->audit_session_id;
514 _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
515 assert_return(c, -EINVAL);
516 assert_return(uid, -EINVAL);
518 if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID))
521 *uid = c->audit_login_uid;
525 _public_ int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **unique_name) {
526 assert_return(c, -EINVAL);
527 assert_return(unique_name, -EINVAL);
529 if (!(c->mask & SD_BUS_CREDS_UNIQUE_NAME))
532 *unique_name = c->unique_name;
536 _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) {
537 assert_return(c, -EINVAL);
538 assert_return(well_known_names, -EINVAL);
540 if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
543 /* As a special hack we return the bus driver as well-known
544 * names list when this is requested. */
545 if (c->well_known_names_driver) {
546 static const char* const wkn[] = {
547 "org.freedesktop.DBus",
551 *well_known_names = (char**) wkn;
555 if (c->well_known_names_local) {
556 static const char* const wkn[] = {
557 "org.freedesktop.DBus.Local",
561 *well_known_names = (char**) wkn;
565 *well_known_names = c->well_known_names;
569 _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) {
570 assert_return(c, -EINVAL);
571 assert_return(ret, -EINVAL);
573 if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
576 assert(c->description);
578 if (!c->unescaped_description) {
579 c->unescaped_description = bus_label_unescape(c->description);
580 if (!c->unescaped_description)
584 *ret = c->unescaped_description;
588 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
592 assert(capability >= 0);
593 assert(c->capability);
595 sz = DIV_ROUND_UP(cap_last_cap(), 32U);
596 if ((unsigned)capability > cap_last_cap())
599 return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability));
602 _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
603 assert_return(c, -EINVAL);
604 assert_return(capability >= 0, -EINVAL);
606 if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS))
609 return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
612 _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
613 assert_return(c, -EINVAL);
614 assert_return(capability >= 0, -EINVAL);
616 if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS))
619 return has_cap(c, CAP_OFFSET_PERMITTED, capability);
622 _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
623 assert_return(c, -EINVAL);
624 assert_return(capability >= 0, -EINVAL);
626 if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS))
629 return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
632 _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) {
633 assert_return(c, -EINVAL);
634 assert_return(capability >= 0, -EINVAL);
636 if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS))
639 return has_cap(c, CAP_OFFSET_BOUNDING, capability);
642 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
649 max = DIV_ROUND_UP(cap_last_cap(), 32U);
650 p += strspn(p, WHITESPACE);
660 if (!c->capability) {
661 c->capability = new0(uint32_t, max * 4);
666 for (i = 0; i < sz; i ++) {
669 for (j = 0; j < 8; ++j) {
679 c->capability[offset * max + (sz - i - 1)] = v;
685 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
690 assert(c->allocated);
692 if (!(mask & SD_BUS_CREDS_AUGMENT))
695 missing = mask & ~c->mask;
699 /* Try to retrieve PID from creds if it wasn't passed to us */
700 if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
703 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
706 /* Without pid we cannot do much... */
712 c->mask |= SD_BUS_CREDS_PID;
717 c->mask |= SD_BUS_CREDS_TID;
720 if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
721 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
722 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
723 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
724 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
726 _cleanup_fclose_ FILE *f = NULL;
729 p = procfs_file_alloca(pid, "status");
735 else if (errno != EPERM && errno != EACCES)
740 FOREACH_LINE(line, f, return -errno) {
743 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
744 p = startswith(line, "Uid:");
746 unsigned long uid, euid, suid, fsuid;
748 p += strspn(p, WHITESPACE);
749 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
752 c->uid = (uid_t) uid;
753 c->euid = (uid_t) euid;
754 c->suid = (uid_t) suid;
755 c->fsuid = (uid_t) fsuid;
756 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
761 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
762 p = startswith(line, "Gid:");
764 unsigned long gid, egid, sgid, fsgid;
766 p += strspn(p, WHITESPACE);
767 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
770 c->gid = (gid_t) gid;
771 c->egid = (gid_t) egid;
772 c->sgid = (gid_t) sgid;
773 c->fsgid = (gid_t) fsgid;
774 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
779 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
780 p = startswith(line, "Groups:");
782 size_t allocated = 0;
788 p += strspn(p, WHITESPACE);
792 if (sscanf(p, "%lu%n", &g, &n) != 1)
795 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
798 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
802 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
807 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
808 p = startswith(line, "CapEff:");
810 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
814 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
819 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
820 p = startswith(line, "CapPrm:");
822 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
826 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
831 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
832 p = startswith(line, "CapInh:");
834 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
838 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
843 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
844 p = startswith(line, "CapBnd:");
846 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
850 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
858 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
861 p = procfs_file_alloca(pid, "attr/current");
862 r = read_one_line_file(p, &c->label);
864 if (r != -ENOENT && r != -EINVAL && r != -EPERM && r != -EACCES)
867 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
870 if (missing & SD_BUS_CREDS_COMM) {
871 r = get_process_comm(pid, &c->comm);
873 if (r != -EPERM && r != -EACCES)
876 c->mask |= SD_BUS_CREDS_COMM;
879 if (missing & SD_BUS_CREDS_EXE) {
880 r = get_process_exe(pid, &c->exe);
882 if (r != -EPERM && r != -EACCES)
885 c->mask |= SD_BUS_CREDS_EXE;
888 if (missing & SD_BUS_CREDS_CMDLINE) {
891 p = procfs_file_alloca(pid, "cmdline");
892 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
896 if (r != -EPERM && r != -EACCES)
899 if (c->cmdline_size == 0) {
903 c->mask |= SD_BUS_CREDS_CMDLINE;
907 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
908 _cleanup_free_ char *p = NULL;
910 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
913 r = read_one_line_file(p, &c->tid_comm);
917 if (r != -EPERM && r != -EACCES)
920 c->mask |= SD_BUS_CREDS_TID_COMM;
923 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)) {
925 r = cg_pid_get_path(NULL, pid, &c->cgroup);
927 if (r != -EPERM && r != -EACCES)
930 r = cg_get_root_path(&c->cgroup_root);
934 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);
938 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
939 r = audit_session_from_pid(pid, &c->audit_session_id);
941 if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
944 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
947 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
948 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
950 if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
953 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
959 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
960 _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL;
966 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
967 /* There's already all data we need, or augmentation
968 * wasn't turned on. */
970 *ret = sd_bus_creds_ref(c);
978 /* Copy the original data over */
980 if (c->mask & mask & SD_BUS_CREDS_UID) {
982 n->mask |= SD_BUS_CREDS_UID;
985 if (c->mask & mask & SD_BUS_CREDS_EUID) {
987 n->mask |= SD_BUS_CREDS_EUID;
990 if (c->mask & mask & SD_BUS_CREDS_SUID) {
992 n->mask |= SD_BUS_CREDS_SUID;
995 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
997 n->mask |= SD_BUS_CREDS_FSUID;
1000 if (c->mask & mask & SD_BUS_CREDS_GID) {
1002 n->mask |= SD_BUS_CREDS_GID;
1005 if (c->mask & mask & SD_BUS_CREDS_EGID) {
1007 n->mask |= SD_BUS_CREDS_EGID;
1010 if (c->mask & mask & SD_BUS_CREDS_SGID) {
1012 n->mask |= SD_BUS_CREDS_SGID;
1015 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
1016 n->fsgid = c->fsgid;
1017 n->mask |= SD_BUS_CREDS_FSGID;
1020 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
1021 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
1022 if (!n->supplementary_gids)
1024 n->n_supplementary_gids = c->n_supplementary_gids;
1025 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
1028 if (c->mask & mask & SD_BUS_CREDS_PID) {
1030 n->mask |= SD_BUS_CREDS_PID;
1033 if (c->mask & mask & SD_BUS_CREDS_TID) {
1035 n->mask |= SD_BUS_CREDS_TID;
1038 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1039 n->comm = strdup(c->comm);
1043 n->mask |= SD_BUS_CREDS_COMM;
1046 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1047 n->tid_comm = strdup(c->tid_comm);
1051 n->mask |= SD_BUS_CREDS_TID_COMM;
1054 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1055 n->exe = strdup(c->exe);
1059 n->mask |= SD_BUS_CREDS_EXE;
1062 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1063 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1067 n->cmdline_size = c->cmdline_size;
1068 n->mask |= SD_BUS_CREDS_CMDLINE;
1071 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)) {
1072 n->cgroup = strdup(c->cgroup);
1076 n->cgroup_root = strdup(c->cgroup_root);
1077 if (!n->cgroup_root)
1080 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);
1083 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1084 n->capability = memdup(c->capability, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4);
1088 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);
1091 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1092 n->label = strdup(c->label);
1095 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1098 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1099 n->audit_session_id = c->audit_session_id;
1100 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1102 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1103 n->audit_login_uid = c->audit_login_uid;
1104 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1107 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1108 n->unique_name = strdup(c->unique_name);
1109 if (!n->unique_name)
1111 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1114 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1115 n->well_known_names = strv_copy(c->well_known_names);
1116 if (!n->well_known_names)
1118 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1121 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1122 n->description = strdup(c->description);
1123 if (!n->description)
1125 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1130 r = bus_creds_add_more(n, mask,
1131 c->mask & SD_BUS_CREDS_PID ? c->pid : 0,
1132 c->mask & SD_BUS_CREDS_TID ? c->tid : 0);