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 sd_bus_creds
* bus_creds_new(void) {
137 c
= new0(sd_bus_creds
, 1);
146 _public_
int sd_bus_creds_new_from_pid(sd_bus_creds
**ret
, pid_t pid
, uint64_t mask
) {
150 assert_return(pid
>= 0, -EINVAL
);
151 assert_return(mask
<= _SD_BUS_CREDS_ALL
, -EOPNOTSUPP
);
152 assert_return(ret
, -EINVAL
);
161 r
= bus_creds_add_more(c
, mask
| SD_BUS_CREDS_AUGMENT
, pid
, 0);
163 sd_bus_creds_unref(c
);
167 /* Check if the process existed at all, in case we haven't
168 * figured that out already */
169 if (!pid_is_alive(pid
)) {
170 sd_bus_creds_unref(c
);
178 _public_
int sd_bus_creds_get_uid(sd_bus_creds
*c
, uid_t
*uid
) {
179 assert_return(c
, -EINVAL
);
180 assert_return(uid
, -EINVAL
);
182 if (!(c
->mask
& SD_BUS_CREDS_UID
))
189 _public_
int sd_bus_creds_get_euid(sd_bus_creds
*c
, uid_t
*euid
) {
190 assert_return(c
, -EINVAL
);
191 assert_return(euid
, -EINVAL
);
193 if (!(c
->mask
& SD_BUS_CREDS_EUID
))
200 _public_
int sd_bus_creds_get_suid(sd_bus_creds
*c
, uid_t
*suid
) {
201 assert_return(c
, -EINVAL
);
202 assert_return(suid
, -EINVAL
);
204 if (!(c
->mask
& SD_BUS_CREDS_SUID
))
212 _public_
int sd_bus_creds_get_fsuid(sd_bus_creds
*c
, uid_t
*fsuid
) {
213 assert_return(c
, -EINVAL
);
214 assert_return(fsuid
, -EINVAL
);
216 if (!(c
->mask
& SD_BUS_CREDS_FSUID
))
223 _public_
int sd_bus_creds_get_gid(sd_bus_creds
*c
, gid_t
*gid
) {
224 assert_return(c
, -EINVAL
);
225 assert_return(gid
, -EINVAL
);
227 if (!(c
->mask
& SD_BUS_CREDS_GID
))
234 _public_
int sd_bus_creds_get_egid(sd_bus_creds
*c
, gid_t
*egid
) {
235 assert_return(c
, -EINVAL
);
236 assert_return(egid
, -EINVAL
);
238 if (!(c
->mask
& SD_BUS_CREDS_EGID
))
245 _public_
int sd_bus_creds_get_sgid(sd_bus_creds
*c
, gid_t
*sgid
) {
246 assert_return(c
, -EINVAL
);
247 assert_return(sgid
, -EINVAL
);
249 if (!(c
->mask
& SD_BUS_CREDS_SGID
))
256 _public_
int sd_bus_creds_get_fsgid(sd_bus_creds
*c
, gid_t
*fsgid
) {
257 assert_return(c
, -EINVAL
);
258 assert_return(fsgid
, -EINVAL
);
260 if (!(c
->mask
& SD_BUS_CREDS_FSGID
))
267 _public_
int sd_bus_creds_get_supplementary_gids(sd_bus_creds
*c
, const gid_t
**gids
) {
268 assert_return(c
, -EINVAL
);
269 assert_return(gids
, -EINVAL
);
271 if (!(c
->mask
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
))
274 *gids
= c
->supplementary_gids
;
275 return (int) c
->n_supplementary_gids
;
278 _public_
int sd_bus_creds_get_pid(sd_bus_creds
*c
, pid_t
*pid
) {
279 assert_return(c
, -EINVAL
);
280 assert_return(pid
, -EINVAL
);
282 if (!(c
->mask
& SD_BUS_CREDS_PID
))
290 _public_
int sd_bus_creds_get_tid(sd_bus_creds
*c
, pid_t
*tid
) {
291 assert_return(c
, -EINVAL
);
292 assert_return(tid
, -EINVAL
);
294 if (!(c
->mask
& SD_BUS_CREDS_TID
))
302 _public_
int sd_bus_creds_get_selinux_context(sd_bus_creds
*c
, const char **ret
) {
303 assert_return(c
, -EINVAL
);
305 if (!(c
->mask
& SD_BUS_CREDS_SELINUX_CONTEXT
))
313 _public_
int sd_bus_creds_get_comm(sd_bus_creds
*c
, const char **ret
) {
314 assert_return(c
, -EINVAL
);
315 assert_return(ret
, -EINVAL
);
317 if (!(c
->mask
& SD_BUS_CREDS_COMM
))
325 _public_
int sd_bus_creds_get_tid_comm(sd_bus_creds
*c
, const char **ret
) {
326 assert_return(c
, -EINVAL
);
327 assert_return(ret
, -EINVAL
);
329 if (!(c
->mask
& SD_BUS_CREDS_TID_COMM
))
337 _public_
int sd_bus_creds_get_exe(sd_bus_creds
*c
, const char **ret
) {
338 assert_return(c
, -EINVAL
);
339 assert_return(ret
, -EINVAL
);
341 if (!(c
->mask
& SD_BUS_CREDS_EXE
))
349 _public_
int sd_bus_creds_get_cgroup(sd_bus_creds
*c
, const char **ret
) {
350 assert_return(c
, -EINVAL
);
351 assert_return(ret
, -EINVAL
);
353 if (!(c
->mask
& SD_BUS_CREDS_CGROUP
))
361 _public_
int sd_bus_creds_get_unit(sd_bus_creds
*c
, const char **ret
) {
364 assert_return(c
, -EINVAL
);
365 assert_return(ret
, -EINVAL
);
367 if (!(c
->mask
& SD_BUS_CREDS_UNIT
))
375 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
379 r
= cg_path_get_unit(shifted
, (char**) &c
->unit
);
388 _public_
int sd_bus_creds_get_user_unit(sd_bus_creds
*c
, const char **ret
) {
391 assert_return(c
, -EINVAL
);
392 assert_return(ret
, -EINVAL
);
394 if (!(c
->mask
& SD_BUS_CREDS_USER_UNIT
))
402 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
406 r
= cg_path_get_user_unit(shifted
, (char**) &c
->user_unit
);
415 _public_
int sd_bus_creds_get_slice(sd_bus_creds
*c
, const char **ret
) {
418 assert_return(c
, -EINVAL
);
419 assert_return(ret
, -EINVAL
);
421 if (!(c
->mask
& SD_BUS_CREDS_SLICE
))
429 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
433 r
= cg_path_get_slice(shifted
, (char**) &c
->slice
);
442 _public_
int sd_bus_creds_get_session(sd_bus_creds
*c
, const char **ret
) {
445 assert_return(c
, -EINVAL
);
446 assert_return(ret
, -EINVAL
);
448 if (!(c
->mask
& SD_BUS_CREDS_SESSION
))
456 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
460 r
= cg_path_get_session(shifted
, (char**) &c
->session
);
469 _public_
int sd_bus_creds_get_owner_uid(sd_bus_creds
*c
, uid_t
*uid
) {
473 assert_return(c
, -EINVAL
);
474 assert_return(uid
, -EINVAL
);
476 if (!(c
->mask
& SD_BUS_CREDS_OWNER_UID
))
481 r
= cg_shift_path(c
->cgroup
, c
->cgroup_root
, &shifted
);
485 return cg_path_get_owner_uid(shifted
, uid
);
488 _public_
int sd_bus_creds_get_cmdline(sd_bus_creds
*c
, char ***cmdline
) {
489 assert_return(c
, -EINVAL
);
491 if (!(c
->mask
& SD_BUS_CREDS_CMDLINE
))
494 assert_return(c
->cmdline
, -ESRCH
);
497 if (!c
->cmdline_array
) {
498 c
->cmdline_array
= strv_parse_nulstr(c
->cmdline
, c
->cmdline_size
);
499 if (!c
->cmdline_array
)
503 *cmdline
= c
->cmdline_array
;
507 _public_
int sd_bus_creds_get_audit_session_id(sd_bus_creds
*c
, uint32_t *sessionid
) {
508 assert_return(c
, -EINVAL
);
509 assert_return(sessionid
, -EINVAL
);
511 if (!(c
->mask
& SD_BUS_CREDS_AUDIT_SESSION_ID
))
514 *sessionid
= c
->audit_session_id
;
518 _public_
int sd_bus_creds_get_audit_login_uid(sd_bus_creds
*c
, uid_t
*uid
) {
519 assert_return(c
, -EINVAL
);
520 assert_return(uid
, -EINVAL
);
522 if (!(c
->mask
& SD_BUS_CREDS_AUDIT_LOGIN_UID
))
525 *uid
= c
->audit_login_uid
;
529 _public_
int sd_bus_creds_get_unique_name(sd_bus_creds
*c
, const char **unique_name
) {
530 assert_return(c
, -EINVAL
);
531 assert_return(unique_name
, -EINVAL
);
533 if (!(c
->mask
& SD_BUS_CREDS_UNIQUE_NAME
))
536 *unique_name
= c
->unique_name
;
540 _public_
int sd_bus_creds_get_well_known_names(sd_bus_creds
*c
, char ***well_known_names
) {
541 assert_return(c
, -EINVAL
);
542 assert_return(well_known_names
, -EINVAL
);
544 if (!(c
->mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
))
547 /* As a special hack we return the bus driver as well-known
548 * names list when this is requested. */
549 if (c
->well_known_names_driver
) {
550 static const char* const wkn
[] = {
551 "org.freedesktop.DBus",
555 *well_known_names
= (char**) wkn
;
559 if (c
->well_known_names_local
) {
560 static const char* const wkn
[] = {
561 "org.freedesktop.DBus.Local",
565 *well_known_names
= (char**) wkn
;
569 *well_known_names
= c
->well_known_names
;
573 _public_
int sd_bus_creds_get_description(sd_bus_creds
*c
, const char **ret
) {
574 assert_return(c
, -EINVAL
);
575 assert_return(ret
, -EINVAL
);
577 if (!(c
->mask
& SD_BUS_CREDS_DESCRIPTION
))
580 assert(c
->description
);
582 if (!c
->unescaped_description
) {
583 c
->unescaped_description
= bus_label_unescape(c
->description
);
584 if (!c
->unescaped_description
)
588 *ret
= c
->unescaped_description
;
592 static int has_cap(sd_bus_creds
*c
, unsigned offset
, int capability
) {
596 assert(capability
>= 0);
597 assert(c
->capability
);
599 if ((unsigned) capability
> cap_last_cap())
602 sz
= DIV_ROUND_UP(cap_last_cap(), 32U);
604 return !!(c
->capability
[offset
* sz
+ CAP_TO_INDEX(capability
)] & CAP_TO_MASK(capability
));
607 _public_
int sd_bus_creds_has_effective_cap(sd_bus_creds
*c
, int capability
) {
608 assert_return(c
, -EINVAL
);
609 assert_return(capability
>= 0, -EINVAL
);
611 if (!(c
->mask
& SD_BUS_CREDS_EFFECTIVE_CAPS
))
614 return has_cap(c
, CAP_OFFSET_EFFECTIVE
, capability
);
617 _public_
int sd_bus_creds_has_permitted_cap(sd_bus_creds
*c
, int capability
) {
618 assert_return(c
, -EINVAL
);
619 assert_return(capability
>= 0, -EINVAL
);
621 if (!(c
->mask
& SD_BUS_CREDS_PERMITTED_CAPS
))
624 return has_cap(c
, CAP_OFFSET_PERMITTED
, capability
);
627 _public_
int sd_bus_creds_has_inheritable_cap(sd_bus_creds
*c
, int capability
) {
628 assert_return(c
, -EINVAL
);
629 assert_return(capability
>= 0, -EINVAL
);
631 if (!(c
->mask
& SD_BUS_CREDS_INHERITABLE_CAPS
))
634 return has_cap(c
, CAP_OFFSET_INHERITABLE
, capability
);
637 _public_
int sd_bus_creds_has_bounding_cap(sd_bus_creds
*c
, int capability
) {
638 assert_return(c
, -EINVAL
);
639 assert_return(capability
>= 0, -EINVAL
);
641 if (!(c
->mask
& SD_BUS_CREDS_BOUNDING_CAPS
))
644 return has_cap(c
, CAP_OFFSET_BOUNDING
, capability
);
647 static int parse_caps(sd_bus_creds
*c
, unsigned offset
, const char *p
) {
654 max
= DIV_ROUND_UP(cap_last_cap(), 32U);
655 p
+= strspn(p
, WHITESPACE
);
665 if (!c
->capability
) {
666 c
->capability
= new0(uint32_t, max
* 4);
671 for (i
= 0; i
< sz
; i
++) {
674 for (j
= 0; j
< 8; ++j
) {
684 c
->capability
[offset
* max
+ (sz
- i
- 1)] = v
;
690 int bus_creds_add_more(sd_bus_creds
*c
, uint64_t mask
, pid_t pid
, pid_t tid
) {
695 assert(c
->allocated
);
697 if (!(mask
& SD_BUS_CREDS_AUGMENT
))
700 missing
= mask
& ~c
->mask
;
704 /* Try to retrieve PID from creds if it wasn't passed to us */
705 if (pid
<= 0 && (c
->mask
& SD_BUS_CREDS_PID
))
708 if (tid
<= 0 && (c
->mask
& SD_BUS_CREDS_TID
))
711 /* Without pid we cannot do much... */
717 c
->mask
|= SD_BUS_CREDS_PID
;
722 c
->mask
|= SD_BUS_CREDS_TID
;
725 if (missing
& (SD_BUS_CREDS_UID
| SD_BUS_CREDS_EUID
| SD_BUS_CREDS_SUID
| SD_BUS_CREDS_FSUID
|
726 SD_BUS_CREDS_GID
| SD_BUS_CREDS_EGID
| SD_BUS_CREDS_SGID
| SD_BUS_CREDS_FSGID
|
727 SD_BUS_CREDS_SUPPLEMENTARY_GIDS
|
728 SD_BUS_CREDS_EFFECTIVE_CAPS
| SD_BUS_CREDS_INHERITABLE_CAPS
|
729 SD_BUS_CREDS_PERMITTED_CAPS
| SD_BUS_CREDS_BOUNDING_CAPS
)) {
731 _cleanup_fclose_
FILE *f
= NULL
;
734 p
= procfs_file_alloca(pid
, "status");
740 else if (errno
!= EPERM
&& errno
!= EACCES
)
745 FOREACH_LINE(line
, f
, return -errno
) {
748 if (missing
& (SD_BUS_CREDS_UID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_SUID
|SD_BUS_CREDS_FSUID
)) {
749 p
= startswith(line
, "Uid:");
751 unsigned long uid
, euid
, suid
, fsuid
;
753 p
+= strspn(p
, WHITESPACE
);
754 if (sscanf(p
, "%lu %lu %lu %lu", &uid
, &euid
, &suid
, &fsuid
) != 4)
757 if (missing
& SD_BUS_CREDS_UID
)
758 c
->uid
= (uid_t
) uid
;
759 if (missing
& SD_BUS_CREDS_EUID
)
760 c
->euid
= (uid_t
) euid
;
761 if (missing
& SD_BUS_CREDS_SUID
)
762 c
->suid
= (uid_t
) suid
;
763 if (missing
& SD_BUS_CREDS_FSUID
)
764 c
->fsuid
= (uid_t
) fsuid
;
766 c
->mask
|= missing
& (SD_BUS_CREDS_UID
|SD_BUS_CREDS_EUID
|SD_BUS_CREDS_SUID
|SD_BUS_CREDS_FSUID
);
771 if (missing
& (SD_BUS_CREDS_GID
|SD_BUS_CREDS_EGID
|SD_BUS_CREDS_SGID
|SD_BUS_CREDS_FSGID
)) {
772 p
= startswith(line
, "Gid:");
774 unsigned long gid
, egid
, sgid
, fsgid
;
776 p
+= strspn(p
, WHITESPACE
);
777 if (sscanf(p
, "%lu %lu %lu %lu", &gid
, &egid
, &sgid
, &fsgid
) != 4)
780 if (missing
& SD_BUS_CREDS_GID
)
781 c
->gid
= (gid_t
) gid
;
782 if (missing
& SD_BUS_CREDS_EGID
)
783 c
->egid
= (gid_t
) egid
;
784 if (missing
& SD_BUS_CREDS_SGID
)
785 c
->sgid
= (gid_t
) sgid
;
786 if (missing
& SD_BUS_CREDS_FSGID
)
787 c
->fsgid
= (gid_t
) fsgid
;
789 c
->mask
|= missing
& (SD_BUS_CREDS_GID
|SD_BUS_CREDS_EGID
|SD_BUS_CREDS_SGID
|SD_BUS_CREDS_FSGID
);
794 if (missing
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
) {
795 p
= startswith(line
, "Groups:");
797 size_t allocated
= 0;
803 p
+= strspn(p
, WHITESPACE
);
807 if (sscanf(p
, "%lu%n", &g
, &n
) != 1)
810 if (!GREEDY_REALLOC(c
->supplementary_gids
, allocated
, c
->n_supplementary_gids
+1))
813 c
->supplementary_gids
[c
->n_supplementary_gids
++] = (gid_t
) g
;
817 c
->mask
|= SD_BUS_CREDS_SUPPLEMENTARY_GIDS
;
822 if (missing
& SD_BUS_CREDS_EFFECTIVE_CAPS
) {
823 p
= startswith(line
, "CapEff:");
825 r
= parse_caps(c
, CAP_OFFSET_EFFECTIVE
, p
);
829 c
->mask
|= SD_BUS_CREDS_EFFECTIVE_CAPS
;
834 if (missing
& SD_BUS_CREDS_PERMITTED_CAPS
) {
835 p
= startswith(line
, "CapPrm:");
837 r
= parse_caps(c
, CAP_OFFSET_PERMITTED
, p
);
841 c
->mask
|= SD_BUS_CREDS_PERMITTED_CAPS
;
846 if (missing
& SD_BUS_CREDS_INHERITABLE_CAPS
) {
847 p
= startswith(line
, "CapInh:");
849 r
= parse_caps(c
, CAP_OFFSET_INHERITABLE
, p
);
853 c
->mask
|= SD_BUS_CREDS_INHERITABLE_CAPS
;
858 if (missing
& SD_BUS_CREDS_BOUNDING_CAPS
) {
859 p
= startswith(line
, "CapBnd:");
861 r
= parse_caps(c
, CAP_OFFSET_BOUNDING
, p
);
865 c
->mask
|= SD_BUS_CREDS_BOUNDING_CAPS
;
873 if (missing
& SD_BUS_CREDS_SELINUX_CONTEXT
) {
876 p
= procfs_file_alloca(pid
, "attr/current");
877 r
= read_one_line_file(p
, &c
->label
);
879 if (r
!= -ENOENT
&& r
!= -EINVAL
&& r
!= -EPERM
&& r
!= -EACCES
)
882 c
->mask
|= SD_BUS_CREDS_SELINUX_CONTEXT
;
885 if (missing
& SD_BUS_CREDS_COMM
) {
886 r
= get_process_comm(pid
, &c
->comm
);
888 if (r
!= -EPERM
&& r
!= -EACCES
)
891 c
->mask
|= SD_BUS_CREDS_COMM
;
894 if (missing
& SD_BUS_CREDS_EXE
) {
895 r
= get_process_exe(pid
, &c
->exe
);
897 if (r
!= -EPERM
&& r
!= -EACCES
)
900 c
->mask
|= SD_BUS_CREDS_EXE
;
903 if (missing
& SD_BUS_CREDS_CMDLINE
) {
906 p
= procfs_file_alloca(pid
, "cmdline");
907 r
= read_full_file(p
, &c
->cmdline
, &c
->cmdline_size
);
911 if (r
!= -EPERM
&& r
!= -EACCES
)
914 if (c
->cmdline_size
== 0) {
918 c
->mask
|= SD_BUS_CREDS_CMDLINE
;
922 if (tid
> 0 && (missing
& SD_BUS_CREDS_TID_COMM
)) {
923 _cleanup_free_
char *p
= NULL
;
925 if (asprintf(&p
, "/proc/"PID_FMT
"/task/"PID_FMT
"/comm", pid
, tid
) < 0)
928 r
= read_one_line_file(p
, &c
->tid_comm
);
932 if (r
!= -EPERM
&& r
!= -EACCES
)
935 c
->mask
|= SD_BUS_CREDS_TID_COMM
;
938 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
)) {
940 r
= cg_pid_get_path(NULL
, pid
, &c
->cgroup
);
942 if (r
!= -EPERM
&& r
!= -EACCES
)
945 r
= cg_get_root_path(&c
->cgroup_root
);
949 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
);
953 if (missing
& SD_BUS_CREDS_AUDIT_SESSION_ID
) {
954 r
= audit_session_from_pid(pid
, &c
->audit_session_id
);
956 if (r
!= -EOPNOTSUPP
&& r
!= -ENXIO
&& r
!= -ENOENT
&& r
!= -EPERM
&& r
!= -EACCES
)
959 c
->mask
|= SD_BUS_CREDS_AUDIT_SESSION_ID
;
962 if (missing
& SD_BUS_CREDS_AUDIT_LOGIN_UID
) {
963 r
= audit_loginuid_from_pid(pid
, &c
->audit_login_uid
);
965 if (r
!= -EOPNOTSUPP
&& r
!= -ENXIO
&& r
!= -ENOENT
&& r
!= -EPERM
&& r
!= -EACCES
)
968 c
->mask
|= SD_BUS_CREDS_AUDIT_LOGIN_UID
;
974 int bus_creds_extend_by_pid(sd_bus_creds
*c
, uint64_t mask
, sd_bus_creds
**ret
) {
975 _cleanup_bus_creds_unref_ sd_bus_creds
*n
= NULL
;
981 if ((mask
& ~c
->mask
) == 0 || (!(mask
& SD_BUS_CREDS_AUGMENT
))) {
982 /* There's already all data we need, or augmentation
983 * wasn't turned on. */
985 *ret
= sd_bus_creds_ref(c
);
993 /* Copy the original data over */
995 if (c
->mask
& mask
& SD_BUS_CREDS_PID
) {
997 n
->mask
|= SD_BUS_CREDS_PID
;
1000 if (c
->mask
& mask
& SD_BUS_CREDS_TID
) {
1002 n
->mask
|= SD_BUS_CREDS_TID
;
1005 if (c
->mask
& mask
& SD_BUS_CREDS_UID
) {
1007 n
->mask
|= SD_BUS_CREDS_UID
;
1010 if (c
->mask
& mask
& SD_BUS_CREDS_EUID
) {
1012 n
->mask
|= SD_BUS_CREDS_EUID
;
1015 if (c
->mask
& mask
& SD_BUS_CREDS_SUID
) {
1017 n
->mask
|= SD_BUS_CREDS_SUID
;
1020 if (c
->mask
& mask
& SD_BUS_CREDS_FSUID
) {
1021 n
->fsuid
= c
->fsuid
;
1022 n
->mask
|= SD_BUS_CREDS_FSUID
;
1025 if (c
->mask
& mask
& SD_BUS_CREDS_GID
) {
1027 n
->mask
|= SD_BUS_CREDS_GID
;
1030 if (c
->mask
& mask
& SD_BUS_CREDS_EGID
) {
1032 n
->mask
|= SD_BUS_CREDS_EGID
;
1035 if (c
->mask
& mask
& SD_BUS_CREDS_SGID
) {
1037 n
->mask
|= SD_BUS_CREDS_SGID
;
1040 if (c
->mask
& mask
& SD_BUS_CREDS_FSGID
) {
1041 n
->fsgid
= c
->fsgid
;
1042 n
->mask
|= SD_BUS_CREDS_FSGID
;
1045 if (c
->mask
& mask
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
) {
1046 n
->supplementary_gids
= newdup(gid_t
, c
->supplementary_gids
, c
->n_supplementary_gids
);
1047 if (!n
->supplementary_gids
)
1049 n
->n_supplementary_gids
= c
->n_supplementary_gids
;
1050 n
->mask
|= SD_BUS_CREDS_SUPPLEMENTARY_GIDS
;
1053 if (c
->mask
& mask
& SD_BUS_CREDS_COMM
) {
1054 n
->comm
= strdup(c
->comm
);
1058 n
->mask
|= SD_BUS_CREDS_COMM
;
1061 if (c
->mask
& mask
& SD_BUS_CREDS_TID_COMM
) {
1062 n
->tid_comm
= strdup(c
->tid_comm
);
1066 n
->mask
|= SD_BUS_CREDS_TID_COMM
;
1069 if (c
->mask
& mask
& SD_BUS_CREDS_EXE
) {
1070 n
->exe
= strdup(c
->exe
);
1074 n
->mask
|= SD_BUS_CREDS_EXE
;
1077 if (c
->mask
& mask
& SD_BUS_CREDS_CMDLINE
) {
1078 n
->cmdline
= memdup(c
->cmdline
, c
->cmdline_size
);
1082 n
->cmdline_size
= c
->cmdline_size
;
1083 n
->mask
|= SD_BUS_CREDS_CMDLINE
;
1086 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
)) {
1087 n
->cgroup
= strdup(c
->cgroup
);
1091 n
->cgroup_root
= strdup(c
->cgroup_root
);
1092 if (!n
->cgroup_root
)
1095 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
);
1098 if (c
->mask
& mask
& (SD_BUS_CREDS_EFFECTIVE_CAPS
|SD_BUS_CREDS_PERMITTED_CAPS
|SD_BUS_CREDS_INHERITABLE_CAPS
|SD_BUS_CREDS_BOUNDING_CAPS
)) {
1099 n
->capability
= memdup(c
->capability
, DIV_ROUND_UP(cap_last_cap(), 32U) * 4 * 4);
1103 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
);
1106 if (c
->mask
& mask
& SD_BUS_CREDS_SELINUX_CONTEXT
) {
1107 n
->label
= strdup(c
->label
);
1110 n
->mask
|= SD_BUS_CREDS_SELINUX_CONTEXT
;
1113 if (c
->mask
& mask
& SD_BUS_CREDS_AUDIT_SESSION_ID
) {
1114 n
->audit_session_id
= c
->audit_session_id
;
1115 n
->mask
|= SD_BUS_CREDS_AUDIT_SESSION_ID
;
1117 if (c
->mask
& mask
& SD_BUS_CREDS_AUDIT_LOGIN_UID
) {
1118 n
->audit_login_uid
= c
->audit_login_uid
;
1119 n
->mask
|= SD_BUS_CREDS_AUDIT_LOGIN_UID
;
1122 if (c
->mask
& mask
& SD_BUS_CREDS_UNIQUE_NAME
) {
1123 n
->unique_name
= strdup(c
->unique_name
);
1124 if (!n
->unique_name
)
1126 n
->mask
|= SD_BUS_CREDS_UNIQUE_NAME
;
1129 if (c
->mask
& mask
& SD_BUS_CREDS_WELL_KNOWN_NAMES
) {
1130 n
->well_known_names
= strv_copy(c
->well_known_names
);
1131 if (!n
->well_known_names
)
1133 n
->well_known_names_driver
= c
->well_known_names_driver
;
1134 n
->well_known_names_local
= c
->well_known_names_local
;
1135 n
->mask
|= SD_BUS_CREDS_WELL_KNOWN_NAMES
;
1138 if (c
->mask
& mask
& SD_BUS_CREDS_DESCRIPTION
) {
1139 n
->description
= strdup(c
->description
);
1140 if (!n
->description
)
1142 n
->mask
|= SD_BUS_CREDS_DESCRIPTION
;
1147 r
= bus_creds_add_more(n
, mask
,
1148 c
->mask
& SD_BUS_CREDS_PID
? c
->pid
: 0,
1149 c
->mask
& SD_BUS_CREDS_TID
? c
->tid
: 0);