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);
54 free(c->supplementary_gids);
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);
105 free(c->supplementary_gids);
106 c->supplementary_gids = NULL;
108 strv_free(c->well_known_names);
109 c->well_known_names = NULL;
118 m = container_of(c, sd_bus_message, creds);
119 sd_bus_message_unref(m);
126 _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
132 sd_bus_creds* bus_creds_new(void) {
135 c = new0(sd_bus_creds, 1);
144 _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
148 assert_return(pid >= 0, -EINVAL);
149 assert_return(mask <= _SD_BUS_CREDS_ALL, -EOPNOTSUPP);
150 assert_return(ret, -EINVAL);
159 r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
161 sd_bus_creds_unref(c);
165 /* Check if the process existed at all, in case we haven't
166 * figured that out already */
167 if (!pid_is_alive(pid)) {
168 sd_bus_creds_unref(c);
176 _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) {
177 assert_return(c, -EINVAL);
178 assert_return(uid, -EINVAL);
180 if (!(c->mask & SD_BUS_CREDS_UID))
187 _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) {
188 assert_return(c, -EINVAL);
189 assert_return(euid, -EINVAL);
191 if (!(c->mask & SD_BUS_CREDS_EUID))
198 _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) {
199 assert_return(c, -EINVAL);
200 assert_return(suid, -EINVAL);
202 if (!(c->mask & SD_BUS_CREDS_SUID))
210 _public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) {
211 assert_return(c, -EINVAL);
212 assert_return(fsuid, -EINVAL);
214 if (!(c->mask & SD_BUS_CREDS_FSUID))
221 _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
222 assert_return(c, -EINVAL);
223 assert_return(gid, -EINVAL);
225 if (!(c->mask & SD_BUS_CREDS_GID))
233 _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) {
234 assert_return(c, -EINVAL);
235 assert_return(egid, -EINVAL);
237 if (!(c->mask & SD_BUS_CREDS_EGID))
244 _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
245 assert_return(c, -EINVAL);
246 assert_return(sgid, -EINVAL);
248 if (!(c->mask & SD_BUS_CREDS_SGID))
255 _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
256 assert_return(c, -EINVAL);
257 assert_return(fsgid, -EINVAL);
259 if (!(c->mask & SD_BUS_CREDS_FSGID))
266 _public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) {
267 assert_return(c, -EINVAL);
268 assert_return(gids, -EINVAL);
270 if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
273 *gids = c->supplementary_gids;
274 return (int) c->n_supplementary_gids;
277 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
278 assert_return(c, -EINVAL);
279 assert_return(pid, -EINVAL);
281 if (!(c->mask & SD_BUS_CREDS_PID))
289 _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) {
290 assert_return(c, -EINVAL);
291 assert_return(tid, -EINVAL);
293 if (!(c->mask & SD_BUS_CREDS_TID))
301 _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
302 assert_return(c, -EINVAL);
304 if (!(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT))
312 _public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) {
313 assert_return(c, -EINVAL);
314 assert_return(ret, -EINVAL);
316 if (!(c->mask & SD_BUS_CREDS_COMM))
324 _public_ int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **ret) {
325 assert_return(c, -EINVAL);
326 assert_return(ret, -EINVAL);
328 if (!(c->mask & SD_BUS_CREDS_TID_COMM))
336 _public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) {
337 assert_return(c, -EINVAL);
338 assert_return(ret, -EINVAL);
340 if (!(c->mask & SD_BUS_CREDS_EXE))
348 _public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) {
349 assert_return(c, -EINVAL);
350 assert_return(ret, -EINVAL);
352 if (!(c->mask & SD_BUS_CREDS_CGROUP))
360 _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {
363 assert_return(c, -EINVAL);
364 assert_return(ret, -EINVAL);
366 if (!(c->mask & SD_BUS_CREDS_UNIT))
374 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
378 r = cg_path_get_unit(shifted, (char**) &c->unit);
387 _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
390 assert_return(c, -EINVAL);
391 assert_return(ret, -EINVAL);
393 if (!(c->mask & SD_BUS_CREDS_USER_UNIT))
401 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
405 r = cg_path_get_user_unit(shifted, (char**) &c->user_unit);
414 _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
417 assert_return(c, -EINVAL);
418 assert_return(ret, -EINVAL);
420 if (!(c->mask & SD_BUS_CREDS_SLICE))
428 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
432 r = cg_path_get_slice(shifted, (char**) &c->slice);
441 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
444 assert_return(c, -EINVAL);
445 assert_return(ret, -EINVAL);
447 if (!(c->mask & SD_BUS_CREDS_SESSION))
455 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
459 r = cg_path_get_session(shifted, (char**) &c->session);
468 _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
472 assert_return(c, -EINVAL);
473 assert_return(uid, -EINVAL);
475 if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
480 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
484 return cg_path_get_owner_uid(shifted, uid);
487 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
488 assert_return(c, -EINVAL);
490 if (!(c->mask & SD_BUS_CREDS_CMDLINE))
493 assert_return(c->cmdline, -ESRCH);
496 if (!c->cmdline_array) {
497 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
498 if (!c->cmdline_array)
502 *cmdline = c->cmdline_array;
506 _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
507 assert_return(c, -EINVAL);
508 assert_return(sessionid, -EINVAL);
510 if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
513 *sessionid = c->audit_session_id;
517 _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
518 assert_return(c, -EINVAL);
519 assert_return(uid, -EINVAL);
521 if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID))
524 *uid = c->audit_login_uid;
528 _public_ int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **unique_name) {
529 assert_return(c, -EINVAL);
530 assert_return(unique_name, -EINVAL);
532 if (!(c->mask & SD_BUS_CREDS_UNIQUE_NAME))
535 *unique_name = c->unique_name;
539 _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) {
540 assert_return(c, -EINVAL);
541 assert_return(well_known_names, -EINVAL);
543 if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
546 /* As a special hack we return the bus driver as well-known
547 * names list when this is requested. */
548 if (c->well_known_names_driver) {
549 static const char* const wkn[] = {
550 "org.freedesktop.DBus",
554 *well_known_names = (char**) wkn;
558 if (c->well_known_names_local) {
559 static const char* const wkn[] = {
560 "org.freedesktop.DBus.Local",
564 *well_known_names = (char**) wkn;
568 *well_known_names = c->well_known_names;
572 _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) {
573 assert_return(c, -EINVAL);
574 assert_return(ret, -EINVAL);
576 if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
579 assert(c->description);
581 if (!c->unescaped_description) {
582 c->unescaped_description = bus_label_unescape(c->description);
583 if (!c->unescaped_description)
587 *ret = c->unescaped_description;
591 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
595 assert(capability >= 0);
596 assert(c->capability);
598 sz = DIV_ROUND_UP(cap_last_cap(), 32U);
599 if ((unsigned)capability > cap_last_cap())
602 return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability));
605 _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
606 assert_return(c, -EINVAL);
607 assert_return(capability >= 0, -EINVAL);
609 if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS))
612 return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
615 _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
616 assert_return(c, -EINVAL);
617 assert_return(capability >= 0, -EINVAL);
619 if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS))
622 return has_cap(c, CAP_OFFSET_PERMITTED, capability);
625 _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
626 assert_return(c, -EINVAL);
627 assert_return(capability >= 0, -EINVAL);
629 if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS))
632 return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
635 _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) {
636 assert_return(c, -EINVAL);
637 assert_return(capability >= 0, -EINVAL);
639 if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS))
642 return has_cap(c, CAP_OFFSET_BOUNDING, capability);
645 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
652 max = DIV_ROUND_UP(cap_last_cap(), 32U);
653 p += strspn(p, WHITESPACE);
663 if (!c->capability) {
664 c->capability = new0(uint32_t, max * 4);
669 for (i = 0; i < sz; i ++) {
672 for (j = 0; j < 8; ++j) {
682 c->capability[offset * max + (sz - i - 1)] = v;
688 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
693 assert(c->allocated);
695 if (!(mask & SD_BUS_CREDS_AUGMENT))
698 missing = mask & ~c->mask;
702 /* Try to retrieve PID from creds if it wasn't passed to us */
703 if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
706 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
709 /* Without pid we cannot do much... */
715 c->mask |= SD_BUS_CREDS_PID;
720 c->mask |= SD_BUS_CREDS_TID;
723 if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
724 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
725 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
726 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
727 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
729 _cleanup_fclose_ FILE *f = NULL;
732 p = procfs_file_alloca(pid, "status");
738 else if (errno != EPERM && errno != EACCES)
743 FOREACH_LINE(line, f, return -errno) {
746 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
747 p = startswith(line, "Uid:");
749 unsigned long uid, euid, suid, fsuid;
751 p += strspn(p, WHITESPACE);
752 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
755 c->uid = (uid_t) uid;
756 c->euid = (uid_t) euid;
757 c->suid = (uid_t) suid;
758 c->fsuid = (uid_t) fsuid;
759 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
764 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
765 p = startswith(line, "Gid:");
767 unsigned long gid, egid, sgid, fsgid;
769 p += strspn(p, WHITESPACE);
770 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
773 c->gid = (gid_t) gid;
774 c->egid = (gid_t) egid;
775 c->sgid = (gid_t) sgid;
776 c->fsgid = (gid_t) fsgid;
777 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
782 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
783 p = startswith(line, "Groups:");
785 size_t allocated = 0;
791 p += strspn(p, WHITESPACE);
795 if (sscanf(p, "%lu%n", &g, &n) != 1)
798 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
801 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
805 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
810 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
811 p = startswith(line, "CapEff:");
813 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
817 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
822 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
823 p = startswith(line, "CapPrm:");
825 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
829 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
834 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
835 p = startswith(line, "CapInh:");
837 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
841 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
846 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
847 p = startswith(line, "CapBnd:");
849 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
853 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
861 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
864 p = procfs_file_alloca(pid, "attr/current");
865 r = read_one_line_file(p, &c->label);
867 if (r != -ENOENT && r != -EINVAL && r != -EPERM && r != -EACCES)
870 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
873 if (missing & SD_BUS_CREDS_COMM) {
874 r = get_process_comm(pid, &c->comm);
876 if (r != -EPERM && r != -EACCES)
879 c->mask |= SD_BUS_CREDS_COMM;
882 if (missing & SD_BUS_CREDS_EXE) {
883 r = get_process_exe(pid, &c->exe);
885 if (r != -EPERM && r != -EACCES)
888 c->mask |= SD_BUS_CREDS_EXE;
891 if (missing & SD_BUS_CREDS_CMDLINE) {
894 p = procfs_file_alloca(pid, "cmdline");
895 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
899 if (r != -EPERM && r != -EACCES)
902 if (c->cmdline_size == 0) {
906 c->mask |= SD_BUS_CREDS_CMDLINE;
910 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
911 _cleanup_free_ char *p = NULL;
913 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
916 r = read_one_line_file(p, &c->tid_comm);
920 if (r != -EPERM && r != -EACCES)
923 c->mask |= SD_BUS_CREDS_TID_COMM;
926 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)) {
928 r = cg_pid_get_path(NULL, pid, &c->cgroup);
930 if (r != -EPERM && r != -EACCES)
933 r = cg_get_root_path(&c->cgroup_root);
937 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);
941 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
942 r = audit_session_from_pid(pid, &c->audit_session_id);
944 if (r != -EOPNOTSUPP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
947 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
950 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
951 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
953 if (r != -EOPNOTSUPP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
956 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
962 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
963 _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL;
969 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
970 /* There's already all data we need, or augmentation
971 * wasn't turned on. */
973 *ret = sd_bus_creds_ref(c);
981 /* Copy the original data over */
983 if (c->mask & mask & SD_BUS_CREDS_UID) {
985 n->mask |= SD_BUS_CREDS_UID;
988 if (c->mask & mask & SD_BUS_CREDS_EUID) {
990 n->mask |= SD_BUS_CREDS_EUID;
993 if (c->mask & mask & SD_BUS_CREDS_SUID) {
995 n->mask |= SD_BUS_CREDS_SUID;
998 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
1000 n->mask |= SD_BUS_CREDS_FSUID;
1003 if (c->mask & mask & SD_BUS_CREDS_GID) {
1005 n->mask |= SD_BUS_CREDS_GID;
1008 if (c->mask & mask & SD_BUS_CREDS_EGID) {
1010 n->mask |= SD_BUS_CREDS_EGID;
1013 if (c->mask & mask & SD_BUS_CREDS_SGID) {
1015 n->mask |= SD_BUS_CREDS_SGID;
1018 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
1019 n->fsgid = c->fsgid;
1020 n->mask |= SD_BUS_CREDS_FSGID;
1023 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
1024 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
1025 if (!n->supplementary_gids)
1027 n->n_supplementary_gids = c->n_supplementary_gids;
1028 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
1031 if (c->mask & mask & SD_BUS_CREDS_PID) {
1033 n->mask |= SD_BUS_CREDS_PID;
1036 if (c->mask & mask & SD_BUS_CREDS_TID) {
1038 n->mask |= SD_BUS_CREDS_TID;
1041 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1042 n->comm = strdup(c->comm);
1046 n->mask |= SD_BUS_CREDS_COMM;
1049 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1050 n->tid_comm = strdup(c->tid_comm);
1054 n->mask |= SD_BUS_CREDS_TID_COMM;
1057 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1058 n->exe = strdup(c->exe);
1062 n->mask |= SD_BUS_CREDS_EXE;
1065 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1066 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1070 n->cmdline_size = c->cmdline_size;
1071 n->mask |= SD_BUS_CREDS_CMDLINE;
1074 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)) {
1075 n->cgroup = strdup(c->cgroup);
1079 n->cgroup_root = strdup(c->cgroup_root);
1080 if (!n->cgroup_root)
1083 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);
1086 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1087 n->capability = memdup(c->capability, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4);
1091 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);
1094 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1095 n->label = strdup(c->label);
1098 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1101 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1102 n->audit_session_id = c->audit_session_id;
1103 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1105 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1106 n->audit_login_uid = c->audit_login_uid;
1107 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1110 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1111 n->unique_name = strdup(c->unique_name);
1112 if (!n->unique_name)
1114 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1117 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1118 n->well_known_names = strv_copy(c->well_known_names);
1119 if (!n->well_known_names)
1121 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1124 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1125 n->description = strdup(c->description);
1126 if (!n->description)
1128 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1133 r = bus_creds_add_more(n, mask,
1134 c->mask & SD_BUS_CREDS_PID ? c->pid : 0,
1135 c->mask & SD_BUS_CREDS_TID ? c->tid : 0);