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 "process-util.h"
28 #include "capability.h"
29 #include "cgroup-util.h"
32 #include "bus-message.h"
35 #include "bus-creds.h"
36 #include "bus-label.h"
39 CAP_OFFSET_INHERITABLE = 0,
40 CAP_OFFSET_PERMITTED = 1,
41 CAP_OFFSET_EFFECTIVE = 2,
42 CAP_OFFSET_BOUNDING = 3
45 void bus_creds_done(sd_bus_creds *c) {
48 /* For internal bus cred structures that are allocated by
55 free(c->unescaped_description);
56 free(c->supplementary_gids);
58 free(c->well_known_names); /* note that this is an strv, but
59 * we only free the array, not the
60 * strings the array points to. The
61 * full strv we only free if
62 * c->allocated is set, see
65 strv_free(c->cmdline_array);
68 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
69 assert_return(c, NULL);
77 /* If this is an embedded creds structure, then
78 * forward ref counting to the message */
79 m = container_of(c, sd_bus_message, creds);
80 sd_bus_message_ref(m);
86 _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
103 free(c->unique_name);
104 free(c->cgroup_root);
105 free(c->description);
107 free(c->supplementary_gids);
108 c->supplementary_gids = NULL;
110 strv_free(c->well_known_names);
111 c->well_known_names = NULL;
120 m = container_of(c, sd_bus_message, creds);
121 sd_bus_message_unref(m);
128 _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
134 sd_bus_creds* bus_creds_new(void) {
137 c = new0(sd_bus_creds, 1);
146 _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
150 assert_return(pid >= 0, -EINVAL);
151 assert_return(mask <= _SD_BUS_CREDS_ALL, -EOPNOTSUPP);
152 assert_return(ret, -EINVAL);
161 r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
163 sd_bus_creds_unref(c);
167 /* Check if the process existed at all, in case we haven't
168 * figured that out already */
169 if (!pid_is_alive(pid)) {
170 sd_bus_creds_unref(c);
178 _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) {
179 assert_return(c, -EINVAL);
180 assert_return(uid, -EINVAL);
182 if (!(c->mask & SD_BUS_CREDS_UID))
189 _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) {
190 assert_return(c, -EINVAL);
191 assert_return(euid, -EINVAL);
193 if (!(c->mask & SD_BUS_CREDS_EUID))
200 _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) {
201 assert_return(c, -EINVAL);
202 assert_return(suid, -EINVAL);
204 if (!(c->mask & SD_BUS_CREDS_SUID))
212 _public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) {
213 assert_return(c, -EINVAL);
214 assert_return(fsuid, -EINVAL);
216 if (!(c->mask & SD_BUS_CREDS_FSUID))
223 _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
224 assert_return(c, -EINVAL);
225 assert_return(gid, -EINVAL);
227 if (!(c->mask & SD_BUS_CREDS_GID))
235 _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) {
236 assert_return(c, -EINVAL);
237 assert_return(egid, -EINVAL);
239 if (!(c->mask & SD_BUS_CREDS_EGID))
246 _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
247 assert_return(c, -EINVAL);
248 assert_return(sgid, -EINVAL);
250 if (!(c->mask & SD_BUS_CREDS_SGID))
257 _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
258 assert_return(c, -EINVAL);
259 assert_return(fsgid, -EINVAL);
261 if (!(c->mask & SD_BUS_CREDS_FSGID))
268 _public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) {
269 assert_return(c, -EINVAL);
270 assert_return(gids, -EINVAL);
272 if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
275 *gids = c->supplementary_gids;
276 return (int) c->n_supplementary_gids;
279 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
280 assert_return(c, -EINVAL);
281 assert_return(pid, -EINVAL);
283 if (!(c->mask & SD_BUS_CREDS_PID))
291 _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) {
292 assert_return(c, -EINVAL);
293 assert_return(tid, -EINVAL);
295 if (!(c->mask & SD_BUS_CREDS_TID))
303 _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
304 assert_return(c, -EINVAL);
306 if (!(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT))
314 _public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) {
315 assert_return(c, -EINVAL);
316 assert_return(ret, -EINVAL);
318 if (!(c->mask & SD_BUS_CREDS_COMM))
326 _public_ int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **ret) {
327 assert_return(c, -EINVAL);
328 assert_return(ret, -EINVAL);
330 if (!(c->mask & SD_BUS_CREDS_TID_COMM))
338 _public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) {
339 assert_return(c, -EINVAL);
340 assert_return(ret, -EINVAL);
342 if (!(c->mask & SD_BUS_CREDS_EXE))
350 _public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) {
351 assert_return(c, -EINVAL);
352 assert_return(ret, -EINVAL);
354 if (!(c->mask & SD_BUS_CREDS_CGROUP))
362 _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))
378 _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
379 assert_return(c, -EINVAL);
380 assert_return(ret, -EINVAL);
382 if (!(c->mask & SD_BUS_CREDS_USER_UNIT))
394 _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
395 assert_return(c, -EINVAL);
396 assert_return(ret, -EINVAL);
398 if (!(c->mask & SD_BUS_CREDS_SLICE))
410 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
413 assert_return(c, -EINVAL);
414 assert_return(ret, -EINVAL);
416 if (!(c->mask & SD_BUS_CREDS_SESSION))
424 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
428 r = cg_path_get_session(shifted, (char**) &c->session);
437 _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
441 assert_return(c, -EINVAL);
442 assert_return(uid, -EINVAL);
444 if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
449 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
456 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
457 assert_return(c, -EINVAL);
459 if (!(c->mask & SD_BUS_CREDS_CMDLINE))
462 assert_return(c->cmdline, -ESRCH);
465 if (!c->cmdline_array) {
466 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
467 if (!c->cmdline_array)
471 *cmdline = c->cmdline_array;
475 _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
476 assert_return(c, -EINVAL);
477 assert_return(sessionid, -EINVAL);
479 if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
482 *sessionid = c->audit_session_id;
486 _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
487 assert_return(c, -EINVAL);
488 assert_return(uid, -EINVAL);
490 if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID))
493 *uid = c->audit_login_uid;
497 _public_ int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **unique_name) {
498 assert_return(c, -EINVAL);
499 assert_return(unique_name, -EINVAL);
501 if (!(c->mask & SD_BUS_CREDS_UNIQUE_NAME))
504 *unique_name = c->unique_name;
508 _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) {
509 assert_return(c, -EINVAL);
510 assert_return(well_known_names, -EINVAL);
512 if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
515 /* As a special hack we return the bus driver as well-known
516 * names list when this is requested. */
517 if (c->well_known_names_driver) {
518 static const char* const wkn[] = {
519 "org.freedesktop.DBus",
523 *well_known_names = (char**) wkn;
527 if (c->well_known_names_local) {
528 static const char* const wkn[] = {
529 "org.freedesktop.DBus.Local",
533 *well_known_names = (char**) wkn;
537 *well_known_names = c->well_known_names;
541 _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) {
542 assert_return(c, -EINVAL);
543 assert_return(ret, -EINVAL);
545 if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
548 assert(c->description);
550 if (!c->unescaped_description) {
551 c->unescaped_description = bus_label_unescape(c->description);
552 if (!c->unescaped_description)
556 *ret = c->unescaped_description;
560 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
564 assert(capability >= 0);
565 assert(c->capability);
567 sz = DIV_ROUND_UP(cap_last_cap(), 32U);
568 if ((unsigned)capability > cap_last_cap())
571 return !!(c->capability[offset * sz + CAP_TO_INDEX(capability)] & CAP_TO_MASK(capability));
574 _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
575 assert_return(c, -EINVAL);
576 assert_return(capability >= 0, -EINVAL);
578 if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS))
581 return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
584 _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
585 assert_return(c, -EINVAL);
586 assert_return(capability >= 0, -EINVAL);
588 if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS))
591 return has_cap(c, CAP_OFFSET_PERMITTED, capability);
594 _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
595 assert_return(c, -EINVAL);
596 assert_return(capability >= 0, -EINVAL);
598 if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS))
601 return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
604 _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) {
605 assert_return(c, -EINVAL);
606 assert_return(capability >= 0, -EINVAL);
608 if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS))
611 return has_cap(c, CAP_OFFSET_BOUNDING, capability);
614 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
621 max = DIV_ROUND_UP(cap_last_cap(), 32U);
622 p += strspn(p, WHITESPACE);
632 if (!c->capability) {
633 c->capability = new0(uint32_t, max * 4);
638 for (i = 0; i < sz; i ++) {
641 for (j = 0; j < 8; ++j) {
651 c->capability[offset * max + (sz - i - 1)] = v;
657 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
662 assert(c->allocated);
664 if (!(mask & SD_BUS_CREDS_AUGMENT))
667 missing = mask & ~c->mask;
671 /* Try to retrieve PID from creds if it wasn't passed to us */
672 if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
675 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
678 /* Without pid we cannot do much... */
684 c->mask |= SD_BUS_CREDS_PID;
689 c->mask |= SD_BUS_CREDS_TID;
692 if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
693 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
694 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
695 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
696 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
698 _cleanup_fclose_ FILE *f = NULL;
701 p = procfs_file_alloca(pid, "status");
707 else if (errno != EPERM && errno != EACCES)
712 FOREACH_LINE(line, f, return -errno) {
715 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
716 p = startswith(line, "Uid:");
718 unsigned long uid, euid, suid, fsuid;
720 p += strspn(p, WHITESPACE);
721 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
724 c->uid = (uid_t) uid;
725 c->euid = (uid_t) euid;
726 c->suid = (uid_t) suid;
727 c->fsuid = (uid_t) fsuid;
728 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
733 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
734 p = startswith(line, "Gid:");
736 unsigned long gid, egid, sgid, fsgid;
738 p += strspn(p, WHITESPACE);
739 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
742 c->gid = (gid_t) gid;
743 c->egid = (gid_t) egid;
744 c->sgid = (gid_t) sgid;
745 c->fsgid = (gid_t) fsgid;
746 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
751 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
752 p = startswith(line, "Groups:");
754 size_t allocated = 0;
760 p += strspn(p, WHITESPACE);
764 if (sscanf(p, "%lu%n", &g, &n) != 1)
767 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
770 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
774 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
779 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
780 p = startswith(line, "CapEff:");
782 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
786 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
791 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
792 p = startswith(line, "CapPrm:");
794 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
798 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
803 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
804 p = startswith(line, "CapInh:");
806 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
810 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
815 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
816 p = startswith(line, "CapBnd:");
818 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
822 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
830 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
833 p = procfs_file_alloca(pid, "attr/current");
834 r = read_one_line_file(p, &c->label);
836 if (r != -ENOENT && r != -EINVAL && r != -EPERM && r != -EACCES)
839 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
842 if (missing & SD_BUS_CREDS_COMM) {
843 r = get_process_comm(pid, &c->comm);
845 if (r != -EPERM && r != -EACCES)
848 c->mask |= SD_BUS_CREDS_COMM;
851 if (missing & SD_BUS_CREDS_EXE) {
852 r = get_process_exe(pid, &c->exe);
854 if (r != -EPERM && r != -EACCES)
857 c->mask |= SD_BUS_CREDS_EXE;
860 if (missing & SD_BUS_CREDS_CMDLINE) {
863 p = procfs_file_alloca(pid, "cmdline");
864 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
868 if (r != -EPERM && r != -EACCES)
871 if (c->cmdline_size == 0) {
875 c->mask |= SD_BUS_CREDS_CMDLINE;
879 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
880 _cleanup_free_ char *p = NULL;
882 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
885 r = read_one_line_file(p, &c->tid_comm);
889 if (r != -EPERM && r != -EACCES)
892 c->mask |= SD_BUS_CREDS_TID_COMM;
895 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)) {
897 r = cg_pid_get_path(NULL, pid, &c->cgroup);
899 if (r != -EPERM && r != -EACCES)
902 r = cg_get_root_path(&c->cgroup_root);
906 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);
910 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
911 r = audit_session_from_pid(pid, &c->audit_session_id);
913 if (r != -EOPNOTSUPP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
916 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
919 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
920 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
922 if (r != -EOPNOTSUPP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
925 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
931 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
932 _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL;
938 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
939 /* There's already all data we need, or augmentation
940 * wasn't turned on. */
942 *ret = sd_bus_creds_ref(c);
950 /* Copy the original data over */
952 if (c->mask & mask & SD_BUS_CREDS_UID) {
954 n->mask |= SD_BUS_CREDS_UID;
957 if (c->mask & mask & SD_BUS_CREDS_EUID) {
959 n->mask |= SD_BUS_CREDS_EUID;
962 if (c->mask & mask & SD_BUS_CREDS_SUID) {
964 n->mask |= SD_BUS_CREDS_SUID;
967 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
969 n->mask |= SD_BUS_CREDS_FSUID;
972 if (c->mask & mask & SD_BUS_CREDS_GID) {
974 n->mask |= SD_BUS_CREDS_GID;
977 if (c->mask & mask & SD_BUS_CREDS_EGID) {
979 n->mask |= SD_BUS_CREDS_EGID;
982 if (c->mask & mask & SD_BUS_CREDS_SGID) {
984 n->mask |= SD_BUS_CREDS_SGID;
987 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
989 n->mask |= SD_BUS_CREDS_FSGID;
992 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
993 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
994 if (!n->supplementary_gids)
996 n->n_supplementary_gids = c->n_supplementary_gids;
997 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
1000 if (c->mask & mask & SD_BUS_CREDS_PID) {
1002 n->mask |= SD_BUS_CREDS_PID;
1005 if (c->mask & mask & SD_BUS_CREDS_TID) {
1007 n->mask |= SD_BUS_CREDS_TID;
1010 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1011 n->comm = strdup(c->comm);
1015 n->mask |= SD_BUS_CREDS_COMM;
1018 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1019 n->tid_comm = strdup(c->tid_comm);
1023 n->mask |= SD_BUS_CREDS_TID_COMM;
1026 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1027 n->exe = strdup(c->exe);
1031 n->mask |= SD_BUS_CREDS_EXE;
1034 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1035 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1039 n->cmdline_size = c->cmdline_size;
1040 n->mask |= SD_BUS_CREDS_CMDLINE;
1043 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)) {
1044 n->cgroup = strdup(c->cgroup);
1048 n->cgroup_root = strdup(c->cgroup_root);
1049 if (!n->cgroup_root)
1052 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);
1055 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1056 n->capability = memdup(c->capability, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4);
1060 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);
1063 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1064 n->label = strdup(c->label);
1067 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1070 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1071 n->audit_session_id = c->audit_session_id;
1072 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1074 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1075 n->audit_login_uid = c->audit_login_uid;
1076 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1079 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1080 n->unique_name = strdup(c->unique_name);
1081 if (!n->unique_name)
1083 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1086 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1087 n->well_known_names = strv_copy(c->well_known_names);
1088 if (!n->well_known_names)
1090 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1093 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1094 n->description = strdup(c->description);
1095 if (!n->description)
1097 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1102 r = bus_creds_add_more(n, mask,
1103 c->mask & SD_BUS_CREDS_PID ? c->pid : 0,
1104 c->mask & SD_BUS_CREDS_TID ? c->tid : 0);