LCOV - code coverage report
Current view: top level - core - dbus-execute.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 0 1295 0.0 %
Date: 2019-08-23 13:36:53 Functions: 0 60 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 1316 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <sys/mount.h>
       4                 :            : #include <sys/prctl.h>
       5                 :            : 
       6                 :            : #if HAVE_SECCOMP
       7                 :            : #include <seccomp.h>
       8                 :            : #endif
       9                 :            : 
      10                 :            : #include "af-list.h"
      11                 :            : #include "alloc-util.h"
      12                 :            : #include "bus-util.h"
      13                 :            : #include "cap-list.h"
      14                 :            : #include "capability-util.h"
      15                 :            : #include "cpu-set-util.h"
      16                 :            : #include "dbus-execute.h"
      17                 :            : #include "dbus-util.h"
      18                 :            : #include "env-util.h"
      19                 :            : #include "errno-list.h"
      20                 :            : #include "escape.h"
      21                 :            : #include "execute.h"
      22                 :            : #include "fd-util.h"
      23                 :            : #include "fileio.h"
      24                 :            : #include "hexdecoct.h"
      25                 :            : #include "io-util.h"
      26                 :            : #include "ioprio.h"
      27                 :            : #include "journal-util.h"
      28                 :            : #include "missing.h"
      29                 :            : #include "mountpoint-util.h"
      30                 :            : #include "namespace.h"
      31                 :            : #include "parse-util.h"
      32                 :            : #include "path-util.h"
      33                 :            : #include "process-util.h"
      34                 :            : #include "rlimit-util.h"
      35                 :            : #if HAVE_SECCOMP
      36                 :            : #include "seccomp-util.h"
      37                 :            : #endif
      38                 :            : #include "securebits-util.h"
      39                 :            : #include "specifier.h"
      40                 :            : #include "strv.h"
      41                 :            : #include "syslog-util.h"
      42                 :            : #include "unit-printf.h"
      43                 :            : #include "user-util.h"
      44                 :            : #include "utf8.h"
      45                 :            : 
      46   [ #  #  #  #  :          0 : BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutput);
                   #  # ]
      47   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, exec_input, ExecInput);
                   #  # ]
      48   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode);
                   #  # ]
      49   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_preserve_mode, exec_preserve_mode, ExecPreserveMode);
                   #  # ]
      50   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_keyring_mode, exec_keyring_mode, ExecKeyringMode);
                   #  # ]
      51   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_protect_home, protect_home, ProtectHome);
                   #  # ]
      52   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_protect_system, protect_system, ProtectSystem);
                   #  # ]
      53   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_personality, personality, unsigned long);
                   #  # ]
      54   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET(property_get_ioprio, "i", ExecContext, exec_context_get_effective_ioprio);
                   #  # ]
      55   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_class, "i", ExecContext, exec_context_get_effective_ioprio, IOPRIO_PRIO_CLASS);
                   #  # ]
      56   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_priority, "i", ExecContext, exec_context_get_effective_ioprio, IOPRIO_PRIO_DATA);
                   #  # ]
      57   [ #  #  #  # ]:          0 : static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_string, "s", NULL);
      58   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_level, "i", int, LOG_PRI);
                   #  # ]
      59   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_facility, "i", int, LOG_FAC);
                   #  # ]
      60                 :            : 
      61                 :          0 : static int property_get_environment_files(
      62                 :            :                 sd_bus *bus,
      63                 :            :                 const char *path,
      64                 :            :                 const char *interface,
      65                 :            :                 const char *property,
      66                 :            :                 sd_bus_message *reply,
      67                 :            :                 void *userdata,
      68                 :            :                 sd_bus_error *error) {
      69                 :            : 
      70                 :          0 :         ExecContext *c = userdata;
      71                 :            :         char **j;
      72                 :            :         int r;
      73                 :            : 
      74         [ #  # ]:          0 :         assert(bus);
      75         [ #  # ]:          0 :         assert(reply);
      76         [ #  # ]:          0 :         assert(c);
      77                 :            : 
      78                 :          0 :         r = sd_bus_message_open_container(reply, 'a', "(sb)");
      79         [ #  # ]:          0 :         if (r < 0)
      80                 :          0 :                 return r;
      81                 :            : 
      82   [ #  #  #  # ]:          0 :         STRV_FOREACH(j, c->environment_files) {
      83                 :          0 :                 const char *fn = *j;
      84                 :            : 
      85         [ #  # ]:          0 :                 r = sd_bus_message_append(reply, "(sb)", fn[0] == '-' ? fn + 1 : fn, fn[0] == '-');
      86         [ #  # ]:          0 :                 if (r < 0)
      87                 :          0 :                         return r;
      88                 :            :         }
      89                 :            : 
      90                 :          0 :         return sd_bus_message_close_container(reply);
      91                 :            : }
      92                 :            : 
      93                 :          0 : static int property_get_oom_score_adjust(
      94                 :            :                 sd_bus *bus,
      95                 :            :                 const char *path,
      96                 :            :                 const char *interface,
      97                 :            :                 const char *property,
      98                 :            :                 sd_bus_message *reply,
      99                 :            :                 void *userdata,
     100                 :            :                 sd_bus_error *error) {
     101                 :            : 
     102                 :          0 :         ExecContext *c = userdata;
     103                 :            :         int32_t n;
     104                 :            : 
     105         [ #  # ]:          0 :         assert(bus);
     106         [ #  # ]:          0 :         assert(reply);
     107         [ #  # ]:          0 :         assert(c);
     108                 :            : 
     109         [ #  # ]:          0 :         if (c->oom_score_adjust_set)
     110                 :          0 :                 n = c->oom_score_adjust;
     111                 :            :         else {
     112                 :          0 :                 _cleanup_free_ char *t = NULL;
     113                 :            : 
     114                 :          0 :                 n = 0;
     115         [ #  # ]:          0 :                 if (read_one_line_file("/proc/self/oom_score_adj", &t) >= 0)
     116                 :          0 :                         safe_atoi32(t, &n);
     117                 :            :         }
     118                 :            : 
     119                 :          0 :         return sd_bus_message_append(reply, "i", n);
     120                 :            : }
     121                 :            : 
     122                 :          0 : static int property_get_nice(
     123                 :            :                 sd_bus *bus,
     124                 :            :                 const char *path,
     125                 :            :                 const char *interface,
     126                 :            :                 const char *property,
     127                 :            :                 sd_bus_message *reply,
     128                 :            :                 void *userdata,
     129                 :            :                 sd_bus_error *error) {
     130                 :            : 
     131                 :          0 :         ExecContext *c = userdata;
     132                 :            :         int32_t n;
     133                 :            : 
     134         [ #  # ]:          0 :         assert(bus);
     135         [ #  # ]:          0 :         assert(reply);
     136         [ #  # ]:          0 :         assert(c);
     137                 :            : 
     138         [ #  # ]:          0 :         if (c->nice_set)
     139                 :          0 :                 n = c->nice;
     140                 :            :         else {
     141                 :          0 :                 errno = 0;
     142                 :          0 :                 n = getpriority(PRIO_PROCESS, 0);
     143         [ #  # ]:          0 :                 if (errno > 0)
     144                 :          0 :                         n = 0;
     145                 :            :         }
     146                 :            : 
     147                 :          0 :         return sd_bus_message_append(reply, "i", n);
     148                 :            : }
     149                 :            : 
     150                 :          0 : static int property_get_cpu_sched_policy(
     151                 :            :                 sd_bus *bus,
     152                 :            :                 const char *path,
     153                 :            :                 const char *interface,
     154                 :            :                 const char *property,
     155                 :            :                 sd_bus_message *reply,
     156                 :            :                 void *userdata,
     157                 :            :                 sd_bus_error *error) {
     158                 :            : 
     159                 :          0 :         ExecContext *c = userdata;
     160                 :            :         int32_t n;
     161                 :            : 
     162         [ #  # ]:          0 :         assert(bus);
     163         [ #  # ]:          0 :         assert(reply);
     164         [ #  # ]:          0 :         assert(c);
     165                 :            : 
     166         [ #  # ]:          0 :         if (c->cpu_sched_set)
     167                 :          0 :                 n = c->cpu_sched_policy;
     168                 :            :         else {
     169                 :          0 :                 n = sched_getscheduler(0);
     170         [ #  # ]:          0 :                 if (n < 0)
     171                 :          0 :                         n = SCHED_OTHER;
     172                 :            :         }
     173                 :            : 
     174                 :          0 :         return sd_bus_message_append(reply, "i", n);
     175                 :            : }
     176                 :            : 
     177                 :          0 : static int property_get_cpu_sched_priority(
     178                 :            :                 sd_bus *bus,
     179                 :            :                 const char *path,
     180                 :            :                 const char *interface,
     181                 :            :                 const char *property,
     182                 :            :                 sd_bus_message *reply,
     183                 :            :                 void *userdata,
     184                 :            :                 sd_bus_error *error) {
     185                 :            : 
     186                 :          0 :         ExecContext *c = userdata;
     187                 :            :         int32_t n;
     188                 :            : 
     189         [ #  # ]:          0 :         assert(bus);
     190         [ #  # ]:          0 :         assert(reply);
     191         [ #  # ]:          0 :         assert(c);
     192                 :            : 
     193         [ #  # ]:          0 :         if (c->cpu_sched_set)
     194                 :          0 :                 n = c->cpu_sched_priority;
     195                 :            :         else {
     196                 :          0 :                 struct sched_param p = {};
     197                 :            : 
     198         [ #  # ]:          0 :                 if (sched_getparam(0, &p) >= 0)
     199                 :          0 :                         n = p.sched_priority;
     200                 :            :                 else
     201                 :          0 :                         n = 0;
     202                 :            :         }
     203                 :            : 
     204                 :          0 :         return sd_bus_message_append(reply, "i", n);
     205                 :            : }
     206                 :            : 
     207                 :          0 : static int property_get_cpu_affinity(
     208                 :            :                 sd_bus *bus,
     209                 :            :                 const char *path,
     210                 :            :                 const char *interface,
     211                 :            :                 const char *property,
     212                 :            :                 sd_bus_message *reply,
     213                 :            :                 void *userdata,
     214                 :            :                 sd_bus_error *error) {
     215                 :            : 
     216                 :          0 :         ExecContext *c = userdata;
     217                 :          0 :         _cleanup_free_ uint8_t *array = NULL;
     218                 :            :         size_t allocated;
     219                 :            : 
     220         [ #  # ]:          0 :         assert(bus);
     221         [ #  # ]:          0 :         assert(reply);
     222         [ #  # ]:          0 :         assert(c);
     223                 :            : 
     224                 :          0 :         (void) cpu_set_to_dbus(&c->cpu_set, &array, &allocated);
     225                 :          0 :         return sd_bus_message_append_array(reply, 'y', array, allocated);
     226                 :            : }
     227                 :            : 
     228                 :          0 : static int property_get_numa_mask(
     229                 :            :                 sd_bus *bus,
     230                 :            :                 const char *path,
     231                 :            :                 const char *interface,
     232                 :            :                 const char *property,
     233                 :            :                 sd_bus_message *reply,
     234                 :            :                 void *userdata,
     235                 :            :                 sd_bus_error *error) {
     236                 :            : 
     237                 :          0 :         ExecContext *c = userdata;
     238                 :          0 :         _cleanup_free_ uint8_t *array = NULL;
     239                 :            :         size_t allocated;
     240                 :            : 
     241         [ #  # ]:          0 :         assert(bus);
     242         [ #  # ]:          0 :         assert(reply);
     243         [ #  # ]:          0 :         assert(c);
     244                 :            : 
     245                 :          0 :         (void) cpu_set_to_dbus(&c->numa_policy.nodes, &array, &allocated);
     246                 :            : 
     247                 :          0 :         return sd_bus_message_append_array(reply, 'y', array, allocated);
     248                 :            : }
     249                 :            : 
     250                 :          0 : static int property_get_numa_policy(
     251                 :            :                 sd_bus *bus,
     252                 :            :                 const char *path,
     253                 :            :                 const char *interface,
     254                 :            :                 const char *property,
     255                 :            :                 sd_bus_message *reply,
     256                 :            :                 void *userdata,
     257                 :            :                 sd_bus_error *error) {
     258                 :          0 :         ExecContext *c = userdata;
     259                 :            :         int32_t policy;
     260                 :            : 
     261         [ #  # ]:          0 :         assert(bus);
     262         [ #  # ]:          0 :         assert(reply);
     263         [ #  # ]:          0 :         assert(c);
     264                 :            : 
     265                 :          0 :         policy = numa_policy_get_type(&c->numa_policy);
     266                 :            : 
     267                 :          0 :         return sd_bus_message_append_basic(reply, 'i', &policy);
     268                 :            : }
     269                 :            : 
     270                 :          0 : static int property_get_timer_slack_nsec(
     271                 :            :                 sd_bus *bus,
     272                 :            :                 const char *path,
     273                 :            :                 const char *interface,
     274                 :            :                 const char *property,
     275                 :            :                 sd_bus_message *reply,
     276                 :            :                 void *userdata,
     277                 :            :                 sd_bus_error *error) {
     278                 :            : 
     279                 :          0 :         ExecContext *c = userdata;
     280                 :            :         uint64_t u;
     281                 :            : 
     282         [ #  # ]:          0 :         assert(bus);
     283         [ #  # ]:          0 :         assert(reply);
     284         [ #  # ]:          0 :         assert(c);
     285                 :            : 
     286         [ #  # ]:          0 :         if (c->timer_slack_nsec != NSEC_INFINITY)
     287                 :          0 :                 u = (uint64_t) c->timer_slack_nsec;
     288                 :            :         else
     289                 :          0 :                 u = (uint64_t) prctl(PR_GET_TIMERSLACK);
     290                 :            : 
     291                 :          0 :         return sd_bus_message_append(reply, "t", u);
     292                 :            : }
     293                 :            : 
     294                 :          0 : static int property_get_syscall_filter(
     295                 :            :                 sd_bus *bus,
     296                 :            :                 const char *path,
     297                 :            :                 const char *interface,
     298                 :            :                 const char *property,
     299                 :            :                 sd_bus_message *reply,
     300                 :            :                 void *userdata,
     301                 :            :                 sd_bus_error *error) {
     302                 :            : 
     303                 :          0 :         ExecContext *c = userdata;
     304                 :          0 :         _cleanup_strv_free_ char **l = NULL;
     305                 :            :         int r;
     306                 :            : 
     307                 :            : #if HAVE_SECCOMP
     308                 :            :         Iterator i;
     309                 :            :         void *id, *val;
     310                 :            : #endif
     311                 :            : 
     312         [ #  # ]:          0 :         assert(bus);
     313         [ #  # ]:          0 :         assert(reply);
     314         [ #  # ]:          0 :         assert(c);
     315                 :            : 
     316                 :          0 :         r = sd_bus_message_open_container(reply, 'r', "bas");
     317         [ #  # ]:          0 :         if (r < 0)
     318                 :          0 :                 return r;
     319                 :            : 
     320                 :          0 :         r = sd_bus_message_append(reply, "b", c->syscall_whitelist);
     321         [ #  # ]:          0 :         if (r < 0)
     322                 :          0 :                 return r;
     323                 :            : 
     324                 :            : #if HAVE_SECCOMP
     325         [ #  # ]:          0 :         HASHMAP_FOREACH_KEY(val, id, c->syscall_filter, i) {
     326      [ #  #  # ]:          0 :                 _cleanup_free_ char *name = NULL;
     327                 :          0 :                 const char *e = NULL;
     328                 :            :                 char *s;
     329                 :          0 :                 int num = PTR_TO_INT(val);
     330                 :            : 
     331                 :          0 :                 name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
     332         [ #  # ]:          0 :                 if (!name)
     333                 :          0 :                         continue;
     334                 :            : 
     335         [ #  # ]:          0 :                 if (num >= 0) {
     336                 :          0 :                         e = errno_to_name(num);
     337         [ #  # ]:          0 :                         if (e) {
     338                 :          0 :                                 s = strjoin(name, ":", e);
     339         [ #  # ]:          0 :                                 if (!s)
     340                 :          0 :                                         return -ENOMEM;
     341                 :            :                         } else {
     342                 :          0 :                                 r = asprintf(&s, "%s:%d", name, num);
     343         [ #  # ]:          0 :                                 if (r < 0)
     344                 :          0 :                                         return -ENOMEM;
     345                 :            :                         }
     346                 :            :                 } else
     347                 :          0 :                         s = TAKE_PTR(name);
     348                 :            : 
     349                 :          0 :                 r = strv_consume(&l, s);
     350         [ #  # ]:          0 :                 if (r < 0)
     351                 :          0 :                         return r;
     352                 :            :         }
     353                 :            : #endif
     354                 :            : 
     355                 :          0 :         strv_sort(l);
     356                 :            : 
     357                 :          0 :         r = sd_bus_message_append_strv(reply, l);
     358         [ #  # ]:          0 :         if (r < 0)
     359                 :          0 :                 return r;
     360                 :            : 
     361                 :          0 :         return sd_bus_message_close_container(reply);
     362                 :            : }
     363                 :            : 
     364                 :          0 : static int property_get_syscall_archs(
     365                 :            :                 sd_bus *bus,
     366                 :            :                 const char *path,
     367                 :            :                 const char *interface,
     368                 :            :                 const char *property,
     369                 :            :                 sd_bus_message *reply,
     370                 :            :                 void *userdata,
     371                 :            :                 sd_bus_error *error) {
     372                 :            : 
     373                 :          0 :         ExecContext *c = userdata;
     374                 :          0 :         _cleanup_strv_free_ char **l = NULL;
     375                 :            :         int r;
     376                 :            : 
     377                 :            : #if HAVE_SECCOMP
     378                 :            :         Iterator i;
     379                 :            :         void *id;
     380                 :            : #endif
     381                 :            : 
     382         [ #  # ]:          0 :         assert(bus);
     383         [ #  # ]:          0 :         assert(reply);
     384         [ #  # ]:          0 :         assert(c);
     385                 :            : 
     386                 :            : #if HAVE_SECCOMP
     387         [ #  # ]:          0 :         SET_FOREACH(id, c->syscall_archs, i) {
     388                 :            :                 const char *name;
     389                 :            : 
     390                 :          0 :                 name = seccomp_arch_to_string(PTR_TO_UINT32(id) - 1);
     391         [ #  # ]:          0 :                 if (!name)
     392                 :          0 :                         continue;
     393                 :            : 
     394                 :          0 :                 r = strv_extend(&l, name);
     395         [ #  # ]:          0 :                 if (r < 0)
     396                 :          0 :                         return -ENOMEM;
     397                 :            :         }
     398                 :            : #endif
     399                 :            : 
     400                 :          0 :         strv_sort(l);
     401                 :            : 
     402                 :          0 :         r = sd_bus_message_append_strv(reply, l);
     403         [ #  # ]:          0 :         if (r < 0)
     404                 :          0 :                 return r;
     405                 :            : 
     406                 :          0 :         return 0;
     407                 :            : }
     408                 :            : 
     409                 :          0 : static int property_get_selinux_context(
     410                 :            :                 sd_bus *bus,
     411                 :            :                 const char *path,
     412                 :            :                 const char *interface,
     413                 :            :                 const char *property,
     414                 :            :                 sd_bus_message *reply,
     415                 :            :                 void *userdata,
     416                 :            :                 sd_bus_error *error) {
     417                 :            : 
     418                 :          0 :         ExecContext *c = userdata;
     419                 :            : 
     420         [ #  # ]:          0 :         assert(bus);
     421         [ #  # ]:          0 :         assert(reply);
     422         [ #  # ]:          0 :         assert(c);
     423                 :            : 
     424                 :          0 :         return sd_bus_message_append(reply, "(bs)", c->selinux_context_ignore, c->selinux_context);
     425                 :            : }
     426                 :            : 
     427                 :          0 : static int property_get_apparmor_profile(
     428                 :            :                 sd_bus *bus,
     429                 :            :                 const char *path,
     430                 :            :                 const char *interface,
     431                 :            :                 const char *property,
     432                 :            :                 sd_bus_message *reply,
     433                 :            :                 void *userdata,
     434                 :            :                 sd_bus_error *error) {
     435                 :            : 
     436                 :          0 :         ExecContext *c = userdata;
     437                 :            : 
     438         [ #  # ]:          0 :         assert(bus);
     439         [ #  # ]:          0 :         assert(reply);
     440         [ #  # ]:          0 :         assert(c);
     441                 :            : 
     442                 :          0 :         return sd_bus_message_append(reply, "(bs)", c->apparmor_profile_ignore, c->apparmor_profile);
     443                 :            : }
     444                 :            : 
     445                 :          0 : static int property_get_smack_process_label(
     446                 :            :                 sd_bus *bus,
     447                 :            :                 const char *path,
     448                 :            :                 const char *interface,
     449                 :            :                 const char *property,
     450                 :            :                 sd_bus_message *reply,
     451                 :            :                 void *userdata,
     452                 :            :                 sd_bus_error *error) {
     453                 :            : 
     454                 :          0 :         ExecContext *c = userdata;
     455                 :            : 
     456         [ #  # ]:          0 :         assert(bus);
     457         [ #  # ]:          0 :         assert(reply);
     458         [ #  # ]:          0 :         assert(c);
     459                 :            : 
     460                 :          0 :         return sd_bus_message_append(reply, "(bs)", c->smack_process_label_ignore, c->smack_process_label);
     461                 :            : }
     462                 :            : 
     463                 :          0 : static int property_get_address_families(
     464                 :            :                 sd_bus *bus,
     465                 :            :                 const char *path,
     466                 :            :                 const char *interface,
     467                 :            :                 const char *property,
     468                 :            :                 sd_bus_message *reply,
     469                 :            :                 void *userdata,
     470                 :            :                 sd_bus_error *error) {
     471                 :            : 
     472                 :          0 :         ExecContext *c = userdata;
     473                 :          0 :         _cleanup_strv_free_ char **l = NULL;
     474                 :            :         Iterator i;
     475                 :            :         void *af;
     476                 :            :         int r;
     477                 :            : 
     478         [ #  # ]:          0 :         assert(bus);
     479         [ #  # ]:          0 :         assert(reply);
     480         [ #  # ]:          0 :         assert(c);
     481                 :            : 
     482                 :          0 :         r = sd_bus_message_open_container(reply, 'r', "bas");
     483         [ #  # ]:          0 :         if (r < 0)
     484                 :          0 :                 return r;
     485                 :            : 
     486                 :          0 :         r = sd_bus_message_append(reply, "b", c->address_families_whitelist);
     487         [ #  # ]:          0 :         if (r < 0)
     488                 :          0 :                 return r;
     489                 :            : 
     490         [ #  # ]:          0 :         SET_FOREACH(af, c->address_families, i) {
     491                 :            :                 const char *name;
     492                 :            : 
     493                 :          0 :                 name = af_to_name(PTR_TO_INT(af));
     494         [ #  # ]:          0 :                 if (!name)
     495                 :          0 :                         continue;
     496                 :            : 
     497                 :          0 :                 r = strv_extend(&l, name);
     498         [ #  # ]:          0 :                 if (r < 0)
     499                 :          0 :                         return -ENOMEM;
     500                 :            :         }
     501                 :            : 
     502                 :          0 :         strv_sort(l);
     503                 :            : 
     504                 :          0 :         r = sd_bus_message_append_strv(reply, l);
     505         [ #  # ]:          0 :         if (r < 0)
     506                 :          0 :                 return r;
     507                 :            : 
     508                 :          0 :         return sd_bus_message_close_container(reply);
     509                 :            : }
     510                 :            : 
     511                 :          0 : static int property_get_working_directory(
     512                 :            :                 sd_bus *bus,
     513                 :            :                 const char *path,
     514                 :            :                 const char *interface,
     515                 :            :                 const char *property,
     516                 :            :                 sd_bus_message *reply,
     517                 :            :                 void *userdata,
     518                 :            :                 sd_bus_error *error) {
     519                 :            : 
     520                 :          0 :         ExecContext *c = userdata;
     521                 :            :         const char *wd;
     522                 :            : 
     523         [ #  # ]:          0 :         assert(bus);
     524         [ #  # ]:          0 :         assert(reply);
     525         [ #  # ]:          0 :         assert(c);
     526                 :            : 
     527         [ #  # ]:          0 :         if (c->working_directory_home)
     528                 :          0 :                 wd = "~";
     529                 :            :         else
     530                 :          0 :                 wd = c->working_directory;
     531                 :            : 
     532         [ #  # ]:          0 :         if (c->working_directory_missing_ok)
     533   [ #  #  #  #  :          0 :                 wd = strjoina("!", wd);
          #  #  #  #  #  
                #  #  # ]
     534                 :            : 
     535                 :          0 :         return sd_bus_message_append(reply, "s", wd);
     536                 :            : }
     537                 :            : 
     538                 :          0 : static int property_get_stdio_fdname(
     539                 :            :                 sd_bus *bus,
     540                 :            :                 const char *path,
     541                 :            :                 const char *interface,
     542                 :            :                 const char *property,
     543                 :            :                 sd_bus_message *reply,
     544                 :            :                 void *userdata,
     545                 :            :                 sd_bus_error *error) {
     546                 :            : 
     547                 :          0 :         ExecContext *c = userdata;
     548                 :            :         int fileno;
     549                 :            : 
     550         [ #  # ]:          0 :         assert(bus);
     551         [ #  # ]:          0 :         assert(c);
     552         [ #  # ]:          0 :         assert(property);
     553         [ #  # ]:          0 :         assert(reply);
     554                 :            : 
     555         [ #  # ]:          0 :         if (streq(property, "StandardInputFileDescriptorName"))
     556                 :          0 :                 fileno = STDIN_FILENO;
     557         [ #  # ]:          0 :         else if (streq(property, "StandardOutputFileDescriptorName"))
     558                 :          0 :                 fileno = STDOUT_FILENO;
     559                 :            :         else {
     560         [ #  # ]:          0 :                 assert(streq(property, "StandardErrorFileDescriptorName"));
     561                 :          0 :                 fileno = STDERR_FILENO;
     562                 :            :         }
     563                 :            : 
     564                 :          0 :         return sd_bus_message_append(reply, "s", exec_context_fdname(c, fileno));
     565                 :            : }
     566                 :            : 
     567                 :          0 : static int property_get_input_data(
     568                 :            :                 sd_bus *bus,
     569                 :            :                 const char *path,
     570                 :            :                 const char *interface,
     571                 :            :                 const char *property,
     572                 :            :                 sd_bus_message *reply,
     573                 :            :                 void *userdata,
     574                 :            :                 sd_bus_error *error) {
     575                 :            : 
     576                 :          0 :         ExecContext *c = userdata;
     577                 :            : 
     578         [ #  # ]:          0 :         assert(bus);
     579         [ #  # ]:          0 :         assert(c);
     580         [ #  # ]:          0 :         assert(property);
     581         [ #  # ]:          0 :         assert(reply);
     582                 :            : 
     583                 :          0 :         return sd_bus_message_append_array(reply, 'y', c->stdin_data, c->stdin_data_size);
     584                 :            : }
     585                 :            : 
     586                 :          0 : static int property_get_bind_paths(
     587                 :            :                 sd_bus *bus,
     588                 :            :                 const char *path,
     589                 :            :                 const char *interface,
     590                 :            :                 const char *property,
     591                 :            :                 sd_bus_message *reply,
     592                 :            :                 void *userdata,
     593                 :            :                 sd_bus_error *error) {
     594                 :            : 
     595                 :          0 :         ExecContext *c = userdata;
     596                 :            :         unsigned i;
     597                 :            :         bool ro;
     598                 :            :         int r;
     599                 :            : 
     600         [ #  # ]:          0 :         assert(bus);
     601         [ #  # ]:          0 :         assert(c);
     602         [ #  # ]:          0 :         assert(property);
     603         [ #  # ]:          0 :         assert(reply);
     604                 :            : 
     605                 :          0 :         ro = strstr(property, "ReadOnly");
     606                 :            : 
     607                 :          0 :         r = sd_bus_message_open_container(reply, 'a', "(ssbt)");
     608         [ #  # ]:          0 :         if (r < 0)
     609                 :          0 :                 return r;
     610                 :            : 
     611         [ #  # ]:          0 :         for (i = 0; i < c->n_bind_mounts; i++) {
     612                 :            : 
     613         [ #  # ]:          0 :                 if (ro != c->bind_mounts[i].read_only)
     614                 :          0 :                         continue;
     615                 :            : 
     616                 :          0 :                 r = sd_bus_message_append(
     617                 :            :                                 reply, "(ssbt)",
     618                 :          0 :                                 c->bind_mounts[i].source,
     619                 :          0 :                                 c->bind_mounts[i].destination,
     620                 :          0 :                                 c->bind_mounts[i].ignore_enoent,
     621                 :          0 :                                 c->bind_mounts[i].recursive ? (uint64_t) MS_REC : (uint64_t) 0);
     622         [ #  # ]:          0 :                 if (r < 0)
     623                 :          0 :                         return r;
     624                 :            :         }
     625                 :            : 
     626                 :          0 :         return sd_bus_message_close_container(reply);
     627                 :            : }
     628                 :            : 
     629                 :          0 : static int property_get_temporary_filesystems(
     630                 :            :                 sd_bus *bus,
     631                 :            :                 const char *path,
     632                 :            :                 const char *interface,
     633                 :            :                 const char *property,
     634                 :            :                 sd_bus_message *reply,
     635                 :            :                 void *userdata,
     636                 :            :                 sd_bus_error *error) {
     637                 :            : 
     638                 :          0 :         ExecContext *c = userdata;
     639                 :            :         unsigned i;
     640                 :            :         int r;
     641                 :            : 
     642         [ #  # ]:          0 :         assert(bus);
     643         [ #  # ]:          0 :         assert(c);
     644         [ #  # ]:          0 :         assert(property);
     645         [ #  # ]:          0 :         assert(reply);
     646                 :            : 
     647                 :          0 :         r = sd_bus_message_open_container(reply, 'a', "(ss)");
     648         [ #  # ]:          0 :         if (r < 0)
     649                 :          0 :                 return r;
     650                 :            : 
     651         [ #  # ]:          0 :         for (i = 0; i < c->n_temporary_filesystems; i++) {
     652                 :          0 :                 TemporaryFileSystem *t = c->temporary_filesystems + i;
     653                 :            : 
     654                 :          0 :                 r = sd_bus_message_append(
     655                 :            :                                 reply, "(ss)",
     656                 :            :                                 t->path,
     657                 :            :                                 t->options);
     658         [ #  # ]:          0 :                 if (r < 0)
     659                 :          0 :                         return r;
     660                 :            :         }
     661                 :            : 
     662                 :          0 :         return sd_bus_message_close_container(reply);
     663                 :            : }
     664                 :            : 
     665                 :          0 : static int property_get_log_extra_fields(
     666                 :            :                 sd_bus *bus,
     667                 :            :                 const char *path,
     668                 :            :                 const char *interface,
     669                 :            :                 const char *property,
     670                 :            :                 sd_bus_message *reply,
     671                 :            :                 void *userdata,
     672                 :            :                 sd_bus_error *error) {
     673                 :            : 
     674                 :          0 :         ExecContext *c = userdata;
     675                 :            :         size_t i;
     676                 :            :         int r;
     677                 :            : 
     678         [ #  # ]:          0 :         assert(bus);
     679         [ #  # ]:          0 :         assert(c);
     680         [ #  # ]:          0 :         assert(property);
     681         [ #  # ]:          0 :         assert(reply);
     682                 :            : 
     683                 :          0 :         r = sd_bus_message_open_container(reply, 'a', "ay");
     684         [ #  # ]:          0 :         if (r < 0)
     685                 :          0 :                 return r;
     686                 :            : 
     687         [ #  # ]:          0 :         for (i = 0; i < c->n_log_extra_fields; i++) {
     688                 :          0 :                 r = sd_bus_message_append_array(reply, 'y', c->log_extra_fields[i].iov_base, c->log_extra_fields[i].iov_len);
     689         [ #  # ]:          0 :                 if (r < 0)
     690                 :          0 :                         return r;
     691                 :            :         }
     692                 :            : 
     693                 :          0 :         return sd_bus_message_close_container(reply);
     694                 :            : }
     695                 :            : 
     696                 :            : const sd_bus_vtable bus_exec_vtable[] = {
     697                 :            :         SD_BUS_VTABLE_START(0),
     698                 :            :         SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST),
     699                 :            :         SD_BUS_PROPERTY("EnvironmentFiles", "a(sb)", property_get_environment_files, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     700                 :            :         SD_BUS_PROPERTY("PassEnvironment", "as", NULL, offsetof(ExecContext, pass_environment), SD_BUS_VTABLE_PROPERTY_CONST),
     701                 :            :         SD_BUS_PROPERTY("UnsetEnvironment", "as", NULL, offsetof(ExecContext, unset_environment), SD_BUS_VTABLE_PROPERTY_CONST),
     702                 :            :         SD_BUS_PROPERTY("UMask", "u", bus_property_get_mode, offsetof(ExecContext, umask), SD_BUS_VTABLE_PROPERTY_CONST),
     703                 :            :         SD_BUS_PROPERTY("LimitCPU", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
     704                 :            :         SD_BUS_PROPERTY("LimitCPUSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
     705                 :            :         SD_BUS_PROPERTY("LimitFSIZE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
     706                 :            :         SD_BUS_PROPERTY("LimitFSIZESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
     707                 :            :         SD_BUS_PROPERTY("LimitDATA", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
     708                 :            :         SD_BUS_PROPERTY("LimitDATASoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
     709                 :            :         SD_BUS_PROPERTY("LimitSTACK", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
     710                 :            :         SD_BUS_PROPERTY("LimitSTACKSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
     711                 :            :         SD_BUS_PROPERTY("LimitCORE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
     712                 :            :         SD_BUS_PROPERTY("LimitCORESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
     713                 :            :         SD_BUS_PROPERTY("LimitRSS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
     714                 :            :         SD_BUS_PROPERTY("LimitRSSSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
     715                 :            :         SD_BUS_PROPERTY("LimitNOFILE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
     716                 :            :         SD_BUS_PROPERTY("LimitNOFILESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
     717                 :            :         SD_BUS_PROPERTY("LimitAS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
     718                 :            :         SD_BUS_PROPERTY("LimitASSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
     719                 :            :         SD_BUS_PROPERTY("LimitNPROC", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
     720                 :            :         SD_BUS_PROPERTY("LimitNPROCSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
     721                 :            :         SD_BUS_PROPERTY("LimitMEMLOCK", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
     722                 :            :         SD_BUS_PROPERTY("LimitMEMLOCKSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
     723                 :            :         SD_BUS_PROPERTY("LimitLOCKS", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
     724                 :            :         SD_BUS_PROPERTY("LimitLOCKSSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
     725                 :            :         SD_BUS_PROPERTY("LimitSIGPENDING", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
     726                 :            :         SD_BUS_PROPERTY("LimitSIGPENDINGSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
     727                 :            :         SD_BUS_PROPERTY("LimitMSGQUEUE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
     728                 :            :         SD_BUS_PROPERTY("LimitMSGQUEUESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
     729                 :            :         SD_BUS_PROPERTY("LimitNICE", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
     730                 :            :         SD_BUS_PROPERTY("LimitNICESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
     731                 :            :         SD_BUS_PROPERTY("LimitRTPRIO", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
     732                 :            :         SD_BUS_PROPERTY("LimitRTPRIOSoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
     733                 :            :         SD_BUS_PROPERTY("LimitRTTIME", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
     734                 :            :         SD_BUS_PROPERTY("LimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(ExecContext, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
     735                 :            :         SD_BUS_PROPERTY("WorkingDirectory", "s", property_get_working_directory, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     736                 :            :         SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(ExecContext, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
     737                 :            :         SD_BUS_PROPERTY("RootImage", "s", NULL, offsetof(ExecContext, root_image), SD_BUS_VTABLE_PROPERTY_CONST),
     738                 :            :         SD_BUS_PROPERTY("OOMScoreAdjust", "i", property_get_oom_score_adjust, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     739                 :            :         SD_BUS_PROPERTY("Nice", "i", property_get_nice, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     740                 :            :         SD_BUS_PROPERTY("IOSchedulingClass", "i", property_get_ioprio_class, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     741                 :            :         SD_BUS_PROPERTY("IOSchedulingPriority", "i", property_get_ioprio_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     742                 :            :         SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     743                 :            :         SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     744                 :            :         SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     745                 :            :         SD_BUS_PROPERTY("NUMAPolicy", "i", property_get_numa_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     746                 :            :         SD_BUS_PROPERTY("NUMAMask", "ay", property_get_numa_mask, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     747                 :            :         SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     748                 :            :         SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
     749                 :            :         SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
     750                 :            :         SD_BUS_PROPERTY("StandardInput", "s", property_get_exec_input, offsetof(ExecContext, std_input), SD_BUS_VTABLE_PROPERTY_CONST),
     751                 :            :         SD_BUS_PROPERTY("StandardInputFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     752                 :            :         SD_BUS_PROPERTY("StandardInputData", "ay", property_get_input_data, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     753                 :            :         SD_BUS_PROPERTY("StandardOutput", "s", bus_property_get_exec_output, offsetof(ExecContext, std_output), SD_BUS_VTABLE_PROPERTY_CONST),
     754                 :            :         SD_BUS_PROPERTY("StandardOutputFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     755                 :            :         SD_BUS_PROPERTY("StandardError", "s", bus_property_get_exec_output, offsetof(ExecContext, std_error), SD_BUS_VTABLE_PROPERTY_CONST),
     756                 :            :         SD_BUS_PROPERTY("StandardErrorFileDescriptorName", "s", property_get_stdio_fdname, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     757                 :            :         SD_BUS_PROPERTY("TTYPath", "s", NULL, offsetof(ExecContext, tty_path), SD_BUS_VTABLE_PROPERTY_CONST),
     758                 :            :         SD_BUS_PROPERTY("TTYReset", "b", bus_property_get_bool, offsetof(ExecContext, tty_reset), SD_BUS_VTABLE_PROPERTY_CONST),
     759                 :            :         SD_BUS_PROPERTY("TTYVHangup", "b", bus_property_get_bool, offsetof(ExecContext, tty_vhangup), SD_BUS_VTABLE_PROPERTY_CONST),
     760                 :            :         SD_BUS_PROPERTY("TTYVTDisallocate", "b", bus_property_get_bool, offsetof(ExecContext, tty_vt_disallocate), SD_BUS_VTABLE_PROPERTY_CONST),
     761                 :            :         SD_BUS_PROPERTY("SyslogPriority", "i", bus_property_get_int, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
     762                 :            :         SD_BUS_PROPERTY("SyslogIdentifier", "s", NULL, offsetof(ExecContext, syslog_identifier), SD_BUS_VTABLE_PROPERTY_CONST),
     763                 :            :         SD_BUS_PROPERTY("SyslogLevelPrefix", "b", bus_property_get_bool, offsetof(ExecContext, syslog_level_prefix), SD_BUS_VTABLE_PROPERTY_CONST),
     764                 :            :         SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
     765                 :            :         SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
     766                 :            :         SD_BUS_PROPERTY("LogLevelMax", "i", bus_property_get_int, offsetof(ExecContext, log_level_max), SD_BUS_VTABLE_PROPERTY_CONST),
     767                 :            :         SD_BUS_PROPERTY("LogRateLimitIntervalUSec", "t", bus_property_get_usec, offsetof(ExecContext, log_rate_limit_interval_usec), SD_BUS_VTABLE_PROPERTY_CONST),
     768                 :            :         SD_BUS_PROPERTY("LogRateLimitBurst", "u", bus_property_get_unsigned, offsetof(ExecContext, log_rate_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST),
     769                 :            :         SD_BUS_PROPERTY("LogExtraFields", "aay", property_get_log_extra_fields, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     770                 :            :         SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
     771                 :            :         SD_BUS_PROPERTY("CapabilityBoundingSet", "t", NULL, offsetof(ExecContext, capability_bounding_set), SD_BUS_VTABLE_PROPERTY_CONST),
     772                 :            :         SD_BUS_PROPERTY("AmbientCapabilities", "t", NULL, offsetof(ExecContext, capability_ambient_set), SD_BUS_VTABLE_PROPERTY_CONST),
     773                 :            :         SD_BUS_PROPERTY("User", "s", NULL, offsetof(ExecContext, user), SD_BUS_VTABLE_PROPERTY_CONST),
     774                 :            :         SD_BUS_PROPERTY("Group", "s", NULL, offsetof(ExecContext, group), SD_BUS_VTABLE_PROPERTY_CONST),
     775                 :            :         SD_BUS_PROPERTY("DynamicUser", "b", bus_property_get_bool, offsetof(ExecContext, dynamic_user), SD_BUS_VTABLE_PROPERTY_CONST),
     776                 :            :         SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(ExecContext, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
     777                 :            :         SD_BUS_PROPERTY("SupplementaryGroups", "as", NULL, offsetof(ExecContext, supplementary_groups), SD_BUS_VTABLE_PROPERTY_CONST),
     778                 :            :         SD_BUS_PROPERTY("PAMName", "s", NULL, offsetof(ExecContext, pam_name), SD_BUS_VTABLE_PROPERTY_CONST),
     779                 :            :         SD_BUS_PROPERTY("ReadWritePaths", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST),
     780                 :            :         SD_BUS_PROPERTY("ReadOnlyPaths", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST),
     781                 :            :         SD_BUS_PROPERTY("InaccessiblePaths", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST),
     782                 :            :         SD_BUS_PROPERTY("MountFlags", "t", bus_property_get_ulong, offsetof(ExecContext, mount_flags), SD_BUS_VTABLE_PROPERTY_CONST),
     783                 :            :         SD_BUS_PROPERTY("PrivateTmp", "b", bus_property_get_bool, offsetof(ExecContext, private_tmp), SD_BUS_VTABLE_PROPERTY_CONST),
     784                 :            :         SD_BUS_PROPERTY("PrivateDevices", "b", bus_property_get_bool, offsetof(ExecContext, private_devices), SD_BUS_VTABLE_PROPERTY_CONST),
     785                 :            :         SD_BUS_PROPERTY("ProtectKernelTunables", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_tunables), SD_BUS_VTABLE_PROPERTY_CONST),
     786                 :            :         SD_BUS_PROPERTY("ProtectKernelModules", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_modules), SD_BUS_VTABLE_PROPERTY_CONST),
     787                 :            :         SD_BUS_PROPERTY("ProtectControlGroups", "b", bus_property_get_bool, offsetof(ExecContext, protect_control_groups), SD_BUS_VTABLE_PROPERTY_CONST),
     788                 :            :         SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST),
     789                 :            :         SD_BUS_PROPERTY("PrivateUsers", "b", bus_property_get_bool, offsetof(ExecContext, private_users), SD_BUS_VTABLE_PROPERTY_CONST),
     790                 :            :         SD_BUS_PROPERTY("PrivateMounts", "b", bus_property_get_bool, offsetof(ExecContext, private_mounts), SD_BUS_VTABLE_PROPERTY_CONST),
     791                 :            :         SD_BUS_PROPERTY("ProtectHome", "s", property_get_protect_home, offsetof(ExecContext, protect_home), SD_BUS_VTABLE_PROPERTY_CONST),
     792                 :            :         SD_BUS_PROPERTY("ProtectSystem", "s", property_get_protect_system, offsetof(ExecContext, protect_system), SD_BUS_VTABLE_PROPERTY_CONST),
     793                 :            :         SD_BUS_PROPERTY("SameProcessGroup", "b", bus_property_get_bool, offsetof(ExecContext, same_pgrp), SD_BUS_VTABLE_PROPERTY_CONST),
     794                 :            :         SD_BUS_PROPERTY("UtmpIdentifier", "s", NULL, offsetof(ExecContext, utmp_id), SD_BUS_VTABLE_PROPERTY_CONST),
     795                 :            :         SD_BUS_PROPERTY("UtmpMode", "s", property_get_exec_utmp_mode, offsetof(ExecContext, utmp_mode), SD_BUS_VTABLE_PROPERTY_CONST),
     796                 :            :         SD_BUS_PROPERTY("SELinuxContext", "(bs)", property_get_selinux_context, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     797                 :            :         SD_BUS_PROPERTY("AppArmorProfile", "(bs)", property_get_apparmor_profile, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     798                 :            :         SD_BUS_PROPERTY("SmackProcessLabel", "(bs)", property_get_smack_process_label, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     799                 :            :         SD_BUS_PROPERTY("IgnoreSIGPIPE", "b", bus_property_get_bool, offsetof(ExecContext, ignore_sigpipe), SD_BUS_VTABLE_PROPERTY_CONST),
     800                 :            :         SD_BUS_PROPERTY("NoNewPrivileges", "b", bus_property_get_bool, offsetof(ExecContext, no_new_privileges), SD_BUS_VTABLE_PROPERTY_CONST),
     801                 :            :         SD_BUS_PROPERTY("SystemCallFilter", "(bas)", property_get_syscall_filter, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     802                 :            :         SD_BUS_PROPERTY("SystemCallArchitectures", "as", property_get_syscall_archs, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     803                 :            :         SD_BUS_PROPERTY("SystemCallErrorNumber", "i", bus_property_get_int, offsetof(ExecContext, syscall_errno), SD_BUS_VTABLE_PROPERTY_CONST),
     804                 :            :         SD_BUS_PROPERTY("Personality", "s", property_get_personality, offsetof(ExecContext, personality), SD_BUS_VTABLE_PROPERTY_CONST),
     805                 :            :         SD_BUS_PROPERTY("LockPersonality", "b", bus_property_get_bool, offsetof(ExecContext, lock_personality), SD_BUS_VTABLE_PROPERTY_CONST),
     806                 :            :         SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     807                 :            :         SD_BUS_PROPERTY("RuntimeDirectoryPreserve", "s", property_get_exec_preserve_mode, offsetof(ExecContext, runtime_directory_preserve_mode), SD_BUS_VTABLE_PROPERTY_CONST),
     808                 :            :         SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME].mode), SD_BUS_VTABLE_PROPERTY_CONST),
     809                 :            :         SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME].paths), SD_BUS_VTABLE_PROPERTY_CONST),
     810                 :            :         SD_BUS_PROPERTY("StateDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].mode), SD_BUS_VTABLE_PROPERTY_CONST),
     811                 :            :         SD_BUS_PROPERTY("StateDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].paths), SD_BUS_VTABLE_PROPERTY_CONST),
     812                 :            :         SD_BUS_PROPERTY("CacheDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].mode), SD_BUS_VTABLE_PROPERTY_CONST),
     813                 :            :         SD_BUS_PROPERTY("CacheDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_CACHE].paths), SD_BUS_VTABLE_PROPERTY_CONST),
     814                 :            :         SD_BUS_PROPERTY("LogsDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].mode), SD_BUS_VTABLE_PROPERTY_CONST),
     815                 :            :         SD_BUS_PROPERTY("LogsDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_LOGS].paths), SD_BUS_VTABLE_PROPERTY_CONST),
     816                 :            :         SD_BUS_PROPERTY("ConfigurationDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION].mode), SD_BUS_VTABLE_PROPERTY_CONST),
     817                 :            :         SD_BUS_PROPERTY("ConfigurationDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_CONFIGURATION].paths), SD_BUS_VTABLE_PROPERTY_CONST),
     818                 :            :         SD_BUS_PROPERTY("MemoryDenyWriteExecute", "b", bus_property_get_bool, offsetof(ExecContext, memory_deny_write_execute), SD_BUS_VTABLE_PROPERTY_CONST),
     819                 :            :         SD_BUS_PROPERTY("RestrictRealtime", "b", bus_property_get_bool, offsetof(ExecContext, restrict_realtime), SD_BUS_VTABLE_PROPERTY_CONST),
     820                 :            :         SD_BUS_PROPERTY("RestrictSUIDSGID", "b", bus_property_get_bool, offsetof(ExecContext, restrict_suid_sgid), SD_BUS_VTABLE_PROPERTY_CONST),
     821                 :            :         SD_BUS_PROPERTY("RestrictNamespaces", "t", bus_property_get_ulong, offsetof(ExecContext, restrict_namespaces), SD_BUS_VTABLE_PROPERTY_CONST),
     822                 :            :         SD_BUS_PROPERTY("BindPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     823                 :            :         SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     824                 :            :         SD_BUS_PROPERTY("TemporaryFileSystem", "a(ss)", property_get_temporary_filesystems, 0, SD_BUS_VTABLE_PROPERTY_CONST),
     825                 :            :         SD_BUS_PROPERTY("MountAPIVFS", "b", bus_property_get_bool, offsetof(ExecContext, mount_apivfs), SD_BUS_VTABLE_PROPERTY_CONST),
     826                 :            :         SD_BUS_PROPERTY("KeyringMode", "s", property_get_exec_keyring_mode, offsetof(ExecContext, keyring_mode), SD_BUS_VTABLE_PROPERTY_CONST),
     827                 :            :         SD_BUS_PROPERTY("ProtectHostname", "b", bus_property_get_bool, offsetof(ExecContext, protect_hostname), SD_BUS_VTABLE_PROPERTY_CONST),
     828                 :            :         SD_BUS_PROPERTY("NetworkNamespacePath", "s", NULL, offsetof(ExecContext, network_namespace_path), SD_BUS_VTABLE_PROPERTY_CONST),
     829                 :            : 
     830                 :            :         /* Obsolete/redundant properties: */
     831                 :            :         SD_BUS_PROPERTY("Capabilities", "s", property_get_empty_string, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
     832                 :            :         SD_BUS_PROPERTY("ReadWriteDirectories", "as", NULL, offsetof(ExecContext, read_write_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
     833                 :            :         SD_BUS_PROPERTY("ReadOnlyDirectories", "as", NULL, offsetof(ExecContext, read_only_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
     834                 :            :         SD_BUS_PROPERTY("InaccessibleDirectories", "as", NULL, offsetof(ExecContext, inaccessible_paths), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
     835                 :            :         SD_BUS_PROPERTY("IOScheduling", "i", property_get_ioprio, 0, SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
     836                 :            : 
     837                 :            :         SD_BUS_VTABLE_END
     838                 :            : };
     839                 :            : 
     840                 :          0 : static int append_exec_command(sd_bus_message *reply, ExecCommand *c) {
     841                 :            :         int r;
     842                 :            : 
     843         [ #  # ]:          0 :         assert(reply);
     844         [ #  # ]:          0 :         assert(c);
     845                 :            : 
     846         [ #  # ]:          0 :         if (!c->path)
     847                 :          0 :                 return 0;
     848                 :            : 
     849                 :          0 :         r = sd_bus_message_open_container(reply, 'r', "sasbttttuii");
     850         [ #  # ]:          0 :         if (r < 0)
     851                 :          0 :                 return r;
     852                 :            : 
     853                 :          0 :         r = sd_bus_message_append(reply, "s", c->path);
     854         [ #  # ]:          0 :         if (r < 0)
     855                 :          0 :                 return r;
     856                 :            : 
     857                 :          0 :         r = sd_bus_message_append_strv(reply, c->argv);
     858         [ #  # ]:          0 :         if (r < 0)
     859                 :          0 :                 return r;
     860                 :            : 
     861                 :          0 :         r = sd_bus_message_append(reply, "bttttuii",
     862                 :          0 :                                   !!(c->flags & EXEC_COMMAND_IGNORE_FAILURE),
     863                 :            :                                   c->exec_status.start_timestamp.realtime,
     864                 :            :                                   c->exec_status.start_timestamp.monotonic,
     865                 :            :                                   c->exec_status.exit_timestamp.realtime,
     866                 :            :                                   c->exec_status.exit_timestamp.monotonic,
     867                 :          0 :                                   (uint32_t) c->exec_status.pid,
     868                 :            :                                   (int32_t) c->exec_status.code,
     869                 :            :                                   (int32_t) c->exec_status.status);
     870         [ #  # ]:          0 :         if (r < 0)
     871                 :          0 :                 return r;
     872                 :            : 
     873                 :          0 :         return sd_bus_message_close_container(reply);
     874                 :            : }
     875                 :            : 
     876                 :          0 : static int append_exec_ex_command(sd_bus_message *reply, ExecCommand *c) {
     877                 :          0 :         _cleanup_strv_free_ char **ex_opts = NULL;
     878                 :            :         int r;
     879                 :            : 
     880         [ #  # ]:          0 :         assert(reply);
     881         [ #  # ]:          0 :         assert(c);
     882                 :            : 
     883         [ #  # ]:          0 :         if (!c->path)
     884                 :          0 :                 return 0;
     885                 :            : 
     886                 :          0 :         r = sd_bus_message_open_container(reply, 'r', "sasasttttuii");
     887         [ #  # ]:          0 :         if (r < 0)
     888                 :          0 :                 return r;
     889                 :            : 
     890                 :          0 :         r = sd_bus_message_append(reply, "s", c->path);
     891         [ #  # ]:          0 :         if (r < 0)
     892                 :          0 :                 return r;
     893                 :            : 
     894                 :          0 :         r = sd_bus_message_append_strv(reply, c->argv);
     895         [ #  # ]:          0 :         if (r < 0)
     896                 :          0 :                 return r;
     897                 :            : 
     898                 :          0 :         r = exec_command_flags_to_strv(c->flags, &ex_opts);
     899         [ #  # ]:          0 :         if (r < 0)
     900                 :          0 :                 return r;
     901                 :            : 
     902                 :          0 :         r = sd_bus_message_append_strv(reply, ex_opts);
     903         [ #  # ]:          0 :         if (r < 0)
     904                 :          0 :                 return r;
     905                 :            : 
     906                 :          0 :         r = sd_bus_message_append(reply, "ttttuii",
     907                 :            :                                   c->exec_status.start_timestamp.realtime,
     908                 :            :                                   c->exec_status.start_timestamp.monotonic,
     909                 :            :                                   c->exec_status.exit_timestamp.realtime,
     910                 :            :                                   c->exec_status.exit_timestamp.monotonic,
     911                 :          0 :                                   (uint32_t) c->exec_status.pid,
     912                 :            :                                   (int32_t) c->exec_status.code,
     913                 :            :                                   (int32_t) c->exec_status.status);
     914         [ #  # ]:          0 :         if (r < 0)
     915                 :          0 :                 return r;
     916                 :            : 
     917                 :          0 :         return sd_bus_message_close_container(reply);
     918                 :            : }
     919                 :            : 
     920                 :          0 : int bus_property_get_exec_command(
     921                 :            :                 sd_bus *bus,
     922                 :            :                 const char *path,
     923                 :            :                 const char *interface,
     924                 :            :                 const char *property,
     925                 :            :                 sd_bus_message *reply,
     926                 :            :                 void *userdata,
     927                 :            :                 sd_bus_error *ret_error) {
     928                 :            : 
     929                 :          0 :         ExecCommand *c = (ExecCommand*) userdata;
     930                 :            :         int r;
     931                 :            : 
     932         [ #  # ]:          0 :         assert(bus);
     933         [ #  # ]:          0 :         assert(reply);
     934                 :            : 
     935                 :          0 :         r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
     936         [ #  # ]:          0 :         if (r < 0)
     937                 :          0 :                 return r;
     938                 :            : 
     939                 :          0 :         r = append_exec_command(reply, c);
     940         [ #  # ]:          0 :         if (r < 0)
     941                 :          0 :                 return r;
     942                 :            : 
     943                 :          0 :         return sd_bus_message_close_container(reply);
     944                 :            : }
     945                 :            : 
     946                 :          0 : int bus_property_get_exec_command_list(
     947                 :            :                 sd_bus *bus,
     948                 :            :                 const char *path,
     949                 :            :                 const char *interface,
     950                 :            :                 const char *property,
     951                 :            :                 sd_bus_message *reply,
     952                 :            :                 void *userdata,
     953                 :            :                 sd_bus_error *ret_error) {
     954                 :            : 
     955                 :          0 :         ExecCommand *c = *(ExecCommand**) userdata;
     956                 :            :         int r;
     957                 :            : 
     958         [ #  # ]:          0 :         assert(bus);
     959         [ #  # ]:          0 :         assert(reply);
     960                 :            : 
     961                 :          0 :         r = sd_bus_message_open_container(reply, 'a', "(sasbttttuii)");
     962         [ #  # ]:          0 :         if (r < 0)
     963                 :          0 :                 return r;
     964                 :            : 
     965         [ #  # ]:          0 :         LIST_FOREACH(command, c, c) {
     966                 :          0 :                 r = append_exec_command(reply, c);
     967         [ #  # ]:          0 :                 if (r < 0)
     968                 :          0 :                         return r;
     969                 :            :         }
     970                 :            : 
     971                 :          0 :         return sd_bus_message_close_container(reply);
     972                 :            : }
     973                 :            : 
     974                 :          0 : int bus_property_get_exec_ex_command_list(
     975                 :            :                 sd_bus *bus,
     976                 :            :                 const char *path,
     977                 :            :                 const char *interface,
     978                 :            :                 const char *property,
     979                 :            :                 sd_bus_message *reply,
     980                 :            :                 void *userdata,
     981                 :            :                 sd_bus_error *ret_error) {
     982                 :            : 
     983                 :          0 :         ExecCommand *c, *exec_command = *(ExecCommand**) userdata;
     984                 :            :         int r;
     985                 :            : 
     986         [ #  # ]:          0 :         assert(bus);
     987         [ #  # ]:          0 :         assert(reply);
     988                 :            : 
     989                 :          0 :         r = sd_bus_message_open_container(reply, 'a', "(sasasttttuii)");
     990         [ #  # ]:          0 :         if (r < 0)
     991                 :          0 :                 return r;
     992                 :            : 
     993         [ #  # ]:          0 :         LIST_FOREACH(command, c, exec_command) {
     994                 :          0 :                 r = append_exec_ex_command(reply, c);
     995         [ #  # ]:          0 :                 if (r < 0)
     996                 :          0 :                         return r;
     997                 :            :         }
     998                 :            : 
     999                 :          0 :         return sd_bus_message_close_container(reply);
    1000                 :            : }
    1001                 :            : 
    1002                 :          0 : static char *exec_command_flags_to_exec_chars(ExecCommandFlags flags) {
    1003   [ #  #  #  #  :          0 :         return strjoin(FLAGS_SET(flags, EXEC_COMMAND_IGNORE_FAILURE)   ? "-" : "",
          #  #  #  #  #  
                      # ]
    1004                 :            :                        FLAGS_SET(flags, EXEC_COMMAND_NO_ENV_EXPAND)    ? ":" : "",
    1005                 :            :                        FLAGS_SET(flags, EXEC_COMMAND_FULLY_PRIVILEGED) ? "+" : "",
    1006                 :            :                        FLAGS_SET(flags, EXEC_COMMAND_NO_SETUID)        ? "!" : "",
    1007                 :            :                        FLAGS_SET(flags, EXEC_COMMAND_AMBIENT_MAGIC)    ? "!!" : "");
    1008                 :            : }
    1009                 :            : 
    1010                 :          0 : int bus_set_transient_exec_command(
    1011                 :            :                 Unit *u,
    1012                 :            :                 const char *name,
    1013                 :            :                 ExecCommand **exec_command,
    1014                 :            :                 sd_bus_message *message,
    1015                 :            :                 UnitWriteFlags flags,
    1016                 :            :                 sd_bus_error *error) {
    1017                 :          0 :         bool is_ex_prop = endswith(name, "Ex");
    1018                 :          0 :         unsigned n = 0;
    1019                 :            :         int r;
    1020                 :            : 
    1021         [ #  # ]:          0 :         r = sd_bus_message_enter_container(message, 'a', is_ex_prop ? "(sasas)" : "(sasb)");
    1022         [ #  # ]:          0 :         if (r < 0)
    1023                 :          0 :                 return r;
    1024                 :            : 
    1025   [ #  #  #  # ]:          0 :         while ((r = sd_bus_message_enter_container(message, 'r', is_ex_prop ? "sasas" : "sasb")) > 0) {
    1026   [ #  #  #  # ]:          0 :                 _cleanup_strv_free_ char **argv = NULL, **ex_opts = NULL;
    1027                 :            :                 const char *path;
    1028                 :            :                 int b;
    1029                 :            : 
    1030                 :          0 :                 r = sd_bus_message_read(message, "s", &path);
    1031         [ #  # ]:          0 :                 if (r < 0)
    1032                 :          0 :                         return r;
    1033                 :            : 
    1034         [ #  # ]:          0 :                 if (!path_is_absolute(path))
    1035                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
    1036                 :            : 
    1037                 :          0 :                 r = sd_bus_message_read_strv(message, &argv);
    1038         [ #  # ]:          0 :                 if (r < 0)
    1039                 :          0 :                         return r;
    1040                 :            : 
    1041         [ #  # ]:          0 :                 r = is_ex_prop ? sd_bus_message_read_strv(message, &ex_opts) : sd_bus_message_read(message, "b", &b);
    1042         [ #  # ]:          0 :                 if (r < 0)
    1043                 :          0 :                         return r;
    1044                 :            : 
    1045                 :          0 :                 r = sd_bus_message_exit_container(message);
    1046         [ #  # ]:          0 :                 if (r < 0)
    1047                 :          0 :                         return r;
    1048                 :            : 
    1049         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1050                 :            :                         ExecCommand *c;
    1051                 :            : 
    1052                 :          0 :                         c = new0(ExecCommand, 1);
    1053         [ #  # ]:          0 :                         if (!c)
    1054                 :          0 :                                 return -ENOMEM;
    1055                 :            : 
    1056                 :          0 :                         c->path = strdup(path);
    1057         [ #  # ]:          0 :                         if (!c->path) {
    1058                 :          0 :                                 free(c);
    1059                 :          0 :                                 return -ENOMEM;
    1060                 :            :                         }
    1061                 :            : 
    1062                 :          0 :                         c->argv = TAKE_PTR(argv);
    1063                 :            : 
    1064         [ #  # ]:          0 :                         if (is_ex_prop) {
    1065                 :          0 :                                 r = exec_command_flags_from_strv(ex_opts, &c->flags);
    1066         [ #  # ]:          0 :                                 if (r < 0)
    1067                 :          0 :                                         return r;
    1068                 :            :                         } else
    1069                 :          0 :                                 c->flags = b ? EXEC_COMMAND_IGNORE_FAILURE : 0;
    1070                 :            : 
    1071                 :          0 :                         path_simplify(c->path, false);
    1072                 :          0 :                         exec_command_append_list(exec_command, c);
    1073                 :            :                 }
    1074                 :            : 
    1075                 :          0 :                 n++;
    1076                 :            :         }
    1077         [ #  # ]:          0 :         if (r < 0)
    1078                 :          0 :                 return r;
    1079                 :            : 
    1080                 :          0 :         r = sd_bus_message_exit_container(message);
    1081         [ #  # ]:          0 :         if (r < 0)
    1082                 :          0 :                 return r;
    1083                 :            : 
    1084         [ #  # ]:          0 :         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1085         [ #  # ]:          0 :                 _cleanup_free_ char *buf = NULL;
    1086         [ #  # ]:          0 :                 _cleanup_fclose_ FILE *f = NULL;
    1087                 :            :                 ExecCommand *c;
    1088                 :          0 :                 size_t size = 0;
    1089                 :            : 
    1090         [ #  # ]:          0 :                 if (n == 0)
    1091                 :          0 :                         *exec_command = exec_command_free_list(*exec_command);
    1092                 :            : 
    1093                 :          0 :                 f = open_memstream_unlocked(&buf, &size);
    1094         [ #  # ]:          0 :                 if (!f)
    1095                 :          0 :                         return -ENOMEM;
    1096                 :            : 
    1097                 :          0 :                 fputs("ExecStart=\n", f);
    1098                 :            : 
    1099         [ #  # ]:          0 :                 LIST_FOREACH(command, c, *exec_command) {
    1100   [ #  #  #  #  :          0 :                         _cleanup_free_ char *a = NULL, *t = NULL, *exec_chars = NULL;
                   #  # ]
    1101                 :            :                         const char *p;
    1102                 :            : 
    1103                 :          0 :                         p = unit_escape_setting(c->path, UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS, &t);
    1104         [ #  # ]:          0 :                         if (!p)
    1105                 :          0 :                                 return -ENOMEM;
    1106                 :            : 
    1107                 :          0 :                         a = unit_concat_strv(c->argv, UNIT_ESCAPE_C|UNIT_ESCAPE_SPECIFIERS);
    1108         [ #  # ]:          0 :                         if (!a)
    1109                 :          0 :                                 return -ENOMEM;
    1110                 :            : 
    1111                 :          0 :                         exec_chars = exec_command_flags_to_exec_chars(c->flags);
    1112         [ #  # ]:          0 :                         if (!exec_chars)
    1113                 :          0 :                                 return -ENOMEM;
    1114                 :            : 
    1115                 :          0 :                         fprintf(f, "%s=%s@%s %s\n", name, exec_chars, p, a);
    1116                 :            :                 }
    1117                 :            : 
    1118                 :          0 :                 r = fflush_and_check(f);
    1119         [ #  # ]:          0 :                 if (r < 0)
    1120                 :          0 :                         return r;
    1121                 :            : 
    1122                 :          0 :                 unit_write_setting(u, flags, name, buf);
    1123                 :            :         }
    1124                 :            : 
    1125                 :          0 :         return 1;
    1126                 :            : }
    1127                 :            : 
    1128                 :          0 : static int parse_personality(const char *s, unsigned long *p) {
    1129                 :            :         unsigned long v;
    1130                 :            : 
    1131         [ #  # ]:          0 :         assert(p);
    1132                 :            : 
    1133                 :          0 :         v = personality_from_string(s);
    1134         [ #  # ]:          0 :         if (v == PERSONALITY_INVALID)
    1135                 :          0 :                 return -EINVAL;
    1136                 :            : 
    1137                 :          0 :         *p = v;
    1138                 :          0 :         return 0;
    1139                 :            : }
    1140                 :            : 
    1141                 :          0 : static const char* mount_propagation_flags_to_string_with_check(unsigned long n) {
    1142   [ #  #  #  # ]:          0 :         if (!IN_SET(n, 0, MS_SHARED, MS_PRIVATE, MS_SLAVE))
    1143                 :          0 :                 return NULL;
    1144                 :            : 
    1145                 :          0 :         return mount_propagation_flags_to_string(n);
    1146                 :            : }
    1147                 :            : 
    1148   [ #  #  #  #  :          0 : static BUS_DEFINE_SET_TRANSIENT(nsec, "t", uint64_t, nsec_t, NSEC_FMT);
                   #  # ]
    1149   [ #  #  #  #  :          0 : static BUS_DEFINE_SET_TRANSIENT_IS_VALID(log_level, "i", int32_t, int, "%" PRIi32, log_level_is_valid);
             #  #  #  # ]
    1150                 :            : #if HAVE_SECCOMP
    1151   [ #  #  #  #  :          0 : static BUS_DEFINE_SET_TRANSIENT_IS_VALID(errno, "i", int32_t, int, "%" PRIi32, errno_is_valid);
             #  #  #  # ]
    1152                 :            : #endif
    1153   [ #  #  #  #  :          0 : static BUS_DEFINE_SET_TRANSIENT_PARSE(std_input, ExecInput, exec_input_from_string);
             #  #  #  # ]
    1154   [ #  #  #  #  :          0 : static BUS_DEFINE_SET_TRANSIENT_PARSE(std_output, ExecOutput, exec_output_from_string);
             #  #  #  # ]
    1155   [ #  #  #  #  :          0 : static BUS_DEFINE_SET_TRANSIENT_PARSE(utmp_mode, ExecUtmpMode, exec_utmp_mode_from_string);
             #  #  #  # ]
    1156   [ #  #  #  #  :          0 : static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_system, ProtectSystem, protect_system_from_string);
             #  #  #  # ]
    1157   [ #  #  #  #  :          0 : static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_home, ProtectHome, protect_home_from_string);
             #  #  #  # ]
    1158   [ #  #  #  #  :          0 : static BUS_DEFINE_SET_TRANSIENT_PARSE(keyring_mode, ExecKeyringMode, exec_keyring_mode_from_string);
             #  #  #  # ]
    1159   [ #  #  #  #  :          0 : static BUS_DEFINE_SET_TRANSIENT_PARSE(preserve_mode, ExecPreserveMode, exec_preserve_mode_from_string);
             #  #  #  # ]
    1160   [ #  #  #  #  :          0 : static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(personality, unsigned long, parse_personality);
             #  #  #  # ]
    1161   [ #  #  #  #  :          0 : static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(secure_bits, "i", int32_t, int, "%" PRIi32, secure_bits_to_string_alloc_with_check);
          #  #  #  #  #  
                      # ]
    1162   [ #  #  #  #  :          0 : static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(capability, "t", uint64_t, uint64_t, "%" PRIu64, capability_set_to_string_alloc);
          #  #  #  #  #  
                      # ]
    1163   [ #  #  #  #  :          0 : static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(namespace_flag, "t", uint64_t, unsigned long, "%" PRIu64, namespace_flags_to_string);
          #  #  #  #  #  
                      # ]
    1164   [ #  #  #  #  :          0 : static BUS_DEFINE_SET_TRANSIENT_TO_STRING(mount_flags, "t", uint64_t, unsigned long, "%" PRIu64, mount_propagation_flags_to_string_with_check);
             #  #  #  # ]
    1165                 :            : 
    1166                 :          0 : int bus_exec_context_set_transient_property(
    1167                 :            :                 Unit *u,
    1168                 :            :                 ExecContext *c,
    1169                 :            :                 const char *name,
    1170                 :            :                 sd_bus_message *message,
    1171                 :            :                 UnitWriteFlags flags,
    1172                 :            :                 sd_bus_error *error) {
    1173                 :            : 
    1174                 :            :         const char *suffix;
    1175                 :            :         int r;
    1176                 :            : 
    1177         [ #  # ]:          0 :         assert(u);
    1178         [ #  # ]:          0 :         assert(c);
    1179         [ #  # ]:          0 :         assert(name);
    1180         [ #  # ]:          0 :         assert(message);
    1181                 :            : 
    1182                 :          0 :         flags |= UNIT_PRIVATE;
    1183                 :            : 
    1184         [ #  # ]:          0 :         if (streq(name, "User"))
    1185                 :          0 :                 return bus_set_transient_user(u, name, &c->user, message, flags, error);
    1186                 :            : 
    1187         [ #  # ]:          0 :         if (streq(name, "Group"))
    1188                 :          0 :                 return bus_set_transient_user(u, name, &c->group, message, flags, error);
    1189                 :            : 
    1190         [ #  # ]:          0 :         if (streq(name, "TTYPath"))
    1191                 :          0 :                 return bus_set_transient_path(u, name, &c->tty_path, message, flags, error);
    1192                 :            : 
    1193         [ #  # ]:          0 :         if (streq(name, "RootImage"))
    1194                 :          0 :                 return bus_set_transient_path(u, name, &c->root_image, message, flags, error);
    1195                 :            : 
    1196         [ #  # ]:          0 :         if (streq(name, "RootDirectory"))
    1197                 :          0 :                 return bus_set_transient_path(u, name, &c->root_directory, message, flags, error);
    1198                 :            : 
    1199         [ #  # ]:          0 :         if (streq(name, "SyslogIdentifier"))
    1200                 :          0 :                 return bus_set_transient_string(u, name, &c->syslog_identifier, message, flags, error);
    1201                 :            : 
    1202         [ #  # ]:          0 :         if (streq(name, "LogLevelMax"))
    1203                 :          0 :                 return bus_set_transient_log_level(u, name, &c->log_level_max, message, flags, error);
    1204                 :            : 
    1205         [ #  # ]:          0 :         if (streq(name, "LogRateLimitIntervalUSec"))
    1206                 :          0 :                 return bus_set_transient_usec(u, name, &c->log_rate_limit_interval_usec, message, flags, error);
    1207                 :            : 
    1208         [ #  # ]:          0 :         if (streq(name, "LogRateLimitBurst"))
    1209                 :          0 :                 return bus_set_transient_unsigned(u, name, &c->log_rate_limit_burst, message, flags, error);
    1210                 :            : 
    1211         [ #  # ]:          0 :         if (streq(name, "Personality"))
    1212                 :          0 :                 return bus_set_transient_personality(u, name, &c->personality, message, flags, error);
    1213                 :            : 
    1214         [ #  # ]:          0 :         if (streq(name, "StandardInput"))
    1215                 :          0 :                 return bus_set_transient_std_input(u, name, &c->std_input, message, flags, error);
    1216                 :            : 
    1217         [ #  # ]:          0 :         if (streq(name, "StandardOutput"))
    1218                 :          0 :                 return bus_set_transient_std_output(u, name, &c->std_output, message, flags, error);
    1219                 :            : 
    1220         [ #  # ]:          0 :         if (streq(name, "StandardError"))
    1221                 :          0 :                 return bus_set_transient_std_output(u, name, &c->std_error, message, flags, error);
    1222                 :            : 
    1223         [ #  # ]:          0 :         if (streq(name, "IgnoreSIGPIPE"))
    1224                 :          0 :                 return bus_set_transient_bool(u, name, &c->ignore_sigpipe, message, flags, error);
    1225                 :            : 
    1226         [ #  # ]:          0 :         if (streq(name, "TTYVHangup"))
    1227                 :          0 :                 return bus_set_transient_bool(u, name, &c->tty_vhangup, message, flags, error);
    1228                 :            : 
    1229         [ #  # ]:          0 :         if (streq(name, "TTYReset"))
    1230                 :          0 :                 return bus_set_transient_bool(u, name, &c->tty_reset, message, flags, error);
    1231                 :            : 
    1232         [ #  # ]:          0 :         if (streq(name, "TTYVTDisallocate"))
    1233                 :          0 :                 return bus_set_transient_bool(u, name, &c->tty_vt_disallocate, message, flags, error);
    1234                 :            : 
    1235         [ #  # ]:          0 :         if (streq(name, "PrivateTmp"))
    1236                 :          0 :                 return bus_set_transient_bool(u, name, &c->private_tmp, message, flags, error);
    1237                 :            : 
    1238         [ #  # ]:          0 :         if (streq(name, "PrivateDevices"))
    1239                 :          0 :                 return bus_set_transient_bool(u, name, &c->private_devices, message, flags, error);
    1240                 :            : 
    1241         [ #  # ]:          0 :         if (streq(name, "PrivateMounts"))
    1242                 :          0 :                 return bus_set_transient_bool(u, name, &c->private_mounts, message, flags, error);
    1243                 :            : 
    1244         [ #  # ]:          0 :         if (streq(name, "PrivateNetwork"))
    1245                 :          0 :                 return bus_set_transient_bool(u, name, &c->private_network, message, flags, error);
    1246                 :            : 
    1247         [ #  # ]:          0 :         if (streq(name, "PrivateUsers"))
    1248                 :          0 :                 return bus_set_transient_bool(u, name, &c->private_users, message, flags, error);
    1249                 :            : 
    1250         [ #  # ]:          0 :         if (streq(name, "NoNewPrivileges"))
    1251                 :          0 :                 return bus_set_transient_bool(u, name, &c->no_new_privileges, message, flags, error);
    1252                 :            : 
    1253         [ #  # ]:          0 :         if (streq(name, "SyslogLevelPrefix"))
    1254                 :          0 :                 return bus_set_transient_bool(u, name, &c->syslog_level_prefix, message, flags, error);
    1255                 :            : 
    1256         [ #  # ]:          0 :         if (streq(name, "MemoryDenyWriteExecute"))
    1257                 :          0 :                 return bus_set_transient_bool(u, name, &c->memory_deny_write_execute, message, flags, error);
    1258                 :            : 
    1259         [ #  # ]:          0 :         if (streq(name, "RestrictRealtime"))
    1260                 :          0 :                 return bus_set_transient_bool(u, name, &c->restrict_realtime, message, flags, error);
    1261                 :            : 
    1262         [ #  # ]:          0 :         if (streq(name, "RestrictSUIDSGID"))
    1263                 :          0 :                 return bus_set_transient_bool(u, name, &c->restrict_suid_sgid, message, flags, error);
    1264                 :            : 
    1265         [ #  # ]:          0 :         if (streq(name, "DynamicUser"))
    1266                 :          0 :                 return bus_set_transient_bool(u, name, &c->dynamic_user, message, flags, error);
    1267                 :            : 
    1268         [ #  # ]:          0 :         if (streq(name, "RemoveIPC"))
    1269                 :          0 :                 return bus_set_transient_bool(u, name, &c->remove_ipc, message, flags, error);
    1270                 :            : 
    1271         [ #  # ]:          0 :         if (streq(name, "ProtectKernelTunables"))
    1272                 :          0 :                 return bus_set_transient_bool(u, name, &c->protect_kernel_tunables, message, flags, error);
    1273                 :            : 
    1274         [ #  # ]:          0 :         if (streq(name, "ProtectKernelModules"))
    1275                 :          0 :                 return bus_set_transient_bool(u, name, &c->protect_kernel_modules, message, flags, error);
    1276                 :            : 
    1277         [ #  # ]:          0 :         if (streq(name, "ProtectControlGroups"))
    1278                 :          0 :                 return bus_set_transient_bool(u, name, &c->protect_control_groups, message, flags, error);
    1279                 :            : 
    1280         [ #  # ]:          0 :         if (streq(name, "MountAPIVFS"))
    1281                 :          0 :                 return bus_set_transient_bool(u, name, &c->mount_apivfs, message, flags, error);
    1282                 :            : 
    1283         [ #  # ]:          0 :         if (streq(name, "CPUSchedulingResetOnFork"))
    1284                 :          0 :                 return bus_set_transient_bool(u, name, &c->cpu_sched_reset_on_fork, message, flags, error);
    1285                 :            : 
    1286         [ #  # ]:          0 :         if (streq(name, "NonBlocking"))
    1287                 :          0 :                 return bus_set_transient_bool(u, name, &c->non_blocking, message, flags, error);
    1288                 :            : 
    1289         [ #  # ]:          0 :         if (streq(name, "LockPersonality"))
    1290                 :          0 :                 return bus_set_transient_bool(u, name, &c->lock_personality, message, flags, error);
    1291                 :            : 
    1292         [ #  # ]:          0 :         if (streq(name, "ProtectHostname"))
    1293                 :          0 :                 return bus_set_transient_bool(u, name, &c->protect_hostname, message, flags, error);
    1294                 :            : 
    1295         [ #  # ]:          0 :         if (streq(name, "UtmpIdentifier"))
    1296                 :          0 :                 return bus_set_transient_string(u, name, &c->utmp_id, message, flags, error);
    1297                 :            : 
    1298         [ #  # ]:          0 :         if (streq(name, "UtmpMode"))
    1299                 :          0 :                 return bus_set_transient_utmp_mode(u, name, &c->utmp_mode, message, flags, error);
    1300                 :            : 
    1301         [ #  # ]:          0 :         if (streq(name, "PAMName"))
    1302                 :          0 :                 return bus_set_transient_string(u, name, &c->pam_name, message, flags, error);
    1303                 :            : 
    1304         [ #  # ]:          0 :         if (streq(name, "TimerSlackNSec"))
    1305                 :          0 :                 return bus_set_transient_nsec(u, name, &c->timer_slack_nsec, message, flags, error);
    1306                 :            : 
    1307         [ #  # ]:          0 :         if (streq(name, "ProtectSystem"))
    1308                 :          0 :                 return bus_set_transient_protect_system(u, name, &c->protect_system, message, flags, error);
    1309                 :            : 
    1310         [ #  # ]:          0 :         if (streq(name, "ProtectHome"))
    1311                 :          0 :                 return bus_set_transient_protect_home(u, name, &c->protect_home, message, flags, error);
    1312                 :            : 
    1313         [ #  # ]:          0 :         if (streq(name, "KeyringMode"))
    1314                 :          0 :                 return bus_set_transient_keyring_mode(u, name, &c->keyring_mode, message, flags, error);
    1315                 :            : 
    1316         [ #  # ]:          0 :         if (streq(name, "RuntimeDirectoryPreserve"))
    1317                 :          0 :                 return bus_set_transient_preserve_mode(u, name, &c->runtime_directory_preserve_mode, message, flags, error);
    1318                 :            : 
    1319         [ #  # ]:          0 :         if (streq(name, "UMask"))
    1320                 :          0 :                 return bus_set_transient_mode_t(u, name, &c->umask, message, flags, error);
    1321                 :            : 
    1322         [ #  # ]:          0 :         if (streq(name, "RuntimeDirectoryMode"))
    1323                 :          0 :                 return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_RUNTIME].mode, message, flags, error);
    1324                 :            : 
    1325         [ #  # ]:          0 :         if (streq(name, "StateDirectoryMode"))
    1326                 :          0 :                 return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_STATE].mode, message, flags, error);
    1327                 :            : 
    1328         [ #  # ]:          0 :         if (streq(name, "CacheDirectoryMode"))
    1329                 :          0 :                 return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_CACHE].mode, message, flags, error);
    1330                 :            : 
    1331         [ #  # ]:          0 :         if (streq(name, "LogsDirectoryMode"))
    1332                 :          0 :                 return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_LOGS].mode, message, flags, error);
    1333                 :            : 
    1334         [ #  # ]:          0 :         if (streq(name, "ConfigurationDirectoryMode"))
    1335                 :          0 :                 return bus_set_transient_mode_t(u, name, &c->directories[EXEC_DIRECTORY_CONFIGURATION].mode, message, flags, error);
    1336                 :            : 
    1337         [ #  # ]:          0 :         if (streq(name, "SELinuxContext"))
    1338                 :          0 :                 return bus_set_transient_string(u, name, &c->selinux_context, message, flags, error);
    1339                 :            : 
    1340         [ #  # ]:          0 :         if (streq(name, "SecureBits"))
    1341                 :          0 :                 return bus_set_transient_secure_bits(u, name, &c->secure_bits, message, flags, error);
    1342                 :            : 
    1343         [ #  # ]:          0 :         if (streq(name, "CapabilityBoundingSet"))
    1344                 :          0 :                 return bus_set_transient_capability(u, name, &c->capability_bounding_set, message, flags, error);
    1345                 :            : 
    1346         [ #  # ]:          0 :         if (streq(name, "AmbientCapabilities"))
    1347                 :          0 :                 return bus_set_transient_capability(u, name, &c->capability_ambient_set, message, flags, error);
    1348                 :            : 
    1349         [ #  # ]:          0 :         if (streq(name, "RestrictNamespaces"))
    1350                 :          0 :                 return bus_set_transient_namespace_flag(u, name, &c->restrict_namespaces, message, flags, error);
    1351                 :            : 
    1352         [ #  # ]:          0 :         if (streq(name, "MountFlags"))
    1353                 :          0 :                 return bus_set_transient_mount_flags(u, name, &c->mount_flags, message, flags, error);
    1354                 :            : 
    1355         [ #  # ]:          0 :         if (streq(name, "NetworkNamespacePath"))
    1356                 :          0 :                 return bus_set_transient_path(u, name, &c->network_namespace_path, message, flags, error);
    1357                 :            : 
    1358         [ #  # ]:          0 :         if (streq(name, "SupplementaryGroups")) {
    1359                 :          0 :                 _cleanup_strv_free_ char **l = NULL;
    1360                 :            :                 char **p;
    1361                 :            : 
    1362                 :          0 :                 r = sd_bus_message_read_strv(message, &l);
    1363         [ #  # ]:          0 :                 if (r < 0)
    1364                 :          0 :                         return r;
    1365                 :            : 
    1366   [ #  #  #  # ]:          0 :                 STRV_FOREACH(p, l) {
    1367   [ #  #  #  # ]:          0 :                         if (!isempty(*p) && !valid_user_group_name_or_id(*p))
    1368                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid supplementary group names");
    1369                 :            :                 }
    1370                 :            : 
    1371         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1372         [ #  # ]:          0 :                         if (strv_isempty(l)) {
    1373                 :          0 :                                 c->supplementary_groups = strv_free(c->supplementary_groups);
    1374                 :          0 :                                 unit_write_settingf(u, flags, name, "%s=", name);
    1375                 :            :                         } else {
    1376         [ #  # ]:          0 :                                 _cleanup_free_ char *joined = NULL;
    1377                 :            : 
    1378                 :          0 :                                 r = strv_extend_strv(&c->supplementary_groups, l, true);
    1379         [ #  # ]:          0 :                                 if (r < 0)
    1380                 :          0 :                                         return -ENOMEM;
    1381                 :            : 
    1382                 :          0 :                                 joined = strv_join(c->supplementary_groups, " ");
    1383         [ #  # ]:          0 :                                 if (!joined)
    1384                 :          0 :                                         return -ENOMEM;
    1385                 :            : 
    1386                 :          0 :                                 unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s", name, joined);
    1387                 :            :                         }
    1388                 :            :                 }
    1389                 :            : 
    1390                 :          0 :                 return 1;
    1391                 :            : 
    1392         [ #  # ]:          0 :         } else if (streq(name, "SyslogLevel")) {
    1393                 :            :                 int32_t level;
    1394                 :            : 
    1395                 :          0 :                 r = sd_bus_message_read(message, "i", &level);
    1396         [ #  # ]:          0 :                 if (r < 0)
    1397                 :          0 :                         return r;
    1398                 :            : 
    1399         [ #  # ]:          0 :                 if (!log_level_is_valid(level))
    1400                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Log level value out of range");
    1401                 :            : 
    1402         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1403                 :          0 :                         c->syslog_priority = (c->syslog_priority & LOG_FACMASK) | level;
    1404                 :          0 :                         unit_write_settingf(u, flags, name, "SyslogLevel=%i", level);
    1405                 :            :                 }
    1406                 :            : 
    1407                 :          0 :                 return 1;
    1408                 :            : 
    1409         [ #  # ]:          0 :         } else if (streq(name, "SyslogFacility")) {
    1410                 :            :                 int32_t facility;
    1411                 :            : 
    1412                 :          0 :                 r = sd_bus_message_read(message, "i", &facility);
    1413         [ #  # ]:          0 :                 if (r < 0)
    1414                 :          0 :                         return r;
    1415                 :            : 
    1416         [ #  # ]:          0 :                 if (!log_facility_unshifted_is_valid(facility))
    1417                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Log facility value out of range");
    1418                 :            : 
    1419         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1420                 :          0 :                         c->syslog_priority = (facility << 3) | LOG_PRI(c->syslog_priority);
    1421                 :          0 :                         unit_write_settingf(u, flags, name, "SyslogFacility=%i", facility);
    1422                 :            :                 }
    1423                 :            : 
    1424                 :          0 :                 return 1;
    1425                 :            : 
    1426         [ #  # ]:          0 :         } else if (streq(name, "LogExtraFields")) {
    1427                 :          0 :                 size_t n = 0;
    1428                 :            : 
    1429                 :          0 :                 r = sd_bus_message_enter_container(message, 'a', "ay");
    1430         [ #  # ]:          0 :                 if (r < 0)
    1431                 :          0 :                         return r;
    1432                 :            : 
    1433                 :          0 :                 for (;;) {
    1434      [ #  #  # ]:          0 :                         _cleanup_free_ void *copy = NULL;
    1435                 :            :                         struct iovec *t;
    1436                 :            :                         const char *eq;
    1437                 :            :                         const void *p;
    1438                 :            :                         size_t sz;
    1439                 :            : 
    1440                 :            :                         /* Note that we expect a byte array for each field, instead of a string. That's because on the
    1441                 :            :                          * lower-level journal fields can actually contain binary data and are not restricted to text,
    1442                 :            :                          * and we should not "lose precision" in our types on the way. That said, I am pretty sure
    1443                 :            :                          * actually encoding binary data as unit metadata is not a good idea. Hence we actually refuse
    1444                 :            :                          * any actual binary data, and only accept UTF-8. This allows us to eventually lift this
    1445                 :            :                          * limitation, should a good, valid usecase arise. */
    1446                 :            : 
    1447                 :          0 :                         r = sd_bus_message_read_array(message, 'y', &p, &sz);
    1448         [ #  # ]:          0 :                         if (r < 0)
    1449                 :          0 :                                 return r;
    1450         [ #  # ]:          0 :                         if (r == 0)
    1451                 :          0 :                                 break;
    1452                 :            : 
    1453         [ #  # ]:          0 :                         if (memchr(p, 0, sz))
    1454                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field contains zero byte");
    1455                 :            : 
    1456                 :          0 :                         eq = memchr(p, '=', sz);
    1457         [ #  # ]:          0 :                         if (!eq)
    1458                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field contains no '=' character");
    1459         [ #  # ]:          0 :                         if (!journal_field_valid(p, eq - (const char*) p, false))
    1460                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field invalid");
    1461                 :            : 
    1462         [ #  # ]:          0 :                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1463                 :          0 :                                 t = reallocarray(c->log_extra_fields, c->n_log_extra_fields+1, sizeof(struct iovec));
    1464         [ #  # ]:          0 :                                 if (!t)
    1465                 :          0 :                                         return -ENOMEM;
    1466                 :          0 :                                 c->log_extra_fields = t;
    1467                 :            :                         }
    1468                 :            : 
    1469                 :          0 :                         copy = malloc(sz + 1);
    1470         [ #  # ]:          0 :                         if (!copy)
    1471                 :          0 :                                 return -ENOMEM;
    1472                 :            : 
    1473                 :          0 :                         memcpy(copy, p, sz);
    1474                 :          0 :                         ((uint8_t*) copy)[sz] = 0;
    1475                 :            : 
    1476         [ #  # ]:          0 :                         if (!utf8_is_valid(copy))
    1477                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Journal field is not valid UTF-8");
    1478                 :            : 
    1479         [ #  # ]:          0 :                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1480                 :          0 :                                 c->log_extra_fields[c->n_log_extra_fields++] = IOVEC_MAKE(copy, sz);
    1481                 :          0 :                                 unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C, name, "LogExtraFields=%s", (char*) copy);
    1482                 :            : 
    1483                 :          0 :                                 copy = NULL;
    1484                 :            :                         }
    1485                 :            : 
    1486                 :          0 :                         n++;
    1487                 :            :                 }
    1488                 :            : 
    1489                 :          0 :                 r = sd_bus_message_exit_container(message);
    1490         [ #  # ]:          0 :                 if (r < 0)
    1491                 :          0 :                         return r;
    1492                 :            : 
    1493   [ #  #  #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags) && n == 0) {
    1494                 :          0 :                         exec_context_free_log_extra_fields(c);
    1495                 :          0 :                         unit_write_setting(u, flags, name, "LogExtraFields=");
    1496                 :            :                 }
    1497                 :            : 
    1498                 :          0 :                 return 1;
    1499                 :            :         }
    1500                 :            : 
    1501                 :            : #if HAVE_SECCOMP
    1502                 :            : 
    1503         [ #  # ]:          0 :         if (streq(name, "SystemCallErrorNumber"))
    1504                 :          0 :                 return bus_set_transient_errno(u, name, &c->syscall_errno, message, flags, error);
    1505                 :            : 
    1506         [ #  # ]:          0 :         if (streq(name, "SystemCallFilter")) {
    1507                 :            :                 int whitelist;
    1508                 :          0 :                 _cleanup_strv_free_ char **l = NULL;
    1509                 :            : 
    1510                 :          0 :                 r = sd_bus_message_enter_container(message, 'r', "bas");
    1511         [ #  # ]:          0 :                 if (r < 0)
    1512                 :          0 :                         return r;
    1513                 :            : 
    1514                 :          0 :                 r = sd_bus_message_read(message, "b", &whitelist);
    1515         [ #  # ]:          0 :                 if (r < 0)
    1516                 :          0 :                         return r;
    1517                 :            : 
    1518                 :          0 :                 r = sd_bus_message_read_strv(message, &l);
    1519         [ #  # ]:          0 :                 if (r < 0)
    1520                 :          0 :                         return r;
    1521                 :            : 
    1522                 :          0 :                 r = sd_bus_message_exit_container(message);
    1523         [ #  # ]:          0 :                 if (r < 0)
    1524                 :          0 :                         return r;
    1525                 :            : 
    1526         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1527         [ #  # ]:          0 :                         _cleanup_free_ char *joined = NULL;
    1528                 :          0 :                         SeccompParseFlags invert_flag = whitelist ? 0 : SECCOMP_PARSE_INVERT;
    1529                 :            :                         char **s;
    1530                 :            : 
    1531         [ #  # ]:          0 :                         if (strv_isempty(l)) {
    1532                 :          0 :                                 c->syscall_whitelist = false;
    1533                 :          0 :                                 c->syscall_filter = hashmap_free(c->syscall_filter);
    1534                 :            : 
    1535                 :          0 :                                 unit_write_settingf(u, flags, name, "SystemCallFilter=");
    1536                 :          0 :                                 return 1;
    1537                 :            :                         }
    1538                 :            : 
    1539         [ #  # ]:          0 :                         if (!c->syscall_filter) {
    1540                 :          0 :                                 c->syscall_filter = hashmap_new(NULL);
    1541         [ #  # ]:          0 :                                 if (!c->syscall_filter)
    1542                 :          0 :                                         return log_oom();
    1543                 :            : 
    1544                 :          0 :                                 c->syscall_whitelist = whitelist;
    1545                 :            : 
    1546         [ #  # ]:          0 :                                 if (c->syscall_whitelist) {
    1547                 :          0 :                                         r = seccomp_parse_syscall_filter("@default",
    1548                 :            :                                                                          -1,
    1549                 :            :                                                                          c->syscall_filter,
    1550                 :          0 :                                                                          SECCOMP_PARSE_WHITELIST | invert_flag,
    1551                 :          0 :                                                                          u->id,
    1552                 :            :                                                                          NULL, 0);
    1553         [ #  # ]:          0 :                                         if (r < 0)
    1554                 :          0 :                                                 return r;
    1555                 :            :                                 }
    1556                 :            :                         }
    1557                 :            : 
    1558   [ #  #  #  # ]:          0 :                         STRV_FOREACH(s, l) {
    1559         [ #  # ]:          0 :                                 _cleanup_free_ char *n = NULL;
    1560                 :            :                                 int e;
    1561                 :            : 
    1562                 :          0 :                                 r = parse_syscall_and_errno(*s, &n, &e);
    1563         [ #  # ]:          0 :                                 if (r < 0)
    1564                 :          0 :                                         return r;
    1565                 :            : 
    1566                 :          0 :                                 r = seccomp_parse_syscall_filter(n,
    1567                 :            :                                                                  e,
    1568                 :            :                                                                  c->syscall_filter,
    1569                 :          0 :                                                                  (c->syscall_whitelist ? SECCOMP_PARSE_WHITELIST : 0) | invert_flag,
    1570                 :          0 :                                                                  u->id,
    1571                 :            :                                                                  NULL, 0);
    1572         [ #  # ]:          0 :                                 if (r < 0)
    1573                 :          0 :                                         return r;
    1574                 :            :                         }
    1575                 :            : 
    1576                 :          0 :                         joined = strv_join(l, " ");
    1577         [ #  # ]:          0 :                         if (!joined)
    1578                 :          0 :                                 return -ENOMEM;
    1579                 :            : 
    1580         [ #  # ]:          0 :                         unit_write_settingf(u, flags, name, "SystemCallFilter=%s%s", whitelist ? "" : "~", joined);
    1581                 :            :                 }
    1582                 :            : 
    1583                 :          0 :                 return 1;
    1584                 :            : 
    1585         [ #  # ]:          0 :         } else if (streq(name, "SystemCallArchitectures")) {
    1586                 :          0 :                 _cleanup_strv_free_ char **l = NULL;
    1587                 :            : 
    1588                 :          0 :                 r = sd_bus_message_read_strv(message, &l);
    1589         [ #  # ]:          0 :                 if (r < 0)
    1590                 :          0 :                         return r;
    1591                 :            : 
    1592         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1593         [ #  # ]:          0 :                         _cleanup_free_ char *joined = NULL;
    1594                 :            : 
    1595         [ #  # ]:          0 :                         if (strv_isempty(l))
    1596                 :          0 :                                 c->syscall_archs = set_free(c->syscall_archs);
    1597                 :            :                         else {
    1598                 :            :                                 char **s;
    1599                 :            : 
    1600                 :          0 :                                 r = set_ensure_allocated(&c->syscall_archs, NULL);
    1601         [ #  # ]:          0 :                                 if (r < 0)
    1602                 :          0 :                                         return r;
    1603                 :            : 
    1604   [ #  #  #  # ]:          0 :                                 STRV_FOREACH(s, l) {
    1605                 :            :                                         uint32_t a;
    1606                 :            : 
    1607                 :          0 :                                         r = seccomp_arch_from_string(*s, &a);
    1608         [ #  # ]:          0 :                                         if (r < 0)
    1609                 :          0 :                                                 return r;
    1610                 :            : 
    1611                 :          0 :                                         r = set_put(c->syscall_archs, UINT32_TO_PTR(a + 1));
    1612         [ #  # ]:          0 :                                         if (r < 0)
    1613                 :          0 :                                                 return r;
    1614                 :            :                                 }
    1615                 :            : 
    1616                 :            :                         }
    1617                 :            : 
    1618                 :          0 :                         joined = strv_join(l, " ");
    1619         [ #  # ]:          0 :                         if (!joined)
    1620                 :          0 :                                 return -ENOMEM;
    1621                 :            : 
    1622                 :          0 :                         unit_write_settingf(u, flags, name, "%s=%s", name, joined);
    1623                 :            :                 }
    1624                 :            : 
    1625                 :          0 :                 return 1;
    1626                 :            : 
    1627         [ #  # ]:          0 :         } else if (streq(name, "RestrictAddressFamilies")) {
    1628                 :            :                 int whitelist;
    1629                 :          0 :                 _cleanup_strv_free_ char **l = NULL;
    1630                 :            : 
    1631                 :          0 :                 r = sd_bus_message_enter_container(message, 'r', "bas");
    1632         [ #  # ]:          0 :                 if (r < 0)
    1633                 :          0 :                         return r;
    1634                 :            : 
    1635                 :          0 :                 r = sd_bus_message_read(message, "b", &whitelist);
    1636         [ #  # ]:          0 :                 if (r < 0)
    1637                 :          0 :                         return r;
    1638                 :            : 
    1639                 :          0 :                 r = sd_bus_message_read_strv(message, &l);
    1640         [ #  # ]:          0 :                 if (r < 0)
    1641                 :          0 :                         return r;
    1642                 :            : 
    1643                 :          0 :                 r = sd_bus_message_exit_container(message);
    1644         [ #  # ]:          0 :                 if (r < 0)
    1645                 :          0 :                         return r;
    1646                 :            : 
    1647         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1648         [ #  # ]:          0 :                         _cleanup_free_ char *joined = NULL;
    1649                 :            :                         char **s;
    1650                 :            : 
    1651         [ #  # ]:          0 :                         if (strv_isempty(l)) {
    1652                 :          0 :                                 c->address_families_whitelist = false;
    1653                 :          0 :                                 c->address_families = set_free(c->address_families);
    1654                 :            : 
    1655                 :          0 :                                 unit_write_settingf(u, flags, name, "RestrictAddressFamilies=");
    1656                 :          0 :                                 return 1;
    1657                 :            :                         }
    1658                 :            : 
    1659         [ #  # ]:          0 :                         if (!c->address_families) {
    1660                 :          0 :                                 c->address_families = set_new(NULL);
    1661         [ #  # ]:          0 :                                 if (!c->address_families)
    1662                 :          0 :                                         return log_oom();
    1663                 :            : 
    1664                 :          0 :                                 c->address_families_whitelist = whitelist;
    1665                 :            :                         }
    1666                 :            : 
    1667   [ #  #  #  # ]:          0 :                         STRV_FOREACH(s, l) {
    1668                 :            :                                 int af;
    1669                 :            : 
    1670                 :          0 :                                 af = af_from_name(*s);
    1671         [ #  # ]:          0 :                                 if (af < 0)
    1672                 :          0 :                                         return af;
    1673                 :            : 
    1674         [ #  # ]:          0 :                                 if (whitelist == c->address_families_whitelist) {
    1675                 :          0 :                                         r = set_put(c->address_families, INT_TO_PTR(af));
    1676         [ #  # ]:          0 :                                         if (r < 0)
    1677                 :          0 :                                                 return r;
    1678                 :            :                                 } else
    1679                 :          0 :                                         (void) set_remove(c->address_families, INT_TO_PTR(af));
    1680                 :            :                         }
    1681                 :            : 
    1682                 :          0 :                         joined = strv_join(l, " ");
    1683         [ #  # ]:          0 :                         if (!joined)
    1684                 :          0 :                                 return -ENOMEM;
    1685                 :            : 
    1686         [ #  # ]:          0 :                         unit_write_settingf(u, flags, name, "RestrictAddressFamilies=%s%s", whitelist ? "" : "~", joined);
    1687                 :            :                 }
    1688                 :            : 
    1689                 :          0 :                 return 1;
    1690                 :            :         }
    1691                 :            : #endif
    1692         [ #  # ]:          0 :         if (STR_IN_SET(name, "CPUAffinity", "NUMAMask")) {
    1693                 :            :                 const void *a;
    1694                 :            :                 size_t n;
    1695                 :          0 :                 bool affinity = streq(name, "CPUAffinity");
    1696                 :          0 :                 _cleanup_(cpu_set_reset) CPUSet set = {};
    1697                 :            : 
    1698                 :          0 :                 r = sd_bus_message_read_array(message, 'y', &a, &n);
    1699         [ #  # ]:          0 :                 if (r < 0)
    1700                 :          0 :                         return r;
    1701                 :            : 
    1702                 :          0 :                 r = cpu_set_from_dbus(a, n, &set);
    1703         [ #  # ]:          0 :                 if (r < 0)
    1704                 :          0 :                         return r;
    1705                 :            : 
    1706         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1707         [ #  # ]:          0 :                         if (n == 0) {
    1708         [ #  # ]:          0 :                                 cpu_set_reset(affinity ? &c->cpu_set : &c->numa_policy.nodes);
    1709                 :          0 :                                 unit_write_settingf(u, flags, name, "%s=", name);
    1710                 :            :                         } else {
    1711         [ #  # ]:          0 :                                 _cleanup_free_ char *str = NULL;
    1712                 :            : 
    1713                 :          0 :                                 str = cpu_set_to_string(&set);
    1714         [ #  # ]:          0 :                                 if (!str)
    1715                 :          0 :                                         return -ENOMEM;
    1716                 :            : 
    1717                 :            :                                 /* We forego any optimizations here, and always create the structure using
    1718                 :            :                                  * cpu_set_add_all(), because we don't want to care if the existing size we
    1719                 :            :                                  * got over dbus is appropriate. */
    1720         [ #  # ]:          0 :                                 r = cpu_set_add_all(affinity ? &c->cpu_set : &c->numa_policy.nodes, &set);
    1721         [ #  # ]:          0 :                                 if (r < 0)
    1722                 :          0 :                                         return r;
    1723                 :            : 
    1724                 :          0 :                                 unit_write_settingf(u, flags, name, "%s=%s", name, str);
    1725                 :            :                         }
    1726                 :            :                 }
    1727                 :            : 
    1728                 :          0 :                 return 1;
    1729                 :            : 
    1730         [ #  # ]:          0 :         } else if (streq(name, "NUMAPolicy")) {
    1731                 :            :                 int32_t type;
    1732                 :            : 
    1733                 :          0 :                 r = sd_bus_message_read(message, "i", &type);
    1734         [ #  # ]:          0 :                 if (r < 0)
    1735                 :          0 :                         return r;
    1736                 :            : 
    1737         [ #  # ]:          0 :                 if (!mpol_is_valid(type))
    1738                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid NUMAPolicy value: %i", type);
    1739                 :            : 
    1740         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags))
    1741                 :          0 :                         c->numa_policy.type = type;
    1742                 :            : 
    1743                 :          0 :                 return 1;
    1744         [ #  # ]:          0 :         } else if (streq(name, "Nice")) {
    1745                 :            :                 int32_t q;
    1746                 :            : 
    1747                 :          0 :                 r = sd_bus_message_read(message, "i", &q);
    1748         [ #  # ]:          0 :                 if (r < 0)
    1749                 :          0 :                         return r;
    1750                 :            : 
    1751         [ #  # ]:          0 :                 if (!nice_is_valid(q))
    1752                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid Nice value: %i", q);
    1753                 :            : 
    1754         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1755                 :          0 :                         c->nice = q;
    1756                 :          0 :                         c->nice_set = true;
    1757                 :            : 
    1758                 :          0 :                         unit_write_settingf(u, flags, name, "Nice=%i", q);
    1759                 :            :                 }
    1760                 :            : 
    1761                 :          0 :                 return 1;
    1762                 :            : 
    1763         [ #  # ]:          0 :         } else if (streq(name, "CPUSchedulingPolicy")) {
    1764                 :            :                 int32_t q;
    1765                 :            : 
    1766                 :          0 :                 r = sd_bus_message_read(message, "i", &q);
    1767         [ #  # ]:          0 :                 if (r < 0)
    1768                 :          0 :                         return r;
    1769                 :            : 
    1770         [ #  # ]:          0 :                 if (!sched_policy_is_valid(q))
    1771                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling policy: %i", q);
    1772                 :            : 
    1773         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1774         [ #  # ]:          0 :                         _cleanup_free_ char *s = NULL;
    1775                 :            : 
    1776                 :          0 :                         r = sched_policy_to_string_alloc(q, &s);
    1777         [ #  # ]:          0 :                         if (r < 0)
    1778                 :          0 :                                 return r;
    1779                 :            : 
    1780                 :          0 :                         c->cpu_sched_policy = q;
    1781         [ #  # ]:          0 :                         c->cpu_sched_priority = CLAMP(c->cpu_sched_priority, sched_get_priority_min(q), sched_get_priority_max(q));
    1782                 :          0 :                         c->cpu_sched_set = true;
    1783                 :            : 
    1784                 :          0 :                         unit_write_settingf(u, flags, name, "CPUSchedulingPolicy=%s", s);
    1785                 :            :                 }
    1786                 :            : 
    1787                 :          0 :                 return 1;
    1788                 :            : 
    1789         [ #  # ]:          0 :         } else if (streq(name, "CPUSchedulingPriority")) {
    1790                 :            :                 int32_t p, min, max;
    1791                 :            : 
    1792                 :          0 :                 r = sd_bus_message_read(message, "i", &p);
    1793         [ #  # ]:          0 :                 if (r < 0)
    1794                 :          0 :                         return r;
    1795                 :            : 
    1796                 :          0 :                 min = sched_get_priority_min(c->cpu_sched_policy);
    1797                 :          0 :                 max = sched_get_priority_max(c->cpu_sched_policy);
    1798   [ #  #  #  # ]:          0 :                 if (p < min || p > max)
    1799                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid CPU scheduling priority: %i", p);
    1800                 :            : 
    1801         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1802                 :          0 :                         c->cpu_sched_priority = p;
    1803                 :          0 :                         c->cpu_sched_set = true;
    1804                 :            : 
    1805                 :          0 :                         unit_write_settingf(u, flags, name, "CPUSchedulingPriority=%i", p);
    1806                 :            :                 }
    1807                 :            : 
    1808                 :          0 :                 return 1;
    1809                 :            : 
    1810         [ #  # ]:          0 :         } else if (streq(name, "IOSchedulingClass")) {
    1811                 :            :                 int32_t q;
    1812                 :            : 
    1813                 :          0 :                 r = sd_bus_message_read(message, "i", &q);
    1814         [ #  # ]:          0 :                 if (r < 0)
    1815                 :          0 :                         return r;
    1816                 :            : 
    1817         [ #  # ]:          0 :                 if (!ioprio_class_is_valid(q))
    1818                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling class: %i", q);
    1819                 :            : 
    1820         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1821         [ #  # ]:          0 :                         _cleanup_free_ char *s = NULL;
    1822                 :            : 
    1823                 :          0 :                         r = ioprio_class_to_string_alloc(q, &s);
    1824         [ #  # ]:          0 :                         if (r < 0)
    1825                 :          0 :                                 return r;
    1826                 :            : 
    1827                 :          0 :                         c->ioprio = IOPRIO_PRIO_VALUE(q, IOPRIO_PRIO_DATA(c->ioprio));
    1828                 :          0 :                         c->ioprio_set = true;
    1829                 :            : 
    1830                 :          0 :                         unit_write_settingf(u, flags, name, "IOSchedulingClass=%s", s);
    1831                 :            :                 }
    1832                 :            : 
    1833                 :          0 :                 return 1;
    1834                 :            : 
    1835         [ #  # ]:          0 :         } else if (streq(name, "IOSchedulingPriority")) {
    1836                 :            :                 int32_t p;
    1837                 :            : 
    1838                 :          0 :                 r = sd_bus_message_read(message, "i", &p);
    1839         [ #  # ]:          0 :                 if (r < 0)
    1840                 :          0 :                         return r;
    1841                 :            : 
    1842         [ #  # ]:          0 :                 if (!ioprio_priority_is_valid(p))
    1843                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid IO scheduling priority: %i", p);
    1844                 :            : 
    1845         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1846                 :          0 :                         c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_PRIO_CLASS(c->ioprio), p);
    1847                 :          0 :                         c->ioprio_set = true;
    1848                 :            : 
    1849                 :          0 :                         unit_write_settingf(u, flags, name, "IOSchedulingPriority=%i", p);
    1850                 :            :                 }
    1851                 :            : 
    1852                 :          0 :                 return 1;
    1853                 :            : 
    1854         [ #  # ]:          0 :         } else if (streq(name, "WorkingDirectory")) {
    1855                 :            :                 const char *s;
    1856                 :            :                 bool missing_ok;
    1857                 :            : 
    1858                 :          0 :                 r = sd_bus_message_read(message, "s", &s);
    1859         [ #  # ]:          0 :                 if (r < 0)
    1860                 :          0 :                         return r;
    1861                 :            : 
    1862         [ #  # ]:          0 :                 if (s[0] == '-') {
    1863                 :          0 :                         missing_ok = true;
    1864                 :          0 :                         s++;
    1865                 :            :                 } else
    1866                 :          0 :                         missing_ok = false;
    1867                 :            : 
    1868   [ #  #  #  #  :          0 :                 if (!isempty(s) && !streq(s, "~") && !path_is_absolute(s))
                   #  # ]
    1869                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "WorkingDirectory= expects an absolute path or '~'");
    1870                 :            : 
    1871         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1872         [ #  # ]:          0 :                         if (streq(s, "~")) {
    1873                 :          0 :                                 c->working_directory = mfree(c->working_directory);
    1874                 :          0 :                                 c->working_directory_home = true;
    1875                 :            :                         } else {
    1876                 :          0 :                                 r = free_and_strdup(&c->working_directory, empty_to_null(s));
    1877         [ #  # ]:          0 :                                 if (r < 0)
    1878                 :          0 :                                         return r;
    1879                 :            : 
    1880                 :          0 :                                 c->working_directory_home = false;
    1881                 :            :                         }
    1882                 :            : 
    1883                 :          0 :                         c->working_directory_missing_ok = missing_ok;
    1884         [ #  # ]:          0 :                         unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "WorkingDirectory=%s%s", missing_ok ? "-" : "", s);
    1885                 :            :                 }
    1886                 :            : 
    1887                 :          0 :                 return 1;
    1888                 :            : 
    1889         [ #  # ]:          0 :         } else if (STR_IN_SET(name,
    1890                 :            :                               "StandardInputFileDescriptorName", "StandardOutputFileDescriptorName", "StandardErrorFileDescriptorName")) {
    1891                 :            :                 const char *s;
    1892                 :            : 
    1893                 :          0 :                 r = sd_bus_message_read(message, "s", &s);
    1894         [ #  # ]:          0 :                 if (r < 0)
    1895                 :          0 :                         return r;
    1896                 :            : 
    1897   [ #  #  #  # ]:          0 :                 if (!isempty(s) && !fdname_is_valid(s))
    1898                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid file descriptor name");
    1899                 :            : 
    1900         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1901                 :            : 
    1902         [ #  # ]:          0 :                         if (streq(name, "StandardInputFileDescriptorName")) {
    1903                 :          0 :                                 r = free_and_strdup(c->stdio_fdname + STDIN_FILENO, empty_to_null(s));
    1904         [ #  # ]:          0 :                                 if (r < 0)
    1905                 :          0 :                                         return r;
    1906                 :            : 
    1907                 :          0 :                                 c->std_input = EXEC_INPUT_NAMED_FD;
    1908                 :          0 :                                 unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=fd:%s", exec_context_fdname(c, STDIN_FILENO));
    1909                 :            : 
    1910         [ #  # ]:          0 :                         } else if (streq(name, "StandardOutputFileDescriptorName")) {
    1911                 :          0 :                                 r = free_and_strdup(c->stdio_fdname + STDOUT_FILENO, empty_to_null(s));
    1912         [ #  # ]:          0 :                                 if (r < 0)
    1913                 :          0 :                                         return r;
    1914                 :            : 
    1915                 :          0 :                                 c->std_output = EXEC_OUTPUT_NAMED_FD;
    1916                 :          0 :                                 unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=fd:%s", exec_context_fdname(c, STDOUT_FILENO));
    1917                 :            : 
    1918                 :            :                         } else {
    1919         [ #  # ]:          0 :                                 assert(streq(name, "StandardErrorFileDescriptorName"));
    1920                 :            : 
    1921                 :          0 :                                 r = free_and_strdup(&c->stdio_fdname[STDERR_FILENO], empty_to_null(s));
    1922         [ #  # ]:          0 :                                 if (r < 0)
    1923                 :          0 :                                         return r;
    1924                 :            : 
    1925                 :          0 :                                 c->std_error = EXEC_OUTPUT_NAMED_FD;
    1926                 :          0 :                                 unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=fd:%s", exec_context_fdname(c, STDERR_FILENO));
    1927                 :            :                         }
    1928                 :            :                 }
    1929                 :            : 
    1930                 :          0 :                 return 1;
    1931                 :            : 
    1932         [ #  # ]:          0 :         } else if (STR_IN_SET(name,
    1933                 :            :                               "StandardInputFile",
    1934                 :            :                               "StandardOutputFile", "StandardOutputFileToAppend",
    1935                 :            :                               "StandardErrorFile", "StandardErrorFileToAppend")) {
    1936                 :            :                 const char *s;
    1937                 :            : 
    1938                 :          0 :                 r = sd_bus_message_read(message, "s", &s);
    1939         [ #  # ]:          0 :                 if (r < 0)
    1940                 :          0 :                         return r;
    1941                 :            : 
    1942         [ #  # ]:          0 :                 if (!isempty(s)) {
    1943         [ #  # ]:          0 :                         if (!path_is_absolute(s))
    1944                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute", s);
    1945         [ #  # ]:          0 :                         if (!path_is_normalized(s))
    1946                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not normalized", s);
    1947                 :            :                 }
    1948                 :            : 
    1949         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    1950                 :            : 
    1951         [ #  # ]:          0 :                         if (streq(name, "StandardInputFile")) {
    1952                 :          0 :                                 r = free_and_strdup(&c->stdio_file[STDIN_FILENO], empty_to_null(s));
    1953         [ #  # ]:          0 :                                 if (r < 0)
    1954                 :          0 :                                         return r;
    1955                 :            : 
    1956                 :          0 :                                 c->std_input = EXEC_INPUT_FILE;
    1957                 :          0 :                                 unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardInput=file:%s", s);
    1958                 :            : 
    1959         [ #  # ]:          0 :                         } else if (STR_IN_SET(name, "StandardOutputFile", "StandardOutputFileToAppend")) {
    1960                 :          0 :                                 r = free_and_strdup(&c->stdio_file[STDOUT_FILENO], empty_to_null(s));
    1961         [ #  # ]:          0 :                                 if (r < 0)
    1962                 :          0 :                                         return r;
    1963                 :            : 
    1964         [ #  # ]:          0 :                                 if (streq(name, "StandardOutputFile")) {
    1965                 :          0 :                                         c->std_output = EXEC_OUTPUT_FILE;
    1966                 :          0 :                                         unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=file:%s", s);
    1967                 :            :                                 } else {
    1968         [ #  # ]:          0 :                                         assert(streq(name, "StandardOutputFileToAppend"));
    1969                 :          0 :                                         c->std_output = EXEC_OUTPUT_FILE_APPEND;
    1970                 :          0 :                                         unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardOutput=append:%s", s);
    1971                 :            :                                 }
    1972                 :            :                         } else {
    1973         [ #  # ]:          0 :                                 assert(STR_IN_SET(name, "StandardErrorFile", "StandardErrorFileToAppend"));
    1974                 :            : 
    1975                 :          0 :                                 r = free_and_strdup(&c->stdio_file[STDERR_FILENO], empty_to_null(s));
    1976         [ #  # ]:          0 :                                 if (r < 0)
    1977                 :          0 :                                         return r;
    1978                 :            : 
    1979         [ #  # ]:          0 :                                 if (streq(name, "StandardErrorFile")) {
    1980                 :          0 :                                         c->std_error = EXEC_OUTPUT_FILE;
    1981                 :          0 :                                         unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=file:%s", s);
    1982                 :            :                                 } else {
    1983         [ #  # ]:          0 :                                         assert(streq(name, "StandardErrorFileToAppend"));
    1984                 :          0 :                                         c->std_error = EXEC_OUTPUT_FILE_APPEND;
    1985                 :          0 :                                         unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "StandardError=append:%s", s);
    1986                 :            :                                 }
    1987                 :            :                         }
    1988                 :            :                 }
    1989                 :            : 
    1990                 :          0 :                 return 1;
    1991                 :            : 
    1992         [ #  # ]:          0 :         } else if (streq(name, "StandardInputData")) {
    1993                 :            :                 const void *p;
    1994                 :            :                 size_t sz;
    1995                 :            : 
    1996                 :          0 :                 r = sd_bus_message_read_array(message, 'y', &p, &sz);
    1997         [ #  # ]:          0 :                 if (r < 0)
    1998                 :          0 :                         return r;
    1999                 :            : 
    2000         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    2001         [ #  # ]:          0 :                         _cleanup_free_ char *encoded = NULL;
    2002                 :            : 
    2003         [ #  # ]:          0 :                         if (sz == 0) {
    2004                 :          0 :                                 c->stdin_data = mfree(c->stdin_data);
    2005                 :          0 :                                 c->stdin_data_size = 0;
    2006                 :            : 
    2007                 :          0 :                                 unit_write_settingf(u, flags, name, "StandardInputData=");
    2008                 :            :                         } else {
    2009                 :            :                                 void *q;
    2010                 :            :                                 ssize_t n;
    2011                 :            : 
    2012         [ #  # ]:          0 :                                 if (c->stdin_data_size + sz < c->stdin_data_size || /* check for overflow */
    2013         [ #  # ]:          0 :                                     c->stdin_data_size + sz > EXEC_STDIN_DATA_MAX)
    2014                 :          0 :                                         return -E2BIG;
    2015                 :            : 
    2016                 :          0 :                                 n = base64mem(p, sz, &encoded);
    2017         [ #  # ]:          0 :                                 if (n < 0)
    2018                 :          0 :                                         return (int) n;
    2019                 :            : 
    2020                 :          0 :                                 q = realloc(c->stdin_data, c->stdin_data_size + sz);
    2021         [ #  # ]:          0 :                                 if (!q)
    2022                 :          0 :                                         return -ENOMEM;
    2023                 :            : 
    2024                 :          0 :                                 memcpy((uint8_t*) q + c->stdin_data_size, p, sz);
    2025                 :            : 
    2026                 :          0 :                                 c->stdin_data = q;
    2027                 :          0 :                                 c->stdin_data_size += sz;
    2028                 :            : 
    2029                 :          0 :                                 unit_write_settingf(u, flags, name, "StandardInputData=%s", encoded);
    2030                 :            :                         }
    2031                 :            :                 }
    2032                 :            : 
    2033                 :          0 :                 return 1;
    2034                 :            : 
    2035         [ #  # ]:          0 :         } else if (streq(name, "Environment")) {
    2036                 :            : 
    2037                 :          0 :                 _cleanup_strv_free_ char **l = NULL;
    2038                 :            : 
    2039                 :          0 :                 r = sd_bus_message_read_strv(message, &l);
    2040         [ #  # ]:          0 :                 if (r < 0)
    2041                 :          0 :                         return r;
    2042                 :            : 
    2043         [ #  # ]:          0 :                 if (!strv_env_is_valid(l))
    2044                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment block.");
    2045                 :            : 
    2046         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    2047         [ #  # ]:          0 :                         if (strv_isempty(l)) {
    2048                 :          0 :                                 c->environment = strv_free(c->environment);
    2049                 :          0 :                                 unit_write_setting(u, flags, name, "Environment=");
    2050                 :            :                         } else {
    2051         [ #  # ]:          0 :                                 _cleanup_free_ char *joined = NULL;
    2052                 :            :                                 char **e;
    2053                 :            : 
    2054                 :          0 :                                 joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C);
    2055         [ #  # ]:          0 :                                 if (!joined)
    2056                 :          0 :                                         return -ENOMEM;
    2057                 :            : 
    2058                 :          0 :                                 e = strv_env_merge(2, c->environment, l);
    2059         [ #  # ]:          0 :                                 if (!e)
    2060                 :          0 :                                         return -ENOMEM;
    2061                 :            : 
    2062                 :          0 :                                 strv_free_and_replace(c->environment, e);
    2063                 :          0 :                                 unit_write_settingf(u, flags, name, "Environment=%s", joined);
    2064                 :            :                         }
    2065                 :            :                 }
    2066                 :            : 
    2067                 :          0 :                 return 1;
    2068                 :            : 
    2069         [ #  # ]:          0 :         } else if (streq(name, "UnsetEnvironment")) {
    2070                 :            : 
    2071                 :          0 :                 _cleanup_strv_free_ char **l = NULL;
    2072                 :            : 
    2073                 :          0 :                 r = sd_bus_message_read_strv(message, &l);
    2074         [ #  # ]:          0 :                 if (r < 0)
    2075                 :          0 :                         return r;
    2076                 :            : 
    2077         [ #  # ]:          0 :                 if (!strv_env_name_or_assignment_is_valid(l))
    2078                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid UnsetEnvironment= list.");
    2079                 :            : 
    2080         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    2081         [ #  # ]:          0 :                         if (strv_isempty(l)) {
    2082                 :          0 :                                 c->unset_environment = strv_free(c->unset_environment);
    2083                 :          0 :                                 unit_write_setting(u, flags, name, "UnsetEnvironment=");
    2084                 :            :                         } else {
    2085         [ #  # ]:          0 :                                 _cleanup_free_ char *joined = NULL;
    2086                 :            :                                 char **e;
    2087                 :            : 
    2088                 :          0 :                                 joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS|UNIT_ESCAPE_C);
    2089         [ #  # ]:          0 :                                 if (!joined)
    2090                 :          0 :                                         return -ENOMEM;
    2091                 :            : 
    2092                 :          0 :                                 e = strv_env_merge(2, c->unset_environment, l);
    2093         [ #  # ]:          0 :                                 if (!e)
    2094                 :          0 :                                         return -ENOMEM;
    2095                 :            : 
    2096                 :          0 :                                 strv_free_and_replace(c->unset_environment, e);
    2097                 :          0 :                                 unit_write_settingf(u, flags, name, "UnsetEnvironment=%s", joined);
    2098                 :            :                         }
    2099                 :            :                 }
    2100                 :            : 
    2101                 :          0 :                 return 1;
    2102                 :            : 
    2103         [ #  # ]:          0 :         } else if (streq(name, "OOMScoreAdjust")) {
    2104                 :            :                 int oa;
    2105                 :            : 
    2106                 :          0 :                 r = sd_bus_message_read(message, "i", &oa);
    2107         [ #  # ]:          0 :                 if (r < 0)
    2108                 :          0 :                         return r;
    2109                 :            : 
    2110         [ #  # ]:          0 :                 if (!oom_score_adjust_is_valid(oa))
    2111                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "OOM score adjust value out of range");
    2112                 :            : 
    2113         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    2114                 :          0 :                         c->oom_score_adjust = oa;
    2115                 :          0 :                         c->oom_score_adjust_set = true;
    2116                 :          0 :                         unit_write_settingf(u, flags, name, "OOMScoreAdjust=%i", oa);
    2117                 :            :                 }
    2118                 :            : 
    2119                 :          0 :                 return 1;
    2120                 :            : 
    2121         [ #  # ]:          0 :         } else if (streq(name, "EnvironmentFiles")) {
    2122                 :            : 
    2123                 :          0 :                 _cleanup_free_ char *joined = NULL;
    2124                 :          0 :                 _cleanup_fclose_ FILE *f = NULL;
    2125                 :          0 :                 _cleanup_strv_free_ char **l = NULL;
    2126                 :          0 :                 size_t size = 0;
    2127                 :            :                 char **i;
    2128                 :            : 
    2129                 :          0 :                 r = sd_bus_message_enter_container(message, 'a', "(sb)");
    2130         [ #  # ]:          0 :                 if (r < 0)
    2131                 :          0 :                         return r;
    2132                 :            : 
    2133                 :          0 :                 f = open_memstream_unlocked(&joined, &size);
    2134         [ #  # ]:          0 :                 if (!f)
    2135                 :          0 :                         return -ENOMEM;
    2136                 :            : 
    2137                 :          0 :                 fputs("EnvironmentFile=\n", f);
    2138                 :            : 
    2139   [ #  #  #  # ]:          0 :                 STRV_FOREACH(i, c->environment_files) {
    2140         [ #  # ]:          0 :                         _cleanup_free_ char *q = NULL;
    2141                 :            : 
    2142                 :          0 :                         q = specifier_escape(*i);
    2143         [ #  # ]:          0 :                         if (!q)
    2144                 :          0 :                                 return -ENOMEM;
    2145                 :            : 
    2146                 :          0 :                         fprintf(f, "EnvironmentFile=%s\n", q);
    2147                 :            :                 }
    2148                 :            : 
    2149         [ #  # ]:          0 :                 while ((r = sd_bus_message_enter_container(message, 'r', "sb")) > 0) {
    2150                 :            :                         const char *path;
    2151                 :            :                         int b;
    2152                 :            : 
    2153                 :          0 :                         r = sd_bus_message_read(message, "sb", &path, &b);
    2154         [ #  # ]:          0 :                         if (r < 0)
    2155                 :          0 :                                 return r;
    2156                 :            : 
    2157                 :          0 :                         r = sd_bus_message_exit_container(message);
    2158         [ #  # ]:          0 :                         if (r < 0)
    2159                 :          0 :                                 return r;
    2160                 :            : 
    2161         [ #  # ]:          0 :                         if (!path_is_absolute(path))
    2162                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path %s is not absolute.", path);
    2163                 :            : 
    2164         [ #  # ]:          0 :                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    2165   [ #  #  #  # ]:          0 :                                 _cleanup_free_ char *q = NULL, *buf = NULL;
    2166                 :            : 
    2167         [ #  # ]:          0 :                                 buf = strjoin(b ? "-" : "", path);
    2168         [ #  # ]:          0 :                                 if (!buf)
    2169                 :          0 :                                         return -ENOMEM;
    2170                 :            : 
    2171                 :          0 :                                 q = specifier_escape(buf);
    2172         [ #  # ]:          0 :                                 if (!q)
    2173                 :          0 :                                         return -ENOMEM;
    2174                 :            : 
    2175                 :          0 :                                 fprintf(f, "EnvironmentFile=%s\n", q);
    2176                 :            : 
    2177                 :          0 :                                 r = strv_consume(&l, TAKE_PTR(buf));
    2178         [ #  # ]:          0 :                                 if (r < 0)
    2179                 :          0 :                                         return r;
    2180                 :            :                         }
    2181                 :            :                 }
    2182         [ #  # ]:          0 :                 if (r < 0)
    2183                 :          0 :                         return r;
    2184                 :            : 
    2185                 :          0 :                 r = sd_bus_message_exit_container(message);
    2186         [ #  # ]:          0 :                 if (r < 0)
    2187                 :          0 :                         return r;
    2188                 :            : 
    2189                 :          0 :                 r = fflush_and_check(f);
    2190         [ #  # ]:          0 :                 if (r < 0)
    2191                 :          0 :                         return r;
    2192                 :            : 
    2193         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    2194         [ #  # ]:          0 :                         if (strv_isempty(l)) {
    2195                 :          0 :                                 c->environment_files = strv_free(c->environment_files);
    2196                 :          0 :                                 unit_write_setting(u, flags, name, "EnvironmentFile=");
    2197                 :            :                         } else {
    2198                 :          0 :                                 r = strv_extend_strv(&c->environment_files, l, true);
    2199         [ #  # ]:          0 :                                 if (r < 0)
    2200                 :          0 :                                         return r;
    2201                 :            : 
    2202                 :          0 :                                 unit_write_setting(u, flags, name, joined);
    2203                 :            :                         }
    2204                 :            :                 }
    2205                 :            : 
    2206                 :          0 :                 return 1;
    2207                 :            : 
    2208         [ #  # ]:          0 :         } else if (streq(name, "PassEnvironment")) {
    2209                 :            : 
    2210                 :          0 :                 _cleanup_strv_free_ char **l = NULL;
    2211                 :            : 
    2212                 :          0 :                 r = sd_bus_message_read_strv(message, &l);
    2213         [ #  # ]:          0 :                 if (r < 0)
    2214                 :          0 :                         return r;
    2215                 :            : 
    2216         [ #  # ]:          0 :                 if (!strv_env_name_is_valid(l))
    2217                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PassEnvironment= block.");
    2218                 :            : 
    2219         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    2220         [ #  # ]:          0 :                         if (strv_isempty(l)) {
    2221                 :          0 :                                 c->pass_environment = strv_free(c->pass_environment);
    2222                 :          0 :                                 unit_write_setting(u, flags, name, "PassEnvironment=");
    2223                 :            :                         } else {
    2224         [ #  # ]:          0 :                                 _cleanup_free_ char *joined = NULL;
    2225                 :            : 
    2226                 :          0 :                                 r = strv_extend_strv(&c->pass_environment, l, true);
    2227         [ #  # ]:          0 :                                 if (r < 0)
    2228                 :          0 :                                         return r;
    2229                 :            : 
    2230                 :            :                                 /* We write just the new settings out to file, with unresolved specifiers. */
    2231                 :          0 :                                 joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
    2232         [ #  # ]:          0 :                                 if (!joined)
    2233                 :          0 :                                         return -ENOMEM;
    2234                 :            : 
    2235                 :          0 :                                 unit_write_settingf(u, flags, name, "PassEnvironment=%s", joined);
    2236                 :            :                         }
    2237                 :            :                 }
    2238                 :            : 
    2239                 :          0 :                 return 1;
    2240                 :            : 
    2241         [ #  # ]:          0 :         } else if (STR_IN_SET(name, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories",
    2242                 :            :                               "ReadWritePaths", "ReadOnlyPaths", "InaccessiblePaths")) {
    2243                 :          0 :                 _cleanup_strv_free_ char **l = NULL;
    2244                 :            :                 char ***dirs;
    2245                 :            :                 char **p;
    2246                 :            : 
    2247                 :          0 :                 r = sd_bus_message_read_strv(message, &l);
    2248         [ #  # ]:          0 :                 if (r < 0)
    2249                 :          0 :                         return r;
    2250                 :            : 
    2251   [ #  #  #  # ]:          0 :                 STRV_FOREACH(p, l) {
    2252                 :          0 :                         char *i = *p;
    2253                 :            :                         size_t offset;
    2254                 :            : 
    2255                 :          0 :                         offset = i[0] == '-';
    2256                 :          0 :                         offset += i[offset] == '+';
    2257         [ #  # ]:          0 :                         if (!path_is_absolute(i + offset))
    2258                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s", name);
    2259                 :            : 
    2260                 :          0 :                         path_simplify(i + offset, false);
    2261                 :            :                 }
    2262                 :            : 
    2263         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    2264         [ #  # ]:          0 :                         if (STR_IN_SET(name, "ReadWriteDirectories", "ReadWritePaths"))
    2265                 :          0 :                                 dirs = &c->read_write_paths;
    2266         [ #  # ]:          0 :                         else if (STR_IN_SET(name, "ReadOnlyDirectories", "ReadOnlyPaths"))
    2267                 :          0 :                                 dirs = &c->read_only_paths;
    2268                 :            :                         else /* "InaccessiblePaths" */
    2269                 :          0 :                                 dirs = &c->inaccessible_paths;
    2270                 :            : 
    2271         [ #  # ]:          0 :                         if (strv_isempty(l)) {
    2272                 :          0 :                                 *dirs = strv_free(*dirs);
    2273                 :          0 :                                 unit_write_settingf(u, flags, name, "%s=", name);
    2274                 :            :                         } else {
    2275         [ #  # ]:          0 :                                 _cleanup_free_ char *joined = NULL;
    2276                 :            : 
    2277                 :          0 :                                 joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
    2278         [ #  # ]:          0 :                                 if (!joined)
    2279                 :          0 :                                         return -ENOMEM;
    2280                 :            : 
    2281                 :          0 :                                 r = strv_extend_strv(dirs, l, true);
    2282         [ #  # ]:          0 :                                 if (r < 0)
    2283                 :          0 :                                         return -ENOMEM;
    2284                 :            : 
    2285                 :          0 :                                 unit_write_settingf(u, flags, name, "%s=%s", name, joined);
    2286                 :            :                         }
    2287                 :            :                 }
    2288                 :            : 
    2289                 :          0 :                 return 1;
    2290                 :            : 
    2291         [ #  # ]:          0 :         } else if (STR_IN_SET(name, "RuntimeDirectory", "StateDirectory", "CacheDirectory", "LogsDirectory", "ConfigurationDirectory")) {
    2292                 :          0 :                 _cleanup_strv_free_ char **l = NULL;
    2293                 :            :                 char **p;
    2294                 :            : 
    2295                 :          0 :                 r = sd_bus_message_read_strv(message, &l);
    2296         [ #  # ]:          0 :                 if (r < 0)
    2297                 :          0 :                         return r;
    2298                 :            : 
    2299   [ #  #  #  # ]:          0 :                 STRV_FOREACH(p, l) {
    2300         [ #  # ]:          0 :                         if (!path_is_normalized(*p))
    2301                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path is not normalized: %s", name, *p);
    2302                 :            : 
    2303         [ #  # ]:          0 :                         if (path_is_absolute(*p))
    2304                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path is absolute: %s", name, *p);
    2305                 :            : 
    2306         [ #  # ]:          0 :                         if (path_startswith(*p, "private"))
    2307                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "%s= path can't be 'private': %s", name, *p);
    2308                 :            :                 }
    2309                 :            : 
    2310         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    2311                 :            :                         ExecDirectoryType i;
    2312                 :            :                         ExecDirectory *d;
    2313                 :            : 
    2314         [ #  # ]:          0 :                         assert_se((i = exec_directory_type_from_string(name)) >= 0);
    2315                 :          0 :                         d = c->directories + i;
    2316                 :            : 
    2317         [ #  # ]:          0 :                         if (strv_isempty(l)) {
    2318                 :          0 :                                 d->paths = strv_free(d->paths);
    2319                 :          0 :                                 unit_write_settingf(u, flags, name, "%s=", name);
    2320                 :            :                         } else {
    2321         [ #  # ]:          0 :                                 _cleanup_free_ char *joined = NULL;
    2322                 :            : 
    2323                 :          0 :                                 r = strv_extend_strv(&d->paths, l, true);
    2324         [ #  # ]:          0 :                                 if (r < 0)
    2325                 :          0 :                                         return r;
    2326                 :            : 
    2327                 :          0 :                                 joined = unit_concat_strv(l, UNIT_ESCAPE_SPECIFIERS);
    2328         [ #  # ]:          0 :                                 if (!joined)
    2329                 :          0 :                                         return -ENOMEM;
    2330                 :            : 
    2331                 :          0 :                                 unit_write_settingf(u, flags, name, "%s=%s", name, joined);
    2332                 :            :                         }
    2333                 :            :                 }
    2334                 :            : 
    2335                 :          0 :                 return 1;
    2336                 :            : 
    2337         [ #  # ]:          0 :         } else if (STR_IN_SET(name, "AppArmorProfile", "SmackProcessLabel")) {
    2338                 :            :                 int ignore;
    2339                 :            :                 const char *s;
    2340                 :            : 
    2341                 :          0 :                 r = sd_bus_message_read(message, "(bs)", &ignore, &s);
    2342         [ #  # ]:          0 :                 if (r < 0)
    2343                 :          0 :                         return r;
    2344                 :            : 
    2345         [ #  # ]:          0 :                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    2346                 :            :                         char **p;
    2347                 :            :                         bool *b;
    2348                 :            : 
    2349         [ #  # ]:          0 :                         if (streq(name, "AppArmorProfile")) {
    2350                 :          0 :                                 p = &c->apparmor_profile;
    2351                 :          0 :                                 b = &c->apparmor_profile_ignore;
    2352                 :            :                         } else { /* "SmackProcessLabel" */
    2353                 :          0 :                                 p = &c->smack_process_label;
    2354                 :          0 :                                 b = &c->smack_process_label_ignore;
    2355                 :            :                         }
    2356                 :            : 
    2357         [ #  # ]:          0 :                         if (isempty(s)) {
    2358                 :          0 :                                 *p = mfree(*p);
    2359                 :          0 :                                 *b = false;
    2360                 :            :                         } else {
    2361         [ #  # ]:          0 :                                 if (free_and_strdup(p, s) < 0)
    2362                 :          0 :                                         return -ENOMEM;
    2363                 :          0 :                                 *b = ignore;
    2364                 :            :                         }
    2365                 :            : 
    2366         [ #  # ]:          0 :                         unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "%s=%s%s", name, ignore ? "-" : "", strempty(s));
    2367                 :            :                 }
    2368                 :            : 
    2369                 :          0 :                 return 1;
    2370                 :            : 
    2371         [ #  # ]:          0 :         } else if (STR_IN_SET(name, "BindPaths", "BindReadOnlyPaths")) {
    2372                 :            :                 const char *source, *destination;
    2373                 :            :                 int ignore_enoent;
    2374                 :            :                 uint64_t mount_flags;
    2375                 :          0 :                 bool empty = true;
    2376                 :            : 
    2377                 :          0 :                 r = sd_bus_message_enter_container(message, 'a', "(ssbt)");
    2378         [ #  # ]:          0 :                 if (r < 0)
    2379                 :          0 :                         return r;
    2380                 :            : 
    2381         [ #  # ]:          0 :                 while ((r = sd_bus_message_read(message, "(ssbt)", &source, &destination, &ignore_enoent, &mount_flags)) > 0) {
    2382                 :            : 
    2383         [ #  # ]:          0 :                         if (!path_is_absolute(source))
    2384                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path %s is not absolute.", source);
    2385         [ #  # ]:          0 :                         if (!path_is_absolute(destination))
    2386                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path %s is not absolute.", destination);
    2387   [ #  #  #  # ]:          0 :                         if (!IN_SET(mount_flags, 0, MS_REC))
    2388                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mount flags.");
    2389                 :            : 
    2390         [ #  # ]:          0 :                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    2391                 :          0 :                                 r = bind_mount_add(&c->bind_mounts, &c->n_bind_mounts,
    2392                 :          0 :                                                    &(BindMount) {
    2393                 :          0 :                                                            .source = strdup(source),
    2394                 :          0 :                                                            .destination = strdup(destination),
    2395                 :          0 :                                                            .read_only = !!strstr(name, "ReadOnly"),
    2396                 :          0 :                                                            .recursive = !!(mount_flags & MS_REC),
    2397                 :            :                                                            .ignore_enoent = ignore_enoent,
    2398                 :            :                                                    });
    2399         [ #  # ]:          0 :                                 if (r < 0)
    2400                 :          0 :                                         return r;
    2401                 :            : 
    2402                 :          0 :                                 unit_write_settingf(
    2403                 :          0 :                                                 u, flags|UNIT_ESCAPE_SPECIFIERS, name,
    2404                 :            :                                                 "%s=%s%s:%s:%s",
    2405                 :            :                                                 name,
    2406         [ #  # ]:          0 :                                                 ignore_enoent ? "-" : "",
    2407                 :            :                                                 source,
    2408                 :            :                                                 destination,
    2409         [ #  # ]:          0 :                                                 (mount_flags & MS_REC) ? "rbind" : "norbind");
    2410                 :            :                         }
    2411                 :            : 
    2412                 :          0 :                         empty = false;
    2413                 :            :                 }
    2414         [ #  # ]:          0 :                 if (r < 0)
    2415                 :          0 :                         return r;
    2416                 :            : 
    2417                 :          0 :                 r = sd_bus_message_exit_container(message);
    2418         [ #  # ]:          0 :                 if (r < 0)
    2419                 :          0 :                         return r;
    2420                 :            : 
    2421         [ #  # ]:          0 :                 if (empty) {
    2422                 :          0 :                         bind_mount_free_many(c->bind_mounts, c->n_bind_mounts);
    2423                 :          0 :                         c->bind_mounts = NULL;
    2424                 :          0 :                         c->n_bind_mounts = 0;
    2425                 :            : 
    2426                 :          0 :                         unit_write_settingf(u, flags, name, "%s=", name);
    2427                 :            :                 }
    2428                 :            : 
    2429                 :          0 :                 return 1;
    2430                 :            : 
    2431         [ #  # ]:          0 :         } else if (streq(name, "TemporaryFileSystem")) {
    2432                 :            :                 const char *path, *options;
    2433                 :          0 :                 bool empty = true;
    2434                 :            : 
    2435                 :          0 :                 r = sd_bus_message_enter_container(message, 'a', "(ss)");
    2436         [ #  # ]:          0 :                 if (r < 0)
    2437                 :          0 :                         return r;
    2438                 :            : 
    2439         [ #  # ]:          0 :                 while ((r = sd_bus_message_read(message, "(ss)", &path, &options)) > 0) {
    2440                 :            : 
    2441         [ #  # ]:          0 :                         if (!path_is_absolute(path))
    2442                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Mount point %s is not absolute.", path);
    2443                 :            : 
    2444         [ #  # ]:          0 :                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    2445                 :          0 :                                 r = temporary_filesystem_add(&c->temporary_filesystems, &c->n_temporary_filesystems, path, options);
    2446         [ #  # ]:          0 :                                 if (r < 0)
    2447                 :          0 :                                         return r;
    2448                 :            : 
    2449                 :          0 :                                 unit_write_settingf(
    2450                 :          0 :                                                 u, flags|UNIT_ESCAPE_SPECIFIERS, name,
    2451                 :            :                                                 "%s=%s:%s",
    2452                 :            :                                                 name,
    2453                 :            :                                                 path,
    2454                 :            :                                                 options);
    2455                 :            :                         }
    2456                 :            : 
    2457                 :          0 :                         empty = false;
    2458                 :            :                 }
    2459         [ #  # ]:          0 :                 if (r < 0)
    2460                 :          0 :                         return r;
    2461                 :            : 
    2462                 :          0 :                 r = sd_bus_message_exit_container(message);
    2463         [ #  # ]:          0 :                 if (r < 0)
    2464                 :          0 :                         return r;
    2465                 :            : 
    2466         [ #  # ]:          0 :                 if (empty) {
    2467                 :          0 :                         temporary_filesystem_free_many(c->temporary_filesystems, c->n_temporary_filesystems);
    2468                 :          0 :                         c->temporary_filesystems = NULL;
    2469                 :          0 :                         c->n_temporary_filesystems = 0;
    2470                 :            : 
    2471                 :          0 :                         unit_write_settingf(u, flags, name, "%s=", name);
    2472                 :            :                 }
    2473                 :            : 
    2474                 :          0 :                 return 1;
    2475                 :            : 
    2476         [ #  # ]:          0 :         } else if ((suffix = startswith(name, "Limit"))) {
    2477                 :          0 :                 const char *soft = NULL;
    2478                 :            :                 int ri;
    2479                 :            : 
    2480                 :          0 :                 ri = rlimit_from_string(suffix);
    2481         [ #  # ]:          0 :                 if (ri < 0) {
    2482                 :          0 :                         soft = endswith(suffix, "Soft");
    2483         [ #  # ]:          0 :                         if (soft) {
    2484                 :            :                                 const char *n;
    2485                 :            : 
    2486                 :          0 :                                 n = strndupa(suffix, soft - suffix);
    2487                 :          0 :                                 ri = rlimit_from_string(n);
    2488         [ #  # ]:          0 :                                 if (ri >= 0)
    2489   [ #  #  #  #  :          0 :                                         name = strjoina("Limit", n);
          #  #  #  #  #  
                #  #  # ]
    2490                 :            :                         }
    2491                 :            :                 }
    2492                 :            : 
    2493         [ #  # ]:          0 :                 if (ri >= 0) {
    2494                 :            :                         uint64_t rl;
    2495                 :            :                         rlim_t x;
    2496                 :            : 
    2497                 :          0 :                         r = sd_bus_message_read(message, "t", &rl);
    2498         [ #  # ]:          0 :                         if (r < 0)
    2499                 :          0 :                                 return r;
    2500                 :            : 
    2501         [ #  # ]:          0 :                         if (rl == (uint64_t) -1)
    2502                 :          0 :                                 x = RLIM_INFINITY;
    2503                 :            :                         else {
    2504                 :          0 :                                 x = (rlim_t) rl;
    2505                 :            : 
    2506         [ #  # ]:          0 :                                 if ((uint64_t) x != rl)
    2507                 :          0 :                                         return -ERANGE;
    2508                 :            :                         }
    2509                 :            : 
    2510         [ #  # ]:          0 :                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
    2511         [ #  # ]:          0 :                                 _cleanup_free_ char *f = NULL;
    2512                 :            :                                 struct rlimit nl;
    2513                 :            : 
    2514         [ #  # ]:          0 :                                 if (c->rlimit[ri]) {
    2515                 :          0 :                                         nl = *c->rlimit[ri];
    2516                 :            : 
    2517         [ #  # ]:          0 :                                         if (soft)
    2518                 :          0 :                                                 nl.rlim_cur = x;
    2519                 :            :                                         else
    2520                 :          0 :                                                 nl.rlim_max = x;
    2521                 :            :                                 } else
    2522                 :            :                                         /* When the resource limit is not initialized yet, then assign the value to both fields */
    2523                 :          0 :                                         nl = (struct rlimit) {
    2524                 :            :                                                 .rlim_cur = x,
    2525                 :            :                                                 .rlim_max = x,
    2526                 :            :                                         };
    2527                 :            : 
    2528                 :          0 :                                 r = rlimit_format(&nl, &f);
    2529         [ #  # ]:          0 :                                 if (r < 0)
    2530                 :          0 :                                         return r;
    2531                 :            : 
    2532         [ #  # ]:          0 :                                 if (c->rlimit[ri])
    2533                 :          0 :                                         *c->rlimit[ri] = nl;
    2534                 :            :                                 else {
    2535                 :          0 :                                         c->rlimit[ri] = newdup(struct rlimit, &nl, 1);
    2536         [ #  # ]:          0 :                                         if (!c->rlimit[ri])
    2537                 :          0 :                                                 return -ENOMEM;
    2538                 :            :                                 }
    2539                 :            : 
    2540                 :          0 :                                 unit_write_settingf(u, flags, name, "%s=%s", name, f);
    2541                 :            :                         }
    2542                 :            : 
    2543                 :          0 :                         return 1;
    2544                 :            :                 }
    2545                 :            : 
    2546                 :            :         }
    2547                 :            : 
    2548                 :          0 :         return 0;
    2549                 :            : }

Generated by: LCOV version 1.14