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/>.
25 #include "capability.h"
26 #include "cgroup-util.h"
29 #include "bus-message.h"
31 #include "time-util.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);
55 free(c->well_known_names); /* note that this is an strv, but
56 * we only free the array, not the
57 * strings the array points to. The
58 * full strv we only free if
59 * c->allocated is set, see
62 strv_free(c->cmdline_array);
65 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
66 assert_return(c, NULL);
74 /* If this is an embedded creds structure, then
75 * forward ref counting to the message */
76 m = container_of(c, sd_bus_message, creds);
77 sd_bus_message_ref(m);
83 _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
100 free(c->unique_name);
101 free(c->cgroup_root);
102 free(c->description);
103 free(c->supplementary_gids);
105 strv_free(c->well_known_names);
106 c->well_known_names = NULL;
115 m = container_of(c, sd_bus_message, creds);
116 sd_bus_message_unref(m);
123 _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
129 sd_bus_creds* bus_creds_new(void) {
132 c = new0(sd_bus_creds, 1);
141 _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
145 assert_return(pid >= 0, -EINVAL);
146 assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
147 assert_return(ret, -EINVAL);
156 r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
158 sd_bus_creds_unref(c);
162 /* Check if the process existed at all, in case we haven't
163 * figured that out already */
164 if (!pid_is_alive(pid)) {
165 sd_bus_creds_unref(c);
173 _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) {
174 assert_return(c, -EINVAL);
175 assert_return(uid, -EINVAL);
177 if (!(c->mask & SD_BUS_CREDS_UID))
184 _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) {
185 assert_return(c, -EINVAL);
186 assert_return(euid, -EINVAL);
188 if (!(c->mask & SD_BUS_CREDS_EUID))
195 _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) {
196 assert_return(c, -EINVAL);
197 assert_return(suid, -EINVAL);
199 if (!(c->mask & SD_BUS_CREDS_SUID))
207 _public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) {
208 assert_return(c, -EINVAL);
209 assert_return(fsuid, -EINVAL);
211 if (!(c->mask & SD_BUS_CREDS_FSUID))
218 _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
219 assert_return(c, -EINVAL);
220 assert_return(gid, -EINVAL);
222 if (!(c->mask & SD_BUS_CREDS_UID))
230 _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) {
231 assert_return(c, -EINVAL);
232 assert_return(egid, -EINVAL);
234 if (!(c->mask & SD_BUS_CREDS_EGID))
241 _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
242 assert_return(c, -EINVAL);
243 assert_return(sgid, -EINVAL);
245 if (!(c->mask & SD_BUS_CREDS_SGID))
252 _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
253 assert_return(c, -EINVAL);
254 assert_return(fsgid, -EINVAL);
256 if (!(c->mask & SD_BUS_CREDS_FSGID))
263 _public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) {
264 assert_return(c, -EINVAL);
265 assert_return(gids, -EINVAL);
267 if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
270 *gids = c->supplementary_gids;
271 return (int) c->n_supplementary_gids;
274 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
275 assert_return(c, -EINVAL);
276 assert_return(pid, -EINVAL);
278 if (!(c->mask & SD_BUS_CREDS_PID))
286 _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) {
287 assert_return(c, -EINVAL);
288 assert_return(tid, -EINVAL);
290 if (!(c->mask & SD_BUS_CREDS_TID))
298 _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
299 assert_return(c, -EINVAL);
301 if (!(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT))
309 _public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) {
310 assert_return(c, -EINVAL);
311 assert_return(ret, -EINVAL);
313 if (!(c->mask & SD_BUS_CREDS_COMM))
321 _public_ int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **ret) {
322 assert_return(c, -EINVAL);
323 assert_return(ret, -EINVAL);
325 if (!(c->mask & SD_BUS_CREDS_TID_COMM))
333 _public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) {
334 assert_return(c, -EINVAL);
335 assert_return(ret, -EINVAL);
337 if (!(c->mask & SD_BUS_CREDS_EXE))
345 _public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) {
346 assert_return(c, -EINVAL);
347 assert_return(ret, -EINVAL);
349 if (!(c->mask & SD_BUS_CREDS_CGROUP))
357 _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {
360 assert_return(c, -EINVAL);
361 assert_return(ret, -EINVAL);
363 if (!(c->mask & SD_BUS_CREDS_UNIT))
371 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
375 r = cg_path_get_unit(shifted, (char**) &c->unit);
384 _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
387 assert_return(c, -EINVAL);
388 assert_return(ret, -EINVAL);
390 if (!(c->mask & SD_BUS_CREDS_USER_UNIT))
398 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
402 r = cg_path_get_user_unit(shifted, (char**) &c->user_unit);
411 _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
414 assert_return(c, -EINVAL);
415 assert_return(ret, -EINVAL);
417 if (!(c->mask & SD_BUS_CREDS_SLICE))
425 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
429 r = cg_path_get_slice(shifted, (char**) &c->slice);
438 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
441 assert_return(c, -EINVAL);
442 assert_return(ret, -EINVAL);
444 if (!(c->mask & SD_BUS_CREDS_SESSION))
452 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
456 r = cg_path_get_session(shifted, (char**) &c->session);
465 _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
469 assert_return(c, -EINVAL);
470 assert_return(uid, -EINVAL);
472 if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
477 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
481 return cg_path_get_owner_uid(shifted, uid);
484 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
485 assert_return(c, -EINVAL);
487 if (!(c->mask & SD_BUS_CREDS_CMDLINE))
490 assert_return(c->cmdline, -ESRCH);
493 if (!c->cmdline_array) {
494 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
495 if (!c->cmdline_array)
499 *cmdline = c->cmdline_array;
503 _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
504 assert_return(c, -EINVAL);
505 assert_return(sessionid, -EINVAL);
507 if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
510 *sessionid = c->audit_session_id;
514 _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
515 assert_return(c, -EINVAL);
516 assert_return(uid, -EINVAL);
518 if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID))
521 *uid = c->audit_login_uid;
525 _public_ int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **unique_name) {
526 assert_return(c, -EINVAL);
527 assert_return(unique_name, -EINVAL);
529 if (!(c->mask & SD_BUS_CREDS_UNIQUE_NAME))
532 *unique_name = c->unique_name;
536 _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) {
537 assert_return(c, -EINVAL);
538 assert_return(well_known_names, -EINVAL);
540 if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
543 /* As a special hack we return the bus driver as well-known
544 * names list when this is requested. */
545 if (c->well_known_names_driver) {
546 static const char* const wkn[] = {
547 "org.freedesktop.DBus",
551 *well_known_names = (char**) wkn;
555 if (c->well_known_names_local) {
556 static const char* const wkn[] = {
557 "org.freedesktop.DBus.Local",
561 *well_known_names = (char**) wkn;
565 *well_known_names = c->well_known_names;
569 _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) {
570 assert_return(c, -EINVAL);
571 assert_return(ret, -EINVAL);
573 if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
576 assert(c->description);
578 if (!c->unescaped_description) {
579 c->unescaped_description = bus_label_unescape(c->description);
580 if (!c->unescaped_description)
584 *ret = c->unescaped_description;
588 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
592 assert(capability >= 0);
593 assert(c->capability);
595 sz = DIV_ROUND_UP(cap_last_cap(), 32U) * 4;
596 if ((unsigned)capability > cap_last_cap())
599 return !!(c->capability[offset * sz + (capability / 8)] & (1 << (capability % 8)));
602 _public_ int sd_bus_creds_has_effective_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_EFFECTIVE_CAPS))
609 return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
612 _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
613 assert_return(c, -EINVAL);
614 assert_return(capability >= 0, -EINVAL);
616 if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS))
619 return has_cap(c, CAP_OFFSET_PERMITTED, capability);
622 _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
623 assert_return(c, -EINVAL);
624 assert_return(capability >= 0, -EINVAL);
626 if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS))
629 return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
632 _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) {
633 assert_return(c, -EINVAL);
634 assert_return(capability >= 0, -EINVAL);
636 if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS))
639 return has_cap(c, CAP_OFFSET_BOUNDING, capability);
642 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
649 max = DIV_ROUND_UP(cap_last_cap(), 32U) * 4;
650 p += strspn(p, WHITESPACE);
660 if (!c->capability) {
661 c->capability = new0(uint8_t, max * 4);
666 for (i = 0; i < sz; i ++) {
669 x = unhexchar(p[i*2]);
670 y = unhexchar(p[i*2+1]);
675 c->capability[offset * max + (sz - i - 1)] = (uint8_t) x << 4 | (uint8_t) y;
681 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
686 assert(c->allocated);
688 if (!(mask & SD_BUS_CREDS_AUGMENT))
691 missing = mask & ~c->mask;
695 /* Try to retrieve PID from creds if it wasn't passed to us */
696 if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
699 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
702 /* Without pid we cannot do much... */
708 c->mask |= SD_BUS_CREDS_PID;
713 c->mask |= SD_BUS_CREDS_TID;
716 if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
717 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
718 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
719 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
720 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
722 _cleanup_fclose_ FILE *f = NULL;
725 p = procfs_file_alloca(pid, "status");
731 else if (errno != EPERM && errno != EACCES)
736 FOREACH_LINE(line, f, return -errno) {
739 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
740 p = startswith(line, "Uid:");
742 unsigned long uid, euid, suid, fsuid;
744 p += strspn(p, WHITESPACE);
745 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
748 c->uid = (uid_t) uid;
749 c->euid = (uid_t) euid;
750 c->suid = (uid_t) suid;
751 c->fsuid = (uid_t) fsuid;
752 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
757 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
758 p = startswith(line, "Gid:");
760 unsigned long gid, egid, sgid, fsgid;
762 p += strspn(p, WHITESPACE);
763 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
766 c->gid = (gid_t) gid;
767 c->egid = (gid_t) egid;
768 c->sgid = (gid_t) sgid;
769 c->fsgid = (gid_t) fsgid;
770 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
775 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
776 p = startswith(line, "Groups:");
778 size_t allocated = 0;
784 p += strspn(p, WHITESPACE);
788 if (sscanf(p, "%lu%n", &g, &n) != 1)
791 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
794 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
798 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
803 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
804 p = startswith(line, "CapEff:");
806 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
810 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
815 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
816 p = startswith(line, "CapPrm:");
818 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
822 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
827 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
828 p = startswith(line, "CapInh:");
830 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
834 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
839 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
840 p = startswith(line, "CapBnd:");
842 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
846 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
854 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
857 p = procfs_file_alloca(pid, "attr/current");
858 r = read_one_line_file(p, &c->label);
860 if (r != -ENOENT && r != -EINVAL && r != -EPERM && r != -EACCES)
863 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
866 if (missing & SD_BUS_CREDS_COMM) {
867 r = get_process_comm(pid, &c->comm);
869 if (r != -EPERM && r != -EACCES)
872 c->mask |= SD_BUS_CREDS_COMM;
875 if (missing & SD_BUS_CREDS_EXE) {
876 r = get_process_exe(pid, &c->exe);
878 if (r != -EPERM && r != -EACCES)
881 c->mask |= SD_BUS_CREDS_EXE;
884 if (missing & SD_BUS_CREDS_CMDLINE) {
887 p = procfs_file_alloca(pid, "cmdline");
888 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
892 if (r != -EPERM && r != -EACCES)
895 if (c->cmdline_size == 0) {
899 c->mask |= SD_BUS_CREDS_CMDLINE;
903 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
904 _cleanup_free_ char *p = NULL;
906 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
909 r = read_one_line_file(p, &c->tid_comm);
913 if (r != -EPERM && r != -EACCES)
916 c->mask |= SD_BUS_CREDS_TID_COMM;
919 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)) {
921 r = cg_pid_get_path(NULL, pid, &c->cgroup);
923 if (r != -EPERM && r != -EACCES)
926 r = cg_get_root_path(&c->cgroup_root);
930 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);
934 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
935 r = audit_session_from_pid(pid, &c->audit_session_id);
937 if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
940 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
943 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
944 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
946 if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
949 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
955 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
956 _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL;
962 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
963 /* There's already all data we need, or augmentation
964 * wasn't turned on. */
966 *ret = sd_bus_creds_ref(c);
974 /* Copy the original data over */
976 if (c->mask & mask & SD_BUS_CREDS_UID) {
978 n->mask |= SD_BUS_CREDS_UID;
981 if (c->mask & mask & SD_BUS_CREDS_EUID) {
983 n->mask |= SD_BUS_CREDS_EUID;
986 if (c->mask & mask & SD_BUS_CREDS_SUID) {
988 n->mask |= SD_BUS_CREDS_SUID;
991 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
993 n->mask |= SD_BUS_CREDS_FSUID;
996 if (c->mask & mask & SD_BUS_CREDS_GID) {
998 n->mask |= SD_BUS_CREDS_GID;
1001 if (c->mask & mask & SD_BUS_CREDS_EGID) {
1003 n->mask |= SD_BUS_CREDS_EGID;
1006 if (c->mask & mask & SD_BUS_CREDS_SGID) {
1008 n->mask |= SD_BUS_CREDS_SGID;
1011 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
1012 n->fsgid = c->fsgid;
1013 n->mask |= SD_BUS_CREDS_FSGID;
1016 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
1017 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
1018 if (!n->supplementary_gids)
1020 n->n_supplementary_gids = c->n_supplementary_gids;
1021 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
1024 if (c->mask & mask & SD_BUS_CREDS_PID) {
1026 n->mask |= SD_BUS_CREDS_PID;
1029 if (c->mask & mask & SD_BUS_CREDS_TID) {
1031 n->mask |= SD_BUS_CREDS_TID;
1034 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1035 n->comm = strdup(c->comm);
1039 n->mask |= SD_BUS_CREDS_COMM;
1042 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1043 n->tid_comm = strdup(c->tid_comm);
1047 n->mask |= SD_BUS_CREDS_TID_COMM;
1050 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1051 n->exe = strdup(c->exe);
1055 n->mask |= SD_BUS_CREDS_EXE;
1058 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1059 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1063 n->cmdline_size = c->cmdline_size;
1064 n->mask |= SD_BUS_CREDS_CMDLINE;
1067 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)) {
1068 n->cgroup = strdup(c->cgroup);
1072 n->cgroup_root = strdup(c->cgroup_root);
1073 if (!n->cgroup_root)
1076 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);
1079 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1080 n->capability = memdup(c->capability, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4);
1084 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);
1087 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1088 n->label = strdup(c->label);
1091 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1094 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1095 n->audit_session_id = c->audit_session_id;
1096 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1098 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1099 n->audit_login_uid = c->audit_login_uid;
1100 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1103 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1104 n->unique_name = strdup(c->unique_name);
1105 if (!n->unique_name)
1107 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1110 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1111 n->well_known_names = strv_copy(c->well_known_names);
1112 if (!n->well_known_names)
1114 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1117 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1118 n->description = strdup(c->description);
1119 if (!n->description)
1121 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1126 r = bus_creds_add_more(n, mask,
1127 c->mask & SD_BUS_CREDS_PID ? c->pid : 0,
1128 c->mask & SD_BUS_CREDS_TID ? c->tid : 0);