1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
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.
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.
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/>.
29 #include "selinux-access.h"
32 #include "path-util.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"
43 static int property_get_version(
46 const char *interface,
48 sd_bus_message *reply,
50 sd_bus_error *error) {
55 return sd_bus_message_append(reply, "s", PACKAGE_VERSION);
58 static int property_get_features(
61 const char *interface,
63 sd_bus_message *reply,
65 sd_bus_error *error) {
70 return sd_bus_message_append(reply, "s", SYSTEMD_FEATURES);
73 static int property_get_virtualization(
76 const char *interface,
78 sd_bus_message *reply,
80 sd_bus_error *error) {
82 const char *id = NULL;
87 detect_virtualization(&id);
89 return sd_bus_message_append(reply, "s", id);
92 static int property_get_tainted(
95 const char *interface,
97 sd_bus_message *reply,
99 sd_bus_error *error) {
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;
110 e = stpcpy(e, "split-usr:");
112 if (readlink_malloc("/etc/mtab", &p) < 0)
113 e = stpcpy(e, "mtab-not-symlink:");
115 if (access("/proc/cgroups", F_OK) < 0)
116 e = stpcpy(e, "cgroups-missing:");
118 if (hwclock_is_localtime() > 0)
119 e = stpcpy(e, "local-hwclock:");
121 /* remove the last ':' */
125 return sd_bus_message_append(reply, "s", buf);
128 static int property_get_log_target(
131 const char *interface,
132 const char *property,
133 sd_bus_message *reply,
135 sd_bus_error *error) {
140 return sd_bus_message_append(reply, "s", log_target_to_string(log_get_target()));
143 static int property_set_log_target(
146 const char *interface,
147 const char *property,
148 sd_bus_message *value,
150 sd_bus_error *error) {
158 r = sd_bus_message_read(value, "s", &t);
162 return log_set_target_from_string(t);
165 static int property_get_log_level(
168 const char *interface,
169 const char *property,
170 sd_bus_message *reply,
172 sd_bus_error *error) {
174 _cleanup_free_ char *t = NULL;
180 r = log_level_to_string_alloc(log_get_max_level(), &t);
184 return sd_bus_message_append(reply, "s", t);
187 static int property_set_log_level(
190 const char *interface,
191 const char *property,
192 sd_bus_message *value,
194 sd_bus_error *error) {
202 r = sd_bus_message_read(value, "s", &t);
206 return log_set_max_level_from_string(t);
209 static int property_get_n_names(
212 const char *interface,
213 const char *property,
214 sd_bus_message *reply,
216 sd_bus_error *error) {
218 Manager *m = userdata;
224 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->units));
227 static int property_get_n_jobs(
230 const char *interface,
231 const char *property,
232 sd_bus_message *reply,
234 sd_bus_error *error) {
236 Manager *m = userdata;
242 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->jobs));
245 static int property_get_progress(
248 const char *interface,
249 const char *property,
250 sd_bus_message *reply,
252 sd_bus_error *error) {
254 Manager *m = userdata;
261 if (dual_timestamp_is_set(&m->finish_timestamp))
264 d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
266 return sd_bus_message_append(reply, "d", d);
269 static int property_set_runtime_watchdog(
272 const char *interface,
273 const char *property,
274 sd_bus_message *value,
276 sd_bus_error *error) {
278 usec_t *t = userdata;
284 assert_cc(sizeof(usec_t) == sizeof(uint64_t));
286 r = sd_bus_message_read(value, "t", t);
290 return watchdog_set_timeout(t);
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;
304 r = sd_bus_message_read(message, "s", &name);
308 u = manager_get_unit(m, name);
310 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
312 r = selinux_unit_access_check(u, bus, message, "status", error);
316 path = unit_dbus_path(u);
320 return sd_bus_reply_method_return(message, "o", path);
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;
334 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
336 r = sd_bus_message_read(message, "u", &pid);
341 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
346 u = manager_get_unit_by_pid(m, pid);
348 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID %u does not belong to any loaded unit.", pid);
350 r = selinux_unit_access_check(u, bus, message, "status", error);
354 path = unit_dbus_path(u);
358 return sd_bus_reply_method_return(message, "o", path);
361 static int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
362 _cleanup_free_ char *path = NULL;
363 Manager *m = userdata;
372 r = sd_bus_message_read(message, "s", &name);
376 r = manager_load_unit(m, name, NULL, error, &u);
380 r = selinux_unit_access_check(u, bus, message, "status", error);
384 path = unit_dbus_path(u);
388 return sd_bus_reply_method_return(message, "o", path);
391 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) {
400 r = sd_bus_message_read(message, "s", &name);
404 r = manager_load_unit(m, name, NULL, error, &u);
408 return bus_unit_method_start_generic(bus, message, u, job_type, reload_if_possible, error);
411 static int method_start_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
412 return method_start_unit_generic(bus, message, userdata, JOB_START, false, error);
415 static int method_stop_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
416 return method_start_unit_generic(bus, message, userdata, JOB_STOP, false, error);
419 static int method_reload_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
420 return method_start_unit_generic(bus, message, userdata, JOB_RELOAD, false, error);
423 static int method_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
424 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, false, error);
427 static int method_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
428 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, false, error);
431 static int method_reload_or_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
432 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, true, error);
435 static int method_reload_or_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
436 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, true, error);
439 static int method_start_unit_replace(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
440 Manager *m = userdata;
441 const char *old_name;
449 r = sd_bus_message_read(message, "s", &old_name);
453 u = manager_get_unit(m, old_name);
454 if (!u || !u->job || u->job->type != JOB_START)
455 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
457 return method_start_unit_generic(bus, message, m, JOB_START, false, error);
460 static int method_kill_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
461 Manager *m = userdata;
470 r = sd_bus_message_read(message, "s", &name);
474 u = manager_get_unit(m, name);
476 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
478 return bus_unit_method_kill(bus, message, u, error);
481 static int method_reset_failed_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
482 Manager *m = userdata;
491 r = sd_bus_message_read(message, "s", &name);
495 u = manager_get_unit(m, name);
497 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
499 return bus_unit_method_reset_failed(bus, message, u, error);
502 static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
503 Manager *m = userdata;
512 r = sd_bus_message_read(message, "s", &name);
516 u = manager_get_unit(m, name);
518 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
520 return bus_unit_method_set_properties(bus, message, u, error);
523 static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
524 const char *name, *smode;
525 Manager *m = userdata;
535 r = sd_bus_message_read(message, "ss", &name, &smode);
539 t = unit_name_to_type(name);
541 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit type.");
543 if (!unit_vtable[t]->can_transient)
544 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.");
546 mode = job_mode_from_string(smode);
548 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
550 r = selinux_access_check(bus, message, "start", error);
554 r = manager_load_unit(m, name, NULL, error, &u);
558 if (u->load_state != UNIT_NOT_FOUND || set_size(u->dependencies[UNIT_REFERENCED_BY]) > 0)
559 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
561 /* OK, the unit failed to load and is unreferenced, now let's
562 * fill in the transient data instead */
563 r = unit_make_transient(u);
567 /* Set our properties */
568 r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
572 /* And load this stub fully */
577 manager_dispatch_load_queue(m);
579 /* Finally, start it */
580 return bus_unit_queue_job(bus, message, u, JOB_START, mode, false, error);
583 static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
584 _cleanup_free_ char *path = NULL;
585 Manager *m = userdata;
594 r = sd_bus_message_read(message, "u", &id);
598 j = manager_get_job(m, id);
600 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
602 r = selinux_unit_access_check(j->unit, bus, message, "status", error);
606 path = job_dbus_path(j);
610 return sd_bus_reply_method_return(message, "o", path);
613 static int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
614 Manager *m = userdata;
623 r = sd_bus_message_read(message, "u", &id);
627 j = manager_get_job(m, id);
629 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
631 r = selinux_unit_access_check(j->unit, bus, message, "stop", error);
635 job_finish_and_invalidate(j, JOB_CANCELED, true);
637 return sd_bus_reply_method_return(message, NULL);
640 static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
641 Manager *m = userdata;
648 r = selinux_access_check(bus, message, "reboot", error);
652 manager_clear_jobs(m);
654 return sd_bus_reply_method_return(message, NULL);
657 static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
658 Manager *m = userdata;
665 r = selinux_access_check(bus, message, "reload", error);
669 manager_reset_failed(m);
671 return sd_bus_reply_method_return(message, NULL);
674 static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
675 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
676 Manager *m = userdata;
686 r = selinux_access_check(bus, message, "status", error);
690 r = sd_bus_message_new_method_return(message, &reply);
694 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
698 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
699 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
705 following = unit_following(u);
707 unit_path = unit_dbus_path(u);
712 job_path = job_dbus_path(u->job);
717 r = sd_bus_message_append(
718 reply, "(ssssssouso)",
721 unit_load_state_to_string(u->load_state),
722 unit_active_state_to_string(unit_active_state(u)),
723 unit_sub_state_to_string(u),
724 following ? following->id : "",
726 u->job ? u->job->id : 0,
727 u->job ? job_type_to_string(u->job->type) : "",
728 job_path ? job_path : "/");
733 r = sd_bus_message_close_container(reply);
737 return sd_bus_send(bus, reply, NULL);
740 static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
741 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
742 Manager *m = userdata;
751 r = selinux_access_check(bus, message, "status", error);
755 r = sd_bus_message_new_method_return(message, &reply);
759 r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
763 HASHMAP_FOREACH(j, m->jobs, i) {
764 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
766 job_path = job_dbus_path(j);
770 unit_path = unit_dbus_path(j->unit);
774 r = sd_bus_message_append(
778 job_type_to_string(j->type),
779 job_state_to_string(j->state),
786 r = sd_bus_message_close_container(reply);
790 return sd_bus_send(bus, reply, NULL);
793 static int method_subscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
794 Manager *m = userdata;
801 r = selinux_access_check(bus, message, "status", error);
805 r = bus_client_track(&m->subscribed, bus, sd_bus_message_get_sender(message));
809 return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
811 return sd_bus_reply_method_return(message, NULL);
814 static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
815 Manager *m = userdata;
822 r = selinux_access_check(bus, message, "status", error);
826 r = bus_client_untrack(m->subscribed, bus, sd_bus_message_get_sender(message));
830 return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
832 return sd_bus_reply_method_return(message, NULL);
835 static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
836 _cleanup_free_ char *dump = NULL;
837 _cleanup_fclose_ FILE *f = NULL;
838 Manager *m = userdata;
846 r = selinux_access_check(bus, message, "status", error);
850 f = open_memstream(&dump, &size);
854 manager_dump_units(m, f, NULL);
855 manager_dump_jobs(m, f, NULL);
862 return sd_bus_reply_method_return(message, "s", dump);
865 static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
866 _cleanup_free_ char *path = NULL;
867 Manager *m = userdata;
877 r = selinux_access_check(bus, message, "start", error);
881 r = sd_bus_message_read(message, "sb", &name, &cleanup);
888 r = snapshot_create(m, name, cleanup, error, &s);
892 path = unit_dbus_path(UNIT(s));
896 return sd_bus_reply_method_return(message, "o", path);
899 static int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
900 Manager *m = userdata;
909 r = selinux_access_check(bus, message, "stop", error);
913 r = sd_bus_message_read(message, "s", &name);
917 u = manager_get_unit(m, name);
919 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", name);
921 if (u->type != UNIT_SNAPSHOT)
922 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not a snapshot", name);
924 return bus_snapshot_method_remove(bus, message, u, error);
927 static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
928 Manager *m = userdata;
935 r = selinux_access_check(bus, message, "reload", error);
939 /* Instead of sending the reply back right away, we just
940 * remember that we need to and then send it after the reload
941 * is finished. That way the caller knows when the reload
944 assert(!m->queued_message);
945 r = sd_bus_message_new_method_return(message, &m->queued_message);
949 m->queued_message_bus = sd_bus_ref(bus);
950 m->exit_code = MANAGER_RELOAD;
955 static int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
956 Manager *m = userdata;
963 r = selinux_access_check(bus, message, "reload", error);
967 /* We don't send a reply back here, the client should
968 * just wait for us disconnecting. */
970 m->exit_code = MANAGER_REEXECUTE;
974 static int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
975 Manager *m = userdata;
982 r = selinux_access_check(bus, message, "halt", error);
986 if (m->running_as == SYSTEMD_SYSTEM)
987 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
989 m->exit_code = MANAGER_EXIT;
991 return sd_bus_reply_method_return(message, NULL);
994 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
995 Manager *m = userdata;
1002 r = selinux_access_check(bus, message, "reboot", error);
1006 if (m->running_as != SYSTEMD_SYSTEM)
1007 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
1009 m->exit_code = MANAGER_REBOOT;
1011 return sd_bus_reply_method_return(message, NULL);
1015 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1016 Manager *m = userdata;
1023 r = selinux_access_check(bus, message, "halt", error);
1027 if (m->running_as != SYSTEMD_SYSTEM)
1028 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
1030 m->exit_code = MANAGER_POWEROFF;
1032 return sd_bus_reply_method_return(message, NULL);
1035 static int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1036 Manager *m = userdata;
1043 r = selinux_access_check(bus, message, "halt", error);
1047 if (m->running_as != SYSTEMD_SYSTEM)
1048 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
1050 m->exit_code = MANAGER_HALT;
1052 return sd_bus_reply_method_return(message, NULL);
1055 static int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1056 Manager *m = userdata;
1063 r = selinux_access_check(bus, message, "reboot", error);
1067 if (m->running_as != SYSTEMD_SYSTEM)
1068 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1070 m->exit_code = MANAGER_KEXEC;
1072 return sd_bus_reply_method_return(message, NULL);
1075 static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1076 char *ri = NULL, *rt = NULL;
1077 const char *root, *init;
1078 Manager *m = userdata;
1085 r = selinux_access_check(bus, message, "reboot", error);
1089 if (m->running_as != SYSTEMD_SYSTEM)
1090 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1092 r = sd_bus_message_read(message, "ss", &root, &init);
1096 if (path_equal(root, "/") || !path_is_absolute(root))
1097 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
1100 if (isempty(init)) {
1101 if (! path_is_os_tree(root))
1102 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);
1104 _cleanup_free_ char *p = NULL;
1106 if (!path_is_absolute(init))
1107 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
1109 p = strappend(root, init);
1113 if (access(p, X_OK) < 0)
1114 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
1121 if (!isempty(init)) {
1129 free(m->switch_root);
1130 m->switch_root = rt;
1132 free(m->switch_root_init);
1133 m->switch_root_init = ri;
1135 m->exit_code = MANAGER_SWITCH_ROOT;
1137 return sd_bus_reply_method_return(message, NULL);
1140 static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1141 _cleanup_strv_free_ char **plus = NULL;
1142 Manager *m = userdata;
1149 r = selinux_access_check(bus, message, "reload", error);
1153 r = sd_bus_message_read_strv(message, &plus);
1156 if (!strv_env_is_valid(plus))
1157 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1159 r = manager_environment_add(m, NULL, plus);
1163 return sd_bus_reply_method_return(message, NULL);
1166 static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1167 _cleanup_strv_free_ char **minus = NULL;
1168 Manager *m = userdata;
1175 r = selinux_access_check(bus, message, "reload", error);
1179 r = sd_bus_message_read_strv(message, &minus);
1183 if (!strv_env_name_or_assignment_is_valid(minus))
1184 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1186 r = manager_environment_add(m, minus, NULL);
1190 return sd_bus_reply_method_return(message, NULL);
1193 static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1194 _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1195 Manager *m = userdata;
1202 r = selinux_access_check(bus, message, "reload", error);
1206 r = sd_bus_message_read_strv(message, &plus);
1210 r = sd_bus_message_read_strv(message, &minus);
1214 if (!strv_env_is_valid(plus))
1215 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1216 if (!strv_env_name_or_assignment_is_valid(minus))
1217 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1219 r = manager_environment_add(m, minus, plus);
1223 return sd_bus_reply_method_return(message, NULL);
1226 static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1227 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1228 Manager *m = userdata;
1238 r = selinux_access_check(bus, message, "status", error);
1242 r = sd_bus_message_new_method_return(message, &reply);
1246 h = hashmap_new(string_hash_func, string_compare_func);
1250 r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
1254 r = sd_bus_message_open_container(reply, 'a', "(ss)");
1258 HASHMAP_FOREACH(item, h, i) {
1260 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
1265 unit_file_list_free(h);
1267 r = sd_bus_message_close_container(reply);
1271 return sd_bus_send(bus, reply, NULL);
1274 unit_file_list_free(h);
1278 static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1279 Manager *m = userdata;
1281 UnitFileState state;
1282 UnitFileScope scope;
1289 r = selinux_access_check(bus, message, "status", error);
1293 r = sd_bus_message_read(message, "s", &name);
1297 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1299 state = unit_file_get_state(scope, NULL, name);
1303 return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
1306 static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1307 _cleanup_free_ char *default_target = NULL;
1308 Manager *m = userdata;
1309 UnitFileScope scope;
1316 r = selinux_access_check(bus, message, "status", error);
1320 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1322 r = unit_file_get_default(scope, NULL, &default_target);
1326 return sd_bus_reply_method_return(message, "s", default_target);
1329 static int send_unit_files_changed(sd_bus *bus, const char *destination, void *userdata) {
1330 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1335 r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged", &message);
1339 return sd_bus_send_to(bus, message, destination, NULL);
1342 static int reply_unit_file_changes_and_free(
1345 sd_bus_message *message,
1346 int carries_install_info,
1347 UnitFileChange *changes,
1348 unsigned n_changes) {
1350 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1355 bus_manager_foreach_client(m, send_unit_files_changed, NULL);
1357 r = sd_bus_message_new_method_return(message, &reply);
1361 if (carries_install_info >= 0) {
1362 r = sd_bus_message_append(reply, "b", carries_install_info);
1367 r = sd_bus_message_open_container(reply, 'a', "(sss)");
1371 for (i = 0; i < n_changes; i++) {
1372 r = sd_bus_message_append(
1374 unit_file_change_type_to_string(changes[i].type),
1381 r = sd_bus_message_close_container(reply);
1385 return sd_bus_send(bus, reply, NULL);
1388 unit_file_changes_free(changes, n_changes);
1392 static int method_enable_unit_files_generic(
1394 sd_bus_message *message,
1397 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
1398 bool carries_install_info,
1399 sd_bus_error *error) {
1401 _cleanup_strv_free_ char **l = NULL;
1402 UnitFileChange *changes = NULL;
1403 unsigned n_changes = 0;
1404 UnitFileScope scope;
1405 int runtime, force, r;
1411 r = selinux_access_check(bus, message, verb, error);
1415 r = sd_bus_message_read_strv(message, &l);
1419 r = sd_bus_message_read(message, "bb", &runtime, &force);
1423 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1425 r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
1429 return reply_unit_file_changes_and_free(m, bus, message, carries_install_info ? r : -1, changes, n_changes);
1432 static int method_enable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1433 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_enable, true, error);
1436 static int method_reenable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1437 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_reenable, true, error);
1440 static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1441 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
1444 static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1445 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset, true, error);
1448 static int method_mask_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, "disable", unit_file_mask, false, error);
1452 static int method_disable_unit_files_generic(
1454 sd_bus_message *message,
1457 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
1458 sd_bus_error *error) {
1460 _cleanup_strv_free_ char **l = NULL;
1461 UnitFileChange *changes = NULL;
1462 unsigned n_changes = 0;
1463 UnitFileScope scope;
1470 r = selinux_access_check(bus, message, verb, error);
1474 r = sd_bus_message_read_strv(message, &l);
1478 r = sd_bus_message_read(message, "b", &runtime);
1482 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1484 r = call(scope, runtime, NULL, l, &changes, &n_changes);
1488 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1491 static int method_disable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1492 return method_disable_unit_files_generic(bus, message, userdata, "disable", unit_file_disable, error);
1495 static int method_unmask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1496 return method_disable_unit_files_generic(bus, message, userdata, "enable", unit_file_unmask, error);
1499 static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1500 UnitFileChange *changes = NULL;
1501 unsigned n_changes = 0;
1502 Manager *m = userdata;
1503 UnitFileScope scope;
1511 r = selinux_access_check(bus, message, "enable", error);
1515 r = sd_bus_message_read(message, "sb", &name, &force);
1519 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1521 r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
1525 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1528 const sd_bus_vtable bus_manager_vtable[] = {
1529 SD_BUS_VTABLE_START(0),
1531 SD_BUS_PROPERTY("Version", "s", property_get_version, 0, 0),
1532 SD_BUS_PROPERTY("Features", "s", property_get_features, 0, 0),
1533 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, 0),
1534 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, 0),
1535 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), 0),
1536 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), 0),
1537 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), 0),
1538 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), 0),
1539 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), 0),
1540 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), 0),
1541 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), 0),
1542 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), 0),
1543 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), 0),
1544 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), 0),
1545 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), 0),
1546 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), 0),
1547 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
1548 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
1549 SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
1550 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
1551 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
1552 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
1553 SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
1554 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
1555 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), 0),
1556 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), 0),
1557 SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), 0),
1558 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), 0),
1559 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), 0),
1560 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0),
1561 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), 0),
1563 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, 0),
1564 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, 0),
1565 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, 0),
1566 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, 0),
1567 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, 0),
1568 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, 0),
1569 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, 0),
1570 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, 0),
1571 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, 0),
1572 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, 0),
1573 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, 0),
1574 SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, 0),
1575 SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, 0),
1576 SD_BUS_METHOD("SetUnitProperties", "sb", "a(sv)", method_set_unit_properties, 0),
1577 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, 0),
1578 SD_BUS_METHOD("GetJob", "u", "o", method_get_job, 0),
1579 SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, 0),
1580 SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, 0),
1581 SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, 0),
1582 SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, 0),
1583 SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, 0),
1584 SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, 0),
1585 SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, 0),
1586 SD_BUS_METHOD("Dump", NULL, "s", method_dump, 0),
1587 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, 0),
1588 SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, 0),
1589 SD_BUS_METHOD("Reload", NULL, NULL, method_reload, 0),
1590 SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, 0),
1591 SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
1592 SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, 0),
1593 SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, 0),
1594 SD_BUS_METHOD("Halt", NULL, NULL, method_halt, 0),
1595 SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, 0),
1596 SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, 0),
1597 SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, 0),
1598 SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, 0),
1599 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, 0),
1600 SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, 0),
1601 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, 0),
1602 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, 0),
1603 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, 0),
1604 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, 0),
1605 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, 0),
1606 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, 0),
1607 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, 0),
1608 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, 0),
1609 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, 0),
1610 SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, 0),
1612 SD_BUS_SIGNAL("UnitNew", "so", 0),
1613 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
1614 SD_BUS_SIGNAL("JobNew", "uos", 0),
1615 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
1616 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
1617 SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
1618 SD_BUS_SIGNAL("Reloading", "b", 0),
1623 int bus_manager_foreach_client(Manager *m, int (*send_message)(sd_bus *bus, const char *destination, void *userdata), void *userdata) {
1629 n = set_size(m->subscribed);
1633 BusTrackedClient *d;
1635 assert_se(d = set_first(m->subscribed));
1636 return send_message(d->bus, isempty(d->name) ? NULL : d->name, userdata);
1641 /* Send to everybody */
1642 SET_FOREACH(b, m->private_buses, i) {
1643 r = send_message(b, NULL, userdata);
1649 r = send_message(m->api_bus, NULL, userdata);
1657 static int send_finished(sd_bus *bus, const char *destination, void *userdata) {
1658 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1659 usec_t *times = userdata;
1665 r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished", &message);
1669 r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
1673 return sd_bus_send_to(bus, message, destination, NULL);
1676 void bus_manager_send_finished(
1678 usec_t firmware_usec,
1682 usec_t userspace_usec,
1683 usec_t total_usec) {
1689 r = bus_manager_foreach_client(m, send_finished,
1690 (usec_t[6]) { firmware_usec, loader_usec, kernel_usec, initrd_usec, userspace_usec, total_usec });
1692 log_debug("Failed to send finished signal: %s", strerror(-r));
1695 static int send_reloading(sd_bus *bus, const char *destination, void *userdata) {
1696 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1701 r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading", &message);
1705 r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
1709 return sd_bus_send_to(bus, message, destination, NULL);
1712 void bus_manager_send_reloading(Manager *m, bool active) {
1717 r = bus_manager_foreach_client(m, send_reloading, INT_TO_PTR(active));
1719 log_debug("Failed to send reloading signal: %s", strerror(-r));