]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/dbus-manager.c
core: Filter by state behind the D-Bus API, not in the systemctl client.
[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 <unistd.h>
24
25 #include "log.h"
26 #include "strv.h"
27 #include "build.h"
28 #include "install.h"
29 #include "selinux-access.h"
30 #include "watchdog.h"
31 #include "hwclock.h"
32 #include "path-util.h"
33 #include "virt.h"
34 #include "architecture.h"
35 #include "env-util.h"
36 #include "dbus.h"
37 #include "dbus-manager.h"
38 #include "dbus-unit.h"
39 #include "dbus-snapshot.h"
40 #include "dbus-execute.h"
41 #include "bus-errors.h"
42
43 static int property_get_version(
44 sd_bus *bus,
45 const char *path,
46 const char *interface,
47 const char *property,
48 sd_bus_message *reply,
49 void *userdata,
50 sd_bus_error *error) {
51
52 assert(bus);
53 assert(reply);
54
55 return sd_bus_message_append(reply, "s", PACKAGE_VERSION);
56 }
57
58 static int property_get_features(
59 sd_bus *bus,
60 const char *path,
61 const char *interface,
62 const char *property,
63 sd_bus_message *reply,
64 void *userdata,
65 sd_bus_error *error) {
66
67 assert(bus);
68 assert(reply);
69
70 return sd_bus_message_append(reply, "s", SYSTEMD_FEATURES);
71 }
72
73 static int property_get_virtualization(
74 sd_bus *bus,
75 const char *path,
76 const char *interface,
77 const char *property,
78 sd_bus_message *reply,
79 void *userdata,
80 sd_bus_error *error) {
81
82 const char *id = NULL;
83
84 assert(bus);
85 assert(reply);
86
87 detect_virtualization(&id);
88
89 return sd_bus_message_append(reply, "s", id);
90 }
91
92 static int property_get_architecture(
93 sd_bus *bus,
94 const char *path,
95 const char *interface,
96 const char *property,
97 sd_bus_message *reply,
98 void *userdata,
99 sd_bus_error *error) {
100
101 assert(bus);
102 assert(reply);
103
104 return sd_bus_message_append(reply, "s", architecture_to_string(uname_architecture()));
105 }
106
107 static int property_get_tainted(
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 char buf[sizeof("split-usr:mtab-not-symlink:cgroups-missing:local-hwclock:")] = "", *e = buf;
117 _cleanup_free_ char *p = NULL;
118 Manager *m = userdata;
119
120 assert(bus);
121 assert(reply);
122 assert(m);
123
124 if (m->taint_usr)
125 e = stpcpy(e, "split-usr:");
126
127 if (readlink_malloc("/etc/mtab", &p) < 0)
128 e = stpcpy(e, "mtab-not-symlink:");
129
130 if (access("/proc/cgroups", F_OK) < 0)
131 e = stpcpy(e, "cgroups-missing:");
132
133 if (hwclock_is_localtime() > 0)
134 e = stpcpy(e, "local-hwclock:");
135
136 /* remove the last ':' */
137 if (e != buf)
138 e[-1] = 0;
139
140 return sd_bus_message_append(reply, "s", buf);
141 }
142
143 static int property_get_log_target(
144 sd_bus *bus,
145 const char *path,
146 const char *interface,
147 const char *property,
148 sd_bus_message *reply,
149 void *userdata,
150 sd_bus_error *error) {
151
152 assert(bus);
153 assert(reply);
154
155 return sd_bus_message_append(reply, "s", log_target_to_string(log_get_target()));
156 }
157
158 static int property_set_log_target(
159 sd_bus *bus,
160 const char *path,
161 const char *interface,
162 const char *property,
163 sd_bus_message *value,
164 void *userdata,
165 sd_bus_error *error) {
166
167 const char *t;
168 int r;
169
170 assert(bus);
171 assert(value);
172
173 r = sd_bus_message_read(value, "s", &t);
174 if (r < 0)
175 return r;
176
177 return log_set_target_from_string(t);
178 }
179
180 static int property_get_log_level(
181 sd_bus *bus,
182 const char *path,
183 const char *interface,
184 const char *property,
185 sd_bus_message *reply,
186 void *userdata,
187 sd_bus_error *error) {
188
189 _cleanup_free_ char *t = NULL;
190 int r;
191
192 assert(bus);
193 assert(reply);
194
195 r = log_level_to_string_alloc(log_get_max_level(), &t);
196 if (r < 0)
197 return r;
198
199 return sd_bus_message_append(reply, "s", t);
200 }
201
202 static int property_set_log_level(
203 sd_bus *bus,
204 const char *path,
205 const char *interface,
206 const char *property,
207 sd_bus_message *value,
208 void *userdata,
209 sd_bus_error *error) {
210
211 const char *t;
212 int r;
213
214 assert(bus);
215 assert(value);
216
217 r = sd_bus_message_read(value, "s", &t);
218 if (r < 0)
219 return r;
220
221 return log_set_max_level_from_string(t);
222 }
223
224 static int property_get_n_names(
225 sd_bus *bus,
226 const char *path,
227 const char *interface,
228 const char *property,
229 sd_bus_message *reply,
230 void *userdata,
231 sd_bus_error *error) {
232
233 Manager *m = userdata;
234
235 assert(bus);
236 assert(reply);
237 assert(m);
238
239 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->units));
240 }
241
242 static int property_get_n_failed_units(
243 sd_bus *bus,
244 const char *path,
245 const char *interface,
246 const char *property,
247 sd_bus_message *reply,
248 void *userdata,
249 sd_bus_error *error) {
250
251 Manager *m = userdata;
252
253 assert(bus);
254 assert(reply);
255 assert(m);
256
257 return sd_bus_message_append(reply, "u", (uint32_t) set_size(m->failed_units));
258 }
259
260 static int property_get_n_jobs(
261 sd_bus *bus,
262 const char *path,
263 const char *interface,
264 const char *property,
265 sd_bus_message *reply,
266 void *userdata,
267 sd_bus_error *error) {
268
269 Manager *m = userdata;
270
271 assert(bus);
272 assert(reply);
273 assert(m);
274
275 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->jobs));
276 }
277
278 static int property_get_progress(
279 sd_bus *bus,
280 const char *path,
281 const char *interface,
282 const char *property,
283 sd_bus_message *reply,
284 void *userdata,
285 sd_bus_error *error) {
286
287 Manager *m = userdata;
288 double d;
289
290 assert(bus);
291 assert(reply);
292 assert(m);
293
294 if (dual_timestamp_is_set(&m->finish_timestamp))
295 d = 1.0;
296 else
297 d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
298
299 return sd_bus_message_append(reply, "d", d);
300 }
301
302 static int property_get_system_state(
303 sd_bus *bus,
304 const char *path,
305 const char *interface,
306 const char *property,
307 sd_bus_message *reply,
308 void *userdata,
309 sd_bus_error *error) {
310
311 Manager *m = userdata;
312
313 assert(bus);
314 assert(reply);
315 assert(m);
316
317 return sd_bus_message_append(reply, "s", manager_state_to_string(manager_state(m)));
318 }
319
320 static int property_set_runtime_watchdog(
321 sd_bus *bus,
322 const char *path,
323 const char *interface,
324 const char *property,
325 sd_bus_message *value,
326 void *userdata,
327 sd_bus_error *error) {
328
329 usec_t *t = userdata;
330 int r;
331
332 assert(bus);
333 assert(value);
334
335 assert_cc(sizeof(usec_t) == sizeof(uint64_t));
336
337 r = sd_bus_message_read(value, "t", t);
338 if (r < 0)
339 return r;
340
341 return watchdog_set_timeout(t);
342 }
343
344 static int method_get_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
345 _cleanup_free_ char *path = NULL;
346 Manager *m = userdata;
347 const char *name;
348 Unit *u;
349 int r;
350
351 assert(bus);
352 assert(message);
353 assert(m);
354
355 r = sd_bus_message_read(message, "s", &name);
356 if (r < 0)
357 return r;
358
359 u = manager_get_unit(m, name);
360 if (!u)
361 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
362
363 r = selinux_unit_access_check(u, message, "status", error);
364 if (r < 0)
365 return r;
366
367 path = unit_dbus_path(u);
368 if (!path)
369 return -ENOMEM;
370
371 return sd_bus_reply_method_return(message, "o", path);
372 }
373
374 static int method_get_unit_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
375 _cleanup_free_ char *path = NULL;
376 Manager *m = userdata;
377 pid_t pid;
378 Unit *u;
379 int r;
380
381 assert(bus);
382 assert(message);
383 assert(m);
384
385 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
386
387 r = sd_bus_message_read(message, "u", &pid);
388 if (r < 0)
389 return r;
390
391 if (pid == 0) {
392 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
393
394 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
395 if (r < 0)
396 return r;
397
398 r = sd_bus_creds_get_pid(creds, &pid);
399 if (r < 0)
400 return r;
401 }
402
403 u = manager_get_unit_by_pid(m, pid);
404 if (!u)
405 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID %u does not belong to any loaded unit.", pid);
406
407 r = selinux_unit_access_check(u, message, "status", error);
408 if (r < 0)
409 return r;
410
411 path = unit_dbus_path(u);
412 if (!path)
413 return -ENOMEM;
414
415 return sd_bus_reply_method_return(message, "o", path);
416 }
417
418 static int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
419 _cleanup_free_ char *path = NULL;
420 Manager *m = userdata;
421 const char *name;
422 Unit *u;
423 int r;
424
425 assert(bus);
426 assert(message);
427 assert(m);
428
429 r = sd_bus_message_read(message, "s", &name);
430 if (r < 0)
431 return r;
432
433 r = manager_load_unit(m, name, NULL, error, &u);
434 if (r < 0)
435 return r;
436
437 r = selinux_unit_access_check(u, message, "status", error);
438 if (r < 0)
439 return r;
440
441 path = unit_dbus_path(u);
442 if (!path)
443 return -ENOMEM;
444
445 return sd_bus_reply_method_return(message, "o", path);
446 }
447
448 static int method_start_unit_generic(sd_bus *bus, sd_bus_message *message, Manager *m, JobType job_type, bool reload_if_possible, sd_bus_error *error) {
449 const char *name;
450 Unit *u;
451 int r;
452
453 assert(bus);
454 assert(message);
455 assert(m);
456
457 r = sd_bus_message_read(message, "s", &name);
458 if (r < 0)
459 return r;
460
461 r = manager_load_unit(m, name, NULL, error, &u);
462 if (r < 0)
463 return r;
464
465 return bus_unit_method_start_generic(bus, message, u, job_type, reload_if_possible, error);
466 }
467
468 static int method_start_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
469 return method_start_unit_generic(bus, message, userdata, JOB_START, false, error);
470 }
471
472 static int method_stop_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
473 return method_start_unit_generic(bus, message, userdata, JOB_STOP, false, error);
474 }
475
476 static int method_reload_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
477 return method_start_unit_generic(bus, message, userdata, JOB_RELOAD, false, error);
478 }
479
480 static int method_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
481 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, false, error);
482 }
483
484 static int method_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
485 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, false, error);
486 }
487
488 static int method_reload_or_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
489 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, true, error);
490 }
491
492 static int method_reload_or_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
493 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, true, error);
494 }
495
496 static int method_start_unit_replace(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
497 Manager *m = userdata;
498 const char *old_name;
499 Unit *u;
500 int r;
501
502 assert(bus);
503 assert(message);
504 assert(m);
505
506 r = sd_bus_message_read(message, "s", &old_name);
507 if (r < 0)
508 return r;
509
510 u = manager_get_unit(m, old_name);
511 if (!u || !u->job || u->job->type != JOB_START)
512 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
513
514 return method_start_unit_generic(bus, message, m, JOB_START, false, error);
515 }
516
517 static int method_kill_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
518 Manager *m = userdata;
519 const char *name;
520 Unit *u;
521 int r;
522
523 assert(bus);
524 assert(message);
525 assert(m);
526
527 r = sd_bus_message_read(message, "s", &name);
528 if (r < 0)
529 return r;
530
531 u = manager_get_unit(m, name);
532 if (!u)
533 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
534
535 return bus_unit_method_kill(bus, message, u, error);
536 }
537
538 static int method_reset_failed_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
539 Manager *m = userdata;
540 const char *name;
541 Unit *u;
542 int r;
543
544 assert(bus);
545 assert(message);
546 assert(m);
547
548 r = sd_bus_message_read(message, "s", &name);
549 if (r < 0)
550 return r;
551
552 u = manager_get_unit(m, name);
553 if (!u)
554 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
555
556 return bus_unit_method_reset_failed(bus, message, u, error);
557 }
558
559 static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
560 Manager *m = userdata;
561 const char *name;
562 Unit *u;
563 int r;
564
565 assert(bus);
566 assert(message);
567 assert(m);
568
569 r = sd_bus_message_read(message, "s", &name);
570 if (r < 0)
571 return r;
572
573 u = manager_get_unit(m, name);
574 if (!u)
575 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
576
577 return bus_unit_method_set_properties(bus, message, u, error);
578 }
579
580 static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
581 const char *name, *smode;
582 Manager *m = userdata;
583 JobMode mode;
584 UnitType t;
585 Unit *u;
586 int r;
587
588 assert(bus);
589 assert(message);
590 assert(m);
591
592 r = sd_bus_message_read(message, "ss", &name, &smode);
593 if (r < 0)
594 return r;
595
596 t = unit_name_to_type(name);
597 if (t < 0)
598 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit type.");
599
600 if (!unit_vtable[t]->can_transient)
601 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.", unit_type_to_string(t));
602
603 mode = job_mode_from_string(smode);
604 if (mode < 0)
605 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
606
607 r = selinux_access_check(message, "start", error);
608 if (r < 0)
609 return r;
610
611 r = manager_load_unit(m, name, NULL, error, &u);
612 if (r < 0)
613 return r;
614
615 if (u->load_state != UNIT_NOT_FOUND || set_size(u->dependencies[UNIT_REFERENCED_BY]) > 0)
616 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
617
618 /* OK, the unit failed to load and is unreferenced, now let's
619 * fill in the transient data instead */
620 r = unit_make_transient(u);
621 if (r < 0)
622 return r;
623
624 /* Set our properties */
625 r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
626 if (r < 0)
627 return r;
628
629 /* And load this stub fully */
630 r = unit_load(u);
631 if (r < 0)
632 return r;
633
634 manager_dispatch_load_queue(m);
635
636 /* Finally, start it */
637 return bus_unit_queue_job(bus, message, u, JOB_START, mode, false, error);
638 }
639
640 static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
641 _cleanup_free_ char *path = NULL;
642 Manager *m = userdata;
643 uint32_t id;
644 Job *j;
645 int r;
646
647 assert(bus);
648 assert(message);
649 assert(m);
650
651 r = sd_bus_message_read(message, "u", &id);
652 if (r < 0)
653 return r;
654
655 j = manager_get_job(m, id);
656 if (!j)
657 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
658
659 r = selinux_unit_access_check(j->unit, message, "status", error);
660 if (r < 0)
661 return r;
662
663 path = job_dbus_path(j);
664 if (!path)
665 return -ENOMEM;
666
667 return sd_bus_reply_method_return(message, "o", path);
668 }
669
670 static int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
671 Manager *m = userdata;
672 uint32_t id;
673 Job *j;
674 int r;
675
676 assert(bus);
677 assert(message);
678 assert(m);
679
680 r = sd_bus_message_read(message, "u", &id);
681 if (r < 0)
682 return r;
683
684 j = manager_get_job(m, id);
685 if (!j)
686 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
687
688 r = selinux_unit_access_check(j->unit, message, "stop", error);
689 if (r < 0)
690 return r;
691
692 job_finish_and_invalidate(j, JOB_CANCELED, true);
693
694 return sd_bus_reply_method_return(message, NULL);
695 }
696
697 static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
698 Manager *m = userdata;
699 int r;
700
701 assert(bus);
702 assert(message);
703 assert(m);
704
705 r = selinux_access_check(message, "reboot", error);
706 if (r < 0)
707 return r;
708
709 manager_clear_jobs(m);
710
711 return sd_bus_reply_method_return(message, NULL);
712 }
713
714 static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
715 Manager *m = userdata;
716 int r;
717
718 assert(bus);
719 assert(message);
720 assert(m);
721
722 r = selinux_access_check(message, "reload", error);
723 if (r < 0)
724 return r;
725
726 manager_reset_failed(m);
727
728 return sd_bus_reply_method_return(message, NULL);
729 }
730
731 static int list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error, char **states) {
732 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
733 Manager *m = userdata;
734 const char *k;
735 Iterator i;
736 Unit *u;
737 int r;
738
739 assert(bus);
740 assert(message);
741 assert(m);
742
743 r = selinux_access_check(message, "status", error);
744 if (r < 0)
745 return r;
746
747 r = sd_bus_message_new_method_return(message, &reply);
748 if (r < 0)
749 return r;
750
751 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
752 if (r < 0)
753 return r;
754
755 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
756 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
757 Unit *following;
758
759 if (k != u->id)
760 continue;
761
762 following = unit_following(u);
763
764 if (!strv_isempty(states) &&
765 !strv_contains(states, unit_load_state_to_string(u->load_state)) &&
766 !strv_contains(states, unit_active_state_to_string(unit_active_state(u))) &&
767 !strv_contains(states, unit_sub_state_to_string(u)))
768 continue;
769
770 unit_path = unit_dbus_path(u);
771 if (!unit_path)
772 return -ENOMEM;
773
774 if (u->job) {
775 job_path = job_dbus_path(u->job);
776 if (!job_path)
777 return -ENOMEM;
778 }
779
780 r = sd_bus_message_append(
781 reply, "(ssssssouso)",
782 u->id,
783 unit_description(u),
784 unit_load_state_to_string(u->load_state),
785 unit_active_state_to_string(unit_active_state(u)),
786 unit_sub_state_to_string(u),
787 following ? following->id : "",
788 unit_path,
789 u->job ? u->job->id : 0,
790 u->job ? job_type_to_string(u->job->type) : "",
791 job_path ? job_path : "/");
792 if (r < 0)
793 return r;
794 }
795
796 r = sd_bus_message_close_container(reply);
797 if (r < 0)
798 return r;
799
800 return sd_bus_send(bus, reply, NULL);
801 }
802
803 static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
804 return list_units_filtered(bus, message, userdata, error, NULL);
805 }
806
807 static int method_list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
808 _cleanup_strv_free_ char **states = NULL;
809 int r;
810
811 r = sd_bus_message_read_strv(message, &states);
812 if (r < 0)
813 return r;
814
815 return list_units_filtered(bus, message, userdata, error, states);
816 }
817
818 static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
819 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
820 Manager *m = userdata;
821 Iterator i;
822 Job *j;
823 int r;
824
825 assert(bus);
826 assert(message);
827 assert(m);
828
829 r = selinux_access_check(message, "status", error);
830 if (r < 0)
831 return r;
832
833 r = sd_bus_message_new_method_return(message, &reply);
834 if (r < 0)
835 return r;
836
837 r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
838 if (r < 0)
839 return r;
840
841 HASHMAP_FOREACH(j, m->jobs, i) {
842 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
843
844 job_path = job_dbus_path(j);
845 if (!job_path)
846 return -ENOMEM;
847
848 unit_path = unit_dbus_path(j->unit);
849 if (!unit_path)
850 return -ENOMEM;
851
852 r = sd_bus_message_append(
853 reply, "(usssoo)",
854 j->id,
855 j->unit->id,
856 job_type_to_string(j->type),
857 job_state_to_string(j->state),
858 job_path,
859 unit_path);
860 if (r < 0)
861 return r;
862 }
863
864 r = sd_bus_message_close_container(reply);
865 if (r < 0)
866 return r;
867
868 return sd_bus_send(bus, reply, NULL);
869 }
870
871 static int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
872 Manager *m = userdata;
873 int r;
874
875 assert(bus);
876 assert(message);
877 assert(m);
878
879 r = selinux_access_check(message, "status", error);
880 if (r < 0)
881 return r;
882
883 if (bus == m->api_bus) {
884
885 /* Note that direct bus connection subscribe by
886 * default, we only track peers on the API bus here */
887
888 if (!m->subscribed) {
889 r = sd_bus_track_new(bus, &m->subscribed, NULL, NULL);
890 if (r < 0)
891 return r;
892 }
893
894 r = sd_bus_track_add_sender(m->subscribed, message);
895 if (r < 0)
896 return r;
897 if (r == 0)
898 return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
899 }
900
901 return sd_bus_reply_method_return(message, NULL);
902 }
903
904 static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
905 Manager *m = userdata;
906 int r;
907
908 assert(bus);
909 assert(message);
910 assert(m);
911
912 r = selinux_access_check(message, "status", error);
913 if (r < 0)
914 return r;
915
916 if (bus == m->api_bus) {
917 r = sd_bus_track_remove_sender(m->subscribed, message);
918 if (r < 0)
919 return r;
920 if (r == 0)
921 return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
922 }
923
924 return sd_bus_reply_method_return(message, NULL);
925 }
926
927 static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
928 _cleanup_free_ char *dump = NULL;
929 _cleanup_fclose_ FILE *f = NULL;
930 Manager *m = userdata;
931 size_t size;
932 int r;
933
934 assert(bus);
935 assert(message);
936 assert(m);
937
938 r = selinux_access_check(message, "status", error);
939 if (r < 0)
940 return r;
941
942 f = open_memstream(&dump, &size);
943 if (!f)
944 return -ENOMEM;
945
946 manager_dump_units(m, f, NULL);
947 manager_dump_jobs(m, f, NULL);
948
949 fflush(f);
950
951 if (ferror(f))
952 return -ENOMEM;
953
954 return sd_bus_reply_method_return(message, "s", dump);
955 }
956
957 static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
958 _cleanup_free_ char *path = NULL;
959 Manager *m = userdata;
960 const char *name;
961 int cleanup;
962 Snapshot *s = NULL;
963 int r;
964
965 assert(bus);
966 assert(message);
967 assert(m);
968
969 r = selinux_access_check(message, "start", error);
970 if (r < 0)
971 return r;
972
973 r = sd_bus_message_read(message, "sb", &name, &cleanup);
974 if (r < 0)
975 return r;
976
977 if (isempty(name))
978 name = NULL;
979
980 r = snapshot_create(m, name, cleanup, error, &s);
981 if (r < 0)
982 return r;
983
984 path = unit_dbus_path(UNIT(s));
985 if (!path)
986 return -ENOMEM;
987
988 return sd_bus_reply_method_return(message, "o", path);
989 }
990
991 static int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
992 Manager *m = userdata;
993 const char *name;
994 Unit *u;
995 int r;
996
997 assert(bus);
998 assert(message);
999 assert(m);
1000
1001 r = selinux_access_check(message, "stop", error);
1002 if (r < 0)
1003 return r;
1004
1005 r = sd_bus_message_read(message, "s", &name);
1006 if (r < 0)
1007 return r;
1008
1009 u = manager_get_unit(m, name);
1010 if (!u)
1011 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", name);
1012
1013 if (u->type != UNIT_SNAPSHOT)
1014 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not a snapshot", name);
1015
1016 return bus_snapshot_method_remove(bus, message, u, error);
1017 }
1018
1019 static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1020 Manager *m = userdata;
1021 int r;
1022
1023 assert(bus);
1024 assert(message);
1025 assert(m);
1026
1027 r = selinux_access_check(message, "reload", error);
1028 if (r < 0)
1029 return r;
1030
1031 /* Instead of sending the reply back right away, we just
1032 * remember that we need to and then send it after the reload
1033 * is finished. That way the caller knows when the reload
1034 * finished. */
1035
1036 assert(!m->queued_message);
1037 r = sd_bus_message_new_method_return(message, &m->queued_message);
1038 if (r < 0)
1039 return r;
1040
1041 m->queued_message_bus = sd_bus_ref(bus);
1042 m->exit_code = MANAGER_RELOAD;
1043
1044 return 1;
1045 }
1046
1047 static int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1048 Manager *m = userdata;
1049 int r;
1050
1051 assert(bus);
1052 assert(message);
1053 assert(m);
1054
1055 r = selinux_access_check(message, "reload", error);
1056 if (r < 0)
1057 return r;
1058
1059 /* We don't send a reply back here, the client should
1060 * just wait for us disconnecting. */
1061
1062 m->exit_code = MANAGER_REEXECUTE;
1063 return 1;
1064 }
1065
1066 static int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1067 Manager *m = userdata;
1068 int r;
1069
1070 assert(bus);
1071 assert(message);
1072 assert(m);
1073
1074 r = selinux_access_check(message, "halt", error);
1075 if (r < 0)
1076 return r;
1077
1078 if (m->running_as == SYSTEMD_SYSTEM)
1079 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
1080
1081 m->exit_code = MANAGER_EXIT;
1082
1083 return sd_bus_reply_method_return(message, NULL);
1084 }
1085
1086 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1087 Manager *m = userdata;
1088 int r;
1089
1090 assert(bus);
1091 assert(message);
1092 assert(m);
1093
1094 r = selinux_access_check(message, "reboot", error);
1095 if (r < 0)
1096 return r;
1097
1098 if (m->running_as != SYSTEMD_SYSTEM)
1099 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
1100
1101 m->exit_code = MANAGER_REBOOT;
1102
1103 return sd_bus_reply_method_return(message, NULL);
1104 }
1105
1106
1107 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1108 Manager *m = userdata;
1109 int r;
1110
1111 assert(bus);
1112 assert(message);
1113 assert(m);
1114
1115 r = selinux_access_check(message, "halt", error);
1116 if (r < 0)
1117 return r;
1118
1119 if (m->running_as != SYSTEMD_SYSTEM)
1120 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
1121
1122 m->exit_code = MANAGER_POWEROFF;
1123
1124 return sd_bus_reply_method_return(message, NULL);
1125 }
1126
1127 static int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1128 Manager *m = userdata;
1129 int r;
1130
1131 assert(bus);
1132 assert(message);
1133 assert(m);
1134
1135 r = selinux_access_check(message, "halt", error);
1136 if (r < 0)
1137 return r;
1138
1139 if (m->running_as != SYSTEMD_SYSTEM)
1140 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
1141
1142 m->exit_code = MANAGER_HALT;
1143
1144 return sd_bus_reply_method_return(message, NULL);
1145 }
1146
1147 static int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1148 Manager *m = userdata;
1149 int r;
1150
1151 assert(bus);
1152 assert(message);
1153 assert(m);
1154
1155 r = selinux_access_check(message, "reboot", error);
1156 if (r < 0)
1157 return r;
1158
1159 if (m->running_as != SYSTEMD_SYSTEM)
1160 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1161
1162 m->exit_code = MANAGER_KEXEC;
1163
1164 return sd_bus_reply_method_return(message, NULL);
1165 }
1166
1167 static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1168 char *ri = NULL, *rt = NULL;
1169 const char *root, *init;
1170 Manager *m = userdata;
1171 int r;
1172
1173 assert(bus);
1174 assert(message);
1175 assert(m);
1176
1177 r = selinux_access_check(message, "reboot", error);
1178 if (r < 0)
1179 return r;
1180
1181 if (m->running_as != SYSTEMD_SYSTEM)
1182 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1183
1184 r = sd_bus_message_read(message, "ss", &root, &init);
1185 if (r < 0)
1186 return r;
1187
1188 if (path_equal(root, "/") || !path_is_absolute(root))
1189 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
1190
1191 /* Safety check */
1192 if (isempty(init)) {
1193 if (! path_is_os_tree(root))
1194 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. /etc/os-release is missing.", root);
1195 } else {
1196 _cleanup_free_ char *p = NULL;
1197
1198 if (!path_is_absolute(init))
1199 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
1200
1201 p = strappend(root, init);
1202 if (!p)
1203 return -ENOMEM;
1204
1205 if (access(p, X_OK) < 0)
1206 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
1207 }
1208
1209 rt = strdup(root);
1210 if (!rt)
1211 return -ENOMEM;
1212
1213 if (!isempty(init)) {
1214 ri = strdup(init);
1215 if (!ri) {
1216 free(rt);
1217 return -ENOMEM;
1218 }
1219 }
1220
1221 free(m->switch_root);
1222 m->switch_root = rt;
1223
1224 free(m->switch_root_init);
1225 m->switch_root_init = ri;
1226
1227 m->exit_code = MANAGER_SWITCH_ROOT;
1228
1229 return sd_bus_reply_method_return(message, NULL);
1230 }
1231
1232 static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1233 _cleanup_strv_free_ char **plus = NULL;
1234 Manager *m = userdata;
1235 int r;
1236
1237 assert(bus);
1238 assert(message);
1239 assert(m);
1240
1241 r = selinux_access_check(message, "reload", error);
1242 if (r < 0)
1243 return r;
1244
1245 r = sd_bus_message_read_strv(message, &plus);
1246 if (r < 0)
1247 return r;
1248 if (!strv_env_is_valid(plus))
1249 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1250
1251 r = manager_environment_add(m, NULL, plus);
1252 if (r < 0)
1253 return r;
1254
1255 return sd_bus_reply_method_return(message, NULL);
1256 }
1257
1258 static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1259 _cleanup_strv_free_ char **minus = NULL;
1260 Manager *m = userdata;
1261 int r;
1262
1263 assert(bus);
1264 assert(message);
1265 assert(m);
1266
1267 r = selinux_access_check(message, "reload", error);
1268 if (r < 0)
1269 return r;
1270
1271 r = sd_bus_message_read_strv(message, &minus);
1272 if (r < 0)
1273 return r;
1274
1275 if (!strv_env_name_or_assignment_is_valid(minus))
1276 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1277
1278 r = manager_environment_add(m, minus, NULL);
1279 if (r < 0)
1280 return r;
1281
1282 return sd_bus_reply_method_return(message, NULL);
1283 }
1284
1285 static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1286 _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1287 Manager *m = userdata;
1288 int r;
1289
1290 assert(bus);
1291 assert(message);
1292 assert(m);
1293
1294 r = selinux_access_check(message, "reload", error);
1295 if (r < 0)
1296 return r;
1297
1298 r = sd_bus_message_read_strv(message, &plus);
1299 if (r < 0)
1300 return r;
1301
1302 r = sd_bus_message_read_strv(message, &minus);
1303 if (r < 0)
1304 return r;
1305
1306 if (!strv_env_is_valid(plus))
1307 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1308 if (!strv_env_name_or_assignment_is_valid(minus))
1309 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1310
1311 r = manager_environment_add(m, minus, plus);
1312 if (r < 0)
1313 return r;
1314
1315 return sd_bus_reply_method_return(message, NULL);
1316 }
1317
1318 static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1319 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1320 Manager *m = userdata;
1321 UnitFileList *item;
1322 Hashmap *h;
1323 Iterator i;
1324 int r;
1325
1326 assert(bus);
1327 assert(message);
1328 assert(m);
1329
1330 r = selinux_access_check(message, "status", error);
1331 if (r < 0)
1332 return r;
1333
1334 r = sd_bus_message_new_method_return(message, &reply);
1335 if (r < 0)
1336 return r;
1337
1338 h = hashmap_new(string_hash_func, string_compare_func);
1339 if (!h)
1340 return -ENOMEM;
1341
1342 r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
1343 if (r < 0)
1344 goto fail;
1345
1346 r = sd_bus_message_open_container(reply, 'a', "(ss)");
1347 if (r < 0)
1348 goto fail;
1349
1350 HASHMAP_FOREACH(item, h, i) {
1351
1352 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
1353 if (r < 0)
1354 goto fail;
1355 }
1356
1357 unit_file_list_free(h);
1358
1359 r = sd_bus_message_close_container(reply);
1360 if (r < 0)
1361 return r;
1362
1363 return sd_bus_send(bus, reply, NULL);
1364
1365 fail:
1366 unit_file_list_free(h);
1367 return r;
1368 }
1369
1370 static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1371 Manager *m = userdata;
1372 const char *name;
1373 UnitFileState state;
1374 UnitFileScope scope;
1375 int r;
1376
1377 assert(bus);
1378 assert(message);
1379 assert(m);
1380
1381 r = selinux_access_check(message, "status", error);
1382 if (r < 0)
1383 return r;
1384
1385 r = sd_bus_message_read(message, "s", &name);
1386 if (r < 0)
1387 return r;
1388
1389 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1390
1391 state = unit_file_get_state(scope, NULL, name);
1392 if (state < 0)
1393 return state;
1394
1395 return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
1396 }
1397
1398 static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1399 _cleanup_free_ char *default_target = NULL;
1400 Manager *m = userdata;
1401 UnitFileScope scope;
1402 int r;
1403
1404 assert(bus);
1405 assert(message);
1406 assert(m);
1407
1408 r = selinux_access_check(message, "status", error);
1409 if (r < 0)
1410 return r;
1411
1412 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1413
1414 r = unit_file_get_default(scope, NULL, &default_target);
1415 if (r < 0)
1416 return r;
1417
1418 return sd_bus_reply_method_return(message, "s", default_target);
1419 }
1420
1421 static int send_unit_files_changed(sd_bus *bus, void *userdata) {
1422 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1423 int r;
1424
1425 assert(bus);
1426
1427 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1428 if (r < 0)
1429 return r;
1430
1431 return sd_bus_send(bus, message, NULL);
1432 }
1433
1434 static int reply_unit_file_changes_and_free(
1435 Manager *m,
1436 sd_bus *bus,
1437 sd_bus_message *message,
1438 int carries_install_info,
1439 UnitFileChange *changes,
1440 unsigned n_changes) {
1441
1442 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1443 unsigned i;
1444 int r;
1445
1446 if (n_changes > 0) {
1447 r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
1448 if (r < 0)
1449 log_debug("Failed to send UnitFilesChanged signal: %s", strerror(-r));
1450 }
1451
1452 r = sd_bus_message_new_method_return(message, &reply);
1453 if (r < 0)
1454 goto fail;
1455
1456 if (carries_install_info >= 0) {
1457 r = sd_bus_message_append(reply, "b", carries_install_info);
1458 if (r < 0)
1459 goto fail;
1460 }
1461
1462 r = sd_bus_message_open_container(reply, 'a', "(sss)");
1463 if (r < 0)
1464 goto fail;
1465
1466 for (i = 0; i < n_changes; i++) {
1467 r = sd_bus_message_append(
1468 reply, "(sss)",
1469 unit_file_change_type_to_string(changes[i].type),
1470 changes[i].path,
1471 changes[i].source);
1472 if (r < 0)
1473 goto fail;
1474 }
1475
1476 r = sd_bus_message_close_container(reply);
1477 if (r < 0)
1478 goto fail;
1479
1480 return sd_bus_send(bus, reply, NULL);
1481
1482 fail:
1483 unit_file_changes_free(changes, n_changes);
1484 return r;
1485 }
1486
1487 static int method_enable_unit_files_generic(
1488 sd_bus *bus,
1489 sd_bus_message *message,
1490 Manager *m, const
1491 char *verb,
1492 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
1493 bool carries_install_info,
1494 sd_bus_error *error) {
1495
1496 _cleanup_strv_free_ char **l = NULL;
1497 #ifdef HAVE_SELINUX
1498 char **i;
1499 #endif
1500 UnitFileChange *changes = NULL;
1501 unsigned n_changes = 0;
1502 UnitFileScope scope;
1503 int runtime, force, r;
1504
1505 assert(bus);
1506 assert(message);
1507 assert(m);
1508
1509 r = sd_bus_message_read_strv(message, &l);
1510 if (r < 0)
1511 return r;
1512
1513 #ifdef HAVE_SELINUX
1514 STRV_FOREACH(i, l) {
1515 Unit *u;
1516
1517 u = manager_get_unit(m, *i);
1518 if (u) {
1519 r = selinux_unit_access_check(u, message, verb, error);
1520 if (r < 0)
1521 return r;
1522 }
1523 }
1524 #endif
1525
1526 r = sd_bus_message_read(message, "bb", &runtime, &force);
1527 if (r < 0)
1528 return r;
1529
1530 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1531
1532 r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
1533 if (r < 0)
1534 return r;
1535
1536 return reply_unit_file_changes_and_free(m, bus, message, carries_install_info ? r : -1, changes, n_changes);
1537 }
1538
1539 static int method_enable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1540 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_enable, true, error);
1541 }
1542
1543 static int method_reenable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1544 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_reenable, true, error);
1545 }
1546
1547 static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1548 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
1549 }
1550
1551 static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1552 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset, true, error);
1553 }
1554
1555 static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1556 return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
1557 }
1558
1559 static int method_disable_unit_files_generic(
1560 sd_bus *bus,
1561 sd_bus_message *message,
1562 Manager *m, const
1563 char *verb,
1564 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
1565 sd_bus_error *error) {
1566
1567 _cleanup_strv_free_ char **l = NULL;
1568 UnitFileChange *changes = NULL;
1569 unsigned n_changes = 0;
1570 UnitFileScope scope;
1571 int r, runtime;
1572
1573 assert(bus);
1574 assert(message);
1575 assert(m);
1576
1577 r = selinux_access_check(message, verb, error);
1578 if (r < 0)
1579 return r;
1580
1581 r = sd_bus_message_read_strv(message, &l);
1582 if (r < 0)
1583 return r;
1584
1585 r = sd_bus_message_read(message, "b", &runtime);
1586 if (r < 0)
1587 return r;
1588
1589 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1590
1591 r = call(scope, runtime, NULL, l, &changes, &n_changes);
1592 if (r < 0)
1593 return r;
1594
1595 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1596 }
1597
1598 static int method_disable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1599 return method_disable_unit_files_generic(bus, message, userdata, "disable", unit_file_disable, error);
1600 }
1601
1602 static int method_unmask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1603 return method_disable_unit_files_generic(bus, message, userdata, "enable", unit_file_unmask, error);
1604 }
1605
1606 static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1607 UnitFileChange *changes = NULL;
1608 unsigned n_changes = 0;
1609 Manager *m = userdata;
1610 UnitFileScope scope;
1611 const char *name;
1612 int force, r;
1613
1614 assert(bus);
1615 assert(message);
1616 assert(m);
1617
1618 r = selinux_access_check(message, "enable", error);
1619 if (r < 0)
1620 return r;
1621
1622 r = sd_bus_message_read(message, "sb", &name, &force);
1623 if (r < 0)
1624 return r;
1625
1626 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1627
1628 r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
1629 if (r < 0)
1630 return r;
1631
1632 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1633 }
1634
1635 const sd_bus_vtable bus_manager_vtable[] = {
1636 SD_BUS_VTABLE_START(0),
1637
1638 SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1639 SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1640 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1641 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1642 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1643 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1644 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1645 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1646 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1647 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1648 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1649 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1650 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1651 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1652 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1653 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1654 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1655 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
1656 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
1657 SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
1658 SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units, 0, 0),
1659 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
1660 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
1661 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
1662 SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
1663 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
1664 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
1665 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
1666 SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), SD_BUS_VTABLE_PROPERTY_CONST),
1667 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1668 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1669 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), SD_BUS_VTABLE_PROPERTY_CONST),
1670 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), SD_BUS_VTABLE_PROPERTY_CONST),
1671 SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
1672 SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
1673
1674 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1675 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1676 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1677 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, 0),
1678 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, 0),
1679 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, 0),
1680 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, 0),
1681 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, 0),
1682 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, 0),
1683 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, 0),
1684 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, 0),
1685 SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1686 SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, 0),
1687 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, 0),
1688 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, 0),
1689 SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
1690 SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, 0),
1691 SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, 0),
1692 SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, 0),
1693 SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
1694 SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered, SD_BUS_VTABLE_UNPRIVILEGED),
1695 SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
1696 SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1697 SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1698 SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
1699 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, 0),
1700 SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, 0),
1701 SD_BUS_METHOD("Reload", NULL, NULL, method_reload, 0),
1702 SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, 0),
1703 SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
1704 SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1705 SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1706 SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1707 SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1708 SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1709 SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, 0),
1710 SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, 0),
1711 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, 0),
1712 SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
1713 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
1714 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, 0),
1715 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, 0),
1716 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, 0),
1717 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, 0),
1718 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, 0),
1719 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, 0),
1720 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, 0),
1721 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, 0),
1722 SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
1723
1724 SD_BUS_SIGNAL("UnitNew", "so", 0),
1725 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
1726 SD_BUS_SIGNAL("JobNew", "uos", 0),
1727 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
1728 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
1729 SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
1730 SD_BUS_SIGNAL("Reloading", "b", 0),
1731
1732 SD_BUS_VTABLE_END
1733 };
1734
1735 static int send_finished(sd_bus *bus, void *userdata) {
1736 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1737 usec_t *times = userdata;
1738 int r;
1739
1740 assert(bus);
1741 assert(times);
1742
1743 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
1744 if (r < 0)
1745 return r;
1746
1747 r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
1748 if (r < 0)
1749 return r;
1750
1751 return sd_bus_send(bus, message, NULL);
1752 }
1753
1754 void bus_manager_send_finished(
1755 Manager *m,
1756 usec_t firmware_usec,
1757 usec_t loader_usec,
1758 usec_t kernel_usec,
1759 usec_t initrd_usec,
1760 usec_t userspace_usec,
1761 usec_t total_usec) {
1762
1763 int r;
1764
1765 assert(m);
1766
1767 r = bus_foreach_bus(
1768 m,
1769 NULL,
1770 send_finished,
1771 (usec_t[6]) {
1772 firmware_usec,
1773 loader_usec,
1774 kernel_usec,
1775 initrd_usec,
1776 userspace_usec,
1777 total_usec
1778 });
1779 if (r < 0)
1780 log_debug("Failed to send finished signal: %s", strerror(-r));
1781 }
1782
1783 static int send_reloading(sd_bus *bus, void *userdata) {
1784 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1785 int r;
1786
1787 assert(bus);
1788
1789 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
1790 if (r < 0)
1791 return r;
1792
1793 r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
1794 if (r < 0)
1795 return r;
1796
1797 return sd_bus_send(bus, message, NULL);
1798 }
1799
1800 void bus_manager_send_reloading(Manager *m, bool active) {
1801 int r;
1802
1803 assert(m);
1804
1805 r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
1806 if (r < 0)
1807 log_debug("Failed to send reloading signal: %s", strerror(-r));
1808
1809 }