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