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) {
361 assert_return(c, -EINVAL);
362 assert_return(ret, -EINVAL);
364 if (!(c->mask & SD_BUS_CREDS_UNIT))
376 _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
377 assert_return(c, -EINVAL);
378 assert_return(ret, -EINVAL);
380 if (!(c->mask & SD_BUS_CREDS_USER_UNIT))
392 _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
393 assert_return(c, -EINVAL);
394 assert_return(ret, -EINVAL);
396 if (!(c->mask & SD_BUS_CREDS_SLICE))
408 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
411 assert_return(c, -EINVAL);
412 assert_return(ret, -EINVAL);
414 if (!(c->mask & SD_BUS_CREDS_SESSION))
422 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
426 r = cg_path_get_session(shifted, (char**) &c->session);
435 _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
439 assert_return(c, -EINVAL);
440 assert_return(uid, -EINVAL);
442 if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
447 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
454 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
455 assert_return(c, -EINVAL);
457 if (!(c->mask & SD_BUS_CREDS_CMDLINE))
460 assert_return(c->cmdline, -ESRCH);
463 if (!c->cmdline_array) {
464 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
465 if (!c->cmdline_array)
469 *cmdline = c->cmdline_array;
473 _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
474 assert_return(c, -EINVAL);
475 assert_return(sessionid, -EINVAL);
477 if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
480 *sessionid = c->audit_session_id;
484 _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
485 assert_return(c, -EINVAL);
486 assert_return(uid, -EINVAL);
488 if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID))
491 *uid = c->audit_login_uid;
495 _public_ int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **unique_name) {
496 assert_return(c, -EINVAL);
497 assert_return(unique_name, -EINVAL);
499 if (!(c->mask & SD_BUS_CREDS_UNIQUE_NAME))
502 *unique_name = c->unique_name;
506 _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) {
507 assert_return(c, -EINVAL);
508 assert_return(well_known_names, -EINVAL);
510 if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
513 /* As a special hack we return the bus driver as well-known
514 * names list when this is requested. */
515 if (c->well_known_names_driver) {
516 static const char* const wkn[] = {
517 "org.freedesktop.DBus",
521 *well_known_names = (char**) wkn;
525 if (c->well_known_names_local) {
526 static const char* const wkn[] = {
527 "org.freedesktop.DBus.Local",
531 *well_known_names = (char**) wkn;
535 *well_known_names = c->well_known_names;
539 _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) {
540 assert_return(c, -EINVAL);
541 assert_return(ret, -EINVAL);
543 if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
546 assert(c->description);
548 if (!c->unescaped_description) {
549 c->unescaped_description = bus_label_unescape(c->description);
550 if (!c->unescaped_description)
554 *ret = c->unescaped_description;
558 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
562 assert(capability >= 0);
563 assert(c->capability);
565 sz = DIV_ROUND_UP(cap_last_cap(), 32U);
566 if ((unsigned)capability > cap_last_cap())
569 return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability));
572 _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
573 assert_return(c, -EINVAL);
574 assert_return(capability >= 0, -EINVAL);
576 if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS))
579 return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
582 _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
583 assert_return(c, -EINVAL);
584 assert_return(capability >= 0, -EINVAL);
586 if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS))
589 return has_cap(c, CAP_OFFSET_PERMITTED, capability);
592 _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
593 assert_return(c, -EINVAL);
594 assert_return(capability >= 0, -EINVAL);
596 if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS))
599 return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
602 _public_ int sd_bus_creds_has_bounding_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_BOUNDING_CAPS))
609 return has_cap(c, CAP_OFFSET_BOUNDING, capability);
612 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
619 max = DIV_ROUND_UP(cap_last_cap(), 32U);
620 p += strspn(p, WHITESPACE);
630 if (!c->capability) {
631 c->capability = new0(uint32_t, max * 4);
636 for (i = 0; i < sz; i ++) {
639 for (j = 0; j < 8; ++j) {
649 c->capability[offset * max + (sz - i - 1)] = v;
655 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
660 assert(c->allocated);
662 if (!(mask & SD_BUS_CREDS_AUGMENT))
665 missing = mask & ~c->mask;
669 /* Try to retrieve PID from creds if it wasn't passed to us */
670 if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
673 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
676 /* Without pid we cannot do much... */
682 c->mask |= SD_BUS_CREDS_PID;
687 c->mask |= SD_BUS_CREDS_TID;
690 if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
691 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
692 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
693 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
694 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
696 _cleanup_fclose_ FILE *f = NULL;
699 p = procfs_file_alloca(pid, "status");
705 else if (errno != EPERM && errno != EACCES)
710 FOREACH_LINE(line, f, return -errno) {
713 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
714 p = startswith(line, "Uid:");
716 unsigned long uid, euid, suid, fsuid;
718 p += strspn(p, WHITESPACE);
719 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
722 c->uid = (uid_t) uid;
723 c->euid = (uid_t) euid;
724 c->suid = (uid_t) suid;
725 c->fsuid = (uid_t) fsuid;
726 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
731 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
732 p = startswith(line, "Gid:");
734 unsigned long gid, egid, sgid, fsgid;
736 p += strspn(p, WHITESPACE);
737 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
740 c->gid = (gid_t) gid;
741 c->egid = (gid_t) egid;
742 c->sgid = (gid_t) sgid;
743 c->fsgid = (gid_t) fsgid;
744 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
749 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
750 p = startswith(line, "Groups:");
752 size_t allocated = 0;
758 p += strspn(p, WHITESPACE);
762 if (sscanf(p, "%lu%n", &g, &n) != 1)
765 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
768 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
772 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
777 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
778 p = startswith(line, "CapEff:");
780 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
784 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
789 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
790 p = startswith(line, "CapPrm:");
792 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
796 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
801 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
802 p = startswith(line, "CapInh:");
804 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
808 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
813 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
814 p = startswith(line, "CapBnd:");
816 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
820 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
828 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
831 p = procfs_file_alloca(pid, "attr/current");
832 r = read_one_line_file(p, &c->label);
834 if (r != -ENOENT && r != -EINVAL && r != -EPERM && r != -EACCES)
837 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
840 if (missing & SD_BUS_CREDS_COMM) {
841 r = get_process_comm(pid, &c->comm);
843 if (r != -EPERM && r != -EACCES)
846 c->mask |= SD_BUS_CREDS_COMM;
849 if (missing & SD_BUS_CREDS_EXE) {
850 r = get_process_exe(pid, &c->exe);
852 if (r != -EPERM && r != -EACCES)
855 c->mask |= SD_BUS_CREDS_EXE;
858 if (missing & SD_BUS_CREDS_CMDLINE) {
861 p = procfs_file_alloca(pid, "cmdline");
862 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
866 if (r != -EPERM && r != -EACCES)
869 if (c->cmdline_size == 0) {
873 c->mask |= SD_BUS_CREDS_CMDLINE;
877 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
878 _cleanup_free_ char *p = NULL;
880 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
883 r = read_one_line_file(p, &c->tid_comm);
887 if (r != -EPERM && r != -EACCES)
890 c->mask |= SD_BUS_CREDS_TID_COMM;
893 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)) {
895 r = cg_pid_get_path(NULL, pid, &c->cgroup);
897 if (r != -EPERM && r != -EACCES)
900 r = cg_get_root_path(&c->cgroup_root);
904 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);
908 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
909 r = audit_session_from_pid(pid, &c->audit_session_id);
911 if (r != -EOPNOTSUPP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
914 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
917 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
918 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
920 if (r != -EOPNOTSUPP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
923 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
929 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
930 _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL;
936 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
937 /* There's already all data we need, or augmentation
938 * wasn't turned on. */
940 *ret = sd_bus_creds_ref(c);
948 /* Copy the original data over */
950 if (c->mask & mask & SD_BUS_CREDS_UID) {
952 n->mask |= SD_BUS_CREDS_UID;
955 if (c->mask & mask & SD_BUS_CREDS_EUID) {
957 n->mask |= SD_BUS_CREDS_EUID;
960 if (c->mask & mask & SD_BUS_CREDS_SUID) {
962 n->mask |= SD_BUS_CREDS_SUID;
965 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
967 n->mask |= SD_BUS_CREDS_FSUID;
970 if (c->mask & mask & SD_BUS_CREDS_GID) {
972 n->mask |= SD_BUS_CREDS_GID;
975 if (c->mask & mask & SD_BUS_CREDS_EGID) {
977 n->mask |= SD_BUS_CREDS_EGID;
980 if (c->mask & mask & SD_BUS_CREDS_SGID) {
982 n->mask |= SD_BUS_CREDS_SGID;
985 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
987 n->mask |= SD_BUS_CREDS_FSGID;
990 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
991 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
992 if (!n->supplementary_gids)
994 n->n_supplementary_gids = c->n_supplementary_gids;
995 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
998 if (c->mask & mask & SD_BUS_CREDS_PID) {
1000 n->mask |= SD_BUS_CREDS_PID;
1003 if (c->mask & mask & SD_BUS_CREDS_TID) {
1005 n->mask |= SD_BUS_CREDS_TID;
1008 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1009 n->comm = strdup(c->comm);
1013 n->mask |= SD_BUS_CREDS_COMM;
1016 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1017 n->tid_comm = strdup(c->tid_comm);
1021 n->mask |= SD_BUS_CREDS_TID_COMM;
1024 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1025 n->exe = strdup(c->exe);
1029 n->mask |= SD_BUS_CREDS_EXE;
1032 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1033 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1037 n->cmdline_size = c->cmdline_size;
1038 n->mask |= SD_BUS_CREDS_CMDLINE;
1041 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)) {
1042 n->cgroup = strdup(c->cgroup);
1046 n->cgroup_root = strdup(c->cgroup_root);
1047 if (!n->cgroup_root)
1050 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);
1053 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1054 n->capability = memdup(c->capability, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4);
1058 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);
1061 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1062 n->label = strdup(c->label);
1065 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1068 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1069 n->audit_session_id = c->audit_session_id;
1070 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1072 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1073 n->audit_login_uid = c->audit_login_uid;
1074 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1077 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1078 n->unique_name = strdup(c->unique_name);
1079 if (!n->unique_name)
1081 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1084 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1085 n->well_known_names = strv_copy(c->well_known_names);
1086 if (!n->well_known_names)
1088 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1091 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1092 n->description = strdup(c->description);
1093 if (!n->description)
1095 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1100 r = bus_creds_add_more(n, mask,
1101 c->mask & SD_BUS_CREDS_PID ? c->pid : 0,
1102 c->mask & SD_BUS_CREDS_TID ? c->tid : 0);