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))
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 if ((unsigned) capability > cap_last_cap())
568 sz = DIV_ROUND_UP(cap_last_cap(), 32U);
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_PID) {
953 n->mask |= SD_BUS_CREDS_PID;
956 if (c->mask & mask & SD_BUS_CREDS_TID) {
958 n->mask |= SD_BUS_CREDS_TID;
961 if (c->mask & mask & SD_BUS_CREDS_UID) {
963 n->mask |= SD_BUS_CREDS_UID;
966 if (c->mask & mask & SD_BUS_CREDS_EUID) {
968 n->mask |= SD_BUS_CREDS_EUID;
971 if (c->mask & mask & SD_BUS_CREDS_SUID) {
973 n->mask |= SD_BUS_CREDS_SUID;
976 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
978 n->mask |= SD_BUS_CREDS_FSUID;
981 if (c->mask & mask & SD_BUS_CREDS_GID) {
983 n->mask |= SD_BUS_CREDS_GID;
986 if (c->mask & mask & SD_BUS_CREDS_EGID) {
988 n->mask |= SD_BUS_CREDS_EGID;
991 if (c->mask & mask & SD_BUS_CREDS_SGID) {
993 n->mask |= SD_BUS_CREDS_SGID;
996 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
998 n->mask |= SD_BUS_CREDS_FSGID;
1001 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
1002 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
1003 if (!n->supplementary_gids)
1005 n->n_supplementary_gids = c->n_supplementary_gids;
1006 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
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->well_known_names_driver = c->well_known_names_driver;
1090 n->well_known_names_local = c->well_known_names_local;
1091 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1094 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1095 n->description = strdup(c->description);
1096 if (!n->description)
1098 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1103 r = bus_creds_add_more(n, mask,
1104 c->mask & SD_BUS_CREDS_PID ? c->pid : 0,
1105 c->mask & SD_BUS_CREDS_TID ? c->tid : 0);