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