1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include <linux/capability.h>
4 #include <stdlib.h>
5 
6 #include "alloc-util.h"
7 #include "audit-util.h"
8 #include "bus-creds.h"
9 #include "bus-label.h"
10 #include "bus-message.h"
11 #include "capability-util.h"
12 #include "cgroup-util.h"
13 #include "errno-util.h"
14 #include "fd-util.h"
15 #include "fileio.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"
21 #include "strv.h"
22 #include "terminal-util.h"
23 #include "user-util.h"
24 #include "util.h"
25 
26 enum {
27         CAP_OFFSET_INHERITABLE = 0,
28         CAP_OFFSET_PERMITTED = 1,
29         CAP_OFFSET_EFFECTIVE = 2,
30         CAP_OFFSET_BOUNDING = 3
31 };
32 
bus_creds_done(sd_bus_creds * c)33 void bus_creds_done(sd_bus_creds *c) {
34         assert(c);
35 
36         /* For internal bus cred structures that are allocated by
37          * something else */
38 
39         free(c->session);
40         free(c->unit);
41         free(c->user_unit);
42         free(c->slice);
43         free(c->user_slice);
44         free(c->unescaped_description);
45         free(c->supplementary_gids);
46         free(c->tty);
47 
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
53                                     * below. */
54 
55         strv_free(c->cmdline_array);
56 }
57 
sd_bus_creds_ref(sd_bus_creds * c)58 _public_ sd_bus_creds *sd_bus_creds_ref(sd_bus_creds *c) {
59 
60         if (!c)
61                 return NULL;
62 
63         if (c->allocated) {
64                 assert(c->n_ref > 0);
65                 c->n_ref++;
66         } else {
67                 sd_bus_message *m;
68 
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);
73         }
74 
75         return c;
76 }
77 
sd_bus_creds_unref(sd_bus_creds * c)78 _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
79 
80         if (!c)
81                 return NULL;
82 
83         if (c->allocated) {
84                 assert(c->n_ref > 0);
85                 c->n_ref--;
86 
87                 if (c->n_ref == 0) {
88                         free(c->comm);
89                         free(c->tid_comm);
90                         free(c->exe);
91                         free(c->cmdline);
92                         free(c->cgroup);
93                         free(c->capability);
94                         free(c->label);
95                         free(c->unique_name);
96                         free(c->cgroup_root);
97                         free(c->description);
98 
99                         c->supplementary_gids = mfree(c->supplementary_gids);
100 
101                         c->well_known_names = strv_free(c->well_known_names);
102 
103                         bus_creds_done(c);
104 
105                         free(c);
106                 }
107         } else {
108                 sd_bus_message *m;
109 
110                 m = container_of(c, sd_bus_message, creds);
111                 sd_bus_message_unref(m);
112         }
113 
114         return NULL;
115 }
116 
sd_bus_creds_get_mask(const sd_bus_creds * c)117 _public_ uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c) {
118         assert_return(c, 0);
119 
120         return c->mask;
121 }
122 
sd_bus_creds_get_augmented_mask(const sd_bus_creds * c)123 _public_ uint64_t sd_bus_creds_get_augmented_mask(const sd_bus_creds *c) {
124         assert_return(c, 0);
125 
126         return c->augmented;
127 }
128 
bus_creds_new(void)129 sd_bus_creds* bus_creds_new(void) {
130         sd_bus_creds *c;
131 
132         c = new0(sd_bus_creds, 1);
133         if (!c)
134                 return NULL;
135 
136         c->allocated = true;
137         c->n_ref = 1;
138         return c;
139 }
140 
sd_bus_creds_new_from_pid(sd_bus_creds ** ret,pid_t pid,uint64_t mask)141 _public_ int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t mask) {
142         sd_bus_creds *c;
143         int r;
144 
145         assert_return(pid >= 0, -EINVAL);
146         assert_return(mask <= _SD_BUS_CREDS_ALL, -EOPNOTSUPP);
147         assert_return(ret, -EINVAL);
148 
149         if (pid == 0)
150                 pid = getpid_cached();
151 
152         c = bus_creds_new();
153         if (!c)
154                 return -ENOMEM;
155 
156         r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
157         if (r < 0) {
158                 sd_bus_creds_unref(c);
159                 return r;
160         }
161 
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);
166                 return -ESRCH;
167         }
168 
169         *ret = c;
170         return 0;
171 }
172 
sd_bus_creds_get_uid(sd_bus_creds * c,uid_t * uid)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);
176 
177         if (!(c->mask & SD_BUS_CREDS_UID))
178                 return -ENODATA;
179 
180         *uid = c->uid;
181         return 0;
182 }
183 
sd_bus_creds_get_euid(sd_bus_creds * c,uid_t * euid)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);
187 
188         if (!(c->mask & SD_BUS_CREDS_EUID))
189                 return -ENODATA;
190 
191         *euid = c->euid;
192         return 0;
193 }
194 
sd_bus_creds_get_suid(sd_bus_creds * c,uid_t * suid)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);
198 
199         if (!(c->mask & SD_BUS_CREDS_SUID))
200                 return -ENODATA;
201 
202         *suid = c->suid;
203         return 0;
204 }
205 
sd_bus_creds_get_fsuid(sd_bus_creds * c,uid_t * fsuid)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);
209 
210         if (!(c->mask & SD_BUS_CREDS_FSUID))
211                 return -ENODATA;
212 
213         *fsuid = c->fsuid;
214         return 0;
215 }
216 
sd_bus_creds_get_gid(sd_bus_creds * c,gid_t * gid)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);
220 
221         if (!(c->mask & SD_BUS_CREDS_GID))
222                 return -ENODATA;
223 
224         *gid = c->gid;
225         return 0;
226 }
227 
sd_bus_creds_get_egid(sd_bus_creds * c,gid_t * egid)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);
231 
232         if (!(c->mask & SD_BUS_CREDS_EGID))
233                 return -ENODATA;
234 
235         *egid = c->egid;
236         return 0;
237 }
238 
sd_bus_creds_get_sgid(sd_bus_creds * c,gid_t * sgid)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);
242 
243         if (!(c->mask & SD_BUS_CREDS_SGID))
244                 return -ENODATA;
245 
246         *sgid = c->sgid;
247         return 0;
248 }
249 
sd_bus_creds_get_fsgid(sd_bus_creds * c,gid_t * fsgid)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);
253 
254         if (!(c->mask & SD_BUS_CREDS_FSGID))
255                 return -ENODATA;
256 
257         *fsgid = c->fsgid;
258         return 0;
259 }
260 
sd_bus_creds_get_supplementary_gids(sd_bus_creds * c,const gid_t ** gids)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);
264 
265         if (!(c->mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS))
266                 return -ENODATA;
267 
268         *gids = c->supplementary_gids;
269         return (int) c->n_supplementary_gids;
270 }
271 
sd_bus_creds_get_pid(sd_bus_creds * c,pid_t * pid)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);
275 
276         if (!(c->mask & SD_BUS_CREDS_PID))
277                 return -ENODATA;
278 
279         assert(c->pid > 0);
280         *pid = c->pid;
281         return 0;
282 }
283 
sd_bus_creds_get_ppid(sd_bus_creds * c,pid_t * ppid)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);
287 
288         if (!(c->mask & SD_BUS_CREDS_PPID))
289                 return -ENODATA;
290 
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
293          * error code. */
294         if (c->ppid == 0)
295                 return -ENXIO;
296 
297         *ppid = c->ppid;
298         return 0;
299 }
300 
sd_bus_creds_get_tid(sd_bus_creds * c,pid_t * tid)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);
304 
305         if (!(c->mask & SD_BUS_CREDS_TID))
306                 return -ENODATA;
307 
308         assert(c->tid > 0);
309         *tid = c->tid;
310         return 0;
311 }
312 
sd_bus_creds_get_selinux_context(sd_bus_creds * c,const char ** ret)313 _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
314         assert_return(c, -EINVAL);
315 
316         if (!(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT))
317                 return -ENODATA;
318 
319         assert(c->label);
320         *ret = c->label;
321         return 0;
322 }
323 
sd_bus_creds_get_comm(sd_bus_creds * c,const char ** ret)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);
327 
328         if (!(c->mask & SD_BUS_CREDS_COMM))
329                 return -ENODATA;
330 
331         assert(c->comm);
332         *ret = c->comm;
333         return 0;
334 }
335 
sd_bus_creds_get_tid_comm(sd_bus_creds * c,const char ** ret)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);
339 
340         if (!(c->mask & SD_BUS_CREDS_TID_COMM))
341                 return -ENODATA;
342 
343         assert(c->tid_comm);
344         *ret = c->tid_comm;
345         return 0;
346 }
347 
sd_bus_creds_get_exe(sd_bus_creds * c,const char ** ret)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);
351 
352         if (!(c->mask & SD_BUS_CREDS_EXE))
353                 return -ENODATA;
354 
355         if (!c->exe)
356                 return -ENXIO;
357 
358         *ret = c->exe;
359         return 0;
360 }
361 
sd_bus_creds_get_cgroup(sd_bus_creds * c,const char ** ret)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);
365 
366         if (!(c->mask & SD_BUS_CREDS_CGROUP))
367                 return -ENODATA;
368 
369         assert(c->cgroup);
370         *ret = c->cgroup;
371         return 0;
372 }
373 
sd_bus_creds_get_unit(sd_bus_creds * c,const char ** ret)374 _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {
375         int r;
376 
377         assert_return(c, -EINVAL);
378         assert_return(ret, -EINVAL);
379 
380         if (!(c->mask & SD_BUS_CREDS_UNIT))
381                 return -ENODATA;
382 
383         assert(c->cgroup);
384 
385         if (!c->unit) {
386                 const char *shifted;
387 
388                 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
389                 if (r < 0)
390                         return r;
391 
392                 r = cg_path_get_unit(shifted, (char**) &c->unit);
393                 if (r < 0)
394                         return r;
395         }
396 
397         *ret = c->unit;
398         return 0;
399 }
400 
sd_bus_creds_get_user_unit(sd_bus_creds * c,const char ** ret)401 _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
402         int r;
403 
404         assert_return(c, -EINVAL);
405         assert_return(ret, -EINVAL);
406 
407         if (!(c->mask & SD_BUS_CREDS_USER_UNIT))
408                 return -ENODATA;
409 
410         assert(c->cgroup);
411 
412         if (!c->user_unit) {
413                 const char *shifted;
414 
415                 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
416                 if (r < 0)
417                         return r;
418 
419                 r = cg_path_get_user_unit(shifted, (char**) &c->user_unit);
420                 if (r < 0)
421                         return r;
422         }
423 
424         *ret = c->user_unit;
425         return 0;
426 }
427 
sd_bus_creds_get_slice(sd_bus_creds * c,const char ** ret)428 _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
429         int r;
430 
431         assert_return(c, -EINVAL);
432         assert_return(ret, -EINVAL);
433 
434         if (!(c->mask & SD_BUS_CREDS_SLICE))
435                 return -ENODATA;
436 
437         assert(c->cgroup);
438 
439         if (!c->slice) {
440                 const char *shifted;
441 
442                 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
443                 if (r < 0)
444                         return r;
445 
446                 r = cg_path_get_slice(shifted, (char**) &c->slice);
447                 if (r < 0)
448                         return r;
449         }
450 
451         *ret = c->slice;
452         return 0;
453 }
454 
sd_bus_creds_get_user_slice(sd_bus_creds * c,const char ** ret)455 _public_ int sd_bus_creds_get_user_slice(sd_bus_creds *c, const char **ret) {
456         int r;
457 
458         assert_return(c, -EINVAL);
459         assert_return(ret, -EINVAL);
460 
461         if (!(c->mask & SD_BUS_CREDS_USER_SLICE))
462                 return -ENODATA;
463 
464         assert(c->cgroup);
465 
466         if (!c->user_slice) {
467                 const char *shifted;
468 
469                 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
470                 if (r < 0)
471                         return r;
472 
473                 r = cg_path_get_user_slice(shifted, (char**) &c->user_slice);
474                 if (r < 0)
475                         return r;
476         }
477 
478         *ret = c->user_slice;
479         return 0;
480 }
481 
sd_bus_creds_get_session(sd_bus_creds * c,const char ** ret)482 _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
483         int r;
484 
485         assert_return(c, -EINVAL);
486         assert_return(ret, -EINVAL);
487 
488         if (!(c->mask & SD_BUS_CREDS_SESSION))
489                 return -ENODATA;
490 
491         assert(c->cgroup);
492 
493         if (!c->session) {
494                 const char *shifted;
495 
496                 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
497                 if (r < 0)
498                         return r;
499 
500                 r = cg_path_get_session(shifted, (char**) &c->session);
501                 if (r < 0)
502                         return r;
503         }
504 
505         *ret = c->session;
506         return 0;
507 }
508 
sd_bus_creds_get_owner_uid(sd_bus_creds * c,uid_t * uid)509 _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
510         const char *shifted;
511         int r;
512 
513         assert_return(c, -EINVAL);
514         assert_return(uid, -EINVAL);
515 
516         if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
517                 return -ENODATA;
518 
519         assert(c->cgroup);
520 
521         r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
522         if (r < 0)
523                 return r;
524 
525         return cg_path_get_owner_uid(shifted, uid);
526 }
527 
sd_bus_creds_get_cmdline(sd_bus_creds * c,char *** cmdline)528 _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
529         assert_return(c, -EINVAL);
530 
531         if (!(c->mask & SD_BUS_CREDS_CMDLINE))
532                 return -ENODATA;
533 
534         if (!c->cmdline)
535                 return -ENXIO;
536 
537         if (!c->cmdline_array) {
538                 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
539                 if (!c->cmdline_array)
540                         return -ENOMEM;
541         }
542 
543         *cmdline = c->cmdline_array;
544         return 0;
545 }
546 
sd_bus_creds_get_audit_session_id(sd_bus_creds * c,uint32_t * sessionid)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);
550 
551         if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
552                 return -ENODATA;
553 
554         if (!audit_session_is_valid(c->audit_session_id))
555                 return -ENXIO;
556 
557         *sessionid = c->audit_session_id;
558         return 0;
559 }
560 
sd_bus_creds_get_audit_login_uid(sd_bus_creds * c,uid_t * uid)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);
564 
565         if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID))
566                 return -ENODATA;
567 
568         if (!uid_is_valid(c->audit_login_uid))
569                 return -ENXIO;
570 
571         *uid = c->audit_login_uid;
572         return 0;
573 }
574 
sd_bus_creds_get_tty(sd_bus_creds * c,const char ** ret)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);
578 
579         if (!(c->mask & SD_BUS_CREDS_TTY))
580                 return -ENODATA;
581 
582         if (!c->tty)
583                 return -ENXIO;
584 
585         *ret = c->tty;
586         return 0;
587 }
588 
sd_bus_creds_get_unique_name(sd_bus_creds * c,const char ** unique_name)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);
592 
593         if (!(c->mask & SD_BUS_CREDS_UNIQUE_NAME))
594                 return -ENODATA;
595 
596         *unique_name = c->unique_name;
597         return 0;
598 }
599 
sd_bus_creds_get_well_known_names(sd_bus_creds * c,char *** well_known_names)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);
603 
604         if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
605                 return -ENODATA;
606 
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",
612                         NULL
613                 };
614 
615                 *well_known_names = (char**) wkn;
616                 return 0;
617         }
618 
619         if (c->well_known_names_local) {
620                 static const char* const wkn[] = {
621                         "org.freedesktop.DBus.Local",
622                         NULL
623                 };
624 
625                 *well_known_names = (char**) wkn;
626                 return 0;
627         }
628 
629         *well_known_names = c->well_known_names;
630         return 0;
631 }
632 
sd_bus_creds_get_description(sd_bus_creds * c,const char ** ret)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);
636 
637         if (!(c->mask & SD_BUS_CREDS_DESCRIPTION))
638                 return -ENODATA;
639 
640         assert(c->description);
641 
642         if (!c->unescaped_description) {
643                 c->unescaped_description = bus_label_unescape(c->description);
644                 if (!c->unescaped_description)
645                         return -ENOMEM;
646         }
647 
648         *ret = c->unescaped_description;
649         return 0;
650 }
651 
has_cap(sd_bus_creds * c,size_t offset,int capability)652 static int has_cap(sd_bus_creds *c, size_t offset, int capability) {
653         size_t sz;
654 
655         assert(c);
656         assert(capability >= 0);
657         assert(c->capability);
658 
659         unsigned lc = cap_last_cap();
660 
661         if ((unsigned) capability > lc)
662                 return 0;
663 
664         /* If the last cap is 63, then there are 64 caps defined, and we need 2 entries á 32bit hence. *
665          * If the last cap is 64, then there are 65 caps defined, and we need 3 entries á 32bit hence. */
666         sz = DIV_ROUND_UP(lc+1, 32LU);
667 
668         return !!(c->capability[offset * sz + CAP_TO_INDEX((uint32_t) capability)] & CAP_TO_MASK_CORRECTED((uint32_t) capability));
669 }
670 
sd_bus_creds_has_effective_cap(sd_bus_creds * c,int capability)671 _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
672         assert_return(c, -EINVAL);
673         assert_return(capability >= 0, -EINVAL);
674 
675         if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS))
676                 return -ENODATA;
677 
678         return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
679 }
680 
sd_bus_creds_has_permitted_cap(sd_bus_creds * c,int capability)681 _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
682         assert_return(c, -EINVAL);
683         assert_return(capability >= 0, -EINVAL);
684 
685         if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS))
686                 return -ENODATA;
687 
688         return has_cap(c, CAP_OFFSET_PERMITTED, capability);
689 }
690 
sd_bus_creds_has_inheritable_cap(sd_bus_creds * c,int capability)691 _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
692         assert_return(c, -EINVAL);
693         assert_return(capability >= 0, -EINVAL);
694 
695         if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS))
696                 return -ENODATA;
697 
698         return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
699 }
700 
sd_bus_creds_has_bounding_cap(sd_bus_creds * c,int capability)701 _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) {
702         assert_return(c, -EINVAL);
703         assert_return(capability >= 0, -EINVAL);
704 
705         if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS))
706                 return -ENODATA;
707 
708         return has_cap(c, CAP_OFFSET_BOUNDING, capability);
709 }
710 
parse_caps(sd_bus_creds * c,unsigned offset,const char * p)711 static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
712         size_t sz, max;
713         unsigned i, j;
714 
715         assert(c);
716         assert(p);
717 
718         max = DIV_ROUND_UP(cap_last_cap()+1, 32U);
719         p += strspn(p, WHITESPACE);
720 
721         sz = strlen(p);
722         if (sz % 8 != 0)
723                 return -EINVAL;
724 
725         sz /= 8;
726         if (sz > max)
727                 return -EINVAL;
728 
729         if (!c->capability) {
730                 c->capability = new0(uint32_t, max * 4);
731                 if (!c->capability)
732                         return -ENOMEM;
733         }
734 
735         for (i = 0; i < sz; i ++) {
736                 uint32_t v = 0;
737 
738                 for (j = 0; j < 8; ++j) {
739                         int t;
740 
741                         t = unhexchar(*p++);
742                         if (t < 0)
743                                 return -EINVAL;
744 
745                         v = (v << 4) | t;
746                 }
747 
748                 c->capability[offset * max + (sz - i - 1)] = v;
749         }
750 
751         return 0;
752 }
753 
bus_creds_add_more(sd_bus_creds * c,uint64_t mask,pid_t pid,pid_t tid)754 int bus_creds_add_more(sd_bus_creds *c, uint64_t mask, pid_t pid, pid_t tid) {
755         uint64_t missing;
756         int r;
757 
758         assert(c);
759         assert(c->allocated);
760 
761         if (!(mask & SD_BUS_CREDS_AUGMENT))
762                 return 0;
763 
764         /* Try to retrieve PID from creds if it wasn't passed to us */
765         if (pid > 0) {
766                 c->pid = pid;
767                 c->mask |= SD_BUS_CREDS_PID;
768         } else if (c->mask & SD_BUS_CREDS_PID)
769                 pid = c->pid;
770         else
771                 /* Without pid we cannot do much... */
772                 return 0;
773 
774         /* Try to retrieve TID from creds if it wasn't passed to us */
775         if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
776                 tid = c->tid;
777 
778         /* Calculate what we shall and can add */
779         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);
780         if (missing == 0)
781                 return 0;
782 
783         if (tid > 0) {
784                 c->tid = tid;
785                 c->mask |= SD_BUS_CREDS_TID;
786         }
787 
788         if (missing & (SD_BUS_CREDS_PPID |
789                        SD_BUS_CREDS_UID | SD_BUS_CREDS_EUID | SD_BUS_CREDS_SUID | SD_BUS_CREDS_FSUID |
790                        SD_BUS_CREDS_GID | SD_BUS_CREDS_EGID | SD_BUS_CREDS_SGID | SD_BUS_CREDS_FSGID |
791                        SD_BUS_CREDS_SUPPLEMENTARY_GIDS |
792                        SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_INHERITABLE_CAPS |
793                        SD_BUS_CREDS_PERMITTED_CAPS | SD_BUS_CREDS_BOUNDING_CAPS)) {
794 
795                 _cleanup_fclose_ FILE *f = NULL;
796                 const char *p;
797 
798                 p = procfs_file_alloca(pid, "status");
799 
800                 f = fopen(p, "re");
801                 if (!f) {
802                         if (errno == ENOENT)
803                                 return -ESRCH;
804                         else if (!ERRNO_IS_PRIVILEGE(errno))
805                                 return -errno;
806                 } else {
807 
808                         for (;;) {
809                                 _cleanup_free_ char *line = NULL;
810 
811                                 r = read_line(f, LONG_LINE_MAX, &line);
812                                 if (r < 0)
813                                         return r;
814                                 if (r == 0)
815                                         break;
816 
817                                 if (missing & SD_BUS_CREDS_PPID) {
818                                         p = startswith(line, "PPid:");
819                                         if (p) {
820                                                 p += strspn(p, WHITESPACE);
821 
822                                                 /* Explicitly check for PPID 0 (which is the case for PID 1) */
823                                                 if (!streq(p, "0")) {
824                                                         r = parse_pid(p, &c->ppid);
825                                                         if (r < 0)
826                                                                 return r;
827 
828                                                 } else
829                                                         c->ppid = 0;
830 
831                                                 c->mask |= SD_BUS_CREDS_PPID;
832                                                 continue;
833                                         }
834                                 }
835 
836                                 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
837                                         p = startswith(line, "Uid:");
838                                         if (p) {
839                                                 unsigned long uid, euid, suid, fsuid;
840 
841                                                 p += strspn(p, WHITESPACE);
842                                                 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
843                                                         return -EIO;
844 
845                                                 if (missing & SD_BUS_CREDS_UID)
846                                                         c->uid = (uid_t) uid;
847                                                 if (missing & SD_BUS_CREDS_EUID)
848                                                         c->euid = (uid_t) euid;
849                                                 if (missing & SD_BUS_CREDS_SUID)
850                                                         c->suid = (uid_t) suid;
851                                                 if (missing & SD_BUS_CREDS_FSUID)
852                                                         c->fsuid = (uid_t) fsuid;
853 
854                                                 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
855                                                 continue;
856                                         }
857                                 }
858 
859                                 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
860                                         p = startswith(line, "Gid:");
861                                         if (p) {
862                                                 unsigned long gid, egid, sgid, fsgid;
863 
864                                                 p += strspn(p, WHITESPACE);
865                                                 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
866                                                         return -EIO;
867 
868                                                 if (missing & SD_BUS_CREDS_GID)
869                                                         c->gid = (gid_t) gid;
870                                                 if (missing & SD_BUS_CREDS_EGID)
871                                                         c->egid = (gid_t) egid;
872                                                 if (missing & SD_BUS_CREDS_SGID)
873                                                         c->sgid = (gid_t) sgid;
874                                                 if (missing & SD_BUS_CREDS_FSGID)
875                                                         c->fsgid = (gid_t) fsgid;
876 
877                                                 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
878                                                 continue;
879                                         }
880                                 }
881 
882                                 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
883                                         p = startswith(line, "Groups:");
884                                         if (p) {
885                                                 for (;;) {
886                                                         unsigned long g;
887                                                         int n = 0;
888 
889                                                         p += strspn(p, WHITESPACE);
890                                                         if (*p == 0)
891                                                                 break;
892 
893                                                         if (sscanf(p, "%lu%n", &g, &n) != 1)
894                                                                 return -EIO;
895 
896                                                         if (!GREEDY_REALLOC(c->supplementary_gids, c->n_supplementary_gids+1))
897                                                                 return -ENOMEM;
898 
899                                                         c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
900                                                         p += n;
901                                                 }
902 
903                                                 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
904                                                 continue;
905                                         }
906                                 }
907 
908                                 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
909                                         p = startswith(line, "CapEff:");
910                                         if (p) {
911                                                 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
912                                                 if (r < 0)
913                                                         return r;
914 
915                                                 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
916                                                 continue;
917                                         }
918                                 }
919 
920                                 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
921                                         p = startswith(line, "CapPrm:");
922                                         if (p) {
923                                                 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
924                                                 if (r < 0)
925                                                         return r;
926 
927                                                 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
928                                                 continue;
929                                         }
930                                 }
931 
932                                 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
933                                         p = startswith(line, "CapInh:");
934                                         if (p) {
935                                                 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
936                                                 if (r < 0)
937                                                         return r;
938 
939                                                 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
940                                                 continue;
941                                         }
942                                 }
943 
944                                 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
945                                         p = startswith(line, "CapBnd:");
946                                         if (p) {
947                                                 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
948                                                 if (r < 0)
949                                                         return r;
950 
951                                                 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
952                                                 continue;
953                                         }
954                                 }
955                         }
956                 }
957         }
958 
959         if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
960                 const char *p;
961 
962                 p = procfs_file_alloca(pid, "attr/current");
963                 r = read_one_line_file(p, &c->label);
964                 if (r < 0) {
965                         if (!IN_SET(r, -ENOENT, -EINVAL, -EPERM, -EACCES))
966                                 return r;
967                 } else
968                         c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
969         }
970 
971         if (missing & SD_BUS_CREDS_COMM) {
972                 r = get_process_comm(pid, &c->comm);
973                 if (r < 0) {
974                         if (!ERRNO_IS_PRIVILEGE(r))
975                                 return r;
976                 } else
977                         c->mask |= SD_BUS_CREDS_COMM;
978         }
979 
980         if (missing & SD_BUS_CREDS_EXE) {
981                 r = get_process_exe(pid, &c->exe);
982                 if (r == -ESRCH) {
983                         /* Unfortunately we cannot really distinguish
984                          * the case here where the process does not
985                          * exist, and /proc/$PID/exe being unreadable
986                          * because $PID is a kernel thread. Hence,
987                          * assume it is a kernel thread, and rely on
988                          * that this case is caught with a later
989                          * call. */
990                         c->exe = NULL;
991                         c->mask |= SD_BUS_CREDS_EXE;
992                 } else if (r < 0) {
993                         if (!ERRNO_IS_PRIVILEGE(r))
994                                 return r;
995                 } else
996                         c->mask |= SD_BUS_CREDS_EXE;
997         }
998 
999         if (missing & SD_BUS_CREDS_CMDLINE) {
1000                 const char *p;
1001 
1002                 p = procfs_file_alloca(pid, "cmdline");
1003                 r = read_full_virtual_file(p, &c->cmdline, &c->cmdline_size);
1004                 if (r == -ENOENT)
1005                         return -ESRCH;
1006                 if (r < 0) {
1007                         if (!ERRNO_IS_PRIVILEGE(r))
1008                                 return r;
1009                 } else {
1010                         if (c->cmdline_size == 0)
1011                                 c->cmdline = mfree(c->cmdline);
1012 
1013                         c->mask |= SD_BUS_CREDS_CMDLINE;
1014                 }
1015         }
1016 
1017         if (tid > 0 && (missing & SD_BUS_CREDS_TID_COMM)) {
1018                 _cleanup_free_ char *p = NULL;
1019 
1020                 if (asprintf(&p, "/proc/"PID_FMT"/task/"PID_FMT"/comm", pid, tid) < 0)
1021                         return -ENOMEM;
1022 
1023                 r = read_one_line_file(p, &c->tid_comm);
1024                 if (r == -ENOENT)
1025                         return -ESRCH;
1026                 if (r < 0) {
1027                         if (!ERRNO_IS_PRIVILEGE(r))
1028                                 return r;
1029                 } else
1030                         c->mask |= SD_BUS_CREDS_TID_COMM;
1031         }
1032 
1033         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)) {
1034 
1035                 if (!c->cgroup) {
1036                         r = cg_pid_get_path(NULL, pid, &c->cgroup);
1037                         if (r < 0) {
1038                                 if (!ERRNO_IS_PRIVILEGE(r))
1039                                         return r;
1040                         }
1041                 }
1042 
1043                 if (!c->cgroup_root) {
1044                         r = cg_get_root_path(&c->cgroup_root);
1045                         if (r < 0)
1046                                 return r;
1047                 }
1048 
1049                 if (c->cgroup)
1050                         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);
1051         }
1052 
1053         if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1054                 r = audit_session_from_pid(pid, &c->audit_session_id);
1055                 if (r == -ENODATA) {
1056                         /* ENODATA means: no audit session id assigned */
1057                         c->audit_session_id = AUDIT_SESSION_INVALID;
1058                         c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1059                 } else if (r < 0) {
1060                         if (!IN_SET(r, -EOPNOTSUPP, -ENOENT, -EPERM, -EACCES))
1061                                 return r;
1062                 } else
1063                         c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1064         }
1065 
1066         if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1067                 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
1068                 if (r == -ENODATA) {
1069                         /* ENODATA means: no audit login uid assigned */
1070                         c->audit_login_uid = UID_INVALID;
1071                         c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1072                 } else if (r < 0) {
1073                         if (!IN_SET(r, -EOPNOTSUPP, -ENOENT, -EPERM, -EACCES))
1074                                 return r;
1075                 } else
1076                         c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1077         }
1078 
1079         if (missing & SD_BUS_CREDS_TTY) {
1080                 r = get_ctty(pid, NULL, &c->tty);
1081                 if (r == -ENXIO) {
1082                         /* ENXIO means: process has no controlling TTY */
1083                         c->tty = NULL;
1084                         c->mask |= SD_BUS_CREDS_TTY;
1085                 } else if (r < 0) {
1086                         if (!IN_SET(r, -EPERM, -EACCES, -ENOENT))
1087                                 return r;
1088                 } else
1089                         c->mask |= SD_BUS_CREDS_TTY;
1090         }
1091 
1092         /* In case only the exe path was to be read we cannot
1093          * distinguish the case where the exe path was unreadable
1094          * because the process was a kernel thread, or when the
1095          * process didn't exist at all. Hence, let's do a final check,
1096          * to be sure. */
1097         if (!pid_is_alive(pid))
1098                 return -ESRCH;
1099 
1100         if (tid > 0 && tid != pid && !pid_is_unwaited(tid))
1101                 return -ESRCH;
1102 
1103         c->augmented = missing & c->mask;
1104 
1105         return 0;
1106 }
1107 
bus_creds_extend_by_pid(sd_bus_creds * c,uint64_t mask,sd_bus_creds ** ret)1108 int bus_creds_extend_by_pid(sd_bus_creds *c, uint64_t mask, sd_bus_creds **ret) {
1109         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *n = NULL;
1110         int r;
1111 
1112         assert(c);
1113         assert(ret);
1114 
1115         if ((mask & ~c->mask) == 0 || (!(mask & SD_BUS_CREDS_AUGMENT))) {
1116                 /* There's already all data we need, or augmentation
1117                  * wasn't turned on. */
1118 
1119                 *ret = sd_bus_creds_ref(c);
1120                 return 0;
1121         }
1122 
1123         n = bus_creds_new();
1124         if (!n)
1125                 return -ENOMEM;
1126 
1127         /* Copy the original data over */
1128 
1129         if (c->mask & mask & SD_BUS_CREDS_PID) {
1130                 n->pid = c->pid;
1131                 n->mask |= SD_BUS_CREDS_PID;
1132         }
1133 
1134         if (c->mask & mask & SD_BUS_CREDS_TID) {
1135                 n->tid = c->tid;
1136                 n->mask |= SD_BUS_CREDS_TID;
1137         }
1138 
1139         if (c->mask & mask & SD_BUS_CREDS_PPID) {
1140                 n->ppid = c->ppid;
1141                 n->mask |= SD_BUS_CREDS_PPID;
1142         }
1143 
1144         if (c->mask & mask & SD_BUS_CREDS_UID) {
1145                 n->uid = c->uid;
1146                 n->mask |= SD_BUS_CREDS_UID;
1147         }
1148 
1149         if (c->mask & mask & SD_BUS_CREDS_EUID) {
1150                 n->euid = c->euid;
1151                 n->mask |= SD_BUS_CREDS_EUID;
1152         }
1153 
1154         if (c->mask & mask & SD_BUS_CREDS_SUID) {
1155                 n->suid = c->suid;
1156                 n->mask |= SD_BUS_CREDS_SUID;
1157         }
1158 
1159         if (c->mask & mask & SD_BUS_CREDS_FSUID) {
1160                 n->fsuid = c->fsuid;
1161                 n->mask |= SD_BUS_CREDS_FSUID;
1162         }
1163 
1164         if (c->mask & mask & SD_BUS_CREDS_GID) {
1165                 n->gid = c->gid;
1166                 n->mask |= SD_BUS_CREDS_GID;
1167         }
1168 
1169         if (c->mask & mask & SD_BUS_CREDS_EGID) {
1170                 n->egid = c->egid;
1171                 n->mask |= SD_BUS_CREDS_EGID;
1172         }
1173 
1174         if (c->mask & mask & SD_BUS_CREDS_SGID) {
1175                 n->sgid = c->sgid;
1176                 n->mask |= SD_BUS_CREDS_SGID;
1177         }
1178 
1179         if (c->mask & mask & SD_BUS_CREDS_FSGID) {
1180                 n->fsgid = c->fsgid;
1181                 n->mask |= SD_BUS_CREDS_FSGID;
1182         }
1183 
1184         if (c->mask & mask & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
1185                 if (c->supplementary_gids) {
1186                         n->supplementary_gids = newdup(gid_t, c->supplementary_gids, c->n_supplementary_gids);
1187                         if (!n->supplementary_gids)
1188                                 return -ENOMEM;
1189                         n->n_supplementary_gids = c->n_supplementary_gids;
1190                 } else {
1191                         n->supplementary_gids = NULL;
1192                         n->n_supplementary_gids = 0;
1193                 }
1194 
1195                 n->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
1196         }
1197 
1198         if (c->mask & mask & SD_BUS_CREDS_COMM) {
1199                 assert(c->comm);
1200 
1201                 n->comm = strdup(c->comm);
1202                 if (!n->comm)
1203                         return -ENOMEM;
1204 
1205                 n->mask |= SD_BUS_CREDS_COMM;
1206         }
1207 
1208         if (c->mask & mask & SD_BUS_CREDS_TID_COMM) {
1209                 assert(c->tid_comm);
1210 
1211                 n->tid_comm = strdup(c->tid_comm);
1212                 if (!n->tid_comm)
1213                         return -ENOMEM;
1214 
1215                 n->mask |= SD_BUS_CREDS_TID_COMM;
1216         }
1217 
1218         if (c->mask & mask & SD_BUS_CREDS_EXE) {
1219                 if (c->exe) {
1220                         n->exe = strdup(c->exe);
1221                         if (!n->exe)
1222                                 return -ENOMEM;
1223                 } else
1224                         n->exe = NULL;
1225 
1226                 n->mask |= SD_BUS_CREDS_EXE;
1227         }
1228 
1229         if (c->mask & mask & SD_BUS_CREDS_CMDLINE) {
1230                 if (c->cmdline) {
1231                         n->cmdline = memdup(c->cmdline, c->cmdline_size);
1232                         if (!n->cmdline)
1233                                 return -ENOMEM;
1234 
1235                         n->cmdline_size = c->cmdline_size;
1236                 } else {
1237                         n->cmdline = NULL;
1238                         n->cmdline_size = 0;
1239                 }
1240 
1241                 n->mask |= SD_BUS_CREDS_CMDLINE;
1242         }
1243 
1244         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)) {
1245                 assert(c->cgroup);
1246 
1247                 n->cgroup = strdup(c->cgroup);
1248                 if (!n->cgroup)
1249                         return -ENOMEM;
1250 
1251                 n->cgroup_root = strdup(c->cgroup_root);
1252                 if (!n->cgroup_root)
1253                         return -ENOMEM;
1254 
1255                 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);
1256         }
1257 
1258         if (c->mask & mask & (SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS)) {
1259                 assert(c->capability);
1260 
1261                 n->capability = memdup(c->capability, DIV_ROUND_UP(cap_last_cap()+1, 32U) * 4 * 4);
1262                 if (!n->capability)
1263                         return -ENOMEM;
1264 
1265                 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);
1266         }
1267 
1268         if (c->mask & mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
1269                 assert(c->label);
1270 
1271                 n->label = strdup(c->label);
1272                 if (!n->label)
1273                         return -ENOMEM;
1274                 n->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
1275         }
1276 
1277         if (c->mask & mask & SD_BUS_CREDS_AUDIT_SESSION_ID) {
1278                 n->audit_session_id = c->audit_session_id;
1279                 n->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
1280         }
1281         if (c->mask & mask & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
1282                 n->audit_login_uid = c->audit_login_uid;
1283                 n->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
1284         }
1285 
1286         if (c->mask & mask & SD_BUS_CREDS_TTY) {
1287                 if (c->tty) {
1288                         n->tty = strdup(c->tty);
1289                         if (!n->tty)
1290                                 return -ENOMEM;
1291                 } else
1292                         n->tty = NULL;
1293                 n->mask |= SD_BUS_CREDS_TTY;
1294         }
1295 
1296         if (c->mask & mask & SD_BUS_CREDS_UNIQUE_NAME) {
1297                 assert(c->unique_name);
1298 
1299                 n->unique_name = strdup(c->unique_name);
1300                 if (!n->unique_name)
1301                         return -ENOMEM;
1302                 n->mask |= SD_BUS_CREDS_UNIQUE_NAME;
1303         }
1304 
1305         if (c->mask & mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
1306                 if (strv_isempty(c->well_known_names))
1307                         n->well_known_names = NULL;
1308                 else {
1309                         n->well_known_names = strv_copy(c->well_known_names);
1310                         if (!n->well_known_names)
1311                                 return -ENOMEM;
1312                 }
1313                 n->well_known_names_driver = c->well_known_names_driver;
1314                 n->well_known_names_local = c->well_known_names_local;
1315                 n->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
1316         }
1317 
1318         if (c->mask & mask & SD_BUS_CREDS_DESCRIPTION) {
1319                 assert(c->description);
1320                 n->description = strdup(c->description);
1321                 if (!n->description)
1322                         return -ENOMEM;
1323                 n->mask |= SD_BUS_CREDS_DESCRIPTION;
1324         }
1325 
1326         n->augmented = c->augmented & n->mask;
1327 
1328         /* Get more data */
1329 
1330         r = bus_creds_add_more(n, mask, 0, 0);
1331         if (r < 0)
1332                 return r;
1333 
1334         *ret = TAKE_PTR(n);
1335 
1336         return 0;
1337 }
1338