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