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