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