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));
214 static int selinux_filter(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
215 Manager *m = userdata;
216 const char *verb, *path;
224 /* Our own method calls are all protected individually with
225 * selinux checks, but the built-in interfaces need to be
228 if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set"))
230 else if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", NULL) ||
231 sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", NULL) ||
232 sd_bus_message_is_method_call(message, "org.freedesktop.DBus.ObjectManager", NULL) ||
233 sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Peer", NULL))
238 path = sd_bus_message_get_path(message);
240 if (object_path_startswith("/org/freedesktop/systemd1", path)) {
242 r = selinux_access_check(bus, message, verb, error);
249 if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
252 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
256 u = manager_get_unit_by_pid(m, pid);
258 r = manager_get_job_from_dbus_path(m, path, &j);
262 manager_load_unit_from_dbus_path(m, path, NULL, &u);
268 r = selinux_unit_access_check(u, bus, message, verb, error);
275 static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
276 Manager *m = userdata;
286 r = manager_get_job_from_dbus_path(m, path, &j);
294 static Unit *find_unit(Manager *m, sd_bus *bus, const char *path) {
302 if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
303 sd_bus_message *message;
306 message = sd_bus_get_current(bus);
310 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
314 u = manager_get_unit_by_pid(m, pid);
316 r = manager_load_unit_from_dbus_path(m, path, NULL, &u);
324 static int bus_unit_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
325 Manager *m = userdata;
334 u = find_unit(m, bus, path);
342 static int bus_unit_interface_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
343 Manager *m = userdata;
352 u = find_unit(m, bus, path);
356 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
363 static int bus_unit_cgroup_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
364 Manager *m = userdata;
373 u = find_unit(m, bus, path);
377 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
380 if (!unit_get_cgroup_context(u))
387 static int bus_cgroup_context_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
388 Manager *m = userdata;
398 u = find_unit(m, bus, path);
402 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
405 c = unit_get_cgroup_context(u);
413 static int bus_exec_context_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
414 Manager *m = userdata;
424 u = find_unit(m, bus, path);
428 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
431 c = unit_get_exec_context(u);
439 static int bus_kill_context_find(sd_bus *bus, const char *path, const char *interface, void **found, void *userdata) {
440 Manager *m = userdata;
450 u = find_unit(m, bus, path);
454 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
457 c = unit_get_kill_context(u);
465 static int bus_job_enumerate(sd_bus *bus, const char *path, char ***nodes, void *userdata) {
466 _cleanup_free_ char **l = NULL;
467 Manager *m = userdata;
472 l = new0(char*, hashmap_size(m->jobs)+1);
476 HASHMAP_FOREACH(j, m->jobs, i) {
477 l[k] = job_dbus_path(j);
484 assert(hashmap_size(m->jobs) == k);
492 static int bus_unit_enumerate(sd_bus *bus, const char *path, char ***nodes, void *userdata) {
493 _cleanup_free_ char **l = NULL;
494 Manager *m = userdata;
499 l = new0(char*, hashmap_size(m->units)+1);
503 HASHMAP_FOREACH(u, m->units, i) {
504 l[k] = unit_dbus_path(u);
517 static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
524 r = sd_bus_add_filter(bus, selinux_filter, m);
526 log_error("Failed to add SELinux access filter: %s", strerror(-r));
530 r = sd_bus_add_object_vtable(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
532 log_error("Failed to register Manager vtable: %s", strerror(-r));
536 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
538 log_error("Failed to register Job vtable: %s", strerror(-r));
542 r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
544 log_error("Failed to add job enumerator: %s", strerror(-r));
548 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
550 log_error("Failed to register Unit vtable: %s", strerror(-r));
554 r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
556 log_error("Failed to add job enumerator: %s", strerror(-r));
560 for (t = 0; t < _UNIT_TYPE_MAX; t++) {
561 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);
563 log_error("Failed to register type specific vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
567 if (unit_vtable[t]->cgroup_context_offset > 0) {
568 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);
570 log_error("Failed to register control group unit vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
574 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
576 log_error("Failed to register control group vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
581 if (unit_vtable[t]->exec_context_offset > 0) {
582 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_exec_vtable, bus_exec_context_find, m);
584 log_error("Failed to register execute vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
589 if (unit_vtable[t]->kill_context_offset > 0) {
590 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_kill_vtable, bus_kill_context_find, m);
592 log_error("Failed to register kill vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
601 static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
607 r = sd_bus_add_match(
610 "path='/org/freedesktop/DBus/Local',"
611 "interface='org.freedesktop.DBus.Local',"
612 "member='Disconnected'",
613 signal_disconnected, m);
616 log_error("Failed to register match for Disconnected message: %s", strerror(-r));
623 static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
624 _cleanup_bus_unref_ sd_bus *bus = NULL;
625 _cleanup_close_ int nfd = -1;
626 Manager *m = userdata;
633 nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
635 log_warning("Failed to accept private connection, ignoring: %m");
639 if (set_size(m->private_buses) >= CONNECTIONS_MAX) {
640 log_warning("Too many concurrent connections, refusing");
644 r = set_ensure_allocated(&m->private_buses, trivial_hash_func, trivial_compare_func);
650 r = sd_bus_new(&bus);
652 log_warning("Failed to allocate new private connection bus: %s", strerror(-r));
656 r = sd_bus_set_fd(bus, nfd, nfd);
658 log_warning("Failed to set fd on new connection bus: %s", strerror(-r));
664 r = bus_check_peercred(bus);
666 log_warning("Incoming private connection from unprivileged client, refusing: %s", strerror(-r));
670 assert_se(sd_id128_randomize(&id) >= 0);
672 r = sd_bus_set_server(bus, 1, id);
674 log_warning("Failed to enable server support for new connection bus: %s", strerror(-r));
678 r = sd_bus_start(bus);
680 log_warning("Failed to start new connection bus: %s", strerror(-r));
684 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
686 log_warning("Failed to attach new connection bus to event loop: %s", strerror(-r));
690 if (m->running_as == SYSTEMD_SYSTEM) {
691 /* When we run as system instance we get the Released
692 * signal via a direct connection */
694 r = sd_bus_add_match(
697 "interface='org.freedesktop.systemd1.Agent',"
699 "path='/org/freedesktop/systemd1/agent'",
700 signal_agent_released, m);
703 log_warning("Failed to register Released match on new connection bus: %s", strerror(-r));
708 r = bus_setup_disconnected_match(m, bus);
712 r = bus_setup_api_vtables(m, bus);
714 log_warning("Failed to set up API vtables on new connection bus: %s", strerror(-r));
718 r = set_put(m->private_buses, bus);
720 log_warning("Failed to add new conenction bus to set: %s", strerror(-r));
726 log_debug("Accepted new private connection.");
731 static int bus_list_names(Manager *m, sd_bus *bus) {
732 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
733 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
740 r = sd_bus_call_method(
742 "org.freedesktop.DBus",
743 "/org/freedesktop/DBus",
744 "org.freedesktop.DBus",
749 log_error("Failed to get initial list of names: %s", bus_error_message(&error, r));
753 r = sd_bus_message_enter_container(reply, 'a', "s");
755 return bus_log_parse_error(r);
757 /* This is a bit hacky, we say the owner of the name is the
758 * name itself, because we don't want the extra traffic to
759 * figure out the real owner. */
760 while ((r = sd_bus_message_read(reply, "s", &name)) > 0)
761 manager_dispatch_bus_name_owner_changed(m, name, NULL, name);
763 return bus_log_parse_error(r);
765 r = sd_bus_message_exit_container(reply);
767 return bus_log_parse_error(r);
772 static int bus_setup_api(Manager *m, sd_bus *bus) {
778 r = bus_setup_api_vtables(m, bus);
782 r = sd_bus_add_match(
785 "sender='org.freedesktop.DBus',"
786 "path='/org/freedesktop/DBus',"
787 "interface='org.freedesktop.DBus',"
788 "member='NameOwnerChanged'",
789 signal_name_owner_changed, m);
791 log_warning("Failed to subscribe to NameOwnerChanged signal: %s", strerror(-r));
793 r = sd_bus_add_match(
796 "sender='org.freedesktop.DBus',"
797 "path='/org/freedesktop/DBus',"
798 "interface='org.freedesktop.systemd1.Activator',"
799 "member='ActivationRequest'",
800 signal_activation_request, m);
802 log_warning("Failed to subscribe to activation signal: %s", strerror(-r));
804 /* Allow replacing of our name, to ease implementation of
805 * reexecution, where we keep the old connection open until
806 * after the new connection is set up and the name installed
807 * to allow clients to synchronously wait for reexecution to
809 r = sd_bus_request_name(bus,"org.freedesktop.systemd1", SD_BUS_NAME_ALLOW_REPLACEMENT|SD_BUS_NAME_REPLACE_EXISTING);
811 log_error("Failed to register name: %s", strerror(-r));
815 if (r != SD_BUS_NAME_PRIMARY_OWNER) {
816 log_error("Failed to acquire name.");
820 bus_list_names(m, bus);
822 log_debug("Successfully connected to API bus.");
826 static int bus_init_api(Manager *m) {
827 _cleanup_bus_unref_ sd_bus *bus = NULL;
833 /* The API and system bus is the same if we are running in system mode */
834 if (m->running_as == SYSTEMD_SYSTEM && m->system_bus)
835 bus = sd_bus_ref(m->system_bus);
837 if (m->running_as == SYSTEMD_SYSTEM)
838 r = sd_bus_open_system(&bus);
840 r = sd_bus_open_user(&bus);
843 log_debug("Failed to connect to API bus, retrying later...");
847 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
849 log_error("Failed to attach API bus to event loop: %s", strerror(-r));
853 r = bus_setup_disconnected_match(m, bus);
858 r = bus_setup_api(m, bus);
860 log_error("Failed to set up API bus: %s", strerror(-r));
870 static int bus_setup_system(Manager *m, sd_bus *bus) {
876 if (m->running_as == SYSTEMD_SYSTEM)
879 /* If we are a user instance we get the Released message via
881 r = sd_bus_add_match(
884 "interface='org.freedesktop.systemd1.Agent',"
886 "path='/org/freedesktop/systemd1/agent'",
887 signal_agent_released, m);
890 log_warning("Failed to register Released match on system bus: %s", strerror(-r));
892 log_debug("Successfully connected to system bus.");
896 static int bus_init_system(Manager *m) {
897 _cleanup_bus_unref_ sd_bus *bus = NULL;
903 /* The API and system bus is the same if we are running in system mode */
904 if (m->running_as == SYSTEMD_SYSTEM && m->api_bus) {
905 m->system_bus = sd_bus_ref(m->api_bus);
909 r = sd_bus_open_system(&bus);
911 log_debug("Failed to connect to system bus, retrying later...");
915 r = bus_setup_disconnected_match(m, bus);
919 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
921 log_error("Failed to attach system bus to event loop: %s", strerror(-r));
925 r = bus_setup_system(m, bus);
927 log_error("Fauiled to set up system bus: %s", strerror(-r));
937 static int bus_init_private(Manager *m) {
938 _cleanup_close_ int fd = -1;
939 union sockaddr_union sa = {
940 .un.sun_family = AF_UNIX
948 if (m->private_listen_fd >= 0)
951 if (m->running_as == SYSTEMD_SYSTEM) {
953 /* We want the private bus only when running as init */
957 strcpy(sa.un.sun_path, "/run/systemd/private");
958 salen = offsetof(union sockaddr_union, un.sun_path) + sizeof("/run/systemd/private") - 1;
960 size_t left = sizeof(sa.un.sun_path);
961 char *p = sa.un.sun_path;
964 e = secure_getenv("XDG_RUNTIME_DIR");
966 log_error("Failed to determine XDG_RUNTIME_DIR");
970 left = strpcpy(&p, left, e);
971 left = strpcpy(&p, left, "/systemd/private");
973 salen = sizeof(sa.un) - left;
975 mkdir_parents_label(sa.un.sun_path, 0755);
978 unlink(sa.un.sun_path);
980 fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
982 log_error("Failed to allocate private socket: %m");
986 r = bind(fd, &sa.sa, salen);
988 log_error("Failed to bind private socket: %m");
992 r = listen(fd, SOMAXCONN);
994 log_error("Failed to make private socket listening: %m");
998 r = sd_event_add_io(m->event, fd, EPOLLIN, bus_on_connection, m, &s);
1000 log_error("Failed to allocate event source: %s", strerror(-r));
1004 m->private_listen_fd = fd;
1005 m->private_listen_event_source = s;
1008 log_debug("Successfully created private D-Bus server.");
1013 int bus_init(Manager *m, bool try_bus_connect) {
1016 if (try_bus_connect) {
1017 r = bus_init_system(m);
1021 r = bus_init_api(m);
1026 r = bus_init_private(m);
1033 static void destroy_bus(Manager *m, sd_bus **bus) {
1043 /* Get rid of tracked clients on this bus */
1044 bus_client_untrack_bus(m->subscribed, *bus);
1045 HASHMAP_FOREACH(j, m->jobs, i)
1046 bus_client_untrack_bus(j->subscribed, *bus);
1048 /* Get rid of queued message on this bus */
1049 if (m->queued_message_bus == *bus) {
1050 m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
1052 if (m->queued_message)
1053 m->queued_message = sd_bus_message_unref(m->queued_message);
1056 /* Possibly flush unwritten data, but only if we are
1057 * unprivileged, since we don't want to sync here */
1058 if (m->running_as != SYSTEMD_SYSTEM)
1061 /* And destroy the object */
1063 *bus = sd_bus_unref(*bus);
1066 void bus_done(Manager *m) {
1072 destroy_bus(m, &m->api_bus);
1074 destroy_bus(m, &m->system_bus);
1075 while ((b = set_steal_first(m->private_buses)))
1078 set_free(m->private_buses);
1079 set_free(m->subscribed);
1081 if (m->private_listen_event_source)
1082 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
1084 if (m->private_listen_fd >= 0) {
1085 close_nointr_nofail(m->private_listen_fd);
1086 m->private_listen_fd = -1;
1090 int bus_fdset_add_all(Manager *m, FDSet *fds) {
1098 /* When we are about to reexecute we add all D-Bus fds to the
1099 * set to pass over to the newly executed systemd. They won't
1100 * be used there however, except thatt they are closed at the
1101 * very end of deserialization, those making it possible for
1102 * clients to synchronously wait for systemd to reexec by
1103 * simply waiting for disconnection */
1106 fd = sd_bus_get_fd(m->api_bus);
1108 fd = fdset_put_dup(fds, fd);
1114 SET_FOREACH(b, m->private_buses, i) {
1115 fd = sd_bus_get_fd(b);
1117 fd = fdset_put_dup(fds, fd);
1123 /* We don't offer any APIs on the system bus (well, unless it
1124 * is the same as the API bus) hence we don't bother with it
1130 void bus_serialize(Manager *m, FILE *f) {
1134 bus_client_track_serialize(m, f, m->subscribed);
1137 int bus_deserialize_item(Manager *m, const char *line) {
1141 return bus_client_track_deserialize_item(m, &m->subscribed, line);