1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include "sd-bus.h"
4 
5 #include "alloc-util.h"
6 #include "bpf-firewall.h"
7 #include "bus-common-errors.h"
8 #include "bus-get-properties.h"
9 #include "bus-polkit.h"
10 #include "cgroup-util.h"
11 #include "condition.h"
12 #include "dbus-job.h"
13 #include "dbus-manager.h"
14 #include "dbus-unit.h"
15 #include "dbus-util.h"
16 #include "dbus.h"
17 #include "fd-util.h"
18 #include "install.h"
19 #include "locale-util.h"
20 #include "log.h"
21 #include "path-util.h"
22 #include "process-util.h"
23 #include "selinux-access.h"
24 #include "signal-util.h"
25 #include "special.h"
26 #include "string-table.h"
27 #include "string-util.h"
28 #include "strv.h"
29 #include "user-util.h"
30 #include "web-util.h"
31 
unit_can_start_refuse_manual(Unit * u)32 static bool unit_can_start_refuse_manual(Unit *u) {
33         return unit_can_start(u) && !u->refuse_manual_start;
34 }
35 
unit_can_stop_refuse_manual(Unit * u)36 static bool unit_can_stop_refuse_manual(Unit *u) {
37         return unit_can_stop(u) && !u->refuse_manual_stop;
38 }
39 
unit_can_isolate_refuse_manual(Unit * u)40 static bool unit_can_isolate_refuse_manual(Unit *u) {
41         return unit_can_isolate(u) && !u->refuse_manual_start;
42 }
43 
44 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_collect_mode, collect_mode, CollectMode);
45 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_load_state, unit_load_state, UnitLoadState);
46 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_job_mode, job_mode, JobMode);
47 static BUS_DEFINE_PROPERTY_GET(property_get_description, "s", Unit, unit_description);
48 static BUS_DEFINE_PROPERTY_GET2(property_get_active_state, "s", Unit, unit_active_state, unit_active_state_to_string);
49 static BUS_DEFINE_PROPERTY_GET2(property_get_freezer_state, "s", Unit, unit_freezer_state, freezer_state_to_string);
50 static BUS_DEFINE_PROPERTY_GET(property_get_sub_state, "s", Unit, unit_sub_state_to_string);
51 static BUS_DEFINE_PROPERTY_GET2(property_get_unit_file_state, "s", Unit, unit_get_unit_file_state, unit_file_state_to_string);
52 static BUS_DEFINE_PROPERTY_GET(property_get_can_reload, "b", Unit, unit_can_reload);
53 static BUS_DEFINE_PROPERTY_GET(property_get_can_start, "b", Unit, unit_can_start_refuse_manual);
54 static BUS_DEFINE_PROPERTY_GET(property_get_can_stop, "b", Unit, unit_can_stop_refuse_manual);
55 static BUS_DEFINE_PROPERTY_GET(property_get_can_isolate, "b", Unit, unit_can_isolate_refuse_manual);
56 static BUS_DEFINE_PROPERTY_GET(property_get_can_freeze, "b", Unit, unit_can_freeze);
57 static BUS_DEFINE_PROPERTY_GET(property_get_need_daemon_reload, "b", Unit, unit_need_daemon_reload);
58 static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_strv, "as", 0);
59 
property_get_can_clean(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)60 static int property_get_can_clean(
61                 sd_bus *bus,
62                 const char *path,
63                 const char *interface,
64                 const char *property,
65                 sd_bus_message *reply,
66                 void *userdata,
67                 sd_bus_error *error) {
68 
69         Unit *u = userdata;
70         ExecCleanMask mask;
71         int r;
72 
73         assert(bus);
74         assert(reply);
75 
76         r = unit_can_clean(u, &mask);
77         if (r < 0)
78                 return r;
79 
80         r = sd_bus_message_open_container(reply, 'a', "s");
81         if (r < 0)
82                 return r;
83 
84         for (ExecDirectoryType t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++) {
85                 if (!FLAGS_SET(mask, 1U << t))
86                         continue;
87 
88                 r = sd_bus_message_append(reply, "s", exec_resource_type_to_string(t));
89                 if (r < 0)
90                         return r;
91         }
92 
93         return sd_bus_message_close_container(reply);
94 }
95 
property_get_names(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)96 static int property_get_names(
97                 sd_bus *bus,
98                 const char *path,
99                 const char *interface,
100                 const char *property,
101                 sd_bus_message *reply,
102                 void *userdata,
103                 sd_bus_error *error) {
104 
105         Unit *u = userdata;
106         const char *t;
107         int r;
108 
109         assert(bus);
110         assert(reply);
111         assert(u);
112 
113         r = sd_bus_message_open_container(reply, 'a', "s");
114         if (r < 0)
115                 return r;
116 
117         r = sd_bus_message_append(reply, "s", u->id);
118         if (r < 0)
119                 return r;
120 
121         SET_FOREACH(t, u->aliases) {
122                 r = sd_bus_message_append(reply, "s", t);
123                 if (r < 0)
124                         return r;
125         }
126 
127         return sd_bus_message_close_container(reply);
128 }
129 
property_get_following(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)130 static int property_get_following(
131                 sd_bus *bus,
132                 const char *path,
133                 const char *interface,
134                 const char *property,
135                 sd_bus_message *reply,
136                 void *userdata,
137                 sd_bus_error *error) {
138 
139         Unit *u = userdata, *f;
140 
141         assert(bus);
142         assert(reply);
143         assert(u);
144 
145         f = unit_following(u);
146         return sd_bus_message_append(reply, "s", f ? f->id : NULL);
147 }
148 
property_get_dependencies(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)149 static int property_get_dependencies(
150                 sd_bus *bus,
151                 const char *path,
152                 const char *interface,
153                 const char *property,
154                 sd_bus_message *reply,
155                 void *userdata,
156                 sd_bus_error *error) {
157 
158         Unit *u = userdata, *other;
159         UnitDependency d;
160         Hashmap *deps;
161         void *v;
162         int r;
163 
164         assert(bus);
165         assert(reply);
166         assert(u);
167 
168         d = unit_dependency_from_string(property);
169         assert_se(d >= 0);
170 
171         deps = unit_get_dependencies(u, d);
172 
173         r = sd_bus_message_open_container(reply, 'a', "s");
174         if (r < 0)
175                 return r;
176 
177         HASHMAP_FOREACH_KEY(v, other, deps) {
178                 r = sd_bus_message_append(reply, "s", other->id);
179                 if (r < 0)
180                         return r;
181         }
182 
183         return sd_bus_message_close_container(reply);
184 }
185 
property_get_requires_mounts_for(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)186 static int property_get_requires_mounts_for(
187                 sd_bus *bus,
188                 const char *path,
189                 const char *interface,
190                 const char *property,
191                 sd_bus_message *reply,
192                 void *userdata,
193                 sd_bus_error *error) {
194 
195         Hashmap **h = userdata;
196         const char *p;
197         void *v;
198         int r;
199 
200         assert(bus);
201         assert(reply);
202         assert(h);
203 
204         r = sd_bus_message_open_container(reply, 'a', "s");
205         if (r < 0)
206                 return r;
207 
208         HASHMAP_FOREACH_KEY(v, p, *h) {
209                 r = sd_bus_message_append(reply, "s", p);
210                 if (r < 0)
211                         return r;
212         }
213 
214         return sd_bus_message_close_container(reply);
215 }
216 
property_get_unit_file_preset(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)217 static int property_get_unit_file_preset(
218                 sd_bus *bus,
219                 const char *path,
220                 const char *interface,
221                 const char *property,
222                 sd_bus_message *reply,
223                 void *userdata,
224                 sd_bus_error *error) {
225 
226         Unit *u = userdata;
227         int r;
228 
229         assert(bus);
230         assert(reply);
231         assert(u);
232 
233         r = unit_get_unit_file_preset(u);
234 
235         return sd_bus_message_append(reply, "s",
236                                      r < 0 ? NULL:
237                                      r > 0 ? "enabled" : "disabled");
238 }
239 
property_get_job(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)240 static int property_get_job(
241                 sd_bus *bus,
242                 const char *path,
243                 const char *interface,
244                 const char *property,
245                 sd_bus_message *reply,
246                 void *userdata,
247                 sd_bus_error *error) {
248 
249         _cleanup_free_ char *p = NULL;
250         Job **j = userdata;
251 
252         assert(bus);
253         assert(reply);
254         assert(j);
255 
256         if (!*j)
257                 return sd_bus_message_append(reply, "(uo)", 0, "/");
258 
259         p = job_dbus_path(*j);
260         if (!p)
261                 return -ENOMEM;
262 
263         return sd_bus_message_append(reply, "(uo)", (*j)->id, p);
264 }
265 
property_get_conditions(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)266 static int property_get_conditions(
267                 sd_bus *bus,
268                 const char *path,
269                 const char *interface,
270                 const char *property,
271                 sd_bus_message *reply,
272                 void *userdata,
273                 sd_bus_error *error) {
274 
275         const char *(*to_string)(ConditionType type) = NULL;
276         Condition **list = userdata;
277         int r;
278 
279         assert(bus);
280         assert(reply);
281         assert(list);
282 
283         to_string = streq(property, "Asserts") ? assert_type_to_string : condition_type_to_string;
284 
285         r = sd_bus_message_open_container(reply, 'a', "(sbbsi)");
286         if (r < 0)
287                 return r;
288 
289         LIST_FOREACH(conditions, c, *list) {
290                 int tristate;
291 
292                 tristate =
293                         c->result == CONDITION_UNTESTED ? 0 :
294                         c->result == CONDITION_SUCCEEDED ? 1 : -1;
295 
296                 r = sd_bus_message_append(reply, "(sbbsi)",
297                                           to_string(c->type),
298                                           c->trigger, c->negate,
299                                           c->parameter, tristate);
300                 if (r < 0)
301                         return r;
302 
303         }
304 
305         return sd_bus_message_close_container(reply);
306 }
307 
property_get_load_error(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)308 static int property_get_load_error(
309                 sd_bus *bus,
310                 const char *path,
311                 const char *interface,
312                 const char *property,
313                 sd_bus_message *reply,
314                 void *userdata,
315                 sd_bus_error *error) {
316 
317         _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL;
318         Unit *u = userdata;
319         int r;
320 
321         assert(bus);
322         assert(reply);
323         assert(u);
324 
325         r = bus_unit_validate_load_state(u, &e);
326         if (r < 0)
327                 return sd_bus_message_append(reply, "(ss)", e.name, e.message);
328 
329         return sd_bus_message_append(reply, "(ss)", NULL, NULL);
330 }
331 
property_get_markers(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)332 static int property_get_markers(
333                 sd_bus *bus,
334                 const char *path,
335                 const char *interface,
336                 const char *property,
337                 sd_bus_message *reply,
338                 void *userdata,
339                 sd_bus_error *error) {
340 
341         unsigned *markers = userdata;
342         int r;
343 
344         assert(bus);
345         assert(reply);
346         assert(markers);
347 
348         r = sd_bus_message_open_container(reply, 'a', "s");
349         if (r < 0)
350                 return r;
351 
352         /* Make sure out values fit in the bitfield. */
353         assert_cc(_UNIT_MARKER_MAX <= sizeof(((Unit){}).markers) * 8);
354 
355         for (UnitMarker m = 0; m < _UNIT_MARKER_MAX; m++)
356                 if (FLAGS_SET(*markers, 1u << m)) {
357                         r = sd_bus_message_append(reply, "s", unit_marker_to_string(m));
358                         if (r < 0)
359                                 return r;
360                 }
361 
362         return sd_bus_message_close_container(reply);
363 }
364 
365 static const char *const polkit_message_for_job[_JOB_TYPE_MAX] = {
366         [JOB_START]       = N_("Authentication is required to start '$(unit)'."),
367         [JOB_STOP]        = N_("Authentication is required to stop '$(unit)'."),
368         [JOB_RELOAD]      = N_("Authentication is required to reload '$(unit)'."),
369         [JOB_RESTART]     = N_("Authentication is required to restart '$(unit)'."),
370         [JOB_TRY_RESTART] = N_("Authentication is required to restart '$(unit)'."),
371 };
372 
bus_unit_method_start_generic(sd_bus_message * message,Unit * u,JobType job_type,bool reload_if_possible,sd_bus_error * error)373 int bus_unit_method_start_generic(
374                 sd_bus_message *message,
375                 Unit *u,
376                 JobType job_type,
377                 bool reload_if_possible,
378                 sd_bus_error *error) {
379 
380         BusUnitQueueFlags job_flags = reload_if_possible ? BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE : 0;
381         const char *smode, *verb;
382         JobMode mode;
383         int r;
384 
385         assert(message);
386         assert(u);
387         assert(job_type >= 0 && job_type < _JOB_TYPE_MAX);
388 
389         r = mac_selinux_unit_access_check(
390                         u, message,
391                         job_type_to_access_method(job_type),
392                         error);
393         if (r < 0)
394                 return r;
395 
396         r = sd_bus_message_read(message, "s", &smode);
397         if (r < 0)
398                 return r;
399 
400         mode = job_mode_from_string(smode);
401         if (mode < 0)
402                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s invalid", smode);
403 
404         if (reload_if_possible)
405                 verb = strjoina("reload-or-", job_type_to_string(job_type));
406         else
407                 verb = job_type_to_string(job_type);
408 
409         if (sd_bus_message_is_method_call(message, NULL, "StartUnitWithFlags")) {
410                 uint64_t input_flags = 0;
411 
412                 r = sd_bus_message_read(message, "t", &input_flags);
413                 if (r < 0)
414                         return r;
415                 /* Let clients know that this version doesn't support any flags at the moment. */
416                 if (input_flags != 0)
417                         return sd_bus_reply_method_errorf(message, SD_BUS_ERROR_INVALID_ARGS,
418                                                           "Invalid 'flags' parameter '%" PRIu64 "'",
419                                                           input_flags);
420         }
421 
422         r = bus_verify_manage_units_async_full(
423                         u,
424                         verb,
425                         CAP_SYS_ADMIN,
426                         polkit_message_for_job[job_type],
427                         true,
428                         message,
429                         error);
430         if (r < 0)
431                 return r;
432         if (r == 0)
433                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
434 
435         return bus_unit_queue_job(message, u, job_type, mode, job_flags, error);
436 }
437 
bus_unit_method_start(sd_bus_message * message,void * userdata,sd_bus_error * error)438 static int bus_unit_method_start(sd_bus_message *message, void *userdata, sd_bus_error *error) {
439         return bus_unit_method_start_generic(message, userdata, JOB_START, false, error);
440 }
441 
bus_unit_method_stop(sd_bus_message * message,void * userdata,sd_bus_error * error)442 static int bus_unit_method_stop(sd_bus_message *message, void *userdata, sd_bus_error *error) {
443         return bus_unit_method_start_generic(message, userdata, JOB_STOP, false, error);
444 }
445 
bus_unit_method_reload(sd_bus_message * message,void * userdata,sd_bus_error * error)446 static int bus_unit_method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) {
447         return bus_unit_method_start_generic(message, userdata, JOB_RELOAD, false, error);
448 }
449 
bus_unit_method_restart(sd_bus_message * message,void * userdata,sd_bus_error * error)450 static int bus_unit_method_restart(sd_bus_message *message, void *userdata, sd_bus_error *error) {
451         return bus_unit_method_start_generic(message, userdata, JOB_RESTART, false, error);
452 }
453 
bus_unit_method_try_restart(sd_bus_message * message,void * userdata,sd_bus_error * error)454 static int bus_unit_method_try_restart(sd_bus_message *message, void *userdata, sd_bus_error *error) {
455         return bus_unit_method_start_generic(message, userdata, JOB_TRY_RESTART, false, error);
456 }
457 
bus_unit_method_reload_or_restart(sd_bus_message * message,void * userdata,sd_bus_error * error)458 static int bus_unit_method_reload_or_restart(sd_bus_message *message, void *userdata, sd_bus_error *error) {
459         return bus_unit_method_start_generic(message, userdata, JOB_RESTART, true, error);
460 }
461 
bus_unit_method_reload_or_try_restart(sd_bus_message * message,void * userdata,sd_bus_error * error)462 static int bus_unit_method_reload_or_try_restart(sd_bus_message *message, void *userdata, sd_bus_error *error) {
463         return bus_unit_method_start_generic(message, userdata, JOB_TRY_RESTART, true, error);
464 }
465 
bus_unit_method_enqueue_job(sd_bus_message * message,void * userdata,sd_bus_error * error)466 int bus_unit_method_enqueue_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
467         BusUnitQueueFlags flags = BUS_UNIT_QUEUE_VERBOSE_REPLY;
468         const char *jtype, *smode;
469         Unit *u = userdata;
470         JobType type;
471         JobMode mode;
472         int r;
473 
474         assert(message);
475         assert(u);
476 
477         r = sd_bus_message_read(message, "ss", &jtype, &smode);
478         if (r < 0)
479                 return r;
480 
481         /* Parse the two magic reload types "reload-or-…" manually */
482         if (streq(jtype, "reload-or-restart")) {
483                 type = JOB_RESTART;
484                 flags |= BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE;
485         } else if (streq(jtype, "reload-or-try-restart")) {
486                 type = JOB_TRY_RESTART;
487                 flags |= BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE;
488         } else {
489                 /* And the rest generically */
490                 type = job_type_from_string(jtype);
491                 if (type < 0)
492                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job type %s invalid", jtype);
493         }
494 
495         mode = job_mode_from_string(smode);
496         if (mode < 0)
497                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s invalid", smode);
498 
499         r = mac_selinux_unit_access_check(
500                         u, message,
501                         job_type_to_access_method(type),
502                         error);
503         if (r < 0)
504                 return r;
505 
506         r = bus_verify_manage_units_async_full(
507                         u,
508                         jtype,
509                         CAP_SYS_ADMIN,
510                         polkit_message_for_job[type],
511                         true,
512                         message,
513                         error);
514         if (r < 0)
515                 return r;
516         if (r == 0)
517                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
518 
519         return bus_unit_queue_job(message, u, type, mode, flags, error);
520 }
521 
bus_unit_method_kill(sd_bus_message * message,void * userdata,sd_bus_error * error)522 int bus_unit_method_kill(sd_bus_message *message, void *userdata, sd_bus_error *error) {
523         Unit *u = userdata;
524         const char *swho;
525         int32_t signo;
526         KillWho who;
527         int r;
528 
529         assert(message);
530         assert(u);
531 
532         r = mac_selinux_unit_access_check(u, message, "stop", error);
533         if (r < 0)
534                 return r;
535 
536         r = sd_bus_message_read(message, "si", &swho, &signo);
537         if (r < 0)
538                 return r;
539 
540         if (isempty(swho))
541                 who = KILL_ALL;
542         else {
543                 who = kill_who_from_string(swho);
544                 if (who < 0)
545                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid who argument %s", swho);
546         }
547 
548         if (!SIGNAL_VALID(signo))
549                 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Signal number out of range.");
550 
551         r = bus_verify_manage_units_async_full(
552                         u,
553                         "kill",
554                         CAP_KILL,
555                         N_("Authentication is required to send a UNIX signal to the processes of '$(unit)'."),
556                         true,
557                         message,
558                         error);
559         if (r < 0)
560                 return r;
561         if (r == 0)
562                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
563 
564         r = unit_kill(u, who, signo, error);
565         if (r < 0)
566                 return r;
567 
568         return sd_bus_reply_method_return(message, NULL);
569 }
570 
bus_unit_method_reset_failed(sd_bus_message * message,void * userdata,sd_bus_error * error)571 int bus_unit_method_reset_failed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
572         Unit *u = userdata;
573         int r;
574 
575         assert(message);
576         assert(u);
577 
578         r = mac_selinux_unit_access_check(u, message, "reload", error);
579         if (r < 0)
580                 return r;
581 
582         r = bus_verify_manage_units_async_full(
583                         u,
584                         "reset-failed",
585                         CAP_SYS_ADMIN,
586                         N_("Authentication is required to reset the \"failed\" state of '$(unit)'."),
587                         true,
588                         message,
589                         error);
590         if (r < 0)
591                 return r;
592         if (r == 0)
593                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
594 
595         unit_reset_failed(u);
596 
597         return sd_bus_reply_method_return(message, NULL);
598 }
599 
bus_unit_method_set_properties(sd_bus_message * message,void * userdata,sd_bus_error * error)600 int bus_unit_method_set_properties(sd_bus_message *message, void *userdata, sd_bus_error *error) {
601         Unit *u = userdata;
602         int runtime, r;
603 
604         assert(message);
605         assert(u);
606 
607         r = mac_selinux_unit_access_check(u, message, "start", error);
608         if (r < 0)
609                 return r;
610 
611         r = sd_bus_message_read(message, "b", &runtime);
612         if (r < 0)
613                 return r;
614 
615         r = bus_verify_manage_units_async_full(
616                         u,
617                         "set-property",
618                         CAP_SYS_ADMIN,
619                         N_("Authentication is required to set properties on '$(unit)'."),
620                         true,
621                         message,
622                         error);
623         if (r < 0)
624                 return r;
625         if (r == 0)
626                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
627 
628         r = bus_unit_set_properties(u, message, runtime ? UNIT_RUNTIME : UNIT_PERSISTENT, true, error);
629         if (r < 0)
630                 return r;
631 
632         return sd_bus_reply_method_return(message, NULL);
633 }
634 
bus_unit_method_ref(sd_bus_message * message,void * userdata,sd_bus_error * error)635 int bus_unit_method_ref(sd_bus_message *message, void *userdata, sd_bus_error *error) {
636         Unit *u = userdata;
637         int r;
638 
639         assert(message);
640         assert(u);
641 
642         r = mac_selinux_unit_access_check(u, message, "start", error);
643         if (r < 0)
644                 return r;
645 
646         r = bus_verify_manage_units_async_full(
647                         u,
648                         "ref",
649                         CAP_SYS_ADMIN,
650                         NULL,
651                         false,
652                         message,
653                         error);
654         if (r < 0)
655                 return r;
656         if (r == 0)
657                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
658 
659         r = bus_unit_track_add_sender(u, message);
660         if (r < 0)
661                 return r;
662 
663         return sd_bus_reply_method_return(message, NULL);
664 }
665 
bus_unit_method_unref(sd_bus_message * message,void * userdata,sd_bus_error * error)666 int bus_unit_method_unref(sd_bus_message *message, void *userdata, sd_bus_error *error) {
667         Unit *u = userdata;
668         int r;
669 
670         assert(message);
671         assert(u);
672 
673         r = bus_unit_track_remove_sender(u, message);
674         if (r == -EUNATCH)
675                 return sd_bus_error_set(error, BUS_ERROR_NOT_REFERENCED, "Unit has not been referenced yet.");
676         if (r < 0)
677                 return r;
678 
679         return sd_bus_reply_method_return(message, NULL);
680 }
681 
bus_unit_method_clean(sd_bus_message * message,void * userdata,sd_bus_error * error)682 int bus_unit_method_clean(sd_bus_message *message, void *userdata, sd_bus_error *error) {
683         ExecCleanMask mask = 0;
684         Unit *u = userdata;
685         int r;
686 
687         assert(message);
688         assert(u);
689 
690         r = mac_selinux_unit_access_check(u, message, "stop", error);
691         if (r < 0)
692                 return r;
693 
694         r = sd_bus_message_enter_container(message, 'a', "s");
695         if (r < 0)
696                 return r;
697 
698         for (;;) {
699                 const char *i;
700 
701                 r = sd_bus_message_read(message, "s", &i);
702                 if (r < 0)
703                         return r;
704                 if (r == 0)
705                         break;
706 
707                 if (streq(i, "all"))
708                         mask |= EXEC_CLEAN_ALL;
709                 else {
710                         ExecDirectoryType t;
711 
712                         t = exec_resource_type_from_string(i);
713                         if (t < 0)
714                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid resource type: %s", i);
715 
716                         mask |= 1U << t;
717                 }
718         }
719 
720         r = sd_bus_message_exit_container(message);
721         if (r < 0)
722                 return r;
723 
724         r = bus_verify_manage_units_async_full(
725                         u,
726                         "clean",
727                         CAP_DAC_OVERRIDE,
728                         N_("Authentication is required to delete files and directories associated with '$(unit)'."),
729                         true,
730                         message,
731                         error);
732         if (r < 0)
733                 return r;
734         if (r == 0)
735                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
736 
737         r = unit_clean(u, mask);
738         if (r == -EOPNOTSUPP)
739                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Unit '%s' does not support cleaning.", u->id);
740         if (r == -EUNATCH)
741                 return sd_bus_error_set(error, BUS_ERROR_NOTHING_TO_CLEAN, "No matching resources found.");
742         if (r == -EBUSY)
743                 return sd_bus_error_set(error, BUS_ERROR_UNIT_BUSY, "Unit is not inactive or has pending job.");
744         if (r < 0)
745                 return r;
746 
747         return sd_bus_reply_method_return(message, NULL);
748 }
749 
bus_unit_method_freezer_generic(sd_bus_message * message,void * userdata,sd_bus_error * error,FreezerAction action)750 static int bus_unit_method_freezer_generic(sd_bus_message *message, void *userdata, sd_bus_error *error, FreezerAction action) {
751         const char* perm;
752         int (*method)(Unit*);
753         Unit *u = userdata;
754         bool reply_no_delay = false;
755         int r;
756 
757         assert(message);
758         assert(u);
759         assert(IN_SET(action, FREEZER_FREEZE, FREEZER_THAW));
760 
761         if (action == FREEZER_FREEZE) {
762                 perm = "stop";
763                 method = unit_freeze;
764         } else {
765                 perm = "start";
766                 method = unit_thaw;
767         }
768 
769         r = mac_selinux_unit_access_check(u, message, perm, error);
770         if (r < 0)
771                 return r;
772 
773         r = bus_verify_manage_units_async_full(
774                         u,
775                         perm,
776                         CAP_SYS_ADMIN,
777                         N_("Authentication is required to freeze or thaw the processes of '$(unit)' unit."),
778                         true,
779                         message,
780                         error);
781         if (r < 0)
782                 return r;
783         if (r == 0)
784                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
785 
786         r = method(u);
787         if (r == -EOPNOTSUPP)
788                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Unit '%s' does not support freezing.", u->id);
789         if (r == -EBUSY)
790                 return sd_bus_error_set(error, BUS_ERROR_UNIT_BUSY, "Unit has a pending job.");
791         if (r == -EHOSTDOWN)
792                 return sd_bus_error_set(error, BUS_ERROR_UNIT_INACTIVE, "Unit is inactive.");
793         if (r == -EALREADY)
794                 return sd_bus_error_setf(error, SD_BUS_ERROR_FAILED, "Previously requested freezer operation for unit '%s' is still in progress.", u->id);
795         if (r < 0)
796                 return r;
797         if (r == 0)
798                 reply_no_delay = true;
799 
800         assert(!u->pending_freezer_message);
801 
802         r = sd_bus_message_new_method_return(message, &u->pending_freezer_message);
803         if (r < 0)
804                 return r;
805 
806         if (reply_no_delay) {
807                 r = bus_unit_send_pending_freezer_message(u);
808                 if (r < 0)
809                         return r;
810         }
811 
812         return 1;
813 }
814 
bus_unit_method_thaw(sd_bus_message * message,void * userdata,sd_bus_error * error)815 int bus_unit_method_thaw(sd_bus_message *message, void *userdata, sd_bus_error *error) {
816         return bus_unit_method_freezer_generic(message, userdata, error, FREEZER_THAW);
817 }
818 
bus_unit_method_freeze(sd_bus_message * message,void * userdata,sd_bus_error * error)819 int bus_unit_method_freeze(sd_bus_message *message, void *userdata, sd_bus_error *error) {
820         return bus_unit_method_freezer_generic(message, userdata, error, FREEZER_FREEZE);
821 }
822 
property_get_refs(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)823 static int property_get_refs(
824                 sd_bus *bus,
825                 const char *path,
826                 const char *interface,
827                 const char *property,
828                 sd_bus_message *reply,
829                 void *userdata,
830                 sd_bus_error *error) {
831 
832         Unit *u = userdata;
833         int r;
834 
835         assert(bus);
836         assert(reply);
837 
838         r = sd_bus_message_open_container(reply, 'a', "s");
839         if (r < 0)
840                 return r;
841 
842         for (const char *i = sd_bus_track_first(u->bus_track); i; i = sd_bus_track_next(u->bus_track)) {
843                 int c;
844 
845                 c = sd_bus_track_count_name(u->bus_track, i);
846                 if (c < 0)
847                         return c;
848 
849                 /* Add the item multiple times if the ref count for each is above 1 */
850                 for (int k = 0; k < c; k++) {
851                         r = sd_bus_message_append(reply, "s", i);
852                         if (r < 0)
853                                 return r;
854                 }
855         }
856 
857         return sd_bus_message_close_container(reply);
858 }
859 
860 const sd_bus_vtable bus_unit_vtable[] = {
861         SD_BUS_VTABLE_START(0),
862 
863         SD_BUS_PROPERTY("Id", "s", NULL, offsetof(Unit, id), SD_BUS_VTABLE_PROPERTY_CONST),
864         SD_BUS_PROPERTY("Names", "as", property_get_names, 0, SD_BUS_VTABLE_PROPERTY_CONST),
865         SD_BUS_PROPERTY("Following", "s", property_get_following, 0, 0),
866         SD_BUS_PROPERTY("Requires", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
867         SD_BUS_PROPERTY("Requisite", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
868         SD_BUS_PROPERTY("Wants", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
869         SD_BUS_PROPERTY("BindsTo", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
870         SD_BUS_PROPERTY("PartOf", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
871         SD_BUS_PROPERTY("Upholds", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
872         SD_BUS_PROPERTY("RequiredBy", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
873         SD_BUS_PROPERTY("RequisiteOf", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
874         SD_BUS_PROPERTY("WantedBy", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
875         SD_BUS_PROPERTY("BoundBy", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
876         SD_BUS_PROPERTY("UpheldBy", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
877         SD_BUS_PROPERTY("ConsistsOf", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
878         SD_BUS_PROPERTY("Conflicts", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
879         SD_BUS_PROPERTY("ConflictedBy", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
880         SD_BUS_PROPERTY("Before", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
881         SD_BUS_PROPERTY("After", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
882         SD_BUS_PROPERTY("OnSuccess", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
883         SD_BUS_PROPERTY("OnSuccessOf", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
884         SD_BUS_PROPERTY("OnFailure", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
885         SD_BUS_PROPERTY("OnFailureOf", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
886         SD_BUS_PROPERTY("Triggers", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
887         SD_BUS_PROPERTY("TriggeredBy", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
888         SD_BUS_PROPERTY("PropagatesReloadTo", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
889         SD_BUS_PROPERTY("ReloadPropagatedFrom", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
890         SD_BUS_PROPERTY("PropagatesStopTo", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
891         SD_BUS_PROPERTY("StopPropagatedFrom", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
892         SD_BUS_PROPERTY("JoinsNamespaceOf", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
893         SD_BUS_PROPERTY("SliceOf", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
894         SD_BUS_PROPERTY("RequiresMountsFor", "as", property_get_requires_mounts_for, offsetof(Unit, requires_mounts_for), SD_BUS_VTABLE_PROPERTY_CONST),
895         SD_BUS_PROPERTY("Documentation", "as", NULL, offsetof(Unit, documentation), SD_BUS_VTABLE_PROPERTY_CONST),
896         SD_BUS_PROPERTY("Description", "s", property_get_description, 0, SD_BUS_VTABLE_PROPERTY_CONST),
897         SD_BUS_PROPERTY("LoadState", "s", property_get_load_state, offsetof(Unit, load_state), SD_BUS_VTABLE_PROPERTY_CONST),
898         SD_BUS_PROPERTY("ActiveState", "s", property_get_active_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
899         SD_BUS_PROPERTY("FreezerState", "s", property_get_freezer_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
900         SD_BUS_PROPERTY("SubState", "s", property_get_sub_state, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
901         SD_BUS_PROPERTY("FragmentPath", "s", NULL, offsetof(Unit, fragment_path), SD_BUS_VTABLE_PROPERTY_CONST),
902         SD_BUS_PROPERTY("SourcePath", "s", NULL, offsetof(Unit, source_path), SD_BUS_VTABLE_PROPERTY_CONST),
903         SD_BUS_PROPERTY("DropInPaths", "as", NULL, offsetof(Unit, dropin_paths), SD_BUS_VTABLE_PROPERTY_CONST),
904         SD_BUS_PROPERTY("UnitFileState", "s", property_get_unit_file_state, 0, 0),
905         SD_BUS_PROPERTY("UnitFilePreset", "s", property_get_unit_file_preset, 0, 0),
906         BUS_PROPERTY_DUAL_TIMESTAMP("StateChangeTimestamp", offsetof(Unit, state_change_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
907         BUS_PROPERTY_DUAL_TIMESTAMP("InactiveExitTimestamp", offsetof(Unit, inactive_exit_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
908         BUS_PROPERTY_DUAL_TIMESTAMP("ActiveEnterTimestamp", offsetof(Unit, active_enter_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
909         BUS_PROPERTY_DUAL_TIMESTAMP("ActiveExitTimestamp", offsetof(Unit, active_exit_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
910         BUS_PROPERTY_DUAL_TIMESTAMP("InactiveEnterTimestamp", offsetof(Unit, inactive_enter_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
911         SD_BUS_PROPERTY("CanStart", "b", property_get_can_start, 0, SD_BUS_VTABLE_PROPERTY_CONST),
912         SD_BUS_PROPERTY("CanStop", "b", property_get_can_stop, 0, SD_BUS_VTABLE_PROPERTY_CONST),
913         SD_BUS_PROPERTY("CanReload", "b", property_get_can_reload, 0, SD_BUS_VTABLE_PROPERTY_CONST),
914         SD_BUS_PROPERTY("CanIsolate", "b", property_get_can_isolate, 0, SD_BUS_VTABLE_PROPERTY_CONST),
915         SD_BUS_PROPERTY("CanClean", "as", property_get_can_clean, 0, SD_BUS_VTABLE_PROPERTY_CONST),
916         SD_BUS_PROPERTY("CanFreeze", "b", property_get_can_freeze, 0, SD_BUS_VTABLE_PROPERTY_CONST),
917         SD_BUS_PROPERTY("Job", "(uo)", property_get_job, offsetof(Unit, job), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
918         SD_BUS_PROPERTY("StopWhenUnneeded", "b", bus_property_get_bool, offsetof(Unit, stop_when_unneeded), SD_BUS_VTABLE_PROPERTY_CONST),
919         SD_BUS_PROPERTY("RefuseManualStart", "b", bus_property_get_bool, offsetof(Unit, refuse_manual_start), SD_BUS_VTABLE_PROPERTY_CONST),
920         SD_BUS_PROPERTY("RefuseManualStop", "b", bus_property_get_bool, offsetof(Unit, refuse_manual_stop), SD_BUS_VTABLE_PROPERTY_CONST),
921         SD_BUS_PROPERTY("AllowIsolate", "b", bus_property_get_bool, offsetof(Unit, allow_isolate), SD_BUS_VTABLE_PROPERTY_CONST),
922         SD_BUS_PROPERTY("DefaultDependencies", "b", bus_property_get_bool, offsetof(Unit, default_dependencies), SD_BUS_VTABLE_PROPERTY_CONST),
923         SD_BUS_PROPERTY("OnSuccesJobMode", "s", property_get_job_mode, offsetof(Unit, on_success_job_mode), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN), /* deprecated */
924         SD_BUS_PROPERTY("OnSuccessJobMode", "s", property_get_job_mode, offsetof(Unit, on_success_job_mode), SD_BUS_VTABLE_PROPERTY_CONST),
925         SD_BUS_PROPERTY("OnFailureJobMode", "s", property_get_job_mode, offsetof(Unit, on_failure_job_mode), SD_BUS_VTABLE_PROPERTY_CONST),
926         SD_BUS_PROPERTY("IgnoreOnIsolate", "b", bus_property_get_bool, offsetof(Unit, ignore_on_isolate), SD_BUS_VTABLE_PROPERTY_CONST),
927         SD_BUS_PROPERTY("NeedDaemonReload", "b", property_get_need_daemon_reload, 0, 0),
928         SD_BUS_PROPERTY("Markers", "as", property_get_markers, offsetof(Unit, markers), 0),
929         SD_BUS_PROPERTY("JobTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_timeout), SD_BUS_VTABLE_PROPERTY_CONST),
930         SD_BUS_PROPERTY("JobRunningTimeoutUSec", "t", bus_property_get_usec, offsetof(Unit, job_running_timeout), SD_BUS_VTABLE_PROPERTY_CONST),
931         SD_BUS_PROPERTY("JobTimeoutAction", "s", bus_property_get_emergency_action, offsetof(Unit, job_timeout_action), SD_BUS_VTABLE_PROPERTY_CONST),
932         SD_BUS_PROPERTY("JobTimeoutRebootArgument", "s", NULL, offsetof(Unit, job_timeout_reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
933         SD_BUS_PROPERTY("ConditionResult", "b", bus_property_get_bool, offsetof(Unit, condition_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
934         SD_BUS_PROPERTY("AssertResult", "b", bus_property_get_bool, offsetof(Unit, assert_result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
935         BUS_PROPERTY_DUAL_TIMESTAMP("ConditionTimestamp", offsetof(Unit, condition_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
936         BUS_PROPERTY_DUAL_TIMESTAMP("AssertTimestamp", offsetof(Unit, assert_timestamp), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
937         SD_BUS_PROPERTY("Conditions", "a(sbbsi)", property_get_conditions, offsetof(Unit, conditions), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
938         SD_BUS_PROPERTY("Asserts", "a(sbbsi)", property_get_conditions, offsetof(Unit, asserts), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
939         SD_BUS_PROPERTY("LoadError", "(ss)", property_get_load_error, 0, SD_BUS_VTABLE_PROPERTY_CONST),
940         SD_BUS_PROPERTY("Transient", "b", bus_property_get_bool, offsetof(Unit, transient), SD_BUS_VTABLE_PROPERTY_CONST),
941         SD_BUS_PROPERTY("Perpetual", "b", bus_property_get_bool, offsetof(Unit, perpetual), SD_BUS_VTABLE_PROPERTY_CONST),
942         SD_BUS_PROPERTY("StartLimitIntervalUSec", "t", bus_property_get_usec, offsetof(Unit, start_ratelimit.interval), SD_BUS_VTABLE_PROPERTY_CONST),
943         SD_BUS_PROPERTY("StartLimitBurst", "u", bus_property_get_unsigned, offsetof(Unit, start_ratelimit.burst), SD_BUS_VTABLE_PROPERTY_CONST),
944         SD_BUS_PROPERTY("StartLimitAction", "s", bus_property_get_emergency_action, offsetof(Unit, start_limit_action), SD_BUS_VTABLE_PROPERTY_CONST),
945         SD_BUS_PROPERTY("FailureAction", "s", bus_property_get_emergency_action, offsetof(Unit, failure_action), SD_BUS_VTABLE_PROPERTY_CONST),
946         SD_BUS_PROPERTY("FailureActionExitStatus", "i", bus_property_get_int, offsetof(Unit, failure_action_exit_status), SD_BUS_VTABLE_PROPERTY_CONST),
947         SD_BUS_PROPERTY("SuccessAction", "s", bus_property_get_emergency_action, offsetof(Unit, success_action), SD_BUS_VTABLE_PROPERTY_CONST),
948         SD_BUS_PROPERTY("SuccessActionExitStatus", "i", bus_property_get_int, offsetof(Unit, success_action_exit_status), SD_BUS_VTABLE_PROPERTY_CONST),
949         SD_BUS_PROPERTY("RebootArgument", "s", NULL, offsetof(Unit, reboot_arg), SD_BUS_VTABLE_PROPERTY_CONST),
950         SD_BUS_PROPERTY("InvocationID", "ay", bus_property_get_id128, offsetof(Unit, invocation_id), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
951         SD_BUS_PROPERTY("CollectMode", "s", property_get_collect_mode, offsetof(Unit, collect_mode), SD_BUS_VTABLE_PROPERTY_CONST),
952         SD_BUS_PROPERTY("Refs", "as", property_get_refs, 0, 0),
953 
954         SD_BUS_METHOD_WITH_ARGS("Start",
955                                 SD_BUS_ARGS("s", mode),
956                                 SD_BUS_RESULT("o", job),
957                                 bus_unit_method_start,
958                                 SD_BUS_VTABLE_UNPRIVILEGED),
959         SD_BUS_METHOD_WITH_ARGS("Stop",
960                                 SD_BUS_ARGS("s", mode),
961                                 SD_BUS_RESULT("o", job),
962                                 bus_unit_method_stop,
963                                 SD_BUS_VTABLE_UNPRIVILEGED),
964         SD_BUS_METHOD_WITH_ARGS("Reload",
965                                 SD_BUS_ARGS("s", mode),
966                                 SD_BUS_RESULT("o", job),
967                                 bus_unit_method_reload,
968                                 SD_BUS_VTABLE_UNPRIVILEGED),
969         SD_BUS_METHOD_WITH_ARGS("Restart",
970                                 SD_BUS_ARGS("s", mode),
971                                 SD_BUS_RESULT("o", job),
972                                 bus_unit_method_restart,
973                                 SD_BUS_VTABLE_UNPRIVILEGED),
974         SD_BUS_METHOD_WITH_ARGS("TryRestart",
975                                 SD_BUS_ARGS("s", mode),
976                                 SD_BUS_RESULT("o", job),
977                                 bus_unit_method_try_restart,
978                                 SD_BUS_VTABLE_UNPRIVILEGED),
979         SD_BUS_METHOD_WITH_ARGS("ReloadOrRestart",
980                                 SD_BUS_ARGS("s", mode),
981                                 SD_BUS_RESULT("o", job),
982                                 bus_unit_method_reload_or_restart,
983                                 SD_BUS_VTABLE_UNPRIVILEGED),
984         SD_BUS_METHOD_WITH_ARGS("ReloadOrTryRestart",
985                                 SD_BUS_ARGS("s", mode),
986                                 SD_BUS_RESULT("o", job),
987                                 bus_unit_method_reload_or_try_restart,
988                                 SD_BUS_VTABLE_UNPRIVILEGED),
989         SD_BUS_METHOD_WITH_ARGS("EnqueueJob",
990                                 SD_BUS_ARGS("s", job_type, "s", job_mode),
991                                 SD_BUS_RESULT("u", job_id, "o", job_path, "s", unit_id, "o", unit_path, "s", job_type, "a(uosos)", affected_jobs),
992                                 bus_unit_method_enqueue_job,
993                                 SD_BUS_VTABLE_UNPRIVILEGED),
994         SD_BUS_METHOD_WITH_ARGS("Kill",
995                                 SD_BUS_ARGS("s", whom, "i", signal),
996                                 SD_BUS_NO_RESULT,
997                                 bus_unit_method_kill,
998                                 SD_BUS_VTABLE_UNPRIVILEGED),
999         SD_BUS_METHOD("ResetFailed",
1000                       NULL,
1001                       NULL,
1002                       bus_unit_method_reset_failed,
1003                       SD_BUS_VTABLE_UNPRIVILEGED),
1004         SD_BUS_METHOD_WITH_ARGS("SetProperties",
1005                                 SD_BUS_ARGS("b", runtime, "a(sv)", properties),
1006                                 SD_BUS_NO_RESULT,
1007                                 bus_unit_method_set_properties,
1008                                 SD_BUS_VTABLE_UNPRIVILEGED),
1009         SD_BUS_METHOD("Ref",
1010                       NULL,
1011                       NULL,
1012                       bus_unit_method_ref,
1013                       SD_BUS_VTABLE_UNPRIVILEGED),
1014         SD_BUS_METHOD("Unref",
1015                       NULL,
1016                       NULL,
1017                       bus_unit_method_unref,
1018                       SD_BUS_VTABLE_UNPRIVILEGED),
1019         SD_BUS_METHOD_WITH_ARGS("Clean",
1020                                 SD_BUS_ARGS("as", mask),
1021                                 SD_BUS_NO_RESULT,
1022                                 bus_unit_method_clean,
1023                                 SD_BUS_VTABLE_UNPRIVILEGED),
1024         SD_BUS_METHOD("Freeze",
1025                       NULL,
1026                       NULL,
1027                       bus_unit_method_freeze,
1028                       SD_BUS_VTABLE_UNPRIVILEGED),
1029         SD_BUS_METHOD("Thaw",
1030                       NULL,
1031                       NULL,
1032                       bus_unit_method_thaw,
1033                       SD_BUS_VTABLE_UNPRIVILEGED),
1034 
1035         /* For dependency types we don't support anymore always return an empty array */
1036         SD_BUS_PROPERTY("RequiresOverridable", "as", property_get_empty_strv, 0, SD_BUS_VTABLE_HIDDEN),
1037         SD_BUS_PROPERTY("RequisiteOverridable", "as", property_get_empty_strv, 0, SD_BUS_VTABLE_HIDDEN),
1038         SD_BUS_PROPERTY("RequiredByOverridable", "as", property_get_empty_strv, 0, SD_BUS_VTABLE_HIDDEN),
1039         SD_BUS_PROPERTY("RequisiteOfOverridable", "as", property_get_empty_strv, 0, SD_BUS_VTABLE_HIDDEN),
1040         /* Obsolete alias names */
1041         SD_BUS_PROPERTY("StartLimitInterval", "t", bus_property_get_usec, offsetof(Unit, start_ratelimit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
1042         SD_BUS_PROPERTY("StartLimitIntervalSec", "t", bus_property_get_usec, offsetof(Unit, start_ratelimit.interval), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
1043 
1044         SD_BUS_VTABLE_END
1045 };
1046 
property_get_slice(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)1047 static int property_get_slice(
1048                 sd_bus *bus,
1049                 const char *path,
1050                 const char *interface,
1051                 const char *property,
1052                 sd_bus_message *reply,
1053                 void *userdata,
1054                 sd_bus_error *error) {
1055 
1056         Unit *u = userdata;
1057 
1058         assert(bus);
1059         assert(reply);
1060         assert(u);
1061 
1062         return sd_bus_message_append(reply, "s", unit_slice_name(u));
1063 }
1064 
property_get_current_memory(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)1065 static int property_get_current_memory(
1066                 sd_bus *bus,
1067                 const char *path,
1068                 const char *interface,
1069                 const char *property,
1070                 sd_bus_message *reply,
1071                 void *userdata,
1072                 sd_bus_error *error) {
1073 
1074         uint64_t sz = UINT64_MAX;
1075         Unit *u = userdata;
1076         int r;
1077 
1078         assert(bus);
1079         assert(reply);
1080         assert(u);
1081 
1082         r = unit_get_memory_current(u, &sz);
1083         if (r < 0 && r != -ENODATA)
1084                 log_unit_warning_errno(u, r, "Failed to get memory.usage_in_bytes attribute: %m");
1085 
1086         return sd_bus_message_append(reply, "t", sz);
1087 }
1088 
property_get_available_memory(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)1089 static int property_get_available_memory(
1090                 sd_bus *bus,
1091                 const char *path,
1092                 const char *interface,
1093                 const char *property,
1094                 sd_bus_message *reply,
1095                 void *userdata,
1096                 sd_bus_error *error) {
1097 
1098         uint64_t sz = UINT64_MAX;
1099         Unit *u = userdata;
1100         int r;
1101 
1102         assert(bus);
1103         assert(reply);
1104         assert(u);
1105 
1106         r = unit_get_memory_available(u, &sz);
1107         if (r < 0 && r != -ENODATA)
1108                 log_unit_warning_errno(u, r, "Failed to get total available memory from cgroup: %m");
1109 
1110         return sd_bus_message_append(reply, "t", sz);
1111 }
1112 
property_get_current_tasks(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)1113 static int property_get_current_tasks(
1114                 sd_bus *bus,
1115                 const char *path,
1116                 const char *interface,
1117                 const char *property,
1118                 sd_bus_message *reply,
1119                 void *userdata,
1120                 sd_bus_error *error) {
1121 
1122         uint64_t cn = UINT64_MAX;
1123         Unit *u = userdata;
1124         int r;
1125 
1126         assert(bus);
1127         assert(reply);
1128         assert(u);
1129 
1130         r = unit_get_tasks_current(u, &cn);
1131         if (r < 0 && r != -ENODATA)
1132                 log_unit_warning_errno(u, r, "Failed to get pids.current attribute: %m");
1133 
1134         return sd_bus_message_append(reply, "t", cn);
1135 }
1136 
property_get_cpu_usage(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)1137 static int property_get_cpu_usage(
1138                 sd_bus *bus,
1139                 const char *path,
1140                 const char *interface,
1141                 const char *property,
1142                 sd_bus_message *reply,
1143                 void *userdata,
1144                 sd_bus_error *error) {
1145 
1146         nsec_t ns = NSEC_INFINITY;
1147         Unit *u = userdata;
1148         int r;
1149 
1150         assert(bus);
1151         assert(reply);
1152         assert(u);
1153 
1154         r = unit_get_cpu_usage(u, &ns);
1155         if (r < 0 && r != -ENODATA)
1156                 log_unit_warning_errno(u, r, "Failed to get cpuacct.usage attribute: %m");
1157 
1158         return sd_bus_message_append(reply, "t", ns);
1159 }
1160 
property_get_cpuset_cpus(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)1161 static int property_get_cpuset_cpus(
1162                 sd_bus *bus,
1163                 const char *path,
1164                 const char *interface,
1165                 const char *property,
1166                 sd_bus_message *reply,
1167                 void *userdata,
1168                 sd_bus_error *error) {
1169 
1170         Unit *u = userdata;
1171         _cleanup_(cpu_set_reset) CPUSet cpus = {};
1172         _cleanup_free_ uint8_t *array = NULL;
1173         size_t allocated;
1174 
1175         assert(bus);
1176         assert(reply);
1177         assert(u);
1178 
1179         (void) unit_get_cpuset(u, &cpus, "cpuset.cpus.effective");
1180         (void) cpu_set_to_dbus(&cpus, &array, &allocated);
1181         return sd_bus_message_append_array(reply, 'y', array, allocated);
1182 }
1183 
property_get_cpuset_mems(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)1184 static int property_get_cpuset_mems(
1185                 sd_bus *bus,
1186                 const char *path,
1187                 const char *interface,
1188                 const char *property,
1189                 sd_bus_message *reply,
1190                 void *userdata,
1191                 sd_bus_error *error) {
1192 
1193         Unit *u = userdata;
1194         _cleanup_(cpu_set_reset) CPUSet mems = {};
1195         _cleanup_free_ uint8_t *array = NULL;
1196         size_t allocated;
1197 
1198         assert(bus);
1199         assert(reply);
1200         assert(u);
1201 
1202         (void) unit_get_cpuset(u, &mems, "cpuset.mems.effective");
1203         (void) cpu_set_to_dbus(&mems, &array, &allocated);
1204         return sd_bus_message_append_array(reply, 'y', array, allocated);
1205 }
1206 
property_get_cgroup(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)1207 static int property_get_cgroup(
1208                 sd_bus *bus,
1209                 const char *path,
1210                 const char *interface,
1211                 const char *property,
1212                 sd_bus_message *reply,
1213                 void *userdata,
1214                 sd_bus_error *error) {
1215 
1216         Unit *u = userdata;
1217         const char *t = NULL;
1218 
1219         assert(bus);
1220         assert(reply);
1221         assert(u);
1222 
1223         /* Three cases: a) u->cgroup_path is NULL, in which case the
1224          * unit has no control group, which we report as the empty
1225          * string. b) u->cgroup_path is the empty string, which
1226          * indicates the root cgroup, which we report as "/". c) all
1227          * other cases we report as-is. */
1228 
1229         if (u->cgroup_path)
1230                 t = empty_to_root(u->cgroup_path);
1231 
1232         return sd_bus_message_append(reply, "s", t);
1233 }
1234 
append_process(sd_bus_message * reply,const char * p,pid_t pid,Set * pids)1235 static int append_process(sd_bus_message *reply, const char *p, pid_t pid, Set *pids) {
1236         _cleanup_free_ char *buf = NULL, *cmdline = NULL;
1237         int r;
1238 
1239         assert(reply);
1240         assert(pid > 0);
1241 
1242         r = set_put(pids, PID_TO_PTR(pid));
1243         if (IN_SET(r, 0, -EEXIST))
1244                 return 0;
1245         if (r < 0)
1246                 return r;
1247 
1248         if (!p) {
1249                 r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, pid, &buf);
1250                 if (r == -ESRCH)
1251                         return 0;
1252                 if (r < 0)
1253                         return r;
1254 
1255                 p = buf;
1256         }
1257 
1258         (void) get_process_cmdline(pid, SIZE_MAX,
1259                                    PROCESS_CMDLINE_COMM_FALLBACK | PROCESS_CMDLINE_QUOTE,
1260                                    &cmdline);
1261 
1262         return sd_bus_message_append(reply,
1263                                      "(sus)",
1264                                      p,
1265                                      (uint32_t) pid,
1266                                      cmdline);
1267 }
1268 
append_cgroup(sd_bus_message * reply,const char * p,Set * pids)1269 static int append_cgroup(sd_bus_message *reply, const char *p, Set *pids) {
1270         _cleanup_closedir_ DIR *d = NULL;
1271         _cleanup_fclose_ FILE *f = NULL;
1272         int r;
1273 
1274         assert(reply);
1275         assert(p);
1276 
1277         r = cg_enumerate_processes(SYSTEMD_CGROUP_CONTROLLER, p, &f);
1278         if (r == -ENOENT)
1279                 return 0;
1280         if (r < 0)
1281                 return r;
1282 
1283         for (;;) {
1284                 pid_t pid;
1285 
1286                 /* libvirt / qemu uses threaded mode and cgroup.procs cannot be read at the lower levels.
1287                  * From https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html#threads,
1288                  * “cgroup.procs” in a threaded domain cgroup contains the PIDs of all processes in
1289                  * the subtree and is not readable in the subtree proper. */
1290                 r = cg_read_pid(f, &pid);
1291                 if (IN_SET(r, 0, -EOPNOTSUPP))
1292                         break;
1293                 if (r < 0)
1294                         return r;
1295 
1296                 if (is_kernel_thread(pid) > 0)
1297                         continue;
1298 
1299                 r = append_process(reply, p, pid, pids);
1300                 if (r < 0)
1301                         return r;
1302         }
1303 
1304         r = cg_enumerate_subgroups(SYSTEMD_CGROUP_CONTROLLER, p, &d);
1305         if (r == -ENOENT)
1306                 return 0;
1307         if (r < 0)
1308                 return r;
1309 
1310         for (;;) {
1311                 _cleanup_free_ char *g = NULL, *j = NULL;
1312 
1313                 r = cg_read_subgroup(d, &g);
1314                 if (r < 0)
1315                         return r;
1316                 if (r == 0)
1317                         break;
1318 
1319                 j = path_join(empty_to_root(p), g);
1320                 if (!j)
1321                         return -ENOMEM;
1322 
1323                 r = append_cgroup(reply, j, pids);
1324                 if (r < 0)
1325                         return r;
1326         }
1327 
1328         return 0;
1329 }
1330 
bus_unit_method_get_processes(sd_bus_message * message,void * userdata,sd_bus_error * error)1331 int bus_unit_method_get_processes(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1332         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1333         _cleanup_set_free_ Set *pids = NULL;
1334         Unit *u = userdata;
1335         pid_t pid;
1336         int r;
1337 
1338         assert(message);
1339 
1340         r = mac_selinux_unit_access_check(u, message, "status", error);
1341         if (r < 0)
1342                 return r;
1343 
1344         pids = set_new(NULL);
1345         if (!pids)
1346                 return -ENOMEM;
1347 
1348         r = sd_bus_message_new_method_return(message, &reply);
1349         if (r < 0)
1350                 return r;
1351 
1352         r = sd_bus_message_open_container(reply, 'a', "(sus)");
1353         if (r < 0)
1354                 return r;
1355 
1356         if (u->cgroup_path) {
1357                 r = append_cgroup(reply, u->cgroup_path, pids);
1358                 if (r < 0)
1359                         return r;
1360         }
1361 
1362         /* The main and control pids might live outside of the cgroup, hence fetch them separately */
1363         pid = unit_main_pid(u);
1364         if (pid > 0) {
1365                 r = append_process(reply, NULL, pid, pids);
1366                 if (r < 0)
1367                         return r;
1368         }
1369 
1370         pid = unit_control_pid(u);
1371         if (pid > 0) {
1372                 r = append_process(reply, NULL, pid, pids);
1373                 if (r < 0)
1374                         return r;
1375         }
1376 
1377         r = sd_bus_message_close_container(reply);
1378         if (r < 0)
1379                 return r;
1380 
1381         return sd_bus_send(NULL, reply, NULL);
1382 }
1383 
property_get_ip_counter(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)1384 static int property_get_ip_counter(
1385                 sd_bus *bus,
1386                 const char *path,
1387                 const char *interface,
1388                 const char *property,
1389                 sd_bus_message *reply,
1390                 void *userdata,
1391                 sd_bus_error *error) {
1392 
1393         static const char *const table[_CGROUP_IP_ACCOUNTING_METRIC_MAX] = {
1394                 [CGROUP_IP_INGRESS_BYTES]   = "IPIngressBytes",
1395                 [CGROUP_IP_EGRESS_BYTES]    = "IPEgressBytes",
1396                 [CGROUP_IP_INGRESS_PACKETS] = "IPIngressPackets",
1397                 [CGROUP_IP_EGRESS_PACKETS]  = "IPEgressPackets",
1398         };
1399 
1400         uint64_t value = UINT64_MAX;
1401         Unit *u = userdata;
1402         ssize_t metric;
1403 
1404         assert(bus);
1405         assert(reply);
1406         assert(property);
1407         assert(u);
1408 
1409         assert_se((metric = string_table_lookup(table, ELEMENTSOF(table), property)) >= 0);
1410         (void) unit_get_ip_accounting(u, metric, &value);
1411         return sd_bus_message_append(reply, "t", value);
1412 }
1413 
property_get_io_counter(sd_bus * bus,const char * path,const char * interface,const char * property,sd_bus_message * reply,void * userdata,sd_bus_error * error)1414 static int property_get_io_counter(
1415                 sd_bus *bus,
1416                 const char *path,
1417                 const char *interface,
1418                 const char *property,
1419                 sd_bus_message *reply,
1420                 void *userdata,
1421                 sd_bus_error *error) {
1422 
1423         static const char *const table[_CGROUP_IO_ACCOUNTING_METRIC_MAX] = {
1424                 [CGROUP_IO_READ_BYTES]       = "IOReadBytes",
1425                 [CGROUP_IO_WRITE_BYTES]      = "IOWriteBytes",
1426                 [CGROUP_IO_READ_OPERATIONS]  = "IOReadOperations",
1427                 [CGROUP_IO_WRITE_OPERATIONS] = "IOWriteOperations",
1428         };
1429 
1430         uint64_t value = UINT64_MAX;
1431         Unit *u = userdata;
1432         ssize_t metric;
1433 
1434         assert(bus);
1435         assert(reply);
1436         assert(property);
1437         assert(u);
1438 
1439         assert_se((metric = string_table_lookup(table, ELEMENTSOF(table), property)) >= 0);
1440         (void) unit_get_io_accounting(u, metric, false, &value);
1441         return sd_bus_message_append(reply, "t", value);
1442 }
1443 
bus_unit_method_attach_processes(sd_bus_message * message,void * userdata,sd_bus_error * error)1444 int bus_unit_method_attach_processes(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1445 
1446         _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
1447         _cleanup_set_free_ Set *pids = NULL;
1448         Unit *u = userdata;
1449         const char *path;
1450         int r;
1451 
1452         assert(message);
1453 
1454         /* This migrates the processes with the specified PIDs into the cgroup of this unit, optionally below a
1455          * specified cgroup path. Obviously this only works for units that actually maintain a cgroup
1456          * representation. If a process is already in the cgroup no operation is executed – in this case the specified
1457          * subcgroup path has no effect! */
1458 
1459         r = mac_selinux_unit_access_check(u, message, "start", error);
1460         if (r < 0)
1461                 return r;
1462 
1463         r = sd_bus_message_read(message, "s", &path);
1464         if (r < 0)
1465                 return r;
1466 
1467         path = empty_to_null(path);
1468         if (path) {
1469                 if (!path_is_absolute(path))
1470                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Control group path is not absolute: %s", path);
1471 
1472                 if (!path_is_normalized(path))
1473                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Control group path is not normalized: %s", path);
1474         }
1475 
1476         if (!unit_cgroup_delegate(u))
1477                 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Process migration not available on non-delegated units.");
1478 
1479         if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(u)))
1480                 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Unit is not active, refusing.");
1481 
1482         r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID|SD_BUS_CREDS_PID, &creds);
1483         if (r < 0)
1484                 return r;
1485 
1486         r = sd_bus_message_enter_container(message, 'a', "u");
1487         if (r < 0)
1488                 return r;
1489         for (;;) {
1490                 uid_t process_uid, sender_uid;
1491                 uint32_t upid;
1492                 pid_t pid;
1493 
1494                 r = sd_bus_message_read(message, "u", &upid);
1495                 if (r < 0)
1496                         return r;
1497                 if (r == 0)
1498                         break;
1499 
1500                 if (upid == 0) {
1501                         r = sd_bus_creds_get_pid(creds, &pid);
1502                         if (r < 0)
1503                                 return r;
1504                 } else
1505                         pid = (uid_t) upid;
1506 
1507                 /* Filter out duplicates */
1508                 if (set_contains(pids, PID_TO_PTR(pid)))
1509                         continue;
1510 
1511                 /* Check if this process is suitable for attaching to this unit */
1512                 r = unit_pid_attachable(u, pid, error);
1513                 if (r < 0)
1514                         return r;
1515 
1516                 /* Let's query the sender's UID, so that we can make our security decisions */
1517                 r = sd_bus_creds_get_euid(creds, &sender_uid);
1518                 if (r < 0)
1519                         return r;
1520 
1521                 /* Let's validate security: if the sender is root, then all is OK. If the sender is any other unit,
1522                  * then the process' UID and the target unit's UID have to match the sender's UID */
1523                 if (sender_uid != 0 && sender_uid != getuid()) {
1524                         r = get_process_uid(pid, &process_uid);
1525                         if (r < 0)
1526                                 return sd_bus_error_set_errnof(error, r, "Failed to retrieve process UID: %m");
1527 
1528                         if (process_uid != sender_uid)
1529                                 return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Process " PID_FMT " not owned by client's UID. Refusing.", pid);
1530                         if (process_uid != u->ref_uid)
1531                                 return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Process " PID_FMT " not owned by target unit's UID. Refusing.", pid);
1532                 }
1533 
1534                 if (!pids) {
1535                         pids = set_new(NULL);
1536                         if (!pids)
1537                                 return -ENOMEM;
1538                 }
1539 
1540                 r = set_put(pids, PID_TO_PTR(pid));
1541                 if (r < 0)
1542                         return r;
1543         }
1544 
1545         r = sd_bus_message_exit_container(message);
1546         if (r < 0)
1547                 return r;
1548 
1549         r = unit_attach_pids_to_cgroup(u, pids, path);
1550         if (r < 0)
1551                 return sd_bus_error_set_errnof(error, r, "Failed to attach processes to control group: %m");
1552 
1553         return sd_bus_reply_method_return(message, NULL);
1554 }
1555 
1556 const sd_bus_vtable bus_unit_cgroup_vtable[] = {
1557         SD_BUS_VTABLE_START(0),
1558         SD_BUS_PROPERTY("Slice", "s", property_get_slice, 0, 0),
1559         SD_BUS_PROPERTY("ControlGroup", "s", property_get_cgroup, 0, 0),
1560         SD_BUS_PROPERTY("ControlGroupId", "t", NULL, offsetof(Unit, cgroup_id), 0),
1561         SD_BUS_PROPERTY("MemoryCurrent", "t", property_get_current_memory, 0, 0),
1562         SD_BUS_PROPERTY("MemoryAvailable", "t", property_get_available_memory, 0, 0),
1563         SD_BUS_PROPERTY("CPUUsageNSec", "t", property_get_cpu_usage, 0, 0),
1564         SD_BUS_PROPERTY("EffectiveCPUs", "ay", property_get_cpuset_cpus, 0, 0),
1565         SD_BUS_PROPERTY("EffectiveMemoryNodes", "ay", property_get_cpuset_mems, 0, 0),
1566         SD_BUS_PROPERTY("TasksCurrent", "t", property_get_current_tasks, 0, 0),
1567         SD_BUS_PROPERTY("IPIngressBytes", "t", property_get_ip_counter, 0, 0),
1568         SD_BUS_PROPERTY("IPIngressPackets", "t", property_get_ip_counter, 0, 0),
1569         SD_BUS_PROPERTY("IPEgressBytes", "t", property_get_ip_counter, 0, 0),
1570         SD_BUS_PROPERTY("IPEgressPackets", "t", property_get_ip_counter, 0, 0),
1571         SD_BUS_PROPERTY("IOReadBytes", "t", property_get_io_counter, 0, 0),
1572         SD_BUS_PROPERTY("IOReadOperations", "t", property_get_io_counter, 0, 0),
1573         SD_BUS_PROPERTY("IOWriteBytes", "t", property_get_io_counter, 0, 0),
1574         SD_BUS_PROPERTY("IOWriteOperations", "t", property_get_io_counter, 0, 0),
1575 
1576         SD_BUS_METHOD_WITH_ARGS("GetProcesses",
1577                                  SD_BUS_NO_ARGS,
1578                                  SD_BUS_ARGS("a(sus)", processes),
1579                                  bus_unit_method_get_processes,
1580                                  SD_BUS_VTABLE_UNPRIVILEGED),
1581 
1582         SD_BUS_METHOD_WITH_ARGS("AttachProcesses",
1583                                  SD_BUS_ARGS("s", subcgroup, "au", pids),
1584                                  SD_BUS_NO_RESULT,
1585                                  bus_unit_method_attach_processes,
1586                                  SD_BUS_VTABLE_UNPRIVILEGED),
1587 
1588         SD_BUS_VTABLE_END
1589 };
1590 
send_new_signal(sd_bus * bus,void * userdata)1591 static int send_new_signal(sd_bus *bus, void *userdata) {
1592         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
1593         _cleanup_free_ char *p = NULL;
1594         Unit *u = userdata;
1595         int r;
1596 
1597         assert(bus);
1598         assert(u);
1599 
1600         p = unit_dbus_path(u);
1601         if (!p)
1602                 return -ENOMEM;
1603 
1604         r = sd_bus_message_new_signal(
1605                         bus,
1606                         &m,
1607                         "/org/freedesktop/systemd1",
1608                         "org.freedesktop.systemd1.Manager",
1609                         "UnitNew");
1610         if (r < 0)
1611                 return r;
1612 
1613         r = sd_bus_message_append(m, "so", u->id, p);
1614         if (r < 0)
1615                 return r;
1616 
1617         return sd_bus_send(bus, m, NULL);
1618 }
1619 
send_changed_signal(sd_bus * bus,void * userdata)1620 static int send_changed_signal(sd_bus *bus, void *userdata) {
1621         _cleanup_free_ char *p = NULL;
1622         Unit *u = userdata;
1623         int r;
1624 
1625         assert(bus);
1626         assert(u);
1627 
1628         p = unit_dbus_path(u);
1629         if (!p)
1630                 return -ENOMEM;
1631 
1632         /* Send a properties changed signal. First for the specific
1633          * type, then for the generic unit. The clients may rely on
1634          * this order to get atomic behavior if needed. */
1635 
1636         r = sd_bus_emit_properties_changed_strv(
1637                         bus, p,
1638                         unit_dbus_interface_from_type(u->type),
1639                         NULL);
1640         if (r < 0)
1641                 return r;
1642 
1643         return sd_bus_emit_properties_changed_strv(
1644                         bus, p,
1645                         "org.freedesktop.systemd1.Unit",
1646                         NULL);
1647 }
1648 
bus_unit_send_change_signal(Unit * u)1649 void bus_unit_send_change_signal(Unit *u) {
1650         int r;
1651         assert(u);
1652 
1653         if (u->in_dbus_queue) {
1654                 LIST_REMOVE(dbus_queue, u->manager->dbus_unit_queue, u);
1655                 u->in_dbus_queue = false;
1656         }
1657 
1658         if (!u->id)
1659                 return;
1660 
1661         r = bus_foreach_bus(u->manager, u->bus_track, u->sent_dbus_new_signal ? send_changed_signal : send_new_signal, u);
1662         if (r < 0)
1663                 log_unit_debug_errno(u, r, "Failed to send unit change signal for %s: %m", u->id);
1664 
1665         u->sent_dbus_new_signal = true;
1666 }
1667 
bus_unit_send_pending_change_signal(Unit * u,bool including_new)1668 void bus_unit_send_pending_change_signal(Unit *u, bool including_new) {
1669 
1670         /* Sends out any pending change signals, but only if they really are pending. This call is used when we are
1671          * about to change state in order to force out a PropertiesChanged signal beforehand if there was one pending
1672          * so that clients can follow the full state transition */
1673 
1674         if (!u->in_dbus_queue) /* If not enqueued, don't bother */
1675                 return;
1676 
1677         if (!u->sent_dbus_new_signal && !including_new) /* If the unit was never announced, don't bother, it's fine if
1678                                                          * the unit appears in the new state right-away (except if the
1679                                                          * caller explicitly asked us to send it anyway) */
1680                 return;
1681 
1682         if (MANAGER_IS_RELOADING(u->manager)) /* Don't generate unnecessary PropertiesChanged signals for the same unit
1683                                                * when we are reloading. */
1684                 return;
1685 
1686         bus_unit_send_change_signal(u);
1687 }
1688 
bus_unit_send_pending_freezer_message(Unit * u)1689 int bus_unit_send_pending_freezer_message(Unit *u) {
1690         int r;
1691 
1692         assert(u);
1693 
1694         if (!u->pending_freezer_message)
1695                 return 0;
1696 
1697         r = sd_bus_send(NULL, u->pending_freezer_message, NULL);
1698         if (r < 0)
1699                 log_warning_errno(r, "Failed to send queued message, ignoring: %m");
1700 
1701         u->pending_freezer_message = sd_bus_message_unref(u->pending_freezer_message);
1702 
1703         return 0;
1704 }
1705 
send_removed_signal(sd_bus * bus,void * userdata)1706 static int send_removed_signal(sd_bus *bus, void *userdata) {
1707         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
1708         _cleanup_free_ char *p = NULL;
1709         Unit *u = userdata;
1710         int r;
1711 
1712         assert(bus);
1713         assert(u);
1714 
1715         p = unit_dbus_path(u);
1716         if (!p)
1717                 return -ENOMEM;
1718 
1719         r = sd_bus_message_new_signal(
1720                         bus,
1721                         &m,
1722                         "/org/freedesktop/systemd1",
1723                         "org.freedesktop.systemd1.Manager",
1724                         "UnitRemoved");
1725         if (r < 0)
1726                 return r;
1727 
1728         r = sd_bus_message_append(m, "so", u->id, p);
1729         if (r < 0)
1730                 return r;
1731 
1732         return sd_bus_send(bus, m, NULL);
1733 }
1734 
bus_unit_send_removed_signal(Unit * u)1735 void bus_unit_send_removed_signal(Unit *u) {
1736         int r;
1737         assert(u);
1738 
1739         if (!u->sent_dbus_new_signal || u->in_dbus_queue)
1740                 bus_unit_send_change_signal(u);
1741 
1742         if (!u->id)
1743                 return;
1744 
1745         r = bus_foreach_bus(u->manager, u->bus_track, send_removed_signal, u);
1746         if (r < 0)
1747                 log_unit_debug_errno(u, r, "Failed to send unit remove signal for %s: %m", u->id);
1748 }
1749 
bus_unit_queue_job_one(sd_bus_message * message,Unit * u,JobType type,JobMode mode,BusUnitQueueFlags flags,sd_bus_message * reply,sd_bus_error * error)1750 int bus_unit_queue_job_one(
1751                 sd_bus_message *message,
1752                 Unit *u,
1753                 JobType type,
1754                 JobMode mode,
1755                 BusUnitQueueFlags flags,
1756                 sd_bus_message *reply,
1757                 sd_bus_error *error) {
1758 
1759         _cleanup_set_free_ Set *affected = NULL;
1760         _cleanup_free_ char *job_path = NULL, *unit_path = NULL;
1761         Job *j, *a;
1762         int r;
1763 
1764         if (FLAGS_SET(flags, BUS_UNIT_QUEUE_VERBOSE_REPLY)) {
1765                 affected = set_new(NULL);
1766                 if (!affected)
1767                         return -ENOMEM;
1768         }
1769 
1770         r = manager_add_job(u->manager, type, u, mode, affected, error, &j);
1771         if (r < 0)
1772                 return r;
1773 
1774         if (FLAGS_SET(flags, BUS_UNIT_QUEUE_RETURN_SKIP_ON_CONDITION_FAIL))
1775                 j->return_skip_on_cond_failure = true;
1776 
1777         r = bus_job_track_sender(j, message);
1778         if (r < 0)
1779                 return r;
1780 
1781         /* Before we send the method reply, force out the announcement JobNew for this job */
1782         bus_job_send_pending_change_signal(j, true);
1783 
1784         job_path = job_dbus_path(j);
1785         if (!job_path)
1786                 return -ENOMEM;
1787 
1788         /* The classic response is just a job object path */
1789         if (!FLAGS_SET(flags, BUS_UNIT_QUEUE_VERBOSE_REPLY))
1790                 return sd_bus_message_append(reply, "o", job_path);
1791 
1792         /* In verbose mode respond with the anchor job plus everything that has been affected */
1793 
1794         unit_path = unit_dbus_path(j->unit);
1795         if (!unit_path)
1796                 return -ENOMEM;
1797 
1798         r = sd_bus_message_append(reply, "uosos",
1799                                   j->id, job_path,
1800                                   j->unit->id, unit_path,
1801                                   job_type_to_string(j->type));
1802         if (r < 0)
1803                 return r;
1804 
1805         r = sd_bus_message_open_container(reply, 'a', "(uosos)");
1806         if (r < 0)
1807                 return r;
1808 
1809         SET_FOREACH(a, affected) {
1810                 if (a->id == j->id)
1811                         continue;
1812 
1813                 /* Free paths from previous iteration */
1814                 job_path = mfree(job_path);
1815                 unit_path = mfree(unit_path);
1816 
1817                 job_path = job_dbus_path(a);
1818                 if (!job_path)
1819                         return -ENOMEM;
1820 
1821                 unit_path = unit_dbus_path(a->unit);
1822                 if (!unit_path)
1823                         return -ENOMEM;
1824 
1825                 r = sd_bus_message_append(reply, "(uosos)",
1826                                           a->id, job_path,
1827                                           a->unit->id, unit_path,
1828                                           job_type_to_string(a->type));
1829                 if (r < 0)
1830                         return r;
1831         }
1832 
1833         return sd_bus_message_close_container(reply);
1834 }
1835 
bus_unit_queue_job(sd_bus_message * message,Unit * u,JobType type,JobMode mode,BusUnitQueueFlags flags,sd_bus_error * error)1836 int bus_unit_queue_job(
1837                 sd_bus_message *message,
1838                 Unit *u,
1839                 JobType type,
1840                 JobMode mode,
1841                 BusUnitQueueFlags flags,
1842                 sd_bus_error *error) {
1843 
1844         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1845         int r;
1846 
1847         assert(message);
1848         assert(u);
1849         assert(type >= 0 && type < _JOB_TYPE_MAX);
1850         assert(mode >= 0 && mode < _JOB_MODE_MAX);
1851 
1852         r = mac_selinux_unit_access_check(
1853                         u, message,
1854                         job_type_to_access_method(type),
1855                         error);
1856         if (r < 0)
1857                 return r;
1858 
1859         if (FLAGS_SET(flags, BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE) && unit_can_reload(u)) {
1860                 if (type == JOB_RESTART)
1861                         type = JOB_RELOAD_OR_START;
1862                 else if (type == JOB_TRY_RESTART)
1863                         type = JOB_TRY_RELOAD;
1864         }
1865 
1866         if (type == JOB_STOP &&
1867             IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_ERROR, UNIT_BAD_SETTING) &&
1868             unit_active_state(u) == UNIT_INACTIVE)
1869                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", u->id);
1870 
1871         if ((type == JOB_START && u->refuse_manual_start) ||
1872             (type == JOB_STOP && u->refuse_manual_stop) ||
1873             (IN_SET(type, JOB_RESTART, JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)) ||
1874             (type == JOB_RELOAD_OR_START && job_type_collapse(type, u) == JOB_START && u->refuse_manual_start))
1875                 return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id);
1876 
1877         r = sd_bus_message_new_method_return(message, &reply);
1878         if (r < 0)
1879                 return r;
1880 
1881         r = bus_unit_queue_job_one(message, u, type, mode, flags, reply, error);
1882         if (r < 0)
1883                 return r;
1884 
1885         return sd_bus_send(NULL, reply, NULL);
1886 }
1887 
bus_unit_set_live_property(Unit * u,const char * name,sd_bus_message * message,UnitWriteFlags flags,sd_bus_error * error)1888 static int bus_unit_set_live_property(
1889                 Unit *u,
1890                 const char *name,
1891                 sd_bus_message *message,
1892                 UnitWriteFlags flags,
1893                 sd_bus_error *error) {
1894 
1895         int r;
1896 
1897         assert(u);
1898         assert(name);
1899         assert(message);
1900 
1901         /* Handles setting properties both "live" (i.e. at any time during runtime), and during creation (for
1902          * transient units that are being created). */
1903 
1904         if (streq(name, "Description")) {
1905                 const char *d;
1906 
1907                 r = sd_bus_message_read(message, "s", &d);
1908                 if (r < 0)
1909                         return r;
1910 
1911                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1912                         r = unit_set_description(u, d);
1913                         if (r < 0)
1914                                 return r;
1915 
1916                         unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name, "Description=%s", d);
1917                 }
1918 
1919                 return 1;
1920         }
1921 
1922         /* A setting that only applies to active units. We don't actually write this to /run, this state is
1923          * managed internally. "+foo" sets flag foo, "-foo" unsets flag foo, just "foo" resets flags to
1924          * foo. The last type cannot be mixed with "+" or "-". */
1925 
1926         if (streq(name, "Markers")) {
1927                 unsigned settings = 0, mask = 0;
1928                 bool some_plus_minus = false, some_absolute = false;
1929 
1930                 r = sd_bus_message_enter_container(message, 'a', "s");
1931                 if (r < 0)
1932                         return r;
1933 
1934                 for (;;) {
1935                         const char *word;
1936                         bool b;
1937 
1938                         r = sd_bus_message_read(message, "s", &word);
1939                         if (r < 0)
1940                                 return r;
1941                         if (r == 0)
1942                                 break;
1943 
1944                         if (IN_SET(word[0], '+', '-')) {
1945                                 b = word[0] == '+';
1946                                 word++;
1947                                 some_plus_minus = true;
1948                         } else {
1949                                 b = true;
1950                                 some_absolute = true;
1951                         }
1952 
1953                         UnitMarker m = unit_marker_from_string(word);
1954                         if (m < 0)
1955                                 return sd_bus_error_setf(error, BUS_ERROR_BAD_UNIT_SETTING,
1956                                                          "Unknown marker \"%s\".", word);
1957 
1958                         SET_FLAG(settings, 1u << m, b);
1959                         SET_FLAG(mask, 1u << m, true);
1960                 }
1961 
1962                 r = sd_bus_message_exit_container(message);
1963                 if (r < 0)
1964                         return r;
1965 
1966                 if (some_plus_minus && some_absolute)
1967                         return sd_bus_error_set(error, BUS_ERROR_BAD_UNIT_SETTING, "Bad marker syntax.");
1968 
1969                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
1970                         if (some_absolute)
1971                                 u->markers = settings;
1972                         else
1973                                 u->markers = settings | (u->markers & ~mask);
1974                 }
1975 
1976                 return 1;
1977         }
1978 
1979         return 0;
1980 }
1981 
bus_set_transient_emergency_action(Unit * u,const char * name,EmergencyAction * p,sd_bus_message * message,UnitWriteFlags flags,sd_bus_error * error)1982 static int bus_set_transient_emergency_action(
1983                 Unit *u,
1984                 const char *name,
1985                 EmergencyAction *p,
1986                 sd_bus_message *message,
1987                 UnitWriteFlags flags,
1988                 sd_bus_error *error) {
1989 
1990         const char *s;
1991         EmergencyAction v;
1992         int r;
1993         bool system;
1994 
1995         assert(p);
1996 
1997         r = sd_bus_message_read(message, "s", &s);
1998         if (r < 0)
1999                 return r;
2000 
2001         system = MANAGER_IS_SYSTEM(u->manager);
2002         r = parse_emergency_action(s, system, &v);
2003         if (r < 0)
2004                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
2005                                          r == -EOPNOTSUPP ? "%s setting invalid for manager type: %s"
2006                                                           : "Invalid %s setting: %s",
2007                                          name, s);
2008 
2009         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2010                 *p = v;
2011                 unit_write_settingf(u, flags, name,
2012                                     "%s=%s", name, s);
2013         }
2014 
2015         return 1;
2016 }
2017 
bus_set_transient_exit_status(Unit * u,const char * name,int * p,sd_bus_message * message,UnitWriteFlags flags,sd_bus_error * error)2018 static int bus_set_transient_exit_status(
2019                 Unit *u,
2020                 const char *name,
2021                 int *p,
2022                 sd_bus_message *message,
2023                 UnitWriteFlags flags,
2024                 sd_bus_error *error) {
2025 
2026         int32_t k;
2027         int r;
2028 
2029         assert(p);
2030 
2031         r = sd_bus_message_read(message, "i", &k);
2032         if (r < 0)
2033                 return r;
2034 
2035         if (k > 255)
2036                 return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Exit status must be in range 0…255 or negative.");
2037 
2038         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2039                 *p = k < 0 ? -1 : k;
2040 
2041                 if (k < 0)
2042                         unit_write_settingf(u, flags, name, "%s=", name);
2043                 else
2044                         unit_write_settingf(u, flags, name, "%s=%i", name, k);
2045         }
2046 
2047         return 1;
2048 }
2049 
2050 static BUS_DEFINE_SET_TRANSIENT_PARSE(collect_mode, CollectMode, collect_mode_from_string);
2051 static BUS_DEFINE_SET_TRANSIENT_PARSE(job_mode, JobMode, job_mode_from_string);
2052 
bus_set_transient_conditions(Unit * u,const char * name,Condition ** list,bool is_condition,sd_bus_message * message,UnitWriteFlags flags,sd_bus_error * error)2053 static int bus_set_transient_conditions(
2054                 Unit *u,
2055                 const char *name,
2056                 Condition **list,
2057                 bool is_condition,
2058                 sd_bus_message *message,
2059                 UnitWriteFlags flags,
2060                 sd_bus_error *error) {
2061 
2062         const char *type_name, *param;
2063         int trigger, negate, r;
2064         bool empty = true;
2065 
2066         assert(list);
2067 
2068         r = sd_bus_message_enter_container(message, 'a', "(sbbs)");
2069         if (r < 0)
2070                 return r;
2071 
2072         while ((r = sd_bus_message_read(message, "(sbbs)", &type_name, &trigger, &negate, &param)) > 0) {
2073                 ConditionType t;
2074 
2075                 t = is_condition ? condition_type_from_string(type_name) : assert_type_from_string(type_name);
2076                 if (t < 0)
2077                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid condition type: %s", type_name);
2078 
2079                 if (isempty(param))
2080                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Condition parameter in %s is empty", type_name);
2081 
2082                 if (condition_takes_path(t) && !path_is_absolute(param))
2083                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path in condition %s is not absolute: %s", type_name, param);
2084 
2085                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2086                         Condition *c;
2087 
2088                         c = condition_new(t, param, trigger, negate);
2089                         if (!c)
2090                                 return -ENOMEM;
2091 
2092                         LIST_PREPEND(conditions, *list, c);
2093 
2094                         unit_write_settingf(u, flags|UNIT_ESCAPE_SPECIFIERS, name,
2095                                             "%s=%s%s%s", type_name,
2096                                             trigger ? "|" : "", negate ? "!" : "", param);
2097                 }
2098 
2099                 empty = false;
2100         }
2101         if (r < 0)
2102                 return r;
2103 
2104         r = sd_bus_message_exit_container(message);
2105         if (r < 0)
2106                 return r;
2107 
2108         if (!UNIT_WRITE_FLAGS_NOOP(flags) && empty) {
2109                 *list = condition_free_list(*list);
2110                 unit_write_settingf(u, flags, name, "%sNull=", is_condition ? "Condition" : "Assert");
2111         }
2112 
2113         return 1;
2114 }
2115 
bus_unit_set_transient_property(Unit * u,const char * name,sd_bus_message * message,UnitWriteFlags flags,sd_bus_error * error)2116 static int bus_unit_set_transient_property(
2117                 Unit *u,
2118                 const char *name,
2119                 sd_bus_message *message,
2120                 UnitWriteFlags flags,
2121                 sd_bus_error *error) {
2122 
2123         UnitDependency d;
2124         int r;
2125 
2126         assert(u);
2127         assert(name);
2128         assert(message);
2129 
2130         /* Handles settings when transient units are created. This settings cannot be altered anymore after
2131          * the unit has been created. */
2132 
2133         if (streq(name, "SourcePath"))
2134                 return bus_set_transient_path(u, name, &u->source_path, message, flags, error);
2135 
2136         if (streq(name, "StopWhenUnneeded"))
2137                 return bus_set_transient_bool(u, name, &u->stop_when_unneeded, message, flags, error);
2138 
2139         if (streq(name, "RefuseManualStart"))
2140                 return bus_set_transient_bool(u, name, &u->refuse_manual_start, message, flags, error);
2141 
2142         if (streq(name, "RefuseManualStop"))
2143                 return bus_set_transient_bool(u, name, &u->refuse_manual_stop, message, flags, error);
2144 
2145         if (streq(name, "AllowIsolate"))
2146                 return bus_set_transient_bool(u, name, &u->allow_isolate, message, flags, error);
2147 
2148         if (streq(name, "DefaultDependencies"))
2149                 return bus_set_transient_bool(u, name, &u->default_dependencies, message, flags, error);
2150 
2151         if (streq(name, "OnSuccessJobMode"))
2152                 return bus_set_transient_job_mode(u, name, &u->on_success_job_mode, message, flags, error);
2153 
2154         if (streq(name, "OnFailureJobMode"))
2155                 return bus_set_transient_job_mode(u, name, &u->on_failure_job_mode, message, flags, error);
2156 
2157         if (streq(name, "IgnoreOnIsolate"))
2158                 return bus_set_transient_bool(u, name, &u->ignore_on_isolate, message, flags, error);
2159 
2160         if (streq(name, "JobTimeoutUSec")) {
2161                 r = bus_set_transient_usec_fix_0(u, name, &u->job_timeout, message, flags, error);
2162                 if (r >= 0 && !UNIT_WRITE_FLAGS_NOOP(flags) && !u->job_running_timeout_set)
2163                         u->job_running_timeout = u->job_timeout;
2164         }
2165 
2166         if (streq(name, "JobRunningTimeoutUSec")) {
2167                 r = bus_set_transient_usec_fix_0(u, name, &u->job_running_timeout, message, flags, error);
2168                 if (r >= 0 && !UNIT_WRITE_FLAGS_NOOP(flags))
2169                         u->job_running_timeout_set = true;
2170 
2171                 return r;
2172         }
2173 
2174         if (streq(name, "JobTimeoutAction"))
2175                 return bus_set_transient_emergency_action(u, name, &u->job_timeout_action, message, flags, error);
2176 
2177         if (streq(name, "JobTimeoutRebootArgument"))
2178                 return bus_set_transient_string(u, name, &u->job_timeout_reboot_arg, message, flags, error);
2179 
2180         if (streq(name, "StartLimitIntervalUSec"))
2181                 return bus_set_transient_usec(u, name, &u->start_ratelimit.interval, message, flags, error);
2182 
2183         if (streq(name, "StartLimitBurst"))
2184                 return bus_set_transient_unsigned(u, name, &u->start_ratelimit.burst, message, flags, error);
2185 
2186         if (streq(name, "StartLimitAction"))
2187                 return bus_set_transient_emergency_action(u, name, &u->start_limit_action, message, flags, error);
2188 
2189         if (streq(name, "FailureAction"))
2190                 return bus_set_transient_emergency_action(u, name, &u->failure_action, message, flags, error);
2191 
2192         if (streq(name, "SuccessAction"))
2193                 return bus_set_transient_emergency_action(u, name, &u->success_action, message, flags, error);
2194 
2195         if (streq(name, "FailureActionExitStatus"))
2196                 return bus_set_transient_exit_status(u, name, &u->failure_action_exit_status, message, flags, error);
2197 
2198         if (streq(name, "SuccessActionExitStatus"))
2199                 return bus_set_transient_exit_status(u, name, &u->success_action_exit_status, message, flags, error);
2200 
2201         if (streq(name, "RebootArgument"))
2202                 return bus_set_transient_string(u, name, &u->reboot_arg, message, flags, error);
2203 
2204         if (streq(name, "CollectMode"))
2205                 return bus_set_transient_collect_mode(u, name, &u->collect_mode, message, flags, error);
2206 
2207         if (streq(name, "Conditions"))
2208                 return bus_set_transient_conditions(u, name, &u->conditions, true, message, flags, error);
2209 
2210         if (streq(name, "Asserts"))
2211                 return bus_set_transient_conditions(u, name, &u->asserts, false, message, flags, error);
2212 
2213         if (streq(name, "Documentation")) {
2214                 _cleanup_strv_free_ char **l = NULL;
2215 
2216                 r = sd_bus_message_read_strv(message, &l);
2217                 if (r < 0)
2218                         return r;
2219 
2220                 STRV_FOREACH(p, l)
2221                         if (!documentation_url_is_valid(*p))
2222                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid URL in %s: %s", name, *p);
2223 
2224                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2225                         if (strv_isempty(l)) {
2226                                 u->documentation = strv_free(u->documentation);
2227                                 unit_write_settingf(u, flags, name, "%s=", name);
2228                         } else {
2229                                 strv_extend_strv(&u->documentation, l, false);
2230 
2231                                 STRV_FOREACH(p, l)
2232                                         unit_write_settingf(u, flags, name, "%s=%s", name, *p);
2233                         }
2234                 }
2235 
2236                 return 1;
2237 
2238         } else if (streq(name, "Slice")) {
2239                 Unit *slice;
2240                 const char *s;
2241 
2242                 if (!UNIT_HAS_CGROUP_CONTEXT(u))
2243                         return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "The slice property is only available for units with control groups.");
2244                 if (u->type == UNIT_SLICE)
2245                         return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Slice may not be set for slice units.");
2246                 if (unit_has_name(u, SPECIAL_INIT_SCOPE))
2247                         return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Cannot set slice for init.scope");
2248 
2249                 r = sd_bus_message_read(message, "s", &s);
2250                 if (r < 0)
2251                         return r;
2252 
2253                 if (!unit_name_is_valid(s, UNIT_NAME_PLAIN))
2254                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit name '%s'", s);
2255 
2256                 /* Note that we do not dispatch the load queue here yet, as we don't want our own transient unit to be
2257                  * loaded while we are still setting it up. Or in other words, we use manager_load_unit_prepare()
2258                  * instead of manager_load_unit() on purpose, here. */
2259                 r = manager_load_unit_prepare(u->manager, s, NULL, error, &slice);
2260                 if (r < 0)
2261                         return r;
2262 
2263                 if (slice->type != UNIT_SLICE)
2264                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit name '%s' is not a slice", s);
2265 
2266                 if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2267                         r = unit_set_slice(u, slice);
2268                         if (r < 0)
2269                                 return r;
2270 
2271                         unit_write_settingf(u, flags|UNIT_PRIVATE, name, "Slice=%s", s);
2272                 }
2273 
2274                 return 1;
2275 
2276         } else if (streq(name, "RequiresMountsFor")) {
2277                 _cleanup_strv_free_ char **l = NULL;
2278 
2279                 r = sd_bus_message_read_strv(message, &l);
2280                 if (r < 0)
2281                         return r;
2282 
2283                 STRV_FOREACH(p, l) {
2284                         path_simplify(*p);
2285 
2286                         if (!path_is_absolute(*p))
2287                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path specified in %s is not absolute: %s", name, *p);
2288 
2289                         if (!path_is_valid(*p))
2290                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path specified in %s has invalid length: %s", name, *p);
2291 
2292                         if (!path_is_normalized(*p))
2293                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Path specified in %s is not normalized: %s", name, *p);
2294 
2295                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2296                                 r = unit_require_mounts_for(u, *p, UNIT_DEPENDENCY_FILE);
2297                                 if (r < 0)
2298                                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Failed to add required mount \"%s\": %m", *p);
2299 
2300                                 unit_write_settingf(u, flags, name, "%s=%s", name, *p);
2301                         }
2302                 }
2303 
2304                 return 1;
2305         }
2306 
2307         if (streq(name, "RequiresOverridable"))
2308                 d = UNIT_REQUIRES; /* redirect for obsolete unit dependency type */
2309         else if (streq(name, "RequisiteOverridable"))
2310                 d = UNIT_REQUISITE; /* same here */
2311         else
2312                 d = unit_dependency_from_string(name);
2313 
2314         if (d >= 0) {
2315                 const char *other;
2316 
2317                 if (!IN_SET(d,
2318                             UNIT_REQUIRES,
2319                             UNIT_REQUISITE,
2320                             UNIT_WANTS,
2321                             UNIT_BINDS_TO,
2322                             UNIT_PART_OF,
2323                             UNIT_UPHOLDS,
2324                             UNIT_CONFLICTS,
2325                             UNIT_BEFORE,
2326                             UNIT_AFTER,
2327                             UNIT_ON_SUCCESS,
2328                             UNIT_ON_FAILURE,
2329                             UNIT_PROPAGATES_RELOAD_TO,
2330                             UNIT_RELOAD_PROPAGATED_FROM,
2331                             UNIT_PROPAGATES_STOP_TO,
2332                             UNIT_STOP_PROPAGATED_FROM,
2333                             UNIT_JOINS_NAMESPACE_OF))
2334                     return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Dependency type %s may not be created transiently.", unit_dependency_to_string(d));
2335 
2336                 r = sd_bus_message_enter_container(message, 'a', "s");
2337                 if (r < 0)
2338                         return r;
2339 
2340                 while ((r = sd_bus_message_read(message, "s", &other)) > 0) {
2341                         if (!unit_name_is_valid(other, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE))
2342                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit name %s", other);
2343 
2344                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
2345                                 _cleanup_free_ char *label = NULL;
2346 
2347                                 r = unit_add_dependency_by_name(u, d, other, true, UNIT_DEPENDENCY_FILE);
2348                                 if (r < 0)
2349                                         return r;
2350 
2351                                 label = strjoin(name, "-", other);
2352                                 if (!label)
2353                                         return -ENOMEM;
2354 
2355                                 unit_write_settingf(u, flags, label, "%s=%s", unit_dependency_to_string(d), other);
2356                         }
2357 
2358                 }
2359                 if (r < 0)
2360                         return r;
2361 
2362                 r = sd_bus_message_exit_container(message);
2363                 if (r < 0)
2364                         return r;
2365 
2366                 return 1;
2367 
2368         } else if (streq(name, "AddRef")) {
2369 
2370                 int b;
2371 
2372                 /* Why is this called "AddRef" rather than just "Ref", or "Reference"? There's already a "Ref()" method
2373                  * on the Unit interface, and it's probably not a good idea to expose a property and a method on the
2374                  * same interface (well, strictly speaking AddRef isn't exposed as full property, we just read it for
2375                  * transient units, but still). And "References" and "ReferencedBy" is already used as unit reference
2376                  * dependency type, hence let's not confuse things with that.
2377                  *
2378                  * Note that we don't actually add the reference to the bus track. We do that only after the setup of
2379                  * the transient unit is complete, so that setting this property multiple times in the same transient
2380                  * unit creation call doesn't count as individual references. */
2381 
2382                 r = sd_bus_message_read(message, "b", &b);
2383                 if (r < 0)
2384                         return r;
2385 
2386                 if (!UNIT_WRITE_FLAGS_NOOP(flags))
2387                         u->bus_track_add = b;
2388 
2389                 return 1;
2390         }
2391 
2392         return 0;
2393 }
2394 
bus_unit_set_properties(Unit * u,sd_bus_message * message,UnitWriteFlags flags,bool commit,sd_bus_error * error)2395 int bus_unit_set_properties(
2396                 Unit *u,
2397                 sd_bus_message *message,
2398                 UnitWriteFlags flags,
2399                 bool commit,
2400                 sd_bus_error *error) {
2401 
2402         bool for_real = false;
2403         unsigned n = 0;
2404         int r;
2405 
2406         assert(u);
2407         assert(message);
2408 
2409         /* We iterate through the array twice. First run we just check
2410          * if all passed data is valid, second run actually applies
2411          * it. This is to implement transaction-like behaviour without
2412          * actually providing full transactions. */
2413 
2414         r = sd_bus_message_enter_container(message, 'a', "(sv)");
2415         if (r < 0)
2416                 return r;
2417 
2418         for (;;) {
2419                 const char *name;
2420                 UnitWriteFlags f;
2421 
2422                 r = sd_bus_message_enter_container(message, 'r', "sv");
2423                 if (r < 0)
2424                         return r;
2425                 if (r == 0) {
2426                         if (for_real || UNIT_WRITE_FLAGS_NOOP(flags))
2427                                 break;
2428 
2429                         /* Reached EOF. Let's try again, and this time for realz... */
2430                         r = sd_bus_message_rewind(message, false);
2431                         if (r < 0)
2432                                 return r;
2433 
2434                         for_real = true;
2435                         continue;
2436                 }
2437 
2438                 r = sd_bus_message_read(message, "s", &name);
2439                 if (r < 0)
2440                         return r;
2441 
2442                 if (!UNIT_VTABLE(u)->bus_set_property)
2443                         return sd_bus_error_setf(error, SD_BUS_ERROR_PROPERTY_READ_ONLY,
2444                                                  "Objects of this type do not support setting properties.");
2445 
2446                 r = sd_bus_message_enter_container(message, 'v', NULL);
2447                 if (r < 0)
2448                         return r;
2449 
2450                 /* If not for real, then mask out the two target flags */
2451                 f = for_real ? flags : (flags & ~(UNIT_RUNTIME|UNIT_PERSISTENT));
2452 
2453                 r = UNIT_VTABLE(u)->bus_set_property(u, name, message, f, error);
2454                 if (r == 0 && u->transient && u->load_state == UNIT_STUB)
2455                         r = bus_unit_set_transient_property(u, name, message, f, error);
2456                 if (r == 0)
2457                         r = bus_unit_set_live_property(u, name, message, f, error);
2458                 if (r < 0)
2459                         return r;
2460 
2461                 if (r == 0)
2462                         return sd_bus_error_setf(error, SD_BUS_ERROR_PROPERTY_READ_ONLY,
2463                                                  "Cannot set property %s, or unknown property.", name);
2464 
2465                 r = sd_bus_message_exit_container(message);
2466                 if (r < 0)
2467                         return r;
2468 
2469                 r = sd_bus_message_exit_container(message);
2470                 if (r < 0)
2471                         return r;
2472 
2473                 n += for_real;
2474         }
2475 
2476         r = sd_bus_message_exit_container(message);
2477         if (r < 0)
2478                 return r;
2479 
2480         if (commit && n > 0 && UNIT_VTABLE(u)->bus_commit_properties)
2481                 UNIT_VTABLE(u)->bus_commit_properties(u);
2482 
2483         return n;
2484 }
2485 
bus_unit_validate_load_state(Unit * u,sd_bus_error * error)2486 int bus_unit_validate_load_state(Unit *u, sd_bus_error *error) {
2487         assert(u);
2488 
2489         /* Generates a pretty error if a unit isn't properly loaded. */
2490 
2491         switch (u->load_state) {
2492 
2493         case UNIT_LOADED:
2494                 return 0;
2495 
2496         case UNIT_NOT_FOUND:
2497                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not found.", u->id);
2498 
2499         case UNIT_BAD_SETTING:
2500                 return sd_bus_error_setf(error, BUS_ERROR_BAD_UNIT_SETTING, "Unit %s has a bad unit file setting.", u->id);
2501 
2502         case UNIT_ERROR: /* Only show .load_error in UNIT_ERROR state */
2503                 return sd_bus_error_set_errnof(error, u->load_error,
2504                                                "Unit %s failed to load properly, please adjust/correct and reload service manager: %m", u->id);
2505 
2506         case UNIT_MASKED:
2507                 return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit %s is masked.", u->id);
2508 
2509         case UNIT_STUB:
2510         case UNIT_MERGED:
2511         default:
2512                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unexpected load state of unit %s", u->id);
2513         }
2514 }
2515 
bus_unit_track_handler(sd_bus_track * t,void * userdata)2516 static int bus_unit_track_handler(sd_bus_track *t, void *userdata) {
2517         Unit *u = userdata;
2518 
2519         assert(t);
2520         assert(u);
2521 
2522         u->bus_track = sd_bus_track_unref(u->bus_track); /* make sure we aren't called again */
2523 
2524         /* If the client that tracks us disappeared, then there's reason to believe that the cgroup is empty now too,
2525          * let's see */
2526         unit_add_to_cgroup_empty_queue(u);
2527 
2528         /* Also add the unit to the GC queue, after all if the client left it might be time to GC this unit */
2529         unit_add_to_gc_queue(u);
2530 
2531         return 0;
2532 }
2533 
bus_unit_allocate_bus_track(Unit * u)2534 static int bus_unit_allocate_bus_track(Unit *u) {
2535         int r;
2536 
2537         assert(u);
2538 
2539         if (u->bus_track)
2540                 return 0;
2541 
2542         r = sd_bus_track_new(u->manager->api_bus, &u->bus_track, bus_unit_track_handler, u);
2543         if (r < 0)
2544                 return r;
2545 
2546         r = sd_bus_track_set_recursive(u->bus_track, true);
2547         if (r < 0) {
2548                 u->bus_track = sd_bus_track_unref(u->bus_track);
2549                 return r;
2550         }
2551 
2552         return 0;
2553 }
2554 
bus_unit_track_add_name(Unit * u,const char * name)2555 int bus_unit_track_add_name(Unit *u, const char *name) {
2556         int r;
2557 
2558         assert(u);
2559 
2560         r = bus_unit_allocate_bus_track(u);
2561         if (r < 0)
2562                 return r;
2563 
2564         return sd_bus_track_add_name(u->bus_track, name);
2565 }
2566 
bus_unit_track_add_sender(Unit * u,sd_bus_message * m)2567 int bus_unit_track_add_sender(Unit *u, sd_bus_message *m) {
2568         int r;
2569 
2570         assert(u);
2571 
2572         r = bus_unit_allocate_bus_track(u);
2573         if (r < 0)
2574                 return r;
2575 
2576         return sd_bus_track_add_sender(u->bus_track, m);
2577 }
2578 
bus_unit_track_remove_sender(Unit * u,sd_bus_message * m)2579 int bus_unit_track_remove_sender(Unit *u, sd_bus_message *m) {
2580         assert(u);
2581 
2582         /* If we haven't allocated the bus track object yet, then there's definitely no reference taken yet,
2583          * return an error */
2584         if (!u->bus_track)
2585                 return -EUNATCH;
2586 
2587         return sd_bus_track_remove_sender(u->bus_track, m);
2588 }
2589