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 "cgroup-util.h"
28 #include "bus-message.h"
30 #include "time-util.h"
32 #include "bus-creds.h"
33 #include "bus-label.h"
36 CAP_OFFSET_INHERITABLE = 0,
37 CAP_OFFSET_PERMITTED = 1,
38 CAP_OFFSET_EFFECTIVE = 2,
39 CAP_OFFSET_BOUNDING = 3
42 void bus_creds_done(sd_bus_creds *c) {
45 /* For internal bus cred structures that are allocated by
52 free(c->unescaped_description);
54 free(c->well_known_names); /* note that this is an strv, but
55 * we only free the array, not the
56 * strings the array points to. The
57 * full strv we only free if
58 * c->allocated is set, see
61 strv_free(c->cmdline_array);
64 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
65 assert_return(c, NULL);
73 /* If this is an embedded creds structure, then
74 * forward ref counting to the message */
75 m = container_of(c, sd_bus_message, creds);
76 sd_bus_message_ref(m);
82 _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
100 free(c->cgroup_root);
101 free(c->description);
102 free(c->supplementary_gids);
104 strv_free(c->well_known_names);
105 c->well_known_names = NULL;
114 m = container_of(c, sd_bus_message, creds);
115 sd_bus_message_unref(m);
122 _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
128 sd_bus_creds* bus_creds_new(void) {
131 c = new0(sd_bus_creds, 1);
140 _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
144 assert_return(pid >= 0, -EINVAL);
145 assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
146 assert_return(ret, -EINVAL);
155 r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
157 sd_bus_creds_unref(c);
161 /* Check if the process existed at all, in case we haven't
162 * figured that out already */
163 if (!pid_is_alive(pid)) {
164 sd_bus_creds_unref(c);
172 _public_ int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid) {
173 assert_return(c, -EINVAL);
174 assert_return(uid, -EINVAL);
176 if (!(c->mask & SD_BUS_CREDS_UID))
183 _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) {
184 assert_return(c, -EINVAL);
185 assert_return(euid, -EINVAL);
187 if (!(c->mask & SD_BUS_CREDS_EUID))
194 _public_ int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid) {
195 assert_return(c, -EINVAL);
196 assert_return(suid, -EINVAL);
198 if (!(c->mask & SD_BUS_CREDS_SUID))
206 _public_ int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid) {
207 assert_return(c, -EINVAL);
208 assert_return(fsuid, -EINVAL);
210 if (!(c->mask & SD_BUS_CREDS_FSUID))
217 _public_ int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid) {
218 assert_return(c, -EINVAL);
219 assert_return(gid, -EINVAL);
221 if (!(c->mask & SD_BUS_CREDS_UID))
229 _public_ int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid) {
230 assert_return(c, -EINVAL);
231 assert_return(egid, -EINVAL);
233 if (!(c->mask & SD_BUS_CREDS_EGID))
240 _public_ int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid) {
241 assert_return(c, -EINVAL);
242 assert_return(sgid, -EINVAL);
244 if (!(c->mask & SD_BUS_CREDS_SGID))
251 _public_ int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid) {
252 assert_return(c, -EINVAL);
253 assert_return(fsgid, -EINVAL);
255 if (!(c->mask & SD_BUS_CREDS_FSGID))
262 _public_ int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids) {
263 assert_return(c, -EINVAL);
264 assert_return(gids, -EINVAL);
266 if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
269 *gids = c->supplementary_gids;
270 return (int) c->n_supplementary_gids;
273 _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
274 assert_return(c, -EINVAL);
275 assert_return(pid, -EINVAL);
277 if (!(c->mask & SD_BUS_CREDS_PID))
285 _public_ int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid) {
286 assert_return(c, -EINVAL);
287 assert_return(tid, -EINVAL);
289 if (!(c->mask & SD_BUS_CREDS_TID))
297 _public_ int sd_bus_creds_get_pid_starttime(sd_bus_creds *c, uint64_t *usec) {
298 assert_return(c, -EINVAL);
299 assert_return(usec, -EINVAL);
301 if (!(c->mask & SD_BUS_CREDS_PID_STARTTIME))
304 assert(c->pid_starttime > 0);
305 *usec = c->pid_starttime;
309 _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
310 assert_return(c, -EINVAL);
312 if (!(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT))
320 _public_ int sd_bus_creds_get_comm(sd_bus_creds *c, const char **ret) {
321 assert_return(c, -EINVAL);
322 assert_return(ret, -EINVAL);
324 if (!(c->mask & SD_BUS_CREDS_COMM))
332 _public_ int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **ret) {
333 assert_return(c, -EINVAL);
334 assert_return(ret, -EINVAL);
336 if (!(c->mask & SD_BUS_CREDS_TID_COMM))
344 _public_ int sd_bus_creds_get_exe(sd_bus_creds *c, const char **ret) {
345 assert_return(c, -EINVAL);
346 assert_return(ret, -EINVAL);
348 if (!(c->mask & SD_BUS_CREDS_EXE))
356 _public_ int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **ret) {
357 assert_return(c, -EINVAL);
358 assert_return(ret, -EINVAL);
360 if (!(c->mask & SD_BUS_CREDS_CGROUP))
368 _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {
371 assert_return(c, -EINVAL);
372 assert_return(ret, -EINVAL);
374 if (!(c->mask & SD_BUS_CREDS_UNIT))
382 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
386 r = cg_path_get_unit(shifted, (char**) &c->unit);
395 _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
398 assert_return(c, -EINVAL);
399 assert_return(ret, -EINVAL);
401 if (!(c->mask & SD_BUS_CREDS_USER_UNIT))
409 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
413 r = cg_path_get_user_unit(shifted, (char**) &c->user_unit);
422 _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
425 assert_return(c, -EINVAL);
426 assert_return(ret, -EINVAL);
428 if (!(c->mask & SD_BUS_CREDS_SLICE))
436 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
440 r = cg_path_get_slice(shifted, (char**) &c->slice);
449 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
452 assert_return(c, -EINVAL);
453 assert_return(ret, -EINVAL);
455 if (!(c->mask & SD_BUS_CREDS_SESSION))
463 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
467 r = cg_path_get_session(shifted, (char**) &c->session);
476 _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
480 assert_return(c, -EINVAL);
481 assert_return(uid, -EINVAL);
483 if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
488 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
492 return cg_path_get_owner_uid(shifted, uid);
495 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
496 assert_return(c, -EINVAL);
498 if (!(c->mask & SD_BUS_CREDS_CMDLINE))
501 assert_return(c->cmdline, -ESRCH);
504 if (!c->cmdline_array) {
505 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
506 if (!c->cmdline_array)
510 *cmdline = c->cmdline_array;
514 _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
515 assert_return(c, -EINVAL);
516 assert_return(sessionid, -EINVAL);
518 if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
521 *sessionid = c->audit_session_id;
525 _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
526 assert_return(c, -EINVAL);
527 assert_return(uid, -EINVAL);
529 if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID))
532 *uid = c->audit_login_uid;
536 _public_ int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **unique_name) {
537 assert_return(c, -EINVAL);
538 assert_return(unique_name, -EINVAL);
540 if (!(c->mask & SD_BUS_CREDS_UNIQUE_NAME))
543 *unique_name = c->unique_name;
547 _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) {
548 assert_return(c, -EINVAL);
549 assert_return(well_known_names, -EINVAL);
551 if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
554 /* As a special hack we return the bus driver as well-known
555 * names list when this is requested. */
556 if (c->well_known_names_driver) {
557 static const char* const wkn[] = {
558 "org.freedesktop.DBus",
562 *well_known_names = (char**) wkn;
566 *well_known_names = c->well_known_names;
570 _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) {
571 assert_return(c, -EINVAL);
572 assert_return(ret, -EINVAL);
574 if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
577 assert(c->description);
579 if (!c->unescaped_description) {
580 c->unescaped_description = bus_label_unescape(c->description);
581 if (!c->unescaped_description)
585 *ret = c->unescaped_description;
589 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
593 assert(c->capability);
595 sz = c->capability_size / 4;
596 if ((size_t) capability >= sz*8)
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 p += strspn(p, WHITESPACE);
656 if (!c->capability) {
657 c->capability = new0(uint8_t, sz * 4);
661 c->capability_size = sz * 4;
664 for (i = 0; i < sz; i ++) {
667 x = unhexchar(p[i*2]);
668 y = unhexchar(p[i*2+1]);
673 c->capability[offset * sz + (sz - i - 1)] = (uint8_t) x << 4 | (uint8_t) y;
679 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
684 assert(c->allocated);
686 if (!(mask & SD_BUS_CREDS_AUGMENT))
689 missing = mask & ~c->mask;
693 /* Try to retrieve PID from creds if it wasn't passed to us */
694 if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
697 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
700 /* Without pid we cannot do much... */
706 c->mask |= SD_BUS_CREDS_PID;
711 c->mask |= SD_BUS_CREDS_TID;
714 if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
715 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
716 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
717 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
718 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
720 _cleanup_fclose_ FILE *f = NULL;
723 p = procfs_file_alloca(pid, "status");
729 else if (errno != EPERM && errno != EACCES)
734 FOREACH_LINE(line, f, return -errno) {
737 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
738 p = startswith(line, "Uid:");
740 unsigned long uid, euid, suid, fsuid;
742 p += strspn(p, WHITESPACE);
743 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
746 c->uid = (uid_t) uid;
747 c->euid = (uid_t) euid;
748 c->suid = (uid_t) suid;
749 c->fsuid = (uid_t) fsuid;
750 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
755 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
756 p = startswith(line, "Gid:");
758 unsigned long gid, egid, sgid, fsgid;
760 p += strspn(p, WHITESPACE);
761 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
764 c->gid = (gid_t) gid;
765 c->egid = (gid_t) egid;
766 c->sgid = (gid_t) sgid;
767 c->fsgid = (gid_t) fsgid;
768 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
773 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
774 p = startswith(line, "Groups:");
776 size_t allocated = 0;
782 p += strspn(p, WHITESPACE);
786 if (sscanf(p, "%lu%n", &g, &n) != 1)
789 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
792 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
796 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
801 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
802 p = startswith(line, "CapEff:");
804 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
808 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
813 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
814 p = startswith(line, "CapPrm:");
816 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
820 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
825 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
826 p = startswith(line, "CapInh:");
828 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
832 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
837 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
838 p = startswith(line, "CapBnd:");
840 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
844 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
852 if (missing & (SD_BUS_CREDS_PID_STARTTIME)) {
853 unsigned long long st;
855 r = get_starttime_of_pid(pid, &st);
857 if (r != -EPERM && r != -EACCES)
860 c->pid_starttime = ((usec_t) st * USEC_PER_SEC) / (usec_t) sysconf(_SC_CLK_TCK);
861 c->mask |= SD_BUS_CREDS_PID_STARTTIME;
865 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
868 p = procfs_file_alloca(pid, "attr/current");
869 r = read_one_line_file(p, &c->label);
871 if (r != -ENOENT && r != -EINVAL && r != -EPERM && r != -EACCES)
874 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
877 if (missing & SD_BUS_CREDS_COMM) {
878 r = get_process_comm(pid, &c->comm);
880 if (r != -EPERM && r != -EACCES)
883 c->mask |= SD_BUS_CREDS_COMM;
886 if (missing & SD_BUS_CREDS_EXE) {
887 r = get_process_exe(pid, &c->exe);
889 if (r != -EPERM && r != -EACCES)
892 c->mask |= SD_BUS_CREDS_EXE;
895 if (missing & SD_BUS_CREDS_CMDLINE) {
898 p = procfs_file_alloca(pid, "cmdline");
899 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
903 if (r != -EPERM && r != -EACCES)
906 if (c->cmdline_size == 0) {
910 c->mask |= SD_BUS_CREDS_CMDLINE;
914 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
915 _cleanup_free_ char *p = NULL;
917 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
920 r = read_one_line_file(p, &c->tid_comm);
924 if (r != -EPERM && r != -EACCES)
927 c->mask |= SD_BUS_CREDS_TID_COMM;
930 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)) {
932 r = cg_pid_get_path(NULL, pid, &c->cgroup);
934 if (r != -EPERM && r != -EACCES)
937 r = cg_get_root_path(&c->cgroup_root);
941 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);
945 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
946 r = audit_session_from_pid(pid, &c->audit_session_id);
948 if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
951 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
954 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
955 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
957 if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
960 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
966 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
967 _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL;
973 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
974 /* There's already all data we need, or augmentation
975 * wasn't turned on. */
977 *ret = sd_bus_creds_ref(c);
985 /* Copy the original data over */
987 if (c->mask & mask & SD_BUS_CREDS_UID) {
989 n->mask |= SD_BUS_CREDS_UID;
992 if (c->mask & mask & SD_BUS_CREDS_EUID) {
994 n->mask |= SD_BUS_CREDS_EUID;
997 if (c->mask & mask & SD_BUS_CREDS_SUID) {
999 n->mask |= SD_BUS_CREDS_SUID;
1002 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
1003 n->fsuid = c->fsuid;
1004 n->mask |= SD_BUS_CREDS_FSUID;
1007 if (c->mask & mask & SD_BUS_CREDS_GID) {
1009 n->mask |= SD_BUS_CREDS_GID;
1012 if (c->mask & mask & SD_BUS_CREDS_EGID) {
1014 n->mask |= SD_BUS_CREDS_EGID;
1017 if (c->mask & mask & SD_BUS_CREDS_SGID) {
1019 n->mask |= SD_BUS_CREDS_SGID;
1022 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
1023 n->fsgid = c->fsgid;
1024 n->mask |= SD_BUS_CREDS_FSGID;
1027 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
1028 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
1029 if (!n->supplementary_gids)
1031 n->n_supplementary_gids = c->n_supplementary_gids;
1032 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
1035 if (c->mask & mask & SD_BUS_CREDS_PID) {
1037 n->mask |= SD_BUS_CREDS_PID;
1040 if (c->mask & mask & SD_BUS_CREDS_TID) {
1042 n->mask |= SD_BUS_CREDS_TID;
1045 if (c->mask & mask & SD_BUS_CREDS_PID_STARTTIME) {
1046 n->pid_starttime = c->pid_starttime;
1047 n->mask |= SD_BUS_CREDS_PID_STARTTIME;
1050 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1051 n->comm = strdup(c->comm);
1055 n->mask |= SD_BUS_CREDS_COMM;
1058 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1059 n->tid_comm = strdup(c->tid_comm);
1063 n->mask |= SD_BUS_CREDS_TID_COMM;
1066 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1067 n->exe = strdup(c->exe);
1071 n->mask |= SD_BUS_CREDS_EXE;
1074 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1075 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1079 n->cmdline_size = c->cmdline_size;
1080 n->mask |= SD_BUS_CREDS_CMDLINE;
1083 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)) {
1084 n->cgroup = strdup(c->cgroup);
1088 n->cgroup_root = strdup(c->cgroup_root);
1089 if (!n->cgroup_root)
1092 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);
1095 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1096 n->capability = memdup(c->capability, c->capability_size);
1100 n->capability_size = c->capability_size;
1101 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);
1104 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1105 n->label = strdup(c->label);
1108 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1111 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1112 n->audit_session_id = c->audit_session_id;
1113 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1115 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1116 n->audit_login_uid = c->audit_login_uid;
1117 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1120 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1121 n->unique_name = strdup(c->unique_name);
1122 if (!n->unique_name)
1124 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1127 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1128 n->well_known_names = strv_copy(c->well_known_names);
1129 if (!n->well_known_names)
1131 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1134 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1135 n->description = strdup(c->description);
1136 if (!n->description)
1138 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1143 r = bus_creds_add_more(n, mask,
1144 c->mask & SD_BUS_CREDS_PID ? c->pid : 0,
1145 c->mask & SD_BUS_CREDS_TID ? c->tid : 0);