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