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

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include <errno.h>
       4                 :            : #include <sys/prctl.h>
       5                 :            : #include <sys/statvfs.h>
       6                 :            : #include <unistd.h>
       7                 :            : 
       8                 :            : #include "alloc-util.h"
       9                 :            : #include "architecture.h"
      10                 :            : #include "build.h"
      11                 :            : #include "bus-common-errors.h"
      12                 :            : #include "dbus-execute.h"
      13                 :            : #include "dbus-job.h"
      14                 :            : #include "dbus-manager.h"
      15                 :            : #include "dbus-scope.h"
      16                 :            : #include "dbus-unit.h"
      17                 :            : #include "dbus.h"
      18                 :            : #include "env-util.h"
      19                 :            : #include "fd-util.h"
      20                 :            : #include "fileio.h"
      21                 :            : #include "format-util.h"
      22                 :            : #include "fs-util.h"
      23                 :            : #include "install.h"
      24                 :            : #include "log.h"
      25                 :            : #include "os-util.h"
      26                 :            : #include "parse-util.h"
      27                 :            : #include "path-util.h"
      28                 :            : #include "selinux-access.h"
      29                 :            : #include "stat-util.h"
      30                 :            : #include "string-util.h"
      31                 :            : #include "strv.h"
      32                 :            : #include "syslog-util.h"
      33                 :            : #include "user-util.h"
      34                 :            : #include "virt.h"
      35                 :            : #include "watchdog.h"
      36                 :            : 
      37                 :            : /* Require 16MiB free in /run/systemd for reloading/reexecing. After all we need to serialize our state there, and if
      38                 :            :  * we can't we'll fail badly. */
      39                 :            : #define RELOAD_DISK_SPACE_MIN (UINT64_C(16) * UINT64_C(1024) * UINT64_C(1024))
      40                 :            : 
      41                 :          0 : static UnitFileFlags unit_file_bools_to_flags(bool runtime, bool force) {
      42                 :          0 :         return (runtime ? UNIT_FILE_RUNTIME : 0) |
      43         [ #  # ]:          0 :                (force   ? UNIT_FILE_FORCE   : 0);
      44                 :            : }
      45                 :            : 
      46   [ #  #  #  #  :          0 : BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_oom_policy, oom_policy, OOMPolicy);
                   #  # ]
      47                 :            : 
      48   [ #  #  #  # ]:          0 : static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_version, "s", GIT_VERSION);
      49   [ #  #  #  # ]:          0 : static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_features, "s", SYSTEMD_FEATURES);
      50   [ #  #  #  # ]:          0 : static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_architecture, "s", architecture_to_string(uname_architecture()));
      51   [ #  #  #  # ]:          0 : static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_log_target, "s", log_target_to_string(log_get_target()));
      52   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET2(property_get_system_state, "s", Manager, manager_state, manager_state_to_string);
                   #  # ]
      53   [ #  #  #  # ]:          0 : static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_timer_slack_nsec, "t", (uint64_t) prctl(PR_GET_TIMERSLACK));
      54   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET_REF(property_get_hashmap_size, "u", Hashmap *, hashmap_size);
                   #  # ]
      55   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET_REF(property_get_set_size, "u", Set *, set_size);
                   #  # ]
      56   [ #  #  #  #  :          0 : static BUS_DEFINE_PROPERTY_GET(property_get_default_timeout_abort_usec, "t", Manager, manager_default_timeout_abort_usec);
                   #  # ]
      57                 :            : 
      58                 :          0 : static int property_get_virtualization(
      59                 :            :                 sd_bus *bus,
      60                 :            :                 const char *path,
      61                 :            :                 const char *interface,
      62                 :            :                 const char *property,
      63                 :            :                 sd_bus_message *reply,
      64                 :            :                 void *userdata,
      65                 :            :                 sd_bus_error *error) {
      66                 :            : 
      67                 :            :         int v;
      68                 :            : 
      69         [ #  # ]:          0 :         assert(bus);
      70         [ #  # ]:          0 :         assert(reply);
      71                 :            : 
      72                 :          0 :         v = detect_virtualization();
      73                 :            : 
      74                 :            :         /* Make sure to return the empty string when we detect no virtualization, as that is the API.
      75                 :            :          *
      76                 :            :          * https://github.com/systemd/systemd/issues/1423
      77                 :            :          */
      78                 :            : 
      79         [ #  # ]:          0 :         return sd_bus_message_append(
      80                 :            :                         reply, "s",
      81                 :          0 :                         v == VIRTUALIZATION_NONE ? NULL : virtualization_to_string(v));
      82                 :            : }
      83                 :            : 
      84                 :          0 : static int property_get_tainted(
      85                 :            :                 sd_bus *bus,
      86                 :            :                 const char *path,
      87                 :            :                 const char *interface,
      88                 :            :                 const char *property,
      89                 :            :                 sd_bus_message *reply,
      90                 :            :                 void *userdata,
      91                 :            :                 sd_bus_error *error) {
      92                 :            : 
      93                 :          0 :         _cleanup_free_ char *s = NULL;
      94                 :          0 :         Manager *m = userdata;
      95                 :            : 
      96         [ #  # ]:          0 :         assert(bus);
      97         [ #  # ]:          0 :         assert(reply);
      98         [ #  # ]:          0 :         assert(m);
      99                 :            : 
     100                 :          0 :         s = manager_taint_string(m);
     101         [ #  # ]:          0 :         if (!s)
     102                 :          0 :                 return log_oom();
     103                 :            : 
     104                 :          0 :         return sd_bus_message_append(reply, "s", s);
     105                 :            : }
     106                 :            : 
     107                 :          0 : static int property_set_log_target(
     108                 :            :                 sd_bus *bus,
     109                 :            :                 const char *path,
     110                 :            :                 const char *interface,
     111                 :            :                 const char *property,
     112                 :            :                 sd_bus_message *value,
     113                 :            :                 void *userdata,
     114                 :            :                 sd_bus_error *error) {
     115                 :            : 
     116                 :          0 :         Manager *m = userdata;
     117                 :            :         const char *t;
     118                 :            :         int r;
     119                 :            : 
     120         [ #  # ]:          0 :         assert(bus);
     121         [ #  # ]:          0 :         assert(value);
     122                 :            : 
     123                 :          0 :         r = sd_bus_message_read(value, "s", &t);
     124         [ #  # ]:          0 :         if (r < 0)
     125                 :          0 :                 return r;
     126                 :            : 
     127         [ #  # ]:          0 :         if (isempty(t))
     128                 :          0 :                 manager_restore_original_log_target(m);
     129                 :            :         else {
     130                 :            :                 LogTarget target;
     131                 :            : 
     132                 :          0 :                 target = log_target_from_string(t);
     133         [ #  # ]:          0 :                 if (target < 0)
     134                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid log target '%s'", t);
     135                 :            : 
     136                 :          0 :                 manager_override_log_target(m, target);
     137                 :            :         }
     138                 :            : 
     139                 :          0 :         return 0;
     140                 :            : }
     141                 :            : 
     142                 :          0 : static int property_get_log_level(
     143                 :            :                 sd_bus *bus,
     144                 :            :                 const char *path,
     145                 :            :                 const char *interface,
     146                 :            :                 const char *property,
     147                 :            :                 sd_bus_message *reply,
     148                 :            :                 void *userdata,
     149                 :            :                 sd_bus_error *error) {
     150                 :            : 
     151                 :          0 :         _cleanup_free_ char *t = NULL;
     152                 :            :         int r;
     153                 :            : 
     154         [ #  # ]:          0 :         assert(bus);
     155         [ #  # ]:          0 :         assert(reply);
     156                 :            : 
     157                 :          0 :         r = log_level_to_string_alloc(log_get_max_level(), &t);
     158         [ #  # ]:          0 :         if (r < 0)
     159                 :          0 :                 return r;
     160                 :            : 
     161                 :          0 :         return sd_bus_message_append(reply, "s", t);
     162                 :            : }
     163                 :            : 
     164                 :          0 : static int property_set_log_level(
     165                 :            :                 sd_bus *bus,
     166                 :            :                 const char *path,
     167                 :            :                 const char *interface,
     168                 :            :                 const char *property,
     169                 :            :                 sd_bus_message *value,
     170                 :            :                 void *userdata,
     171                 :            :                 sd_bus_error *error) {
     172                 :            : 
     173                 :          0 :         Manager *m = userdata;
     174                 :            :         const char *t;
     175                 :            :         int r;
     176                 :            : 
     177         [ #  # ]:          0 :         assert(bus);
     178         [ #  # ]:          0 :         assert(value);
     179                 :            : 
     180                 :          0 :         r = sd_bus_message_read(value, "s", &t);
     181         [ #  # ]:          0 :         if (r < 0)
     182                 :          0 :                 return r;
     183                 :            : 
     184         [ #  # ]:          0 :         if (isempty(t))
     185                 :          0 :                 manager_restore_original_log_level(m);
     186                 :            :         else {
     187                 :            :                 int level;
     188                 :            : 
     189                 :          0 :                 level = log_level_from_string(t);
     190         [ #  # ]:          0 :                 if (level < 0)
     191                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid log level '%s'", t);
     192                 :            : 
     193                 :          0 :                 manager_override_log_level(m, level);
     194                 :            :         }
     195                 :            : 
     196                 :          0 :         return 0;
     197                 :            : }
     198                 :            : 
     199                 :          0 : static int property_get_progress(
     200                 :            :                 sd_bus *bus,
     201                 :            :                 const char *path,
     202                 :            :                 const char *interface,
     203                 :            :                 const char *property,
     204                 :            :                 sd_bus_message *reply,
     205                 :            :                 void *userdata,
     206                 :            :                 sd_bus_error *error) {
     207                 :            : 
     208                 :          0 :         Manager *m = userdata;
     209                 :            :         double d;
     210                 :            : 
     211         [ #  # ]:          0 :         assert(bus);
     212         [ #  # ]:          0 :         assert(reply);
     213         [ #  # ]:          0 :         assert(m);
     214                 :            : 
     215         [ #  # ]:          0 :         if (MANAGER_IS_FINISHED(m))
     216                 :          0 :                 d = 1.0;
     217                 :            :         else
     218                 :          0 :                 d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
     219                 :            : 
     220                 :          0 :         return sd_bus_message_append(reply, "d", d);
     221                 :            : }
     222                 :            : 
     223                 :          0 : static int property_get_environment(
     224                 :            :                 sd_bus *bus,
     225                 :            :                 const char *path,
     226                 :            :                 const char *interface,
     227                 :            :                 const char *property,
     228                 :            :                 sd_bus_message *reply,
     229                 :            :                 void *userdata,
     230                 :            :                 sd_bus_error *error) {
     231                 :            : 
     232                 :          0 :         _cleanup_strv_free_ char **l = NULL;
     233                 :          0 :         Manager *m = userdata;
     234                 :            :         int r;
     235                 :            : 
     236         [ #  # ]:          0 :         assert(bus);
     237         [ #  # ]:          0 :         assert(reply);
     238         [ #  # ]:          0 :         assert(m);
     239                 :            : 
     240                 :          0 :         r = manager_get_effective_environment(m, &l);
     241         [ #  # ]:          0 :         if (r < 0)
     242                 :          0 :                 return r;
     243                 :            : 
     244                 :          0 :         return sd_bus_message_append_strv(reply, l);
     245                 :            : }
     246                 :            : 
     247                 :          0 : static int property_get_show_status(
     248                 :            :                 sd_bus *bus,
     249                 :            :                 const char *path,
     250                 :            :                 const char *interface,
     251                 :            :                 const char *property,
     252                 :            :                 sd_bus_message *reply,
     253                 :            :                 void *userdata,
     254                 :            :                 sd_bus_error *error) {
     255                 :            : 
     256                 :          0 :         Manager *m = userdata;
     257                 :            :         int b;
     258                 :            : 
     259         [ #  # ]:          0 :         assert(bus);
     260         [ #  # ]:          0 :         assert(reply);
     261         [ #  # ]:          0 :         assert(m);
     262                 :            : 
     263         [ #  # ]:          0 :         b = IN_SET(m->show_status, SHOW_STATUS_TEMPORARY, SHOW_STATUS_YES);
     264                 :          0 :         return sd_bus_message_append_basic(reply, 'b', &b);
     265                 :            : }
     266                 :            : 
     267                 :          0 : static int property_set_runtime_watchdog(
     268                 :            :                 sd_bus *bus,
     269                 :            :                 const char *path,
     270                 :            :                 const char *interface,
     271                 :            :                 const char *property,
     272                 :            :                 sd_bus_message *value,
     273                 :            :                 void *userdata,
     274                 :            :                 sd_bus_error *error) {
     275                 :            : 
     276                 :          0 :         usec_t *t = userdata;
     277                 :            :         int r;
     278                 :            : 
     279         [ #  # ]:          0 :         assert(bus);
     280         [ #  # ]:          0 :         assert(value);
     281                 :            : 
     282                 :            :         assert_cc(sizeof(usec_t) == sizeof(uint64_t));
     283                 :            : 
     284                 :          0 :         r = sd_bus_message_read(value, "t", t);
     285         [ #  # ]:          0 :         if (r < 0)
     286                 :          0 :                 return r;
     287                 :            : 
     288                 :          0 :         return watchdog_set_timeout(t);
     289                 :            : }
     290                 :            : 
     291                 :          0 : static int bus_get_unit_by_name(Manager *m, sd_bus_message *message, const char *name, Unit **ret_unit, sd_bus_error *error) {
     292                 :            :         Unit *u;
     293                 :            :         int r;
     294                 :            : 
     295         [ #  # ]:          0 :         assert(m);
     296         [ #  # ]:          0 :         assert(message);
     297         [ #  # ]:          0 :         assert(ret_unit);
     298                 :            : 
     299                 :            :         /* More or less a wrapper around manager_get_unit() that generates nice errors and has one trick up its sleeve:
     300                 :            :          * if the name is specified empty we use the client's unit. */
     301                 :            : 
     302         [ #  # ]:          0 :         if (isempty(name)) {
     303         [ #  # ]:          0 :                 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
     304                 :            :                 pid_t pid;
     305                 :            : 
     306                 :          0 :                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
     307         [ #  # ]:          0 :                 if (r < 0)
     308                 :          0 :                         return r;
     309                 :            : 
     310                 :          0 :                 r = sd_bus_creds_get_pid(creds, &pid);
     311         [ #  # ]:          0 :                 if (r < 0)
     312                 :          0 :                         return r;
     313                 :            : 
     314                 :          0 :                 u = manager_get_unit_by_pid(m, pid);
     315         [ #  # ]:          0 :                 if (!u)
     316                 :          0 :                         return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
     317                 :            :         } else {
     318                 :          0 :                 u = manager_get_unit(m, name);
     319         [ #  # ]:          0 :                 if (!u)
     320                 :          0 :                         return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
     321                 :            :         }
     322                 :            : 
     323                 :          0 :         *ret_unit = u;
     324                 :          0 :         return 0;
     325                 :            : }
     326                 :            : 
     327                 :          0 : static int bus_load_unit_by_name(Manager *m, sd_bus_message *message, const char *name, Unit **ret_unit, sd_bus_error *error) {
     328         [ #  # ]:          0 :         assert(m);
     329         [ #  # ]:          0 :         assert(message);
     330         [ #  # ]:          0 :         assert(ret_unit);
     331                 :            : 
     332                 :            :         /* Pretty much the same as bus_get_unit_by_name(), but we also load the unit if necessary. */
     333                 :            : 
     334         [ #  # ]:          0 :         if (isempty(name))
     335                 :          0 :                 return bus_get_unit_by_name(m, message, name, ret_unit, error);
     336                 :            : 
     337                 :          0 :         return manager_load_unit(m, name, NULL, error, ret_unit);
     338                 :            : }
     339                 :            : 
     340                 :          0 : static int reply_unit_path(Unit *u, sd_bus_message *message, sd_bus_error *error) {
     341                 :          0 :         _cleanup_free_ char *path = NULL;
     342                 :            :         int r;
     343                 :            : 
     344         [ #  # ]:          0 :         assert(u);
     345         [ #  # ]:          0 :         assert(message);
     346                 :            : 
     347                 :          0 :         r = mac_selinux_unit_access_check(u, message, "status", error);
     348         [ #  # ]:          0 :         if (r < 0)
     349                 :          0 :                 return r;
     350                 :            : 
     351                 :          0 :         path = unit_dbus_path(u);
     352         [ #  # ]:          0 :         if (!path)
     353                 :          0 :                 return log_oom();
     354                 :            : 
     355                 :          0 :         return sd_bus_reply_method_return(message, "o", path);
     356                 :            : }
     357                 :            : 
     358                 :          0 : static int method_get_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     359                 :          0 :         Manager *m = userdata;
     360                 :            :         const char *name;
     361                 :            :         Unit *u;
     362                 :            :         int r;
     363                 :            : 
     364         [ #  # ]:          0 :         assert(message);
     365         [ #  # ]:          0 :         assert(m);
     366                 :            : 
     367                 :            :         /* Anyone can call this method */
     368                 :            : 
     369                 :          0 :         r = sd_bus_message_read(message, "s", &name);
     370         [ #  # ]:          0 :         if (r < 0)
     371                 :          0 :                 return r;
     372                 :            : 
     373                 :          0 :         r = bus_get_unit_by_name(m, message, name, &u, error);
     374         [ #  # ]:          0 :         if (r < 0)
     375                 :          0 :                 return r;
     376                 :            : 
     377                 :          0 :         return reply_unit_path(u, message, error);
     378                 :            : }
     379                 :            : 
     380                 :          0 : static int method_get_unit_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     381                 :          0 :         Manager *m = userdata;
     382                 :            :         pid_t pid;
     383                 :            :         Unit *u;
     384                 :            :         int r;
     385                 :            : 
     386         [ #  # ]:          0 :         assert(message);
     387         [ #  # ]:          0 :         assert(m);
     388                 :            : 
     389                 :            :         assert_cc(sizeof(pid_t) == sizeof(uint32_t));
     390                 :            : 
     391                 :            :         /* Anyone can call this method */
     392                 :            : 
     393                 :          0 :         r = sd_bus_message_read(message, "u", &pid);
     394         [ #  # ]:          0 :         if (r < 0)
     395                 :          0 :                 return r;
     396         [ #  # ]:          0 :         if (pid < 0)
     397                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PID " PID_FMT, pid);
     398                 :            : 
     399         [ #  # ]:          0 :         if (pid == 0) {
     400         [ #  # ]:          0 :                 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
     401                 :            : 
     402                 :          0 :                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
     403         [ #  # ]:          0 :                 if (r < 0)
     404                 :          0 :                         return r;
     405                 :            : 
     406                 :          0 :                 r = sd_bus_creds_get_pid(creds, &pid);
     407         [ #  # ]:          0 :                 if (r < 0)
     408                 :          0 :                         return r;
     409                 :            :         }
     410                 :            : 
     411                 :          0 :         u = manager_get_unit_by_pid(m, pid);
     412         [ #  # ]:          0 :         if (!u)
     413                 :          0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID "PID_FMT" does not belong to any loaded unit.", pid);
     414                 :            : 
     415                 :          0 :         return reply_unit_path(u, message, error);
     416                 :            : }
     417                 :            : 
     418                 :          0 : static int method_get_unit_by_invocation_id(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     419                 :          0 :         _cleanup_free_ char *path = NULL;
     420                 :          0 :         Manager *m = userdata;
     421                 :            :         sd_id128_t id;
     422                 :            :         const void *a;
     423                 :            :         Unit *u;
     424                 :            :         size_t sz;
     425                 :            :         int r;
     426                 :            : 
     427         [ #  # ]:          0 :         assert(message);
     428         [ #  # ]:          0 :         assert(m);
     429                 :            : 
     430                 :            :         /* Anyone can call this method */
     431                 :            : 
     432                 :          0 :         r = sd_bus_message_read_array(message, 'y', &a, &sz);
     433         [ #  # ]:          0 :         if (r < 0)
     434                 :          0 :                 return r;
     435         [ #  # ]:          0 :         if (sz == 0)
     436                 :          0 :                 id = SD_ID128_NULL;
     437         [ #  # ]:          0 :         else if (sz == 16)
     438                 :          0 :                 memcpy(&id, a, sz);
     439                 :            :         else
     440                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid invocation ID");
     441                 :            : 
     442         [ #  # ]:          0 :         if (sd_id128_is_null(id)) {
     443         [ #  # ]:          0 :                 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
     444                 :            :                 pid_t pid;
     445                 :            : 
     446                 :          0 :                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
     447         [ #  # ]:          0 :                 if (r < 0)
     448                 :          0 :                         return r;
     449                 :            : 
     450                 :          0 :                 r = sd_bus_creds_get_pid(creds, &pid);
     451         [ #  # ]:          0 :                 if (r < 0)
     452                 :          0 :                         return r;
     453                 :            : 
     454                 :          0 :                 u = manager_get_unit_by_pid(m, pid);
     455         [ #  # ]:          0 :                 if (!u)
     456                 :          0 :                         return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Client " PID_FMT " not member of any unit.", pid);
     457                 :            :         } else {
     458                 :          0 :                 u = hashmap_get(m->units_by_invocation_id, &id);
     459         [ #  # ]:          0 :                 if (!u)
     460                 :          0 :                         return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_INVOCATION_ID, "No unit with the specified invocation ID " SD_ID128_FORMAT_STR " known.", SD_ID128_FORMAT_VAL(id));
     461                 :            :         }
     462                 :            : 
     463                 :          0 :         r = mac_selinux_unit_access_check(u, message, "status", error);
     464         [ #  # ]:          0 :         if (r < 0)
     465                 :          0 :                 return r;
     466                 :            : 
     467                 :            :         /* So here's a special trick: the bus path we return actually references the unit by its invocation ID instead
     468                 :            :          * of the unit name. This means it stays valid only as long as the invocation ID stays the same. */
     469                 :          0 :         path = unit_dbus_path_invocation_id(u);
     470         [ #  # ]:          0 :         if (!path)
     471                 :          0 :                 return -ENOMEM;
     472                 :            : 
     473                 :          0 :         return sd_bus_reply_method_return(message, "o", path);
     474                 :            : }
     475                 :            : 
     476                 :          0 : static int method_get_unit_by_control_group(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     477                 :          0 :         Manager *m = userdata;
     478                 :            :         const char *cgroup;
     479                 :            :         Unit *u;
     480                 :            :         int r;
     481                 :            : 
     482                 :          0 :         r = sd_bus_message_read(message, "s", &cgroup);
     483         [ #  # ]:          0 :         if (r < 0)
     484                 :          0 :                 return r;
     485                 :            : 
     486                 :          0 :         u = manager_get_unit_by_cgroup(m, cgroup);
     487         [ #  # ]:          0 :         if (!u)
     488                 :          0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Control group '%s' is not valid or not managed by this instance", cgroup);
     489                 :            : 
     490                 :          0 :         return reply_unit_path(u, message, error);
     491                 :            : }
     492                 :            : 
     493                 :          0 : static int method_load_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     494                 :          0 :         Manager *m = userdata;
     495                 :            :         const char *name;
     496                 :            :         Unit *u;
     497                 :            :         int r;
     498                 :            : 
     499         [ #  # ]:          0 :         assert(message);
     500         [ #  # ]:          0 :         assert(m);
     501                 :            : 
     502                 :            :         /* Anyone can call this method */
     503                 :            : 
     504                 :          0 :         r = sd_bus_message_read(message, "s", &name);
     505         [ #  # ]:          0 :         if (r < 0)
     506                 :          0 :                 return r;
     507                 :            : 
     508                 :          0 :         r = bus_load_unit_by_name(m, message, name, &u, error);
     509         [ #  # ]:          0 :         if (r < 0)
     510                 :          0 :                 return r;
     511                 :            : 
     512                 :          0 :         return reply_unit_path(u, message, error);
     513                 :            : }
     514                 :            : 
     515                 :          0 : static int method_start_unit_generic(sd_bus_message *message, Manager *m, JobType job_type, bool reload_if_possible, sd_bus_error *error) {
     516                 :            :         const char *name;
     517                 :            :         Unit *u;
     518                 :            :         int r;
     519                 :            : 
     520         [ #  # ]:          0 :         assert(message);
     521         [ #  # ]:          0 :         assert(m);
     522                 :            : 
     523                 :          0 :         r = sd_bus_message_read(message, "s", &name);
     524         [ #  # ]:          0 :         if (r < 0)
     525                 :          0 :                 return r;
     526                 :            : 
     527                 :          0 :         r = manager_load_unit(m, name, NULL, error, &u);
     528         [ #  # ]:          0 :         if (r < 0)
     529                 :          0 :                 return r;
     530                 :            : 
     531                 :          0 :         return bus_unit_method_start_generic(message, u, job_type, reload_if_possible, error);
     532                 :            : }
     533                 :            : 
     534                 :          0 : static int method_start_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     535                 :          0 :         return method_start_unit_generic(message, userdata, JOB_START, false, error);
     536                 :            : }
     537                 :            : 
     538                 :          0 : static int method_stop_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     539                 :          0 :         return method_start_unit_generic(message, userdata, JOB_STOP, false, error);
     540                 :            : }
     541                 :            : 
     542                 :          0 : static int method_reload_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     543                 :          0 :         return method_start_unit_generic(message, userdata, JOB_RELOAD, false, error);
     544                 :            : }
     545                 :            : 
     546                 :          0 : static int method_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     547                 :          0 :         return method_start_unit_generic(message, userdata, JOB_RESTART, false, error);
     548                 :            : }
     549                 :            : 
     550                 :          0 : static int method_try_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     551                 :          0 :         return method_start_unit_generic(message, userdata, JOB_TRY_RESTART, false, error);
     552                 :            : }
     553                 :            : 
     554                 :          0 : static int method_reload_or_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     555                 :          0 :         return method_start_unit_generic(message, userdata, JOB_RESTART, true, error);
     556                 :            : }
     557                 :            : 
     558                 :          0 : static int method_reload_or_try_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     559                 :          0 :         return method_start_unit_generic(message, userdata, JOB_TRY_RESTART, true, error);
     560                 :            : }
     561                 :            : 
     562                 :            : typedef enum GenericUnitOperationFlags {
     563                 :            :         GENERIC_UNIT_LOAD            = 1 << 0, /* Load if the unit is not loaded yet */
     564                 :            :         GENERIC_UNIT_VALIDATE_LOADED = 1 << 1, /* Verify unit is properly loaded before forwarding call */
     565                 :            : } GenericUnitOperationFlags;
     566                 :            : 
     567                 :          0 : static int method_generic_unit_operation(
     568                 :            :                 sd_bus_message *message,
     569                 :            :                 Manager *m,
     570                 :            :                 sd_bus_error *error,
     571                 :            :                 sd_bus_message_handler_t handler,
     572                 :            :                 GenericUnitOperationFlags flags) {
     573                 :            : 
     574                 :            :         const char *name;
     575                 :            :         Unit *u;
     576                 :            :         int r;
     577                 :            : 
     578         [ #  # ]:          0 :         assert(message);
     579         [ #  # ]:          0 :         assert(m);
     580                 :            : 
     581                 :            :         /* Read the first argument from the command and pass the operation to the specified per-unit
     582                 :            :          * method. */
     583                 :            : 
     584                 :          0 :         r = sd_bus_message_read(message, "s", &name);
     585         [ #  # ]:          0 :         if (r < 0)
     586                 :          0 :                 return r;
     587                 :            : 
     588   [ #  #  #  # ]:          0 :         if (!isempty(name) && FLAGS_SET(flags, GENERIC_UNIT_LOAD))
     589                 :          0 :                 r = manager_load_unit(m, name, NULL, error, &u);
     590                 :            :         else
     591                 :          0 :                 r = bus_get_unit_by_name(m, message, name, &u, error);
     592         [ #  # ]:          0 :         if (r < 0)
     593                 :          0 :                 return r;
     594                 :            : 
     595         [ #  # ]:          0 :         if (FLAGS_SET(flags, GENERIC_UNIT_VALIDATE_LOADED)) {
     596                 :          0 :                 r = bus_unit_validate_load_state(u, error);
     597         [ #  # ]:          0 :                 if (r < 0)
     598                 :          0 :                         return r;
     599                 :            :         }
     600                 :            : 
     601                 :          0 :         return handler(message, u, error);
     602                 :            : }
     603                 :            : 
     604                 :          0 : static int method_enqueue_unit_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     605                 :            :         /* We don't bother with GENERIC_UNIT_VALIDATE_LOADED here, as the job logic validates that anyway */
     606                 :          0 :         return method_generic_unit_operation(message, userdata, error, bus_unit_method_enqueue_job, GENERIC_UNIT_LOAD);
     607                 :            : }
     608                 :            : 
     609                 :          0 : static int method_start_unit_replace(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     610                 :          0 :         Manager *m = userdata;
     611                 :            :         const char *old_name;
     612                 :            :         Unit *u;
     613                 :            :         int r;
     614                 :            : 
     615         [ #  # ]:          0 :         assert(message);
     616         [ #  # ]:          0 :         assert(m);
     617                 :            : 
     618                 :          0 :         r = sd_bus_message_read(message, "s", &old_name);
     619         [ #  # ]:          0 :         if (r < 0)
     620                 :          0 :                 return r;
     621                 :            : 
     622                 :          0 :         r = bus_get_unit_by_name(m, message, old_name, &u, error);
     623         [ #  # ]:          0 :         if (r < 0)
     624                 :          0 :                 return r;
     625   [ #  #  #  # ]:          0 :         if (!u->job || u->job->type != JOB_START)
     626                 :          0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
     627                 :            : 
     628                 :          0 :         return method_start_unit_generic(message, m, JOB_START, false, error);
     629                 :            : }
     630                 :            : 
     631                 :          0 : static int method_kill_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     632                 :            :         /* We don't bother with GENERIC_UNIT_LOAD nor GENERIC_UNIT_VALIDATE_LOADED here, as it shouldn't
     633                 :            :          * matter whether a unit is loaded for killing any processes possibly in the unit's cgroup. */
     634                 :          0 :         return method_generic_unit_operation(message, userdata, error, bus_unit_method_kill, 0);
     635                 :            : }
     636                 :            : 
     637                 :          0 : static int method_clean_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     638                 :            :         /* Load the unit if necessary, in order to load it, and insist on the unit being loaded to be
     639                 :            :          * cleaned */
     640                 :          0 :         return method_generic_unit_operation(message, userdata, error, bus_unit_method_clean, GENERIC_UNIT_LOAD|GENERIC_UNIT_VALIDATE_LOADED);
     641                 :            : }
     642                 :            : 
     643                 :          0 : static int method_reset_failed_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     644                 :            :         /* Don't load the unit (because unloaded units can't be in failed state), and don't insist on the
     645                 :            :          * unit to be loaded properly (since a failed unit might have its unit file disappeared) */
     646                 :          0 :         return method_generic_unit_operation(message, userdata, error, bus_unit_method_reset_failed, 0);
     647                 :            : }
     648                 :            : 
     649                 :          0 : static int method_set_unit_properties(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     650                 :            :         /* Only change properties on fully loaded units, and load them in order to set properties */
     651                 :          0 :         return method_generic_unit_operation(message, userdata, error, bus_unit_method_set_properties, GENERIC_UNIT_LOAD|GENERIC_UNIT_VALIDATE_LOADED);
     652                 :            : }
     653                 :            : 
     654                 :          0 : static int method_ref_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     655                 :            :         /* Only allow reffing of fully loaded units, and make sure reffing a unit loads it. */
     656                 :          0 :         return method_generic_unit_operation(message, userdata, error, bus_unit_method_ref, GENERIC_UNIT_LOAD|GENERIC_UNIT_VALIDATE_LOADED);
     657                 :            : }
     658                 :            : 
     659                 :          0 : static int method_unref_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     660                 :            :         /* Dropping a ref OTOH should not require the unit to still be loaded. And since a reffed unit is a
     661                 :            :          * loaded unit there's no need to load the unit for unreffing it. */
     662                 :          0 :         return method_generic_unit_operation(message, userdata, error, bus_unit_method_unref, 0);
     663                 :            : }
     664                 :            : 
     665                 :          0 : static int reply_unit_info(sd_bus_message *reply, Unit *u) {
     666                 :          0 :         _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
     667                 :            :         Unit *following;
     668                 :            : 
     669                 :          0 :         following = unit_following(u);
     670                 :            : 
     671                 :          0 :         unit_path = unit_dbus_path(u);
     672         [ #  # ]:          0 :         if (!unit_path)
     673                 :          0 :                 return -ENOMEM;
     674                 :            : 
     675         [ #  # ]:          0 :         if (u->job) {
     676                 :          0 :                 job_path = job_dbus_path(u->job);
     677         [ #  # ]:          0 :                 if (!job_path)
     678                 :          0 :                         return -ENOMEM;
     679                 :            :         }
     680                 :            : 
     681         [ #  # ]:          0 :         return sd_bus_message_append(
     682                 :            :                         reply, "(ssssssouso)",
     683                 :            :                         u->id,
     684                 :            :                         unit_description(u),
     685                 :            :                         unit_load_state_to_string(u->load_state),
     686                 :            :                         unit_active_state_to_string(unit_active_state(u)),
     687                 :            :                         unit_sub_state_to_string(u),
     688                 :            :                         following ? following->id : "",
     689                 :            :                         unit_path,
     690         [ #  # ]:          0 :                         u->job ? u->job->id : 0,
     691         [ #  # ]:          0 :                         u->job ? job_type_to_string(u->job->type) : "",
     692                 :            :                         empty_to_root(job_path));
     693                 :            : }
     694                 :            : 
     695                 :          0 : static int method_list_units_by_names(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     696                 :          0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
     697                 :          0 :         Manager *m = userdata;
     698                 :            :         int r;
     699                 :            :         char **unit;
     700                 :          0 :         _cleanup_strv_free_ char **units = NULL;
     701                 :            : 
     702         [ #  # ]:          0 :         assert(message);
     703         [ #  # ]:          0 :         assert(m);
     704                 :            : 
     705                 :          0 :         r = sd_bus_message_read_strv(message, &units);
     706         [ #  # ]:          0 :         if (r < 0)
     707                 :          0 :                 return r;
     708                 :            : 
     709                 :          0 :         r = sd_bus_message_new_method_return(message, &reply);
     710         [ #  # ]:          0 :         if (r < 0)
     711                 :          0 :                 return r;
     712                 :            : 
     713                 :          0 :         r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
     714         [ #  # ]:          0 :         if (r < 0)
     715                 :          0 :                 return r;
     716                 :            : 
     717   [ #  #  #  # ]:          0 :         STRV_FOREACH(unit, units) {
     718                 :            :                 Unit *u;
     719                 :            : 
     720         [ #  # ]:          0 :                 if (!unit_name_is_valid(*unit, UNIT_NAME_ANY))
     721                 :          0 :                         continue;
     722                 :            : 
     723                 :          0 :                 r = bus_load_unit_by_name(m, message, *unit, &u, error);
     724         [ #  # ]:          0 :                 if (r < 0)
     725                 :          0 :                         return r;
     726                 :            : 
     727                 :          0 :                 r = reply_unit_info(reply, u);
     728         [ #  # ]:          0 :                 if (r < 0)
     729                 :          0 :                         return r;
     730                 :            :         }
     731                 :            : 
     732                 :          0 :         r = sd_bus_message_close_container(reply);
     733         [ #  # ]:          0 :         if (r < 0)
     734                 :          0 :                 return r;
     735                 :            : 
     736                 :          0 :         return sd_bus_send(NULL, reply, NULL);
     737                 :            : }
     738                 :            : 
     739                 :          0 : static int method_get_unit_processes(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     740                 :            :         /* Don't load a unit (since it won't have any processes if it's not loaded), but don't insist on the
     741                 :            :          * unit being loaded (because even improperly loaded units might still have processes around */
     742                 :          0 :         return method_generic_unit_operation(message, userdata, error, bus_unit_method_get_processes, 0);
     743                 :            : }
     744                 :            : 
     745                 :          0 : static int method_attach_processes_to_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     746                 :            :         /* Don't allow attaching new processes to units that aren't loaded. Don't bother with loading a unit
     747                 :            :          * for this purpose though, as an unloaded unit is a stopped unit, and we don't allow attaching
     748                 :            :          * processes to stopped units anyway. */
     749                 :          0 :         return method_generic_unit_operation(message, userdata, error, bus_unit_method_attach_processes, GENERIC_UNIT_VALIDATE_LOADED);
     750                 :            : }
     751                 :            : 
     752                 :          0 : static int transient_unit_from_message(
     753                 :            :                 Manager *m,
     754                 :            :                 sd_bus_message *message,
     755                 :            :                 const char *name,
     756                 :            :                 Unit **unit,
     757                 :            :                 sd_bus_error *error) {
     758                 :            : 
     759                 :            :         UnitType t;
     760                 :            :         Unit *u;
     761                 :            :         int r;
     762                 :            : 
     763         [ #  # ]:          0 :         assert(m);
     764         [ #  # ]:          0 :         assert(message);
     765         [ #  # ]:          0 :         assert(name);
     766                 :            : 
     767                 :          0 :         t = unit_name_to_type(name);
     768         [ #  # ]:          0 :         if (t < 0)
     769                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit name or type.");
     770                 :            : 
     771         [ #  # ]:          0 :         if (!unit_vtable[t]->can_transient)
     772                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.", unit_type_to_string(t));
     773                 :            : 
     774                 :          0 :         r = manager_load_unit(m, name, NULL, error, &u);
     775         [ #  # ]:          0 :         if (r < 0)
     776                 :          0 :                 return r;
     777                 :            : 
     778         [ #  # ]:          0 :         if (!unit_is_pristine(u))
     779                 :          0 :                 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
     780                 :            : 
     781                 :            :         /* OK, the unit failed to load and is unreferenced, now let's
     782                 :            :          * fill in the transient data instead */
     783                 :          0 :         r = unit_make_transient(u);
     784         [ #  # ]:          0 :         if (r < 0)
     785                 :          0 :                 return r;
     786                 :            : 
     787                 :            :         /* Set our properties */
     788                 :          0 :         r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
     789         [ #  # ]:          0 :         if (r < 0)
     790                 :          0 :                 return r;
     791                 :            : 
     792                 :            :         /* If the client asked for it, automatically add a reference to this unit. */
     793         [ #  # ]:          0 :         if (u->bus_track_add) {
     794                 :          0 :                 r = bus_unit_track_add_sender(u, message);
     795         [ #  # ]:          0 :                 if (r < 0)
     796         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to watch sender: %m");
     797                 :            :         }
     798                 :            : 
     799                 :            :         /* Now load the missing bits of the unit we just created */
     800                 :          0 :         unit_add_to_load_queue(u);
     801                 :          0 :         manager_dispatch_load_queue(m);
     802                 :            : 
     803                 :          0 :         *unit = u;
     804                 :            : 
     805                 :          0 :         return 0;
     806                 :            : }
     807                 :            : 
     808                 :          0 : static int transient_aux_units_from_message(
     809                 :            :                 Manager *m,
     810                 :            :                 sd_bus_message *message,
     811                 :            :                 sd_bus_error *error) {
     812                 :            : 
     813                 :            :         int r;
     814                 :            : 
     815         [ #  # ]:          0 :         assert(m);
     816         [ #  # ]:          0 :         assert(message);
     817                 :            : 
     818                 :          0 :         r = sd_bus_message_enter_container(message, 'a', "(sa(sv))");
     819         [ #  # ]:          0 :         if (r < 0)
     820                 :          0 :                 return r;
     821                 :            : 
     822         [ #  # ]:          0 :         while ((r = sd_bus_message_enter_container(message, 'r', "sa(sv)")) > 0) {
     823                 :          0 :                 const char *name = NULL;
     824                 :            :                 Unit *u;
     825                 :            : 
     826                 :          0 :                 r = sd_bus_message_read(message, "s", &name);
     827         [ #  # ]:          0 :                 if (r < 0)
     828                 :          0 :                         return r;
     829                 :            : 
     830                 :          0 :                 r = transient_unit_from_message(m, message, name, &u, error);
     831         [ #  # ]:          0 :                 if (r < 0)
     832                 :          0 :                         return r;
     833                 :            : 
     834                 :          0 :                 r = sd_bus_message_exit_container(message);
     835         [ #  # ]:          0 :                 if (r < 0)
     836                 :          0 :                         return r;
     837                 :            :         }
     838         [ #  # ]:          0 :         if (r < 0)
     839                 :          0 :                 return r;
     840                 :            : 
     841                 :          0 :         r = sd_bus_message_exit_container(message);
     842         [ #  # ]:          0 :         if (r < 0)
     843                 :          0 :                 return r;
     844                 :            : 
     845                 :          0 :         return 0;
     846                 :            : }
     847                 :            : 
     848                 :          0 : static int method_start_transient_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     849                 :            :         const char *name, *smode;
     850                 :          0 :         Manager *m = userdata;
     851                 :            :         JobMode mode;
     852                 :            :         Unit *u;
     853                 :            :         int r;
     854                 :            : 
     855         [ #  # ]:          0 :         assert(message);
     856         [ #  # ]:          0 :         assert(m);
     857                 :            : 
     858                 :          0 :         r = mac_selinux_access_check(message, "start", error);
     859         [ #  # ]:          0 :         if (r < 0)
     860                 :          0 :                 return r;
     861                 :            : 
     862                 :          0 :         r = sd_bus_message_read(message, "ss", &name, &smode);
     863         [ #  # ]:          0 :         if (r < 0)
     864                 :          0 :                 return r;
     865                 :            : 
     866                 :          0 :         mode = job_mode_from_string(smode);
     867         [ #  # ]:          0 :         if (mode < 0)
     868                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
     869                 :            : 
     870                 :          0 :         r = bus_verify_manage_units_async(m, message, error);
     871         [ #  # ]:          0 :         if (r < 0)
     872                 :          0 :                 return r;
     873         [ #  # ]:          0 :         if (r == 0)
     874                 :          0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
     875                 :            : 
     876                 :          0 :         r = transient_unit_from_message(m, message, name, &u, error);
     877         [ #  # ]:          0 :         if (r < 0)
     878                 :          0 :                 return r;
     879                 :            : 
     880                 :          0 :         r = transient_aux_units_from_message(m, message, error);
     881         [ #  # ]:          0 :         if (r < 0)
     882                 :          0 :                 return r;
     883                 :            : 
     884                 :            :         /* Finally, start it */
     885                 :          0 :         return bus_unit_queue_job(message, u, JOB_START, mode, 0, error);
     886                 :            : }
     887                 :            : 
     888                 :          0 : static int method_get_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     889                 :          0 :         _cleanup_free_ char *path = NULL;
     890                 :          0 :         Manager *m = userdata;
     891                 :            :         uint32_t id;
     892                 :            :         Job *j;
     893                 :            :         int r;
     894                 :            : 
     895         [ #  # ]:          0 :         assert(message);
     896         [ #  # ]:          0 :         assert(m);
     897                 :            : 
     898                 :            :         /* Anyone can call this method */
     899                 :            : 
     900                 :          0 :         r = sd_bus_message_read(message, "u", &id);
     901         [ #  # ]:          0 :         if (r < 0)
     902                 :          0 :                 return r;
     903                 :            : 
     904                 :          0 :         j = manager_get_job(m, id);
     905         [ #  # ]:          0 :         if (!j)
     906                 :          0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
     907                 :            : 
     908                 :          0 :         r = mac_selinux_unit_access_check(j->unit, message, "status", error);
     909         [ #  # ]:          0 :         if (r < 0)
     910                 :          0 :                 return r;
     911                 :            : 
     912                 :          0 :         path = job_dbus_path(j);
     913         [ #  # ]:          0 :         if (!path)
     914                 :          0 :                 return -ENOMEM;
     915                 :            : 
     916                 :          0 :         return sd_bus_reply_method_return(message, "o", path);
     917                 :            : }
     918                 :            : 
     919                 :          0 : static int method_cancel_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     920                 :          0 :         Manager *m = userdata;
     921                 :            :         uint32_t id;
     922                 :            :         Job *j;
     923                 :            :         int r;
     924                 :            : 
     925         [ #  # ]:          0 :         assert(message);
     926         [ #  # ]:          0 :         assert(m);
     927                 :            : 
     928                 :          0 :         r = sd_bus_message_read(message, "u", &id);
     929         [ #  # ]:          0 :         if (r < 0)
     930                 :          0 :                 return r;
     931                 :            : 
     932                 :          0 :         j = manager_get_job(m, id);
     933         [ #  # ]:          0 :         if (!j)
     934                 :          0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
     935                 :            : 
     936                 :          0 :         return bus_job_method_cancel(message, j, error);
     937                 :            : }
     938                 :            : 
     939                 :          0 : static int method_clear_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     940                 :          0 :         Manager *m = userdata;
     941                 :            :         int r;
     942                 :            : 
     943         [ #  # ]:          0 :         assert(message);
     944         [ #  # ]:          0 :         assert(m);
     945                 :            : 
     946                 :          0 :         r = mac_selinux_access_check(message, "reload", error);
     947         [ #  # ]:          0 :         if (r < 0)
     948                 :          0 :                 return r;
     949                 :            : 
     950                 :          0 :         r = bus_verify_manage_units_async(m, message, error);
     951         [ #  # ]:          0 :         if (r < 0)
     952                 :          0 :                 return r;
     953         [ #  # ]:          0 :         if (r == 0)
     954                 :          0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
     955                 :            : 
     956                 :          0 :         manager_clear_jobs(m);
     957                 :            : 
     958                 :          0 :         return sd_bus_reply_method_return(message, NULL);
     959                 :            : }
     960                 :            : 
     961                 :          0 : static int method_reset_failed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
     962                 :          0 :         Manager *m = userdata;
     963                 :            :         int r;
     964                 :            : 
     965         [ #  # ]:          0 :         assert(message);
     966         [ #  # ]:          0 :         assert(m);
     967                 :            : 
     968                 :          0 :         r = mac_selinux_access_check(message, "reload", error);
     969         [ #  # ]:          0 :         if (r < 0)
     970                 :          0 :                 return r;
     971                 :            : 
     972                 :          0 :         r = bus_verify_manage_units_async(m, message, error);
     973         [ #  # ]:          0 :         if (r < 0)
     974                 :          0 :                 return r;
     975         [ #  # ]:          0 :         if (r == 0)
     976                 :          0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
     977                 :            : 
     978                 :          0 :         manager_reset_failed(m);
     979                 :            : 
     980                 :          0 :         return sd_bus_reply_method_return(message, NULL);
     981                 :            : }
     982                 :            : 
     983                 :          0 : static int list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_error *error, char **states, char **patterns) {
     984                 :          0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
     985                 :          0 :         Manager *m = userdata;
     986                 :            :         const char *k;
     987                 :            :         Iterator i;
     988                 :            :         Unit *u;
     989                 :            :         int r;
     990                 :            : 
     991         [ #  # ]:          0 :         assert(message);
     992         [ #  # ]:          0 :         assert(m);
     993                 :            : 
     994                 :            :         /* Anyone can call this method */
     995                 :            : 
     996                 :          0 :         r = mac_selinux_access_check(message, "status", error);
     997         [ #  # ]:          0 :         if (r < 0)
     998                 :          0 :                 return r;
     999                 :            : 
    1000                 :          0 :         r = sd_bus_message_new_method_return(message, &reply);
    1001         [ #  # ]:          0 :         if (r < 0)
    1002                 :          0 :                 return r;
    1003                 :            : 
    1004                 :          0 :         r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
    1005         [ #  # ]:          0 :         if (r < 0)
    1006                 :          0 :                 return r;
    1007                 :            : 
    1008         [ #  # ]:          0 :         HASHMAP_FOREACH_KEY(u, k, m->units, i) {
    1009         [ #  # ]:          0 :                 if (k != u->id)
    1010                 :          0 :                         continue;
    1011                 :            : 
    1012         [ #  # ]:          0 :                 if (!strv_isempty(states) &&
    1013         [ #  # ]:          0 :                     !strv_contains(states, unit_load_state_to_string(u->load_state)) &&
    1014         [ #  # ]:          0 :                     !strv_contains(states, unit_active_state_to_string(unit_active_state(u))) &&
    1015         [ #  # ]:          0 :                     !strv_contains(states, unit_sub_state_to_string(u)))
    1016                 :          0 :                         continue;
    1017                 :            : 
    1018         [ #  # ]:          0 :                 if (!strv_isempty(patterns) &&
    1019         [ #  # ]:          0 :                     !strv_fnmatch_or_empty(patterns, u->id, FNM_NOESCAPE))
    1020                 :          0 :                         continue;
    1021                 :            : 
    1022                 :          0 :                 r = reply_unit_info(reply, u);
    1023         [ #  # ]:          0 :                 if (r < 0)
    1024                 :          0 :                         return r;
    1025                 :            :         }
    1026                 :            : 
    1027                 :          0 :         r = sd_bus_message_close_container(reply);
    1028         [ #  # ]:          0 :         if (r < 0)
    1029                 :          0 :                 return r;
    1030                 :            : 
    1031                 :          0 :         return sd_bus_send(NULL, reply, NULL);
    1032                 :            : }
    1033                 :            : 
    1034                 :          0 : static int method_list_units(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1035                 :          0 :         return list_units_filtered(message, userdata, error, NULL, NULL);
    1036                 :            : }
    1037                 :            : 
    1038                 :          0 : static int method_list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1039                 :          0 :         _cleanup_strv_free_ char **states = NULL;
    1040                 :            :         int r;
    1041                 :            : 
    1042                 :          0 :         r = sd_bus_message_read_strv(message, &states);
    1043         [ #  # ]:          0 :         if (r < 0)
    1044                 :          0 :                 return r;
    1045                 :            : 
    1046                 :          0 :         return list_units_filtered(message, userdata, error, states, NULL);
    1047                 :            : }
    1048                 :            : 
    1049                 :          0 : static int method_list_units_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1050                 :          0 :         _cleanup_strv_free_ char **states = NULL;
    1051                 :          0 :         _cleanup_strv_free_ char **patterns = NULL;
    1052                 :            :         int r;
    1053                 :            : 
    1054                 :          0 :         r = sd_bus_message_read_strv(message, &states);
    1055         [ #  # ]:          0 :         if (r < 0)
    1056                 :          0 :                 return r;
    1057                 :            : 
    1058                 :          0 :         r = sd_bus_message_read_strv(message, &patterns);
    1059         [ #  # ]:          0 :         if (r < 0)
    1060                 :          0 :                 return r;
    1061                 :            : 
    1062                 :          0 :         return list_units_filtered(message, userdata, error, states, patterns);
    1063                 :            : }
    1064                 :            : 
    1065                 :          0 : static int method_list_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1066                 :          0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
    1067                 :          0 :         Manager *m = userdata;
    1068                 :            :         Iterator i;
    1069                 :            :         Job *j;
    1070                 :            :         int r;
    1071                 :            : 
    1072         [ #  # ]:          0 :         assert(message);
    1073         [ #  # ]:          0 :         assert(m);
    1074                 :            : 
    1075                 :            :         /* Anyone can call this method */
    1076                 :            : 
    1077                 :          0 :         r = mac_selinux_access_check(message, "status", error);
    1078         [ #  # ]:          0 :         if (r < 0)
    1079                 :          0 :                 return r;
    1080                 :            : 
    1081                 :          0 :         r = sd_bus_message_new_method_return(message, &reply);
    1082         [ #  # ]:          0 :         if (r < 0)
    1083                 :          0 :                 return r;
    1084                 :            : 
    1085                 :          0 :         r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
    1086         [ #  # ]:          0 :         if (r < 0)
    1087                 :          0 :                 return r;
    1088                 :            : 
    1089         [ #  # ]:          0 :         HASHMAP_FOREACH(j, m->jobs, i) {
    1090   [ #  #  #  # ]:          0 :                 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
    1091                 :            : 
    1092                 :          0 :                 job_path = job_dbus_path(j);
    1093         [ #  # ]:          0 :                 if (!job_path)
    1094                 :          0 :                         return -ENOMEM;
    1095                 :            : 
    1096                 :          0 :                 unit_path = unit_dbus_path(j->unit);
    1097         [ #  # ]:          0 :                 if (!unit_path)
    1098                 :          0 :                         return -ENOMEM;
    1099                 :            : 
    1100                 :          0 :                 r = sd_bus_message_append(
    1101                 :            :                                 reply, "(usssoo)",
    1102                 :          0 :                                 j->id,
    1103                 :          0 :                                 j->unit->id,
    1104                 :          0 :                                 job_type_to_string(j->type),
    1105                 :          0 :                                 job_state_to_string(j->state),
    1106                 :            :                                 job_path,
    1107                 :            :                                 unit_path);
    1108         [ #  # ]:          0 :                 if (r < 0)
    1109                 :          0 :                         return r;
    1110                 :            :         }
    1111                 :            : 
    1112                 :          0 :         r = sd_bus_message_close_container(reply);
    1113         [ #  # ]:          0 :         if (r < 0)
    1114                 :          0 :                 return r;
    1115                 :            : 
    1116                 :          0 :         return sd_bus_send(NULL, reply, NULL);
    1117                 :            : }
    1118                 :            : 
    1119                 :          0 : static int method_subscribe(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1120                 :          0 :         Manager *m = userdata;
    1121                 :            :         int r;
    1122                 :            : 
    1123         [ #  # ]:          0 :         assert(message);
    1124         [ #  # ]:          0 :         assert(m);
    1125                 :            : 
    1126                 :            :         /* Anyone can call this method */
    1127                 :            : 
    1128                 :          0 :         r = mac_selinux_access_check(message, "status", error);
    1129         [ #  # ]:          0 :         if (r < 0)
    1130                 :          0 :                 return r;
    1131                 :            : 
    1132         [ #  # ]:          0 :         if (sd_bus_message_get_bus(message) == m->api_bus) {
    1133                 :            : 
    1134                 :            :                 /* Note that direct bus connection subscribe by
    1135                 :            :                  * default, we only track peers on the API bus here */
    1136                 :            : 
    1137         [ #  # ]:          0 :                 if (!m->subscribed) {
    1138                 :          0 :                         r = sd_bus_track_new(sd_bus_message_get_bus(message), &m->subscribed, NULL, NULL);
    1139         [ #  # ]:          0 :                         if (r < 0)
    1140                 :          0 :                                 return r;
    1141                 :            :                 }
    1142                 :            : 
    1143                 :          0 :                 r = sd_bus_track_add_sender(m->subscribed, message);
    1144         [ #  # ]:          0 :                 if (r < 0)
    1145                 :          0 :                         return r;
    1146         [ #  # ]:          0 :                 if (r == 0)
    1147                 :          0 :                         return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
    1148                 :            :         }
    1149                 :            : 
    1150                 :          0 :         return sd_bus_reply_method_return(message, NULL);
    1151                 :            : }
    1152                 :            : 
    1153                 :          0 : static int method_unsubscribe(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1154                 :          0 :         Manager *m = userdata;
    1155                 :            :         int r;
    1156                 :            : 
    1157         [ #  # ]:          0 :         assert(message);
    1158         [ #  # ]:          0 :         assert(m);
    1159                 :            : 
    1160                 :            :         /* Anyone can call this method */
    1161                 :            : 
    1162                 :          0 :         r = mac_selinux_access_check(message, "status", error);
    1163         [ #  # ]:          0 :         if (r < 0)
    1164                 :          0 :                 return r;
    1165                 :            : 
    1166         [ #  # ]:          0 :         if (sd_bus_message_get_bus(message) == m->api_bus) {
    1167                 :          0 :                 r = sd_bus_track_remove_sender(m->subscribed, message);
    1168         [ #  # ]:          0 :                 if (r < 0)
    1169                 :          0 :                         return r;
    1170         [ #  # ]:          0 :                 if (r == 0)
    1171                 :          0 :                         return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
    1172                 :            :         }
    1173                 :            : 
    1174                 :          0 :         return sd_bus_reply_method_return(message, NULL);
    1175                 :            : }
    1176                 :            : 
    1177                 :          0 : static int dump_impl(sd_bus_message *message, void *userdata, sd_bus_error *error, int (*reply)(sd_bus_message *, char *)) {
    1178                 :          0 :         _cleanup_free_ char *dump = NULL;
    1179                 :          0 :         Manager *m = userdata;
    1180                 :            :         int r;
    1181                 :            : 
    1182         [ #  # ]:          0 :         assert(message);
    1183         [ #  # ]:          0 :         assert(m);
    1184                 :            : 
    1185                 :            :         /* Anyone can call this method */
    1186                 :            : 
    1187                 :          0 :         r = mac_selinux_access_check(message, "status", error);
    1188         [ #  # ]:          0 :         if (r < 0)
    1189                 :          0 :                 return r;
    1190                 :            : 
    1191                 :          0 :         r = manager_get_dump_string(m, &dump);
    1192         [ #  # ]:          0 :         if (r < 0)
    1193                 :          0 :                 return r;
    1194                 :            : 
    1195                 :          0 :         return reply(message, dump);
    1196                 :            : }
    1197                 :            : 
    1198                 :          0 : static int reply_dump(sd_bus_message *message, char *dump) {
    1199                 :          0 :         return sd_bus_reply_method_return(message, "s", dump);
    1200                 :            : }
    1201                 :            : 
    1202                 :          0 : static int method_dump(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1203                 :          0 :         return dump_impl(message, userdata, error, reply_dump);
    1204                 :            : }
    1205                 :            : 
    1206                 :          0 : static int reply_dump_by_fd(sd_bus_message *message, char *dump) {
    1207                 :          0 :         _cleanup_close_ int fd = -1;
    1208                 :            : 
    1209                 :          0 :         fd = acquire_data_fd(dump, strlen(dump), 0);
    1210         [ #  # ]:          0 :         if (fd < 0)
    1211                 :          0 :                 return fd;
    1212                 :            : 
    1213                 :          0 :         return sd_bus_reply_method_return(message, "h", fd);
    1214                 :            : }
    1215                 :            : 
    1216                 :          0 : static int method_dump_by_fd(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1217                 :          0 :         return dump_impl(message, userdata, error, reply_dump_by_fd);
    1218                 :            : }
    1219                 :            : 
    1220                 :          0 : static int method_refuse_snapshot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1221                 :          0 :         return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Support for snapshots has been removed.");
    1222                 :            : }
    1223                 :            : 
    1224                 :          0 : static int verify_run_space(const char *message, sd_bus_error *error) {
    1225                 :            :         struct statvfs svfs;
    1226                 :            :         uint64_t available;
    1227                 :            : 
    1228         [ #  # ]:          0 :         if (statvfs("/run/systemd", &svfs) < 0)
    1229                 :          0 :                 return sd_bus_error_set_errnof(error, errno, "Failed to statvfs(/run/systemd): %m");
    1230                 :            : 
    1231                 :          0 :         available = (uint64_t) svfs.f_bfree * (uint64_t) svfs.f_bsize;
    1232                 :            : 
    1233         [ #  # ]:          0 :         if (available < RELOAD_DISK_SPACE_MIN) {
    1234                 :            :                 char fb_available[FORMAT_BYTES_MAX], fb_need[FORMAT_BYTES_MAX];
    1235                 :          0 :                 return sd_bus_error_setf(error,
    1236                 :            :                                          BUS_ERROR_DISK_FULL,
    1237                 :            :                                          "%s, not enough space available on /run/systemd. "
    1238                 :            :                                          "Currently, %s are free, but a safety buffer of %s is enforced.",
    1239                 :            :                                          message,
    1240                 :            :                                          format_bytes(fb_available, sizeof(fb_available), available),
    1241                 :            :                                          format_bytes(fb_need, sizeof(fb_need), RELOAD_DISK_SPACE_MIN));
    1242                 :            :         }
    1243                 :            : 
    1244                 :          0 :         return 0;
    1245                 :            : }
    1246                 :            : 
    1247                 :          0 : int verify_run_space_and_log(const char *message) {
    1248                 :          0 :         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
    1249                 :            :         int r;
    1250                 :            : 
    1251                 :          0 :         r = verify_run_space(message, &error);
    1252         [ #  # ]:          0 :         if (r < 0)
    1253         [ #  # ]:          0 :                 return log_error_errno(r, "%s", bus_error_message(&error, r));
    1254                 :            : 
    1255                 :          0 :         return 0;
    1256                 :            : }
    1257                 :            : 
    1258                 :          0 : static int method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1259                 :          0 :         Manager *m = userdata;
    1260                 :            :         int r;
    1261                 :            : 
    1262         [ #  # ]:          0 :         assert(message);
    1263         [ #  # ]:          0 :         assert(m);
    1264                 :            : 
    1265                 :          0 :         r = verify_run_space("Refusing to reload", error);
    1266         [ #  # ]:          0 :         if (r < 0)
    1267                 :          0 :                 return r;
    1268                 :            : 
    1269                 :          0 :         r = mac_selinux_access_check(message, "reload", error);
    1270         [ #  # ]:          0 :         if (r < 0)
    1271                 :          0 :                 return r;
    1272                 :            : 
    1273                 :          0 :         r = bus_verify_reload_daemon_async(m, message, error);
    1274         [ #  # ]:          0 :         if (r < 0)
    1275                 :          0 :                 return r;
    1276         [ #  # ]:          0 :         if (r == 0)
    1277                 :          0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1278                 :            : 
    1279                 :            :         /* Instead of sending the reply back right away, we just
    1280                 :            :          * remember that we need to and then send it after the reload
    1281                 :            :          * is finished. That way the caller knows when the reload
    1282                 :            :          * finished. */
    1283                 :            : 
    1284         [ #  # ]:          0 :         assert(!m->pending_reload_message);
    1285                 :          0 :         r = sd_bus_message_new_method_return(message, &m->pending_reload_message);
    1286         [ #  # ]:          0 :         if (r < 0)
    1287                 :          0 :                 return r;
    1288                 :            : 
    1289                 :          0 :         m->objective = MANAGER_RELOAD;
    1290                 :            : 
    1291                 :          0 :         return 1;
    1292                 :            : }
    1293                 :            : 
    1294                 :          0 : static int method_reexecute(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1295                 :          0 :         Manager *m = userdata;
    1296                 :            :         int r;
    1297                 :            : 
    1298         [ #  # ]:          0 :         assert(message);
    1299         [ #  # ]:          0 :         assert(m);
    1300                 :            : 
    1301                 :          0 :         r = verify_run_space("Refusing to reexecute", error);
    1302         [ #  # ]:          0 :         if (r < 0)
    1303                 :          0 :                 return r;
    1304                 :            : 
    1305                 :          0 :         r = mac_selinux_access_check(message, "reload", error);
    1306         [ #  # ]:          0 :         if (r < 0)
    1307                 :          0 :                 return r;
    1308                 :            : 
    1309                 :          0 :         r = bus_verify_reload_daemon_async(m, message, error);
    1310         [ #  # ]:          0 :         if (r < 0)
    1311                 :          0 :                 return r;
    1312         [ #  # ]:          0 :         if (r == 0)
    1313                 :          0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1314                 :            : 
    1315                 :            :         /* We don't send a reply back here, the client should
    1316                 :            :          * just wait for us disconnecting. */
    1317                 :            : 
    1318                 :          0 :         m->objective = MANAGER_REEXECUTE;
    1319                 :          0 :         return 1;
    1320                 :            : }
    1321                 :            : 
    1322                 :          0 : static int method_exit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1323                 :          0 :         Manager *m = userdata;
    1324                 :            :         int r;
    1325                 :            : 
    1326         [ #  # ]:          0 :         assert(message);
    1327         [ #  # ]:          0 :         assert(m);
    1328                 :            : 
    1329                 :          0 :         r = mac_selinux_access_check(message, "halt", error);
    1330         [ #  # ]:          0 :         if (r < 0)
    1331                 :          0 :                 return r;
    1332                 :            : 
    1333                 :            :         /* Exit() (in contrast to SetExitCode()) is actually allowed even if
    1334                 :            :          * we are running on the host. It will fall back on reboot() in
    1335                 :            :          * systemd-shutdown if it cannot do the exit() because it isn't a
    1336                 :            :          * container. */
    1337                 :            : 
    1338                 :          0 :         m->objective = MANAGER_EXIT;
    1339                 :            : 
    1340                 :          0 :         return sd_bus_reply_method_return(message, NULL);
    1341                 :            : }
    1342                 :            : 
    1343                 :          0 : static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1344                 :          0 :         Manager *m = userdata;
    1345                 :            :         int r;
    1346                 :            : 
    1347         [ #  # ]:          0 :         assert(message);
    1348         [ #  # ]:          0 :         assert(m);
    1349                 :            : 
    1350                 :          0 :         r = mac_selinux_access_check(message, "reboot", error);
    1351         [ #  # ]:          0 :         if (r < 0)
    1352                 :          0 :                 return r;
    1353                 :            : 
    1354         [ #  # ]:          0 :         if (!MANAGER_IS_SYSTEM(m))
    1355                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
    1356                 :            : 
    1357                 :          0 :         m->objective = MANAGER_REBOOT;
    1358                 :            : 
    1359                 :          0 :         return sd_bus_reply_method_return(message, NULL);
    1360                 :            : }
    1361                 :            : 
    1362                 :          0 : static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1363                 :          0 :         Manager *m = userdata;
    1364                 :            :         int r;
    1365                 :            : 
    1366         [ #  # ]:          0 :         assert(message);
    1367         [ #  # ]:          0 :         assert(m);
    1368                 :            : 
    1369                 :          0 :         r = mac_selinux_access_check(message, "halt", error);
    1370         [ #  # ]:          0 :         if (r < 0)
    1371                 :          0 :                 return r;
    1372                 :            : 
    1373         [ #  # ]:          0 :         if (!MANAGER_IS_SYSTEM(m))
    1374                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
    1375                 :            : 
    1376                 :          0 :         m->objective = MANAGER_POWEROFF;
    1377                 :            : 
    1378                 :          0 :         return sd_bus_reply_method_return(message, NULL);
    1379                 :            : }
    1380                 :            : 
    1381                 :          0 : static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1382                 :          0 :         Manager *m = userdata;
    1383                 :            :         int r;
    1384                 :            : 
    1385         [ #  # ]:          0 :         assert(message);
    1386         [ #  # ]:          0 :         assert(m);
    1387                 :            : 
    1388                 :          0 :         r = mac_selinux_access_check(message, "halt", error);
    1389         [ #  # ]:          0 :         if (r < 0)
    1390                 :          0 :                 return r;
    1391                 :            : 
    1392         [ #  # ]:          0 :         if (!MANAGER_IS_SYSTEM(m))
    1393                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
    1394                 :            : 
    1395                 :          0 :         m->objective = MANAGER_HALT;
    1396                 :            : 
    1397                 :          0 :         return sd_bus_reply_method_return(message, NULL);
    1398                 :            : }
    1399                 :            : 
    1400                 :          0 : static int method_kexec(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1401                 :          0 :         Manager *m = userdata;
    1402                 :            :         int r;
    1403                 :            : 
    1404         [ #  # ]:          0 :         assert(message);
    1405         [ #  # ]:          0 :         assert(m);
    1406                 :            : 
    1407                 :          0 :         r = mac_selinux_access_check(message, "reboot", error);
    1408         [ #  # ]:          0 :         if (r < 0)
    1409                 :          0 :                 return r;
    1410                 :            : 
    1411         [ #  # ]:          0 :         if (!MANAGER_IS_SYSTEM(m))
    1412                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
    1413                 :            : 
    1414                 :          0 :         m->objective = MANAGER_KEXEC;
    1415                 :            : 
    1416                 :          0 :         return sd_bus_reply_method_return(message, NULL);
    1417                 :            : }
    1418                 :            : 
    1419                 :          0 : static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1420                 :          0 :         _cleanup_free_ char *ri = NULL, *rt = NULL;
    1421                 :            :         const char *root, *init;
    1422                 :          0 :         Manager *m = userdata;
    1423                 :            :         struct statvfs svfs;
    1424                 :            :         uint64_t available;
    1425                 :            :         int r;
    1426                 :            : 
    1427         [ #  # ]:          0 :         assert(message);
    1428         [ #  # ]:          0 :         assert(m);
    1429                 :            : 
    1430         [ #  # ]:          0 :         if (statvfs("/run/systemd", &svfs) < 0)
    1431                 :          0 :                 return sd_bus_error_set_errnof(error, errno, "Failed to statvfs(/run/systemd): %m");
    1432                 :            : 
    1433                 :          0 :         available = (uint64_t) svfs.f_bfree * (uint64_t) svfs.f_bsize;
    1434                 :            : 
    1435         [ #  # ]:          0 :         if (available < RELOAD_DISK_SPACE_MIN) {
    1436                 :            :                 char fb_available[FORMAT_BYTES_MAX], fb_need[FORMAT_BYTES_MAX];
    1437         [ #  # ]:          0 :                 log_warning("Dangerously low amount of free space on /run/systemd, root switching operation might not complete successfully. "
    1438                 :            :                             "Currently, %s are free, but %s are suggested. Proceeding anyway.",
    1439                 :            :                             format_bytes(fb_available, sizeof(fb_available), available),
    1440                 :            :                             format_bytes(fb_need, sizeof(fb_need), RELOAD_DISK_SPACE_MIN));
    1441                 :            :         }
    1442                 :            : 
    1443                 :          0 :         r = mac_selinux_access_check(message, "reboot", error);
    1444         [ #  # ]:          0 :         if (r < 0)
    1445                 :          0 :                 return r;
    1446                 :            : 
    1447         [ #  # ]:          0 :         if (!MANAGER_IS_SYSTEM(m))
    1448                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Root switching is only supported by system manager.");
    1449                 :            : 
    1450                 :          0 :         r = sd_bus_message_read(message, "ss", &root, &init);
    1451         [ #  # ]:          0 :         if (r < 0)
    1452                 :          0 :                 return r;
    1453                 :            : 
    1454         [ #  # ]:          0 :         if (isempty(root))
    1455                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New root directory may not be the empty string.");
    1456         [ #  # ]:          0 :         if (!path_is_absolute(root))
    1457                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New root path '%s' is not absolute.", root);
    1458         [ #  # ]:          0 :         if (path_equal(root, "/"))
    1459                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "New root directory cannot be the old root directory.");
    1460                 :            : 
    1461                 :            :         /* Safety check */
    1462         [ #  # ]:          0 :         if (isempty(init)) {
    1463                 :          0 :                 r = path_is_os_tree(root);
    1464         [ #  # ]:          0 :                 if (r < 0)
    1465                 :          0 :                         return sd_bus_error_set_errnof(error, r, "Failed to determine whether root path '%s' contains an OS tree: %m", root);
    1466         [ #  # ]:          0 :                 if (r == 0)
    1467                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path '%s' does not seem to be an OS tree. os-release file is missing.", root);
    1468                 :            :         } else {
    1469         [ #  # ]:          0 :                 _cleanup_free_ char *chased = NULL;
    1470                 :            : 
    1471         [ #  # ]:          0 :                 if (!path_is_absolute(init))
    1472                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path to init binary '%s' not absolute.", init);
    1473                 :            : 
    1474                 :          0 :                 r = chase_symlinks(init, root, CHASE_PREFIX_ROOT|CHASE_TRAIL_SLASH, &chased);
    1475         [ #  # ]:          0 :                 if (r < 0)
    1476                 :          0 :                         return sd_bus_error_set_errnof(error, r, "Could not resolve init executable %s: %m", init);
    1477                 :            : 
    1478         [ #  # ]:          0 :                 if (laccess(chased, X_OK) < 0) {
    1479         [ #  # ]:          0 :                         if (errno == EACCES)
    1480                 :          0 :                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Init binary %s is not executable.", init);
    1481                 :            : 
    1482                 :          0 :                         return sd_bus_error_set_errnof(error, r, "Could not check whether init binary %s is executable: %m", init);
    1483                 :            :                 }
    1484                 :            :         }
    1485                 :            : 
    1486                 :          0 :         rt = strdup(root);
    1487         [ #  # ]:          0 :         if (!rt)
    1488                 :          0 :                 return -ENOMEM;
    1489                 :            : 
    1490         [ #  # ]:          0 :         if (!isempty(init)) {
    1491                 :          0 :                 ri = strdup(init);
    1492         [ #  # ]:          0 :                 if (!ri)
    1493                 :          0 :                         return -ENOMEM;
    1494                 :            :         }
    1495                 :            : 
    1496                 :          0 :         free_and_replace(m->switch_root, rt);
    1497                 :          0 :         free_and_replace(m->switch_root_init, ri);
    1498                 :            : 
    1499                 :          0 :         m->objective = MANAGER_SWITCH_ROOT;
    1500                 :            : 
    1501                 :          0 :         return sd_bus_reply_method_return(message, NULL);
    1502                 :            : }
    1503                 :            : 
    1504                 :          0 : static int method_set_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1505                 :          0 :         _cleanup_strv_free_ char **plus = NULL;
    1506                 :          0 :         Manager *m = userdata;
    1507                 :            :         int r;
    1508                 :            : 
    1509         [ #  # ]:          0 :         assert(message);
    1510         [ #  # ]:          0 :         assert(m);
    1511                 :            : 
    1512                 :          0 :         r = mac_selinux_access_check(message, "reload", error);
    1513         [ #  # ]:          0 :         if (r < 0)
    1514                 :          0 :                 return r;
    1515                 :            : 
    1516                 :          0 :         r = sd_bus_message_read_strv(message, &plus);
    1517         [ #  # ]:          0 :         if (r < 0)
    1518                 :          0 :                 return r;
    1519         [ #  # ]:          0 :         if (!strv_env_is_valid(plus))
    1520                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
    1521                 :            : 
    1522                 :          0 :         r = bus_verify_set_environment_async(m, message, error);
    1523         [ #  # ]:          0 :         if (r < 0)
    1524                 :          0 :                 return r;
    1525         [ #  # ]:          0 :         if (r == 0)
    1526                 :          0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1527                 :            : 
    1528                 :          0 :         r = manager_client_environment_modify(m, NULL, plus);
    1529         [ #  # ]:          0 :         if (r < 0)
    1530                 :          0 :                 return r;
    1531                 :            : 
    1532                 :          0 :         return sd_bus_reply_method_return(message, NULL);
    1533                 :            : }
    1534                 :            : 
    1535                 :          0 : static int method_unset_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1536                 :          0 :         _cleanup_strv_free_ char **minus = NULL;
    1537                 :          0 :         Manager *m = userdata;
    1538                 :            :         int r;
    1539                 :            : 
    1540         [ #  # ]:          0 :         assert(message);
    1541         [ #  # ]:          0 :         assert(m);
    1542                 :            : 
    1543                 :          0 :         r = mac_selinux_access_check(message, "reload", error);
    1544         [ #  # ]:          0 :         if (r < 0)
    1545                 :          0 :                 return r;
    1546                 :            : 
    1547                 :          0 :         r = sd_bus_message_read_strv(message, &minus);
    1548         [ #  # ]:          0 :         if (r < 0)
    1549                 :          0 :                 return r;
    1550                 :            : 
    1551         [ #  # ]:          0 :         if (!strv_env_name_or_assignment_is_valid(minus))
    1552                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
    1553                 :            : 
    1554                 :          0 :         r = bus_verify_set_environment_async(m, message, error);
    1555         [ #  # ]:          0 :         if (r < 0)
    1556                 :          0 :                 return r;
    1557         [ #  # ]:          0 :         if (r == 0)
    1558                 :          0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1559                 :            : 
    1560                 :          0 :         r = manager_client_environment_modify(m, minus, NULL);
    1561         [ #  # ]:          0 :         if (r < 0)
    1562                 :          0 :                 return r;
    1563                 :            : 
    1564                 :          0 :         return sd_bus_reply_method_return(message, NULL);
    1565                 :            : }
    1566                 :            : 
    1567                 :          0 : static int method_unset_and_set_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1568                 :          0 :         _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
    1569                 :          0 :         Manager *m = userdata;
    1570                 :            :         int r;
    1571                 :            : 
    1572         [ #  # ]:          0 :         assert(message);
    1573         [ #  # ]:          0 :         assert(m);
    1574                 :            : 
    1575                 :          0 :         r = mac_selinux_access_check(message, "reload", error);
    1576         [ #  # ]:          0 :         if (r < 0)
    1577                 :          0 :                 return r;
    1578                 :            : 
    1579                 :          0 :         r = sd_bus_message_read_strv(message, &minus);
    1580         [ #  # ]:          0 :         if (r < 0)
    1581                 :          0 :                 return r;
    1582                 :            : 
    1583                 :          0 :         r = sd_bus_message_read_strv(message, &plus);
    1584         [ #  # ]:          0 :         if (r < 0)
    1585                 :          0 :                 return r;
    1586                 :            : 
    1587         [ #  # ]:          0 :         if (!strv_env_name_or_assignment_is_valid(minus))
    1588                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
    1589         [ #  # ]:          0 :         if (!strv_env_is_valid(plus))
    1590                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
    1591                 :            : 
    1592                 :          0 :         r = bus_verify_set_environment_async(m, message, error);
    1593         [ #  # ]:          0 :         if (r < 0)
    1594                 :          0 :                 return r;
    1595         [ #  # ]:          0 :         if (r == 0)
    1596                 :          0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    1597                 :            : 
    1598                 :          0 :         r = manager_client_environment_modify(m, minus, plus);
    1599         [ #  # ]:          0 :         if (r < 0)
    1600                 :          0 :                 return r;
    1601                 :            : 
    1602                 :          0 :         return sd_bus_reply_method_return(message, NULL);
    1603                 :            : }
    1604                 :            : 
    1605                 :          0 : static int method_set_exit_code(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1606                 :          0 :         Manager *m = userdata;
    1607                 :            :         uint8_t code;
    1608                 :            :         int r;
    1609                 :            : 
    1610         [ #  # ]:          0 :         assert(message);
    1611         [ #  # ]:          0 :         assert(m);
    1612                 :            : 
    1613                 :          0 :         r = mac_selinux_access_check(message, "exit", error);
    1614         [ #  # ]:          0 :         if (r < 0)
    1615                 :          0 :                 return r;
    1616                 :            : 
    1617                 :          0 :         r = sd_bus_message_read_basic(message, 'y', &code);
    1618         [ #  # ]:          0 :         if (r < 0)
    1619                 :          0 :                 return r;
    1620                 :            : 
    1621   [ #  #  #  # ]:          0 :         if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0)
    1622                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "ExitCode can only be set for user service managers or in containers.");
    1623                 :            : 
    1624                 :          0 :         m->return_value = code;
    1625                 :            : 
    1626                 :          0 :         return sd_bus_reply_method_return(message, NULL);
    1627                 :            : }
    1628                 :            : 
    1629                 :          0 : static int method_lookup_dynamic_user_by_name(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1630                 :          0 :         Manager *m = userdata;
    1631                 :            :         const char *name;
    1632                 :            :         uid_t uid;
    1633                 :            :         int r;
    1634                 :            : 
    1635         [ #  # ]:          0 :         assert(message);
    1636         [ #  # ]:          0 :         assert(m);
    1637                 :            : 
    1638                 :          0 :         r = sd_bus_message_read_basic(message, 's', &name);
    1639         [ #  # ]:          0 :         if (r < 0)
    1640                 :          0 :                 return r;
    1641                 :            : 
    1642         [ #  # ]:          0 :         if (!MANAGER_IS_SYSTEM(m))
    1643                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Dynamic users are only supported in the system instance.");
    1644         [ #  # ]:          0 :         if (!valid_user_group_name(name))
    1645                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "User name invalid: %s", name);
    1646                 :            : 
    1647                 :          0 :         r = dynamic_user_lookup_name(m, name, &uid);
    1648         [ #  # ]:          0 :         if (r == -ESRCH)
    1649                 :          0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_DYNAMIC_USER, "Dynamic user %s does not exist.", name);
    1650         [ #  # ]:          0 :         if (r < 0)
    1651                 :          0 :                 return r;
    1652                 :            : 
    1653                 :          0 :         return sd_bus_reply_method_return(message, "u", (uint32_t) uid);
    1654                 :            : }
    1655                 :            : 
    1656                 :          0 : static int method_lookup_dynamic_user_by_uid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1657                 :          0 :         _cleanup_free_ char *name = NULL;
    1658                 :          0 :         Manager *m = userdata;
    1659                 :            :         uid_t uid;
    1660                 :            :         int r;
    1661                 :            : 
    1662         [ #  # ]:          0 :         assert(message);
    1663         [ #  # ]:          0 :         assert(m);
    1664                 :            : 
    1665                 :            :         assert_cc(sizeof(uid) == sizeof(uint32_t));
    1666                 :          0 :         r = sd_bus_message_read_basic(message, 'u', &uid);
    1667         [ #  # ]:          0 :         if (r < 0)
    1668                 :          0 :                 return r;
    1669                 :            : 
    1670         [ #  # ]:          0 :         if (!MANAGER_IS_SYSTEM(m))
    1671                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Dynamic users are only supported in the system instance.");
    1672         [ #  # ]:          0 :         if (!uid_is_valid(uid))
    1673                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "User ID invalid: " UID_FMT, uid);
    1674                 :            : 
    1675                 :          0 :         r = dynamic_user_lookup_uid(m, uid, &name);
    1676         [ #  # ]:          0 :         if (r == -ESRCH)
    1677                 :          0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_DYNAMIC_USER, "Dynamic user ID " UID_FMT " does not exist.", uid);
    1678         [ #  # ]:          0 :         if (r < 0)
    1679                 :          0 :                 return r;
    1680                 :            : 
    1681                 :          0 :         return sd_bus_reply_method_return(message, "s", name);
    1682                 :            : }
    1683                 :            : 
    1684                 :          0 : static int method_get_dynamic_users(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1685                 :          0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
    1686                 :          0 :         Manager *m = userdata;
    1687                 :            :         DynamicUser *d;
    1688                 :            :         Iterator i;
    1689                 :            :         int r;
    1690                 :            : 
    1691         [ #  # ]:          0 :         assert(message);
    1692         [ #  # ]:          0 :         assert(m);
    1693                 :            : 
    1694                 :            :         assert_cc(sizeof(uid_t) == sizeof(uint32_t));
    1695                 :            : 
    1696         [ #  # ]:          0 :         if (!MANAGER_IS_SYSTEM(m))
    1697                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Dynamic users are only supported in the system instance.");
    1698                 :            : 
    1699                 :          0 :         r = sd_bus_message_new_method_return(message, &reply);
    1700         [ #  # ]:          0 :         if (r < 0)
    1701                 :          0 :                 return r;
    1702                 :            : 
    1703                 :          0 :         r = sd_bus_message_open_container(reply, 'a', "(us)");
    1704         [ #  # ]:          0 :         if (r < 0)
    1705                 :          0 :                 return r;
    1706                 :            : 
    1707         [ #  # ]:          0 :         HASHMAP_FOREACH(d, m->dynamic_users, i) {
    1708                 :            :                 uid_t uid;
    1709                 :            : 
    1710                 :          0 :                 r = dynamic_user_current(d, &uid);
    1711         [ #  # ]:          0 :                 if (r == -EAGAIN) /* not realized yet? */
    1712                 :          0 :                         continue;
    1713         [ #  # ]:          0 :                 if (r < 0)
    1714                 :          0 :                         return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Failed to lookup a dynamic user.");
    1715                 :            : 
    1716                 :          0 :                 r = sd_bus_message_append(reply, "(us)", uid, d->name);
    1717         [ #  # ]:          0 :                 if (r < 0)
    1718                 :          0 :                         return r;
    1719                 :            :         }
    1720                 :            : 
    1721                 :          0 :         r = sd_bus_message_close_container(reply);
    1722         [ #  # ]:          0 :         if (r < 0)
    1723                 :          0 :                 return r;
    1724                 :            : 
    1725                 :          0 :         return sd_bus_send(NULL, reply, NULL);
    1726                 :            : }
    1727                 :            : 
    1728                 :          0 : static int list_unit_files_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error, char **states, char **patterns) {
    1729                 :          0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
    1730                 :          0 :         Manager *m = userdata;
    1731                 :            :         UnitFileList *item;
    1732                 :            :         Hashmap *h;
    1733                 :            :         Iterator i;
    1734                 :            :         int r;
    1735                 :            : 
    1736         [ #  # ]:          0 :         assert(message);
    1737         [ #  # ]:          0 :         assert(m);
    1738                 :            : 
    1739                 :            :         /* Anyone can call this method */
    1740                 :            : 
    1741                 :          0 :         r = mac_selinux_access_check(message, "status", error);
    1742         [ #  # ]:          0 :         if (r < 0)
    1743                 :          0 :                 return r;
    1744                 :            : 
    1745                 :          0 :         r = sd_bus_message_new_method_return(message, &reply);
    1746         [ #  # ]:          0 :         if (r < 0)
    1747                 :          0 :                 return r;
    1748                 :            : 
    1749                 :          0 :         h = hashmap_new(&string_hash_ops);
    1750         [ #  # ]:          0 :         if (!h)
    1751                 :          0 :                 return -ENOMEM;
    1752                 :            : 
    1753                 :          0 :         r = unit_file_get_list(m->unit_file_scope, NULL, h, states, patterns);
    1754         [ #  # ]:          0 :         if (r < 0)
    1755                 :          0 :                 goto fail;
    1756                 :            : 
    1757                 :          0 :         r = sd_bus_message_open_container(reply, 'a', "(ss)");
    1758         [ #  # ]:          0 :         if (r < 0)
    1759                 :          0 :                 goto fail;
    1760                 :            : 
    1761         [ #  # ]:          0 :         HASHMAP_FOREACH(item, h, i) {
    1762                 :            : 
    1763                 :          0 :                 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
    1764         [ #  # ]:          0 :                 if (r < 0)
    1765                 :          0 :                         goto fail;
    1766                 :            :         }
    1767                 :            : 
    1768                 :          0 :         unit_file_list_free(h);
    1769                 :            : 
    1770                 :          0 :         r = sd_bus_message_close_container(reply);
    1771         [ #  # ]:          0 :         if (r < 0)
    1772                 :          0 :                 return r;
    1773                 :            : 
    1774                 :          0 :         return sd_bus_send(NULL, reply, NULL);
    1775                 :            : 
    1776                 :          0 : fail:
    1777                 :          0 :         unit_file_list_free(h);
    1778                 :          0 :         return r;
    1779                 :            : }
    1780                 :            : 
    1781                 :          0 : static int method_list_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1782                 :          0 :         return list_unit_files_by_patterns(message, userdata, error, NULL, NULL);
    1783                 :            : }
    1784                 :            : 
    1785                 :          0 : static int method_list_unit_files_by_patterns(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1786                 :          0 :         _cleanup_strv_free_ char **states = NULL;
    1787                 :          0 :         _cleanup_strv_free_ char **patterns = NULL;
    1788                 :            :         int r;
    1789                 :            : 
    1790                 :          0 :         r = sd_bus_message_read_strv(message, &states);
    1791         [ #  # ]:          0 :         if (r < 0)
    1792                 :          0 :                 return r;
    1793                 :            : 
    1794                 :          0 :         r = sd_bus_message_read_strv(message, &patterns);
    1795         [ #  # ]:          0 :         if (r < 0)
    1796                 :          0 :                 return r;
    1797                 :            : 
    1798                 :          0 :         return list_unit_files_by_patterns(message, userdata, error, states, patterns);
    1799                 :            : }
    1800                 :            : 
    1801                 :          0 : static int method_get_unit_file_state(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1802                 :          0 :         Manager *m = userdata;
    1803                 :            :         const char *name;
    1804                 :            :         UnitFileState state;
    1805                 :            :         int r;
    1806                 :            : 
    1807         [ #  # ]:          0 :         assert(message);
    1808         [ #  # ]:          0 :         assert(m);
    1809                 :            : 
    1810                 :            :         /* Anyone can call this method */
    1811                 :            : 
    1812                 :          0 :         r = mac_selinux_access_check(message, "status", error);
    1813         [ #  # ]:          0 :         if (r < 0)
    1814                 :          0 :                 return r;
    1815                 :            : 
    1816                 :          0 :         r = sd_bus_message_read(message, "s", &name);
    1817         [ #  # ]:          0 :         if (r < 0)
    1818                 :          0 :                 return r;
    1819                 :            : 
    1820                 :          0 :         r = unit_file_get_state(m->unit_file_scope, NULL, name, &state);
    1821         [ #  # ]:          0 :         if (r < 0)
    1822                 :          0 :                 return r;
    1823                 :            : 
    1824                 :          0 :         return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
    1825                 :            : }
    1826                 :            : 
    1827                 :          0 : static int method_get_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    1828                 :          0 :         _cleanup_free_ char *default_target = NULL;
    1829                 :          0 :         Manager *m = userdata;
    1830                 :            :         int r;
    1831                 :            : 
    1832         [ #  # ]:          0 :         assert(message);
    1833         [ #  # ]:          0 :         assert(m);
    1834                 :            : 
    1835                 :            :         /* Anyone can call this method */
    1836                 :            : 
    1837                 :          0 :         r = mac_selinux_access_check(message, "status", error);
    1838         [ #  # ]:          0 :         if (r < 0)
    1839                 :          0 :                 return r;
    1840                 :            : 
    1841                 :          0 :         r = unit_file_get_default(m->unit_file_scope, NULL, &default_target);
    1842         [ #  # ]:          0 :         if (r < 0)
    1843                 :          0 :                 return r;
    1844                 :            : 
    1845                 :          0 :         return sd_bus_reply_method_return(message, "s", default_target);
    1846                 :            : }
    1847                 :            : 
    1848                 :          0 : static int send_unit_files_changed(sd_bus *bus, void *userdata) {
    1849                 :          0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
    1850                 :            :         int r;
    1851                 :            : 
    1852         [ #  # ]:          0 :         assert(bus);
    1853                 :            : 
    1854                 :          0 :         r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
    1855         [ #  # ]:          0 :         if (r < 0)
    1856                 :          0 :                 return r;
    1857                 :            : 
    1858                 :          0 :         return sd_bus_send(bus, message, NULL);
    1859                 :            : }
    1860                 :            : 
    1861                 :            : /* Create an error reply, using the error information from changes[]
    1862                 :            :  * if possible, and fall back to generating an error from error code c.
    1863                 :            :  * The error message only describes the first error.
    1864                 :            :  *
    1865                 :            :  * Coordinate with unit_file_dump_changes() in install.c.
    1866                 :            :  */
    1867                 :          0 : static int install_error(
    1868                 :            :                 sd_bus_error *error,
    1869                 :            :                 int c,
    1870                 :            :                 UnitFileChange *changes,
    1871                 :            :                 size_t n_changes) {
    1872                 :            : 
    1873                 :            :         size_t i;
    1874                 :            :         int r;
    1875                 :            : 
    1876         [ #  # ]:          0 :         for (i = 0; i < n_changes; i++)
    1877                 :            : 
    1878   [ #  #  #  #  :          0 :                 switch(changes[i].type) {
                #  #  # ]
    1879                 :            : 
    1880                 :          0 :                 case 0 ... INT_MAX:
    1881                 :          0 :                         continue;
    1882                 :            : 
    1883                 :          0 :                 case -EEXIST:
    1884         [ #  # ]:          0 :                         if (changes[i].source)
    1885                 :          0 :                                 r = sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS,
    1886                 :            :                                                       "File %s already exists and is a symlink to %s.",
    1887                 :          0 :                                                       changes[i].path, changes[i].source);
    1888                 :            :                         else
    1889                 :          0 :                                 r = sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS,
    1890                 :            :                                                       "File %s already exists.",
    1891                 :          0 :                                                       changes[i].path);
    1892                 :          0 :                         goto found;
    1893                 :            : 
    1894                 :          0 :                 case -ERFKILL:
    1895                 :          0 :                         r = sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED,
    1896                 :          0 :                                               "Unit file %s is masked.", changes[i].path);
    1897                 :          0 :                         goto found;
    1898                 :            : 
    1899                 :          0 :                 case -EADDRNOTAVAIL:
    1900                 :          0 :                         r = sd_bus_error_setf(error, BUS_ERROR_UNIT_GENERATED,
    1901                 :          0 :                                               "Unit %s is transient or generated.", changes[i].path);
    1902                 :          0 :                         goto found;
    1903                 :            : 
    1904                 :          0 :                 case -ELOOP:
    1905                 :          0 :                         r = sd_bus_error_setf(error, BUS_ERROR_UNIT_LINKED,
    1906                 :          0 :                                               "Refusing to operate on linked unit file %s", changes[i].path);
    1907                 :          0 :                         goto found;
    1908                 :            : 
    1909                 :          0 :                 case -ENOENT:
    1910                 :          0 :                         r = sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit file %s does not exist.", changes[i].path);
    1911                 :          0 :                         goto found;
    1912                 :            : 
    1913                 :          0 :                 default:
    1914                 :          0 :                         r = sd_bus_error_set_errnof(error, changes[i].type, "File %s: %m", changes[i].path);
    1915                 :          0 :                         goto found;
    1916                 :            :                 }
    1917                 :            : 
    1918         [ #  # ]:          0 :         r = c < 0 ? c : -EINVAL;
    1919                 :            : 
    1920                 :          0 :  found:
    1921                 :          0 :         unit_file_changes_free(changes, n_changes);
    1922                 :          0 :         return r;
    1923                 :            : }
    1924                 :            : 
    1925                 :          0 : static int reply_unit_file_changes_and_free(
    1926                 :            :                 Manager *m,
    1927                 :            :                 sd_bus_message *message,
    1928                 :            :                 int carries_install_info,
    1929                 :            :                 UnitFileChange *changes,
    1930                 :            :                 size_t n_changes,
    1931                 :            :                 sd_bus_error *error) {
    1932                 :            : 
    1933                 :          0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
    1934                 :          0 :         bool bad = false, good = false;
    1935                 :            :         size_t i;
    1936                 :            :         int r;
    1937                 :            : 
    1938         [ #  # ]:          0 :         if (unit_file_changes_have_modification(changes, n_changes)) {
    1939                 :          0 :                 r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
    1940         [ #  # ]:          0 :                 if (r < 0)
    1941         [ #  # ]:          0 :                         log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m");
    1942                 :            :         }
    1943                 :            : 
    1944                 :          0 :         r = sd_bus_message_new_method_return(message, &reply);
    1945         [ #  # ]:          0 :         if (r < 0)
    1946                 :          0 :                 goto fail;
    1947                 :            : 
    1948         [ #  # ]:          0 :         if (carries_install_info >= 0) {
    1949                 :          0 :                 r = sd_bus_message_append(reply, "b", carries_install_info);
    1950         [ #  # ]:          0 :                 if (r < 0)
    1951                 :          0 :                         goto fail;
    1952                 :            :         }
    1953                 :            : 
    1954                 :          0 :         r = sd_bus_message_open_container(reply, 'a', "(sss)");
    1955         [ #  # ]:          0 :         if (r < 0)
    1956                 :          0 :                 goto fail;
    1957                 :            : 
    1958         [ #  # ]:          0 :         for (i = 0; i < n_changes; i++) {
    1959                 :            : 
    1960         [ #  # ]:          0 :                 if (changes[i].type < 0) {
    1961                 :          0 :                         bad = true;
    1962                 :          0 :                         continue;
    1963                 :            :                 }
    1964                 :            : 
    1965                 :          0 :                 r = sd_bus_message_append(
    1966                 :            :                                 reply, "(sss)",
    1967                 :          0 :                                 unit_file_change_type_to_string(changes[i].type),
    1968                 :          0 :                                 changes[i].path,
    1969                 :          0 :                                 changes[i].source);
    1970         [ #  # ]:          0 :                 if (r < 0)
    1971                 :          0 :                         goto fail;
    1972                 :            : 
    1973                 :          0 :                 good = true;
    1974                 :            :         }
    1975                 :            : 
    1976                 :            :         /* If there was a failed change, and no successful change, then return the first failure as proper method call
    1977                 :            :          * error. */
    1978   [ #  #  #  # ]:          0 :         if (bad && !good)
    1979                 :          0 :                 return install_error(error, 0, changes, n_changes);
    1980                 :            : 
    1981                 :          0 :         r = sd_bus_message_close_container(reply);
    1982         [ #  # ]:          0 :         if (r < 0)
    1983                 :          0 :                 goto fail;
    1984                 :            : 
    1985                 :          0 :         unit_file_changes_free(changes, n_changes);
    1986                 :          0 :         return sd_bus_send(NULL, reply, NULL);
    1987                 :            : 
    1988                 :          0 : fail:
    1989                 :          0 :         unit_file_changes_free(changes, n_changes);
    1990                 :          0 :         return r;
    1991                 :            : }
    1992                 :            : 
    1993                 :          0 : static int method_enable_unit_files_generic(
    1994                 :            :                 sd_bus_message *message,
    1995                 :            :                 Manager *m,
    1996                 :            :                 int (*call)(UnitFileScope scope, UnitFileFlags flags, const char *root_dir, char *files[], UnitFileChange **changes, size_t *n_changes),
    1997                 :            :                 bool carries_install_info,
    1998                 :            :                 sd_bus_error *error) {
    1999                 :            : 
    2000                 :          0 :         _cleanup_strv_free_ char **l = NULL;
    2001                 :          0 :         UnitFileChange *changes = NULL;
    2002                 :          0 :         size_t n_changes = 0;
    2003                 :            :         UnitFileFlags flags;
    2004                 :            :         int runtime, force, r;
    2005                 :            : 
    2006         [ #  # ]:          0 :         assert(message);
    2007         [ #  # ]:          0 :         assert(m);
    2008                 :            : 
    2009                 :          0 :         r = sd_bus_message_read_strv(message, &l);
    2010         [ #  # ]:          0 :         if (r < 0)
    2011                 :          0 :                 return r;
    2012                 :            : 
    2013                 :          0 :         r = sd_bus_message_read(message, "bb", &runtime, &force);
    2014         [ #  # ]:          0 :         if (r < 0)
    2015                 :          0 :                 return r;
    2016                 :            : 
    2017                 :          0 :         flags = unit_file_bools_to_flags(runtime, force);
    2018                 :            : 
    2019                 :          0 :         r = bus_verify_manage_unit_files_async(m, message, error);
    2020         [ #  # ]:          0 :         if (r < 0)
    2021                 :          0 :                 return r;
    2022         [ #  # ]:          0 :         if (r == 0)
    2023                 :          0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    2024                 :            : 
    2025                 :          0 :         r = call(m->unit_file_scope, flags, NULL, l, &changes, &n_changes);
    2026         [ #  # ]:          0 :         if (r < 0)
    2027                 :          0 :                 return install_error(error, r, changes, n_changes);
    2028                 :            : 
    2029         [ #  # ]:          0 :         return reply_unit_file_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes, error);
    2030                 :            : }
    2031                 :            : 
    2032                 :          0 : static int method_enable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2033                 :          0 :         return method_enable_unit_files_generic(message, userdata, unit_file_enable, true, error);
    2034                 :            : }
    2035                 :            : 
    2036                 :          0 : static int method_reenable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2037                 :          0 :         return method_enable_unit_files_generic(message, userdata, unit_file_reenable, true, error);
    2038                 :            : }
    2039                 :            : 
    2040                 :          0 : static int method_link_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2041                 :          0 :         return method_enable_unit_files_generic(message, userdata, unit_file_link, false, error);
    2042                 :            : }
    2043                 :            : 
    2044                 :          0 : static int unit_file_preset_without_mode(UnitFileScope scope, UnitFileFlags flags, const char *root_dir, char **files, UnitFileChange **changes, size_t *n_changes) {
    2045                 :          0 :         return unit_file_preset(scope, flags, root_dir, files, UNIT_FILE_PRESET_FULL, changes, n_changes);
    2046                 :            : }
    2047                 :            : 
    2048                 :          0 : static int method_preset_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2049                 :          0 :         return method_enable_unit_files_generic(message, userdata, unit_file_preset_without_mode, true, error);
    2050                 :            : }
    2051                 :            : 
    2052                 :          0 : static int method_mask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2053                 :          0 :         return method_enable_unit_files_generic(message, userdata, unit_file_mask, false, error);
    2054                 :            : }
    2055                 :            : 
    2056                 :          0 : static int method_preset_unit_files_with_mode(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2057                 :            : 
    2058                 :          0 :         _cleanup_strv_free_ char **l = NULL;
    2059                 :          0 :         UnitFileChange *changes = NULL;
    2060                 :          0 :         size_t n_changes = 0;
    2061                 :          0 :         Manager *m = userdata;
    2062                 :            :         UnitFilePresetMode mm;
    2063                 :            :         int runtime, force, r;
    2064                 :            :         UnitFileFlags flags;
    2065                 :            :         const char *mode;
    2066                 :            : 
    2067         [ #  # ]:          0 :         assert(message);
    2068         [ #  # ]:          0 :         assert(m);
    2069                 :            : 
    2070                 :          0 :         r = sd_bus_message_read_strv(message, &l);
    2071         [ #  # ]:          0 :         if (r < 0)
    2072                 :          0 :                 return r;
    2073                 :            : 
    2074                 :          0 :         r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
    2075         [ #  # ]:          0 :         if (r < 0)
    2076                 :          0 :                 return r;
    2077                 :            : 
    2078                 :          0 :         flags = unit_file_bools_to_flags(runtime, force);
    2079                 :            : 
    2080         [ #  # ]:          0 :         if (isempty(mode))
    2081                 :          0 :                 mm = UNIT_FILE_PRESET_FULL;
    2082                 :            :         else {
    2083                 :          0 :                 mm = unit_file_preset_mode_from_string(mode);
    2084         [ #  # ]:          0 :                 if (mm < 0)
    2085                 :          0 :                         return -EINVAL;
    2086                 :            :         }
    2087                 :            : 
    2088                 :          0 :         r = bus_verify_manage_unit_files_async(m, message, error);
    2089         [ #  # ]:          0 :         if (r < 0)
    2090                 :          0 :                 return r;
    2091         [ #  # ]:          0 :         if (r == 0)
    2092                 :          0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    2093                 :            : 
    2094                 :          0 :         r = unit_file_preset(m->unit_file_scope, flags, NULL, l, mm, &changes, &n_changes);
    2095         [ #  # ]:          0 :         if (r < 0)
    2096                 :          0 :                 return install_error(error, r, changes, n_changes);
    2097                 :            : 
    2098                 :          0 :         return reply_unit_file_changes_and_free(m, message, r, changes, n_changes, error);
    2099                 :            : }
    2100                 :            : 
    2101                 :          0 : static int method_disable_unit_files_generic(
    2102                 :            :                 sd_bus_message *message,
    2103                 :            :                 Manager *m,
    2104                 :            :                 int (*call)(UnitFileScope scope, UnitFileFlags flags, const char *root_dir, char *files[], UnitFileChange **changes, size_t *n_changes),
    2105                 :            :                 sd_bus_error *error) {
    2106                 :            : 
    2107                 :          0 :         _cleanup_strv_free_ char **l = NULL;
    2108                 :          0 :         UnitFileChange *changes = NULL;
    2109                 :          0 :         size_t n_changes = 0;
    2110                 :            :         int r, runtime;
    2111                 :            : 
    2112         [ #  # ]:          0 :         assert(message);
    2113         [ #  # ]:          0 :         assert(m);
    2114                 :            : 
    2115                 :          0 :         r = sd_bus_message_read_strv(message, &l);
    2116         [ #  # ]:          0 :         if (r < 0)
    2117                 :          0 :                 return r;
    2118                 :            : 
    2119                 :          0 :         r = sd_bus_message_read(message, "b", &runtime);
    2120         [ #  # ]:          0 :         if (r < 0)
    2121                 :          0 :                 return r;
    2122                 :            : 
    2123                 :          0 :         r = bus_verify_manage_unit_files_async(m, message, error);
    2124         [ #  # ]:          0 :         if (r < 0)
    2125                 :          0 :                 return r;
    2126         [ #  # ]:          0 :         if (r == 0)
    2127                 :          0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    2128                 :            : 
    2129                 :          0 :         r = call(m->unit_file_scope, runtime ? UNIT_FILE_RUNTIME : 0, NULL, l, &changes, &n_changes);
    2130         [ #  # ]:          0 :         if (r < 0)
    2131                 :          0 :                 return install_error(error, r, changes, n_changes);
    2132                 :            : 
    2133                 :          0 :         return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error);
    2134                 :            : }
    2135                 :            : 
    2136                 :          0 : static int method_disable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2137                 :          0 :         return method_disable_unit_files_generic(message, userdata, unit_file_disable, error);
    2138                 :            : }
    2139                 :            : 
    2140                 :          0 : static int method_unmask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2141                 :          0 :         return method_disable_unit_files_generic(message, userdata, unit_file_unmask, error);
    2142                 :            : }
    2143                 :            : 
    2144                 :          0 : static int method_revert_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2145                 :          0 :         _cleanup_strv_free_ char **l = NULL;
    2146                 :          0 :         UnitFileChange *changes = NULL;
    2147                 :          0 :         size_t n_changes = 0;
    2148                 :          0 :         Manager *m = userdata;
    2149                 :            :         int r;
    2150                 :            : 
    2151         [ #  # ]:          0 :         assert(message);
    2152         [ #  # ]:          0 :         assert(m);
    2153                 :            : 
    2154                 :          0 :         r = sd_bus_message_read_strv(message, &l);
    2155         [ #  # ]:          0 :         if (r < 0)
    2156                 :          0 :                 return r;
    2157                 :            : 
    2158                 :          0 :         r = bus_verify_manage_unit_files_async(m, message, error);
    2159         [ #  # ]:          0 :         if (r < 0)
    2160                 :          0 :                 return r;
    2161         [ #  # ]:          0 :         if (r == 0)
    2162                 :          0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    2163                 :            : 
    2164                 :          0 :         r = unit_file_revert(m->unit_file_scope, NULL, l, &changes, &n_changes);
    2165         [ #  # ]:          0 :         if (r < 0)
    2166                 :          0 :                 return install_error(error, r, changes, n_changes);
    2167                 :            : 
    2168                 :          0 :         return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error);
    2169                 :            : }
    2170                 :            : 
    2171                 :          0 : static int method_set_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2172                 :          0 :         UnitFileChange *changes = NULL;
    2173                 :          0 :         size_t n_changes = 0;
    2174                 :          0 :         Manager *m = userdata;
    2175                 :            :         const char *name;
    2176                 :            :         int force, r;
    2177                 :            : 
    2178         [ #  # ]:          0 :         assert(message);
    2179         [ #  # ]:          0 :         assert(m);
    2180                 :            : 
    2181                 :          0 :         r = mac_selinux_access_check(message, "enable", error);
    2182         [ #  # ]:          0 :         if (r < 0)
    2183                 :          0 :                 return r;
    2184                 :            : 
    2185                 :          0 :         r = sd_bus_message_read(message, "sb", &name, &force);
    2186         [ #  # ]:          0 :         if (r < 0)
    2187                 :          0 :                 return r;
    2188                 :            : 
    2189                 :          0 :         r = bus_verify_manage_unit_files_async(m, message, error);
    2190         [ #  # ]:          0 :         if (r < 0)
    2191                 :          0 :                 return r;
    2192         [ #  # ]:          0 :         if (r == 0)
    2193                 :          0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    2194                 :            : 
    2195         [ #  # ]:          0 :         r = unit_file_set_default(m->unit_file_scope, force ? UNIT_FILE_FORCE : 0, NULL, name, &changes, &n_changes);
    2196         [ #  # ]:          0 :         if (r < 0)
    2197                 :          0 :                 return install_error(error, r, changes, n_changes);
    2198                 :            : 
    2199                 :          0 :         return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error);
    2200                 :            : }
    2201                 :            : 
    2202                 :          0 : static int method_preset_all_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2203                 :          0 :         UnitFileChange *changes = NULL;
    2204                 :          0 :         size_t n_changes = 0;
    2205                 :          0 :         Manager *m = userdata;
    2206                 :            :         UnitFilePresetMode mm;
    2207                 :            :         const char *mode;
    2208                 :            :         UnitFileFlags flags;
    2209                 :            :         int force, runtime, r;
    2210                 :            : 
    2211         [ #  # ]:          0 :         assert(message);
    2212         [ #  # ]:          0 :         assert(m);
    2213                 :            : 
    2214                 :          0 :         r = mac_selinux_access_check(message, "enable", error);
    2215         [ #  # ]:          0 :         if (r < 0)
    2216                 :          0 :                 return r;
    2217                 :            : 
    2218                 :          0 :         r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
    2219         [ #  # ]:          0 :         if (r < 0)
    2220                 :          0 :                 return r;
    2221                 :            : 
    2222                 :          0 :         flags = unit_file_bools_to_flags(runtime, force);
    2223                 :            : 
    2224         [ #  # ]:          0 :         if (isempty(mode))
    2225                 :          0 :                 mm = UNIT_FILE_PRESET_FULL;
    2226                 :            :         else {
    2227                 :          0 :                 mm = unit_file_preset_mode_from_string(mode);
    2228         [ #  # ]:          0 :                 if (mm < 0)
    2229                 :          0 :                         return -EINVAL;
    2230                 :            :         }
    2231                 :            : 
    2232                 :          0 :         r = bus_verify_manage_unit_files_async(m, message, error);
    2233         [ #  # ]:          0 :         if (r < 0)
    2234                 :          0 :                 return r;
    2235         [ #  # ]:          0 :         if (r == 0)
    2236                 :          0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    2237                 :            : 
    2238                 :          0 :         r = unit_file_preset_all(m->unit_file_scope, flags, NULL, mm, &changes, &n_changes);
    2239         [ #  # ]:          0 :         if (r < 0)
    2240                 :          0 :                 return install_error(error, r, changes, n_changes);
    2241                 :            : 
    2242                 :          0 :         return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error);
    2243                 :            : }
    2244                 :            : 
    2245                 :          0 : static int method_add_dependency_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2246                 :          0 :         _cleanup_strv_free_ char **l = NULL;
    2247                 :          0 :         Manager *m = userdata;
    2248                 :          0 :         UnitFileChange *changes = NULL;
    2249                 :          0 :         size_t n_changes = 0;
    2250                 :            :         int runtime, force, r;
    2251                 :            :         char *target, *type;
    2252                 :            :         UnitDependency dep;
    2253                 :            :         UnitFileFlags flags;
    2254                 :            : 
    2255         [ #  # ]:          0 :         assert(message);
    2256         [ #  # ]:          0 :         assert(m);
    2257                 :            : 
    2258                 :          0 :         r = bus_verify_manage_unit_files_async(m, message, error);
    2259         [ #  # ]:          0 :         if (r < 0)
    2260                 :          0 :                 return r;
    2261         [ #  # ]:          0 :         if (r == 0)
    2262                 :          0 :                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
    2263                 :            : 
    2264                 :          0 :         r = sd_bus_message_read_strv(message, &l);
    2265         [ #  # ]:          0 :         if (r < 0)
    2266                 :          0 :                 return r;
    2267                 :            : 
    2268                 :          0 :         r = sd_bus_message_read(message, "ssbb", &target, &type, &runtime, &force);
    2269         [ #  # ]:          0 :         if (r < 0)
    2270                 :          0 :                 return r;
    2271                 :            : 
    2272                 :          0 :         flags = unit_file_bools_to_flags(runtime, force);
    2273                 :            : 
    2274                 :          0 :         dep = unit_dependency_from_string(type);
    2275         [ #  # ]:          0 :         if (dep < 0)
    2276                 :          0 :                 return -EINVAL;
    2277                 :            : 
    2278                 :          0 :         r = unit_file_add_dependency(m->unit_file_scope, flags, NULL, l, target, dep, &changes, &n_changes);
    2279         [ #  # ]:          0 :         if (r < 0)
    2280                 :          0 :                 return install_error(error, r, changes, n_changes);
    2281                 :            : 
    2282                 :          0 :         return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes, error);
    2283                 :            : }
    2284                 :            : 
    2285                 :          0 : static int method_get_unit_file_links(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2286                 :          0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
    2287                 :          0 :         UnitFileChange *changes = NULL;
    2288                 :          0 :         size_t n_changes = 0, i;
    2289                 :            :         UnitFileFlags flags;
    2290                 :            :         const char *name;
    2291                 :            :         char **p;
    2292                 :            :         int runtime, r;
    2293                 :            : 
    2294                 :          0 :         r = sd_bus_message_read(message, "sb", &name, &runtime);
    2295         [ #  # ]:          0 :         if (r < 0)
    2296                 :          0 :                 return r;
    2297                 :            : 
    2298                 :          0 :         r = sd_bus_message_new_method_return(message, &reply);
    2299         [ #  # ]:          0 :         if (r < 0)
    2300                 :          0 :                 return r;
    2301                 :            : 
    2302                 :          0 :         r = sd_bus_message_open_container(reply, SD_BUS_TYPE_ARRAY, "s");
    2303         [ #  # ]:          0 :         if (r < 0)
    2304                 :          0 :                 return r;
    2305                 :            : 
    2306                 :          0 :         p = STRV_MAKE(name);
    2307                 :          0 :         flags = UNIT_FILE_DRY_RUN |
    2308         [ #  # ]:          0 :                 (runtime ? UNIT_FILE_RUNTIME : 0);
    2309                 :            : 
    2310                 :          0 :         r = unit_file_disable(UNIT_FILE_SYSTEM, flags, NULL, p, &changes, &n_changes);
    2311         [ #  # ]:          0 :         if (r < 0)
    2312         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to get file links for %s: %m", name);
    2313                 :            : 
    2314         [ #  # ]:          0 :         for (i = 0; i < n_changes; i++)
    2315         [ #  # ]:          0 :                 if (changes[i].type == UNIT_FILE_UNLINK) {
    2316                 :          0 :                         r = sd_bus_message_append(reply, "s", changes[i].path);
    2317         [ #  # ]:          0 :                         if (r < 0)
    2318                 :          0 :                                 return r;
    2319                 :            :                 }
    2320                 :            : 
    2321                 :          0 :         r = sd_bus_message_close_container(reply);
    2322         [ #  # ]:          0 :         if (r < 0)
    2323                 :          0 :                 return r;
    2324                 :            : 
    2325                 :          0 :         return sd_bus_send(NULL, reply, NULL);
    2326                 :            : }
    2327                 :            : 
    2328                 :          0 : static int method_get_job_waiting(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2329                 :          0 :         Manager *m = userdata;
    2330                 :            :         uint32_t id;
    2331                 :            :         Job *j;
    2332                 :            :         int r;
    2333                 :            : 
    2334         [ #  # ]:          0 :         assert(message);
    2335         [ #  # ]:          0 :         assert(m);
    2336                 :            : 
    2337                 :          0 :         r = sd_bus_message_read(message, "u", &id);
    2338         [ #  # ]:          0 :         if (r < 0)
    2339                 :          0 :                 return r;
    2340                 :            : 
    2341                 :          0 :         j = manager_get_job(m, id);
    2342         [ #  # ]:          0 :         if (!j)
    2343                 :          0 :                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
    2344                 :            : 
    2345                 :          0 :         return bus_job_method_get_waiting_jobs(message, j, error);
    2346                 :            : }
    2347                 :            : 
    2348                 :          0 : static int method_abandon_scope(sd_bus_message *message, void *userdata, sd_bus_error *error) {
    2349                 :          0 :         Manager *m = userdata;
    2350                 :            :         const char *name;
    2351                 :            :         Unit *u;
    2352                 :            :         int r;
    2353                 :            : 
    2354         [ #  # ]:          0 :         assert(message);
    2355         [ #  # ]:          0 :         assert(m);
    2356                 :            : 
    2357                 :          0 :         r = sd_bus_message_read(message, "s", &name);
    2358         [ #  # ]:          0 :         if (r < 0)
    2359                 :          0 :                 return r;
    2360                 :            : 
    2361                 :          0 :         r = bus_get_unit_by_name(m, message, name, &u, error);
    2362         [ #  # ]:          0 :         if (r < 0)
    2363                 :          0 :                 return r;
    2364                 :            : 
    2365         [ #  # ]:          0 :         if (u->type != UNIT_SCOPE)
    2366                 :          0 :                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit '%s' is not a scope unit, refusing.", name);
    2367                 :            : 
    2368                 :          0 :         return bus_scope_method_abandon(message, u, error);
    2369                 :            : }
    2370                 :            : 
    2371                 :            : const sd_bus_vtable bus_manager_vtable[] = {
    2372                 :            :         SD_BUS_VTABLE_START(0),
    2373                 :            : 
    2374                 :            :         SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
    2375                 :            :         SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
    2376                 :            :         SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
    2377                 :            :         SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
    2378                 :            :         SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
    2379                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_FIRMWARE]), SD_BUS_VTABLE_PROPERTY_CONST),
    2380                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_LOADER]), SD_BUS_VTABLE_PROPERTY_CONST),
    2381                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_KERNEL]), SD_BUS_VTABLE_PROPERTY_CONST),
    2382                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD]), SD_BUS_VTABLE_PROPERTY_CONST),
    2383                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_USERSPACE]), SD_BUS_VTABLE_PROPERTY_CONST),
    2384                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
    2385                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_SECURITY_START]), SD_BUS_VTABLE_PROPERTY_CONST),
    2386                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_SECURITY_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
    2387                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_GENERATORS_START]), SD_BUS_VTABLE_PROPERTY_CONST),
    2388                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_GENERATORS_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
    2389                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD_START]), SD_BUS_VTABLE_PROPERTY_CONST),
    2390                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
    2391                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("InitRDSecurityStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_SECURITY_START]), SD_BUS_VTABLE_PROPERTY_CONST),
    2392                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("InitRDSecurityFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_SECURITY_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
    2393                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("InitRDGeneratorsStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_GENERATORS_START]), SD_BUS_VTABLE_PROPERTY_CONST),
    2394                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("InitRDGeneratorsFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_GENERATORS_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
    2395                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("InitRDUnitsLoadStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_UNITS_LOAD_START]), SD_BUS_VTABLE_PROPERTY_CONST),
    2396                 :            :         BUS_PROPERTY_DUAL_TIMESTAMP("InitRDUnitsLoadFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD_UNITS_LOAD_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST),
    2397                 :            :         SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
    2398                 :            :         SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
    2399                 :            :         SD_BUS_PROPERTY("NNames", "u", property_get_hashmap_size, offsetof(Manager, units), 0),
    2400                 :            :         SD_BUS_PROPERTY("NFailedUnits", "u", property_get_set_size, offsetof(Manager, failed_units), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
    2401                 :            :         SD_BUS_PROPERTY("NJobs", "u", property_get_hashmap_size, offsetof(Manager, jobs), 0),
    2402                 :            :         SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
    2403                 :            :         SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
    2404                 :            :         SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
    2405                 :            :         SD_BUS_PROPERTY("Environment", "as", property_get_environment, 0, 0),
    2406                 :            :         SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
    2407                 :            :         SD_BUS_PROPERTY("ShowStatus", "b", property_get_show_status, 0, 0),
    2408                 :            :         SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.search_path), SD_BUS_VTABLE_PROPERTY_CONST),
    2409                 :            :         SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
    2410                 :            :         SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
    2411                 :            :         SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
    2412                 :            :         SD_BUS_WRITABLE_PROPERTY("RebootWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, reboot_watchdog), 0),
    2413                 :            :         /* The following item is an obsolete alias */
    2414                 :            :         SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, reboot_watchdog), SD_BUS_VTABLE_HIDDEN),
    2415                 :            :         SD_BUS_WRITABLE_PROPERTY("KExecWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, kexec_watchdog), 0),
    2416                 :            :         SD_BUS_WRITABLE_PROPERTY("ServiceWatchdogs", "b", bus_property_get_bool, bus_property_set_bool, offsetof(Manager, service_watchdogs), 0),
    2417                 :            :         SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
    2418                 :            :         SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
    2419                 :            :         SD_BUS_PROPERTY("ExitCode", "y", bus_property_get_unsigned, offsetof(Manager, return_value), 0),
    2420                 :            :         SD_BUS_PROPERTY("DefaultTimerAccuracyUSec", "t", bus_property_get_usec, offsetof(Manager, default_timer_accuracy_usec), SD_BUS_VTABLE_PROPERTY_CONST),
    2421                 :            :         SD_BUS_PROPERTY("DefaultTimeoutStartUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_start_usec), SD_BUS_VTABLE_PROPERTY_CONST),
    2422                 :            :         SD_BUS_PROPERTY("DefaultTimeoutStopUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
    2423                 :            :         SD_BUS_PROPERTY("DefaultTimeoutAbortUSec", "t", property_get_default_timeout_abort_usec, 0, 0),
    2424                 :            :         SD_BUS_PROPERTY("DefaultRestartUSec", "t", bus_property_get_usec, offsetof(Manager, default_restart_usec), SD_BUS_VTABLE_PROPERTY_CONST),
    2425                 :            :         SD_BUS_PROPERTY("DefaultStartLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST),
    2426                 :            :         /* The following two items are obsolete alias */
    2427                 :            :         SD_BUS_PROPERTY("DefaultStartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
    2428                 :            :         SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
    2429                 :            :         SD_BUS_PROPERTY("DefaultStartLimitBurst", "u", bus_property_get_unsigned, offsetof(Manager, default_start_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST),
    2430                 :            :         SD_BUS_PROPERTY("DefaultCPUAccounting", "b", bus_property_get_bool, offsetof(Manager, default_cpu_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
    2431                 :            :         SD_BUS_PROPERTY("DefaultBlockIOAccounting", "b", bus_property_get_bool, offsetof(Manager, default_blockio_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
    2432                 :            :         SD_BUS_PROPERTY("DefaultMemoryAccounting", "b", bus_property_get_bool, offsetof(Manager, default_memory_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
    2433                 :            :         SD_BUS_PROPERTY("DefaultTasksAccounting", "b", bus_property_get_bool, offsetof(Manager, default_tasks_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
    2434                 :            :         SD_BUS_PROPERTY("DefaultLimitCPU", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
    2435                 :            :         SD_BUS_PROPERTY("DefaultLimitCPUSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
    2436                 :            :         SD_BUS_PROPERTY("DefaultLimitFSIZE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
    2437                 :            :         SD_BUS_PROPERTY("DefaultLimitFSIZESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
    2438                 :            :         SD_BUS_PROPERTY("DefaultLimitDATA", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
    2439                 :            :         SD_BUS_PROPERTY("DefaultLimitDATASoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
    2440                 :            :         SD_BUS_PROPERTY("DefaultLimitSTACK", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
    2441                 :            :         SD_BUS_PROPERTY("DefaultLimitSTACKSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
    2442                 :            :         SD_BUS_PROPERTY("DefaultLimitCORE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
    2443                 :            :         SD_BUS_PROPERTY("DefaultLimitCORESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
    2444                 :            :         SD_BUS_PROPERTY("DefaultLimitRSS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
    2445                 :            :         SD_BUS_PROPERTY("DefaultLimitRSSSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
    2446                 :            :         SD_BUS_PROPERTY("DefaultLimitNOFILE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
    2447                 :            :         SD_BUS_PROPERTY("DefaultLimitNOFILESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
    2448                 :            :         SD_BUS_PROPERTY("DefaultLimitAS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
    2449                 :            :         SD_BUS_PROPERTY("DefaultLimitASSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
    2450                 :            :         SD_BUS_PROPERTY("DefaultLimitNPROC", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
    2451                 :            :         SD_BUS_PROPERTY("DefaultLimitNPROCSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
    2452                 :            :         SD_BUS_PROPERTY("DefaultLimitMEMLOCK", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
    2453                 :            :         SD_BUS_PROPERTY("DefaultLimitMEMLOCKSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
    2454                 :            :         SD_BUS_PROPERTY("DefaultLimitLOCKS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
    2455                 :            :         SD_BUS_PROPERTY("DefaultLimitLOCKSSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
    2456                 :            :         SD_BUS_PROPERTY("DefaultLimitSIGPENDING", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
    2457                 :            :         SD_BUS_PROPERTY("DefaultLimitSIGPENDINGSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
    2458                 :            :         SD_BUS_PROPERTY("DefaultLimitMSGQUEUE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
    2459                 :            :         SD_BUS_PROPERTY("DefaultLimitMSGQUEUESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
    2460                 :            :         SD_BUS_PROPERTY("DefaultLimitNICE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
    2461                 :            :         SD_BUS_PROPERTY("DefaultLimitNICESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
    2462                 :            :         SD_BUS_PROPERTY("DefaultLimitRTPRIO", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
    2463                 :            :         SD_BUS_PROPERTY("DefaultLimitRTPRIOSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
    2464                 :            :         SD_BUS_PROPERTY("DefaultLimitRTTIME", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
    2465                 :            :         SD_BUS_PROPERTY("DefaultLimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
    2466                 :            :         SD_BUS_PROPERTY("DefaultTasksMax", "t", NULL, offsetof(Manager, default_tasks_max), SD_BUS_VTABLE_PROPERTY_CONST),
    2467                 :            :         SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
    2468                 :            :         SD_BUS_PROPERTY("DefaultOOMPolicy", "s", bus_property_get_oom_policy, offsetof(Manager, default_oom_policy), SD_BUS_VTABLE_PROPERTY_CONST),
    2469                 :            : 
    2470                 :            :         SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    2471                 :            :         SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
    2472                 :            :         SD_BUS_METHOD("GetUnitByInvocationID", "ay", "o", method_get_unit_by_invocation_id, SD_BUS_VTABLE_UNPRIVILEGED),
    2473                 :            :         SD_BUS_METHOD("GetUnitByControlGroup", "s", "o", method_get_unit_by_control_group, SD_BUS_VTABLE_UNPRIVILEGED),
    2474                 :            :         SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    2475                 :            :         SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    2476                 :            :         SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, SD_BUS_VTABLE_UNPRIVILEGED),
    2477                 :            :         SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    2478                 :            :         SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    2479                 :            :         SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    2480                 :            :         SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    2481                 :            :         SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    2482                 :            :         SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    2483                 :            :         SD_BUS_METHOD("EnqueueUnitJob", "sss", "uososa(uosos)", method_enqueue_unit_job, SD_BUS_VTABLE_UNPRIVILEGED),
    2484                 :            :         SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    2485                 :            :         SD_BUS_METHOD("CleanUnit", "sas", NULL, method_clean_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    2486                 :            :         SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    2487                 :            :         SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, SD_BUS_VTABLE_UNPRIVILEGED),
    2488                 :            :         SD_BUS_METHOD("RefUnit", "s", NULL, method_ref_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    2489                 :            :         SD_BUS_METHOD("UnrefUnit", "s", NULL, method_unref_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    2490                 :            :         SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    2491                 :            :         SD_BUS_METHOD("GetUnitProcesses", "s", "a(sus)", method_get_unit_processes, SD_BUS_VTABLE_UNPRIVILEGED),
    2492                 :            :         SD_BUS_METHOD("AttachProcessesToUnit", "ssau", NULL, method_attach_processes_to_unit, SD_BUS_VTABLE_UNPRIVILEGED),
    2493                 :            :         SD_BUS_METHOD("AbandonScope", "s", NULL, method_abandon_scope, SD_BUS_VTABLE_UNPRIVILEGED),
    2494                 :            :         SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
    2495                 :            :         SD_BUS_METHOD("GetJobAfter", "u", "a(usssoo)", method_get_job_waiting, SD_BUS_VTABLE_UNPRIVILEGED),
    2496                 :            :         SD_BUS_METHOD("GetJobBefore", "u", "a(usssoo)", method_get_job_waiting, SD_BUS_VTABLE_UNPRIVILEGED),
    2497                 :            :         SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, SD_BUS_VTABLE_UNPRIVILEGED),
    2498                 :            :         SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
    2499                 :            :         SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, SD_BUS_VTABLE_UNPRIVILEGED),
    2500                 :            :         SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
    2501                 :            :         SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered, SD_BUS_VTABLE_UNPRIVILEGED),
    2502                 :            :         SD_BUS_METHOD("ListUnitsByPatterns", "asas", "a(ssssssouso)", method_list_units_by_patterns, SD_BUS_VTABLE_UNPRIVILEGED),
    2503                 :            :         SD_BUS_METHOD("ListUnitsByNames", "as", "a(ssssssouso)", method_list_units_by_names, SD_BUS_VTABLE_UNPRIVILEGED),
    2504                 :            :         SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
    2505                 :            :         SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
    2506                 :            :         SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
    2507                 :            :         SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
    2508                 :            :         SD_BUS_METHOD("DumpByFileDescriptor", NULL, "h", method_dump_by_fd, SD_BUS_VTABLE_UNPRIVILEGED),
    2509                 :            :         SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_refuse_snapshot, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_HIDDEN),
    2510                 :            :         SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_refuse_snapshot, SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_HIDDEN),
    2511                 :            :         SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
    2512                 :            :         SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, SD_BUS_VTABLE_UNPRIVILEGED),
    2513                 :            :         SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
    2514                 :            :         SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
    2515                 :            :         SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
    2516                 :            :         SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
    2517                 :            :         SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
    2518                 :            :         SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
    2519                 :            :         SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
    2520                 :            :         SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, SD_BUS_VTABLE_UNPRIVILEGED),
    2521                 :            :         SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
    2522                 :            :         SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2523                 :            :         SD_BUS_METHOD("ListUnitFilesByPatterns", "asas", "a(ss)", method_list_unit_files_by_patterns, SD_BUS_VTABLE_UNPRIVILEGED),
    2524                 :            :         SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
    2525                 :            :         SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2526                 :            :         SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2527                 :            :         SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2528                 :            :         SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2529                 :            :         SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2530                 :            :         SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, SD_BUS_VTABLE_UNPRIVILEGED),
    2531                 :            :         SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2532                 :            :         SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2533                 :            :         SD_BUS_METHOD("RevertUnitFiles", "as", "a(sss)", method_revert_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2534                 :            :         SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
    2535                 :            :         SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
    2536                 :            :         SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2537                 :            :         SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
    2538                 :            :         SD_BUS_METHOD("GetUnitFileLinks", "sb", "as", method_get_unit_file_links, SD_BUS_VTABLE_UNPRIVILEGED),
    2539                 :            :         SD_BUS_METHOD("SetExitCode", "y", NULL, method_set_exit_code, SD_BUS_VTABLE_UNPRIVILEGED),
    2540                 :            :         SD_BUS_METHOD("LookupDynamicUserByName", "s", "u", method_lookup_dynamic_user_by_name, SD_BUS_VTABLE_UNPRIVILEGED),
    2541                 :            :         SD_BUS_METHOD("LookupDynamicUserByUID", "u", "s", method_lookup_dynamic_user_by_uid, SD_BUS_VTABLE_UNPRIVILEGED),
    2542                 :            :         SD_BUS_METHOD("GetDynamicUsers", NULL, "a(us)", method_get_dynamic_users, SD_BUS_VTABLE_UNPRIVILEGED),
    2543                 :            : 
    2544                 :            :         SD_BUS_SIGNAL("UnitNew", "so", 0),
    2545                 :            :         SD_BUS_SIGNAL("UnitRemoved", "so", 0),
    2546                 :            :         SD_BUS_SIGNAL("JobNew", "uos", 0),
    2547                 :            :         SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
    2548                 :            :         SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
    2549                 :            :         SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
    2550                 :            :         SD_BUS_SIGNAL("Reloading", "b", 0),
    2551                 :            : 
    2552                 :            :         SD_BUS_VTABLE_END
    2553                 :            : };
    2554                 :            : 
    2555                 :          0 : static int send_finished(sd_bus *bus, void *userdata) {
    2556                 :          0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
    2557                 :          0 :         usec_t *times = userdata;
    2558                 :            :         int r;
    2559                 :            : 
    2560         [ #  # ]:          0 :         assert(bus);
    2561         [ #  # ]:          0 :         assert(times);
    2562                 :            : 
    2563                 :          0 :         r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
    2564         [ #  # ]:          0 :         if (r < 0)
    2565                 :          0 :                 return r;
    2566                 :            : 
    2567                 :          0 :         r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
    2568         [ #  # ]:          0 :         if (r < 0)
    2569                 :          0 :                 return r;
    2570                 :            : 
    2571                 :          0 :         return sd_bus_send(bus, message, NULL);
    2572                 :            : }
    2573                 :            : 
    2574                 :          0 : void bus_manager_send_finished(
    2575                 :            :                 Manager *m,
    2576                 :            :                 usec_t firmware_usec,
    2577                 :            :                 usec_t loader_usec,
    2578                 :            :                 usec_t kernel_usec,
    2579                 :            :                 usec_t initrd_usec,
    2580                 :            :                 usec_t userspace_usec,
    2581                 :            :                 usec_t total_usec) {
    2582                 :            : 
    2583                 :            :         int r;
    2584                 :            : 
    2585         [ #  # ]:          0 :         assert(m);
    2586                 :            : 
    2587                 :          0 :         r = bus_foreach_bus(
    2588                 :            :                         m,
    2589                 :            :                         NULL,
    2590                 :            :                         send_finished,
    2591                 :          0 :                         (usec_t[6]) {
    2592                 :            :                                 firmware_usec,
    2593                 :            :                                 loader_usec,
    2594                 :            :                                 kernel_usec,
    2595                 :            :                                 initrd_usec,
    2596                 :            :                                 userspace_usec,
    2597                 :            :                                 total_usec
    2598                 :            :                         });
    2599         [ #  # ]:          0 :         if (r < 0)
    2600         [ #  # ]:          0 :                 log_debug_errno(r, "Failed to send finished signal: %m");
    2601                 :          0 : }
    2602                 :            : 
    2603                 :          0 : static int send_reloading(sd_bus *bus, void *userdata) {
    2604                 :          0 :         _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
    2605                 :            :         int r;
    2606                 :            : 
    2607         [ #  # ]:          0 :         assert(bus);
    2608                 :            : 
    2609                 :          0 :         r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
    2610         [ #  # ]:          0 :         if (r < 0)
    2611                 :          0 :                 return r;
    2612                 :            : 
    2613                 :          0 :         r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
    2614         [ #  # ]:          0 :         if (r < 0)
    2615                 :          0 :                 return r;
    2616                 :            : 
    2617                 :          0 :         return sd_bus_send(bus, message, NULL);
    2618                 :            : }
    2619                 :            : 
    2620                 :          0 : void bus_manager_send_reloading(Manager *m, bool active) {
    2621                 :            :         int r;
    2622                 :            : 
    2623         [ #  # ]:          0 :         assert(m);
    2624                 :            : 
    2625                 :          0 :         r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
    2626         [ #  # ]:          0 :         if (r < 0)
    2627         [ #  # ]:          0 :                 log_debug_errno(r, "Failed to send reloading signal: %m");
    2628                 :          0 : }
    2629                 :            : 
    2630                 :          0 : static int send_changed_signal(sd_bus *bus, void *userdata) {
    2631         [ #  # ]:          0 :         assert(bus);
    2632                 :            : 
    2633                 :          0 :         return sd_bus_emit_properties_changed_strv(bus,
    2634                 :            :                                                    "/org/freedesktop/systemd1",
    2635                 :            :                                                    "org.freedesktop.systemd1.Manager",
    2636                 :            :                                                    NULL);
    2637                 :            : }
    2638                 :            : 
    2639                 :          0 : void bus_manager_send_change_signal(Manager *m) {
    2640                 :            :         int r;
    2641                 :            : 
    2642         [ #  # ]:          0 :         assert(m);
    2643                 :            : 
    2644                 :          0 :         r = bus_foreach_bus(m, NULL, send_changed_signal, NULL);
    2645         [ #  # ]:          0 :         if (r < 0)
    2646         [ #  # ]:          0 :                 log_debug_errno(r, "Failed to send manager change signal: %m");
    2647                 :          0 : }

Generated by: LCOV version 1.14