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"
34 #include "architecture.h"
37 #include "dbus-manager.h"
38 #include "dbus-unit.h"
39 #include "dbus-snapshot.h"
40 #include "dbus-execute.h"
41 #include "bus-errors.h"
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_architecture(
95 const char *interface,
97 sd_bus_message *reply,
99 sd_bus_error *error) {
104 return sd_bus_message_append(reply, "s", architecture_to_string(uname_architecture()));
107 static int property_get_tainted(
110 const char *interface,
111 const char *property,
112 sd_bus_message *reply,
114 sd_bus_error *error) {
116 char buf[sizeof("split-usr:mtab-not-symlink:cgroups-missing:local-hwclock:")] = "", *e = buf;
117 _cleanup_free_ char *p = NULL;
118 Manager *m = userdata;
125 e = stpcpy(e, "split-usr:");
127 if (readlink_malloc("/etc/mtab", &p) < 0)
128 e = stpcpy(e, "mtab-not-symlink:");
130 if (access("/proc/cgroups", F_OK) < 0)
131 e = stpcpy(e, "cgroups-missing:");
133 if (hwclock_is_localtime() > 0)
134 e = stpcpy(e, "local-hwclock:");
136 /* remove the last ':' */
140 return sd_bus_message_append(reply, "s", buf);
143 static int property_get_log_target(
146 const char *interface,
147 const char *property,
148 sd_bus_message *reply,
150 sd_bus_error *error) {
155 return sd_bus_message_append(reply, "s", log_target_to_string(log_get_target()));
158 static int property_set_log_target(
161 const char *interface,
162 const char *property,
163 sd_bus_message *value,
165 sd_bus_error *error) {
173 r = sd_bus_message_read(value, "s", &t);
177 return log_set_target_from_string(t);
180 static int property_get_log_level(
183 const char *interface,
184 const char *property,
185 sd_bus_message *reply,
187 sd_bus_error *error) {
189 _cleanup_free_ char *t = NULL;
195 r = log_level_to_string_alloc(log_get_max_level(), &t);
199 return sd_bus_message_append(reply, "s", t);
202 static int property_set_log_level(
205 const char *interface,
206 const char *property,
207 sd_bus_message *value,
209 sd_bus_error *error) {
217 r = sd_bus_message_read(value, "s", &t);
221 return log_set_max_level_from_string(t);
224 static int property_get_n_names(
227 const char *interface,
228 const char *property,
229 sd_bus_message *reply,
231 sd_bus_error *error) {
233 Manager *m = userdata;
239 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->units));
242 static int property_get_n_jobs(
245 const char *interface,
246 const char *property,
247 sd_bus_message *reply,
249 sd_bus_error *error) {
251 Manager *m = userdata;
257 return sd_bus_message_append(reply, "u", (uint32_t) hashmap_size(m->jobs));
260 static int property_get_progress(
263 const char *interface,
264 const char *property,
265 sd_bus_message *reply,
267 sd_bus_error *error) {
269 Manager *m = userdata;
276 if (dual_timestamp_is_set(&m->finish_timestamp))
279 d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
281 return sd_bus_message_append(reply, "d", d);
284 static int property_set_runtime_watchdog(
287 const char *interface,
288 const char *property,
289 sd_bus_message *value,
291 sd_bus_error *error) {
293 usec_t *t = userdata;
299 assert_cc(sizeof(usec_t) == sizeof(uint64_t));
301 r = sd_bus_message_read(value, "t", t);
305 return watchdog_set_timeout(t);
308 static int method_get_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
309 _cleanup_free_ char *path = NULL;
310 Manager *m = userdata;
319 r = sd_bus_message_read(message, "s", &name);
323 u = manager_get_unit(m, name);
325 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", name);
327 r = selinux_unit_access_check(u, bus, message, "status", error);
331 path = unit_dbus_path(u);
335 return sd_bus_reply_method_return(message, "o", path);
338 static int method_get_unit_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
339 _cleanup_free_ char *path = NULL;
340 Manager *m = userdata;
349 assert_cc(sizeof(pid_t) == sizeof(uint32_t));
351 r = sd_bus_message_read(message, "u", &pid);
356 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
358 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
362 r = sd_bus_creds_get_pid(creds, &pid);
367 u = manager_get_unit_by_pid(m, pid);
369 return sd_bus_error_setf(error, BUS_ERROR_NO_UNIT_FOR_PID, "PID %u does not belong to any loaded unit.", pid);
371 r = selinux_unit_access_check(u, bus, message, "status", error);
375 path = unit_dbus_path(u);
379 return sd_bus_reply_method_return(message, "o", path);
382 static int method_load_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
383 _cleanup_free_ char *path = NULL;
384 Manager *m = userdata;
393 r = sd_bus_message_read(message, "s", &name);
397 r = manager_load_unit(m, name, NULL, error, &u);
401 r = selinux_unit_access_check(u, bus, message, "status", error);
405 path = unit_dbus_path(u);
409 return sd_bus_reply_method_return(message, "o", path);
412 static int method_start_unit_generic(sd_bus *bus, sd_bus_message *message, Manager *m, JobType job_type, bool reload_if_possible, sd_bus_error *error) {
421 r = sd_bus_message_read(message, "s", &name);
425 r = manager_load_unit(m, name, NULL, error, &u);
429 return bus_unit_method_start_generic(bus, message, u, job_type, reload_if_possible, error);
432 static int method_start_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
433 return method_start_unit_generic(bus, message, userdata, JOB_START, false, error);
436 static int method_stop_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
437 return method_start_unit_generic(bus, message, userdata, JOB_STOP, false, error);
440 static int method_reload_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
441 return method_start_unit_generic(bus, message, userdata, JOB_RELOAD, false, error);
444 static int method_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
445 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, false, error);
448 static int method_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
449 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, false, error);
452 static int method_reload_or_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
453 return method_start_unit_generic(bus, message, userdata, JOB_RESTART, true, error);
456 static int method_reload_or_try_restart_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
457 return method_start_unit_generic(bus, message, userdata, JOB_TRY_RESTART, true, error);
460 static int method_start_unit_replace(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
461 Manager *m = userdata;
462 const char *old_name;
470 r = sd_bus_message_read(message, "s", &old_name);
474 u = manager_get_unit(m, old_name);
475 if (!u || !u->job || u->job->type != JOB_START)
476 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "No job queued for unit %s", old_name);
478 return method_start_unit_generic(bus, message, m, JOB_START, false, error);
481 static int method_kill_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_kill(bus, message, u, error);
502 static int method_reset_failed_unit(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_reset_failed(bus, message, u, error);
523 static int method_set_unit_properties(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
524 Manager *m = userdata;
533 r = sd_bus_message_read(message, "s", &name);
537 u = manager_get_unit(m, name);
539 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not loaded.", name);
541 return bus_unit_method_set_properties(bus, message, u, error);
544 static int method_start_transient_unit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
545 const char *name, *smode;
546 Manager *m = userdata;
556 r = sd_bus_message_read(message, "ss", &name, &smode);
560 t = unit_name_to_type(name);
562 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit type.");
564 if (!unit_vtable[t]->can_transient)
565 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit type %s does not support transient units.", unit_type_to_string(t));
567 mode = job_mode_from_string(smode);
569 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Job mode %s is invalid.", smode);
571 r = selinux_access_check(bus, message, "start", error);
575 r = manager_load_unit(m, name, NULL, error, &u);
579 if (u->load_state != UNIT_NOT_FOUND || set_size(u->dependencies[UNIT_REFERENCED_BY]) > 0)
580 return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name);
582 /* OK, the unit failed to load and is unreferenced, now let's
583 * fill in the transient data instead */
584 r = unit_make_transient(u);
588 /* Set our properties */
589 r = bus_unit_set_properties(u, message, UNIT_RUNTIME, false, error);
593 /* And load this stub fully */
598 manager_dispatch_load_queue(m);
600 /* Finally, start it */
601 return bus_unit_queue_job(bus, message, u, JOB_START, mode, false, error);
604 static int method_get_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
605 _cleanup_free_ char *path = NULL;
606 Manager *m = userdata;
615 r = sd_bus_message_read(message, "u", &id);
619 j = manager_get_job(m, id);
621 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
623 r = selinux_unit_access_check(j->unit, bus, message, "status", error);
627 path = job_dbus_path(j);
631 return sd_bus_reply_method_return(message, "o", path);
634 static int method_cancel_job(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
635 Manager *m = userdata;
644 r = sd_bus_message_read(message, "u", &id);
648 j = manager_get_job(m, id);
650 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_JOB, "Job %u does not exist.", (unsigned) id);
652 r = selinux_unit_access_check(j->unit, bus, message, "stop", error);
656 job_finish_and_invalidate(j, JOB_CANCELED, true);
658 return sd_bus_reply_method_return(message, NULL);
661 static int method_clear_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
662 Manager *m = userdata;
669 r = selinux_access_check(bus, message, "reboot", error);
673 manager_clear_jobs(m);
675 return sd_bus_reply_method_return(message, NULL);
678 static int method_reset_failed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
679 Manager *m = userdata;
686 r = selinux_access_check(bus, message, "reload", error);
690 manager_reset_failed(m);
692 return sd_bus_reply_method_return(message, NULL);
695 static int method_list_units(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
696 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
697 Manager *m = userdata;
707 r = selinux_access_check(bus, message, "status", error);
711 r = sd_bus_message_new_method_return(message, &reply);
715 r = sd_bus_message_open_container(reply, 'a', "(ssssssouso)");
719 HASHMAP_FOREACH_KEY(u, k, m->units, i) {
720 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
726 following = unit_following(u);
728 unit_path = unit_dbus_path(u);
733 job_path = job_dbus_path(u->job);
738 r = sd_bus_message_append(
739 reply, "(ssssssouso)",
742 unit_load_state_to_string(u->load_state),
743 unit_active_state_to_string(unit_active_state(u)),
744 unit_sub_state_to_string(u),
745 following ? following->id : "",
747 u->job ? u->job->id : 0,
748 u->job ? job_type_to_string(u->job->type) : "",
749 job_path ? job_path : "/");
754 r = sd_bus_message_close_container(reply);
758 return sd_bus_send(bus, reply, NULL);
761 static int method_list_jobs(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
762 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
763 Manager *m = userdata;
772 r = selinux_access_check(bus, message, "status", error);
776 r = sd_bus_message_new_method_return(message, &reply);
780 r = sd_bus_message_open_container(reply, 'a', "(usssoo)");
784 HASHMAP_FOREACH(j, m->jobs, i) {
785 _cleanup_free_ char *unit_path = NULL, *job_path = NULL;
787 job_path = job_dbus_path(j);
791 unit_path = unit_dbus_path(j->unit);
795 r = sd_bus_message_append(
799 job_type_to_string(j->type),
800 job_state_to_string(j->state),
807 r = sd_bus_message_close_container(reply);
811 return sd_bus_send(bus, reply, NULL);
814 static int method_subscribe(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 if (bus == m->api_bus) {
828 /* Note that direct bus connection subscribe by
829 * default, we only track peers on the API bus here */
831 if (!m->subscribed) {
832 r = sd_bus_track_new(bus, &m->subscribed, NULL, NULL);
837 r = sd_bus_track_add_sender(m->subscribed, message);
841 return sd_bus_error_setf(error, BUS_ERROR_ALREADY_SUBSCRIBED, "Client is already subscribed.");
844 return sd_bus_reply_method_return(message, NULL);
847 static int method_unsubscribe(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
848 Manager *m = userdata;
855 r = selinux_access_check(bus, message, "status", error);
859 if (bus == m->api_bus) {
860 r = sd_bus_track_remove_sender(m->subscribed, message);
864 return sd_bus_error_setf(error, BUS_ERROR_NOT_SUBSCRIBED, "Client is not subscribed.");
867 return sd_bus_reply_method_return(message, NULL);
870 static int method_dump(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
871 _cleanup_free_ char *dump = NULL;
872 _cleanup_fclose_ FILE *f = NULL;
873 Manager *m = userdata;
881 r = selinux_access_check(bus, message, "status", error);
885 f = open_memstream(&dump, &size);
889 manager_dump_units(m, f, NULL);
890 manager_dump_jobs(m, f, NULL);
897 return sd_bus_reply_method_return(message, "s", dump);
900 static int method_create_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
901 _cleanup_free_ char *path = NULL;
902 Manager *m = userdata;
912 r = selinux_access_check(bus, message, "start", error);
916 r = sd_bus_message_read(message, "sb", &name, &cleanup);
923 r = snapshot_create(m, name, cleanup, error, &s);
927 path = unit_dbus_path(UNIT(s));
931 return sd_bus_reply_method_return(message, "o", path);
934 static int method_remove_snapshot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
935 Manager *m = userdata;
944 r = selinux_access_check(bus, message, "stop", error);
948 r = sd_bus_message_read(message, "s", &name);
952 u = manager_get_unit(m, name);
954 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s does not exist.", name);
956 if (u->type != UNIT_SNAPSHOT)
957 return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s is not a snapshot", name);
959 return bus_snapshot_method_remove(bus, message, u, error);
962 static int method_reload(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
963 Manager *m = userdata;
970 r = selinux_access_check(bus, message, "reload", error);
974 /* Instead of sending the reply back right away, we just
975 * remember that we need to and then send it after the reload
976 * is finished. That way the caller knows when the reload
979 assert(!m->queued_message);
980 r = sd_bus_message_new_method_return(message, &m->queued_message);
984 m->queued_message_bus = sd_bus_ref(bus);
985 m->exit_code = MANAGER_RELOAD;
990 static int method_reexecute(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
991 Manager *m = userdata;
998 r = selinux_access_check(bus, message, "reload", error);
1002 /* We don't send a reply back here, the client should
1003 * just wait for us disconnecting. */
1005 m->exit_code = MANAGER_REEXECUTE;
1009 static int method_exit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1010 Manager *m = userdata;
1017 r = selinux_access_check(bus, message, "halt", error);
1021 if (m->running_as == SYSTEMD_SYSTEM)
1022 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Exit is only supported for user service managers.");
1024 m->exit_code = MANAGER_EXIT;
1026 return sd_bus_reply_method_return(message, NULL);
1029 static int method_reboot(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1030 Manager *m = userdata;
1037 r = selinux_access_check(bus, message, "reboot", error);
1041 if (m->running_as != SYSTEMD_SYSTEM)
1042 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers.");
1044 m->exit_code = MANAGER_REBOOT;
1046 return sd_bus_reply_method_return(message, NULL);
1050 static int method_poweroff(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1051 Manager *m = userdata;
1058 r = selinux_access_check(bus, message, "halt", error);
1062 if (m->running_as != SYSTEMD_SYSTEM)
1063 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers.");
1065 m->exit_code = MANAGER_POWEROFF;
1067 return sd_bus_reply_method_return(message, NULL);
1070 static int method_halt(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1071 Manager *m = userdata;
1078 r = selinux_access_check(bus, message, "halt", error);
1082 if (m->running_as != SYSTEMD_SYSTEM)
1083 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers.");
1085 m->exit_code = MANAGER_HALT;
1087 return sd_bus_reply_method_return(message, NULL);
1090 static int method_kexec(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1091 Manager *m = userdata;
1098 r = selinux_access_check(bus, message, "reboot", error);
1102 if (m->running_as != SYSTEMD_SYSTEM)
1103 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1105 m->exit_code = MANAGER_KEXEC;
1107 return sd_bus_reply_method_return(message, NULL);
1110 static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1111 char *ri = NULL, *rt = NULL;
1112 const char *root, *init;
1113 Manager *m = userdata;
1120 r = selinux_access_check(bus, message, "reboot", error);
1124 if (m->running_as != SYSTEMD_SYSTEM)
1125 return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers.");
1127 r = sd_bus_message_read(message, "ss", &root, &init);
1131 if (path_equal(root, "/") || !path_is_absolute(root))
1132 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid switch root path %s", root);
1135 if (isempty(init)) {
1136 if (! path_is_os_tree(root))
1137 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. /etc/os-release is missing.", root);
1139 _cleanup_free_ char *p = NULL;
1141 if (!path_is_absolute(init))
1142 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid init path %s", init);
1144 p = strappend(root, init);
1148 if (access(p, X_OK) < 0)
1149 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified init binary %s does not exist.", p);
1156 if (!isempty(init)) {
1164 free(m->switch_root);
1165 m->switch_root = rt;
1167 free(m->switch_root_init);
1168 m->switch_root_init = ri;
1170 m->exit_code = MANAGER_SWITCH_ROOT;
1172 return sd_bus_reply_method_return(message, NULL);
1175 static int method_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1176 _cleanup_strv_free_ char **plus = NULL;
1177 Manager *m = userdata;
1184 r = selinux_access_check(bus, message, "reload", error);
1188 r = sd_bus_message_read_strv(message, &plus);
1191 if (!strv_env_is_valid(plus))
1192 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1194 r = manager_environment_add(m, NULL, plus);
1198 return sd_bus_reply_method_return(message, NULL);
1201 static int method_unset_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1202 _cleanup_strv_free_ char **minus = NULL;
1203 Manager *m = userdata;
1210 r = selinux_access_check(bus, message, "reload", error);
1214 r = sd_bus_message_read_strv(message, &minus);
1218 if (!strv_env_name_or_assignment_is_valid(minus))
1219 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1221 r = manager_environment_add(m, minus, NULL);
1225 return sd_bus_reply_method_return(message, NULL);
1228 static int method_unset_and_set_environment(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1229 _cleanup_strv_free_ char **minus = NULL, **plus = NULL;
1230 Manager *m = userdata;
1237 r = selinux_access_check(bus, message, "reload", error);
1241 r = sd_bus_message_read_strv(message, &plus);
1245 r = sd_bus_message_read_strv(message, &minus);
1249 if (!strv_env_is_valid(plus))
1250 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
1251 if (!strv_env_name_or_assignment_is_valid(minus))
1252 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment variable names or assignments");
1254 r = manager_environment_add(m, minus, plus);
1258 return sd_bus_reply_method_return(message, NULL);
1261 static int method_list_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1262 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1263 Manager *m = userdata;
1273 r = selinux_access_check(bus, message, "status", error);
1277 r = sd_bus_message_new_method_return(message, &reply);
1281 h = hashmap_new(string_hash_func, string_compare_func);
1285 r = unit_file_get_list(m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
1289 r = sd_bus_message_open_container(reply, 'a', "(ss)");
1293 HASHMAP_FOREACH(item, h, i) {
1295 r = sd_bus_message_append(reply, "(ss)", item->path, unit_file_state_to_string(item->state));
1300 unit_file_list_free(h);
1302 r = sd_bus_message_close_container(reply);
1306 return sd_bus_send(bus, reply, NULL);
1309 unit_file_list_free(h);
1313 static int method_get_unit_file_state(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1314 Manager *m = userdata;
1316 UnitFileState state;
1317 UnitFileScope scope;
1324 r = selinux_access_check(bus, message, "status", error);
1328 r = sd_bus_message_read(message, "s", &name);
1332 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1334 state = unit_file_get_state(scope, NULL, name);
1338 return sd_bus_reply_method_return(message, "s", unit_file_state_to_string(state));
1341 static int method_get_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1342 _cleanup_free_ char *default_target = NULL;
1343 Manager *m = userdata;
1344 UnitFileScope scope;
1351 r = selinux_access_check(bus, message, "status", error);
1355 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1357 r = unit_file_get_default(scope, NULL, &default_target);
1361 return sd_bus_reply_method_return(message, "s", default_target);
1364 static int send_unit_files_changed(sd_bus *bus, void *userdata) {
1365 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1370 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
1374 return sd_bus_send(bus, message, NULL);
1377 static int reply_unit_file_changes_and_free(
1380 sd_bus_message *message,
1381 int carries_install_info,
1382 UnitFileChange *changes,
1383 unsigned n_changes) {
1385 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1389 if (n_changes > 0) {
1390 r = bus_foreach_bus(m, NULL, send_unit_files_changed, NULL);
1392 log_debug("Failed to send UnitFilesChanged signal: %s", strerror(-r));
1395 r = sd_bus_message_new_method_return(message, &reply);
1399 if (carries_install_info >= 0) {
1400 r = sd_bus_message_append(reply, "b", carries_install_info);
1405 r = sd_bus_message_open_container(reply, 'a', "(sss)");
1409 for (i = 0; i < n_changes; i++) {
1410 r = sd_bus_message_append(
1412 unit_file_change_type_to_string(changes[i].type),
1419 r = sd_bus_message_close_container(reply);
1423 return sd_bus_send(bus, reply, NULL);
1426 unit_file_changes_free(changes, n_changes);
1430 static int method_enable_unit_files_generic(
1432 sd_bus_message *message,
1435 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], bool force, UnitFileChange **changes, unsigned *n_changes),
1436 bool carries_install_info,
1437 sd_bus_error *error) {
1439 _cleanup_strv_free_ char **l = NULL;
1443 UnitFileChange *changes = NULL;
1444 unsigned n_changes = 0;
1445 UnitFileScope scope;
1446 int runtime, force, r;
1452 r = sd_bus_message_read_strv(message, &l);
1457 STRV_FOREACH(i, l) {
1460 u = manager_get_unit(m, *i);
1462 r = selinux_unit_access_check(u, bus, message, verb, error);
1469 r = sd_bus_message_read(message, "bb", &runtime, &force);
1473 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1475 r = call(scope, runtime, NULL, l, force, &changes, &n_changes);
1479 return reply_unit_file_changes_and_free(m, bus, message, carries_install_info ? r : -1, changes, n_changes);
1482 static int method_enable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1483 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_enable, true, error);
1486 static int method_reenable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1487 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_reenable, true, error);
1490 static int method_link_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1491 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_link, false, error);
1494 static int method_preset_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1495 return method_enable_unit_files_generic(bus, message, userdata, "enable", unit_file_preset, true, error);
1498 static int method_mask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1499 return method_enable_unit_files_generic(bus, message, userdata, "disable", unit_file_mask, false, error);
1502 static int method_disable_unit_files_generic(
1504 sd_bus_message *message,
1507 int (*call)(UnitFileScope scope, bool runtime, const char *root_dir, char *files[], UnitFileChange **changes, unsigned *n_changes),
1508 sd_bus_error *error) {
1510 _cleanup_strv_free_ char **l = NULL;
1511 UnitFileChange *changes = NULL;
1512 unsigned n_changes = 0;
1513 UnitFileScope scope;
1520 r = selinux_access_check(bus, message, verb, error);
1524 r = sd_bus_message_read_strv(message, &l);
1528 r = sd_bus_message_read(message, "b", &runtime);
1532 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1534 r = call(scope, runtime, NULL, l, &changes, &n_changes);
1538 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1541 static int method_disable_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1542 return method_disable_unit_files_generic(bus, message, userdata, "disable", unit_file_disable, error);
1545 static int method_unmask_unit_files(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1546 return method_disable_unit_files_generic(bus, message, userdata, "enable", unit_file_unmask, error);
1549 static int method_set_default_target(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
1550 UnitFileChange *changes = NULL;
1551 unsigned n_changes = 0;
1552 Manager *m = userdata;
1553 UnitFileScope scope;
1561 r = selinux_access_check(bus, message, "enable", error);
1565 r = sd_bus_message_read(message, "sb", &name, &force);
1569 scope = m->running_as == SYSTEMD_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
1571 r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes);
1575 return reply_unit_file_changes_and_free(m, bus, message, -1, changes, n_changes);
1578 const sd_bus_vtable bus_manager_vtable[] = {
1579 SD_BUS_VTABLE_START(0),
1581 SD_BUS_PROPERTY("Version", "s", property_get_version, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1582 SD_BUS_PROPERTY("Features", "s", property_get_features, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1583 SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1584 SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1585 SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST),
1586 BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1587 BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1588 BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1589 BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1590 BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1591 BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1592 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1593 BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1594 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1595 BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1596 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1597 BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
1598 SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0),
1599 SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0),
1600 SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0),
1601 SD_BUS_PROPERTY("NJobs", "u", property_get_n_jobs, 0, 0),
1602 SD_BUS_PROPERTY("NInstalledJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_installed_jobs), 0),
1603 SD_BUS_PROPERTY("NFailedJobs", "u", bus_property_get_unsigned, offsetof(Manager, n_failed_jobs), 0),
1604 SD_BUS_PROPERTY("Progress", "d", property_get_progress, 0, 0),
1605 SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0),
1606 SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST),
1607 SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST),
1608 SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), SD_BUS_VTABLE_PROPERTY_CONST),
1609 SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1610 SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST),
1611 SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), SD_BUS_VTABLE_PROPERTY_CONST),
1612 SD_BUS_WRITABLE_PROPERTY("ShutdownWatchdogUSec", "t", bus_property_get_usec, bus_property_set_usec, offsetof(Manager, shutdown_watchdog), SD_BUS_VTABLE_PROPERTY_CONST),
1613 SD_BUS_PROPERTY("ControlGroup", "s", NULL, offsetof(Manager, cgroup_root), 0),
1615 SD_BUS_METHOD("GetUnit", "s", "o", method_get_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1616 SD_BUS_METHOD("GetUnitByPID", "u", "o", method_get_unit_by_pid, SD_BUS_VTABLE_UNPRIVILEGED),
1617 SD_BUS_METHOD("LoadUnit", "s", "o", method_load_unit, SD_BUS_VTABLE_UNPRIVILEGED),
1618 SD_BUS_METHOD("StartUnit", "ss", "o", method_start_unit, 0),
1619 SD_BUS_METHOD("StartUnitReplace", "sss", "o", method_start_unit_replace, 0),
1620 SD_BUS_METHOD("StopUnit", "ss", "o", method_stop_unit, 0),
1621 SD_BUS_METHOD("ReloadUnit", "ss", "o", method_reload_unit, 0),
1622 SD_BUS_METHOD("RestartUnit", "ss", "o", method_restart_unit, 0),
1623 SD_BUS_METHOD("TryRestartUnit", "ss", "o", method_try_restart_unit, 0),
1624 SD_BUS_METHOD("ReloadOrRestartUnit", "ss", "o", method_reload_or_restart_unit, 0),
1625 SD_BUS_METHOD("ReloadOrTryRestartUnit", "ss", "o", method_reload_or_try_restart_unit, 0),
1626 SD_BUS_METHOD("KillUnit", "ssi", NULL, method_kill_unit, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
1627 SD_BUS_METHOD("ResetFailedUnit", "s", NULL, method_reset_failed_unit, 0),
1628 SD_BUS_METHOD("SetUnitProperties", "sba(sv)", NULL, method_set_unit_properties, 0),
1629 SD_BUS_METHOD("StartTransientUnit", "ssa(sv)a(sa(sv))", "o", method_start_transient_unit, 0),
1630 SD_BUS_METHOD("GetJob", "u", "o", method_get_job, SD_BUS_VTABLE_UNPRIVILEGED),
1631 SD_BUS_METHOD("CancelJob", "u", NULL, method_cancel_job, 0),
1632 SD_BUS_METHOD("ClearJobs", NULL, NULL, method_clear_jobs, 0),
1633 SD_BUS_METHOD("ResetFailed", NULL, NULL, method_reset_failed, 0),
1634 SD_BUS_METHOD("ListUnits", NULL, "a(ssssssouso)", method_list_units, SD_BUS_VTABLE_UNPRIVILEGED),
1635 SD_BUS_METHOD("ListJobs", NULL, "a(usssoo)", method_list_jobs, SD_BUS_VTABLE_UNPRIVILEGED),
1636 SD_BUS_METHOD("Subscribe", NULL, NULL, method_subscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1637 SD_BUS_METHOD("Unsubscribe", NULL, NULL, method_unsubscribe, SD_BUS_VTABLE_UNPRIVILEGED),
1638 SD_BUS_METHOD("Dump", NULL, "s", method_dump, SD_BUS_VTABLE_UNPRIVILEGED),
1639 SD_BUS_METHOD("CreateSnapshot", "sb", "o", method_create_snapshot, 0),
1640 SD_BUS_METHOD("RemoveSnapshot", "s", NULL, method_remove_snapshot, 0),
1641 SD_BUS_METHOD("Reload", NULL, NULL, method_reload, 0),
1642 SD_BUS_METHOD("Reexecute", NULL, NULL, method_reexecute, 0),
1643 SD_BUS_METHOD("Exit", NULL, NULL, method_exit, 0),
1644 SD_BUS_METHOD("Reboot", NULL, NULL, method_reboot, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1645 SD_BUS_METHOD("PowerOff", NULL, NULL, method_poweroff, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1646 SD_BUS_METHOD("Halt", NULL, NULL, method_halt, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1647 SD_BUS_METHOD("KExec", NULL, NULL, method_kexec, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1648 SD_BUS_METHOD("SwitchRoot", "ss", NULL, method_switch_root, SD_BUS_VTABLE_CAPABILITY(CAP_SYS_BOOT)),
1649 SD_BUS_METHOD("SetEnvironment", "as", NULL, method_set_environment, 0),
1650 SD_BUS_METHOD("UnsetEnvironment", "as", NULL, method_unset_environment, 0),
1651 SD_BUS_METHOD("UnsetAndSetEnvironment", "asas", NULL, method_unset_and_set_environment, 0),
1652 SD_BUS_METHOD("ListUnitFiles", NULL, "a(ss)", method_list_unit_files, SD_BUS_VTABLE_UNPRIVILEGED),
1653 SD_BUS_METHOD("GetUnitFileState", "s", "s", method_get_unit_file_state, SD_BUS_VTABLE_UNPRIVILEGED),
1654 SD_BUS_METHOD("EnableUnitFiles", "asbb", "ba(sss)", method_enable_unit_files, 0),
1655 SD_BUS_METHOD("DisableUnitFiles", "asb", "a(sss)", method_disable_unit_files, 0),
1656 SD_BUS_METHOD("ReenableUnitFiles", "asbb", "ba(sss)", method_reenable_unit_files, 0),
1657 SD_BUS_METHOD("LinkUnitFiles", "asbb", "a(sss)", method_link_unit_files, 0),
1658 SD_BUS_METHOD("PresetUnitFiles", "asbb", "ba(sss)", method_preset_unit_files, 0),
1659 SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, 0),
1660 SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, 0),
1661 SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, 0),
1662 SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED),
1664 SD_BUS_SIGNAL("UnitNew", "so", 0),
1665 SD_BUS_SIGNAL("UnitRemoved", "so", 0),
1666 SD_BUS_SIGNAL("JobNew", "uos", 0),
1667 SD_BUS_SIGNAL("JobRemoved", "uoss", 0),
1668 SD_BUS_SIGNAL("StartupFinished", "tttttt", 0),
1669 SD_BUS_SIGNAL("UnitFilesChanged", NULL, 0),
1670 SD_BUS_SIGNAL("Reloading", "b", 0),
1675 static int send_finished(sd_bus *bus, void *userdata) {
1676 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1677 usec_t *times = userdata;
1683 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
1687 r = sd_bus_message_append(message, "tttttt", times[0], times[1], times[2], times[3], times[4], times[5]);
1691 return sd_bus_send(bus, message, NULL);
1694 void bus_manager_send_finished(
1696 usec_t firmware_usec,
1700 usec_t userspace_usec,
1701 usec_t total_usec) {
1707 r = bus_foreach_bus(
1720 log_debug("Failed to send finished signal: %s", strerror(-r));
1723 static int send_reloading(sd_bus *bus, void *userdata) {
1724 _cleanup_bus_message_unref_ sd_bus_message *message = NULL;
1729 r = sd_bus_message_new_signal(bus, &message, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
1733 r = sd_bus_message_append(message, "b", PTR_TO_INT(userdata));
1737 return sd_bus_send(bus, message, NULL);
1740 void bus_manager_send_reloading(Manager *m, bool active) {
1745 r = bus_foreach_bus(m, NULL, send_reloading, INT_TO_PTR(active));
1747 log_debug("Failed to send reloading signal: %s", strerror(-r));