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 _public_
uint64_t sd_bus_creds_get_augmented_mask(const sd_bus_creds
*c
) {
140 sd_bus_creds
* bus_creds_new(void) {
143 c
= new0(sd_bus_creds
, 1);
152 _public_
int sd_bus_creds_new_from_pid(sd_bus_creds
**ret
, pid_t pid
, uint64_t mask
) {
156 assert_return(pid
>= 0, -EINVAL
);
157 assert_return(mask
<= _SD_BUS_CREDS_ALL
, -EOPNOTSUPP
);
158 assert_return(ret
, -EINVAL
);
167 r
= bus_creds_add_more(c
, mask
| SD_BUS_CREDS_AUGMENT
, pid
, 0);
169 sd_bus_creds_unref(c
);
173 /* Check if the process existed at all, in case we haven't
174 * figured that out already */
175 if (!pid_is_alive(pid
)) {
176 sd_bus_creds_unref(c
);
184 _public_
int sd_bus_creds_get_uid(sd_bus_creds
*c
, uid_t
*uid
) {
185 assert_return(c
, -EINVAL
);
186 assert_return(uid
, -EINVAL
);
188 if (!(c
->mask
& SD_BUS_CREDS_UID
))
195 _public_
int sd_bus_creds_get_euid(sd_bus_creds
*c
, uid_t
*euid
) {
196 assert_return(c
, -EINVAL
);
197 assert_return(euid
, -EINVAL
);
199 if (!(c
->mask
& SD_BUS_CREDS_EUID
))
206 _public_
int sd_bus_creds_get_suid(sd_bus_creds
*c
, uid_t
*suid
) {
207 assert_return(c
, -EINVAL
);
208 assert_return(suid
, -EINVAL
);
210 if (!(c
->mask
& SD_BUS_CREDS_SUID
))
218 _public_
int sd_bus_creds_get_fsuid(sd_bus_creds
*c
, uid_t
*fsuid
) {
219 assert_return(c
, -EINVAL
);
220 assert_return(fsuid
, -EINVAL
);
222 if (!(c
->mask
& SD_BUS_CREDS_FSUID
))
229 _public_
int sd_bus_creds_get_gid(sd_bus_creds
*c
, gid_t
*gid
) {
230 assert_return(c
, -EINVAL
);
231 assert_return(gid
, -EINVAL
);
233 if (!(c
->mask
& SD_BUS_CREDS_GID
))
240 _public_
int sd_bus_creds_get_egid(sd_bus_creds
*c
, gid_t
*egid
) {
241 assert_return(c
, -EINVAL
);
242 assert_return(egid
, -EINVAL
);
244 if (!(c
->mask
& SD_BUS_CREDS_EGID
))
251 _public_
int sd_bus_creds_get_sgid(sd_bus_creds
*c
, gid_t
*sgid
) {
252 assert_return(c
, -EINVAL
);
253 assert_return(sgid
, -EINVAL
);
255 if (!(c
->mask
& SD_BUS_CREDS_SGID
))
262 _public_
int sd_bus_creds_get_fsgid(sd_bus_creds
*c
, gid_t
*fsgid
) {
263 assert_return(c
, -EINVAL
);
264 assert_return(fsgid
, -EINVAL
);
266 if (!(c
->mask
& SD_BUS_CREDS_FSGID
))
273 _public_
int sd_bus_creds_get_supplementary_gids(sd_bus_creds
*c
, const gid_t
**gids
) {
274 assert_return(c
, -EINVAL
);
275 assert_return(gids
, -EINVAL
);
277 if (!(c
->mask
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
))
280 *gids
= c
->supplementary_gids
;
281 return (int) c
->n_supplementary_gids
;
284 _public_
int sd_bus_creds_get_pid(sd_bus_creds
*c
, pid_t
*pid
) {
285 assert_return(c
, -EINVAL
);
286 assert_return(pid
, -EINVAL
);
288 if (!(c
->mask
& SD_BUS_CREDS_PID
))
296 _public_
int sd_bus_creds_get_tid(sd_bus_creds
*c
, pid_t
*tid
) {
297 assert_return(c
, -EINVAL
);
298 assert_return(tid
, -EINVAL
);
300 if (!(c
->mask
& SD_BUS_CREDS_TID
))
308 _public_
int sd_bus_creds_get_selinux_context(sd_bus_creds
*c
, const char **ret
) {
309 assert_return(c
, -EINVAL
);
311 if (!(c
->mask
& SD_BUS_CREDS_SELINUX_CONTEXT
))
319 _public_
int sd_bus_creds_get_comm(sd_bus_creds
*c
, const char **ret
) {
320 assert_return(c
, -EINVAL
);
321 assert_return(ret
, -EINVAL
);
323 if (!(c
->mask
& SD_BUS_CREDS_COMM
))
331 _public_
int sd_bus_creds_get_tid_comm(sd_bus_creds
*c
, const char **ret
) {
332 assert_return(c
, -EINVAL
);
333 assert_return(ret
, -EINVAL
);
335 if (!(c
->mask
& SD_BUS_CREDS_TID_COMM
))
343 _public_
int sd_bus_creds_get_exe(sd_bus_creds
*c
, const char **ret
) {
344 assert_return(c
, -EINVAL
);
345 assert_return(ret
, -EINVAL
);
347 if (!(c
->mask
& SD_BUS_CREDS_EXE
))
355 _public_
int sd_bus_creds_get_cgroup(sd_bus_creds
*c
, const char **ret
) {
356 assert_return(c
, -EINVAL
);
357 assert_return(ret
, -EINVAL
);
359 if (!(c
->mask
& SD_BUS_CREDS_CGROUP
))
367 _public_
int sd_bus_creds_get_unit(sd_bus_creds
*c
, const char **ret
) {
370 assert_return(c
, -EINVAL
);
371 assert_return(ret
, -EINVAL
);
373 if (!(c
->mask
& SD_BUS_CREDS_UNIT
))
381 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
385 r
= cg_path_get_unit(shifted
, (char**) &c
->unit
);
394 _public_
int sd_bus_creds_get_user_unit(sd_bus_creds
*c
, const char **ret
) {
397 assert_return(c
, -EINVAL
);
398 assert_return(ret
, -EINVAL
);
400 if (!(c
->mask
& SD_BUS_CREDS_USER_UNIT
))
408 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
412 r
= cg_path_get_user_unit(shifted
, (char**) &c
->user_unit
);
421 _public_
int sd_bus_creds_get_slice(sd_bus_creds
*c
, const char **ret
) {
424 assert_return(c
, -EINVAL
);
425 assert_return(ret
, -EINVAL
);
427 if (!(c
->mask
& SD_BUS_CREDS_SLICE
))
435 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
439 r
= cg_path_get_slice(shifted
, (char**) &c
->slice
);
448 _public_
int sd_bus_creds_get_session(sd_bus_creds
*c
, const char **ret
) {
451 assert_return(c
, -EINVAL
);
452 assert_return(ret
, -EINVAL
);
454 if (!(c
->mask
& SD_BUS_CREDS_SESSION
))
462 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
466 r
= cg_path_get_session(shifted
, (char**) &c
->session
);
475 _public_
int sd_bus_creds_get_owner_uid(sd_bus_creds
*c
, uid_t
*uid
) {
479 assert_return(c
, -EINVAL
);
480 assert_return(uid
, -EINVAL
);
482 if (!(c
->mask
& SD_BUS_CREDS_OWNER_UID
))
487 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
491 return cg_path_get_owner_uid(shifted
, uid
);
494 _public_
int sd_bus_creds_get_cmdline(sd_bus_creds
*c
, char ***cmdline
) {
495 assert_return(c
, -EINVAL
);
497 if (!(c
->mask
& SD_BUS_CREDS_CMDLINE
))
500 assert_return(c
->cmdline
, -ESRCH
);
503 if (!c
->cmdline_array
) {
504 c
->cmdline_array
= strv_parse_nulstr(c
->cmdline
, c
->cmdline_size
);
505 if (!c
->cmdline_array
)
509 *cmdline
= c
->cmdline_array
;
513 _public_
int sd_bus_creds_get_audit_session_id(sd_bus_creds
*c
, uint32_t *sessionid
) {
514 assert_return(c
, -EINVAL
);
515 assert_return(sessionid
, -EINVAL
);
517 if (!(c
->mask
& SD_BUS_CREDS_AUDIT_SESSION_ID
))
520 *sessionid
= c
->audit_session_id
;
524 _public_
int sd_bus_creds_get_audit_login_uid(sd_bus_creds
*c
, uid_t
*uid
) {
525 assert_return(c
, -EINVAL
);
526 assert_return(uid
, -EINVAL
);
528 if (!(c
->mask
& SD_BUS_CREDS_AUDIT_LOGIN_UID
))
531 *uid
= c
->audit_login_uid
;
535 _public_
int sd_bus_creds_get_unique_name(sd_bus_creds
*c
, const char **unique_name
) {
536 assert_return(c
, -EINVAL
);
537 assert_return(unique_name
, -EINVAL
);
539 if (!(c
->mask
& SD_BUS_CREDS_UNIQUE_NAME
))
542 *unique_name
= c
->unique_name
;
546 _public_
int sd_bus_creds_get_well_known_names(sd_bus_creds
*c
, char ***well_known_names
) {
547 assert_return(c
, -EINVAL
);
548 assert_return(well_known_names
, -EINVAL
);
550 if (!(c
->mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
))
553 /* As a special hack we return the bus driver as well-known
554 * names list when this is requested. */
555 if (c
->well_known_names_driver
) {
556 static const char* const wkn
[] = {
557 "org.freedesktop.DBus",
561 *well_known_names
= (char**) wkn
;
565 if (c
->well_known_names_local
) {
566 static const char* const wkn
[] = {
567 "org.freedesktop.DBus.Local",
571 *well_known_names
= (char**) wkn
;
575 *well_known_names
= c
->well_known_names
;
579 _public_
int sd_bus_creds_get_description(sd_bus_creds
*c
, const char **ret
) {
580 assert_return(c
, -EINVAL
);
581 assert_return(ret
, -EINVAL
);
583 if (!(c
->mask
& SD_BUS_CREDS_DESCRIPTION
))
586 assert(c
->description
);
588 if (!c
->unescaped_description
) {
589 c
->unescaped_description
= bus_label_unescape(c
->description
);
590 if (!c
->unescaped_description
)
594 *ret
= c
->unescaped_description
;
598 static int has_cap(sd_bus_creds
*c
, unsigned offset
, int capability
) {
602 assert(capability
>= 0);
603 assert(c
->capability
);
605 if ((unsigned) capability
> cap_last_cap())
608 sz
= DIV_ROUND_UP(cap_last_cap(), 32U);
610 return !!(c
->capability
[offset
* sz
+ CAP_TO_INDEX(capability
)] & CAP_TO_MASK(capability
));
613 _public_
int sd_bus_creds_has_effective_cap(sd_bus_creds
*c
, int capability
) {
614 assert_return(c
, -EINVAL
);
615 assert_return(capability
>= 0, -EINVAL
);
617 if (!(c
->mask
& SD_BUS_CREDS_EFFECTIVE_CAPS
))
620 return has_cap(c
, CAP_OFFSET_EFFECTIVE
, capability
);
623 _public_
int sd_bus_creds_has_permitted_cap(sd_bus_creds
*c
, int capability
) {
624 assert_return(c
, -EINVAL
);
625 assert_return(capability
>= 0, -EINVAL
);
627 if (!(c
->mask
& SD_BUS_CREDS_PERMITTED_CAPS
))
630 return has_cap(c
, CAP_OFFSET_PERMITTED
, capability
);
633 _public_
int sd_bus_creds_has_inheritable_cap(sd_bus_creds
*c
, int capability
) {
634 assert_return(c
, -EINVAL
);
635 assert_return(capability
>= 0, -EINVAL
);
637 if (!(c
->mask
& SD_BUS_CREDS_INHERITABLE_CAPS
))
640 return has_cap(c
, CAP_OFFSET_INHERITABLE
, capability
);
643 _public_
int sd_bus_creds_has_bounding_cap(sd_bus_creds
*c
, int capability
) {
644 assert_return(c
, -EINVAL
);
645 assert_return(capability
>= 0, -EINVAL
);
647 if (!(c
->mask
& SD_BUS_CREDS_BOUNDING_CAPS
))
650 return has_cap(c
, CAP_OFFSET_BOUNDING
, capability
);
653 static int parse_caps(sd_bus_creds
*c
, unsigned offset
, const char *p
) {
660 max
= DIV_ROUND_UP(cap_last_cap(), 32U);
661 p
+= strspn(p
, WHITESPACE
);
671 if (!c
->capability
) {
672 c
->capability
= new0(uint32_t, max
* 4);
677 for (i
= 0; i
< sz
; i
++) {
680 for (j
= 0; j
< 8; ++j
) {
690 c
->capability
[offset
* max
+ (sz
- i
- 1)] = v
;
696 int bus_creds_add_more(sd_bus_creds
*c
, uint64_t mask
, pid_t pid
, pid_t tid
) {
701 assert(c
->allocated
);
703 if (!(mask
& SD_BUS_CREDS_AUGMENT
))
706 /* Try to retrieve PID from creds if it wasn't passed to us */
707 if (pid
<= 0 && (c
->mask
& SD_BUS_CREDS_PID
))
710 /* Without pid we cannot do much... */
714 /* Try to retrieve TID from creds if it wasn't passed to us */
715 if (tid
<= 0 && (c
->mask
& SD_BUS_CREDS_TID
))
718 /* Calculate what we shall and can add */
719 missing
= mask
& ~(c
->mask
|SD_BUS_CREDS_PID
|SD_BUS_CREDS_TID
|SD_BUS_CREDS_UNIQUE_NAME
|SD_BUS_CREDS_WELL_KNOWN_NAMES
|SD_BUS_CREDS_DESCRIPTION
|SD_BUS_CREDS_AUGMENT
);
724 c
->mask
|= SD_BUS_CREDS_PID
;
728 c
->mask
|= SD_BUS_CREDS_TID
;
731 if (missing
& (SD_BUS_CREDS_UID
| SD_BUS_CREDS_EUID
| SD_BUS_CREDS_SUID
| SD_BUS_CREDS_FSUID
|
732 SD_BUS_CREDS_GID
| SD_BUS_CREDS_EGID
| SD_BUS_CREDS_SGID
| SD_BUS_CREDS_FSGID
|
733 SD_BUS_CREDS_SUPPLEMENTARY_GIDS
|
734 SD_BUS_CREDS_EFFECTIVE_CAPS
| SD_BUS_CREDS_INHERITABLE_CAPS
|
735 SD_BUS_CREDS_PERMITTED_CAPS
| SD_BUS_CREDS_BOUNDING_CAPS
)) {
737 _cleanup_fclose_
FILE *f
= NULL
;
740 p
= procfs_file_alloca(pid
, "status");
746 else if (errno
!= EPERM
&& errno
!= EACCES
)
751 FOREACH_LINE(line
, f
, return -errno
) {
754 if (missing
& (SD_BUS_CREDS_UID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_SUID
|SD_BUS_CREDS_FSUID
)) {
755 p
= startswith(line
, "Uid:");
757 unsigned long uid
, euid
, suid
, fsuid
;
759 p
+= strspn(p
, WHITESPACE
);
760 if (sscanf(p
, "%lu %lu %lu %lu", &uid
, &euid
, &suid
, &fsuid
) != 4)
763 if (missing
& SD_BUS_CREDS_UID
)
764 c
->uid
= (uid_t
) uid
;
765 if (missing
& SD_BUS_CREDS_EUID
)
766 c
->euid
= (uid_t
) euid
;
767 if (missing
& SD_BUS_CREDS_SUID
)
768 c
->suid
= (uid_t
) suid
;
769 if (missing
& SD_BUS_CREDS_FSUID
)
770 c
->fsuid
= (uid_t
) fsuid
;
772 c
->mask
|= missing
& (SD_BUS_CREDS_UID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_SUID
|SD_BUS_CREDS_FSUID
);
777 if (missing
& (SD_BUS_CREDS_GID
|SD_BUS_CREDS_EGID
|SD_BUS_CREDS_SGID
|SD_BUS_CREDS_FSGID
)) {
778 p
= startswith(line
, "Gid:");
780 unsigned long gid
, egid
, sgid
, fsgid
;
782 p
+= strspn(p
, WHITESPACE
);
783 if (sscanf(p
, "%lu %lu %lu %lu", &gid
, &egid
, &sgid
, &fsgid
) != 4)
786 if (missing
& SD_BUS_CREDS_GID
)
787 c
->gid
= (gid_t
) gid
;
788 if (missing
& SD_BUS_CREDS_EGID
)
789 c
->egid
= (gid_t
) egid
;
790 if (missing
& SD_BUS_CREDS_SGID
)
791 c
->sgid
= (gid_t
) sgid
;
792 if (missing
& SD_BUS_CREDS_FSGID
)
793 c
->fsgid
= (gid_t
) fsgid
;
795 c
->mask
|= missing
& (SD_BUS_CREDS_GID
|SD_BUS_CREDS_EGID
|SD_BUS_CREDS_SGID
|SD_BUS_CREDS_FSGID
);
800 if (missing
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
) {
801 p
= startswith(line
, "Groups:");
803 size_t allocated
= 0;
809 p
+= strspn(p
, WHITESPACE
);
813 if (sscanf(p
, "%lu%n", &g
, &n
) != 1)
816 if (!GREEDY_REALLOC(c
->supplementary_gids
, allocated
, c
->n_supplementary_gids
+1))
819 c
->supplementary_gids
[c
->n_supplementary_gids
++] = (gid_t
) g
;
823 c
->mask
|= SD_BUS_CREDS_SUPPLEMENTARY_GIDS
;
828 if (missing
& SD_BUS_CREDS_EFFECTIVE_CAPS
) {
829 p
= startswith(line
, "CapEff:");
831 r
= parse_caps(c
, CAP_OFFSET_EFFECTIVE
, p
);
835 c
->mask
|= SD_BUS_CREDS_EFFECTIVE_CAPS
;
840 if (missing
& SD_BUS_CREDS_PERMITTED_CAPS
) {
841 p
= startswith(line
, "CapPrm:");
843 r
= parse_caps(c
, CAP_OFFSET_PERMITTED
, p
);
847 c
->mask
|= SD_BUS_CREDS_PERMITTED_CAPS
;
852 if (missing
& SD_BUS_CREDS_INHERITABLE_CAPS
) {
853 p
= startswith(line
, "CapInh:");
855 r
= parse_caps(c
, CAP_OFFSET_INHERITABLE
, p
);
859 c
->mask
|= SD_BUS_CREDS_INHERITABLE_CAPS
;
864 if (missing
& SD_BUS_CREDS_BOUNDING_CAPS
) {
865 p
= startswith(line
, "CapBnd:");
867 r
= parse_caps(c
, CAP_OFFSET_BOUNDING
, p
);
871 c
->mask
|= SD_BUS_CREDS_BOUNDING_CAPS
;
879 if (missing
& SD_BUS_CREDS_SELINUX_CONTEXT
) {
882 p
= procfs_file_alloca(pid
, "attr/current");
883 r
= read_one_line_file(p
, &c
->label
);
885 if (r
!= -ENOENT
&& r
!= -EINVAL
&& r
!= -EPERM
&& r
!= -EACCES
)
888 c
->mask
|= SD_BUS_CREDS_SELINUX_CONTEXT
;
891 if (missing
& SD_BUS_CREDS_COMM
) {
892 r
= get_process_comm(pid
, &c
->comm
);
894 if (r
!= -EPERM
&& r
!= -EACCES
)
897 c
->mask
|= SD_BUS_CREDS_COMM
;
900 if (missing
& SD_BUS_CREDS_EXE
) {
901 r
= get_process_exe(pid
, &c
->exe
);
903 if (r
!= -EPERM
&& r
!= -EACCES
)
906 c
->mask
|= SD_BUS_CREDS_EXE
;
909 if (missing
& SD_BUS_CREDS_CMDLINE
) {
912 p
= procfs_file_alloca(pid
, "cmdline");
913 r
= read_full_file(p
, &c
->cmdline
, &c
->cmdline_size
);
917 if (r
!= -EPERM
&& r
!= -EACCES
)
920 if (c
->cmdline_size
== 0) {
924 c
->mask
|= SD_BUS_CREDS_CMDLINE
;
928 if (tid
> 0 && (missing
& SD_BUS_CREDS_TID_COMM
)) {
929 _cleanup_free_
char *p
= NULL
;
931 if (asprintf(&p
, "/proc/"PID_FMT
"/task/"PID_FMT
"/comm", pid
, tid
) < 0)
934 r
= read_one_line_file(p
, &c
->tid_comm
);
938 if (r
!= -EPERM
&& r
!= -EACCES
)
941 c
->mask
|= SD_BUS_CREDS_TID_COMM
;
944 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
)) {
947 r
= cg_pid_get_path(NULL
, pid
, &c
->cgroup
);
949 if (r
!= -EPERM
&& r
!= -EACCES
)
954 if (!c
->cgroup_root
) {
955 r
= cg_get_root_path(&c
->cgroup_root
);
961 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
);
964 if (missing
& SD_BUS_CREDS_AUDIT_SESSION_ID
) {
965 r
= audit_session_from_pid(pid
, &c
->audit_session_id
);
967 if (r
!= -EOPNOTSUPP
&& r
!= -ENXIO
&& r
!= -ENOENT
&& r
!= -EPERM
&& r
!= -EACCES
)
970 c
->mask
|= SD_BUS_CREDS_AUDIT_SESSION_ID
;
973 if (missing
& SD_BUS_CREDS_AUDIT_LOGIN_UID
) {
974 r
= audit_loginuid_from_pid(pid
, &c
->audit_login_uid
);
976 if (r
!= -EOPNOTSUPP
&& r
!= -ENXIO
&& r
!= -ENOENT
&& r
!= -EPERM
&& r
!= -EACCES
)
979 c
->mask
|= SD_BUS_CREDS_AUDIT_LOGIN_UID
;
982 c
->augmented
= missing
& c
->mask
;
987 int bus_creds_extend_by_pid(sd_bus_creds
*c
, uint64_t mask
, sd_bus_creds
**ret
) {
988 _cleanup_bus_creds_unref_ sd_bus_creds
*n
= NULL
;
994 if ((mask
& ~c
->mask
) == 0 || (!(mask
& SD_BUS_CREDS_AUGMENT
))) {
995 /* There's already all data we need, or augmentation
996 * wasn't turned on. */
998 *ret
= sd_bus_creds_ref(c
);
1002 n
= bus_creds_new();
1006 /* Copy the original data over */
1008 if (c
->mask
& mask
& SD_BUS_CREDS_PID
) {
1010 n
->mask
|= SD_BUS_CREDS_PID
;
1013 if (c
->mask
& mask
& SD_BUS_CREDS_TID
) {
1015 n
->mask
|= SD_BUS_CREDS_TID
;
1018 if (c
->mask
& mask
& SD_BUS_CREDS_UID
) {
1020 n
->mask
|= SD_BUS_CREDS_UID
;
1023 if (c
->mask
& mask
& SD_BUS_CREDS_EUID
) {
1025 n
->mask
|= SD_BUS_CREDS_EUID
;
1028 if (c
->mask
& mask
& SD_BUS_CREDS_SUID
) {
1030 n
->mask
|= SD_BUS_CREDS_SUID
;
1033 if (c
->mask
& mask
& SD_BUS_CREDS_FSUID
) {
1034 n
->fsuid
= c
->fsuid
;
1035 n
->mask
|= SD_BUS_CREDS_FSUID
;
1038 if (c
->mask
& mask
& SD_BUS_CREDS_GID
) {
1040 n
->mask
|= SD_BUS_CREDS_GID
;
1043 if (c
->mask
& mask
& SD_BUS_CREDS_EGID
) {
1045 n
->mask
|= SD_BUS_CREDS_EGID
;
1048 if (c
->mask
& mask
& SD_BUS_CREDS_SGID
) {
1050 n
->mask
|= SD_BUS_CREDS_SGID
;
1053 if (c
->mask
& mask
& SD_BUS_CREDS_FSGID
) {
1054 n
->fsgid
= c
->fsgid
;
1055 n
->mask
|= SD_BUS_CREDS_FSGID
;
1058 if (c
->mask
& mask
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
) {
1059 n
->supplementary_gids
= newdup(gid_t
, c
->supplementary_gids
, c
->n_supplementary_gids
);
1060 if (!n
->supplementary_gids
)
1062 n
->n_supplementary_gids
= c
->n_supplementary_gids
;
1063 n
->mask
|= SD_BUS_CREDS_SUPPLEMENTARY_GIDS
;
1066 if (c
->mask
& mask
& SD_BUS_CREDS_COMM
) {
1067 n
->comm
= strdup(c
->comm
);
1071 n
->mask
|= SD_BUS_CREDS_COMM
;
1074 if (c
->mask
& mask
& SD_BUS_CREDS_TID_COMM
) {
1075 n
->tid_comm
= strdup(c
->tid_comm
);
1079 n
->mask
|= SD_BUS_CREDS_TID_COMM
;
1082 if (c
->mask
& mask
& SD_BUS_CREDS_EXE
) {
1083 n
->exe
= strdup(c
->exe
);
1087 n
->mask
|= SD_BUS_CREDS_EXE
;
1090 if (c
->mask
& mask
& SD_BUS_CREDS_CMDLINE
) {
1091 n
->cmdline
= memdup(c
->cmdline
, c
->cmdline_size
);
1095 n
->cmdline_size
= c
->cmdline_size
;
1096 n
->mask
|= SD_BUS_CREDS_CMDLINE
;
1099 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
)) {
1100 n
->cgroup
= strdup(c
->cgroup
);
1104 n
->cgroup_root
= strdup(c
->cgroup_root
);
1105 if (!n
->cgroup_root
)
1108 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
);
1111 if (c
->mask
& mask
& (SD_BUS_CREDS_EFFECTIVE_CAPS
|SD_BUS_CREDS_PERMITTED_CAPS
|SD_BUS_CREDS_INHERITABLE_CAPS
|SD_BUS_CREDS_BOUNDING_CAPS
)) {
1112 n
->capability
= memdup(c
->capability
, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4);
1116 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
);
1119 if (c
->mask
& mask
& SD_BUS_CREDS_SELINUX_CONTEXT
) {
1120 n
->label
= strdup(c
->label
);
1123 n
->mask
|= SD_BUS_CREDS_SELINUX_CONTEXT
;
1126 if (c
->mask
& mask
& SD_BUS_CREDS_AUDIT_SESSION_ID
) {
1127 n
->audit_session_id
= c
->audit_session_id
;
1128 n
->mask
|= SD_BUS_CREDS_AUDIT_SESSION_ID
;
1130 if (c
->mask
& mask
& SD_BUS_CREDS_AUDIT_LOGIN_UID
) {
1131 n
->audit_login_uid
= c
->audit_login_uid
;
1132 n
->mask
|= SD_BUS_CREDS_AUDIT_LOGIN_UID
;
1135 if (c
->mask
& mask
& SD_BUS_CREDS_UNIQUE_NAME
) {
1136 n
->unique_name
= strdup(c
->unique_name
);
1137 if (!n
->unique_name
)
1139 n
->mask
|= SD_BUS_CREDS_UNIQUE_NAME
;
1142 if (c
->mask
& mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
) {
1143 n
->well_known_names
= strv_copy(c
->well_known_names
);
1144 if (!n
->well_known_names
)
1146 n
->well_known_names_driver
= c
->well_known_names_driver
;
1147 n
->well_known_names_local
= c
->well_known_names_local
;
1148 n
->mask
|= SD_BUS_CREDS_WELL_KNOWN_NAMES
;
1151 if (c
->mask
& mask
& SD_BUS_CREDS_DESCRIPTION
) {
1152 n
->description
= strdup(c
->description
);
1153 if (!n
->description
)
1155 n
->mask
|= SD_BUS_CREDS_DESCRIPTION
;
1158 n
->augmented
= c
->augmented
& n
->mask
;
1162 r
= bus_creds_add_more(n
, mask
, 0, 0);