LCOV - code coverage report
Current view: top level - libsystemd/sd-bus - bus-creds.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 395 775 51.0 %
Date: 2019-08-23 13:36:53 Functions: 25 45 55.6 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 270 834 32.4 %

           Branch data     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                 :       1214 : void bus_creds_done(sd_bus_creds *c) {
      34         [ -  + ]:       1214 :         assert(c);
      35                 :            : 
      36                 :            :         /* For internal bus cred structures that are allocated by
      37                 :            :          * something else */
      38                 :            : 
      39                 :       1214 :         free(c->session);
      40                 :       1214 :         free(c->unit);
      41                 :       1214 :         free(c->user_unit);
      42                 :       1214 :         free(c->slice);
      43                 :       1214 :         free(c->user_slice);
      44                 :       1214 :         free(c->unescaped_description);
      45                 :       1214 :         free(c->supplementary_gids);
      46                 :       1214 :         free(c->tty);
      47                 :            : 
      48                 :       1214 :         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                 :       1214 :         strv_free(c->cmdline_array);
      56                 :       1214 : }
      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                 :         60 : _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
      79                 :            : 
      80         [ -  + ]:         60 :         if (!c)
      81                 :          0 :                 return NULL;
      82                 :            : 
      83         [ +  - ]:         60 :         if (c->allocated) {
      84         [ -  + ]:         60 :                 assert(c->n_ref > 0);
      85                 :         60 :                 c->n_ref--;
      86                 :            : 
      87         [ +  - ]:         60 :                 if (c->n_ref == 0) {
      88                 :         60 :                         free(c->comm);
      89                 :         60 :                         free(c->tid_comm);
      90                 :         60 :                         free(c->exe);
      91                 :         60 :                         free(c->cmdline);
      92                 :         60 :                         free(c->cgroup);
      93                 :         60 :                         free(c->capability);
      94                 :         60 :                         free(c->label);
      95                 :         60 :                         free(c->unique_name);
      96                 :         60 :                         free(c->cgroup_root);
      97                 :         60 :                         free(c->description);
      98                 :            : 
      99                 :         60 :                         c->supplementary_gids = mfree(c->supplementary_gids);
     100                 :            : 
     101                 :         60 :                         c->well_known_names = strv_free(c->well_known_names);
     102                 :            : 
     103                 :         60 :                         bus_creds_done(c);
     104                 :            : 
     105                 :         60 :                         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                 :         60 :         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                 :        104 : _public_ uint64_t sd_bus_creds_get_augmented_mask(const sd_bus_creds *c) {
     124   [ -  +  -  + ]:        104 :         assert_return(c, 0);
     125                 :            : 
     126                 :        104 :         return c->augmented;
     127                 :            : }
     128                 :            : 
     129                 :         60 : sd_bus_creds* bus_creds_new(void) {
     130                 :            :         sd_bus_creds *c;
     131                 :            : 
     132                 :         60 :         c = new0(sd_bus_creds, 1);
     133         [ -  + ]:         60 :         if (!c)
     134                 :          0 :                 return NULL;
     135                 :            : 
     136                 :         60 :         c->allocated = true;
     137                 :         60 :         c->n_ref = 1;
     138                 :         60 :         return c;
     139                 :            : }
     140                 :            : 
     141                 :          8 : _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   [ -  +  -  + ]:          8 :         assert_return(pid >= 0, -EINVAL);
     146   [ -  +  -  + ]:          8 :         assert_return(mask <= _SD_BUS_CREDS_ALL, -EOPNOTSUPP);
     147   [ -  +  -  + ]:          8 :         assert_return(ret, -EINVAL);
     148                 :            : 
     149         [ +  + ]:          8 :         if (pid == 0)
     150                 :          4 :                 pid = getpid_cached();
     151                 :            : 
     152                 :          8 :         c = bus_creds_new();
     153         [ -  + ]:          8 :         if (!c)
     154                 :          0 :                 return -ENOMEM;
     155                 :            : 
     156                 :          8 :         r = bus_creds_add_more(c, mask | SD_BUS_CREDS_AUGMENT, pid, 0);
     157         [ -  + ]:          8 :         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         [ -  + ]:          8 :         if (!pid_is_alive(pid)) {
     165                 :          0 :                 sd_bus_creds_unref(c);
     166                 :          0 :                 return -ESRCH;
     167                 :            :         }
     168                 :            : 
     169                 :          8 :         *ret = c;
     170                 :          8 :         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                 :         52 : _public_ int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid) {
     185   [ -  +  -  + ]:         52 :         assert_return(c, -EINVAL);
     186   [ -  +  -  + ]:         52 :         assert_return(euid, -EINVAL);
     187                 :            : 
     188         [ -  + ]:         52 :         if (!(c->mask & SD_BUS_CREDS_EUID))
     189                 :          0 :                 return -ENODATA;
     190                 :            : 
     191                 :         52 :         *euid = c->euid;
     192                 :         52 :         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                 :         48 : _public_ int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid) {
     273   [ +  +  +  + ]:         48 :         assert_return(c, -EINVAL);
     274   [ -  +  -  + ]:         28 :         assert_return(pid, -EINVAL);
     275                 :            : 
     276         [ +  - ]:         28 :         if (!(c->mask & SD_BUS_CREDS_PID))
     277                 :         28 :                 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                 :         48 : _public_ int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **ret) {
     314   [ +  +  +  + ]:         48 :         assert_return(c, -EINVAL);
     315                 :            : 
     316         [ +  - ]:         28 :         if (!(c->mask & SD_BUS_CREDS_SELINUX_CONTEXT))
     317                 :         28 :                 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                 :         60 : _public_ int sd_bus_creds_get_unit(sd_bus_creds *c, const char **ret) {
     375                 :            :         int r;
     376                 :            : 
     377   [ -  +  -  + ]:         60 :         assert_return(c, -EINVAL);
     378   [ -  +  -  + ]:         60 :         assert_return(ret, -EINVAL);
     379                 :            : 
     380         [ +  + ]:         60 :         if (!(c->mask & SD_BUS_CREDS_UNIT))
     381                 :         52 :                 return -ENODATA;
     382                 :            : 
     383         [ -  + ]:          8 :         assert(c->cgroup);
     384                 :            : 
     385         [ +  - ]:          8 :         if (!c->unit) {
     386                 :            :                 const char *shifted;
     387                 :            : 
     388                 :          8 :                 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
     389         [ -  + ]:          8 :                 if (r < 0)
     390                 :          0 :                         return r;
     391                 :            : 
     392                 :          8 :                 r = cg_path_get_unit(shifted, (char**) &c->unit);
     393         [ -  + ]:          8 :                 if (r < 0)
     394                 :          0 :                         return r;
     395                 :            :         }
     396                 :            : 
     397                 :          8 :         *ret = c->unit;
     398                 :          8 :         return 0;
     399                 :            : }
     400                 :            : 
     401                 :         60 : _public_ int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **ret) {
     402                 :            :         int r;
     403                 :            : 
     404   [ -  +  -  + ]:         60 :         assert_return(c, -EINVAL);
     405   [ -  +  -  + ]:         60 :         assert_return(ret, -EINVAL);
     406                 :            : 
     407         [ +  + ]:         60 :         if (!(c->mask & SD_BUS_CREDS_USER_UNIT))
     408                 :         52 :                 return -ENODATA;
     409                 :            : 
     410         [ -  + ]:          8 :         assert(c->cgroup);
     411                 :            : 
     412         [ +  - ]:          8 :         if (!c->user_unit) {
     413                 :            :                 const char *shifted;
     414                 :            : 
     415                 :          8 :                 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
     416         [ -  + ]:          8 :                 if (r < 0)
     417                 :          8 :                         return r;
     418                 :            : 
     419                 :          8 :                 r = cg_path_get_user_unit(shifted, (char**) &c->user_unit);
     420         [ +  - ]:          8 :                 if (r < 0)
     421                 :          8 :                         return r;
     422                 :            :         }
     423                 :            : 
     424                 :          0 :         *ret = c->user_unit;
     425                 :          0 :         return 0;
     426                 :            : }
     427                 :            : 
     428                 :         60 : _public_ int sd_bus_creds_get_slice(sd_bus_creds *c, const char **ret) {
     429                 :            :         int r;
     430                 :            : 
     431   [ -  +  -  + ]:         60 :         assert_return(c, -EINVAL);
     432   [ -  +  -  + ]:         60 :         assert_return(ret, -EINVAL);
     433                 :            : 
     434         [ +  + ]:         60 :         if (!(c->mask & SD_BUS_CREDS_SLICE))
     435                 :         52 :                 return -ENODATA;
     436                 :            : 
     437         [ -  + ]:          8 :         assert(c->cgroup);
     438                 :            : 
     439         [ +  - ]:          8 :         if (!c->slice) {
     440                 :            :                 const char *shifted;
     441                 :            : 
     442                 :          8 :                 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
     443         [ -  + ]:          8 :                 if (r < 0)
     444                 :          0 :                         return r;
     445                 :            : 
     446                 :          8 :                 r = cg_path_get_slice(shifted, (char**) &c->slice);
     447         [ -  + ]:          8 :                 if (r < 0)
     448                 :          0 :                         return r;
     449                 :            :         }
     450                 :            : 
     451                 :          8 :         *ret = c->slice;
     452                 :          8 :         return 0;
     453                 :            : }
     454                 :            : 
     455                 :         60 : _public_ int sd_bus_creds_get_user_slice(sd_bus_creds *c, const char **ret) {
     456                 :            :         int r;
     457                 :            : 
     458   [ -  +  -  + ]:         60 :         assert_return(c, -EINVAL);
     459   [ -  +  -  + ]:         60 :         assert_return(ret, -EINVAL);
     460                 :            : 
     461         [ +  + ]:         60 :         if (!(c->mask & SD_BUS_CREDS_USER_SLICE))
     462                 :         52 :                 return -ENODATA;
     463                 :            : 
     464         [ -  + ]:          8 :         assert(c->cgroup);
     465                 :            : 
     466         [ +  - ]:          8 :         if (!c->user_slice) {
     467                 :            :                 const char *shifted;
     468                 :            : 
     469                 :          8 :                 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
     470         [ -  + ]:          8 :                 if (r < 0)
     471                 :          4 :                         return r;
     472                 :            : 
     473                 :          8 :                 r = cg_path_get_user_slice(shifted, (char**) &c->user_slice);
     474         [ +  + ]:          8 :                 if (r < 0)
     475                 :          4 :                         return r;
     476                 :            :         }
     477                 :            : 
     478                 :          4 :         *ret = c->user_slice;
     479                 :          4 :         return 0;
     480                 :            : }
     481                 :            : 
     482                 :         60 : _public_ int sd_bus_creds_get_session(sd_bus_creds *c, const char **ret) {
     483                 :            :         int r;
     484                 :            : 
     485   [ -  +  -  + ]:         60 :         assert_return(c, -EINVAL);
     486   [ -  +  -  + ]:         60 :         assert_return(ret, -EINVAL);
     487                 :            : 
     488         [ +  + ]:         60 :         if (!(c->mask & SD_BUS_CREDS_SESSION))
     489                 :         52 :                 return -ENODATA;
     490                 :            : 
     491         [ -  + ]:          8 :         assert(c->cgroup);
     492                 :            : 
     493         [ +  - ]:          8 :         if (!c->session) {
     494                 :            :                 const char *shifted;
     495                 :            : 
     496                 :          8 :                 r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
     497         [ -  + ]:          8 :                 if (r < 0)
     498                 :          4 :                         return r;
     499                 :            : 
     500                 :          8 :                 r = cg_path_get_session(shifted, (char**) &c->session);
     501         [ +  + ]:          8 :                 if (r < 0)
     502                 :          4 :                         return r;
     503                 :            :         }
     504                 :            : 
     505                 :          4 :         *ret = c->session;
     506                 :          4 :         return 0;
     507                 :            : }
     508                 :            : 
     509                 :         60 : _public_ int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid) {
     510                 :            :         const char *shifted;
     511                 :            :         int r;
     512                 :            : 
     513   [ -  +  -  + ]:         60 :         assert_return(c, -EINVAL);
     514   [ -  +  -  + ]:         60 :         assert_return(uid, -EINVAL);
     515                 :            : 
     516         [ +  + ]:         60 :         if (!(c->mask & SD_BUS_CREDS_OWNER_UID))
     517                 :         52 :                 return -ENODATA;
     518                 :            : 
     519         [ -  + ]:          8 :         assert(c->cgroup);
     520                 :            : 
     521                 :          8 :         r = cg_shift_path(c->cgroup, c->cgroup_root, &shifted);
     522         [ -  + ]:          8 :         if (r < 0)
     523                 :          0 :                 return r;
     524                 :            : 
     525                 :          8 :         return cg_path_get_owner_uid(shifted, uid);
     526                 :            : }
     527                 :            : 
     528                 :         60 : _public_ int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline) {
     529   [ -  +  -  + ]:         60 :         assert_return(c, -EINVAL);
     530                 :            : 
     531         [ +  + ]:         60 :         if (!(c->mask & SD_BUS_CREDS_CMDLINE))
     532                 :         52 :                 return -ENODATA;
     533                 :            : 
     534         [ -  + ]:          8 :         if (!c->cmdline)
     535                 :          0 :                 return -ENXIO;
     536                 :            : 
     537         [ +  - ]:          8 :         if (!c->cmdline_array) {
     538                 :          8 :                 c->cmdline_array = strv_parse_nulstr(c->cmdline, c->cmdline_size);
     539         [ -  + ]:          8 :                 if (!c->cmdline_array)
     540                 :          0 :                         return -ENOMEM;
     541                 :            :         }
     542                 :            : 
     543                 :          8 :         *cmdline = c->cmdline_array;
     544                 :          8 :         return 0;
     545                 :            : }
     546                 :            : 
     547                 :         60 : _public_ int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid) {
     548   [ -  +  -  + ]:         60 :         assert_return(c, -EINVAL);
     549   [ -  +  -  + ]:         60 :         assert_return(sessionid, -EINVAL);
     550                 :            : 
     551         [ +  + ]:         60 :         if (!(c->mask & SD_BUS_CREDS_AUDIT_SESSION_ID))
     552                 :         52 :                 return -ENODATA;
     553                 :            : 
     554         [ +  + ]:          8 :         if (!audit_session_is_valid(c->audit_session_id))
     555                 :          4 :                 return -ENXIO;
     556                 :            : 
     557                 :          4 :         *sessionid = c->audit_session_id;
     558                 :          4 :         return 0;
     559                 :            : }
     560                 :            : 
     561                 :         60 : _public_ int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *uid) {
     562   [ -  +  -  + ]:         60 :         assert_return(c, -EINVAL);
     563   [ -  +  -  + ]:         60 :         assert_return(uid, -EINVAL);
     564                 :            : 
     565         [ +  + ]:         60 :         if (!(c->mask & SD_BUS_CREDS_AUDIT_LOGIN_UID))
     566                 :         52 :                 return -ENODATA;
     567                 :            : 
     568         [ +  + ]:          8 :         if (!uid_is_valid(c->audit_login_uid))
     569                 :          4 :                 return -ENXIO;
     570                 :            : 
     571                 :          4 :         *uid = c->audit_login_uid;
     572                 :          4 :         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                 :         60 : _public_ int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***well_known_names) {
     601   [ -  +  -  + ]:         60 :         assert_return(c, -EINVAL);
     602   [ -  +  -  + ]:         60 :         assert_return(well_known_names, -EINVAL);
     603                 :            : 
     604         [ +  - ]:         60 :         if (!(c->mask & SD_BUS_CREDS_WELL_KNOWN_NAMES))
     605                 :         60 :                 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                 :       1216 : static int has_cap(sd_bus_creds *c, size_t offset, int capability) {
     653                 :            :         unsigned long lc;
     654                 :            :         size_t sz;
     655                 :            : 
     656         [ -  + ]:       1216 :         assert(c);
     657         [ -  + ]:       1216 :         assert(capability >= 0);
     658         [ -  + ]:       1216 :         assert(c->capability);
     659                 :            : 
     660                 :       1216 :         lc = cap_last_cap();
     661                 :            : 
     662         [ -  + ]:       1216 :         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                 :       1216 :         sz = DIV_ROUND_UP(lc+1, 32LU);
     668                 :            : 
     669                 :       1216 :         return !!(c->capability[offset * sz + CAP_TO_INDEX((uint32_t) capability)] & CAP_TO_MASK_CORRECTED((uint32_t) capability));
     670                 :            : }
     671                 :            : 
     672                 :        408 : _public_ int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability) {
     673   [ -  +  -  + ]:        408 :         assert_return(c, -EINVAL);
     674   [ -  +  -  + ]:        408 :         assert_return(capability >= 0, -EINVAL);
     675                 :            : 
     676         [ +  + ]:        408 :         if (!(c->mask & SD_BUS_CREDS_EFFECTIVE_CAPS))
     677                 :        104 :                 return -ENODATA;
     678                 :            : 
     679                 :        304 :         return has_cap(c, CAP_OFFSET_EFFECTIVE, capability);
     680                 :            : }
     681                 :            : 
     682                 :        356 : _public_ int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability) {
     683   [ -  +  -  + ]:        356 :         assert_return(c, -EINVAL);
     684   [ -  +  -  + ]:        356 :         assert_return(capability >= 0, -EINVAL);
     685                 :            : 
     686         [ +  + ]:        356 :         if (!(c->mask & SD_BUS_CREDS_PERMITTED_CAPS))
     687                 :         52 :                 return -ENODATA;
     688                 :            : 
     689                 :        304 :         return has_cap(c, CAP_OFFSET_PERMITTED, capability);
     690                 :            : }
     691                 :            : 
     692                 :        356 : _public_ int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability) {
     693   [ -  +  -  + ]:        356 :         assert_return(c, -EINVAL);
     694   [ -  +  -  + ]:        356 :         assert_return(capability >= 0, -EINVAL);
     695                 :            : 
     696         [ +  + ]:        356 :         if (!(c->mask & SD_BUS_CREDS_INHERITABLE_CAPS))
     697                 :         52 :                 return -ENODATA;
     698                 :            : 
     699                 :        304 :         return has_cap(c, CAP_OFFSET_INHERITABLE, capability);
     700                 :            : }
     701                 :            : 
     702                 :        356 : _public_ int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability) {
     703   [ -  +  -  + ]:        356 :         assert_return(c, -EINVAL);
     704   [ -  +  -  + ]:        356 :         assert_return(capability >= 0, -EINVAL);
     705                 :            : 
     706         [ +  + ]:        356 :         if (!(c->mask & SD_BUS_CREDS_BOUNDING_CAPS))
     707                 :         52 :                 return -ENODATA;
     708                 :            : 
     709                 :        304 :         return has_cap(c, CAP_OFFSET_BOUNDING, capability);
     710                 :            : }
     711                 :            : 
     712                 :         32 : static int parse_caps(sd_bus_creds *c, unsigned offset, const char *p) {
     713                 :            :         size_t sz, max;
     714                 :            :         unsigned i, j;
     715                 :            : 
     716         [ -  + ]:         32 :         assert(c);
     717         [ -  + ]:         32 :         assert(p);
     718                 :            : 
     719                 :         32 :         max = DIV_ROUND_UP(cap_last_cap()+1, 32U);
     720                 :         32 :         p += strspn(p, WHITESPACE);
     721                 :            : 
     722                 :         32 :         sz = strlen(p);
     723         [ -  + ]:         32 :         if (sz % 8 != 0)
     724                 :          0 :                 return -EINVAL;
     725                 :            : 
     726                 :         32 :         sz /= 8;
     727         [ -  + ]:         32 :         if (sz > max)
     728                 :          0 :                 return -EINVAL;
     729                 :            : 
     730         [ +  + ]:         32 :         if (!c->capability) {
     731         [ +  - ]:          8 :                 c->capability = new0(uint32_t, max * 4);
     732         [ -  + ]:          8 :                 if (!c->capability)
     733                 :          0 :                         return -ENOMEM;
     734                 :            :         }
     735                 :            : 
     736         [ +  + ]:         96 :         for (i = 0; i < sz; i ++) {
     737                 :         64 :                 uint32_t v = 0;
     738                 :            : 
     739         [ +  + ]:        576 :                 for (j = 0; j < 8; ++j) {
     740                 :            :                         int t;
     741                 :            : 
     742                 :        512 :                         t = unhexchar(*p++);
     743         [ -  + ]:        512 :                         if (t < 0)
     744                 :          0 :                                 return -EINVAL;
     745                 :            : 
     746                 :        512 :                         v = (v << 4) | t;
     747                 :            :                 }
     748                 :            : 
     749                 :         64 :                 c->capability[offset * max + (sz - i - 1)] = v;
     750                 :            :         }
     751                 :            : 
     752                 :         32 :         return 0;
     753                 :            : }
     754                 :            : 
     755                 :         60 : 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         [ -  + ]:         60 :         assert(c);
     760         [ -  + ]:         60 :         assert(c->allocated);
     761                 :            : 
     762         [ +  + ]:         60 :         if (!(mask & SD_BUS_CREDS_AUGMENT))
     763                 :         52 :                 return 0;
     764                 :            : 
     765                 :            :         /* Try to retrieve PID from creds if it wasn't passed to us */
     766         [ +  - ]:          8 :         if (pid > 0) {
     767                 :          8 :                 c->pid = pid;
     768                 :          8 :                 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   [ +  -  -  + ]:          8 :         if (tid <= 0 && (c->mask & SD_BUS_CREDS_TID))
     777                 :          0 :                 tid = c->tid;
     778                 :            : 
     779                 :            :         /* Calculate what we shall and can add */
     780                 :          8 :         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         [ -  + ]:          8 :         if (missing == 0)
     782                 :          0 :                 return 0;
     783                 :            : 
     784         [ -  + ]:          8 :         if (tid > 0) {
     785                 :          0 :                 c->tid = tid;
     786                 :          0 :                 c->mask |= SD_BUS_CREDS_TID;
     787                 :            :         }
     788                 :            : 
     789         [ +  - ]:          8 :         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         [ +  - ]:          8 :                 _cleanup_fclose_ FILE *f = NULL;
     797                 :            :                 const char *p;
     798                 :            : 
     799   [ -  +  -  +  :          8 :                 p = procfs_file_alloca(pid, "status");
                   -  + ]
     800                 :            : 
     801                 :          8 :                 f = fopen(p, "re");
     802         [ -  + ]:          8 :                 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                 :        440 :                         for (;;) {
     810   [ +  -  +  + ]:        448 :                                 _cleanup_free_ char *line = NULL;
     811                 :            : 
     812                 :        448 :                                 r = read_line(f, LONG_LINE_MAX, &line);
     813         [ -  + ]:        448 :                                 if (r < 0)
     814                 :          0 :                                         return r;
     815         [ +  + ]:        448 :                                 if (r == 0)
     816                 :          8 :                                         break;
     817                 :            : 
     818         [ +  - ]:        440 :                                 if (missing & SD_BUS_CREDS_PPID) {
     819                 :        440 :                                         p = startswith(line, "PPid:");
     820         [ +  + ]:        440 :                                         if (p) {
     821                 :          8 :                                                 p += strspn(p, WHITESPACE);
     822                 :            : 
     823                 :            :                                                 /* Explicitly check for PPID 0 (which is the case for PID 1) */
     824         [ +  + ]:          8 :                                                 if (!streq(p, "0")) {
     825                 :          4 :                                                         r = parse_pid(p, &c->ppid);
     826         [ -  + ]:          4 :                                                         if (r < 0)
     827                 :          0 :                                                                 return r;
     828                 :            : 
     829                 :            :                                                 } else
     830                 :          4 :                                                         c->ppid = 0;
     831                 :            : 
     832                 :          8 :                                                 c->mask |= SD_BUS_CREDS_PPID;
     833                 :          8 :                                                 continue;
     834                 :            :                                         }
     835                 :            :                                 }
     836                 :            : 
     837         [ +  - ]:        432 :                                 if (missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID)) {
     838                 :        432 :                                         p = startswith(line, "Uid:");
     839         [ +  + ]:        432 :                                         if (p) {
     840                 :            :                                                 unsigned long uid, euid, suid, fsuid;
     841                 :            : 
     842                 :          8 :                                                 p += strspn(p, WHITESPACE);
     843         [ -  + ]:          8 :                                                 if (sscanf(p, "%lu %lu %lu %lu", &uid, &euid, &suid, &fsuid) != 4)
     844                 :          0 :                                                         return -EIO;
     845                 :            : 
     846         [ +  - ]:          8 :                                                 if (missing & SD_BUS_CREDS_UID)
     847                 :          8 :                                                         c->uid = (uid_t) uid;
     848         [ +  - ]:          8 :                                                 if (missing & SD_BUS_CREDS_EUID)
     849                 :          8 :                                                         c->euid = (uid_t) euid;
     850         [ +  - ]:          8 :                                                 if (missing & SD_BUS_CREDS_SUID)
     851                 :          8 :                                                         c->suid = (uid_t) suid;
     852         [ +  - ]:          8 :                                                 if (missing & SD_BUS_CREDS_FSUID)
     853                 :          8 :                                                         c->fsuid = (uid_t) fsuid;
     854                 :            : 
     855                 :          8 :                                                 c->mask |= missing & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID);
     856                 :          8 :                                                 continue;
     857                 :            :                                         }
     858                 :            :                                 }
     859                 :            : 
     860         [ +  - ]:        424 :                                 if (missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID)) {
     861                 :        424 :                                         p = startswith(line, "Gid:");
     862         [ +  + ]:        424 :                                         if (p) {
     863                 :            :                                                 unsigned long gid, egid, sgid, fsgid;
     864                 :            : 
     865                 :          8 :                                                 p += strspn(p, WHITESPACE);
     866         [ -  + ]:          8 :                                                 if (sscanf(p, "%lu %lu %lu %lu", &gid, &egid, &sgid, &fsgid) != 4)
     867                 :          0 :                                                         return -EIO;
     868                 :            : 
     869         [ +  - ]:          8 :                                                 if (missing & SD_BUS_CREDS_GID)
     870                 :          8 :                                                         c->gid = (gid_t) gid;
     871         [ +  - ]:          8 :                                                 if (missing & SD_BUS_CREDS_EGID)
     872                 :          8 :                                                         c->egid = (gid_t) egid;
     873         [ +  - ]:          8 :                                                 if (missing & SD_BUS_CREDS_SGID)
     874                 :          8 :                                                         c->sgid = (gid_t) sgid;
     875         [ +  - ]:          8 :                                                 if (missing & SD_BUS_CREDS_FSGID)
     876                 :          8 :                                                         c->fsgid = (gid_t) fsgid;
     877                 :            : 
     878                 :          8 :                                                 c->mask |= missing & (SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID);
     879                 :          8 :                                                 continue;
     880                 :            :                                         }
     881                 :            :                                 }
     882                 :            : 
     883         [ +  - ]:        416 :                                 if (missing & SD_BUS_CREDS_SUPPLEMENTARY_GIDS) {
     884                 :        416 :                                         p = startswith(line, "Groups:");
     885         [ +  + ]:        416 :                                         if (p) {
     886                 :          8 :                                                 size_t allocated = 0;
     887                 :            : 
     888                 :         36 :                                                 for (;;) {
     889                 :            :                                                         unsigned long g;
     890                 :         44 :                                                         int n = 0;
     891                 :            : 
     892                 :         44 :                                                         p += strspn(p, WHITESPACE);
     893         [ +  + ]:         44 :                                                         if (*p == 0)
     894                 :          8 :                                                                 break;
     895                 :            : 
     896         [ -  + ]:         36 :                                                         if (sscanf(p, "%lu%n", &g, &n) != 1)
     897                 :          0 :                                                                 return -EIO;
     898                 :            : 
     899         [ -  + ]:         36 :                                                         if (!GREEDY_REALLOC(c->supplementary_gids, allocated, c->n_supplementary_gids+1))
     900                 :          0 :                                                                 return -ENOMEM;
     901                 :            : 
     902                 :         36 :                                                         c->supplementary_gids[c->n_supplementary_gids++] = (gid_t) g;
     903                 :         36 :                                                         p += n;
     904                 :            :                                                 }
     905                 :            : 
     906                 :          8 :                                                 c->mask |= SD_BUS_CREDS_SUPPLEMENTARY_GIDS;
     907                 :          8 :                                                 continue;
     908                 :            :                                         }
     909                 :            :                                 }
     910                 :            : 
     911         [ +  - ]:        408 :                                 if (missing & SD_BUS_CREDS_EFFECTIVE_CAPS) {
     912                 :        408 :                                         p = startswith(line, "CapEff:");
     913         [ +  + ]:        408 :                                         if (p) {
     914                 :          8 :                                                 r = parse_caps(c, CAP_OFFSET_EFFECTIVE, p);
     915         [ -  + ]:          8 :                                                 if (r < 0)
     916                 :          0 :                                                         return r;
     917                 :            : 
     918                 :          8 :                                                 c->mask |= SD_BUS_CREDS_EFFECTIVE_CAPS;
     919                 :          8 :                                                 continue;
     920                 :            :                                         }
     921                 :            :                                 }
     922                 :            : 
     923         [ +  - ]:        400 :                                 if (missing & SD_BUS_CREDS_PERMITTED_CAPS) {
     924                 :        400 :                                         p = startswith(line, "CapPrm:");
     925         [ +  + ]:        400 :                                         if (p) {
     926                 :          8 :                                                 r = parse_caps(c, CAP_OFFSET_PERMITTED, p);
     927         [ -  + ]:          8 :                                                 if (r < 0)
     928                 :          0 :                                                         return r;
     929                 :            : 
     930                 :          8 :                                                 c->mask |= SD_BUS_CREDS_PERMITTED_CAPS;
     931                 :          8 :                                                 continue;
     932                 :            :                                         }
     933                 :            :                                 }
     934                 :            : 
     935         [ +  - ]:        392 :                                 if (missing & SD_BUS_CREDS_INHERITABLE_CAPS) {
     936                 :        392 :                                         p = startswith(line, "CapInh:");
     937         [ +  + ]:        392 :                                         if (p) {
     938                 :          8 :                                                 r = parse_caps(c, CAP_OFFSET_INHERITABLE, p);
     939         [ -  + ]:          8 :                                                 if (r < 0)
     940                 :          0 :                                                         return r;
     941                 :            : 
     942                 :          8 :                                                 c->mask |= SD_BUS_CREDS_INHERITABLE_CAPS;
     943                 :          8 :                                                 continue;
     944                 :            :                                         }
     945                 :            :                                 }
     946                 :            : 
     947         [ +  - ]:        384 :                                 if (missing & SD_BUS_CREDS_BOUNDING_CAPS) {
     948                 :        384 :                                         p = startswith(line, "CapBnd:");
     949         [ +  + ]:        384 :                                         if (p) {
     950                 :          8 :                                                 r = parse_caps(c, CAP_OFFSET_BOUNDING, p);
     951         [ -  + ]:          8 :                                                 if (r < 0)
     952                 :          0 :                                                         return r;
     953                 :            : 
     954                 :          8 :                                                 c->mask |= SD_BUS_CREDS_BOUNDING_CAPS;
     955                 :          8 :                                                 continue;
     956                 :            :                                         }
     957                 :            :                                 }
     958                 :            :                         }
     959                 :            :                 }
     960                 :            :         }
     961                 :            : 
     962         [ +  - ]:          8 :         if (missing & SD_BUS_CREDS_SELINUX_CONTEXT) {
     963                 :            :                 const char *p;
     964                 :            : 
     965   [ -  +  -  +  :          8 :                 p = procfs_file_alloca(pid, "attr/current");
                   -  + ]
     966                 :          8 :                 r = read_one_line_file(p, &c->label);
     967         [ -  + ]:          8 :                 if (r < 0) {
     968   [ #  #  #  # ]:          0 :                         if (!IN_SET(r, -ENOENT, -EINVAL, -EPERM, -EACCES))
     969                 :          0 :                                 return r;
     970                 :            :                 } else
     971                 :          8 :                         c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
     972                 :            :         }
     973                 :            : 
     974         [ +  - ]:          8 :         if (missing & SD_BUS_CREDS_COMM) {
     975                 :          8 :                 r = get_process_comm(pid, &c->comm);
     976         [ -  + ]:          8 :                 if (r < 0) {
     977   [ #  #  #  # ]:          0 :                         if (!IN_SET(r, -EPERM, -EACCES))
     978                 :          0 :                                 return r;
     979                 :            :                 } else
     980                 :          8 :                         c->mask |= SD_BUS_CREDS_COMM;
     981                 :            :         }
     982                 :            : 
     983         [ +  - ]:          8 :         if (missing & SD_BUS_CREDS_EXE) {
     984                 :          8 :                 r = get_process_exe(pid, &c->exe);
     985         [ -  + ]:          8 :                 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         [ +  + ]:          8 :                 } else if (r < 0) {
     996   [ +  -  -  + ]:          4 :                         if (!IN_SET(r, -EPERM, -EACCES))
     997                 :          0 :                                 return r;
     998                 :            :                 } else
     999                 :          4 :                         c->mask |= SD_BUS_CREDS_EXE;
    1000                 :            :         }
    1001                 :            : 
    1002         [ +  - ]:          8 :         if (missing & SD_BUS_CREDS_CMDLINE) {
    1003                 :            :                 const char *p;
    1004                 :            : 
    1005   [ -  +  -  +  :          8 :                 p = procfs_file_alloca(pid, "cmdline");
                   -  + ]
    1006                 :          8 :                 r = read_full_file(p, &c->cmdline, &c->cmdline_size);
    1007         [ -  + ]:          8 :                 if (r == -ENOENT)
    1008                 :          0 :                         return -ESRCH;
    1009         [ -  + ]:          8 :                 if (r < 0) {
    1010   [ #  #  #  # ]:          0 :                         if (!IN_SET(r, -EPERM, -EACCES))
    1011                 :          0 :                                 return r;
    1012                 :            :                 } else {
    1013         [ -  + ]:          8 :                         if (c->cmdline_size == 0)
    1014                 :          0 :                                 c->cmdline = mfree(c->cmdline);
    1015                 :            : 
    1016                 :          8 :                         c->mask |= SD_BUS_CREDS_CMDLINE;
    1017                 :            :                 }
    1018                 :            :         }
    1019                 :            : 
    1020   [ -  +  #  # ]:          8 :         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         [ +  - ]:          8 :         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         [ +  - ]:          8 :                 if (!c->cgroup) {
    1039                 :          8 :                         r = cg_pid_get_path(NULL, pid, &c->cgroup);
    1040         [ -  + ]:          8 :                         if (r < 0) {
    1041   [ #  #  #  # ]:          0 :                                 if (!IN_SET(r, -EPERM, -EACCES))
    1042                 :          0 :                                         return r;
    1043                 :            :                         }
    1044                 :            :                 }
    1045                 :            : 
    1046         [ +  - ]:          8 :                 if (!c->cgroup_root) {
    1047                 :          8 :                         r = cg_get_root_path(&c->cgroup_root);
    1048         [ -  + ]:          8 :                         if (r < 0)
    1049                 :          0 :                                 return r;
    1050                 :            :                 }
    1051                 :            : 
    1052         [ +  - ]:          8 :                 if (c->cgroup)
    1053                 :          8 :                         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         [ +  - ]:          8 :         if (missing & SD_BUS_CREDS_AUDIT_SESSION_ID) {
    1057                 :          8 :                 r = audit_session_from_pid(pid, &c->audit_session_id);
    1058         [ +  + ]:          8 :                 if (r == -ENODATA) {
    1059                 :            :                         /* ENODATA means: no audit session id assigned */
    1060                 :          4 :                         c->audit_session_id = AUDIT_SESSION_INVALID;
    1061                 :          4 :                         c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
    1062         [ -  + ]:          4 :                 } else if (r < 0) {
    1063   [ #  #  #  # ]:          0 :                         if (!IN_SET(r, -EOPNOTSUPP, -ENOENT, -EPERM, -EACCES))
    1064                 :          0 :                                 return r;
    1065                 :            :                 } else
    1066                 :          4 :                         c->mask |= SD_BUS_CREDS_AUDIT_SESSION_ID;
    1067                 :            :         }
    1068                 :            : 
    1069         [ +  - ]:          8 :         if (missing & SD_BUS_CREDS_AUDIT_LOGIN_UID) {
    1070                 :          8 :                 r = audit_loginuid_from_pid(pid, &c->audit_login_uid);
    1071         [ +  + ]:          8 :                 if (r == -ENODATA) {
    1072                 :            :                         /* ENODATA means: no audit login uid assigned */
    1073                 :          4 :                         c->audit_login_uid = UID_INVALID;
    1074                 :          4 :                         c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
    1075         [ -  + ]:          4 :                 } else if (r < 0) {
    1076   [ #  #  #  # ]:          0 :                         if (!IN_SET(r, -EOPNOTSUPP, -ENOENT, -EPERM, -EACCES))
    1077                 :          0 :                                 return r;
    1078                 :            :                 } else
    1079                 :          4 :                         c->mask |= SD_BUS_CREDS_AUDIT_LOGIN_UID;
    1080                 :            :         }
    1081                 :            : 
    1082         [ +  - ]:          8 :         if (missing & SD_BUS_CREDS_TTY) {
    1083                 :          8 :                 r = get_ctty(pid, NULL, &c->tty);
    1084         [ +  - ]:          8 :                 if (r == -ENXIO) {
    1085                 :            :                         /* ENXIO means: process has no controlling TTY */
    1086                 :          8 :                         c->tty = NULL;
    1087                 :          8 :                         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         [ -  + ]:          8 :         if (!pid_is_alive(pid))
    1101                 :          0 :                 return -ESRCH;
    1102                 :            : 
    1103   [ -  +  #  #  :          8 :         if (tid > 0 && tid != pid && !pid_is_unwaited(tid))
                   #  # ]
    1104                 :          0 :                 return -ESRCH;
    1105                 :            : 
    1106                 :          8 :         c->augmented = missing & c->mask;
    1107                 :            : 
    1108                 :          8 :         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