LCOV - code coverage report
Current view: top level - libsystemd/sd-bus - bus-creds.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 395 775 51.0 %
Date: 2019-08-22 15:41:25 Functions: 25 45 55.6 %

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

Generated by: LCOV version 1.14