1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 #include <linux/capability.h>
6 #include "alloc-util.h"
7 #include "audit-util.h"
10 #include "bus-message.h"
12 #include "capability-util.h"
13 #include "cgroup-util.h"
16 #include "format-util.h"
17 #include "hexdecoct.h"
18 #include "parse-util.h"
19 #include "process-util.h"
20 #include "string-util.h"
22 #include "terminal-util.h"
23 #include "user-util.h"
27 CAP_OFFSET_INHERITABLE
= 0,
28 CAP_OFFSET_PERMITTED
= 1,
29 CAP_OFFSET_EFFECTIVE
= 2,
30 CAP_OFFSET_BOUNDING
= 3
33 void bus_creds_done(sd_bus_creds
*c
) {
36 /* For internal bus cred structures that are allocated by
44 free(c
->unescaped_description
);
45 free(c
->supplementary_gids
);
48 free(c
->well_known_names
); /* note that this is an strv, but
49 * we only free the array, not the
50 * strings the array points to. The
51 * full strv we only free if
52 * c->allocated is set, see
55 strv_free(c
->cmdline_array
);
58 _public_ sd_bus_creds
*sd_bus_creds_ref(sd_bus_creds
*c
) {
69 /* If this is an embedded creds structure, then
70 * forward ref counting to the message */
71 m
= container_of(c
, sd_bus_message
, creds
);
72 sd_bus_message_ref(m
);
78 _public_ sd_bus_creds
*sd_bus_creds_unref(sd_bus_creds
*c
) {
99 c
->supplementary_gids
= mfree(c
->supplementary_gids
);
101 c
->well_known_names
= strv_free(c
->well_known_names
);
110 m
= container_of(c
, sd_bus_message
, creds
);
111 sd_bus_message_unref(m
);
117 _public_
uint64_t sd_bus_creds_get_mask(const sd_bus_creds
*c
) {
123 _public_
uint64_t sd_bus_creds_get_augmented_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
, -EOPNOTSUPP
);
147 assert_return(ret
, -EINVAL
);
150 pid
= getpid_cached();
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
))
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_GID
))
228 _public_
int sd_bus_creds_get_egid(sd_bus_creds
*c
, gid_t
*egid
) {
229 assert_return(c
, -EINVAL
);
230 assert_return(egid
, -EINVAL
);
232 if (!(c
->mask
& SD_BUS_CREDS_EGID
))
239 _public_
int sd_bus_creds_get_sgid(sd_bus_creds
*c
, gid_t
*sgid
) {
240 assert_return(c
, -EINVAL
);
241 assert_return(sgid
, -EINVAL
);
243 if (!(c
->mask
& SD_BUS_CREDS_SGID
))
250 _public_
int sd_bus_creds_get_fsgid(sd_bus_creds
*c
, gid_t
*fsgid
) {
251 assert_return(c
, -EINVAL
);
252 assert_return(fsgid
, -EINVAL
);
254 if (!(c
->mask
& SD_BUS_CREDS_FSGID
))
261 _public_
int sd_bus_creds_get_supplementary_gids(sd_bus_creds
*c
, const gid_t
**gids
) {
262 assert_return(c
, -EINVAL
);
263 assert_return(gids
, -EINVAL
);
265 if (!(c
->mask
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
))
268 *gids
= c
->supplementary_gids
;
269 return (int) c
->n_supplementary_gids
;
272 _public_
int sd_bus_creds_get_pid(sd_bus_creds
*c
, pid_t
*pid
) {
273 assert_return(c
, -EINVAL
);
274 assert_return(pid
, -EINVAL
);
276 if (!(c
->mask
& SD_BUS_CREDS_PID
))
284 _public_
int sd_bus_creds_get_ppid(sd_bus_creds
*c
, pid_t
*ppid
) {
285 assert_return(c
, -EINVAL
);
286 assert_return(ppid
, -EINVAL
);
288 if (!(c
->mask
& SD_BUS_CREDS_PPID
))
291 /* PID 1 has no parent process. Let's distinguish the case of
292 * not knowing and not having a parent process by the returned
301 _public_
int sd_bus_creds_get_tid(sd_bus_creds
*c
, pid_t
*tid
) {
302 assert_return(c
, -EINVAL
);
303 assert_return(tid
, -EINVAL
);
305 if (!(c
->mask
& SD_BUS_CREDS_TID
))
313 _public_
int sd_bus_creds_get_selinux_context(sd_bus_creds
*c
, const char **ret
) {
314 assert_return(c
, -EINVAL
);
316 if (!(c
->mask
& SD_BUS_CREDS_SELINUX_CONTEXT
))
324 _public_
int sd_bus_creds_get_comm(sd_bus_creds
*c
, const char **ret
) {
325 assert_return(c
, -EINVAL
);
326 assert_return(ret
, -EINVAL
);
328 if (!(c
->mask
& SD_BUS_CREDS_COMM
))
336 _public_
int sd_bus_creds_get_tid_comm(sd_bus_creds
*c
, const char **ret
) {
337 assert_return(c
, -EINVAL
);
338 assert_return(ret
, -EINVAL
);
340 if (!(c
->mask
& SD_BUS_CREDS_TID_COMM
))
348 _public_
int sd_bus_creds_get_exe(sd_bus_creds
*c
, const char **ret
) {
349 assert_return(c
, -EINVAL
);
350 assert_return(ret
, -EINVAL
);
352 if (!(c
->mask
& SD_BUS_CREDS_EXE
))
362 _public_
int sd_bus_creds_get_cgroup(sd_bus_creds
*c
, const char **ret
) {
363 assert_return(c
, -EINVAL
);
364 assert_return(ret
, -EINVAL
);
366 if (!(c
->mask
& SD_BUS_CREDS_CGROUP
))
374 _public_
int sd_bus_creds_get_unit(sd_bus_creds
*c
, const char **ret
) {
377 assert_return(c
, -EINVAL
);
378 assert_return(ret
, -EINVAL
);
380 if (!(c
->mask
& SD_BUS_CREDS_UNIT
))
388 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
392 r
= cg_path_get_unit(shifted
, (char**) &c
->unit
);
401 _public_
int sd_bus_creds_get_user_unit(sd_bus_creds
*c
, const char **ret
) {
404 assert_return(c
, -EINVAL
);
405 assert_return(ret
, -EINVAL
);
407 if (!(c
->mask
& SD_BUS_CREDS_USER_UNIT
))
415 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
419 r
= cg_path_get_user_unit(shifted
, (char**) &c
->user_unit
);
428 _public_
int sd_bus_creds_get_slice(sd_bus_creds
*c
, const char **ret
) {
431 assert_return(c
, -EINVAL
);
432 assert_return(ret
, -EINVAL
);
434 if (!(c
->mask
& SD_BUS_CREDS_SLICE
))
442 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
446 r
= cg_path_get_slice(shifted
, (char**) &c
->slice
);
455 _public_
int sd_bus_creds_get_user_slice(sd_bus_creds
*c
, const char **ret
) {
458 assert_return(c
, -EINVAL
);
459 assert_return(ret
, -EINVAL
);
461 if (!(c
->mask
& SD_BUS_CREDS_USER_SLICE
))
466 if (!c
->user_slice
) {
469 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
473 r
= cg_path_get_user_slice(shifted
, (char**) &c
->user_slice
);
478 *ret
= c
->user_slice
;
482 _public_
int sd_bus_creds_get_session(sd_bus_creds
*c
, const char **ret
) {
485 assert_return(c
, -EINVAL
);
486 assert_return(ret
, -EINVAL
);
488 if (!(c
->mask
& SD_BUS_CREDS_SESSION
))
496 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
500 r
= cg_path_get_session(shifted
, (char**) &c
->session
);
509 _public_
int sd_bus_creds_get_owner_uid(sd_bus_creds
*c
, uid_t
*uid
) {
513 assert_return(c
, -EINVAL
);
514 assert_return(uid
, -EINVAL
);
516 if (!(c
->mask
& SD_BUS_CREDS_OWNER_UID
))
521 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
525 return cg_path_get_owner_uid(shifted
, uid
);
528 _public_
int sd_bus_creds_get_cmdline(sd_bus_creds
*c
, char ***cmdline
) {
529 assert_return(c
, -EINVAL
);
531 if (!(c
->mask
& SD_BUS_CREDS_CMDLINE
))
537 if (!c
->cmdline_array
) {
538 c
->cmdline_array
= strv_parse_nulstr(c
->cmdline
, c
->cmdline_size
);
539 if (!c
->cmdline_array
)
543 *cmdline
= c
->cmdline_array
;
547 _public_
int sd_bus_creds_get_audit_session_id(sd_bus_creds
*c
, uint32_t *sessionid
) {
548 assert_return(c
, -EINVAL
);
549 assert_return(sessionid
, -EINVAL
);
551 if (!(c
->mask
& SD_BUS_CREDS_AUDIT_SESSION_ID
))
554 if (!audit_session_is_valid(c
->audit_session_id
))
557 *sessionid
= c
->audit_session_id
;
561 _public_
int sd_bus_creds_get_audit_login_uid(sd_bus_creds
*c
, uid_t
*uid
) {
562 assert_return(c
, -EINVAL
);
563 assert_return(uid
, -EINVAL
);
565 if (!(c
->mask
& SD_BUS_CREDS_AUDIT_LOGIN_UID
))
568 if (!uid_is_valid(c
->audit_login_uid
))
571 *uid
= c
->audit_login_uid
;
575 _public_
int sd_bus_creds_get_tty(sd_bus_creds
*c
, const char **ret
) {
576 assert_return(c
, -EINVAL
);
577 assert_return(ret
, -EINVAL
);
579 if (!(c
->mask
& SD_BUS_CREDS_TTY
))
589 _public_
int sd_bus_creds_get_unique_name(sd_bus_creds
*c
, const char **unique_name
) {
590 assert_return(c
, -EINVAL
);
591 assert_return(unique_name
, -EINVAL
);
593 if (!(c
->mask
& SD_BUS_CREDS_UNIQUE_NAME
))
596 *unique_name
= c
->unique_name
;
600 _public_
int sd_bus_creds_get_well_known_names(sd_bus_creds
*c
, char ***well_known_names
) {
601 assert_return(c
, -EINVAL
);
602 assert_return(well_known_names
, -EINVAL
);
604 if (!(c
->mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
))
607 /* As a special hack we return the bus driver as well-known
608 * names list when this is requested. */
609 if (c
->well_known_names_driver
) {
610 static const char* const wkn
[] = {
611 "org.freedesktop.DBus",
615 *well_known_names
= (char**) wkn
;
619 if (c
->well_known_names_local
) {
620 static const char* const wkn
[] = {
621 "org.freedesktop.DBus.Local",
625 *well_known_names
= (char**) wkn
;
629 *well_known_names
= c
->well_known_names
;
633 _public_
int sd_bus_creds_get_description(sd_bus_creds
*c
, const char **ret
) {
634 assert_return(c
, -EINVAL
);
635 assert_return(ret
, -EINVAL
);
637 if (!(c
->mask
& SD_BUS_CREDS_DESCRIPTION
))
640 assert(c
->description
);
642 if (!c
->unescaped_description
) {
643 c
->unescaped_description
= bus_label_unescape(c
->description
);
644 if (!c
->unescaped_description
)
648 *ret
= c
->unescaped_description
;
652 static int has_cap(sd_bus_creds
*c
, size_t offset
, int capability
) {
657 assert(capability
>= 0);
658 assert(c
->capability
);
662 if ((unsigned long) capability
> lc
)
665 /* If the last cap is 63, then there are 64 caps defined, and we need 2 entries á 32bit hence. *
666 * If the last cap is 64, then there are 65 caps defined, and we need 3 entries á 32bit hence. */
667 sz
= DIV_ROUND_UP(lc
+1, 32LU);
669 return !!(c
->capability
[offset
* sz
+ CAP_TO_INDEX((uint32_t) capability
)] & CAP_TO_MASK_CORRECTED((uint32_t) capability
));
672 _public_
int sd_bus_creds_has_effective_cap(sd_bus_creds
*c
, int capability
) {
673 assert_return(c
, -EINVAL
);
674 assert_return(capability
>= 0, -EINVAL
);
676 if (!(c
->mask
& SD_BUS_CREDS_EFFECTIVE_CAPS
))
679 return has_cap(c
, CAP_OFFSET_EFFECTIVE
, capability
);
682 _public_
int sd_bus_creds_has_permitted_cap(sd_bus_creds
*c
, int capability
) {
683 assert_return(c
, -EINVAL
);
684 assert_return(capability
>= 0, -EINVAL
);
686 if (!(c
->mask
& SD_BUS_CREDS_PERMITTED_CAPS
))
689 return has_cap(c
, CAP_OFFSET_PERMITTED
, capability
);
692 _public_
int sd_bus_creds_has_inheritable_cap(sd_bus_creds
*c
, int capability
) {
693 assert_return(c
, -EINVAL
);
694 assert_return(capability
>= 0, -EINVAL
);
696 if (!(c
->mask
& SD_BUS_CREDS_INHERITABLE_CAPS
))
699 return has_cap(c
, CAP_OFFSET_INHERITABLE
, capability
);
702 _public_
int sd_bus_creds_has_bounding_cap(sd_bus_creds
*c
, int capability
) {
703 assert_return(c
, -EINVAL
);
704 assert_return(capability
>= 0, -EINVAL
);
706 if (!(c
->mask
& SD_BUS_CREDS_BOUNDING_CAPS
))
709 return has_cap(c
, CAP_OFFSET_BOUNDING
, capability
);
712 static int parse_caps(sd_bus_creds
*c
, unsigned offset
, const char *p
) {
719 max
= DIV_ROUND_UP(cap_last_cap()+1, 32U);
720 p
+= strspn(p
, WHITESPACE
);
730 if (!c
->capability
) {
731 c
->capability
= new0(uint32_t, max
* 4);
736 for (i
= 0; i
< sz
; i
++) {
739 for (j
= 0; j
< 8; ++j
) {
749 c
->capability
[offset
* max
+ (sz
- i
- 1)] = v
;
755 int bus_creds_add_more(sd_bus_creds
*c
, uint64_t mask
, pid_t pid
, pid_t tid
) {
760 assert(c
->allocated
);
762 if (!(mask
& SD_BUS_CREDS_AUGMENT
))
765 /* Try to retrieve PID from creds if it wasn't passed to us */
768 c
->mask
|= SD_BUS_CREDS_PID
;
769 } else if (c
->mask
& SD_BUS_CREDS_PID
)
772 /* Without pid we cannot do much... */
775 /* Try to retrieve TID from creds if it wasn't passed to us */
776 if (tid
<= 0 && (c
->mask
& SD_BUS_CREDS_TID
))
779 /* Calculate what we shall and can add */
780 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
);
786 c
->mask
|= SD_BUS_CREDS_TID
;
789 if (missing
& (SD_BUS_CREDS_PPID
|
790 SD_BUS_CREDS_UID
| SD_BUS_CREDS_EUID
| SD_BUS_CREDS_SUID
| SD_BUS_CREDS_FSUID
|
791 SD_BUS_CREDS_GID
| SD_BUS_CREDS_EGID
| SD_BUS_CREDS_SGID
| SD_BUS_CREDS_FSGID
|
792 SD_BUS_CREDS_SUPPLEMENTARY_GIDS
|
793 SD_BUS_CREDS_EFFECTIVE_CAPS
| SD_BUS_CREDS_INHERITABLE_CAPS
|
794 SD_BUS_CREDS_PERMITTED_CAPS
| SD_BUS_CREDS_BOUNDING_CAPS
)) {
796 _cleanup_fclose_
FILE *f
= NULL
;
799 p
= procfs_file_alloca(pid
, "status");
805 else if (!IN_SET(errno
, EPERM
, EACCES
))
810 _cleanup_free_
char *line
= NULL
;
812 r
= read_line(f
, LONG_LINE_MAX
, &line
);
818 if (missing
& SD_BUS_CREDS_PPID
) {
819 p
= startswith(line
, "PPid:");
821 p
+= strspn(p
, WHITESPACE
);
823 /* Explicitly check for PPID 0 (which is the case for PID 1) */
824 if (!streq(p
, "0")) {
825 r
= parse_pid(p
, &c
->ppid
);
832 c
->mask
|= SD_BUS_CREDS_PPID
;
837 if (missing
& (SD_BUS_CREDS_UID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_SUID
|SD_BUS_CREDS_FSUID
)) {
838 p
= startswith(line
, "Uid:");
840 unsigned long uid
, euid
, suid
, fsuid
;
842 p
+= strspn(p
, WHITESPACE
);
843 if (sscanf(p
, "%lu %lu %lu %lu", &uid
, &euid
, &suid
, &fsuid
) != 4)
846 if (missing
& SD_BUS_CREDS_UID
)
847 c
->uid
= (uid_t
) uid
;
848 if (missing
& SD_BUS_CREDS_EUID
)
849 c
->euid
= (uid_t
) euid
;
850 if (missing
& SD_BUS_CREDS_SUID
)
851 c
->suid
= (uid_t
) suid
;
852 if (missing
& SD_BUS_CREDS_FSUID
)
853 c
->fsuid
= (uid_t
) fsuid
;
855 c
->mask
|= missing
& (SD_BUS_CREDS_UID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_SUID
|SD_BUS_CREDS_FSUID
);
860 if (missing
& (SD_BUS_CREDS_GID
|SD_BUS_CREDS_EGID
|SD_BUS_CREDS_SGID
|SD_BUS_CREDS_FSGID
)) {
861 p
= startswith(line
, "Gid:");
863 unsigned long gid
, egid
, sgid
, fsgid
;
865 p
+= strspn(p
, WHITESPACE
);
866 if (sscanf(p
, "%lu %lu %lu %lu", &gid
, &egid
, &sgid
, &fsgid
) != 4)
869 if (missing
& SD_BUS_CREDS_GID
)
870 c
->gid
= (gid_t
) gid
;
871 if (missing
& SD_BUS_CREDS_EGID
)
872 c
->egid
= (gid_t
) egid
;
873 if (missing
& SD_BUS_CREDS_SGID
)
874 c
->sgid
= (gid_t
) sgid
;
875 if (missing
& SD_BUS_CREDS_FSGID
)
876 c
->fsgid
= (gid_t
) fsgid
;
878 c
->mask
|= missing
& (SD_BUS_CREDS_GID
|SD_BUS_CREDS_EGID
|SD_BUS_CREDS_SGID
|SD_BUS_CREDS_FSGID
);
883 if (missing
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
) {
884 p
= startswith(line
, "Groups:");
886 size_t allocated
= 0;
892 p
+= strspn(p
, WHITESPACE
);
896 if (sscanf(p
, "%lu%n", &g
, &n
) != 1)
899 if (!GREEDY_REALLOC(c
->supplementary_gids
, allocated
, c
->n_supplementary_gids
+1))
902 c
->supplementary_gids
[c
->n_supplementary_gids
++] = (gid_t
) g
;
906 c
->mask
|= SD_BUS_CREDS_SUPPLEMENTARY_GIDS
;
911 if (missing
& SD_BUS_CREDS_EFFECTIVE_CAPS
) {
912 p
= startswith(line
, "CapEff:");
914 r
= parse_caps(c
, CAP_OFFSET_EFFECTIVE
, p
);
918 c
->mask
|= SD_BUS_CREDS_EFFECTIVE_CAPS
;
923 if (missing
& SD_BUS_CREDS_PERMITTED_CAPS
) {
924 p
= startswith(line
, "CapPrm:");
926 r
= parse_caps(c
, CAP_OFFSET_PERMITTED
, p
);
930 c
->mask
|= SD_BUS_CREDS_PERMITTED_CAPS
;
935 if (missing
& SD_BUS_CREDS_INHERITABLE_CAPS
) {
936 p
= startswith(line
, "CapInh:");
938 r
= parse_caps(c
, CAP_OFFSET_INHERITABLE
, p
);
942 c
->mask
|= SD_BUS_CREDS_INHERITABLE_CAPS
;
947 if (missing
& SD_BUS_CREDS_BOUNDING_CAPS
) {
948 p
= startswith(line
, "CapBnd:");
950 r
= parse_caps(c
, CAP_OFFSET_BOUNDING
, p
);
954 c
->mask
|= SD_BUS_CREDS_BOUNDING_CAPS
;
962 if (missing
& SD_BUS_CREDS_SELINUX_CONTEXT
) {
965 p
= procfs_file_alloca(pid
, "attr/current");
966 r
= read_one_line_file(p
, &c
->label
);
968 if (!IN_SET(r
, -ENOENT
, -EINVAL
, -EPERM
, -EACCES
))
971 c
->mask
|= SD_BUS_CREDS_SELINUX_CONTEXT
;
974 if (missing
& SD_BUS_CREDS_COMM
) {
975 r
= get_process_comm(pid
, &c
->comm
);
977 if (!IN_SET(r
, -EPERM
, -EACCES
))
980 c
->mask
|= SD_BUS_CREDS_COMM
;
983 if (missing
& SD_BUS_CREDS_EXE
) {
984 r
= get_process_exe(pid
, &c
->exe
);
986 /* Unfortunately we cannot really distinguish
987 * the case here where the process does not
988 * exist, and /proc/$PID/exe being unreadable
989 * because $PID is a kernel thread. Hence,
990 * assume it is a kernel thread, and rely on
991 * that this case is caught with a later
994 c
->mask
|= SD_BUS_CREDS_EXE
;
996 if (!IN_SET(r
, -EPERM
, -EACCES
))
999 c
->mask
|= SD_BUS_CREDS_EXE
;
1002 if (missing
& SD_BUS_CREDS_CMDLINE
) {
1005 p
= procfs_file_alloca(pid
, "cmdline");
1006 r
= read_full_file(p
, &c
->cmdline
, &c
->cmdline_size
);
1010 if (!IN_SET(r
, -EPERM
, -EACCES
))
1013 if (c
->cmdline_size
== 0)
1014 c
->cmdline
= mfree(c
->cmdline
);
1016 c
->mask
|= SD_BUS_CREDS_CMDLINE
;
1020 if (tid
> 0 && (missing
& SD_BUS_CREDS_TID_COMM
)) {
1021 _cleanup_free_
char *p
= NULL
;
1023 if (asprintf(&p
, "/proc/"PID_FMT
"/task/"PID_FMT
"/comm", pid
, tid
) < 0)
1026 r
= read_one_line_file(p
, &c
->tid_comm
);
1030 if (!IN_SET(r
, -EPERM
, -EACCES
))
1033 c
->mask
|= SD_BUS_CREDS_TID_COMM
;
1036 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
)) {
1039 r
= cg_pid_get_path(NULL
, pid
, &c
->cgroup
);
1041 if (!IN_SET(r
, -EPERM
, -EACCES
))
1046 if (!c
->cgroup_root
) {
1047 r
= cg_get_root_path(&c
->cgroup_root
);
1053 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
);
1056 if (missing
& SD_BUS_CREDS_AUDIT_SESSION_ID
) {
1057 r
= audit_session_from_pid(pid
, &c
->audit_session_id
);
1058 if (r
== -ENODATA
) {
1059 /* ENODATA means: no audit session id assigned */
1060 c
->audit_session_id
= AUDIT_SESSION_INVALID
;
1061 c
->mask
|= SD_BUS_CREDS_AUDIT_SESSION_ID
;
1063 if (!IN_SET(r
, -EOPNOTSUPP
, -ENOENT
, -EPERM
, -EACCES
))
1066 c
->mask
|= SD_BUS_CREDS_AUDIT_SESSION_ID
;
1069 if (missing
& SD_BUS_CREDS_AUDIT_LOGIN_UID
) {
1070 r
= audit_loginuid_from_pid(pid
, &c
->audit_login_uid
);
1071 if (r
== -ENODATA
) {
1072 /* ENODATA means: no audit login uid assigned */
1073 c
->audit_login_uid
= UID_INVALID
;
1074 c
->mask
|= SD_BUS_CREDS_AUDIT_LOGIN_UID
;
1076 if (!IN_SET(r
, -EOPNOTSUPP
, -ENOENT
, -EPERM
, -EACCES
))
1079 c
->mask
|= SD_BUS_CREDS_AUDIT_LOGIN_UID
;
1082 if (missing
& SD_BUS_CREDS_TTY
) {
1083 r
= get_ctty(pid
, NULL
, &c
->tty
);
1085 /* ENXIO means: process has no controlling TTY */
1087 c
->mask
|= SD_BUS_CREDS_TTY
;
1089 if (!IN_SET(r
, -EPERM
, -EACCES
, -ENOENT
))
1092 c
->mask
|= SD_BUS_CREDS_TTY
;
1095 /* In case only the exe path was to be read we cannot
1096 * distinguish the case where the exe path was unreadable
1097 * because the process was a kernel thread, or when the
1098 * process didn't exist at all. Hence, let's do a final check,
1100 if (!pid_is_alive(pid
))
1103 if (tid
> 0 && tid
!= pid
&& !pid_is_unwaited(tid
))
1106 c
->augmented
= missing
& c
->mask
;
1111 int bus_creds_extend_by_pid(sd_bus_creds
*c
, uint64_t mask
, sd_bus_creds
**ret
) {
1112 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*n
= NULL
;
1118 if ((mask
& ~c
->mask
) == 0 || (!(mask
& SD_BUS_CREDS_AUGMENT
))) {
1119 /* There's already all data we need, or augmentation
1120 * wasn't turned on. */
1122 *ret
= sd_bus_creds_ref(c
);
1126 n
= bus_creds_new();
1130 /* Copy the original data over */
1132 if (c
->mask
& mask
& SD_BUS_CREDS_PID
) {
1134 n
->mask
|= SD_BUS_CREDS_PID
;
1137 if (c
->mask
& mask
& SD_BUS_CREDS_TID
) {
1139 n
->mask
|= SD_BUS_CREDS_TID
;
1142 if (c
->mask
& mask
& SD_BUS_CREDS_PPID
) {
1144 n
->mask
|= SD_BUS_CREDS_PPID
;
1147 if (c
->mask
& mask
& SD_BUS_CREDS_UID
) {
1149 n
->mask
|= SD_BUS_CREDS_UID
;
1152 if (c
->mask
& mask
& SD_BUS_CREDS_EUID
) {
1154 n
->mask
|= SD_BUS_CREDS_EUID
;
1157 if (c
->mask
& mask
& SD_BUS_CREDS_SUID
) {
1159 n
->mask
|= SD_BUS_CREDS_SUID
;
1162 if (c
->mask
& mask
& SD_BUS_CREDS_FSUID
) {
1163 n
->fsuid
= c
->fsuid
;
1164 n
->mask
|= SD_BUS_CREDS_FSUID
;
1167 if (c
->mask
& mask
& SD_BUS_CREDS_GID
) {
1169 n
->mask
|= SD_BUS_CREDS_GID
;
1172 if (c
->mask
& mask
& SD_BUS_CREDS_EGID
) {
1174 n
->mask
|= SD_BUS_CREDS_EGID
;
1177 if (c
->mask
& mask
& SD_BUS_CREDS_SGID
) {
1179 n
->mask
|= SD_BUS_CREDS_SGID
;
1182 if (c
->mask
& mask
& SD_BUS_CREDS_FSGID
) {
1183 n
->fsgid
= c
->fsgid
;
1184 n
->mask
|= SD_BUS_CREDS_FSGID
;
1187 if (c
->mask
& mask
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
) {
1188 if (c
->supplementary_gids
) {
1189 n
->supplementary_gids
= newdup(gid_t
, c
->supplementary_gids
, c
->n_supplementary_gids
);
1190 if (!n
->supplementary_gids
)
1192 n
->n_supplementary_gids
= c
->n_supplementary_gids
;
1194 n
->supplementary_gids
= NULL
;
1195 n
->n_supplementary_gids
= 0;
1198 n
->mask
|= SD_BUS_CREDS_SUPPLEMENTARY_GIDS
;
1201 if (c
->mask
& mask
& SD_BUS_CREDS_COMM
) {
1204 n
->comm
= strdup(c
->comm
);
1208 n
->mask
|= SD_BUS_CREDS_COMM
;
1211 if (c
->mask
& mask
& SD_BUS_CREDS_TID_COMM
) {
1212 assert(c
->tid_comm
);
1214 n
->tid_comm
= strdup(c
->tid_comm
);
1218 n
->mask
|= SD_BUS_CREDS_TID_COMM
;
1221 if (c
->mask
& mask
& SD_BUS_CREDS_EXE
) {
1223 n
->exe
= strdup(c
->exe
);
1229 n
->mask
|= SD_BUS_CREDS_EXE
;
1232 if (c
->mask
& mask
& SD_BUS_CREDS_CMDLINE
) {
1234 n
->cmdline
= memdup(c
->cmdline
, c
->cmdline_size
);
1238 n
->cmdline_size
= c
->cmdline_size
;
1241 n
->cmdline_size
= 0;
1244 n
->mask
|= SD_BUS_CREDS_CMDLINE
;
1247 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_USER_SLICE
|SD_BUS_CREDS_OWNER_UID
)) {
1250 n
->cgroup
= strdup(c
->cgroup
);
1254 n
->cgroup_root
= strdup(c
->cgroup_root
);
1255 if (!n
->cgroup_root
)
1258 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_USER_SLICE
|SD_BUS_CREDS_OWNER_UID
);
1261 if (c
->mask
& mask
& (SD_BUS_CREDS_EFFECTIVE_CAPS
|SD_BUS_CREDS_PERMITTED_CAPS
|SD_BUS_CREDS_INHERITABLE_CAPS
|SD_BUS_CREDS_BOUNDING_CAPS
)) {
1262 assert(c
->capability
);
1264 n
->capability
= memdup(c
->capability
, DIV_ROUND_UP(cap_last_cap()+1, 32U) * 4 * 4);
1268 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
);
1271 if (c
->mask
& mask
& SD_BUS_CREDS_SELINUX_CONTEXT
) {
1274 n
->label
= strdup(c
->label
);
1277 n
->mask
|= SD_BUS_CREDS_SELINUX_CONTEXT
;
1280 if (c
->mask
& mask
& SD_BUS_CREDS_AUDIT_SESSION_ID
) {
1281 n
->audit_session_id
= c
->audit_session_id
;
1282 n
->mask
|= SD_BUS_CREDS_AUDIT_SESSION_ID
;
1284 if (c
->mask
& mask
& SD_BUS_CREDS_AUDIT_LOGIN_UID
) {
1285 n
->audit_login_uid
= c
->audit_login_uid
;
1286 n
->mask
|= SD_BUS_CREDS_AUDIT_LOGIN_UID
;
1289 if (c
->mask
& mask
& SD_BUS_CREDS_TTY
) {
1291 n
->tty
= strdup(c
->tty
);
1296 n
->mask
|= SD_BUS_CREDS_TTY
;
1299 if (c
->mask
& mask
& SD_BUS_CREDS_UNIQUE_NAME
) {
1300 assert(c
->unique_name
);
1302 n
->unique_name
= strdup(c
->unique_name
);
1303 if (!n
->unique_name
)
1305 n
->mask
|= SD_BUS_CREDS_UNIQUE_NAME
;
1308 if (c
->mask
& mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
) {
1309 if (strv_isempty(c
->well_known_names
))
1310 n
->well_known_names
= NULL
;
1312 n
->well_known_names
= strv_copy(c
->well_known_names
);
1313 if (!n
->well_known_names
)
1316 n
->well_known_names_driver
= c
->well_known_names_driver
;
1317 n
->well_known_names_local
= c
->well_known_names_local
;
1318 n
->mask
|= SD_BUS_CREDS_WELL_KNOWN_NAMES
;
1321 if (c
->mask
& mask
& SD_BUS_CREDS_DESCRIPTION
) {
1322 assert(c
->description
);
1323 n
->description
= strdup(c
->description
);
1324 if (!n
->description
)
1326 n
->mask
|= SD_BUS_CREDS_DESCRIPTION
;
1329 n
->augmented
= c
->augmented
& n
->mask
;
1333 r
= bus_creds_add_more(n
, mask
, 0, 0);