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