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 *well_known_names = c->well_known_names;
558 _public_ int sd_bus_creds_get_description(sd_bus_creds *c, const char **ret) {
559 assert_return(c, -EINVAL);
560 assert_return(ret, -EINVAL);
562 if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
565 assert(c->description);
567 if (!c->unescaped_description) {
568 c->unescaped_description = bus_label_unescape(c->description);
569 if (!c->unescaped_description)
573 *ret = c->unescaped_description;
577 static int has_cap(sd_bus_creds *c, unsigned offset, int capability) {
581 assert(c->capability);
583 sz = c->capability_size / 4;
584 if ((size_t) capability >= sz*8)
587 return !!(c->capability[offset * sz + (capability / 8)] & (1 << (capability % 8)));
590 _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
591 assert_return(c, -EINVAL);
592 assert_return(capability >= 0, -EINVAL);
594 if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS))
597 return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
600 _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
601 assert_return(c, -EINVAL);
602 assert_return(capability >= 0, -EINVAL);
604 if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS))
607 return has_cap(c, CAP_OFFSET_PERMITTED, capability);
610 _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
611 assert_return(c, -EINVAL);
612 assert_return(capability >= 0, -EINVAL);
614 if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS))
617 return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
620 _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) {
621 assert_return(c, -EINVAL);
622 assert_return(capability >= 0, -EINVAL);
624 if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS))
627 return has_cap(c, CAP_OFFSET_BOUNDING, capability);
630 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
637 p += strspn(p, WHITESPACE);
644 if (!c->capability) {
645 c->capability = new0(uint8_t, sz * 4);
649 c->capability_size = sz * 4;
652 for (i = 0; i < sz; i ++) {
655 x = unhexchar(p[i*2]);
656 y = unhexchar(p[i*2+1]);
661 c->capability[offset * sz + (sz - i - 1)] = (uint8_t) x << 4 | (uint8_t) y;
667 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
672 assert(c->allocated);
674 if (!(mask & SD_BUS_CREDS_AUGMENT))
677 missing = mask & ~c->mask;
681 /* Try to retrieve PID from creds if it wasn't passed to us */
682 if (pid <= 0 && (c->mask & SD_BUS_CREDS_PID))
685 if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
688 /* Without pid we cannot do much... */
694 c->mask |= SD_BUS_CREDS_PID;
699 c->mask |= SD_BUS_CREDS_TID;
702 if (missing & (SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
703 SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
704 SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
705 SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
706 SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
708 _cleanup_fclose_ FILE *f = NULL;
711 p = procfs_file_alloca(pid, "status");
717 else if (errno != EPERM && errno != EACCES)
722 FOREACH_LINE(line, f, return -errno) {
725 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
726 p = startswith(line, "Uid:");
728 unsigned long uid, euid, suid, fsuid;
730 p += strspn(p, WHITESPACE);
731 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
734 c->uid = (uid_t) uid;
735 c->euid = (uid_t) euid;
736 c->suid = (uid_t) suid;
737 c->fsuid = (uid_t) fsuid;
738 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
743 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
744 p = startswith(line, "Gid:");
746 unsigned long gid, egid, sgid, fsgid;
748 p += strspn(p, WHITESPACE);
749 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
752 c->gid = (gid_t) gid;
753 c->egid = (gid_t) egid;
754 c->sgid = (gid_t) sgid;
755 c->fsgid = (gid_t) fsgid;
756 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
761 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
762 p = startswith(line, "Groups:");
764 size_t allocated = 0;
770 p += strspn(p, WHITESPACE);
774 if (sscanf(p, "%lu%n", &g, &n) != 1)
777 if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
780 c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
784 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
789 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
790 p = startswith(line, "CapEff:");
792 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
796 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
801 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
802 p = startswith(line, "CapPrm:");
804 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
808 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
813 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
814 p = startswith(line, "CapInh:");
816 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
820 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
825 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
826 p = startswith(line, "CapBnd:");
828 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
832 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
840 if (missing & (SD_BUS_CREDS_PID_STARTTIME)) {
841 unsigned long long st;
843 r = get_starttime_of_pid(pid, &st);
845 if (r != -EPERM && r != -EACCES)
848 c->pid_starttime = ((usec_t) st * USEC_PER_SEC) / (usec_t) sysconf(_SC_CLK_TCK);
849 c->mask |= SD_BUS_CREDS_PID_STARTTIME;
853 if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
856 p = procfs_file_alloca(pid, "attr/current");
857 r = read_one_line_file(p, &c->label);
859 if (r != -ENOENT && r != -EINVAL && r != -EPERM && r != -EACCES)
862 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
865 if (missing & SD_BUS_CREDS_COMM) {
866 r = get_process_comm(pid, &c->comm);
868 if (r != -EPERM && r != -EACCES)
871 c->mask |= SD_BUS_CREDS_COMM;
874 if (missing & SD_BUS_CREDS_EXE) {
875 r = get_process_exe(pid, &c->exe);
877 if (r != -EPERM && r != -EACCES)
880 c->mask |= SD_BUS_CREDS_EXE;
883 if (missing & SD_BUS_CREDS_CMDLINE) {
886 p = procfs_file_alloca(pid, "cmdline");
887 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
891 if (r != -EPERM && r != -EACCES)
894 if (c->cmdline_size == 0) {
898 c->mask |= SD_BUS_CREDS_CMDLINE;
902 if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
903 _cleanup_free_ char *p = NULL;
905 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
908 r = read_one_line_file(p, &c->tid_comm);
912 if (r != -EPERM && r != -EACCES)
915 c->mask |= SD_BUS_CREDS_TID_COMM;
918 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)) {
920 r = cg_pid_get_path(NULL, pid, &c->cgroup);
922 if (r != -EPERM && r != -EACCES)
925 r = cg_get_root_path(&c->cgroup_root);
929 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);
933 if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
934 r = audit_session_from_pid(pid, &c->audit_session_id);
936 if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
939 c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
942 if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
943 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
945 if (r != -ENOTSUP && r != -ENXIO && r != -ENOENT && r != -EPERM && r != -EACCES)
948 c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
954 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
955 _cleanup_bus_creds_unref_ sd_bus_creds *n = NULL;
961 if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
962 /* There's already all data we need, or augmentation
963 * wasn't turned on. */
965 *ret = sd_bus_creds_ref(c);
973 /* Copy the original data over */
975 if (c->mask & mask & SD_BUS_CREDS_UID) {
977 n->mask |= SD_BUS_CREDS_UID;
980 if (c->mask & mask & SD_BUS_CREDS_EUID) {
982 n->mask |= SD_BUS_CREDS_EUID;
985 if (c->mask & mask & SD_BUS_CREDS_SUID) {
987 n->mask |= SD_BUS_CREDS_SUID;
990 if (c->mask & mask & SD_BUS_CREDS_FSUID) {
992 n->mask |= SD_BUS_CREDS_FSUID;
995 if (c->mask & mask & SD_BUS_CREDS_GID) {
997 n->mask |= SD_BUS_CREDS_GID;
1000 if (c->mask & mask & SD_BUS_CREDS_EGID) {
1002 n->mask |= SD_BUS_CREDS_EGID;
1005 if (c->mask & mask & SD_BUS_CREDS_SGID) {
1007 n->mask |= SD_BUS_CREDS_SGID;
1010 if (c->mask & mask & SD_BUS_CREDS_FSGID) {
1011 n->fsgid = c->fsgid;
1012 n->mask |= SD_BUS_CREDS_FSGID;
1015 if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
1016 n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
1017 if (!n->supplementary_gids)
1019 n->n_supplementary_gids = c->n_supplementary_gids;
1020 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
1023 if (c->mask & mask & SD_BUS_CREDS_PID) {
1025 n->mask |= SD_BUS_CREDS_PID;
1028 if (c->mask & mask & SD_BUS_CREDS_TID) {
1030 n->mask |= SD_BUS_CREDS_TID;
1033 if (c->mask & mask & SD_BUS_CREDS_PID_STARTTIME) {
1034 n->pid_starttime = c->pid_starttime;
1035 n->mask |= SD_BUS_CREDS_PID_STARTTIME;
1038 if (c->mask & mask & SD_BUS_CREDS_COMM) {
1039 n->comm = strdup(c->comm);
1043 n->mask |= SD_BUS_CREDS_COMM;
1046 if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1047 n->tid_comm = strdup(c->tid_comm);
1051 n->mask |= SD_BUS_CREDS_TID_COMM;
1054 if (c->mask & mask & SD_BUS_CREDS_EXE) {
1055 n->exe = strdup(c->exe);
1059 n->mask |= SD_BUS_CREDS_EXE;
1062 if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1063 n->cmdline = memdup(c->cmdline, c->cmdline_size);
1067 n->cmdline_size = c->cmdline_size;
1068 n->mask |= SD_BUS_CREDS_CMDLINE;
1071 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)) {
1072 n->cgroup = strdup(c->cgroup);
1076 n->cgroup_root = strdup(c->cgroup_root);
1077 if (!n->cgroup_root)
1080 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);
1083 if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1084 n->capability = memdup(c->capability, c->capability_size);
1088 n->capability_size = c->capability_size;
1089 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);
1092 if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1093 n->label = strdup(c->label);
1096 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1099 if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1100 n->audit_session_id = c->audit_session_id;
1101 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1103 if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1104 n->audit_login_uid = c->audit_login_uid;
1105 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1108 if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1109 n->unique_name = strdup(c->unique_name);
1110 if (!n->unique_name)
1112 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1115 if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1116 n->well_known_names = strv_copy(c->well_known_names);
1117 if (!n->well_known_names)
1119 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1122 if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1123 n->description = strdup(c->description);
1124 if (!n->description)
1126 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1131 r = bus_creds_add_more(n, mask,
1132 c->mask & SD_BUS_CREDS_PID ? c->pid : 0,
1133 c->mask & SD_BUS_CREDS_TID ? c->tid : 0);