chiark / gitweb /
Rename more things to elogind
[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                 r = sd_bus_message_read(message, "s", &name);
679                 if (r < 0)
680                         return r;
681
682                 r = transient_unit_from_message(m, message, name, &u, error);
683                 if (r < 0 && r != -EEXIST)
684                         return r;
685
686                 if (r != -EEXIST) {
687                         r = unit_load(u);
688                         if (r < 0)
689                                 return r;
690                 }
691
692                 r = sd_bus_message_exit_container(message);
693                 if (r < 0)
694                         return r;
695         }
696         if (r < 0)
697                 return r;
698
699         r = sd_bus_message_exit_container(message);
700         if (r < 0)
701                 return r;
702
703         return 0;
704 }
705
706 static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
707         const char *name, *smode;
708         Manager *m = userdata;
709         JobMode mode;
710         UnitType t;
711         Unit *u;
712         int r;
713
714         assert(bus);
715         assert(message);
716         assert(m);
717
718         r = mac_selinux_access_check(message, "start", error);
719         if (r < 0)
720                 return r;
721
722         r = sd_bus_message_read(message, "ss", &name, &smode);
723         if (r < 0)
724                 return r;
725
726         t = unit_name_to_type(name);
727         if (t < 0)
728                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit type.");
729
730         if (!unit_vtable[t]->can_transient)
731                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.", unit_type_to_string(t));
732
733         mode = job_mode_from_string(smode);
734         if (mode < 0)
735                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
736
737         r = bus_verify_manage_units_async(m, message, error);
738         if (r < 0)
739                 return r;
740         if (r == 0)
741                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
742
743         r = transient_unit_from_message(m, message, name, &u, error);
744         if (r < 0)
745                 return r;
746
747         r = transient_aux_units_from_message(m, message, error);
748         if (r < 0)
749                 return r;
750
751         /* And load this stub fully */
752         r = unit_load(u);
753         if (r < 0)
754                 return r;
755
756         manager_dispatch_load_queue(m);
757
758         /* Finally, start it */
759         return bus_unit_queue_job(bus, message, u, JOB_START, mode, false, error);
760 }
761
762 static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
763         _cleanup_free_ char *path = NULL;
764         Manager *m = userdata;
765         uint32_t id;
766         Job *j;
767         int r;
768
769         assert(bus);
770         assert(message);
771         assert(m);
772
773         /* Anyone can call this method */
774
775         r = sd_bus_message_read(message, "u", &id);
776         if (r < 0)
777                 return r;
778
779         j = manager_get_job(m, id);
780         if (!j)
781                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
782
783         r = mac_selinux_unit_access_check(j->unit, message, "status", error);
784         if (r < 0)
785                 return r;
786
787         path = job_dbus_path(j);
788         if (!path)
789                 return -ENOMEM;
790
791         return sd_bus_reply_method_return(message, "o", path);
792 }
793
794 static int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
795         Manager *m = userdata;
796         uint32_t id;
797         Job *j;
798         int r;
799
800         assert(bus);
801         assert(message);
802         assert(m);
803
804         r = sd_bus_message_read(message, "u", &id);
805         if (r < 0)
806                 return r;
807
808         j = manager_get_job(m, id);
809         if (!j)
810                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
811
812         return bus_job_method_cancel(bus, message, j, error);
813 }
814
815 static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
816         Manager *m = userdata;
817         int r;
818
819         assert(bus);
820         assert(message);
821         assert(m);
822
823         r = mac_selinux_access_check(message, "reload", error);
824         if (r < 0)
825                 return r;
826
827         r = bus_verify_manage_units_async(m, message, error);
828         if (r < 0)
829                 return r;
830         if (r == 0)
831                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
832
833         manager_clear_jobs(m);
834
835         return sd_bus_reply_method_return(message, NULL);
836 }
837
838 static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
839         Manager *m = userdata;
840         int r;
841
842         assert(bus);
843         assert(message);
844         assert(m);
845
846         r = mac_selinux_access_check(message, "reload", error);
847         if (r < 0)
848                 return r;
849
850         r = bus_verify_manage_units_async(m, message, error);
851         if (r < 0)
852                 return r;
853         if (r == 0)
854                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
855
856         manager_reset_failed(m);
857
858         return sd_bus_reply_method_return(message, NULL);
859 }
860
861 static int list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error, char **states) {
862         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
863         Manager *m = userdata;
864         const char *k;
865         Iterator i;
866         Unit *u;
867         int r;
868
869         assert(bus);
870         assert(message);
871         assert(m);
872
873         /* Anyone can call this method */
874
875         r = mac_selinux_access_check(message, "status", error);
876         if (r < 0)
877                 return r;
878
879         r = sd_bus_message_new_method_return(message, &reply);
880         if (r < 0)
881                 return r;
882
883         r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
884         if (r < 0)
885                 return r;
886
887         HASHMAP_FOREACH_KEY(u, k, m->units, i) {
888                 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
889                 Unit *following;
890
891                 if (k != u->id)
892                         continue;
893
894                 following = unit_following(u);
895
896                 if (!strv_isempty(states) &&
897                     !strv_contains(states, unit_load_state_to_string(u->load_state)) &&
898                     !strv_contains(states, unit_active_state_to_string(unit_active_state(u))) &&
899                     !strv_contains(states, unit_sub_state_to_string(u)))
900                         continue;
901
902                 unit_path = unit_dbus_path(u);
903                 if (!unit_path)
904                         return -ENOMEM;
905
906                 if (u->job) {
907                         job_path = job_dbus_path(u->job);
908                         if (!job_path)
909                                 return -ENOMEM;
910                 }
911
912                 r = sd_bus_message_append(
913                                 reply, "(ssssssouso)",
914                                 u->id,
915                                 unit_description(u),
916                                 unit_load_state_to_string(u->load_state),
917                                 unit_active_state_to_string(unit_active_state(u)),
918                                 unit_sub_state_to_string(u),
919                                 following ? following->id : "",
920                                 unit_path,
921                                 u->job ? u->job->id : 0,
922                                 u->job ? job_type_to_string(u->job->type) : "",
923                                 job_path ? job_path : "/");
924                 if (r < 0)
925                         return r;
926         }
927
928         r = sd_bus_message_close_container(reply);
929         if (r < 0)
930                 return r;
931
932         return sd_bus_send(bus, reply, NULL);
933 }
934
935 static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
936         return list_units_filtered(bus, message, userdata, error, NULL);
937 }
938
939 static int method_list_units_filtered(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
940         _cleanup_strv_free_ char **states = NULL;
941         int r;
942
943         r = sd_bus_message_read_strv(message, &states);
944         if (r < 0)
945                 return r;
946
947         return list_units_filtered(bus, message, userdata, error, states);
948 }
949
950 static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
951         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
952         Manager *m = userdata;
953         Iterator i;
954         Job *j;
955         int r;
956
957         assert(bus);
958         assert(message);
959         assert(m);
960
961         /* Anyone can call this method */
962
963         r = mac_selinux_access_check(message, "status", error);
964         if (r < 0)
965                 return r;
966
967         r = sd_bus_message_new_method_return(message, &reply);
968         if (r < 0)
969                 return r;
970
971         r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
972         if (r < 0)
973                 return r;
974
975         HASHMAP_FOREACH(j, m->jobs, i) {
976                 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
977
978                 job_path = job_dbus_path(j);
979                 if (!job_path)
980                         return -ENOMEM;
981
982                 unit_path = unit_dbus_path(j->unit);
983                 if (!unit_path)
984                         return -ENOMEM;
985
986                 r = sd_bus_message_append(
987                                 reply, "(usssoo)",
988                                 j->id,
989                                 j->unit->id,
990                                 job_type_to_string(j->type),
991                                 job_state_to_string(j->state),
992                                 job_path,
993                                 unit_path);
994                 if (r < 0)
995                         return r;
996         }
997
998         r = sd_bus_message_close_container(reply);
999         if (r < 0)
1000                 return r;
1001
1002         return sd_bus_send(bus, reply, NULL);
1003 }
1004
1005 static int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1006         Manager *m = userdata;
1007         int r;
1008
1009         assert(bus);
1010         assert(message);
1011         assert(m);
1012
1013         /* Anyone can call this method */
1014
1015         r = mac_selinux_access_check(message, "status", error);
1016         if (r < 0)
1017                 return r;
1018
1019         if (bus == m->api_bus) {
1020
1021                 /* Note that direct bus connection subscribe by
1022                  * default, we only track peers on the API bus here */
1023
1024                 if (!m->subscribed) {
1025                         r = sd_bus_track_new(bus, &m->subscribed, NULL, NULL);
1026                         if (r < 0)
1027                                 return r;
1028                 }
1029
1030                 r = sd_bus_track_add_sender(m->subscribed, message);
1031                 if (r < 0)
1032                         return r;
1033                 if (r == 0)
1034                         return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
1035         }
1036
1037         return sd_bus_reply_method_return(message, NULL);
1038 }
1039
1040 static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1041         Manager *m = userdata;
1042         int r;
1043
1044         assert(bus);
1045         assert(message);
1046         assert(m);
1047
1048         /* Anyone can call this method */
1049
1050         r = mac_selinux_access_check(message, "status", error);
1051         if (r < 0)
1052                 return r;
1053
1054         if (bus == m->api_bus) {
1055                 r = sd_bus_track_remove_sender(m->subscribed, message);
1056                 if (r < 0)
1057                         return r;
1058                 if (r == 0)
1059                         return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
1060         }
1061
1062         return sd_bus_reply_method_return(message, NULL);
1063 }
1064
1065 static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1066         _cleanup_free_ char *dump = NULL;
1067         _cleanup_fclose_ FILE *f = NULL;
1068         Manager *m = userdata;
1069         size_t size;
1070         int r;
1071
1072         assert(bus);
1073         assert(message);
1074         assert(m);
1075
1076         /* Anyone can call this method */
1077
1078         r = mac_selinux_access_check(message, "status", error);
1079         if (r < 0)
1080                 return r;
1081
1082         f = open_memstream(&dump, &size);
1083         if (!f)
1084                 return -ENOMEM;
1085
1086         manager_dump_units(m, f, NULL);
1087         manager_dump_jobs(m, f, NULL);
1088
1089         fflush(f);
1090
1091         if (ferror(f))
1092                 return -ENOMEM;
1093
1094         return sd_bus_reply_method_return(message, "s", dump);
1095 }
1096
1097 static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1098         _cleanup_free_ char *path = NULL;
1099         Manager *m = userdata;
1100         const char *name;
1101         int cleanup;
1102         Snapshot *s = NULL;
1103         int r;
1104
1105         assert(bus);
1106         assert(message);
1107         assert(m);
1108
1109         r = mac_selinux_access_check(message, "start", error);
1110         if (r < 0)
1111                 return r;
1112
1113         r = sd_bus_message_read(message, "sb", &name, &cleanup);
1114         if (r < 0)
1115                 return r;
1116
1117         if (isempty(name))
1118                 name = NULL;
1119
1120         r = bus_verify_manage_units_async(m, message, error);
1121         if (r < 0)
1122                 return r;
1123         if (r == 0)
1124                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1125
1126         r = snapshot_create(m, name, cleanup, error, &s);
1127         if (r < 0)
1128                 return r;
1129
1130         path = unit_dbus_path(UNIT(s));
1131         if (!path)
1132                 return -ENOMEM;
1133
1134         return sd_bus_reply_method_return(message, "o", path);
1135 }
1136
1137 static int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1138         Manager *m = userdata;
1139         const char *name;
1140         Unit *u;
1141         int r;
1142
1143         assert(bus);
1144         assert(message);
1145         assert(m);
1146
1147         r = sd_bus_message_read(message, "s", &name);
1148         if (r < 0)
1149                 return r;
1150
1151         u = manager_get_unit(m, name);
1152         if (!u)
1153                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", name);
1154
1155         if (u->type != UNIT_SNAPSHOT)
1156                 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not a snapshot", name);
1157
1158         return bus_snapshot_method_remove(bus, message, u, error);
1159 }
1160
1161 static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1162         Manager *m = userdata;
1163         int r;
1164
1165         assert(bus);
1166         assert(message);
1167         assert(m);
1168
1169         r = mac_selinux_access_check(message, "reload", error);
1170         if (r < 0)
1171                 return r;
1172
1173         r = bus_verify_reload_daemon_async(m, message, error);
1174         if (r < 0)
1175                 return r;
1176         if (r == 0)
1177                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1178
1179         /* Instead of sending the reply back right away, we just
1180          * remember that we need to and then send it after the reload
1181          * is finished. That way the caller knows when the reload
1182          * finished. */
1183
1184         assert(!m->queued_message);
1185         r = sd_bus_message_new_method_return(message, &m->queued_message);
1186         if (r < 0)
1187                 return r;
1188
1189         m->queued_message_bus = sd_bus_ref(bus);
1190         m->exit_code = MANAGER_RELOAD;
1191
1192         return 1;
1193 }
1194
1195 static int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1196         Manager *m = userdata;
1197         int r;
1198
1199         assert(bus);
1200         assert(message);
1201         assert(m);
1202
1203         r = mac_selinux_access_check(message, "reload", error);
1204         if (r < 0)
1205                 return r;
1206
1207         r = bus_verify_reload_daemon_async(m, message, error);
1208         if (r < 0)
1209                 return r;
1210         if (r == 0)
1211                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1212
1213         /* We don't send a reply back here, the client should
1214          * just wait for us disconnecting. */
1215
1216         m->exit_code = MANAGER_REEXECUTE;
1217         return 1;
1218 }
1219
1220 static int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1221         Manager *m = userdata;
1222         int r;
1223
1224         assert(bus);
1225         assert(message);
1226         assert(m);
1227
1228         r = mac_selinux_access_check(message, "halt", error);
1229         if (r < 0)
1230                 return r;
1231
1232         if (m->running_as == SYSTEMD_SYSTEM)
1233                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
1234
1235         m->exit_code = MANAGER_EXIT;
1236
1237         return sd_bus_reply_method_return(message, NULL);
1238 }
1239
1240 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1241         Manager *m = userdata;
1242         int r;
1243
1244         assert(bus);
1245         assert(message);
1246         assert(m);
1247
1248         r = mac_selinux_access_check(message, "reboot", error);
1249         if (r < 0)
1250                 return r;
1251
1252         if (m->running_as != SYSTEMD_SYSTEM)
1253                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
1254
1255         m->exit_code = MANAGER_REBOOT;
1256
1257         return sd_bus_reply_method_return(message, NULL);
1258 }
1259
1260 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1261         Manager *m = userdata;
1262         int r;
1263
1264         assert(bus);
1265         assert(message);
1266         assert(m);
1267
1268         r = mac_selinux_access_check(message, "halt", error);
1269         if (r < 0)
1270                 return r;
1271
1272         if (m->running_as != SYSTEMD_SYSTEM)
1273                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
1274
1275         m->exit_code = MANAGER_POWEROFF;
1276
1277         return sd_bus_reply_method_return(message, NULL);
1278 }
1279
1280 static int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1281         Manager *m = userdata;
1282         int r;
1283
1284         assert(bus);
1285         assert(message);
1286         assert(m);
1287
1288         r = mac_selinux_access_check(message, "halt", error);
1289         if (r < 0)
1290                 return r;
1291
1292         if (m->running_as != SYSTEMD_SYSTEM)
1293                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
1294
1295         m->exit_code = MANAGER_HALT;
1296
1297         return sd_bus_reply_method_return(message, NULL);
1298 }
1299
1300 static int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1301         Manager *m = userdata;
1302         int r;
1303
1304         assert(bus);
1305         assert(message);
1306         assert(m);
1307
1308         r = mac_selinux_access_check(message, "reboot", error);
1309         if (r < 0)
1310                 return r;
1311
1312         if (m->running_as != SYSTEMD_SYSTEM)
1313                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1314
1315         m->exit_code = MANAGER_KEXEC;
1316
1317         return sd_bus_reply_method_return(message, NULL);
1318 }
1319
1320 static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1321         char *ri = NULL, *rt = NULL;
1322         const char *root, *init;
1323         Manager *m = userdata;
1324         int r;
1325
1326         assert(bus);
1327         assert(message);
1328         assert(m);
1329
1330         r = mac_selinux_access_check(message, "reboot", error);
1331         if (r < 0)
1332                 return r;
1333
1334         if (m->running_as != SYSTEMD_SYSTEM)
1335                 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Root switching is only supported by system manager.");
1336
1337         r = sd_bus_message_read(message, "ss", &root, &init);
1338         if (r < 0)
1339                 return r;
1340
1341         if (path_equal(root, "/") || !path_is_absolute(root))
1342                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
1343
1344         /* Safety check */
1345         if (isempty(init)) {
1346                 if (!path_is_os_tree(root))
1347                         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);
1348         } else {
1349                 _cleanup_free_ char *p = NULL;
1350
1351                 if (!path_is_absolute(init))
1352                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
1353
1354                 p = strappend(root, init);
1355                 if (!p)
1356                         return -ENOMEM;
1357
1358                 if (access(p, X_OK) < 0)
1359                         return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
1360         }
1361
1362         rt = strdup(root);
1363         if (!rt)
1364                 return -ENOMEM;
1365
1366         if (!isempty(init)) {
1367                 ri = strdup(init);
1368                 if (!ri) {
1369                         free(rt);
1370                         return -ENOMEM;
1371                 }
1372         }
1373
1374         free(m->switch_root);
1375         m->switch_root = rt;
1376
1377         free(m->switch_root_init);
1378         m->switch_root_init = ri;
1379
1380         m->exit_code = MANAGER_SWITCH_ROOT;
1381
1382         return sd_bus_reply_method_return(message, NULL);
1383 }
1384
1385 static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1386         _cleanup_strv_free_ char **plus = NULL;
1387         Manager *m = userdata;
1388         int r;
1389
1390         assert(bus);
1391         assert(message);
1392         assert(m);
1393
1394         r = mac_selinux_access_check(message, "reload", error);
1395         if (r < 0)
1396                 return r;
1397
1398         r = sd_bus_message_read_strv(message, &plus);
1399         if (r < 0)
1400                 return r;
1401         if (!strv_env_is_valid(plus))
1402                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1403
1404         r = bus_verify_set_environment_async(m, message, error);
1405         if (r < 0)
1406                 return r;
1407         if (r == 0)
1408                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1409
1410         r = manager_environment_add(m, NULL, plus);
1411         if (r < 0)
1412                 return r;
1413
1414         return sd_bus_reply_method_return(message, NULL);
1415 }
1416
1417 static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1418         _cleanup_strv_free_ char **minus = NULL;
1419         Manager *m = userdata;
1420         int r;
1421
1422         assert(bus);
1423         assert(message);
1424         assert(m);
1425
1426         r = mac_selinux_access_check(message, "reload", error);
1427         if (r < 0)
1428                 return r;
1429
1430         r = sd_bus_message_read_strv(message, &minus);
1431         if (r < 0)
1432                 return r;
1433
1434         if (!strv_env_name_or_assignment_is_valid(minus))
1435                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1436
1437         r = bus_verify_set_environment_async(m, message, error);
1438         if (r < 0)
1439                 return r;
1440         if (r == 0)
1441                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1442
1443         r = manager_environment_add(m, minus, NULL);
1444         if (r < 0)
1445                 return r;
1446
1447         return sd_bus_reply_method_return(message, NULL);
1448 }
1449
1450 static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1451         _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1452         Manager *m = userdata;
1453         int r;
1454
1455         assert(bus);
1456         assert(message);
1457         assert(m);
1458
1459         r = mac_selinux_access_check(message, "reload", error);
1460         if (r < 0)
1461                 return r;
1462
1463         r = sd_bus_message_read_strv(message, &minus);
1464         if (r < 0)
1465                 return r;
1466
1467         r = sd_bus_message_read_strv(message, &plus);
1468         if (r < 0)
1469                 return r;
1470
1471         if (!strv_env_name_or_assignment_is_valid(minus))
1472                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1473         if (!strv_env_is_valid(plus))
1474                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1475
1476         r = bus_verify_set_environment_async(m, message, error);
1477         if (r < 0)
1478                 return r;
1479         if (r == 0)
1480                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1481
1482         r = manager_environment_add(m, minus, plus);
1483         if (r < 0)
1484                 return r;
1485
1486         return sd_bus_reply_method_return(message, NULL);
1487 }
1488
1489 static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1490         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1491         Manager *m = userdata;
1492         UnitFileList *item;
1493         Hashmap *h;
1494         Iterator i;
1495         int r;
1496
1497         assert(bus);
1498         assert(message);
1499         assert(m);
1500
1501         /* Anyone can call this method */
1502
1503         r = mac_selinux_access_check(message, "status", error);
1504         if (r < 0)
1505                 return r;
1506
1507         r = sd_bus_message_new_method_return(message, &reply);
1508         if (r < 0)
1509                 return r;
1510
1511         h = hashmap_new(&string_hash_ops);
1512         if (!h)
1513                 return -ENOMEM;
1514
1515         r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
1516         if (r < 0)
1517                 goto fail;
1518
1519         r = sd_bus_message_open_container(reply, 'a', "(ss)");
1520         if (r < 0)
1521                 goto fail;
1522
1523         HASHMAP_FOREACH(item, h, i) {
1524
1525                 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
1526                 if (r < 0)
1527                         goto fail;
1528         }
1529
1530         unit_file_list_free(h);
1531
1532         r = sd_bus_message_close_container(reply);
1533         if (r < 0)
1534                 return r;
1535
1536         return sd_bus_send(bus, reply, NULL);
1537
1538 fail:
1539         unit_file_list_free(h);
1540         return r;
1541 }
1542
1543 static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1544         Manager *m = userdata;
1545         const char *name;
1546         UnitFileState state;
1547         UnitFileScope scope;
1548         int r;
1549
1550         assert(bus);
1551         assert(message);
1552         assert(m);
1553
1554         /* Anyone can call this method */
1555
1556         r = mac_selinux_access_check(message, "status", error);
1557         if (r < 0)
1558                 return r;
1559
1560         r = sd_bus_message_read(message, "s", &name);
1561         if (r < 0)
1562                 return r;
1563
1564         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1565
1566         state = unit_file_get_state(scope, NULL, name);
1567         if (state < 0)
1568                 return state;
1569
1570         return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
1571 }
1572
1573 static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1574         _cleanup_free_ char *default_target = NULL;
1575         Manager *m = userdata;
1576         UnitFileScope scope;
1577         int r;
1578
1579         assert(bus);
1580         assert(message);
1581         assert(m);
1582
1583         /* Anyone can call this method */
1584
1585         r = mac_selinux_access_check(message, "status", error);
1586         if (r < 0)
1587                 return r;
1588
1589         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1590
1591         r = unit_file_get_default(scope, NULL, &default_target);
1592         if (r < 0)
1593                 return r;
1594
1595         return sd_bus_reply_method_return(message, "s", default_target);
1596 }
1597
1598 static int send_unit_files_changed(sd_bus *bus, void *userdata) {
1599         _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1600         int r;
1601
1602         assert(bus);
1603
1604         r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1605         if (r < 0)
1606                 return r;
1607
1608         return sd_bus_send(bus, message, NULL);
1609 }
1610
1611 static int reply_unit_file_changes_and_free(
1612                 Manager *m,
1613                 sd_bus *bus,
1614                 sd_bus_message *message,
1615                 int carries_install_info,
1616                 UnitFileChange *changes,
1617                 unsigned n_changes) {
1618
1619         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1620         unsigned i;
1621         int r;
1622
1623         if (n_changes > 0) {
1624                 r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
1625                 if (r < 0)
1626                         log_debug_errno(r, "Failed to send UnitFilesChanged signal: %m");
1627         }
1628
1629         r = sd_bus_message_new_method_return(message, &reply);
1630         if (r < 0)
1631                 goto fail;
1632
1633         if (carries_install_info >= 0) {
1634                 r = sd_bus_message_append(reply, "b", carries_install_info);
1635                 if (r < 0)
1636                         goto fail;
1637         }
1638
1639         r = sd_bus_message_open_container(reply, 'a', "(sss)");
1640         if (r < 0)
1641                 goto fail;
1642
1643         for (i = 0; i < n_changes; i++) {
1644                 r = sd_bus_message_append(
1645                                 reply, "(sss)",
1646                                 unit_file_change_type_to_string(changes[i].type),
1647                                 changes[i].path,
1648                                 changes[i].source);
1649                 if (r < 0)
1650                         goto fail;
1651         }
1652
1653         r = sd_bus_message_close_container(reply);
1654         if (r < 0)
1655                 goto fail;
1656
1657         return sd_bus_send(bus, reply, NULL);
1658
1659 fail:
1660         unit_file_changes_free(changes, n_changes);
1661         return r;
1662 }
1663
1664 static int method_enable_unit_files_generic(
1665                 sd_bus *bus,
1666                 sd_bus_message *message,
1667                 Manager *m,
1668                 const char *verb,
1669                 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
1670                 bool carries_install_info,
1671                 sd_bus_error *error) {
1672
1673         _cleanup_strv_free_ char **l = NULL;
1674         UnitFileChange *changes = NULL;
1675         unsigned n_changes = 0;
1676         UnitFileScope scope;
1677         int runtime, force, r;
1678
1679         assert(bus);
1680         assert(message);
1681         assert(m);
1682
1683         r = sd_bus_message_read_strv(message, &l);
1684         if (r < 0)
1685                 return r;
1686
1687         r = sd_bus_message_read(message, "bb", &runtime, &force);
1688         if (r < 0)
1689                 return r;
1690
1691         r = mac_selinux_unit_access_check_strv(l, message, m, verb, error);
1692         if (r < 0)
1693                 return r;
1694
1695         r = bus_verify_manage_unit_files_async(m, message, error);
1696         if (r < 0)
1697                 return r;
1698         if (r == 0)
1699                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1700
1701         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1702
1703         r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
1704         if (r < 0)
1705                 return r;
1706
1707         return reply_unit_file_changes_and_free(m, bus, message, carries_install_info ? r : -1, changes, n_changes);
1708 }
1709
1710 static int method_enable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1711         return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_enable, true, error);
1712 }
1713
1714 static int method_reenable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1715         return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_reenable, true, error);
1716 }
1717
1718 static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1719         return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
1720 }
1721
1722 static int unit_file_preset_without_mode(UnitFileScope scope, bool runtime, const char *root_dir, char **files, bool force, UnitFileChange **changes, unsigned *n_changes) {
1723         return unit_file_preset(scope, runtime, root_dir, files, UNIT_FILE_PRESET_FULL, force, changes, n_changes);
1724 }
1725
1726 static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1727         return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset_without_mode, true, error);
1728 }
1729
1730 static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1731         return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
1732 }
1733
1734 static int method_preset_unit_files_with_mode(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1735
1736         _cleanup_strv_free_ char **l = NULL;
1737         UnitFileChange *changes = NULL;
1738         unsigned n_changes = 0;
1739         Manager *m = userdata;
1740         UnitFilePresetMode mm;
1741         UnitFileScope scope;
1742         int runtime, force, r;
1743         const char *mode;
1744
1745         assert(bus);
1746         assert(message);
1747         assert(m);
1748
1749         r = sd_bus_message_read_strv(message, &l);
1750         if (r < 0)
1751                 return r;
1752
1753         r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
1754         if (r < 0)
1755                 return r;
1756
1757         if (isempty(mode))
1758                 mm = UNIT_FILE_PRESET_FULL;
1759         else {
1760                 mm = unit_file_preset_mode_from_string(mode);
1761                 if (mm < 0)
1762                         return -EINVAL;
1763         }
1764
1765         r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
1766         if (r < 0)
1767                 return r;
1768
1769         r = bus_verify_manage_unit_files_async(m, message, error);
1770         if (r < 0)
1771                 return r;
1772         if (r == 0)
1773                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1774
1775         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1776
1777         r = unit_file_preset(scope, runtime, NULL, l, mm, force, &changes, &n_changes);
1778         if (r < 0)
1779                 return r;
1780
1781         return reply_unit_file_changes_and_free(m, bus, message, r, changes, n_changes);
1782 }
1783
1784 static int method_disable_unit_files_generic(
1785                 sd_bus *bus,
1786                 sd_bus_message *message,
1787                 Manager *m, const
1788                 char *verb,
1789                 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
1790                 sd_bus_error *error) {
1791
1792         _cleanup_strv_free_ char **l = NULL;
1793         UnitFileChange *changes = NULL;
1794         unsigned n_changes = 0;
1795         UnitFileScope scope;
1796         int r, runtime;
1797
1798         assert(bus);
1799         assert(message);
1800         assert(m);
1801
1802         r = sd_bus_message_read_strv(message, &l);
1803         if (r < 0)
1804                 return r;
1805
1806         r = sd_bus_message_read(message, "b", &runtime);
1807         if (r < 0)
1808                 return r;
1809
1810         r = mac_selinux_unit_access_check_strv(l, message, m, verb, error);
1811         if (r < 0)
1812                 return r;
1813
1814         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1815
1816         r = bus_verify_manage_unit_files_async(m, message, error);
1817         if (r < 0)
1818                 return r;
1819         if (r == 0)
1820                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1821
1822         r = call(scope, runtime, NULL, l, &changes, &n_changes);
1823         if (r < 0)
1824                 return r;
1825
1826         return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1827 }
1828
1829 static int method_disable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1830         return method_disable_unit_files_generic(bus, message, userdata, "disable", unit_file_disable, error);
1831 }
1832
1833 static int method_unmask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1834         return method_disable_unit_files_generic(bus, message, userdata, "enable", unit_file_unmask, error);
1835 }
1836
1837 static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1838         UnitFileChange *changes = NULL;
1839         unsigned n_changes = 0;
1840         Manager *m = userdata;
1841         UnitFileScope scope;
1842         const char *name;
1843         int force, r;
1844
1845         assert(bus);
1846         assert(message);
1847         assert(m);
1848
1849         r = mac_selinux_access_check(message, "enable", error);
1850         if (r < 0)
1851                 return r;
1852
1853         r = sd_bus_message_read(message, "sb", &name, &force);
1854         if (r < 0)
1855                 return r;
1856
1857         r = bus_verify_manage_unit_files_async(m, message, error);
1858         if (r < 0)
1859                 return r;
1860         if (r == 0)
1861                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1862
1863         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1864
1865         r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
1866         if (r < 0)
1867                 return r;
1868
1869         return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1870 }
1871
1872 static int method_preset_all_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1873         UnitFileChange *changes = NULL;
1874         unsigned n_changes = 0;
1875         Manager *m = userdata;
1876         UnitFilePresetMode mm;
1877         UnitFileScope scope;
1878         const char *mode;
1879         int force, runtime, r;
1880
1881         assert(bus);
1882         assert(message);
1883         assert(m);
1884
1885         r = mac_selinux_access_check(message, "enable", error);
1886         if (r < 0)
1887                 return r;
1888
1889         r = sd_bus_message_read(message, "sbb", &mode, &runtime, &force);
1890         if (r < 0)
1891                 return r;
1892
1893         if (isempty(mode))
1894                 mm = UNIT_FILE_PRESET_FULL;
1895         else {
1896                 mm = unit_file_preset_mode_from_string(mode);
1897                 if (mm < 0)
1898                         return -EINVAL;
1899         }
1900
1901         r = bus_verify_manage_unit_files_async(m, message, error);
1902         if (r < 0)
1903                 return r;
1904         if (r == 0)
1905                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1906
1907         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1908
1909         r = unit_file_preset_all(scope, runtime, NULL, mm, force, &changes, &n_changes);
1910         if (r < 0)
1911                 return r;
1912
1913         return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1914 }
1915
1916 static int method_add_dependency_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1917         _cleanup_strv_free_ char **l = NULL;
1918         Manager *m = userdata;
1919         UnitFileChange *changes = NULL;
1920         unsigned n_changes = 0;
1921         UnitFileScope scope;
1922         int runtime, force, r;
1923         char *target;
1924         char *type;
1925         UnitDependency dep;
1926
1927         assert(bus);
1928         assert(message);
1929         assert(m);
1930
1931         r = bus_verify_manage_unit_files_async(m, message, error);
1932         if (r < 0)
1933                 return r;
1934         if (r == 0)
1935                 return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
1936
1937         r = sd_bus_message_read_strv(message, &l);
1938         if (r < 0)
1939                 return r;
1940
1941         r = sd_bus_message_read(message, "ssbb", &target, &type, &runtime, &force);
1942         if (r < 0)
1943                 return r;
1944
1945         dep = unit_dependency_from_string(type);
1946         if (dep < 0)
1947                 return -EINVAL;
1948
1949         r = mac_selinux_unit_access_check_strv(l, message, m, "enable", error);
1950         if (r < 0)
1951                 return r;
1952
1953         scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1954
1955         r = unit_file_add_dependency(scope, runtime, NULL, l, target, dep, force, &changes, &n_changes);
1956         if (r < 0)
1957                 return r;
1958
1959         return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1960 }
1961
1962 const sd_bus_vtable bus_manager_vtable[] = {
1963         SD_BUS_VTABLE_START(0),
1964
1965         SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1966         SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1967         SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1968         SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1969         SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1970         BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1971         BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1972         BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1973         BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1974         BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1975         BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1976         BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1977         BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1978         BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1979         BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1980         BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1981         BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1982         SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
1983         SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
1984         SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
1985         SD_BUS_PROPERTY("NFailedUnits", "u", property_get_n_failed_units, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
1986         SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
1987         SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
1988         SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
1989         SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
1990         SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
1991         SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
1992         SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
1993         SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), SD_BUS_VTABLE_PROPERTY_CONST),
1994         SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1995         SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1996         SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
1997         SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
1998         SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
1999         SD_BUS_PROPERTY("SystemState", "s", property_get_system_state, 0, 0),
2000
2001         SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2002         SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
2003         SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2004         SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2005         SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, SD_BUS_VTABLE_UNPRIVILEGED),
2006         SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2007         SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2008         SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2009         SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2010         SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2011         SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2012         SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2013         SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2014         SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, SD_BUS_VTABLE_UNPRIVILEGED),
2015         SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, SD_BUS_VTABLE_UNPRIVILEGED),
2016         SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
2017         SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, SD_BUS_VTABLE_UNPRIVILEGED),
2018         SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
2019         SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, SD_BUS_VTABLE_UNPRIVILEGED),
2020         SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
2021         SD_BUS_METHOD("ListUnitsFiltered", "as", "a(ssssssouso)", method_list_units_filtered, SD_BUS_VTABLE_UNPRIVILEGED),
2022         SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
2023         SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
2024         SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
2025         SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
2026         SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
2027         SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, SD_BUS_VTABLE_UNPRIVILEGED),
2028         SD_BUS_METHOD("Reload", NULL, NULL, method_reload, SD_BUS_VTABLE_UNPRIVILEGED),
2029         SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, SD_BUS_VTABLE_UNPRIVILEGED),
2030         SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
2031         SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2032         SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2033         SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2034         SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2035         SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
2036         SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2037         SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2038         SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, SD_BUS_VTABLE_UNPRIVILEGED),
2039         SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2040         SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
2041         SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2042         SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2043         SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2044         SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2045         SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2046         SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, SD_BUS_VTABLE_UNPRIVILEGED),
2047         SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2048         SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2049         SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
2050         SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
2051         SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2052         SD_BUS_METHOD("AddDependencyUnitFiles", "asssbb", "a(sss)", method_add_dependency_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
2053
2054         SD_BUS_SIGNAL("UnitNew", "so", 0),
2055         SD_BUS_SIGNAL("UnitRemoved", "so", 0),
2056         SD_BUS_SIGNAL("JobNew", "uos", 0),
2057         SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
2058         SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
2059         SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
2060         SD_BUS_SIGNAL("Reloading", "b", 0),
2061
2062         SD_BUS_VTABLE_END
2063 };
2064
2065 static int send_finished(sd_bus *bus, void *userdata) {
2066         _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
2067         usec_t *times = userdata;
2068         int r;
2069
2070         assert(bus);
2071         assert(times);
2072
2073         r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
2074         if (r < 0)
2075                 return r;
2076
2077         r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
2078         if (r < 0)
2079                 return r;
2080
2081         return sd_bus_send(bus, message, NULL);
2082 }
2083
2084 void bus_manager_send_finished(
2085                 Manager *m,
2086                 usec_t firmware_usec,
2087                 usec_t loader_usec,
2088                 usec_t kernel_usec,
2089                 usec_t initrd_usec,
2090                 usec_t userspace_usec,
2091                 usec_t total_usec) {
2092
2093         int r;
2094
2095         assert(m);
2096
2097         r = bus_foreach_bus(
2098                         m,
2099                         NULL,
2100                         send_finished,
2101                         (usec_t[6]) {
2102                                 firmware_usec,
2103                                 loader_usec,
2104                                 kernel_usec,
2105                                 initrd_usec,
2106                                 userspace_usec,
2107                                 total_usec
2108                         });
2109         if (r < 0)
2110                 log_debug_errno(r, "Failed to send finished signal: %m");
2111 }
2112
2113 static int send_reloading(sd_bus *bus, void *userdata) {
2114         _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
2115         int r;
2116
2117         assert(bus);
2118
2119         r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
2120         if (r < 0)
2121                 return r;
2122
2123         r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
2124         if (r < 0)
2125                 return r;
2126
2127         return sd_bus_send(bus, message, NULL);
2128 }
2129
2130 void bus_manager_send_reloading(Manager *m, bool active) {
2131         int r;
2132
2133         assert(m);
2134
2135         r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
2136         if (r < 0)
2137                 log_debug_errno(r, "Failed to send reloading signal: %m");
2138 }
2139
2140 static int send_changed_signal(sd_bus *bus, void *userdata) {
2141         assert(bus);
2142
2143         return sd_bus_emit_properties_changed_strv(bus,
2144                                                    "/org/freedesktop/systemd1",
2145                                                    "org.freedesktop.systemd1.Manager",
2146                                                    NULL);
2147 }
2148
2149 void bus_manager_send_change_signal(Manager *m) {
2150         int r;
2151
2152         assert(m);
2153
2154         r = bus_foreach_bus(m, NULL, send_changed_signal, NULL);
2155         if (r < 0)
2156                 log_debug_errno(r, "Failed to send manager change signal: %m");
2157 }