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