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/>.
22 #include <sys/epoll.h>
23 #include <sys/timerfd.h>
32 #include "dbus-unit.h"
34 #include "dbus-manager.h"
35 #include "dbus-execute.h"
36 #include "dbus-kill.h"
37 #include "dbus-cgroup.h"
41 #include "bus-error.h"
42 #include "bus-errors.h"
44 #include "dbus-client-track.h"
45 #include "bus-internal.h"
46 #include "selinux-access.h"
48 #define CONNECTIONS_MAX 512
50 static void destroy_bus(Manager *m, sd_bus **bus);
52 int bus_send_queued_message(Manager *m) {
57 if (!m->queued_message)
60 assert(m->queued_message_bus);
62 /* If we cannot get rid of this message we won't dispatch any
63 * D-Bus messages, so that we won't end up wanting to queue
66 r = sd_bus_send(m->queued_message_bus, m->queued_message, NULL);
68 log_warning("Failed to send queued message: %s", strerror(-r));
70 m->queued_message = sd_bus_message_unref(m->queued_message);
71 m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
76 static int signal_agent_released(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
77 Manager *m = userdata;
85 r = sd_bus_message_read(message, "s", &cgroup);
87 bus_log_parse_error(r);
91 manager_notify_cgroup_empty(m, cgroup);
93 if (m->running_as == SYSTEMD_SYSTEM && m->system_bus) {
94 /* If we are running as system manager, forward the
95 * message to the system bus */
97 r = sd_bus_send(m->system_bus, message, NULL);
99 log_warning("Failed to forward Released message: %s", strerror(-r));
105 static int signal_disconnected(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
106 Manager *m = userdata;
112 if (bus == m->api_bus)
113 destroy_bus(m, &m->api_bus);
114 if (bus == m->system_bus)
115 destroy_bus(m, &m->system_bus);
116 if (set_remove(m->private_buses, bus)) {
117 log_debug("Got disconnect on private connection.");
118 destroy_bus(m, &bus);
124 static int signal_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
125 const char *name, *old_owner, *new_owner;
126 Manager *m = userdata;
133 r = sd_bus_message_read(message, "sss", &name, &old_owner, &new_owner);
135 bus_log_parse_error(r);
139 manager_dispatch_bus_name_owner_changed(
141 isempty(old_owner) ? NULL : old_owner,
142 isempty(new_owner) ? NULL : new_owner);
147 static int signal_activation_request(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
148 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
149 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
150 Manager *m = userdata;
159 r = sd_bus_message_read(message, "s", &name);
161 bus_log_parse_error(r);
165 if (manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SERVICE) ||
166 manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SOCKET)) {
167 r = sd_bus_error_setf(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down.");
171 r = manager_load_unit(m, name, NULL, &error, &u);
175 if (u->refuse_manual_start) {
176 r = sd_bus_error_setf(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, %u may be requested by dependency only.", u->id);
180 r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &error, NULL);
184 /* Successfully queued, that's it for us */
188 if (!sd_bus_error_is_set(&error))
189 sd_bus_error_set_errno(&error, r);
191 log_debug("D-Bus activation failed for %s: %s", name, bus_error_message(&error, r));
193 r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure", &reply);
195 bus_log_create_error(r);
199 r = sd_bus_message_append(reply, "sss", name, error.name, error.message);
201 bus_log_create_error(r);
205 r = sd_bus_send_to(bus, reply, "org.freedesktop.DBus", NULL);
207 log_error("Failed to respond with to bus activation request: %s", strerror(-r));
215 static int selinux_filter(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
216 Manager *m = userdata;
217 const char *verb, *path;
225 /* Our own method calls are all protected individually with
226 * selinux checks, but the built-in interfaces need to be
229 if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set"))
231 else if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", NULL) ||
232 sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", NULL) ||
233 sd_bus_message_is_method_call(message, "org.freedesktop.DBus.ObjectManager", NULL) ||
234 sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Peer", NULL))
239 path = sd_bus_message_get_path(message);
241 if (object_path_startswith("/org/freedesktop/systemd1", path)) {
243 r = selinux_access_check(bus, message, verb, error);
250 if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
251 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
254 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
258 r = sd_bus_creds_get_pid(creds, &pid);
262 u = manager_get_unit_by_pid(m, pid);
264 r = manager_get_job_from_dbus_path(m, path, &j);
268 manager_load_unit_from_dbus_path(m, path, NULL, &u);
274 r = selinux_unit_access_check(u, bus, message, verb, error);
282 static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
283 Manager *m = userdata;
293 r = manager_get_job_from_dbus_path(m, path, &j);
301 static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_bus_error *error) {
309 if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
310 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
311 sd_bus_message *message;
314 message = sd_bus_get_current(bus);
318 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
322 r = sd_bus_creds_get_pid(creds, &pid);
326 u = manager_get_unit_by_pid(m, pid);
328 r = manager_load_unit_from_dbus_path(m, path, error, &u);
340 static int bus_unit_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
341 Manager *m = userdata;
349 return find_unit(m, bus, path, (Unit**) found, error);
352 static int bus_unit_interface_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
353 Manager *m = userdata;
363 r = find_unit(m, bus, path, &u, error);
367 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
374 static int bus_unit_cgroup_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
375 Manager *m = userdata;
385 r = find_unit(m, bus, path, &u, error);
389 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
392 if (!unit_get_cgroup_context(u))
399 static int bus_cgroup_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
400 Manager *m = userdata;
411 r = find_unit(m, bus, path, &u, error);
415 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
418 c = unit_get_cgroup_context(u);
426 static int bus_exec_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
427 Manager *m = userdata;
438 r = find_unit(m, bus, path, &u, error);
442 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
445 c = unit_get_exec_context(u);
453 static int bus_kill_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
454 Manager *m = userdata;
465 r = find_unit(m, bus, path, &u, error);
469 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
472 c = unit_get_kill_context(u);
480 static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
481 _cleanup_free_ char **l = NULL;
482 Manager *m = userdata;
487 l = new0(char*, hashmap_size(m->jobs)+1);
491 HASHMAP_FOREACH(j, m->jobs, i) {
492 l[k] = job_dbus_path(j);
499 assert(hashmap_size(m->jobs) == k);
507 static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
508 _cleanup_free_ char **l = NULL;
509 Manager *m = userdata;
514 l = new0(char*, hashmap_size(m->units)+1);
518 HASHMAP_FOREACH(u, m->units, i) {
519 l[k] = unit_dbus_path(u);
532 static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
540 r = sd_bus_add_filter(bus, selinux_filter, m);
542 log_error("Failed to add SELinux access filter: %s", strerror(-r));
547 r = sd_bus_add_object_vtable(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
549 log_error("Failed to register Manager vtable: %s", strerror(-r));
553 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
555 log_error("Failed to register Job vtable: %s", strerror(-r));
559 r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
561 log_error("Failed to add job enumerator: %s", strerror(-r));
565 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
567 log_error("Failed to register Unit vtable: %s", strerror(-r));
571 r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
573 log_error("Failed to add job enumerator: %s", strerror(-r));
577 for (t = 0; t < _UNIT_TYPE_MAX; t++) {
578 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, unit_vtable[t]->bus_vtable, bus_unit_interface_find, m);
580 log_error("Failed to register type specific vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
584 if (unit_vtable[t]->cgroup_context_offset > 0) {
585 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_unit_cgroup_vtable, bus_unit_cgroup_find, m);
587 log_error("Failed to register control group unit vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
591 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
593 log_error("Failed to register control group vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
598 if (unit_vtable[t]->exec_context_offset > 0) {
599 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_exec_vtable, bus_exec_context_find, m);
601 log_error("Failed to register execute vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
606 if (unit_vtable[t]->kill_context_offset > 0) {
607 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_kill_vtable, bus_kill_context_find, m);
609 log_error("Failed to register kill vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
618 static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
624 r = sd_bus_add_match(
627 "path='/org/freedesktop/DBus/Local',"
628 "interface='org.freedesktop.DBus.Local',"
629 "member='Disconnected'",
630 signal_disconnected, m);
633 log_error("Failed to register match for Disconnected message: %s", strerror(-r));
640 static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
641 _cleanup_bus_unref_ sd_bus *bus = NULL;
642 _cleanup_close_ int nfd = -1;
643 Manager *m = userdata;
650 nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
652 log_warning("Failed to accept private connection, ignoring: %m");
656 if (set_size(m->private_buses) >= CONNECTIONS_MAX) {
657 log_warning("Too many concurrent connections, refusing");
661 r = set_ensure_allocated(&m->private_buses, trivial_hash_func, trivial_compare_func);
667 r = sd_bus_new(&bus);
669 log_warning("Failed to allocate new private connection bus: %s", strerror(-r));
673 r = sd_bus_set_fd(bus, nfd, nfd);
675 log_warning("Failed to set fd on new connection bus: %s", strerror(-r));
681 r = bus_check_peercred(bus);
683 log_warning("Incoming private connection from unprivileged client, refusing: %s", strerror(-r));
687 assert_se(sd_id128_randomize(&id) >= 0);
689 r = sd_bus_set_server(bus, 1, id);
691 log_warning("Failed to enable server support for new connection bus: %s", strerror(-r));
695 r = sd_bus_start(bus);
697 log_warning("Failed to start new connection bus: %s", strerror(-r));
701 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
703 log_warning("Failed to attach new connection bus to event loop: %s", strerror(-r));
707 if (m->running_as == SYSTEMD_SYSTEM) {
708 /* When we run as system instance we get the Released
709 * signal via a direct connection */
711 r = sd_bus_add_match(
714 "interface='org.freedesktop.systemd1.Agent',"
716 "path='/org/freedesktop/systemd1/agent'",
717 signal_agent_released, m);
720 log_warning("Failed to register Released match on new connection bus: %s", strerror(-r));
725 r = bus_setup_disconnected_match(m, bus);
729 r = bus_setup_api_vtables(m, bus);
731 log_warning("Failed to set up API vtables on new connection bus: %s", strerror(-r));
735 r = set_put(m->private_buses, bus);
737 log_warning("Failed to add new conenction bus to set: %s", strerror(-r));
743 log_debug("Accepted new private connection.");
748 static int bus_list_names(Manager *m, sd_bus *bus) {
749 _cleanup_strv_free_ char **names = NULL;
756 r = sd_bus_list_names(bus, &names, NULL);
758 log_error("Failed to get initial list of names: %s", strerror(-r));
762 /* This is a bit hacky, we say the owner of the name is the
763 * name itself, because we don't want the extra traffic to
764 * figure out the real owner. */
765 STRV_FOREACH(i, names)
766 manager_dispatch_bus_name_owner_changed(m, *i, NULL, *i);
771 static int bus_setup_api(Manager *m, sd_bus *bus) {
777 r = bus_setup_api_vtables(m, bus);
781 r = sd_bus_add_match(
784 "sender='org.freedesktop.DBus',"
785 "path='/org/freedesktop/DBus',"
786 "interface='org.freedesktop.DBus',"
787 "member='NameOwnerChanged'",
788 signal_name_owner_changed, m);
790 log_warning("Failed to subscribe to NameOwnerChanged signal: %s", strerror(-r));
792 r = sd_bus_add_match(
795 "sender='org.freedesktop.DBus',"
796 "path='/org/freedesktop/DBus',"
797 "interface='org.freedesktop.systemd1.Activator',"
798 "member='ActivationRequest'",
799 signal_activation_request, m);
801 log_warning("Failed to subscribe to activation signal: %s", strerror(-r));
803 /* Allow replacing of our name, to ease implementation of
804 * reexecution, where we keep the old connection open until
805 * after the new connection is set up and the name installed
806 * to allow clients to synchronously wait for reexecution to
808 r = sd_bus_request_name(bus,"org.freedesktop.systemd1", SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_ALLOW_REPLACEMENT);
810 log_error("Failed to register name: %s", strerror(-r));
814 bus_list_names(m, bus);
816 log_debug("Successfully connected to API bus.");
820 static int bus_init_api(Manager *m) {
821 _cleanup_bus_unref_ sd_bus *bus = NULL;
827 /* The API and system bus is the same if we are running in system mode */
828 if (m->running_as == SYSTEMD_SYSTEM && m->system_bus)
829 bus = sd_bus_ref(m->system_bus);
831 if (m->running_as == SYSTEMD_SYSTEM)
832 r = sd_bus_open_system(&bus);
834 r = sd_bus_open_user(&bus);
837 log_debug("Failed to connect to API bus, retrying later...");
841 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
843 log_error("Failed to attach API bus to event loop: %s", strerror(-r));
847 r = bus_setup_disconnected_match(m, bus);
852 r = bus_setup_api(m, bus);
854 log_error("Failed to set up API bus: %s", strerror(-r));
864 static int bus_setup_system(Manager *m, sd_bus *bus) {
870 if (m->running_as == SYSTEMD_SYSTEM)
873 /* If we are a user instance we get the Released message via
875 r = sd_bus_add_match(
878 "interface='org.freedesktop.systemd1.Agent',"
880 "path='/org/freedesktop/systemd1/agent'",
881 signal_agent_released, m);
884 log_warning("Failed to register Released match on system bus: %s", strerror(-r));
886 log_debug("Successfully connected to system bus.");
890 static int bus_init_system(Manager *m) {
891 _cleanup_bus_unref_ sd_bus *bus = NULL;
897 /* The API and system bus is the same if we are running in system mode */
898 if (m->running_as == SYSTEMD_SYSTEM && m->api_bus) {
899 m->system_bus = sd_bus_ref(m->api_bus);
903 r = sd_bus_open_system(&bus);
905 log_debug("Failed to connect to system bus, retrying later...");
909 r = bus_setup_disconnected_match(m, bus);
913 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
915 log_error("Failed to attach system bus to event loop: %s", strerror(-r));
919 r = bus_setup_system(m, bus);
921 log_error("Fauiled to set up system bus: %s", strerror(-r));
931 static int bus_init_private(Manager *m) {
932 _cleanup_close_ int fd = -1;
933 union sockaddr_union sa = {
934 .un.sun_family = AF_UNIX
942 if (m->private_listen_fd >= 0)
945 /* We don't need the private socket if we have kdbus */
946 if (m->kdbus_fd >= 0)
949 if (m->running_as == SYSTEMD_SYSTEM) {
951 /* We want the private bus only when running as init */
955 strcpy(sa.un.sun_path, "/run/systemd/private");
956 salen = offsetof(union sockaddr_union, un.sun_path) + sizeof("/run/systemd/private") - 1;
958 size_t left = sizeof(sa.un.sun_path);
959 char *p = sa.un.sun_path;
962 e = secure_getenv("XDG_RUNTIME_DIR");
964 log_error("Failed to determine XDG_RUNTIME_DIR");
968 left = strpcpy(&p, left, e);
969 left = strpcpy(&p, left, "/systemd/private");
971 salen = sizeof(sa.un) - left;
973 mkdir_parents_label(sa.un.sun_path, 0755);
976 unlink(sa.un.sun_path);
978 fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
980 log_error("Failed to allocate private socket: %m");
984 r = bind(fd, &sa.sa, salen);
986 log_error("Failed to bind private socket: %m");
990 r = listen(fd, SOMAXCONN);
992 log_error("Failed to make private socket listening: %m");
996 r = sd_event_add_io(m->event, fd, EPOLLIN, bus_on_connection, m, &s);
998 log_error("Failed to allocate event source: %s", strerror(-r));
1002 m->private_listen_fd = fd;
1003 m->private_listen_event_source = s;
1006 log_debug("Successfully created private D-Bus server.");
1011 int bus_init(Manager *m, bool try_bus_connect) {
1014 if (try_bus_connect) {
1015 r = bus_init_system(m);
1019 r = bus_init_api(m);
1024 r = bus_init_private(m);
1031 static void destroy_bus(Manager *m, sd_bus **bus) {
1041 /* Get rid of tracked clients on this bus */
1042 bus_client_untrack_bus(m->subscribed, *bus);
1043 HASHMAP_FOREACH(j, m->jobs, i)
1044 bus_client_untrack_bus(j->subscribed, *bus);
1046 /* Get rid of queued message on this bus */
1047 if (m->queued_message_bus == *bus) {
1048 m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
1050 if (m->queued_message)
1051 m->queued_message = sd_bus_message_unref(m->queued_message);
1054 /* Possibly flush unwritten data, but only if we are
1055 * unprivileged, since we don't want to sync here */
1056 if (m->running_as != SYSTEMD_SYSTEM)
1059 /* And destroy the object */
1061 *bus = sd_bus_unref(*bus);
1064 void bus_done(Manager *m) {
1070 destroy_bus(m, &m->api_bus);
1072 destroy_bus(m, &m->system_bus);
1073 while ((b = set_steal_first(m->private_buses)))
1076 set_free(m->private_buses);
1077 set_free(m->subscribed);
1079 if (m->private_listen_event_source)
1080 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
1082 if (m->private_listen_fd >= 0) {
1083 close_nointr_nofail(m->private_listen_fd);
1084 m->private_listen_fd = -1;
1088 int bus_fdset_add_all(Manager *m, FDSet *fds) {
1096 /* When we are about to reexecute we add all D-Bus fds to the
1097 * set to pass over to the newly executed systemd. They won't
1098 * be used there however, except thatt they are closed at the
1099 * very end of deserialization, those making it possible for
1100 * clients to synchronously wait for systemd to reexec by
1101 * simply waiting for disconnection */
1104 fd = sd_bus_get_fd(m->api_bus);
1106 fd = fdset_put_dup(fds, fd);
1112 SET_FOREACH(b, m->private_buses, i) {
1113 fd = sd_bus_get_fd(b);
1115 fd = fdset_put_dup(fds, fd);
1121 /* We don't offer any APIs on the system bus (well, unless it
1122 * is the same as the API bus) hence we don't bother with it
1128 void bus_serialize(Manager *m, FILE *f) {
1132 bus_client_track_serialize(m, f, m->subscribed);
1135 int bus_deserialize_item(Manager *m, const char *line) {
1139 return bus_client_track_deserialize_item(m, &m->subscribed, line);