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 "formats-util.h"
27 #include "capability.h"
28 #include "cgroup-util.h"
31 #include "bus-message.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);
55 free(c->supplementary_gids);
57 free(c->well_known_names); /* note that this is an strv, but
58 * we only free the array, not the
59 * strings the array points to. The
60 * full strv we only free if
61 * c->allocated is set, see
64 strv_free(c->cmdline_array);
67 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
68 assert_return(c, NULL);
76 /* If this is an embedded creds structure, then
77 * forward ref counting to the message */
78 m = container_of(c, sd_bus_message, creds);
79 sd_bus_message_ref(m);
85 _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
102 free(c->unique_name);
103 free(c->cgroup_root);
104 free(c->description);
106 free(c->supplementary_gids);
107 c->supplementary_gids = NULL;
109 strv_free(c->well_known_names);
110 c->well_known_names = NULL;
119 m = container_of(c, sd_bus_message, creds);
120 sd_bus_message_unref(m);
127 _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
133 sd_bus_creds* bus_creds_new(void) {
136 c = new0(sd_bus_creds, 1);
145 _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
149 assert_return(pid >= 0, -EINVAL);
150 assert_return(mask <= _SD_BUS_CREDS_ALL, -EOPNOTSUPP);
151 assert_return(ret, -EINVAL);
160 r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
162 sd_bus_creds_unref(c);
166 /* Check if the process existed at all, in case we haven't
167 * figured that out already */
168 if (!pid_is_alive(pid)) {
169 sd_bus_creds_unref(c);
177 _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) {
178 assert_return(c, -EINVAL);
179 assert_return(uid, -EINVAL);
181 if (!(c->mask & SD_BUS_CREDS_UID))
188 _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) {
189 assert_return(c, -EINVAL);
190 assert_return(euid, -EINVAL);
192 if (!(c->mask & SD_BUS_CREDS_EUID))
199 _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) {
200 assert_return(c, -EINVAL);
201 assert_return(suid, -EINVAL);
203 if (!(c->mask & SD_BUS_CREDS_SUID))
211 _public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) {
212 assert_return(c, -EINVAL);
213 assert_return(fsuid, -EINVAL);
215 if (!(c->mask & SD_BUS_CREDS_FSUID))
222 _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
223 assert_return(c, -EINVAL);
224 assert_return(gid, -EINVAL);
226 if (!(c->mask & SD_BUS_CREDS_GID))
234 _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) {
235 assert_return(c, -EINVAL);
236 assert_return(egid, -EINVAL);
238 if (!(c->mask & SD_BUS_CREDS_EGID))
245 _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
246 assert_return(c, -EINVAL);
247 assert_return(sgid, -EINVAL);
249 if (!(c->mask & SD_BUS_CREDS_SGID))
256 _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
257 assert_return(c, -EINVAL);
258 assert_return(fsgid, -EINVAL);
260 if (!(c->mask & SD_BUS_CREDS_FSGID))
267 _public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) {
268 assert_return(c, -EINVAL);
269 assert_return(gids, -EINVAL);
271 if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
274 *gids = c->supplementary_gids;
275 return (int) c->n_supplementary_gids;
278 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
279 assert_return(c, -EINVAL);
280 assert_return(pid, -EINVAL);
282 if (!(c->mask & SD_BUS_CREDS_PID))
290 _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) {
291 assert_return(c, -EINVAL);
292 assert_return(tid, -EINVAL);
294 if (!(c->mask & SD_BUS_CREDS_TID))
302 _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
303 assert_return(c, -EINVAL);
305 if (!(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT))
313 _public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) {
314 assert_return(c, -EINVAL);
315 assert_return(ret, -EINVAL);
317 if (!(c->mask & SD_BUS_CREDS_COMM))
325 _public_ int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **ret) {
326 assert_return(c, -EINVAL);
327 assert_return(ret, -EINVAL);
329 if (!(c->mask & SD_BUS_CREDS_TID_COMM))
337 _public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) {
338 assert_return(c, -EINVAL);
339 assert_return(ret, -EINVAL);
341 if (!(c->mask & SD_BUS_CREDS_EXE))
349 _public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) {
350 assert_return(c, -EINVAL);
351 assert_return(ret, -EINVAL);
353 if (!(c->mask & SD_BUS_CREDS_CGROUP))
361 _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {
362 assert_return(c, -EINVAL);
363 assert_return(ret, -EINVAL);
365 if (!(c->mask & SD_BUS_CREDS_UNIT))
377 _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
378 assert_return(c, -EINVAL);
379 assert_return(ret, -EINVAL);
381 if (!(c->mask & SD_BUS_CREDS_USER_UNIT))
393 _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
394 assert_return(c, -EINVAL);
395 assert_return(ret, -EINVAL);
397 if (!(c->mask & SD_BUS_CREDS_SLICE))
409 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
412 assert_return(c, -EINVAL);
413 assert_return(ret, -EINVAL);
415 if (!(c->mask & SD_BUS_CREDS_SESSION))
423 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
427 r = cg_path_get_session(shifted, (char**) &c->session);
436 _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
440 assert_return(c, -EINVAL);
441 assert_return(uid, -EINVAL);
443 if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
448 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
455 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
456 assert_return(c, -EINVAL);
458 if (!(c->mask & SD_BUS_CREDS_CMDLINE))
461 assert_return(c->cmdline, -ESRCH);
464 if (!c->cmdline_array) {
465 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
466 if (!c->cmdline_array)
470 *cmdline = c->cmdline_array;
474 _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
475 assert_return(c, -EINVAL);
476 assert_return(sessionid, -EINVAL);
478 if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
481 *sessionid = c->audit_session_id;
485 _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
486 assert_return(c, -EINVAL);
487 assert_return(uid, -EINVAL);
489 if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID))
492 *uid = c->audit_login_uid;
496 _public_ int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **unique_name) {
497 assert_return(c, -EINVAL);
498 assert_return(unique_name, -EINVAL);
500 if (!(c->mask & SD_BUS_CREDS_UNIQUE_NAME))
503 *unique_name = c->unique_name;
507 _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) {
508 assert_return(c, -EINVAL);
509 assert_return(well_known_names, -EINVAL);
511 if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
514 /* As a special hack we return the bus driver as well-known
515 * names list when this is requested. */
516 if (c->well_known_names_driver) {
517 static const char* const wkn[] = {
518 "org.freedesktop.DBus",
522 *well_known_names = (char**) wkn;
526 if (c->well_known_names_local) {
527 static const char* const wkn[] = {
528 "org.freedesktop.DBus.Local",
532 *well_known_names = (char**) wkn;
536 *well_known_names = c->well_known_names;
540 _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) {
541 assert_return(c, -EINVAL);
542 assert_return(ret, -EINVAL);
544 if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
547 assert(c->description);
549 if (!c->unescaped_description) {
550 c->unescaped_description = bus_label_unescape(c->description);
551 if (!c->unescaped_description)
555 *ret = c->unescaped_description;
559 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
563 assert(capability >= 0);
564 assert(c->capability);
566 sz = DIV_ROUND_UP(cap_last_cap(), 32U);
567 if ((unsigned)capability > cap_last_cap())
570 return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability));
573 _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
574 assert_return(c, -EINVAL);
575 assert_return(capability >= 0, -EINVAL);
577 if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS))
580 return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
583 _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
584 assert_return(c, -EINVAL);
585 assert_return(capability >= 0, -EINVAL);
587 if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS))
590 return has_cap(c, CAP_OFFSET_PERMITTED, capability);
593 _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
594 assert_return(c, -EINVAL);
595 assert_return(capability >= 0, -EINVAL);
597 if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS))
600 return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
603 _public_ int sd_bus_creds_has_bounding_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_BOUNDING_CAPS))
610 return has_cap(c, CAP_OFFSET_BOUNDING, capability);
613 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
620 max = DIV_ROUND_UP(cap_last_cap(), 32U);
621 p += strspn(p, WHITESPACE);
631 if (!c->capability) {
632 c->capability = new0(uint32_t, max * 4);
637 for (i = 0; i < sz; i ++) {
640 for (j = 0; j < 8; ++j) {
650 c->capability[offset * max + (sz - i - 1)] = v;
656 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
661 assert(c->allocated);
663 if (!(mask & SD_BUS_CREDS_AUGMENT))
666 missing = mask & ~c->mask;
670 /* Try to retrieve PID from creds if it wasn't passed to us */
671 if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
674 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
677 /* Without pid we cannot do much... */
683 c->mask |= SD_BUS_CREDS_PID;
688 c->mask |= SD_BUS_CREDS_TID;
691 if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
692 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
693 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
694 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
695 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
697 _cleanup_fclose_ FILE *f = NULL;
700 p = procfs_file_alloca(pid, "status");
706 else if (errno != EPERM && errno != EACCES)
711 FOREACH_LINE(line, f, return -errno) {
714 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
715 p = startswith(line, "Uid:");
717 unsigned long uid, euid, suid, fsuid;
719 p += strspn(p, WHITESPACE);
720 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
723 c->uid = (uid_t) uid;
724 c->euid = (uid_t) euid;
725 c->suid = (uid_t) suid;
726 c->fsuid = (uid_t) fsuid;
727 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
732 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
733 p = startswith(line, "Gid:");
735 unsigned long gid, egid, sgid, fsgid;
737 p += strspn(p, WHITESPACE);
738 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
741 c->gid = (gid_t) gid;
742 c->egid = (gid_t) egid;
743 c->sgid = (gid_t) sgid;
744 c->fsgid = (gid_t) fsgid;
745 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
750 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
751 p = startswith(line, "Groups:");
753 size_t allocated = 0;
759 p += strspn(p, WHITESPACE);
763 if (sscanf(p, "%lu%n", &g, &n) != 1)
766 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
769 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
773 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
778 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
779 p = startswith(line, "CapEff:");
781 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
785 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
790 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
791 p = startswith(line, "CapPrm:");
793 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
797 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
802 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
803 p = startswith(line, "CapInh:");
805 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
809 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
814 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
815 p = startswith(line, "CapBnd:");
817 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
821 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
829 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
832 p = procfs_file_alloca(pid, "attr/current");
833 r = read_one_line_file(p, &c->label);
835 if (r != -ENOENT && r != -EINVAL && r != -EPERM && r != -EACCES)
838 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
841 if (missing & SD_BUS_CREDS_COMM) {
842 r = get_process_comm(pid, &c->comm);
844 if (r != -EPERM && r != -EACCES)
847 c->mask |= SD_BUS_CREDS_COMM;
850 if (missing & SD_BUS_CREDS_EXE) {
851 r = get_process_exe(pid, &c->exe);
853 if (r != -EPERM && r != -EACCES)
856 c->mask |= SD_BUS_CREDS_EXE;
859 if (missing & SD_BUS_CREDS_CMDLINE) {
862 p = procfs_file_alloca(pid, "cmdline");
863 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
867 if (r != -EPERM && r != -EACCES)
870 if (c->cmdline_size == 0) {
874 c->mask |= SD_BUS_CREDS_CMDLINE;
878 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
879 _cleanup_free_ char *p = NULL;
881 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
884 r = read_one_line_file(p, &c->tid_comm);
888 if (r != -EPERM && r != -EACCES)
891 c->mask |= SD_BUS_CREDS_TID_COMM;
894 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)) {
896 r = cg_pid_get_path(NULL, pid, &c->cgroup);
898 if (r != -EPERM && r != -EACCES)
901 r = cg_get_root_path(&c->cgroup_root);
905 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);
909 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
910 r = audit_session_from_pid(pid, &c->audit_session_id);
912 if (r != -EOPNOTSUPP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
915 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
918 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
919 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
921 if (r != -EOPNOTSUPP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
924 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
930 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
931 _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL;
937 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
938 /* There's already all data we need, or augmentation
939 * wasn't turned on. */
941 *ret = sd_bus_creds_ref(c);
949 /* Copy the original data over */
951 if (c->mask & mask & SD_BUS_CREDS_UID) {
953 n->mask |= SD_BUS_CREDS_UID;
956 if (c->mask & mask & SD_BUS_CREDS_EUID) {
958 n->mask |= SD_BUS_CREDS_EUID;
961 if (c->mask & mask & SD_BUS_CREDS_SUID) {
963 n->mask |= SD_BUS_CREDS_SUID;
966 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
968 n->mask |= SD_BUS_CREDS_FSUID;
971 if (c->mask & mask & SD_BUS_CREDS_GID) {
973 n->mask |= SD_BUS_CREDS_GID;
976 if (c->mask & mask & SD_BUS_CREDS_EGID) {
978 n->mask |= SD_BUS_CREDS_EGID;
981 if (c->mask & mask & SD_BUS_CREDS_SGID) {
983 n->mask |= SD_BUS_CREDS_SGID;
986 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
988 n->mask |= SD_BUS_CREDS_FSGID;
991 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
992 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
993 if (!n->supplementary_gids)
995 n->n_supplementary_gids = c->n_supplementary_gids;
996 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
999 if (c->mask & mask & SD_BUS_CREDS_PID) {
1001 n->mask |= SD_BUS_CREDS_PID;
1004 if (c->mask & mask & SD_BUS_CREDS_TID) {
1006 n->mask |= SD_BUS_CREDS_TID;
1009 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1010 n->comm = strdup(c->comm);
1014 n->mask |= SD_BUS_CREDS_COMM;
1017 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1018 n->tid_comm = strdup(c->tid_comm);
1022 n->mask |= SD_BUS_CREDS_TID_COMM;
1025 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1026 n->exe = strdup(c->exe);
1030 n->mask |= SD_BUS_CREDS_EXE;
1033 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1034 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1038 n->cmdline_size = c->cmdline_size;
1039 n->mask |= SD_BUS_CREDS_CMDLINE;
1042 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)) {
1043 n->cgroup = strdup(c->cgroup);
1047 n->cgroup_root = strdup(c->cgroup_root);
1048 if (!n->cgroup_root)
1051 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);
1054 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1055 n->capability = memdup(c->capability, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4);
1059 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);
1062 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1063 n->label = strdup(c->label);
1066 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1069 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1070 n->audit_session_id = c->audit_session_id;
1071 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1073 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1074 n->audit_login_uid = c->audit_login_uid;
1075 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1078 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1079 n->unique_name = strdup(c->unique_name);
1080 if (!n->unique_name)
1082 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1085 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1086 n->well_known_names = strv_copy(c->well_known_names);
1087 if (!n->well_known_names)
1089 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1092 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1093 n->description = strdup(c->description);
1094 if (!n->description)
1096 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1101 r = bus_creds_add_more(n, mask,
1102 c->mask & SD_BUS_CREDS_PID ? c->pid : 0,
1103 c->mask & SD_BUS_CREDS_TID ? c->tid : 0);