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")) {
250 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
253 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
257 r = sd_bus_creds_get_pid(creds, &pid);
261 u = manager_get_unit_by_pid(m, pid);
263 r = manager_get_job_from_dbus_path(m, path, &j);
267 manager_load_unit_from_dbus_path(m, path, NULL, &u);
273 r = selinux_unit_access_check(u, bus, message, verb, error);
280 static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
281 Manager *m = userdata;
291 r = manager_get_job_from_dbus_path(m, path, &j);
299 static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_bus_error *error) {
307 if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
308 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
309 sd_bus_message *message;
312 message = sd_bus_get_current(bus);
316 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
320 r = sd_bus_creds_get_pid(creds, &pid);
324 u = manager_get_unit_by_pid(m, pid);
326 r = manager_load_unit_from_dbus_path(m, path, error, &u);
338 static int bus_unit_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
339 Manager *m = userdata;
347 return find_unit(m, bus, path, (Unit**) found, error);
350 static int bus_unit_interface_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
351 Manager *m = userdata;
361 r = find_unit(m, bus, path, &u, error);
365 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
372 static int bus_unit_cgroup_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
373 Manager *m = userdata;
383 r = find_unit(m, bus, path, &u, error);
387 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
390 if (!unit_get_cgroup_context(u))
397 static int bus_cgroup_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
398 Manager *m = userdata;
409 r = find_unit(m, bus, path, &u, error);
413 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
416 c = unit_get_cgroup_context(u);
424 static int bus_exec_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
425 Manager *m = userdata;
436 r = find_unit(m, bus, path, &u, error);
440 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
443 c = unit_get_exec_context(u);
451 static int bus_kill_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
452 Manager *m = userdata;
463 r = find_unit(m, bus, path, &u, error);
467 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
470 c = unit_get_kill_context(u);
478 static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
479 _cleanup_free_ char **l = NULL;
480 Manager *m = userdata;
485 l = new0(char*, hashmap_size(m->jobs)+1);
489 HASHMAP_FOREACH(j, m->jobs, i) {
490 l[k] = job_dbus_path(j);
497 assert(hashmap_size(m->jobs) == k);
505 static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
506 _cleanup_free_ char **l = NULL;
507 Manager *m = userdata;
512 l = new0(char*, hashmap_size(m->units)+1);
516 HASHMAP_FOREACH(u, m->units, i) {
517 l[k] = unit_dbus_path(u);
530 static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
537 r = sd_bus_add_filter(bus, selinux_filter, m);
539 log_error("Failed to add SELinux access filter: %s", strerror(-r));
543 r = sd_bus_add_object_vtable(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
545 log_error("Failed to register Manager vtable: %s", strerror(-r));
549 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
551 log_error("Failed to register Job vtable: %s", strerror(-r));
555 r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
557 log_error("Failed to add job enumerator: %s", strerror(-r));
561 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
563 log_error("Failed to register Unit vtable: %s", strerror(-r));
567 r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
569 log_error("Failed to add job enumerator: %s", strerror(-r));
573 for (t = 0; t < _UNIT_TYPE_MAX; t++) {
574 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);
576 log_error("Failed to register type specific vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
580 if (unit_vtable[t]->cgroup_context_offset > 0) {
581 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);
583 log_error("Failed to register control group unit vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
587 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
589 log_error("Failed to register control group vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
594 if (unit_vtable[t]->exec_context_offset > 0) {
595 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_exec_vtable, bus_exec_context_find, m);
597 log_error("Failed to register execute vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
602 if (unit_vtable[t]->kill_context_offset > 0) {
603 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_kill_vtable, bus_kill_context_find, m);
605 log_error("Failed to register kill vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
614 static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
620 r = sd_bus_add_match(
623 "path='/org/freedesktop/DBus/Local',"
624 "interface='org.freedesktop.DBus.Local',"
625 "member='Disconnected'",
626 signal_disconnected, m);
629 log_error("Failed to register match for Disconnected message: %s", strerror(-r));
636 static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
637 _cleanup_bus_unref_ sd_bus *bus = NULL;
638 _cleanup_close_ int nfd = -1;
639 Manager *m = userdata;
646 nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
648 log_warning("Failed to accept private connection, ignoring: %m");
652 if (set_size(m->private_buses) >= CONNECTIONS_MAX) {
653 log_warning("Too many concurrent connections, refusing");
657 r = set_ensure_allocated(&m->private_buses, trivial_hash_func, trivial_compare_func);
663 r = sd_bus_new(&bus);
665 log_warning("Failed to allocate new private connection bus: %s", strerror(-r));
669 r = sd_bus_set_fd(bus, nfd, nfd);
671 log_warning("Failed to set fd on new connection bus: %s", strerror(-r));
677 r = bus_check_peercred(bus);
679 log_warning("Incoming private connection from unprivileged client, refusing: %s", strerror(-r));
683 assert_se(sd_id128_randomize(&id) >= 0);
685 r = sd_bus_set_server(bus, 1, id);
687 log_warning("Failed to enable server support for new connection bus: %s", strerror(-r));
691 r = sd_bus_start(bus);
693 log_warning("Failed to start new connection bus: %s", strerror(-r));
697 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
699 log_warning("Failed to attach new connection bus to event loop: %s", strerror(-r));
703 if (m->running_as == SYSTEMD_SYSTEM) {
704 /* When we run as system instance we get the Released
705 * signal via a direct connection */
707 r = sd_bus_add_match(
710 "interface='org.freedesktop.systemd1.Agent',"
712 "path='/org/freedesktop/systemd1/agent'",
713 signal_agent_released, m);
716 log_warning("Failed to register Released match on new connection bus: %s", strerror(-r));
721 r = bus_setup_disconnected_match(m, bus);
725 r = bus_setup_api_vtables(m, bus);
727 log_warning("Failed to set up API vtables on new connection bus: %s", strerror(-r));
731 r = set_put(m->private_buses, bus);
733 log_warning("Failed to add new conenction bus to set: %s", strerror(-r));
739 log_debug("Accepted new private connection.");
744 static int bus_list_names(Manager *m, sd_bus *bus) {
745 _cleanup_strv_free_ char **names = NULL;
752 r = sd_bus_list_names(bus, &names, NULL);
754 log_error("Failed to get initial list of names: %s", strerror(-r));
758 /* This is a bit hacky, we say the owner of the name is the
759 * name itself, because we don't want the extra traffic to
760 * figure out the real owner. */
761 STRV_FOREACH(i, names)
762 manager_dispatch_bus_name_owner_changed(m, *i, NULL, *i);
767 static int bus_setup_api(Manager *m, sd_bus *bus) {
773 r = bus_setup_api_vtables(m, bus);
777 r = sd_bus_add_match(
780 "sender='org.freedesktop.DBus',"
781 "path='/org/freedesktop/DBus',"
782 "interface='org.freedesktop.DBus',"
783 "member='NameOwnerChanged'",
784 signal_name_owner_changed, m);
786 log_warning("Failed to subscribe to NameOwnerChanged signal: %s", strerror(-r));
788 r = sd_bus_add_match(
791 "sender='org.freedesktop.DBus',"
792 "path='/org/freedesktop/DBus',"
793 "interface='org.freedesktop.systemd1.Activator',"
794 "member='ActivationRequest'",
795 signal_activation_request, m);
797 log_warning("Failed to subscribe to activation signal: %s", strerror(-r));
799 /* Allow replacing of our name, to ease implementation of
800 * reexecution, where we keep the old connection open until
801 * after the new connection is set up and the name installed
802 * to allow clients to synchronously wait for reexecution to
804 r = sd_bus_request_name(bus,"org.freedesktop.systemd1", SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_DO_NOT_QUEUE);
806 log_error("Failed to register name: %s", strerror(-r));
810 bus_list_names(m, bus);
812 log_debug("Successfully connected to API bus.");
816 static int bus_init_api(Manager *m) {
817 _cleanup_bus_unref_ sd_bus *bus = NULL;
823 /* The API and system bus is the same if we are running in system mode */
824 if (m->running_as == SYSTEMD_SYSTEM && m->system_bus)
825 bus = sd_bus_ref(m->system_bus);
827 if (m->running_as == SYSTEMD_SYSTEM)
828 r = sd_bus_open_system(&bus);
830 r = sd_bus_open_user(&bus);
833 log_debug("Failed to connect to API bus, retrying later...");
837 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
839 log_error("Failed to attach API bus to event loop: %s", strerror(-r));
843 r = bus_setup_disconnected_match(m, bus);
848 r = bus_setup_api(m, bus);
850 log_error("Failed to set up API bus: %s", strerror(-r));
860 static int bus_setup_system(Manager *m, sd_bus *bus) {
866 if (m->running_as == SYSTEMD_SYSTEM)
869 /* If we are a user instance we get the Released message via
871 r = sd_bus_add_match(
874 "interface='org.freedesktop.systemd1.Agent',"
876 "path='/org/freedesktop/systemd1/agent'",
877 signal_agent_released, m);
880 log_warning("Failed to register Released match on system bus: %s", strerror(-r));
882 log_debug("Successfully connected to system bus.");
886 static int bus_init_system(Manager *m) {
887 _cleanup_bus_unref_ sd_bus *bus = NULL;
893 /* The API and system bus is the same if we are running in system mode */
894 if (m->running_as == SYSTEMD_SYSTEM && m->api_bus) {
895 m->system_bus = sd_bus_ref(m->api_bus);
899 r = sd_bus_open_system(&bus);
901 log_debug("Failed to connect to system bus, retrying later...");
905 r = bus_setup_disconnected_match(m, bus);
909 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
911 log_error("Failed to attach system bus to event loop: %s", strerror(-r));
915 r = bus_setup_system(m, bus);
917 log_error("Fauiled to set up system bus: %s", strerror(-r));
927 static int bus_init_private(Manager *m) {
928 _cleanup_close_ int fd = -1;
929 union sockaddr_union sa = {
930 .un.sun_family = AF_UNIX
938 if (m->private_listen_fd >= 0)
941 /* We don't need the private socket if we have kdbus */
942 if (m->kdbus_fd >= 0)
945 if (m->running_as == SYSTEMD_SYSTEM) {
947 /* We want the private bus only when running as init */
951 strcpy(sa.un.sun_path, "/run/systemd/private");
952 salen = offsetof(union sockaddr_union, un.sun_path) + sizeof("/run/systemd/private") - 1;
954 size_t left = sizeof(sa.un.sun_path);
955 char *p = sa.un.sun_path;
958 e = secure_getenv("XDG_RUNTIME_DIR");
960 log_error("Failed to determine XDG_RUNTIME_DIR");
964 left = strpcpy(&p, left, e);
965 left = strpcpy(&p, left, "/systemd/private");
967 salen = sizeof(sa.un) - left;
969 mkdir_parents_label(sa.un.sun_path, 0755);
972 unlink(sa.un.sun_path);
974 fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
976 log_error("Failed to allocate private socket: %m");
980 r = bind(fd, &sa.sa, salen);
982 log_error("Failed to bind private socket: %m");
986 r = listen(fd, SOMAXCONN);
988 log_error("Failed to make private socket listening: %m");
992 r = sd_event_add_io(m->event, fd, EPOLLIN, bus_on_connection, m, &s);
994 log_error("Failed to allocate event source: %s", strerror(-r));
998 m->private_listen_fd = fd;
999 m->private_listen_event_source = s;
1002 log_debug("Successfully created private D-Bus server.");
1007 int bus_init(Manager *m, bool try_bus_connect) {
1010 if (try_bus_connect) {
1011 r = bus_init_system(m);
1015 r = bus_init_api(m);
1020 r = bus_init_private(m);
1027 static void destroy_bus(Manager *m, sd_bus **bus) {
1037 /* Get rid of tracked clients on this bus */
1038 bus_client_untrack_bus(m->subscribed, *bus);
1039 HASHMAP_FOREACH(j, m->jobs, i)
1040 bus_client_untrack_bus(j->subscribed, *bus);
1042 /* Get rid of queued message on this bus */
1043 if (m->queued_message_bus == *bus) {
1044 m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
1046 if (m->queued_message)
1047 m->queued_message = sd_bus_message_unref(m->queued_message);
1050 /* Possibly flush unwritten data, but only if we are
1051 * unprivileged, since we don't want to sync here */
1052 if (m->running_as != SYSTEMD_SYSTEM)
1055 /* And destroy the object */
1057 *bus = sd_bus_unref(*bus);
1060 void bus_done(Manager *m) {
1066 destroy_bus(m, &m->api_bus);
1068 destroy_bus(m, &m->system_bus);
1069 while ((b = set_steal_first(m->private_buses)))
1072 set_free(m->private_buses);
1073 set_free(m->subscribed);
1075 if (m->private_listen_event_source)
1076 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
1078 if (m->private_listen_fd >= 0) {
1079 close_nointr_nofail(m->private_listen_fd);
1080 m->private_listen_fd = -1;
1084 int bus_fdset_add_all(Manager *m, FDSet *fds) {
1092 /* When we are about to reexecute we add all D-Bus fds to the
1093 * set to pass over to the newly executed systemd. They won't
1094 * be used there however, except thatt they are closed at the
1095 * very end of deserialization, those making it possible for
1096 * clients to synchronously wait for systemd to reexec by
1097 * simply waiting for disconnection */
1100 fd = sd_bus_get_fd(m->api_bus);
1102 fd = fdset_put_dup(fds, fd);
1108 SET_FOREACH(b, m->private_buses, i) {
1109 fd = sd_bus_get_fd(b);
1111 fd = fdset_put_dup(fds, fd);
1117 /* We don't offer any APIs on the system bus (well, unless it
1118 * is the same as the API bus) hence we don't bother with it
1124 void bus_serialize(Manager *m, FILE *f) {
1128 bus_client_track_serialize(m, f, m->subscribed);
1131 int bus_deserialize_item(Manager *m, const char *line) {
1135 return bus_client_track_deserialize_item(m, &m->subscribed, line);