]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/dbus-manager.c
tty-ask-password: Split out password sending
[thirdparty/systemd.git] / src / core / dbus-manager.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <errno.h>
23 #include <sys/prctl.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 "clock-util.h"
31 #include "dbus-execute.h"
32 #include "dbus-job.h"
33 #include "dbus-manager.h"
34 #include "dbus-unit.h"
35 #include "dbus.h"
36 #include "env-util.h"
37 #include "fd-util.h"
38 #include "fileio.h"
39 #include "formats-util.h"
40 #include "install.h"
41 #include "log.h"
42 #include "path-util.h"
43 #include "selinux-access.h"
44 #include "stat-util.h"
45 #include "string-util.h"
46 #include "strv.h"
47 #include "syslog-util.h"
48 #include "virt.h"
49 #include "watchdog.h"
50
51 static int property_get_version(
52 sd_bus *bus,
53 const char *path,
54 const char *interface,
55 const char *property,
56 sd_bus_message *reply,
57 void *userdata,
58 sd_bus_error *error) {
59
60 assert(bus);
61 assert(reply);
62
63 return sd_bus_message_append(reply, "s", PACKAGE_VERSION);
64 }
65
66 static int property_get_features(
67 sd_bus *bus,
68 const char *path,
69 const char *interface,
70 const char *property,
71 sd_bus_message *reply,
72 void *userdata,
73 sd_bus_error *error) {
74
75 assert(bus);
76 assert(reply);
77
78 return sd_bus_message_append(reply, "s", SYSTEMD_FEATURES);
79 }
80
81 static int property_get_virtualization(
82 sd_bus *bus,
83 const char *path,
84 const char *interface,
85 const char *property,
86 sd_bus_message *reply,
87 void *userdata,
88 sd_bus_error *error) {
89
90 int v;
91
92 assert(bus);
93 assert(reply);
94
95 v = detect_virtualization();
96
97 /* Make sure to return the empty string when we detect no virtualization, as that is the API.
98 *
99 * https://github.com/systemd/systemd/issues/1423
100 */
101
102 return sd_bus_message_append(
103 reply, "s",
104 v == VIRTUALIZATION_NONE ? "" : virtualization_to_string(v));
105 }
106
107 static int property_get_architecture(
108 sd_bus *bus,
109 const char *path,
110 const char *interface,
111 const char *property,
112 sd_bus_message *reply,
113 void *userdata,
114 sd_bus_error *error) {
115
116 assert(bus);
117 assert(reply);
118
119 return sd_bus_message_append(reply, "s", architecture_to_string(uname_architecture()));
120 }
121
122 static int property_get_tainted(
123 sd_bus *bus,
124 const char *path,
125 const char *interface,
126 const char *property,
127 sd_bus_message *reply,
128 void *userdata,
129 sd_bus_error *error) {
130
131 char buf[sizeof("split-usr:cgroups-missing:local-hwclock:")] = "", *e = buf;
132 Manager *m = userdata;
133
134 assert(bus);
135 assert(reply);
136 assert(m);
137
138 if (m->taint_usr)
139 e = stpcpy(e, "split-usr:");
140
141 if (access("/proc/cgroups", F_OK) < 0)
142 e = stpcpy(e, "cgroups-missing:");
143
144 if (clock_is_localtime() > 0)
145 e = stpcpy(e, "local-hwclock:");
146
147 /* remove the last ':' */
148 if (e != buf)
149 e[-1] = 0;
150
151 return sd_bus_message_append(reply, "s", buf);
152 }
153
154 static int property_get_log_target(
155 sd_bus *bus,
156 const char *path,
157 const char *interface,
158 const char *property,
159 sd_bus_message *reply,
160 void *userdata,
161 sd_bus_error *error) {
162
163 assert(bus);
164 assert(reply);
165
166 return sd_bus_message_append(reply, "s", log_target_to_string(log_get_target()));
167 }
168
169 static int property_set_log_target(
170 sd_bus *bus,
171 const char *path,
172 const char *interface,
173 const char *property,
174 sd_bus_message *value,
175 void *userdata,
176 sd_bus_error *error) {
177
178 const char *t;
179 int r;
180
181 assert(bus);
182 assert(value);
183
184 r = sd_bus_message_read(value, "s", &t);
185 if (r < 0)
186 return r;
187
188 return log_set_target_from_string(t);
189 }
190
191 static int property_get_log_level(
192 sd_bus *bus,
193 const char *path,
194 const char *interface,
195 const char *property,
196 sd_bus_message *reply,
197 void *userdata,
198 sd_bus_error *error) {
199
200 _cleanup_free_ char *t = NULL;
201 int r;
202
203 assert(bus);
204 assert(reply);
205
206 r = log_level_to_string_alloc(log_get_max_level(), &t);
207 if (r < 0)
208 return r;
209
210 return sd_bus_message_append(reply, "s", t);
211 }
212
213 static int property_set_log_level(
214 sd_bus *bus,
215 const char *path,
216 const char *interface,
217 const char *property,
218 sd_bus_message *value,
219 void *userdata,
220 sd_bus_error *error) {
221
222 const char *t;
223 int r;
224
225 assert(bus);
226 assert(value);
227
228 r = sd_bus_message_read(value, "s", &t);
229 if (r < 0)
230 return r;
231
232 r = log_set_max_level_from_string(t);
233 if (r == 0)
234 log_info("Setting log level to %s.", t);
235 return r;
236 }
237
238 static int property_get_n_names(
239 sd_bus *bus,
240 const char *path,
241 const char *interface,
242 const char *property,
243 sd_bus_message *reply,
244 void *userdata,
245 sd_bus_error *error) {
246
247 Manager *m = userdata;
248
249 assert(bus);
250 assert(reply);
251 assert(m);
252
253 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->units));
254 }
255
256 static int property_get_n_failed_units(
257 sd_bus *bus,
258 const char *path,
259 const char *interface,
260 const char *property,
261 sd_bus_message *reply,
262 void *userdata,
263 sd_bus_error *error) {
264
265 Manager *m = userdata;
266
267 assert(bus);
268 assert(reply);
269 assert(m);
270
271 return sd_bus_message_append(reply, "u", (uint32_t) set_size(m->failed_units));
272 }
273
274 static int property_get_n_jobs(
275 sd_bus *bus,
276 const char *path,
277 const char *interface,
278 const char *property,
279 sd_bus_message *reply,
280 void *userdata,
281 sd_bus_error *error) {
282
283 Manager *m = userdata;
284
285 assert(bus);
286 assert(reply);
287 assert(m);
288
289 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->jobs));
290 }
291
292 static int property_get_progress(
293 sd_bus *bus,
294 const char *path,
295 const char *interface,
296 const char *property,
297 sd_bus_message *reply,
298 void *userdata,
299 sd_bus_error *error) {
300
301 Manager *m = userdata;
302 double d;
303
304 assert(bus);
305 assert(reply);
306 assert(m);
307
308 if (dual_timestamp_is_set(&m->finish_timestamp))
309 d = 1.0;
310 else
311 d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
312
313 return sd_bus_message_append(reply, "d", d);
314 }
315
316 static int property_get_system_state(
317 sd_bus *bus,
318 const char *path,
319 const char *interface,
320 const char *property,
321 sd_bus_message *reply,
322 void *userdata,
323 sd_bus_error *error) {
324
325 Manager *m = userdata;
326
327 assert(bus);
328 assert(reply);
329 assert(m);
330
331 return sd_bus_message_append(reply, "s", manager_state_to_string(manager_state(m)));
332 }
333
334 static int property_set_runtime_watchdog(
335 sd_bus *bus,
336 const char *path,
337 const char *interface,
338 const char *property,
339 sd_bus_message *value,
340 void *userdata,
341 sd_bus_error *error) {
342
343 usec_t *t = userdata;
344 int r;
345
346 assert(bus);
347 assert(value);
348
349 assert_cc(sizeof(usec_t) == sizeof(uint64_t));
350
351 r = sd_bus_message_read(value, "t", t);
352 if (r < 0)
353 return r;
354
355 return watchdog_set_timeout(t);
356 }
357
358 static int property_get_timer_slack_nsec(
359 sd_bus *bus,
360 const char *path,
361 const char *interface,
362 const char *property,
363 sd_bus_message *reply,
364 void *userdata,
365 sd_bus_error *error) {
366
367 assert(bus);
368 assert(reply);
369
370 return sd_bus_message_append(reply, "t", (uint64_t) prctl(PR_GET_TIMERSLACK));
371 }
372
373 static int method_get_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
374 _cleanup_free_ char *path = NULL;
375 Manager *m = userdata;
376 const char *name;
377 Unit *u;
378 int r;
379
380 assert(message);
381 assert(m);
382
383 /* Anyone can call this method */
384
385 r = sd_bus_message_read(message, "s", &name);
386 if (r < 0)
387 return r;
388
389 if (isempty(name)) {
390 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
391 pid_t pid;
392
393 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
394 if (r < 0)
395 return r;
396
397 r = sd_bus_creds_get_pid(creds, &pid);
398 if (r < 0)
399 return r;
400
401 u = manager_get_unit_by_pid(m, pid);
402 if (!u)
403 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
404 } else {
405 u = manager_get_unit(m, name);
406 if (!u)
407 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
408 }
409
410 r = mac_selinux_unit_access_check(u, message, "status", error);
411 if (r < 0)
412 return r;
413
414 path = unit_dbus_path(u);
415 if (!path)
416 return -ENOMEM;
417
418 return sd_bus_reply_method_return(message, "o", path);
419 }
420
421 static int method_get_unit_by_pid(sd_bus_message *message, void *userdata, sd_bus_error *error) {
422 _cleanup_free_ char *path = NULL;
423 Manager *m = userdata;
424 pid_t pid;
425 Unit *u;
426 int r;
427
428 assert(message);
429 assert(m);
430
431 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
432
433 /* Anyone can call this method */
434
435 r = sd_bus_message_read(message, "u", &pid);
436 if (r < 0)
437 return r;
438 if (pid < 0)
439 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid PID " PID_FMT, pid);
440
441 if (pid == 0) {
442 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
443
444 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
445 if (r < 0)
446 return r;
447
448 r = sd_bus_creds_get_pid(creds, &pid);
449 if (r < 0)
450 return r;
451 }
452
453 u = manager_get_unit_by_pid(m, pid);
454 if (!u)
455 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID "PID_FMT" does not belong to any loaded unit.", pid);
456
457 r = mac_selinux_unit_access_check(u, message, "status", error);
458 if (r < 0)
459 return r;
460
461 path = unit_dbus_path(u);
462 if (!path)
463 return -ENOMEM;
464
465 return sd_bus_reply_method_return(message, "o", path);
466 }
467
468 static int method_load_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
469 _cleanup_free_ char *path = NULL;
470 Manager *m = userdata;
471 const char *name;
472 Unit *u;
473 int r;
474
475 assert(message);
476 assert(m);
477
478 /* Anyone can call this method */
479
480 r = sd_bus_message_read(message, "s", &name);
481 if (r < 0)
482 return r;
483
484 if (isempty(name)) {
485 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
486 pid_t pid;
487
488 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
489 if (r < 0)
490 return r;
491
492 r = sd_bus_creds_get_pid(creds, &pid);
493 if (r < 0)
494 return r;
495
496 u = manager_get_unit_by_pid(m, pid);
497 if (!u)
498 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Client not member of any unit.");
499 } else {
500 r = manager_load_unit(m, name, NULL, error, &u);
501 if (r < 0)
502 return r;
503 }
504
505 r = mac_selinux_unit_access_check(u, message, "status", error);
506 if (r < 0)
507 return r;
508
509 path = unit_dbus_path(u);
510 if (!path)
511 return -ENOMEM;
512
513 return sd_bus_reply_method_return(message, "o", path);
514 }
515
516 static int method_start_unit_generic(sd_bus_message *message, Manager *m, JobType job_type, bool reload_if_possible, sd_bus_error *error) {
517 const char *name;
518 Unit *u;
519 int r;
520
521 assert(message);
522 assert(m);
523
524 r = sd_bus_message_read(message, "s", &name);
525 if (r < 0)
526 return r;
527
528 r = manager_load_unit(m, name, NULL, error, &u);
529 if (r < 0)
530 return r;
531
532 return bus_unit_method_start_generic(message, u, job_type, reload_if_possible, error);
533 }
534
535 static int method_start_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
536 return method_start_unit_generic(message, userdata, JOB_START, false, error);
537 }
538
539 static int method_stop_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
540 return method_start_unit_generic(message, userdata, JOB_STOP, false, error);
541 }
542
543 static int method_reload_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
544 return method_start_unit_generic(message, userdata, JOB_RELOAD, false, error);
545 }
546
547 static int method_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
548 return method_start_unit_generic(message, userdata, JOB_RESTART, false, error);
549 }
550
551 static int method_try_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
552 return method_start_unit_generic(message, userdata, JOB_TRY_RESTART, false, error);
553 }
554
555 static int method_reload_or_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
556 return method_start_unit_generic(message, userdata, JOB_RESTART, true, error);
557 }
558
559 static int method_reload_or_try_restart_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
560 return method_start_unit_generic(message, userdata, JOB_TRY_RESTART, true, error);
561 }
562
563 static int method_start_unit_replace(sd_bus_message *message, void *userdata, sd_bus_error *error) {
564 Manager *m = userdata;
565 const char *old_name;
566 Unit *u;
567 int r;
568
569 assert(message);
570 assert(m);
571
572 r = sd_bus_message_read(message, "s", &old_name);
573 if (r < 0)
574 return r;
575
576 u = manager_get_unit(m, old_name);
577 if (!u || !u->job || u->job->type != JOB_START)
578 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
579
580 return method_start_unit_generic(message, m, JOB_START, false, error);
581 }
582
583 static int method_kill_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
584 Manager *m = userdata;
585 const char *name;
586 Unit *u;
587 int r;
588
589 assert(message);
590 assert(m);
591
592 r = sd_bus_message_read(message, "s", &name);
593 if (r < 0)
594 return r;
595
596 u = manager_get_unit(m, name);
597 if (!u)
598 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
599
600 return bus_unit_method_kill(message, u, error);
601 }
602
603 static int method_reset_failed_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
604 Manager *m = userdata;
605 const char *name;
606 Unit *u;
607 int r;
608
609 assert(message);
610 assert(m);
611
612 r = sd_bus_message_read(message, "s", &name);
613 if (r < 0)
614 return r;
615
616 u = manager_get_unit(m, name);
617 if (!u)
618 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
619
620 return bus_unit_method_reset_failed(message, u, error);
621 }
622
623 static int method_set_unit_properties(sd_bus_message *message, void *userdata, sd_bus_error *error) {
624 Manager *m = userdata;
625 const char *name;
626 Unit *u;
627 int r;
628
629 assert(message);
630 assert(m);
631
632 r = sd_bus_message_read(message, "s", &name);
633 if (r < 0)
634 return r;
635
636 r = manager_load_unit(m, name, NULL, error, &u);
637 if (r < 0)
638 return r;
639
640 r = bus_unit_check_load_state(u, error);
641 if (r < 0)
642 return r;
643
644 return bus_unit_method_set_properties(message, u, error);
645 }
646
647 static int transient_unit_from_message(
648 Manager *m,
649 sd_bus_message *message,
650 const char *name,
651 Unit **unit,
652 sd_bus_error *error) {
653
654 UnitType t;
655 Unit *u;
656 int r;
657
658 assert(m);
659 assert(message);
660 assert(name);
661
662 t = unit_name_to_type(name);
663 if (t < 0)
664 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit name or type.");
665
666 if (!unit_vtable[t]->can_transient)
667 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.", unit_type_to_string(t));
668
669 r = manager_load_unit(m, name, NULL, error, &u);
670 if (r < 0)
671 return r;
672
673 if (!unit_is_pristine(u))
674 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
675
676 /* OK, the unit failed to load and is unreferenced, now let's
677 * fill in the transient data instead */
678 r = unit_make_transient(u);
679 if (r < 0)
680 return r;
681
682 /* Set our properties */
683 r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
684 if (r < 0)
685 return r;
686
687 /* Now load the missing bits of the unit we just created */
688 manager_dispatch_load_queue(m);
689
690 *unit = u;
691
692 return 0;
693 }
694
695 static int transient_aux_units_from_message(
696 Manager *m,
697 sd_bus_message *message,
698 sd_bus_error *error) {
699
700 int r;
701
702 assert(m);
703 assert(message);
704
705 r = sd_bus_message_enter_container(message, 'a', "(sa(sv))");
706 if (r < 0)
707 return r;
708
709 while ((r = sd_bus_message_enter_container(message, 'r', "sa(sv)")) > 0) {
710 const char *name = NULL;
711 Unit *u;
712
713 r = sd_bus_message_read(message, "s", &name);
714 if (r < 0)
715 return r;
716
717 r = transient_unit_from_message(m, message, name, &u, error);
718 if (r < 0)
719 return r;
720
721 r = sd_bus_message_exit_container(message);
722 if (r < 0)
723 return r;
724 }
725 if (r < 0)
726 return r;
727
728 r = sd_bus_message_exit_container(message);
729 if (r < 0)
730 return r;
731
732 return 0;
733 }
734
735 static int method_start_transient_unit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
736 const char *name, *smode;
737 Manager *m = userdata;
738 JobMode mode;
739 Unit *u;
740 int r;
741
742 assert(message);
743 assert(m);
744
745 r = mac_selinux_access_check(message, "start", error);
746 if (r < 0)
747 return r;
748
749 r = sd_bus_message_read(message, "ss", &name, &smode);
750 if (r < 0)
751 return r;
752
753 mode = job_mode_from_string(smode);
754 if (mode < 0)
755 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
756
757 r = bus_verify_manage_units_async(m, message, error);
758 if (r < 0)
759 return r;
760 if (r == 0)
761 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
762
763 r = transient_unit_from_message(m, message, name, &u, error);
764 if (r < 0)
765 return r;
766
767 r = transient_aux_units_from_message(m, message, error);
768 if (r < 0)
769 return r;
770
771 /* Finally, start it */
772 return bus_unit_queue_job(message, u, JOB_START, mode, false, error);
773 }
774
775 static int method_get_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
776 _cleanup_free_ char *path = NULL;
777 Manager *m = userdata;
778 uint32_t id;
779 Job *j;
780 int r;
781
782 assert(message);
783 assert(m);
784
785 /* Anyone can call this method */
786
787 r = sd_bus_message_read(message, "u", &id);
788 if (r < 0)
789 return r;
790
791 j = manager_get_job(m, id);
792 if (!j)
793 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
794
795 r = mac_selinux_unit_access_check(j->unit, message, "status", error);
796 if (r < 0)
797 return r;
798
799 path = job_dbus_path(j);
800 if (!path)
801 return -ENOMEM;
802
803 return sd_bus_reply_method_return(message, "o", path);
804 }
805
806 static int method_cancel_job(sd_bus_message *message, void *userdata, sd_bus_error *error) {
807 Manager *m = userdata;
808 uint32_t id;
809 Job *j;
810 int r;
811
812 assert(message);
813 assert(m);
814
815 r = sd_bus_message_read(message, "u", &id);
816 if (r < 0)
817 return r;
818
819 j = manager_get_job(m, id);
820 if (!j)
821 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
822
823 return bus_job_method_cancel(message, j, error);
824 }
825
826 static int method_clear_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
827 Manager *m = userdata;
828 int r;
829
830 assert(message);
831 assert(m);
832
833 r = mac_selinux_access_check(message, "reload", error);
834 if (r < 0)
835 return r;
836
837 r = bus_verify_manage_units_async(m, message, error);
838 if (r < 0)
839 return r;
840 if (r == 0)
841 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
842
843 manager_clear_jobs(m);
844
845 return sd_bus_reply_method_return(message, NULL);
846 }
847
848 static int method_reset_failed(sd_bus_message *message, void *userdata, sd_bus_error *error) {
849 Manager *m = userdata;
850 int r;
851
852 assert(message);
853 assert(m);
854
855 r = mac_selinux_access_check(message, "reload", error);
856 if (r < 0)
857 return r;
858
859 r = bus_verify_manage_units_async(m, message, error);
860 if (r < 0)
861 return r;
862 if (r == 0)
863 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
864
865 manager_reset_failed(m);
866
867 return sd_bus_reply_method_return(message, NULL);
868 }
869
870 static int list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_error *error, char **states) {
871 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
872 Manager *m = userdata;
873 const char *k;
874 Iterator i;
875 Unit *u;
876 int r;
877
878 assert(message);
879 assert(m);
880
881 /* Anyone can call this method */
882
883 r = mac_selinux_access_check(message, "status", error);
884 if (r < 0)
885 return r;
886
887 r = sd_bus_message_new_method_return(message, &reply);
888 if (r < 0)
889 return r;
890
891 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
892 if (r < 0)
893 return r;
894
895 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
896 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
897 Unit *following;
898
899 if (k != u->id)
900 continue;
901
902 following = unit_following(u);
903
904 if (!strv_isempty(states) &&
905 !strv_contains(states, unit_load_state_to_string(u->load_state)) &&
906 !strv_contains(states, unit_active_state_to_string(unit_active_state(u))) &&
907 !strv_contains(states, unit_sub_state_to_string(u)))
908 continue;
909
910 unit_path = unit_dbus_path(u);
911 if (!unit_path)
912 return -ENOMEM;
913
914 if (u->job) {
915 job_path = job_dbus_path(u->job);
916 if (!job_path)
917 return -ENOMEM;
918 }
919
920 r = sd_bus_message_append(
921 reply, "(ssssssouso)",
922 u->id,
923 unit_description(u),
924 unit_load_state_to_string(u->load_state),
925 unit_active_state_to_string(unit_active_state(u)),
926 unit_sub_state_to_string(u),
927 following ? following->id : "",
928 unit_path,
929 u->job ? u->job->id : 0,
930 u->job ? job_type_to_string(u->job->type) : "",
931 job_path ? job_path : "/");
932 if (r < 0)
933 return r;
934 }
935
936 r = sd_bus_message_close_container(reply);
937 if (r < 0)
938 return r;
939
940 return sd_bus_send(NULL, reply, NULL);
941 }
942
943 static int method_list_units(sd_bus_message *message, void *userdata, sd_bus_error *error) {
944 return list_units_filtered(message, userdata, error, NULL);
945 }
946
947 static int method_list_units_filtered(sd_bus_message *message, void *userdata, sd_bus_error *error) {
948 _cleanup_strv_free_ char **states = NULL;
949 int r;
950
951 r = sd_bus_message_read_strv(message, &states);
952 if (r < 0)
953 return r;
954
955 return list_units_filtered(message, userdata, error, states);
956 }
957
958 static int method_list_jobs(sd_bus_message *message, void *userdata, sd_bus_error *error) {
959 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
960 Manager *m = userdata;
961 Iterator i;
962 Job *j;
963 int r;
964
965 assert(message);
966 assert(m);
967
968 /* Anyone can call this method */
969
970 r = mac_selinux_access_check(message, "status", error);
971 if (r < 0)
972 return r;
973
974 r = sd_bus_message_new_method_return(message, &reply);
975 if (r < 0)
976 return r;
977
978 r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
979 if (r < 0)
980 return r;
981
982 HASHMAP_FOREACH(j, m->jobs, i) {
983 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
984
985 job_path = job_dbus_path(j);
986 if (!job_path)
987 return -ENOMEM;
988
989 unit_path = unit_dbus_path(j->unit);
990 if (!unit_path)
991 return -ENOMEM;
992
993 r = sd_bus_message_append(
994 reply, "(usssoo)",
995 j->id,
996 j->unit->id,
997 job_type_to_string(j->type),
998 job_state_to_string(j->state),
999 job_path,
1000 unit_path);
1001 if (r < 0)
1002 return r;
1003 }
1004
1005 r = sd_bus_message_close_container(reply);
1006 if (r < 0)
1007 return r;
1008
1009 return sd_bus_send(NULL, reply, NULL);
1010 }
1011
1012 static int method_subscribe(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1013 Manager *m = userdata;
1014 int r;
1015
1016 assert(message);
1017 assert(m);
1018
1019 /* Anyone can call this method */
1020
1021 r = mac_selinux_access_check(message, "status", error);
1022 if (r < 0)
1023 return r;
1024
1025 if (sd_bus_message_get_bus(message) == m->api_bus) {
1026
1027 /* Note that direct bus connection subscribe by
1028 * default, we only track peers on the API bus here */
1029
1030 if (!m->subscribed) {
1031 r = sd_bus_track_new(sd_bus_message_get_bus(message), &m->subscribed, NULL, NULL);
1032 if (r < 0)
1033 return r;
1034 }
1035
1036 r = sd_bus_track_add_sender(m->subscribed, message);
1037 if (r < 0)
1038 return r;
1039 if (r == 0)
1040 return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
1041 }
1042
1043 return sd_bus_reply_method_return(message, NULL);
1044 }
1045
1046 static int method_unsubscribe(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1047 Manager *m = userdata;
1048 int r;
1049
1050 assert(message);
1051 assert(m);
1052
1053 /* Anyone can call this method */
1054
1055 r = mac_selinux_access_check(message, "status", error);
1056 if (r < 0)
1057 return r;
1058
1059 if (sd_bus_message_get_bus(message) == m->api_bus) {
1060 r = sd_bus_track_remove_sender(m->subscribed, message);
1061 if (r < 0)
1062 return r;
1063 if (r == 0)
1064 return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
1065 }
1066
1067 return sd_bus_reply_method_return(message, NULL);
1068 }
1069
1070 static int method_dump(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1071 _cleanup_free_ char *dump = NULL;
1072 _cleanup_fclose_ FILE *f = NULL;
1073 Manager *m = userdata;
1074 size_t size;
1075 int r;
1076
1077 assert(message);
1078 assert(m);
1079
1080 /* Anyone can call this method */
1081
1082 r = mac_selinux_access_check(message, "status", error);
1083 if (r < 0)
1084 return r;
1085
1086 f = open_memstream(&dump, &size);
1087 if (!f)
1088 return -ENOMEM;
1089
1090 manager_dump_units(m, f, NULL);
1091 manager_dump_jobs(m, f, NULL);
1092
1093 r = fflush_and_check(f);
1094 if (r < 0)
1095 return r;
1096
1097 return sd_bus_reply_method_return(message, "s", dump);
1098 }
1099
1100 static int method_refuse_snapshot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1101 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Support for snapshots has been removed.");
1102 }
1103
1104 static int method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1105 Manager *m = userdata;
1106 int r;
1107
1108 assert(message);
1109 assert(m);
1110
1111 r = mac_selinux_access_check(message, "reload", error);
1112 if (r < 0)
1113 return r;
1114
1115 r = bus_verify_reload_daemon_async(m, message, error);
1116 if (r < 0)
1117 return r;
1118 if (r == 0)
1119 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1120
1121 /* Instead of sending the reply back right away, we just
1122 * remember that we need to and then send it after the reload
1123 * is finished. That way the caller knows when the reload
1124 * finished. */
1125
1126 assert(!m->queued_message);
1127 r = sd_bus_message_new_method_return(message, &m->queued_message);
1128 if (r < 0)
1129 return r;
1130
1131 m->exit_code = MANAGER_RELOAD;
1132
1133 return 1;
1134 }
1135
1136 static int method_reexecute(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1137 Manager *m = userdata;
1138 int r;
1139
1140 assert(message);
1141 assert(m);
1142
1143 r = mac_selinux_access_check(message, "reload", error);
1144 if (r < 0)
1145 return r;
1146
1147 r = bus_verify_reload_daemon_async(m, message, error);
1148 if (r < 0)
1149 return r;
1150 if (r == 0)
1151 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1152
1153 /* We don't send a reply back here, the client should
1154 * just wait for us disconnecting. */
1155
1156 m->exit_code = MANAGER_REEXECUTE;
1157 return 1;
1158 }
1159
1160 static int method_exit(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1161 Manager *m = userdata;
1162 int r;
1163
1164 assert(message);
1165 assert(m);
1166
1167 r = mac_selinux_access_check(message, "halt", error);
1168 if (r < 0)
1169 return r;
1170
1171 /* Exit() (in contrast to SetExitCode()) is actually allowed even if
1172 * we are running on the host. It will fall back on reboot() in
1173 * systemd-shutdown if it cannot do the exit() because it isn't a
1174 * container. */
1175
1176 m->exit_code = MANAGER_EXIT;
1177
1178 return sd_bus_reply_method_return(message, NULL);
1179 }
1180
1181 static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1182 Manager *m = userdata;
1183 int r;
1184
1185 assert(message);
1186 assert(m);
1187
1188 r = mac_selinux_access_check(message, "reboot", error);
1189 if (r < 0)
1190 return r;
1191
1192 if (m->running_as != MANAGER_SYSTEM)
1193 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
1194
1195 m->exit_code = MANAGER_REBOOT;
1196
1197 return sd_bus_reply_method_return(message, NULL);
1198 }
1199
1200 static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1201 Manager *m = userdata;
1202 int r;
1203
1204 assert(message);
1205 assert(m);
1206
1207 r = mac_selinux_access_check(message, "halt", error);
1208 if (r < 0)
1209 return r;
1210
1211 if (m->running_as != MANAGER_SYSTEM)
1212 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
1213
1214 m->exit_code = MANAGER_POWEROFF;
1215
1216 return sd_bus_reply_method_return(message, NULL);
1217 }
1218
1219 static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1220 Manager *m = userdata;
1221 int r;
1222
1223 assert(message);
1224 assert(m);
1225
1226 r = mac_selinux_access_check(message, "halt", error);
1227 if (r < 0)
1228 return r;
1229
1230 if (m->running_as != MANAGER_SYSTEM)
1231 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
1232
1233 m->exit_code = MANAGER_HALT;
1234
1235 return sd_bus_reply_method_return(message, NULL);
1236 }
1237
1238 static int method_kexec(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1239 Manager *m = userdata;
1240 int r;
1241
1242 assert(message);
1243 assert(m);
1244
1245 r = mac_selinux_access_check(message, "reboot", error);
1246 if (r < 0)
1247 return r;
1248
1249 if (m->running_as != MANAGER_SYSTEM)
1250 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1251
1252 m->exit_code = MANAGER_KEXEC;
1253
1254 return sd_bus_reply_method_return(message, NULL);
1255 }
1256
1257 static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1258 char *ri = NULL, *rt = NULL;
1259 const char *root, *init;
1260 Manager *m = userdata;
1261 int r;
1262
1263 assert(message);
1264 assert(m);
1265
1266 r = mac_selinux_access_check(message, "reboot", error);
1267 if (r < 0)
1268 return r;
1269
1270 if (m->running_as != MANAGER_SYSTEM)
1271 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Root switching is only supported by system manager.");
1272
1273 r = sd_bus_message_read(message, "ss", &root, &init);
1274 if (r < 0)
1275 return r;
1276
1277 if (path_equal(root, "/") || !path_is_absolute(root))
1278 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
1279
1280 /* Safety check */
1281 if (isempty(init)) {
1282 if (!path_is_os_tree(root))
1283 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);
1284 } else {
1285 _cleanup_free_ char *p = NULL;
1286
1287 if (!path_is_absolute(init))
1288 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
1289
1290 p = strappend(root, init);
1291 if (!p)
1292 return -ENOMEM;
1293
1294 if (access(p, X_OK) < 0)
1295 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
1296 }
1297
1298 rt = strdup(root);
1299 if (!rt)
1300 return -ENOMEM;
1301
1302 if (!isempty(init)) {
1303 ri = strdup(init);
1304 if (!ri) {
1305 free(rt);
1306 return -ENOMEM;
1307 }
1308 }
1309
1310 free(m->switch_root);
1311 m->switch_root = rt;
1312
1313 free(m->switch_root_init);
1314 m->switch_root_init = ri;
1315
1316 m->exit_code = MANAGER_SWITCH_ROOT;
1317
1318 return sd_bus_reply_method_return(message, NULL);
1319 }
1320
1321 static int method_set_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1322 _cleanup_strv_free_ char **plus = NULL;
1323 Manager *m = userdata;
1324 int r;
1325
1326 assert(message);
1327 assert(m);
1328
1329 r = mac_selinux_access_check(message, "reload", error);
1330 if (r < 0)
1331 return r;
1332
1333 r = sd_bus_message_read_strv(message, &plus);
1334 if (r < 0)
1335 return r;
1336 if (!strv_env_is_valid(plus))
1337 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1338
1339 r = bus_verify_set_environment_async(m, message, error);
1340 if (r < 0)
1341 return r;
1342 if (r == 0)
1343 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1344
1345 r = manager_environment_add(m, NULL, plus);
1346 if (r < 0)
1347 return r;
1348
1349 return sd_bus_reply_method_return(message, NULL);
1350 }
1351
1352 static int method_unset_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1353 _cleanup_strv_free_ char **minus = NULL;
1354 Manager *m = userdata;
1355 int r;
1356
1357 assert(message);
1358 assert(m);
1359
1360 r = mac_selinux_access_check(message, "reload", error);
1361 if (r < 0)
1362 return r;
1363
1364 r = sd_bus_message_read_strv(message, &minus);
1365 if (r < 0)
1366 return r;
1367
1368 if (!strv_env_name_or_assignment_is_valid(minus))
1369 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1370
1371 r = bus_verify_set_environment_async(m, message, error);
1372 if (r < 0)
1373 return r;
1374 if (r == 0)
1375 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1376
1377 r = manager_environment_add(m, minus, NULL);
1378 if (r < 0)
1379 return r;
1380
1381 return sd_bus_reply_method_return(message, NULL);
1382 }
1383
1384 static int method_unset_and_set_environment(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1385 _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1386 Manager *m = userdata;
1387 int r;
1388
1389 assert(message);
1390 assert(m);
1391
1392 r = mac_selinux_access_check(message, "reload", error);
1393 if (r < 0)
1394 return r;
1395
1396 r = sd_bus_message_read_strv(message, &minus);
1397 if (r < 0)
1398 return r;
1399
1400 r = sd_bus_message_read_strv(message, &plus);
1401 if (r < 0)
1402 return r;
1403
1404 if (!strv_env_name_or_assignment_is_valid(minus))
1405 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1406 if (!strv_env_is_valid(plus))
1407 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1408
1409 r = bus_verify_set_environment_async(m, message, error);
1410 if (r < 0)
1411 return r;
1412 if (r == 0)
1413 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1414
1415 r = manager_environment_add(m, minus, plus);
1416 if (r < 0)
1417 return r;
1418
1419 return sd_bus_reply_method_return(message, NULL);
1420 }
1421
1422 static int method_set_exit_code(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1423 uint8_t code;
1424 Manager *m = userdata;
1425 int r;
1426
1427 assert(message);
1428 assert(m);
1429
1430 r = mac_selinux_access_check(message, "exit", error);
1431 if (r < 0)
1432 return r;
1433
1434 r = sd_bus_message_read_basic(message, 'y', &code);
1435 if (r < 0)
1436 return r;
1437
1438 if (m->running_as == MANAGER_SYSTEM && detect_container() <= 0)
1439 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "ExitCode can only be set for user service managers or in containers.");
1440
1441 m->return_value = code;
1442
1443 return sd_bus_reply_method_return(message, NULL);
1444 }
1445
1446 static int method_list_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1447 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1448 Manager *m = userdata;
1449 UnitFileList *item;
1450 Hashmap *h;
1451 Iterator i;
1452 int r;
1453
1454 assert(message);
1455 assert(m);
1456
1457 /* Anyone can call this method */
1458
1459 r = mac_selinux_access_check(message, "status", error);
1460 if (r < 0)
1461 return r;
1462
1463 r = sd_bus_message_new_method_return(message, &reply);
1464 if (r < 0)
1465 return r;
1466
1467 h = hashmap_new(&string_hash_ops);
1468 if (!h)
1469 return -ENOMEM;
1470
1471 r = unit_file_get_list(m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
1472 if (r < 0)
1473 goto fail;
1474
1475 r = sd_bus_message_open_container(reply, 'a', "(ss)");
1476 if (r < 0)
1477 goto fail;
1478
1479 HASHMAP_FOREACH(item, h, i) {
1480
1481 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
1482 if (r < 0)
1483 goto fail;
1484 }
1485
1486 unit_file_list_free(h);
1487
1488 r = sd_bus_message_close_container(reply);
1489 if (r < 0)
1490 return r;
1491
1492 return sd_bus_send(NULL, reply, NULL);
1493
1494 fail:
1495 unit_file_list_free(h);
1496 return r;
1497 }
1498
1499 static int method_get_unit_file_state(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1500 Manager *m = userdata;
1501 const char *name;
1502 UnitFileState state;
1503 UnitFileScope scope;
1504 int r;
1505
1506 assert(message);
1507 assert(m);
1508
1509 /* Anyone can call this method */
1510
1511 r = mac_selinux_access_check(message, "status", error);
1512 if (r < 0)
1513 return r;
1514
1515 r = sd_bus_message_read(message, "s", &name);
1516 if (r < 0)
1517 return r;
1518
1519 scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1520
1521 r = unit_file_get_state(scope, NULL, name, &state);
1522 if (r < 0)
1523 return r;
1524
1525 return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
1526 }
1527
1528 static int method_get_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1529 _cleanup_free_ char *default_target = NULL;
1530 Manager *m = userdata;
1531 UnitFileScope scope;
1532 int r;
1533
1534 assert(message);
1535 assert(m);
1536
1537 /* Anyone can call this method */
1538
1539 r = mac_selinux_access_check(message, "status", error);
1540 if (r < 0)
1541 return r;
1542
1543 scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1544
1545 r = unit_file_get_default(scope, NULL, &default_target);
1546 if (r < 0)
1547 return r;
1548
1549 return sd_bus_reply_method_return(message, "s", default_target);
1550 }
1551
1552 static int send_unit_files_changed(sd_bus *bus, void *userdata) {
1553 _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
1554 int r;
1555
1556 assert(bus);
1557
1558 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1559 if (r < 0)
1560 return r;
1561
1562 return sd_bus_send(bus, message, NULL);
1563 }
1564
1565 static int reply_unit_file_changes_and_free(
1566 Manager *m,
1567 sd_bus_message *message,
1568 int carries_install_info,
1569 UnitFileChange *changes,
1570 unsigned n_changes) {
1571
1572 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1573 unsigned i;
1574 int r;
1575
1576 if (n_changes > 0) {
1577 r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
1578 if (r < 0)
1579 log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m");
1580 }
1581
1582 r = sd_bus_message_new_method_return(message, &reply);
1583 if (r < 0)
1584 goto fail;
1585
1586 if (carries_install_info >= 0) {
1587 r = sd_bus_message_append(reply, "b", carries_install_info);
1588 if (r < 0)
1589 goto fail;
1590 }
1591
1592 r = sd_bus_message_open_container(reply, 'a', "(sss)");
1593 if (r < 0)
1594 goto fail;
1595
1596 for (i = 0; i < n_changes; i++) {
1597 r = sd_bus_message_append(
1598 reply, "(sss)",
1599 unit_file_change_type_to_string(changes[i].type),
1600 changes[i].path,
1601 changes[i].source);
1602 if (r < 0)
1603 goto fail;
1604 }
1605
1606 r = sd_bus_message_close_container(reply);
1607 if (r < 0)
1608 goto fail;
1609
1610 unit_file_changes_free(changes, n_changes);
1611 return sd_bus_send(NULL, reply, NULL);
1612
1613 fail:
1614 unit_file_changes_free(changes, n_changes);
1615 return r;
1616 }
1617
1618 static int method_enable_unit_files_generic(
1619 sd_bus_message *message,
1620 Manager *m,
1621 const char *verb,
1622 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
1623 bool carries_install_info,
1624 sd_bus_error *error) {
1625
1626 _cleanup_strv_free_ char **l = NULL;
1627 UnitFileChange *changes = NULL;
1628 unsigned n_changes = 0;
1629 UnitFileScope scope;
1630 int runtime, force, r;
1631
1632 assert(message);
1633 assert(m);
1634
1635 r = sd_bus_message_read_strv(message, &l);
1636 if (r < 0)
1637 return r;
1638
1639 r = sd_bus_message_read(message, "bb", &runtime, &force);
1640 if (r < 0)
1641 return r;
1642
1643 r = bus_verify_manage_unit_files_async(m, message, error);
1644 if (r < 0)
1645 return r;
1646 if (r == 0)
1647 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1648
1649 scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1650
1651 r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
1652 if (r == -ESHUTDOWN)
1653 return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked");
1654 if (r < 0)
1655 return r;
1656
1657 return reply_unit_file_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes);
1658 }
1659
1660 static int method_enable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1661 return method_enable_unit_files_generic(message, userdata, "enable", unit_file_enable, true, error);
1662 }
1663
1664 static int method_reenable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1665 return method_enable_unit_files_generic(message, userdata, "enable", unit_file_reenable, true, error);
1666 }
1667
1668 static int method_link_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1669 return method_enable_unit_files_generic(message, userdata, "enable", unit_file_link, false, error);
1670 }
1671
1672 static int unit_file_preset_without_mode(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes) {
1673 return unit_file_preset(scope, runtime, root_dir, files, UNIT_FILE_PRESET_FULL, force, changes, n_changes);
1674 }
1675
1676 static int method_preset_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1677 return method_enable_unit_files_generic(message, userdata, "enable", unit_file_preset_without_mode, true, error);
1678 }
1679
1680 static int method_mask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1681 return method_enable_unit_files_generic(message, userdata, "disable", unit_file_mask, false, error);
1682 }
1683
1684 static int method_preset_unit_files_with_mode(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1685
1686 _cleanup_strv_free_ char **l = NULL;
1687 UnitFileChange *changes = NULL;
1688 unsigned n_changes = 0;
1689 Manager *m = userdata;
1690 UnitFilePresetMode mm;
1691 UnitFileScope scope;
1692 int runtime, force, r;
1693 const char *mode;
1694
1695 assert(message);
1696 assert(m);
1697
1698 r = sd_bus_message_read_strv(message, &l);
1699 if (r < 0)
1700 return r;
1701
1702 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
1703 if (r < 0)
1704 return r;
1705
1706 if (isempty(mode))
1707 mm = UNIT_FILE_PRESET_FULL;
1708 else {
1709 mm = unit_file_preset_mode_from_string(mode);
1710 if (mm < 0)
1711 return -EINVAL;
1712 }
1713
1714 r = bus_verify_manage_unit_files_async(m, message, error);
1715 if (r < 0)
1716 return r;
1717 if (r == 0)
1718 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1719
1720 scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1721
1722 r = unit_file_preset(scope, runtime, NULL, l, mm, force, &changes, &n_changes);
1723 if (r < 0)
1724 return r;
1725
1726 return reply_unit_file_changes_and_free(m, message, r, changes, n_changes);
1727 }
1728
1729 static int method_disable_unit_files_generic(
1730 sd_bus_message *message,
1731 Manager *m, const
1732 char *verb,
1733 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
1734 sd_bus_error *error) {
1735
1736 _cleanup_strv_free_ char **l = NULL;
1737 UnitFileChange *changes = NULL;
1738 unsigned n_changes = 0;
1739 UnitFileScope scope;
1740 int r, runtime;
1741
1742 assert(message);
1743 assert(m);
1744
1745 r = sd_bus_message_read_strv(message, &l);
1746 if (r < 0)
1747 return r;
1748
1749 r = sd_bus_message_read(message, "b", &runtime);
1750 if (r < 0)
1751 return r;
1752
1753 scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1754
1755 r = bus_verify_manage_unit_files_async(m, message, error);
1756 if (r < 0)
1757 return r;
1758 if (r == 0)
1759 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1760
1761 r = call(scope, runtime, NULL, l, &changes, &n_changes);
1762 if (r < 0)
1763 return r;
1764
1765 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
1766 }
1767
1768 static int method_disable_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1769 return method_disable_unit_files_generic(message, userdata, "disable", unit_file_disable, error);
1770 }
1771
1772 static int method_unmask_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1773 return method_disable_unit_files_generic(message, userdata, "enable", unit_file_unmask, error);
1774 }
1775
1776 static int method_set_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1777 UnitFileChange *changes = NULL;
1778 unsigned n_changes = 0;
1779 Manager *m = userdata;
1780 UnitFileScope scope;
1781 const char *name;
1782 int force, r;
1783
1784 assert(message);
1785 assert(m);
1786
1787 r = mac_selinux_access_check(message, "enable", error);
1788 if (r < 0)
1789 return r;
1790
1791 r = sd_bus_message_read(message, "sb", &name, &force);
1792 if (r < 0)
1793 return r;
1794
1795 r = bus_verify_manage_unit_files_async(m, message, error);
1796 if (r < 0)
1797 return r;
1798 if (r == 0)
1799 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1800
1801 scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1802
1803 r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
1804 if (r < 0)
1805 return r;
1806
1807 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
1808 }
1809
1810 static int method_preset_all_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1811 UnitFileChange *changes = NULL;
1812 unsigned n_changes = 0;
1813 Manager *m = userdata;
1814 UnitFilePresetMode mm;
1815 UnitFileScope scope;
1816 const char *mode;
1817 int force, runtime, r;
1818
1819 assert(message);
1820 assert(m);
1821
1822 r = mac_selinux_access_check(message, "enable", error);
1823 if (r < 0)
1824 return r;
1825
1826 r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
1827 if (r < 0)
1828 return r;
1829
1830 if (isempty(mode))
1831 mm = UNIT_FILE_PRESET_FULL;
1832 else {
1833 mm = unit_file_preset_mode_from_string(mode);
1834 if (mm < 0)
1835 return -EINVAL;
1836 }
1837
1838 r = bus_verify_manage_unit_files_async(m, message, error);
1839 if (r < 0)
1840 return r;
1841 if (r == 0)
1842 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1843
1844 scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1845
1846 r = unit_file_preset_all(scope, runtime, NULL, mm, force, &changes, &n_changes);
1847 if (r < 0) {
1848 unit_file_changes_free(changes, n_changes);
1849 return r;
1850 }
1851
1852 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
1853 }
1854
1855 static int method_add_dependency_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) {
1856 _cleanup_strv_free_ char **l = NULL;
1857 Manager *m = userdata;
1858 UnitFileChange *changes = NULL;
1859 unsigned n_changes = 0;
1860 UnitFileScope scope;
1861 int runtime, force, r;
1862 char *target;
1863 char *type;
1864 UnitDependency dep;
1865
1866 assert(message);
1867 assert(m);
1868
1869 r = bus_verify_manage_unit_files_async(m, message, error);
1870 if (r < 0)
1871 return r;
1872 if (r == 0)
1873 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1874
1875 r = sd_bus_message_read_strv(message, &l);
1876 if (r < 0)
1877 return r;
1878
1879 r = sd_bus_message_read(message, "ssbb", &target, &type, &runtime, &force);
1880 if (r < 0)
1881 return r;
1882
1883 dep = unit_dependency_from_string(type);
1884 if (dep < 0)
1885 return -EINVAL;
1886
1887 scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1888
1889 r = unit_file_add_dependency(scope, runtime, NULL, l, target, dep, force, &changes, &n_changes);
1890 if (r == -ESHUTDOWN)
1891 return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked");
1892 if (r < 0)
1893 return r;
1894
1895 return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes);
1896 }
1897
1898 const sd_bus_vtable bus_manager_vtable[] = {
1899 SD_BUS_VTABLE_START(0),
1900
1901 SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1902 SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1903 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1904 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1905 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1906 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1907 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1908 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1909 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1910 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1911 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1912 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1913 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1914 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1915 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1916 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1917 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1918 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
1919 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
1920 SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
1921 SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1922 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
1923 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
1924 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
1925 SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
1926 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
1927 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
1928 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
1929 SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), SD_BUS_VTABLE_PROPERTY_CONST),
1930 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1931 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1932 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
1933 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
1934 SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
1935 SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
1936 SD_BUS_PROPERTY("ExitCode", "y", bus_property_get_unsigned, offsetof(Manager, return_value), 0),
1937 SD_BUS_PROPERTY("DefaultTimerAccuracyUSec", "t", bus_property_get_usec, offsetof(Manager, default_timer_accuracy_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1938 SD_BUS_PROPERTY("DefaultTimeoutStartUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_start_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1939 SD_BUS_PROPERTY("DefaultTimeoutStopUSec", "t", bus_property_get_usec, offsetof(Manager, default_timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1940 SD_BUS_PROPERTY("DefaultRestartUSec", "t", bus_property_get_usec, offsetof(Manager, default_restart_usec), SD_BUS_VTABLE_PROPERTY_CONST),
1941 SD_BUS_PROPERTY("DefaultStartLimitInterval", "t", bus_property_get_usec, offsetof(Manager, default_start_limit_interval), SD_BUS_VTABLE_PROPERTY_CONST),
1942 SD_BUS_PROPERTY("DefaultStartLimitBurst", "u", bus_property_get_unsigned, offsetof(Manager, default_start_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST),
1943 SD_BUS_PROPERTY("DefaultCPUAccounting", "b", bus_property_get_bool, offsetof(Manager, default_cpu_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
1944 SD_BUS_PROPERTY("DefaultBlockIOAccounting", "b", bus_property_get_bool, offsetof(Manager, default_blockio_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
1945 SD_BUS_PROPERTY("DefaultMemoryAccounting", "b", bus_property_get_bool, offsetof(Manager, default_memory_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
1946 SD_BUS_PROPERTY("DefaultTasksAccounting", "b", bus_property_get_bool, offsetof(Manager, default_tasks_accounting), SD_BUS_VTABLE_PROPERTY_CONST),
1947 SD_BUS_PROPERTY("DefaultLimitCPU", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
1948 SD_BUS_PROPERTY("DefaultLimitCPUSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CPU]), SD_BUS_VTABLE_PROPERTY_CONST),
1949 SD_BUS_PROPERTY("DefaultLimitFSIZE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
1950 SD_BUS_PROPERTY("DefaultLimitFSIZESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_FSIZE]), SD_BUS_VTABLE_PROPERTY_CONST),
1951 SD_BUS_PROPERTY("DefaultLimitDATA", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
1952 SD_BUS_PROPERTY("DefaultLimitDATASoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_DATA]), SD_BUS_VTABLE_PROPERTY_CONST),
1953 SD_BUS_PROPERTY("DefaultLimitSTACK", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
1954 SD_BUS_PROPERTY("DefaultLimitSTACKSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_STACK]), SD_BUS_VTABLE_PROPERTY_CONST),
1955 SD_BUS_PROPERTY("DefaultLimitCORE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
1956 SD_BUS_PROPERTY("DefaultLimitCORESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_CORE]), SD_BUS_VTABLE_PROPERTY_CONST),
1957 SD_BUS_PROPERTY("DefaultLimitRSS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
1958 SD_BUS_PROPERTY("DefaultLimitRSSSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RSS]), SD_BUS_VTABLE_PROPERTY_CONST),
1959 SD_BUS_PROPERTY("DefaultLimitNOFILE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
1960 SD_BUS_PROPERTY("DefaultLimitNOFILESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NOFILE]), SD_BUS_VTABLE_PROPERTY_CONST),
1961 SD_BUS_PROPERTY("DefaultLimitAS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
1962 SD_BUS_PROPERTY("DefaultLimitASSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_AS]), SD_BUS_VTABLE_PROPERTY_CONST),
1963 SD_BUS_PROPERTY("DefaultLimitNPROC", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
1964 SD_BUS_PROPERTY("DefaultLimitNPROCSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NPROC]), SD_BUS_VTABLE_PROPERTY_CONST),
1965 SD_BUS_PROPERTY("DefaultLimitMEMLOCK", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
1966 SD_BUS_PROPERTY("DefaultLimitMEMLOCKSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MEMLOCK]), SD_BUS_VTABLE_PROPERTY_CONST),
1967 SD_BUS_PROPERTY("DefaultLimitLOCKS", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
1968 SD_BUS_PROPERTY("DefaultLimitLOCKSSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_LOCKS]), SD_BUS_VTABLE_PROPERTY_CONST),
1969 SD_BUS_PROPERTY("DefaultLimitSIGPENDING", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
1970 SD_BUS_PROPERTY("DefaultLimitSIGPENDINGSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_SIGPENDING]), SD_BUS_VTABLE_PROPERTY_CONST),
1971 SD_BUS_PROPERTY("DefaultLimitMSGQUEUE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
1972 SD_BUS_PROPERTY("DefaultLimitMSGQUEUESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_MSGQUEUE]), SD_BUS_VTABLE_PROPERTY_CONST),
1973 SD_BUS_PROPERTY("DefaultLimitNICE", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
1974 SD_BUS_PROPERTY("DefaultLimitNICESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_NICE]), SD_BUS_VTABLE_PROPERTY_CONST),
1975 SD_BUS_PROPERTY("DefaultLimitRTPRIO", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
1976 SD_BUS_PROPERTY("DefaultLimitRTPRIOSoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTPRIO]), SD_BUS_VTABLE_PROPERTY_CONST),
1977 SD_BUS_PROPERTY("DefaultLimitRTTIME", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
1978 SD_BUS_PROPERTY("DefaultLimitRTTIMESoft", "t", bus_property_get_rlimit, offsetof(Manager, rlimit[RLIMIT_RTTIME]), SD_BUS_VTABLE_PROPERTY_CONST),
1979 SD_BUS_PROPERTY("DefaultTasksMax", "t", NULL, offsetof(Manager, default_tasks_max), SD_BUS_VTABLE_PROPERTY_CONST),
1980 SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1981
1982 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1983 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1984 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1985 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1986 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, SD_BUS_VTABLE_UNPRIVILEGED),
1987 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1988 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1989 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1990 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1991 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1992 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1993 SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1994 SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1995 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, SD_BUS_VTABLE_UNPRIVILEGED),
1996 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1997 SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
1998 SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, SD_BUS_VTABLE_UNPRIVILEGED),
1999 SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
2000 SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, SD_BUS_VTABLE_UNPRIVILEGED),
2001 SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
2002 SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered, SD_BUS_VTABLE_UNPRIVILEGED),
2003 SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
2004 SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
2005 SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
2006 SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
2007 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_refuse_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
2008 SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_refuse_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
2009 SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
2010 SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, SD_BUS_VTABLE_UNPRIVILEGED),
2011 SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
2012 SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2013 SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2014 SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2015 SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2016 SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2017 SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2018 SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2019 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2020 SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2021 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
2022 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2023 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2024 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2025 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2026 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2027 SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, SD_BUS_VTABLE_UNPRIVILEGED),
2028 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2029 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2030 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
2031 SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
2032 SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2033 SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2034 SD_BUS_METHOD("SetExitCode", "y", NULL, method_set_exit_code, SD_BUS_VTABLE_UNPRIVILEGED),
2035
2036 SD_BUS_SIGNAL("UnitNew", "so", 0),
2037 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
2038 SD_BUS_SIGNAL("JobNew", "uos", 0),
2039 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
2040 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
2041 SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
2042 SD_BUS_SIGNAL("Reloading", "b", 0),
2043
2044 SD_BUS_VTABLE_END
2045 };
2046
2047 static int send_finished(sd_bus *bus, void *userdata) {
2048 _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
2049 usec_t *times = userdata;
2050 int r;
2051
2052 assert(bus);
2053 assert(times);
2054
2055 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
2056 if (r < 0)
2057 return r;
2058
2059 r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
2060 if (r < 0)
2061 return r;
2062
2063 return sd_bus_send(bus, message, NULL);
2064 }
2065
2066 void bus_manager_send_finished(
2067 Manager *m,
2068 usec_t firmware_usec,
2069 usec_t loader_usec,
2070 usec_t kernel_usec,
2071 usec_t initrd_usec,
2072 usec_t userspace_usec,
2073 usec_t total_usec) {
2074
2075 int r;
2076
2077 assert(m);
2078
2079 r = bus_foreach_bus(
2080 m,
2081 NULL,
2082 send_finished,
2083 (usec_t[6]) {
2084 firmware_usec,
2085 loader_usec,
2086 kernel_usec,
2087 initrd_usec,
2088 userspace_usec,
2089 total_usec
2090 });
2091 if (r < 0)
2092 log_debug_errno(r, "Failed to send finished signal: %m");
2093 }
2094
2095 static int send_reloading(sd_bus *bus, void *userdata) {
2096 _cleanup_(sd_bus_message_unrefp) sd_bus_message *message = NULL;
2097 int r;
2098
2099 assert(bus);
2100
2101 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
2102 if (r < 0)
2103 return r;
2104
2105 r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
2106 if (r < 0)
2107 return r;
2108
2109 return sd_bus_send(bus, message, NULL);
2110 }
2111
2112 void bus_manager_send_reloading(Manager *m, bool active) {
2113 int r;
2114
2115 assert(m);
2116
2117 r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
2118 if (r < 0)
2119 log_debug_errno(r, "Failed to send reloading signal: %m");
2120 }
2121
2122 static int send_changed_signal(sd_bus *bus, void *userdata) {
2123 assert(bus);
2124
2125 return sd_bus_emit_properties_changed_strv(bus,
2126 "/org/freedesktop/systemd1",
2127 "org.freedesktop.systemd1.Manager",
2128 NULL);
2129 }
2130
2131 void bus_manager_send_change_signal(Manager *m) {
2132 int r;
2133
2134 assert(m);
2135
2136 r = bus_foreach_bus(m, NULL, send_changed_signal, NULL);
2137 if (r < 0)
2138 log_debug_errno(r, "Failed to send manager change signal: %m");
2139 }