LCOV - code coverage report
Current view: top level - core - dbus-manager.c (source / functions) Hit Total Coverage
Test: main_coverage.info Lines: 0 1335 0.0 %
Date: 2019-08-22 15:41:25 Functions: 0 118 0.0 %

          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