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