1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 #include <linux/capability.h>
7 #include "alloc-util.h"
8 #include "audit-util.h"
10 #include "bus-label.h"
11 #include "bus-message.h"
12 #include "capability-util.h"
13 #include "cgroup-util.h"
14 #include "errno-util.h"
17 #include "format-util.h"
18 #include "hexdecoct.h"
19 #include "nulstr-util.h"
20 #include "parse-util.h"
22 #include "process-util.h"
23 #include "string-util.h"
25 #include "terminal-util.h"
26 #include "user-util.h"
29 CAP_OFFSET_INHERITABLE
= 0,
30 CAP_OFFSET_PERMITTED
= 1,
31 CAP_OFFSET_EFFECTIVE
= 2,
32 CAP_OFFSET_BOUNDING
= 3
35 void bus_creds_done(sd_bus_creds
*c
) {
38 /* For internal bus cred structures that are allocated by
46 free(c
->unescaped_description
);
47 free(c
->supplementary_gids
);
50 free(c
->well_known_names
); /* note that this is an strv, but
51 * we only free the array, not the
52 * strings the array points to. The
53 * full strv we only free if
54 * c->allocated is set, see
57 strv_free(c
->cmdline_array
);
62 _public_ sd_bus_creds
* sd_bus_creds_ref(sd_bus_creds
*c
) {
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
);
103 c
->supplementary_gids
= mfree(c
->supplementary_gids
);
105 c
->well_known_names
= strv_free(c
->well_known_names
);
114 m
= container_of(c
, sd_bus_message
, creds
);
115 sd_bus_message_unref(m
);
121 _public_
uint64_t sd_bus_creds_get_mask(const sd_bus_creds
*c
) {
127 _public_
uint64_t sd_bus_creds_get_augmented_mask(const sd_bus_creds
*c
) {
133 sd_bus_creds
* bus_creds_new(void) {
136 c
= new(sd_bus_creds
, 1);
140 *c
= (sd_bus_creds
) {
143 SD_BUS_CREDS_INIT_FIELDS
,
149 static int bus_creds_new_from_pidref(sd_bus_creds
**ret
, PidRef
*pidref
, uint64_t mask
) {
150 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*c
= NULL
;
153 assert_return(mask
<= _SD_BUS_CREDS_ALL
, -EOPNOTSUPP
);
154 assert_return(ret
, -EINVAL
);
160 r
= bus_creds_add_more(c
, mask
| SD_BUS_CREDS_AUGMENT
, pidref
, 0);
164 r
= pidref_verify(pidref
);
172 _public_
int sd_bus_creds_new_from_pid(sd_bus_creds
**ret
, pid_t pid
, uint64_t mask
) {
173 _cleanup_(pidref_done
) PidRef pidref
= PIDREF_NULL
;
176 assert_return(pid
>= 0, -EINVAL
);
177 assert_return(mask
<= _SD_BUS_CREDS_ALL
, -EOPNOTSUPP
);
178 assert_return(ret
, -EINVAL
);
180 r
= pidref_set_pid(&pidref
, pid
);
184 return bus_creds_new_from_pidref(ret
, &pidref
, mask
);
187 _public_
int sd_bus_creds_new_from_pidfd(sd_bus_creds
**ret
, int pidfd
, uint64_t mask
) {
188 _cleanup_(pidref_done
) PidRef pidref
= PIDREF_NULL
;
191 assert_return(mask
<= _SD_BUS_CREDS_ALL
, -EOPNOTSUPP
);
192 assert_return(ret
, -EINVAL
);
193 assert_return(pidfd
>= 0, -EBADF
);
195 r
= pidref_set_pidfd(&pidref
, pidfd
);
199 return bus_creds_new_from_pidref(ret
, &pidref
, mask
);
202 _public_
int sd_bus_creds_get_uid(sd_bus_creds
*c
, uid_t
*ret
) {
203 assert_return(c
, -EINVAL
);
204 assert_return(ret
, -EINVAL
);
206 if (!(c
->mask
& SD_BUS_CREDS_UID
))
213 _public_
int sd_bus_creds_get_euid(sd_bus_creds
*c
, uid_t
*ret
) {
214 assert_return(c
, -EINVAL
);
215 assert_return(ret
, -EINVAL
);
217 if (!(c
->mask
& SD_BUS_CREDS_EUID
))
224 _public_
int sd_bus_creds_get_suid(sd_bus_creds
*c
, uid_t
*ret
) {
225 assert_return(c
, -EINVAL
);
226 assert_return(ret
, -EINVAL
);
228 if (!(c
->mask
& SD_BUS_CREDS_SUID
))
235 _public_
int sd_bus_creds_get_fsuid(sd_bus_creds
*c
, uid_t
*ret
) {
236 assert_return(c
, -EINVAL
);
237 assert_return(ret
, -EINVAL
);
239 if (!(c
->mask
& SD_BUS_CREDS_FSUID
))
246 _public_
int sd_bus_creds_get_gid(sd_bus_creds
*c
, gid_t
*ret
) {
247 assert_return(c
, -EINVAL
);
248 assert_return(ret
, -EINVAL
);
250 if (!(c
->mask
& SD_BUS_CREDS_GID
))
257 _public_
int sd_bus_creds_get_egid(sd_bus_creds
*c
, gid_t
*ret
) {
258 assert_return(c
, -EINVAL
);
259 assert_return(ret
, -EINVAL
);
261 if (!(c
->mask
& SD_BUS_CREDS_EGID
))
268 _public_
int sd_bus_creds_get_sgid(sd_bus_creds
*c
, gid_t
*ret
) {
269 assert_return(c
, -EINVAL
);
270 assert_return(ret
, -EINVAL
);
272 if (!(c
->mask
& SD_BUS_CREDS_SGID
))
279 _public_
int sd_bus_creds_get_fsgid(sd_bus_creds
*c
, gid_t
*ret
) {
280 assert_return(c
, -EINVAL
);
281 assert_return(ret
, -EINVAL
);
283 if (!(c
->mask
& SD_BUS_CREDS_FSGID
))
290 _public_
int sd_bus_creds_get_supplementary_gids(sd_bus_creds
*c
, const gid_t
**ret
) {
291 assert_return(c
, -EINVAL
);
292 assert_return(ret
, -EINVAL
);
294 if (!(c
->mask
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
))
297 *ret
= c
->supplementary_gids
;
298 return (int) c
->n_supplementary_gids
;
301 _public_
int sd_bus_creds_get_pid(sd_bus_creds
*c
, pid_t
*ret
) {
302 assert_return(c
, -EINVAL
);
303 assert_return(ret
, -EINVAL
);
305 if (!(c
->mask
& SD_BUS_CREDS_PID
))
313 _public_
int sd_bus_creds_get_pidfd_dup(sd_bus_creds
*c
, int *ret
) {
314 _cleanup_close_
int copy
= -EBADF
;
316 assert_return(c
, -EINVAL
);
317 assert_return(ret
, -EINVAL
);
319 if (!(c
->mask
& SD_BUS_CREDS_PIDFD
))
322 copy
= fcntl(c
->pidfd
, F_DUPFD_CLOEXEC
, 3);
326 *ret
= TAKE_FD(copy
);
330 _public_
int sd_bus_creds_get_ppid(sd_bus_creds
*c
, pid_t
*ret
) {
331 assert_return(c
, -EINVAL
);
332 assert_return(ret
, -EINVAL
);
334 if (!(c
->mask
& SD_BUS_CREDS_PPID
))
337 /* PID 1 has no parent process. Let's distinguish the case of
338 * not knowing and not having a parent process by the returned
347 _public_
int sd_bus_creds_get_tid(sd_bus_creds
*c
, pid_t
*ret
) {
348 assert_return(c
, -EINVAL
);
349 assert_return(ret
, -EINVAL
);
351 if (!(c
->mask
& SD_BUS_CREDS_TID
))
359 _public_
int sd_bus_creds_get_selinux_context(sd_bus_creds
*c
, const char **ret
) {
360 assert_return(c
, -EINVAL
);
362 if (!(c
->mask
& SD_BUS_CREDS_SELINUX_CONTEXT
))
370 _public_
int sd_bus_creds_get_comm(sd_bus_creds
*c
, const char **ret
) {
371 assert_return(c
, -EINVAL
);
372 assert_return(ret
, -EINVAL
);
374 if (!(c
->mask
& SD_BUS_CREDS_COMM
))
382 _public_
int sd_bus_creds_get_tid_comm(sd_bus_creds
*c
, const char **ret
) {
383 assert_return(c
, -EINVAL
);
384 assert_return(ret
, -EINVAL
);
386 if (!(c
->mask
& SD_BUS_CREDS_TID_COMM
))
394 _public_
int sd_bus_creds_get_exe(sd_bus_creds
*c
, const char **ret
) {
395 assert_return(c
, -EINVAL
);
396 assert_return(ret
, -EINVAL
);
398 if (!(c
->mask
& SD_BUS_CREDS_EXE
))
408 _public_
int sd_bus_creds_get_cgroup(sd_bus_creds
*c
, const char **ret
) {
409 assert_return(c
, -EINVAL
);
410 assert_return(ret
, -EINVAL
);
412 if (!(c
->mask
& SD_BUS_CREDS_CGROUP
))
420 _public_
int sd_bus_creds_get_unit(sd_bus_creds
*c
, const char **ret
) {
423 assert_return(c
, -EINVAL
);
424 assert_return(ret
, -EINVAL
);
426 if (!(c
->mask
& SD_BUS_CREDS_UNIT
))
434 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
438 r
= cg_path_get_unit(shifted
, (char**) &c
->unit
);
447 _public_
int sd_bus_creds_get_user_unit(sd_bus_creds
*c
, const char **ret
) {
450 assert_return(c
, -EINVAL
);
451 assert_return(ret
, -EINVAL
);
453 if (!(c
->mask
& SD_BUS_CREDS_USER_UNIT
))
461 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
465 r
= cg_path_get_user_unit(shifted
, (char**) &c
->user_unit
);
474 _public_
int sd_bus_creds_get_slice(sd_bus_creds
*c
, const char **ret
) {
477 assert_return(c
, -EINVAL
);
478 assert_return(ret
, -EINVAL
);
480 if (!(c
->mask
& SD_BUS_CREDS_SLICE
))
488 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
492 r
= cg_path_get_slice(shifted
, (char**) &c
->slice
);
501 _public_
int sd_bus_creds_get_user_slice(sd_bus_creds
*c
, const char **ret
) {
504 assert_return(c
, -EINVAL
);
505 assert_return(ret
, -EINVAL
);
507 if (!(c
->mask
& SD_BUS_CREDS_USER_SLICE
))
512 if (!c
->user_slice
) {
515 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
519 r
= cg_path_get_user_slice(shifted
, (char**) &c
->user_slice
);
524 *ret
= c
->user_slice
;
528 _public_
int sd_bus_creds_get_session(sd_bus_creds
*c
, const char **ret
) {
531 assert_return(c
, -EINVAL
);
532 assert_return(ret
, -EINVAL
);
534 if (!(c
->mask
& SD_BUS_CREDS_SESSION
))
542 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
546 r
= cg_path_get_session(shifted
, (char**) &c
->session
);
555 _public_
int sd_bus_creds_get_owner_uid(sd_bus_creds
*c
, uid_t
*ret
) {
559 assert_return(c
, -EINVAL
);
560 assert_return(ret
, -EINVAL
);
562 if (!(c
->mask
& SD_BUS_CREDS_OWNER_UID
))
567 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
571 return cg_path_get_owner_uid(shifted
, ret
);
574 _public_
int sd_bus_creds_get_cmdline(sd_bus_creds
*c
, char ***ret
) {
575 assert_return(c
, -EINVAL
);
576 assert_return(ret
, -EINVAL
);
578 if (!(c
->mask
& SD_BUS_CREDS_CMDLINE
))
584 if (!c
->cmdline_array
) {
585 c
->cmdline_array
= strv_parse_nulstr(c
->cmdline
, c
->cmdline_size
);
586 if (!c
->cmdline_array
)
590 *ret
= c
->cmdline_array
;
594 _public_
int sd_bus_creds_get_audit_session_id(sd_bus_creds
*c
, uint32_t *ret
) {
595 assert_return(c
, -EINVAL
);
596 assert_return(ret
, -EINVAL
);
598 if (!(c
->mask
& SD_BUS_CREDS_AUDIT_SESSION_ID
))
601 if (!audit_session_is_valid(c
->audit_session_id
))
604 *ret
= c
->audit_session_id
;
608 _public_
int sd_bus_creds_get_audit_login_uid(sd_bus_creds
*c
, uid_t
*ret
) {
609 assert_return(c
, -EINVAL
);
610 assert_return(ret
, -EINVAL
);
612 if (!(c
->mask
& SD_BUS_CREDS_AUDIT_LOGIN_UID
))
615 if (!uid_is_valid(c
->audit_login_uid
))
618 *ret
= c
->audit_login_uid
;
622 _public_
int sd_bus_creds_get_tty(sd_bus_creds
*c
, const char **ret
) {
623 assert_return(c
, -EINVAL
);
624 assert_return(ret
, -EINVAL
);
626 if (!(c
->mask
& SD_BUS_CREDS_TTY
))
636 _public_
int sd_bus_creds_get_unique_name(sd_bus_creds
*c
, const char **ret
) {
637 assert_return(c
, -EINVAL
);
638 assert_return(ret
, -EINVAL
);
640 if (!(c
->mask
& SD_BUS_CREDS_UNIQUE_NAME
))
643 *ret
= c
->unique_name
;
647 _public_
int sd_bus_creds_get_well_known_names(sd_bus_creds
*c
, char ***ret
) {
648 assert_return(c
, -EINVAL
);
649 assert_return(ret
, -EINVAL
);
651 if (!(c
->mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
))
654 /* As a special hack we return the bus driver as well-known
655 * names list when this is requested. */
656 if (c
->well_known_names_driver
) {
657 static const char* const wkn
[] = {
658 "org.freedesktop.DBus",
666 if (c
->well_known_names_local
) {
667 static const char* const wkn
[] = {
668 "org.freedesktop.DBus.Local",
676 *ret
= c
->well_known_names
;
680 _public_
int sd_bus_creds_get_description(sd_bus_creds
*c
, const char **ret
) {
681 assert_return(c
, -EINVAL
);
682 assert_return(ret
, -EINVAL
);
684 if (!(c
->mask
& SD_BUS_CREDS_DESCRIPTION
))
687 assert(c
->description
);
689 if (!c
->unescaped_description
) {
690 c
->unescaped_description
= bus_label_unescape(c
->description
);
691 if (!c
->unescaped_description
)
695 *ret
= c
->unescaped_description
;
699 static int has_cap(sd_bus_creds
*c
, size_t offset
, int capability
) {
703 assert(capability
>= 0);
704 assert(c
->capability
);
706 unsigned lc
= cap_last_cap();
708 if ((unsigned) capability
> lc
)
711 /* If the last cap is 63, then there are 64 caps defined, and we need 2 entries à 32-bit hence. *
712 * If the last cap is 64, then there are 65 caps defined, and we need 3 entries à 32-bit hence. */
713 sz
= DIV_ROUND_UP(lc
+1, 32LU);
715 return !!(c
->capability
[offset
* sz
+ CAP_TO_INDEX((uint32_t) capability
)] & CAP_TO_MASK_CORRECTED((uint32_t) capability
));
718 _public_
int sd_bus_creds_has_effective_cap(sd_bus_creds
*c
, int capability
) {
719 assert_return(c
, -EINVAL
);
720 assert_return(capability
>= 0, -EINVAL
);
722 if (!(c
->mask
& SD_BUS_CREDS_EFFECTIVE_CAPS
))
725 return has_cap(c
, CAP_OFFSET_EFFECTIVE
, capability
);
728 _public_
int sd_bus_creds_has_permitted_cap(sd_bus_creds
*c
, int capability
) {
729 assert_return(c
, -EINVAL
);
730 assert_return(capability
>= 0, -EINVAL
);
732 if (!(c
->mask
& SD_BUS_CREDS_PERMITTED_CAPS
))
735 return has_cap(c
, CAP_OFFSET_PERMITTED
, capability
);
738 _public_
int sd_bus_creds_has_inheritable_cap(sd_bus_creds
*c
, int capability
) {
739 assert_return(c
, -EINVAL
);
740 assert_return(capability
>= 0, -EINVAL
);
742 if (!(c
->mask
& SD_BUS_CREDS_INHERITABLE_CAPS
))
745 return has_cap(c
, CAP_OFFSET_INHERITABLE
, capability
);
748 _public_
int sd_bus_creds_has_bounding_cap(sd_bus_creds
*c
, int capability
) {
749 assert_return(c
, -EINVAL
);
750 assert_return(capability
>= 0, -EINVAL
);
752 if (!(c
->mask
& SD_BUS_CREDS_BOUNDING_CAPS
))
755 return has_cap(c
, CAP_OFFSET_BOUNDING
, capability
);
758 static int parse_caps(sd_bus_creds
*c
, unsigned offset
, const char *p
) {
764 max
= DIV_ROUND_UP(cap_last_cap()+1, 32U);
774 if (!c
->capability
) {
775 c
->capability
= new0(uint32_t, max
* 4);
780 for (unsigned i
= 0; i
< sz
; i
++) {
783 for (unsigned j
= 0; j
< 8; j
++) {
793 c
->capability
[offset
* max
+ (sz
- i
- 1)] = v
;
799 int bus_creds_add_more(sd_bus_creds
*c
, uint64_t mask
, PidRef
*pidref
, pid_t tid
) {
800 _cleanup_(pidref_done
) PidRef pidref_buf
= PIDREF_NULL
;
805 assert(c
->allocated
);
807 if (!(mask
& SD_BUS_CREDS_AUGMENT
))
810 /* Try to retrieve PID from creds if it wasn't passed to us */
811 if (pidref_is_set(pidref
)) {
812 if ((c
->mask
& SD_BUS_CREDS_PID
) && c
->pid
!= pidref
->pid
) /* Insist that things match if already set */
815 c
->pid
= pidref
->pid
;
816 c
->mask
|= SD_BUS_CREDS_PID
;
817 } else if (c
->mask
& SD_BUS_CREDS_PIDFD
) {
818 r
= pidref_set_pidfd(&pidref_buf
, c
->pidfd
);
822 pidref
= &pidref_buf
;
824 } else if (c
->mask
& SD_BUS_CREDS_PID
) {
825 r
= pidref_set_pid(&pidref_buf
, c
->pid
);
829 pidref
= &pidref_buf
;
831 /* Without pid we cannot do much... */
834 /* Try to retrieve TID from creds if it wasn't passed to us */
835 if (tid
<= 0 && (c
->mask
& SD_BUS_CREDS_TID
))
838 /* Calculate what we shall and can add */
839 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
);
845 c
->mask
|= SD_BUS_CREDS_TID
;
848 if ((missing
& SD_BUS_CREDS_PIDFD
) && pidref
->fd
>= 0) {
849 c
->pidfd
= fcntl(pidref
->fd
, F_DUPFD_CLOEXEC
, 3);
853 c
->mask
|= SD_BUS_CREDS_PIDFD
;
856 if (missing
& (SD_BUS_CREDS_PPID
|
857 SD_BUS_CREDS_UID
| SD_BUS_CREDS_EUID
| SD_BUS_CREDS_SUID
| SD_BUS_CREDS_FSUID
|
858 SD_BUS_CREDS_GID
| SD_BUS_CREDS_EGID
| SD_BUS_CREDS_SGID
| SD_BUS_CREDS_FSGID
|
859 SD_BUS_CREDS_SUPPLEMENTARY_GIDS
|
860 SD_BUS_CREDS_EFFECTIVE_CAPS
| SD_BUS_CREDS_INHERITABLE_CAPS
|
861 SD_BUS_CREDS_PERMITTED_CAPS
| SD_BUS_CREDS_BOUNDING_CAPS
)) {
863 _cleanup_fclose_
FILE *f
= NULL
;
866 p
= procfs_file_alloca(pidref
->pid
, "status");
872 if (!ERRNO_IS_PRIVILEGE(errno
))
877 _cleanup_free_
char *line
= NULL
;
879 r
= read_line(f
, LONG_LINE_MAX
, &line
);
885 if (missing
& SD_BUS_CREDS_PPID
) {
886 p
= first_word(line
, "PPid:");
888 /* Explicitly check for PPID 0 (which is the case for PID 1) */
889 if (!streq(p
, "0")) {
890 r
= parse_pid(p
, &c
->ppid
);
896 c
->mask
|= SD_BUS_CREDS_PPID
;
901 if (missing
& (SD_BUS_CREDS_UID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_SUID
|SD_BUS_CREDS_FSUID
)) {
902 p
= first_word(line
, "Uid:");
904 unsigned long uid
, euid
, suid
, fsuid
;
906 if (sscanf(p
, "%lu %lu %lu %lu", &uid
, &euid
, &suid
, &fsuid
) != 4)
909 if (missing
& SD_BUS_CREDS_UID
)
910 c
->uid
= (uid_t
) uid
;
911 if (missing
& SD_BUS_CREDS_EUID
)
912 c
->euid
= (uid_t
) euid
;
913 if (missing
& SD_BUS_CREDS_SUID
)
914 c
->suid
= (uid_t
) suid
;
915 if (missing
& SD_BUS_CREDS_FSUID
)
916 c
->fsuid
= (uid_t
) fsuid
;
918 c
->mask
|= missing
& (SD_BUS_CREDS_UID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_SUID
|SD_BUS_CREDS_FSUID
);
923 if (missing
& (SD_BUS_CREDS_GID
|SD_BUS_CREDS_EGID
|SD_BUS_CREDS_SGID
|SD_BUS_CREDS_FSGID
)) {
924 p
= first_word(line
, "Gid:");
926 unsigned long gid
, egid
, sgid
, fsgid
;
928 if (sscanf(p
, "%lu %lu %lu %lu", &gid
, &egid
, &sgid
, &fsgid
) != 4)
931 if (missing
& SD_BUS_CREDS_GID
)
932 c
->gid
= (gid_t
) gid
;
933 if (missing
& SD_BUS_CREDS_EGID
)
934 c
->egid
= (gid_t
) egid
;
935 if (missing
& SD_BUS_CREDS_SGID
)
936 c
->sgid
= (gid_t
) sgid
;
937 if (missing
& SD_BUS_CREDS_FSGID
)
938 c
->fsgid
= (gid_t
) fsgid
;
940 c
->mask
|= missing
& (SD_BUS_CREDS_GID
|SD_BUS_CREDS_EGID
|SD_BUS_CREDS_SGID
|SD_BUS_CREDS_FSGID
);
945 if (missing
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
) {
946 p
= startswith(line
, "Groups:");
952 p
= skip_leading_chars(p
, /* bad = */ NULL
);
956 if (sscanf(p
, "%lu%n", &g
, &n
) != 1)
959 if (!GREEDY_REALLOC(c
->supplementary_gids
, c
->n_supplementary_gids
+1))
962 c
->supplementary_gids
[c
->n_supplementary_gids
++] = (gid_t
) g
;
966 c
->mask
|= SD_BUS_CREDS_SUPPLEMENTARY_GIDS
;
971 if (missing
& SD_BUS_CREDS_EFFECTIVE_CAPS
) {
972 p
= first_word(line
, "CapEff:");
974 r
= parse_caps(c
, CAP_OFFSET_EFFECTIVE
, p
);
978 c
->mask
|= SD_BUS_CREDS_EFFECTIVE_CAPS
;
983 if (missing
& SD_BUS_CREDS_PERMITTED_CAPS
) {
984 p
= first_word(line
, "CapPrm:");
986 r
= parse_caps(c
, CAP_OFFSET_PERMITTED
, p
);
990 c
->mask
|= SD_BUS_CREDS_PERMITTED_CAPS
;
995 if (missing
& SD_BUS_CREDS_INHERITABLE_CAPS
) {
996 p
= first_word(line
, "CapInh:");
998 r
= parse_caps(c
, CAP_OFFSET_INHERITABLE
, p
);
1002 c
->mask
|= SD_BUS_CREDS_INHERITABLE_CAPS
;
1007 if (missing
& SD_BUS_CREDS_BOUNDING_CAPS
) {
1008 p
= first_word(line
, "CapBnd:");
1010 r
= parse_caps(c
, CAP_OFFSET_BOUNDING
, p
);
1014 c
->mask
|= SD_BUS_CREDS_BOUNDING_CAPS
;
1022 if (missing
& SD_BUS_CREDS_SELINUX_CONTEXT
) {
1025 p
= procfs_file_alloca(pidref
->pid
, "attr/current");
1026 r
= read_one_line_file(p
, &c
->label
);
1028 if (!IN_SET(r
, -ENOENT
, -EINVAL
, -EPERM
, -EACCES
))
1031 c
->mask
|= SD_BUS_CREDS_SELINUX_CONTEXT
;
1034 if (missing
& SD_BUS_CREDS_COMM
) {
1035 r
= pid_get_comm(pidref
->pid
, &c
->comm
);
1037 if (!ERRNO_IS_PRIVILEGE(r
))
1040 c
->mask
|= SD_BUS_CREDS_COMM
;
1043 if (missing
& SD_BUS_CREDS_EXE
) {
1044 r
= get_process_exe(pidref
->pid
, &c
->exe
);
1046 /* Unfortunately we cannot really distinguish
1047 * the case here where the process does not
1048 * exist, and /proc/$PID/exe being unreadable
1049 * because $PID is a kernel thread. Hence,
1050 * assume it is a kernel thread, and rely on
1051 * that this case is caught with a later
1054 c
->mask
|= SD_BUS_CREDS_EXE
;
1056 if (!ERRNO_IS_PRIVILEGE(r
))
1059 c
->mask
|= SD_BUS_CREDS_EXE
;
1062 if (missing
& SD_BUS_CREDS_CMDLINE
) {
1065 p
= procfs_file_alloca(pidref
->pid
, "cmdline");
1066 r
= read_full_file(p
, &c
->cmdline
, &c
->cmdline_size
);
1070 if (!ERRNO_IS_PRIVILEGE(r
))
1073 if (c
->cmdline_size
== 0)
1074 c
->cmdline
= mfree(c
->cmdline
);
1076 c
->mask
|= SD_BUS_CREDS_CMDLINE
;
1080 if (tid
> 0 && (missing
& SD_BUS_CREDS_TID_COMM
)) {
1081 _cleanup_free_
char *p
= NULL
;
1083 if (asprintf(&p
, "/proc/"PID_FMT
"/task/"PID_FMT
"/comm", pidref
->pid
, tid
) < 0)
1086 r
= read_one_line_file(p
, &c
->tid_comm
);
1090 if (!ERRNO_IS_PRIVILEGE(r
))
1093 c
->mask
|= SD_BUS_CREDS_TID_COMM
;
1096 if (missing
& (SD_BUS_CREDS_CGROUP
|SD_BUS_CREDS_UNIT
|SD_BUS_CREDS_USER_UNIT
|SD_BUS_CREDS_SLICE
|SD_BUS_CREDS_USER_SLICE
|SD_BUS_CREDS_SESSION
|SD_BUS_CREDS_OWNER_UID
)) {
1099 r
= cg_pid_get_path(NULL
, pidref
->pid
, &c
->cgroup
);
1100 if (r
< 0 && !ERRNO_IS_NEG_PRIVILEGE(r
))
1104 if (!c
->cgroup_root
) {
1105 r
= cg_get_root_path(&c
->cgroup_root
);
1111 c
->mask
|= missing
& (SD_BUS_CREDS_CGROUP
|SD_BUS_CREDS_UNIT
|SD_BUS_CREDS_USER_UNIT
|SD_BUS_CREDS_SLICE
|SD_BUS_CREDS_USER_SLICE
|SD_BUS_CREDS_SESSION
|SD_BUS_CREDS_OWNER_UID
);
1114 if (missing
& SD_BUS_CREDS_AUDIT_SESSION_ID
) {
1115 r
= audit_session_from_pid(pidref
, &c
->audit_session_id
);
1116 if (r
== -ENODATA
) {
1117 /* ENODATA means: no audit session id assigned */
1118 c
->audit_session_id
= AUDIT_SESSION_INVALID
;
1119 c
->mask
|= SD_BUS_CREDS_AUDIT_SESSION_ID
;
1121 if (!IN_SET(r
, -EOPNOTSUPP
, -ENOENT
, -EPERM
, -EACCES
))
1124 c
->mask
|= SD_BUS_CREDS_AUDIT_SESSION_ID
;
1127 if (missing
& SD_BUS_CREDS_AUDIT_LOGIN_UID
) {
1128 r
= audit_loginuid_from_pid(pidref
, &c
->audit_login_uid
);
1129 if (r
== -ENODATA
) {
1130 /* ENODATA means: no audit login uid assigned */
1131 c
->audit_login_uid
= UID_INVALID
;
1132 c
->mask
|= SD_BUS_CREDS_AUDIT_LOGIN_UID
;
1134 if (!IN_SET(r
, -EOPNOTSUPP
, -ENOENT
, -EPERM
, -EACCES
))
1137 c
->mask
|= SD_BUS_CREDS_AUDIT_LOGIN_UID
;
1140 if (missing
& SD_BUS_CREDS_TTY
) {
1141 r
= get_ctty(pidref
->pid
, NULL
, &c
->tty
);
1143 /* ENXIO means: process has no controlling TTY */
1145 c
->mask
|= SD_BUS_CREDS_TTY
;
1147 if (!IN_SET(r
, -EPERM
, -EACCES
, -ENOENT
))
1150 c
->mask
|= SD_BUS_CREDS_TTY
;
1153 r
= pidref_verify(pidref
);
1157 /* Validate tid is still valid, too */
1158 if (tid
> 0 && tid
!= pidref
->pid
&& pid_is_unwaited(tid
) == 0)
1161 c
->augmented
= missing
& c
->mask
;