]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/dbus.c
mkdir: append _label to all mkdir() calls that explicitly set the selinux context
[thirdparty/systemd.git] / src / core / dbus.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
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.
12
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.
17
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/>.
20 ***/
21
22 #include <sys/epoll.h>
23 #include <sys/timerfd.h>
24 #include <errno.h>
25 #include <unistd.h>
26 #include <dbus/dbus.h>
27
28 #include "dbus.h"
29 #include "log.h"
30 #include "strv.h"
31 #include "cgroup.h"
32 #include "mkdir.h"
33 #include "dbus-unit.h"
34 #include "dbus-job.h"
35 #include "dbus-manager.h"
36 #include "dbus-service.h"
37 #include "dbus-socket.h"
38 #include "dbus-target.h"
39 #include "dbus-device.h"
40 #include "dbus-mount.h"
41 #include "dbus-automount.h"
42 #include "dbus-snapshot.h"
43 #include "dbus-swap.h"
44 #include "dbus-timer.h"
45 #include "dbus-path.h"
46 #include "bus-errors.h"
47 #include "special.h"
48 #include "dbus-common.h"
49
50 #define CONNECTIONS_MAX 52
51
52 /* Well-known address (http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-types) */
53 #define DBUS_SYSTEM_BUS_DEFAULT_ADDRESS "unix:path=/var/run/dbus/system_bus_socket"
54 /* Only used as a fallback */
55 #define DBUS_SESSION_BUS_DEFAULT_ADDRESS "autolaunch:"
56
57 static const char bus_properties_interface[] = BUS_PROPERTIES_INTERFACE;
58 static const char bus_introspectable_interface[] = BUS_INTROSPECTABLE_INTERFACE;
59
60 const char *const bus_interface_table[] = {
61 "org.freedesktop.DBus.Properties", bus_properties_interface,
62 "org.freedesktop.DBus.Introspectable", bus_introspectable_interface,
63 "org.freedesktop.systemd1.Manager", bus_manager_interface,
64 "org.freedesktop.systemd1.Job", bus_job_interface,
65 "org.freedesktop.systemd1.Unit", bus_unit_interface,
66 "org.freedesktop.systemd1.Service", bus_service_interface,
67 "org.freedesktop.systemd1.Socket", bus_socket_interface,
68 "org.freedesktop.systemd1.Target", bus_target_interface,
69 "org.freedesktop.systemd1.Device", bus_device_interface,
70 "org.freedesktop.systemd1.Mount", bus_mount_interface,
71 "org.freedesktop.systemd1.Automount", bus_automount_interface,
72 "org.freedesktop.systemd1.Snapshot", bus_snapshot_interface,
73 "org.freedesktop.systemd1.Swap", bus_swap_interface,
74 "org.freedesktop.systemd1.Timer", bus_timer_interface,
75 "org.freedesktop.systemd1.Path", bus_path_interface,
76 NULL
77 };
78
79 static void bus_done_api(Manager *m);
80 static void bus_done_system(Manager *m);
81 static void bus_done_private(Manager *m);
82 static void shutdown_connection(Manager *m, DBusConnection *c);
83
84 static void bus_dispatch_status(DBusConnection *bus, DBusDispatchStatus status, void *data) {
85 Manager *m = data;
86
87 assert(bus);
88 assert(m);
89
90 /* We maintain two sets, one for those connections where we
91 * requested a dispatch, and another where we didn't. And then,
92 * we move the connections between the two sets. */
93
94 if (status == DBUS_DISPATCH_COMPLETE)
95 set_move_one(m->bus_connections, m->bus_connections_for_dispatch, bus);
96 else
97 set_move_one(m->bus_connections_for_dispatch, m->bus_connections, bus);
98 }
99
100 void bus_watch_event(Manager *m, Watch *w, int events) {
101 assert(m);
102 assert(w);
103
104 /* This is called by the event loop whenever there is
105 * something happening on D-Bus' file handles. */
106
107 if (!dbus_watch_get_enabled(w->data.bus_watch))
108 return;
109
110 dbus_watch_handle(w->data.bus_watch, bus_events_to_flags(events));
111 }
112
113 static dbus_bool_t bus_add_watch(DBusWatch *bus_watch, void *data) {
114 Manager *m = data;
115 Watch *w;
116 struct epoll_event ev;
117
118 assert(bus_watch);
119 assert(m);
120
121 if (!(w = new0(Watch, 1)))
122 return FALSE;
123
124 w->fd = dbus_watch_get_unix_fd(bus_watch);
125 w->type = WATCH_DBUS_WATCH;
126 w->data.bus_watch = bus_watch;
127
128 zero(ev);
129 ev.events = bus_flags_to_events(bus_watch);
130 ev.data.ptr = w;
131
132 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, w->fd, &ev) < 0) {
133
134 if (errno != EEXIST) {
135 free(w);
136 return FALSE;
137 }
138
139 /* Hmm, bloody D-Bus creates multiple watches on the
140 * same fd. epoll() does not like that. As a dirty
141 * hack we simply dup() the fd and hence get a second
142 * one we can safely add to the epoll(). */
143
144 if ((w->fd = dup(w->fd)) < 0) {
145 free(w);
146 return FALSE;
147 }
148
149 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, w->fd, &ev) < 0) {
150 close_nointr_nofail(w->fd);
151 free(w);
152 return FALSE;
153 }
154
155 w->fd_is_dupped = true;
156 }
157
158 dbus_watch_set_data(bus_watch, w, NULL);
159
160 return TRUE;
161 }
162
163 static void bus_remove_watch(DBusWatch *bus_watch, void *data) {
164 Manager *m = data;
165 Watch *w;
166
167 assert(bus_watch);
168 assert(m);
169
170 w = dbus_watch_get_data(bus_watch);
171 if (!w)
172 return;
173
174 assert(w->type == WATCH_DBUS_WATCH);
175 assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
176
177 if (w->fd_is_dupped)
178 close_nointr_nofail(w->fd);
179
180 free(w);
181 }
182
183 static void bus_toggle_watch(DBusWatch *bus_watch, void *data) {
184 Manager *m = data;
185 Watch *w;
186 struct epoll_event ev;
187
188 assert(bus_watch);
189 assert(m);
190
191 w = dbus_watch_get_data(bus_watch);
192 if (!w)
193 return;
194
195 assert(w->type == WATCH_DBUS_WATCH);
196
197 zero(ev);
198 ev.events = bus_flags_to_events(bus_watch);
199 ev.data.ptr = w;
200
201 assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_MOD, w->fd, &ev) == 0);
202 }
203
204 static int bus_timeout_arm(Manager *m, Watch *w) {
205 struct itimerspec its;
206
207 assert(m);
208 assert(w);
209
210 zero(its);
211
212 if (dbus_timeout_get_enabled(w->data.bus_timeout)) {
213 timespec_store(&its.it_value, dbus_timeout_get_interval(w->data.bus_timeout) * USEC_PER_MSEC);
214 its.it_interval = its.it_value;
215 }
216
217 if (timerfd_settime(w->fd, 0, &its, NULL) < 0)
218 return -errno;
219
220 return 0;
221 }
222
223 void bus_timeout_event(Manager *m, Watch *w, int events) {
224 assert(m);
225 assert(w);
226
227 /* This is called by the event loop whenever there is
228 * something happening on D-Bus' file handles. */
229
230 if (!(dbus_timeout_get_enabled(w->data.bus_timeout)))
231 return;
232
233 dbus_timeout_handle(w->data.bus_timeout);
234 }
235
236 static dbus_bool_t bus_add_timeout(DBusTimeout *timeout, void *data) {
237 Manager *m = data;
238 Watch *w;
239 struct epoll_event ev;
240
241 assert(timeout);
242 assert(m);
243
244 if (!(w = new0(Watch, 1)))
245 return FALSE;
246
247 if ((w->fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0)
248 goto fail;
249
250 w->type = WATCH_DBUS_TIMEOUT;
251 w->data.bus_timeout = timeout;
252
253 if (bus_timeout_arm(m, w) < 0)
254 goto fail;
255
256 zero(ev);
257 ev.events = EPOLLIN;
258 ev.data.ptr = w;
259
260 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, w->fd, &ev) < 0)
261 goto fail;
262
263 dbus_timeout_set_data(timeout, w, NULL);
264
265 return TRUE;
266
267 fail:
268 if (w->fd >= 0)
269 close_nointr_nofail(w->fd);
270
271 free(w);
272 return FALSE;
273 }
274
275 static void bus_remove_timeout(DBusTimeout *timeout, void *data) {
276 Manager *m = data;
277 Watch *w;
278
279 assert(timeout);
280 assert(m);
281
282 w = dbus_timeout_get_data(timeout);
283 if (!w)
284 return;
285
286 assert(w->type == WATCH_DBUS_TIMEOUT);
287
288 assert_se(epoll_ctl(m->epoll_fd, EPOLL_CTL_DEL, w->fd, NULL) >= 0);
289 close_nointr_nofail(w->fd);
290 free(w);
291 }
292
293 static void bus_toggle_timeout(DBusTimeout *timeout, void *data) {
294 Manager *m = data;
295 Watch *w;
296 int r;
297
298 assert(timeout);
299 assert(m);
300
301 w = dbus_timeout_get_data(timeout);
302 if (!w)
303 return;
304
305 assert(w->type == WATCH_DBUS_TIMEOUT);
306
307 if ((r = bus_timeout_arm(m, w)) < 0)
308 log_error("Failed to rearm timer: %s", strerror(-r));
309 }
310
311 static DBusHandlerResult api_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) {
312 Manager *m = data;
313 DBusError error;
314 DBusMessage *reply = NULL;
315
316 assert(connection);
317 assert(message);
318 assert(m);
319
320 dbus_error_init(&error);
321
322 if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL ||
323 dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL)
324 log_debug("Got D-Bus request: %s.%s() on %s",
325 dbus_message_get_interface(message),
326 dbus_message_get_member(message),
327 dbus_message_get_path(message));
328
329 if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
330 log_debug("API D-Bus connection terminated.");
331 bus_done_api(m);
332
333 } else if (dbus_message_is_signal(message, DBUS_INTERFACE_DBUS, "NameOwnerChanged")) {
334 const char *name, *old_owner, *new_owner;
335
336 if (!dbus_message_get_args(message, &error,
337 DBUS_TYPE_STRING, &name,
338 DBUS_TYPE_STRING, &old_owner,
339 DBUS_TYPE_STRING, &new_owner,
340 DBUS_TYPE_INVALID))
341 log_error("Failed to parse NameOwnerChanged message: %s", bus_error_message(&error));
342 else {
343 if (set_remove(BUS_CONNECTION_SUBSCRIBED(m, connection), (char*) name))
344 log_debug("Subscription client vanished: %s (left: %u)", name, set_size(BUS_CONNECTION_SUBSCRIBED(m, connection)));
345
346 if (old_owner[0] == 0)
347 old_owner = NULL;
348
349 if (new_owner[0] == 0)
350 new_owner = NULL;
351
352 manager_dispatch_bus_name_owner_changed(m, name, old_owner, new_owner);
353 }
354 } else if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Activator", "ActivationRequest")) {
355 const char *name;
356
357 if (!dbus_message_get_args(message, &error,
358 DBUS_TYPE_STRING, &name,
359 DBUS_TYPE_INVALID))
360 log_error("Failed to parse ActivationRequest message: %s", bus_error_message(&error));
361 else {
362 int r;
363 Unit *u;
364
365 log_debug("Got D-Bus activation request for %s", name);
366
367 if (manager_unit_pending_inactive(m, SPECIAL_DBUS_SERVICE) ||
368 manager_unit_pending_inactive(m, SPECIAL_DBUS_SOCKET)) {
369 r = -EADDRNOTAVAIL;
370 dbus_set_error(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down.");
371 } else {
372 r = manager_load_unit(m, name, NULL, &error, &u);
373
374 if (r >= 0 && u->refuse_manual_start)
375 r = -EPERM;
376
377 if (r >= 0)
378 r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &error, NULL);
379 }
380
381 if (r < 0) {
382 const char *id, *text;
383
384 log_debug("D-Bus activation failed for %s: %s", name, strerror(-r));
385
386 if (!(reply = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure")))
387 goto oom;
388
389 id = error.name ? error.name : bus_errno_to_dbus(r);
390 text = bus_error(&error, r);
391
392 if (!dbus_message_set_destination(reply, DBUS_SERVICE_DBUS) ||
393 !dbus_message_append_args(reply,
394 DBUS_TYPE_STRING, &name,
395 DBUS_TYPE_STRING, &id,
396 DBUS_TYPE_STRING, &text,
397 DBUS_TYPE_INVALID))
398 goto oom;
399 }
400
401 /* On success we don't do anything, the service will be spawned now */
402 }
403 }
404
405 dbus_error_free(&error);
406
407 if (reply) {
408 if (!dbus_connection_send(connection, reply, NULL))
409 goto oom;
410
411 dbus_message_unref(reply);
412 }
413
414 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
415
416 oom:
417 if (reply)
418 dbus_message_unref(reply);
419
420 dbus_error_free(&error);
421
422 return DBUS_HANDLER_RESULT_NEED_MEMORY;
423 }
424
425 static DBusHandlerResult system_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) {
426 Manager *m = data;
427 DBusError error;
428
429 assert(connection);
430 assert(message);
431 assert(m);
432
433 dbus_error_init(&error);
434
435 if (m->api_bus != m->system_bus &&
436 (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL ||
437 dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL))
438 log_debug("Got D-Bus request on system bus: %s.%s() on %s",
439 dbus_message_get_interface(message),
440 dbus_message_get_member(message),
441 dbus_message_get_path(message));
442
443 if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected")) {
444 log_debug("System D-Bus connection terminated.");
445 bus_done_system(m);
446
447 } else if (m->running_as != MANAGER_SYSTEM &&
448 dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) {
449
450 const char *cgroup;
451
452 if (!dbus_message_get_args(message, &error,
453 DBUS_TYPE_STRING, &cgroup,
454 DBUS_TYPE_INVALID))
455 log_error("Failed to parse Released message: %s", bus_error_message(&error));
456 else
457 cgroup_notify_empty(m, cgroup);
458 }
459
460 dbus_error_free(&error);
461 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
462 }
463
464 static DBusHandlerResult private_bus_message_filter(DBusConnection *connection, DBusMessage *message, void *data) {
465 Manager *m = data;
466 DBusError error;
467
468 assert(connection);
469 assert(message);
470 assert(m);
471
472 dbus_error_init(&error);
473
474 if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL ||
475 dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_SIGNAL)
476 log_debug("Got D-Bus request: %s.%s() on %s",
477 dbus_message_get_interface(message),
478 dbus_message_get_member(message),
479 dbus_message_get_path(message));
480
481 if (dbus_message_is_signal(message, DBUS_INTERFACE_LOCAL, "Disconnected"))
482 shutdown_connection(m, connection);
483 else if (m->running_as == MANAGER_SYSTEM &&
484 dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) {
485
486 const char *cgroup;
487
488 if (!dbus_message_get_args(message, &error,
489 DBUS_TYPE_STRING, &cgroup,
490 DBUS_TYPE_INVALID))
491 log_error("Failed to parse Released message: %s", bus_error_message(&error));
492 else
493 cgroup_notify_empty(m, cgroup);
494
495 /* Forward the message to the system bus, so that user
496 * instances are notified as well */
497
498 if (m->system_bus)
499 dbus_connection_send(m->system_bus, message, NULL);
500 }
501
502 dbus_error_free(&error);
503
504 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
505 }
506
507 unsigned bus_dispatch(Manager *m) {
508 DBusConnection *c;
509
510 assert(m);
511
512 if (m->queued_message) {
513 /* If we cannot get rid of this message we won't
514 * dispatch any D-Bus messages, so that we won't end
515 * up wanting to queue another message. */
516
517 if (m->queued_message_connection)
518 if (!dbus_connection_send(m->queued_message_connection, m->queued_message, NULL))
519 return 0;
520
521 dbus_message_unref(m->queued_message);
522 m->queued_message = NULL;
523 m->queued_message_connection = NULL;
524 }
525
526 if ((c = set_first(m->bus_connections_for_dispatch))) {
527 if (dbus_connection_dispatch(c) == DBUS_DISPATCH_COMPLETE)
528 set_move_one(m->bus_connections, m->bus_connections_for_dispatch, c);
529
530 return 1;
531 }
532
533 return 0;
534 }
535
536 static void request_name_pending_cb(DBusPendingCall *pending, void *userdata) {
537 DBusMessage *reply;
538 DBusError error;
539
540 dbus_error_init(&error);
541
542 assert_se(reply = dbus_pending_call_steal_reply(pending));
543
544 switch (dbus_message_get_type(reply)) {
545
546 case DBUS_MESSAGE_TYPE_ERROR:
547
548 assert_se(dbus_set_error_from_message(&error, reply));
549 log_warning("RequestName() failed: %s", bus_error_message(&error));
550 break;
551
552 case DBUS_MESSAGE_TYPE_METHOD_RETURN: {
553 uint32_t r;
554
555 if (!dbus_message_get_args(reply,
556 &error,
557 DBUS_TYPE_UINT32, &r,
558 DBUS_TYPE_INVALID)) {
559 log_error("Failed to parse RequestName() reply: %s", bus_error_message(&error));
560 break;
561 }
562
563 if (r == 1)
564 log_debug("Successfully acquired name.");
565 else
566 log_error("Name already owned.");
567
568 break;
569 }
570
571 default:
572 assert_not_reached("Invalid reply message");
573 }
574
575 dbus_message_unref(reply);
576 dbus_error_free(&error);
577 }
578
579 static int request_name(Manager *m) {
580 const char *name = "org.freedesktop.systemd1";
581 /* Allow replacing of our name, to ease implementation of
582 * reexecution, where we keep the old connection open until
583 * after the new connection is set up and the name installed
584 * to allow clients to synchronously wait for reexecution to
585 * finish */
586 uint32_t flags = DBUS_NAME_FLAG_ALLOW_REPLACEMENT|DBUS_NAME_FLAG_REPLACE_EXISTING;
587 DBusMessage *message = NULL;
588 DBusPendingCall *pending = NULL;
589
590 if (!(message = dbus_message_new_method_call(
591 DBUS_SERVICE_DBUS,
592 DBUS_PATH_DBUS,
593 DBUS_INTERFACE_DBUS,
594 "RequestName")))
595 goto oom;
596
597 if (!dbus_message_append_args(
598 message,
599 DBUS_TYPE_STRING, &name,
600 DBUS_TYPE_UINT32, &flags,
601 DBUS_TYPE_INVALID))
602 goto oom;
603
604 if (!dbus_connection_send_with_reply(m->api_bus, message, &pending, -1))
605 goto oom;
606
607 if (!dbus_pending_call_set_notify(pending, request_name_pending_cb, m, NULL))
608 goto oom;
609
610 dbus_message_unref(message);
611 dbus_pending_call_unref(pending);
612
613 /* We simple ask for the name and don't wait for it. Sooner or
614 * later we'll have it. */
615
616 return 0;
617
618 oom:
619 if (pending) {
620 dbus_pending_call_cancel(pending);
621 dbus_pending_call_unref(pending);
622 }
623
624 if (message)
625 dbus_message_unref(message);
626
627 return -ENOMEM;
628 }
629
630 static void query_name_list_pending_cb(DBusPendingCall *pending, void *userdata) {
631 DBusMessage *reply;
632 DBusError error;
633 Manager *m = userdata;
634
635 assert(m);
636
637 dbus_error_init(&error);
638
639 assert_se(reply = dbus_pending_call_steal_reply(pending));
640
641 switch (dbus_message_get_type(reply)) {
642
643 case DBUS_MESSAGE_TYPE_ERROR:
644
645 assert_se(dbus_set_error_from_message(&error, reply));
646 log_warning("ListNames() failed: %s", bus_error_message(&error));
647 break;
648
649 case DBUS_MESSAGE_TYPE_METHOD_RETURN: {
650 int r;
651 char **l;
652
653 if ((r = bus_parse_strv(reply, &l)) < 0)
654 log_warning("Failed to parse ListNames() reply: %s", strerror(-r));
655 else {
656 char **t;
657
658 STRV_FOREACH(t, l)
659 /* This is a bit hacky, we say the
660 * owner of the name is the name
661 * itself, because we don't want the
662 * extra traffic to figure out the
663 * real owner. */
664 manager_dispatch_bus_name_owner_changed(m, *t, NULL, *t);
665
666 strv_free(l);
667 }
668
669 break;
670 }
671
672 default:
673 assert_not_reached("Invalid reply message");
674 }
675
676 dbus_message_unref(reply);
677 dbus_error_free(&error);
678 }
679
680 static int query_name_list(Manager *m) {
681 DBusMessage *message = NULL;
682 DBusPendingCall *pending = NULL;
683
684 /* Asks for the currently installed bus names */
685
686 if (!(message = dbus_message_new_method_call(
687 DBUS_SERVICE_DBUS,
688 DBUS_PATH_DBUS,
689 DBUS_INTERFACE_DBUS,
690 "ListNames")))
691 goto oom;
692
693 if (!dbus_connection_send_with_reply(m->api_bus, message, &pending, -1))
694 goto oom;
695
696 if (!dbus_pending_call_set_notify(pending, query_name_list_pending_cb, m, NULL))
697 goto oom;
698
699 dbus_message_unref(message);
700 dbus_pending_call_unref(pending);
701
702 /* We simple ask for the list and don't wait for it. Sooner or
703 * later we'll get it. */
704
705 return 0;
706
707 oom:
708 if (pending) {
709 dbus_pending_call_cancel(pending);
710 dbus_pending_call_unref(pending);
711 }
712
713 if (message)
714 dbus_message_unref(message);
715
716 return -ENOMEM;
717 }
718
719 static int bus_setup_loop(Manager *m, DBusConnection *bus) {
720 assert(m);
721 assert(bus);
722
723 dbus_connection_set_exit_on_disconnect(bus, FALSE);
724
725 if (!dbus_connection_set_watch_functions(bus, bus_add_watch, bus_remove_watch, bus_toggle_watch, m, NULL) ||
726 !dbus_connection_set_timeout_functions(bus, bus_add_timeout, bus_remove_timeout, bus_toggle_timeout, m, NULL)) {
727 log_error("Not enough memory");
728 return -ENOMEM;
729 }
730
731 if (set_put(m->bus_connections_for_dispatch, bus) < 0) {
732 log_error("Not enough memory");
733 return -ENOMEM;
734 }
735
736 dbus_connection_set_dispatch_status_function(bus, bus_dispatch_status, m, NULL);
737 return 0;
738 }
739
740 static dbus_bool_t allow_only_same_user(DBusConnection *connection, unsigned long uid, void *data) {
741 return uid == 0 || uid == geteuid();
742 }
743
744 static void bus_new_connection(
745 DBusServer *server,
746 DBusConnection *new_connection,
747 void *data) {
748
749 Manager *m = data;
750
751 assert(m);
752
753 if (set_size(m->bus_connections) >= CONNECTIONS_MAX) {
754 log_error("Too many concurrent connections.");
755 return;
756 }
757
758 dbus_connection_set_unix_user_function(new_connection, allow_only_same_user, NULL, NULL);
759
760 if (bus_setup_loop(m, new_connection) < 0)
761 return;
762
763 if (!dbus_connection_register_object_path(new_connection, "/org/freedesktop/systemd1", &bus_manager_vtable, m) ||
764 !dbus_connection_register_fallback(new_connection, "/org/freedesktop/systemd1/unit", &bus_unit_vtable, m) ||
765 !dbus_connection_register_fallback(new_connection, "/org/freedesktop/systemd1/job", &bus_job_vtable, m) ||
766 !dbus_connection_add_filter(new_connection, private_bus_message_filter, m, NULL)) {
767 log_error("Not enough memory.");
768 return;
769 }
770
771 log_debug("Accepted connection on private bus.");
772
773 dbus_connection_ref(new_connection);
774 }
775
776 static int init_registered_system_bus(Manager *m) {
777 char *id;
778
779 if (!dbus_connection_add_filter(m->system_bus, system_bus_message_filter, m, NULL)) {
780 log_error("Not enough memory");
781 return -ENOMEM;
782 }
783
784 if (m->running_as != MANAGER_SYSTEM) {
785 DBusError error;
786
787 dbus_error_init(&error);
788
789 dbus_bus_add_match(m->system_bus,
790 "type='signal',"
791 "interface='org.freedesktop.systemd1.Agent',"
792 "member='Released',"
793 "path='/org/freedesktop/systemd1/agent'",
794 &error);
795
796 if (dbus_error_is_set(&error)) {
797 log_error("Failed to register match: %s", bus_error_message(&error));
798 dbus_error_free(&error);
799 return -1;
800 }
801 }
802
803 log_debug("Successfully connected to system D-Bus bus %s as %s",
804 strnull((id = dbus_connection_get_server_id(m->system_bus))),
805 strnull(dbus_bus_get_unique_name(m->system_bus)));
806 dbus_free(id);
807
808 return 0;
809 }
810
811 static int init_registered_api_bus(Manager *m) {
812 int r;
813
814 if (!dbus_connection_register_object_path(m->api_bus, "/org/freedesktop/systemd1", &bus_manager_vtable, m) ||
815 !dbus_connection_register_fallback(m->api_bus, "/org/freedesktop/systemd1/unit", &bus_unit_vtable, m) ||
816 !dbus_connection_register_fallback(m->api_bus, "/org/freedesktop/systemd1/job", &bus_job_vtable, m) ||
817 !dbus_connection_add_filter(m->api_bus, api_bus_message_filter, m, NULL)) {
818 log_error("Not enough memory");
819 return -ENOMEM;
820 }
821
822 /* Get NameOwnerChange messages */
823 dbus_bus_add_match(m->api_bus,
824 "type='signal',"
825 "sender='"DBUS_SERVICE_DBUS"',"
826 "interface='"DBUS_INTERFACE_DBUS"',"
827 "member='NameOwnerChanged',"
828 "path='"DBUS_PATH_DBUS"'",
829 NULL);
830
831 /* Get activation requests */
832 dbus_bus_add_match(m->api_bus,
833 "type='signal',"
834 "sender='"DBUS_SERVICE_DBUS"',"
835 "interface='org.freedesktop.systemd1.Activator',"
836 "member='ActivationRequest',"
837 "path='"DBUS_PATH_DBUS"'",
838 NULL);
839
840 r = request_name(m);
841 if (r < 0)
842 return r;
843
844 r = query_name_list(m);
845 if (r < 0)
846 return r;
847
848 if (m->running_as == MANAGER_USER) {
849 char *id;
850 log_debug("Successfully connected to API D-Bus bus %s as %s",
851 strnull((id = dbus_connection_get_server_id(m->api_bus))),
852 strnull(dbus_bus_get_unique_name(m->api_bus)));
853 dbus_free(id);
854 } else
855 log_debug("Successfully initialized API on the system bus");
856
857 return 0;
858 }
859
860 static void bus_register_cb(DBusPendingCall *pending, void *userdata) {
861 Manager *m = userdata;
862 DBusConnection **conn;
863 DBusMessage *reply;
864 DBusError error;
865 const char *name;
866 int r = 0;
867
868 dbus_error_init(&error);
869
870 conn = dbus_pending_call_get_data(pending, m->conn_data_slot);
871 assert(conn == &m->system_bus || conn == &m->api_bus);
872
873 reply = dbus_pending_call_steal_reply(pending);
874
875 switch (dbus_message_get_type(reply)) {
876 case DBUS_MESSAGE_TYPE_ERROR:
877 assert_se(dbus_set_error_from_message(&error, reply));
878 log_warning("Failed to register to bus: %s", bus_error_message(&error));
879 r = -1;
880 break;
881 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
882 if (!dbus_message_get_args(reply, &error,
883 DBUS_TYPE_STRING, &name,
884 DBUS_TYPE_INVALID)) {
885 log_error("Failed to parse Hello reply: %s", bus_error_message(&error));
886 r = -1;
887 break;
888 }
889
890 log_debug("Received name %s in reply to Hello", name);
891 if (!dbus_bus_set_unique_name(*conn, name)) {
892 log_error("Failed to set unique name");
893 r = -1;
894 break;
895 }
896
897 if (conn == &m->system_bus) {
898 r = init_registered_system_bus(m);
899 if (r == 0 && m->running_as == MANAGER_SYSTEM)
900 r = init_registered_api_bus(m);
901 } else
902 r = init_registered_api_bus(m);
903
904 break;
905 default:
906 assert_not_reached("Invalid reply message");
907 }
908
909 dbus_message_unref(reply);
910 dbus_error_free(&error);
911
912 if (r < 0) {
913 if (conn == &m->system_bus) {
914 log_debug("Failed setting up the system bus");
915 bus_done_system(m);
916 } else {
917 log_debug("Failed setting up the API bus");
918 bus_done_api(m);
919 }
920 }
921 }
922
923 static int manager_bus_async_register(Manager *m, DBusConnection **conn) {
924 DBusMessage *message = NULL;
925 DBusPendingCall *pending = NULL;
926
927 message = dbus_message_new_method_call(DBUS_SERVICE_DBUS,
928 DBUS_PATH_DBUS,
929 DBUS_INTERFACE_DBUS,
930 "Hello");
931 if (!message)
932 goto oom;
933
934 if (!dbus_connection_send_with_reply(*conn, message, &pending, -1))
935 goto oom;
936
937 if (!dbus_pending_call_set_data(pending, m->conn_data_slot, conn, NULL))
938 goto oom;
939
940 if (!dbus_pending_call_set_notify(pending, bus_register_cb, m, NULL))
941 goto oom;
942
943 dbus_message_unref(message);
944 dbus_pending_call_unref(pending);
945
946 return 0;
947 oom:
948 if (pending) {
949 dbus_pending_call_cancel(pending);
950 dbus_pending_call_unref(pending);
951 }
952
953 if (message)
954 dbus_message_unref(message);
955
956 return -ENOMEM;
957 }
958
959 static DBusConnection* manager_bus_connect_private(Manager *m, DBusBusType type) {
960 const char *address;
961 DBusConnection *connection;
962 DBusError error;
963
964 switch (type) {
965 case DBUS_BUS_SYSTEM:
966 address = getenv("DBUS_SYSTEM_BUS_ADDRESS");
967 if (!address || !address[0])
968 address = DBUS_SYSTEM_BUS_DEFAULT_ADDRESS;
969 break;
970 case DBUS_BUS_SESSION:
971 address = getenv("DBUS_SESSION_BUS_ADDRESS");
972 if (!address || !address[0])
973 address = DBUS_SESSION_BUS_DEFAULT_ADDRESS;
974 break;
975 default:
976 assert_not_reached("Invalid bus type");
977 }
978
979 dbus_error_init(&error);
980
981 connection = dbus_connection_open_private(address, &error);
982 if (!connection) {
983 log_warning("Failed to open private bus connection: %s", bus_error_message(&error));
984 goto fail;
985 }
986
987 return connection;
988 fail:
989 if (connection)
990 dbus_connection_close(connection);
991 dbus_error_free(&error);
992 return NULL;
993 }
994
995 static int bus_init_system(Manager *m) {
996 int r;
997
998 if (m->system_bus)
999 return 0;
1000
1001 m->system_bus = manager_bus_connect_private(m, DBUS_BUS_SYSTEM);
1002 if (!m->system_bus) {
1003 log_debug("Failed to connect to system D-Bus, retrying later");
1004 r = 0;
1005 goto fail;
1006 }
1007
1008 r = bus_setup_loop(m, m->system_bus);
1009 if (r < 0)
1010 goto fail;
1011
1012 r = manager_bus_async_register(m, &m->system_bus);
1013 if (r < 0)
1014 goto fail;
1015
1016 return 0;
1017 fail:
1018 bus_done_system(m);
1019
1020 return r;
1021 }
1022
1023 static int bus_init_api(Manager *m) {
1024 int r;
1025
1026 if (m->api_bus)
1027 return 0;
1028
1029 if (m->running_as == MANAGER_SYSTEM) {
1030 m->api_bus = m->system_bus;
1031 /* In this mode there is no distinct connection to the API bus,
1032 * the API is published on the system bus.
1033 * bus_register_cb() is aware of that and will init the API
1034 * when the system bus gets registered.
1035 * No need to setup anything here. */
1036 return 0;
1037 }
1038
1039 m->api_bus = manager_bus_connect_private(m, DBUS_BUS_SESSION);
1040 if (!m->api_bus) {
1041 log_debug("Failed to connect to API D-Bus, retrying later");
1042 r = 0;
1043 goto fail;
1044 }
1045
1046 r = bus_setup_loop(m, m->api_bus);
1047 if (r < 0)
1048 goto fail;
1049
1050 r = manager_bus_async_register(m, &m->api_bus);
1051 if (r < 0)
1052 goto fail;
1053
1054 return 0;
1055 fail:
1056 bus_done_api(m);
1057
1058 return r;
1059 }
1060
1061 static int bus_init_private(Manager *m) {
1062 DBusError error;
1063 int r;
1064 const char *const external_only[] = {
1065 "EXTERNAL",
1066 NULL
1067 };
1068
1069 assert(m);
1070
1071 dbus_error_init(&error);
1072
1073 if (m->private_bus)
1074 return 0;
1075
1076 if (m->running_as == MANAGER_SYSTEM) {
1077
1078 /* We want the private bus only when running as init */
1079 if (getpid() != 1)
1080 return 0;
1081
1082 unlink("/run/systemd/private");
1083 m->private_bus = dbus_server_listen("unix:path=/run/systemd/private", &error);
1084 } else {
1085 const char *e;
1086 char *p;
1087
1088 e = getenv("XDG_RUNTIME_DIR");
1089 if (!e)
1090 return 0;
1091
1092 if (asprintf(&p, "unix:path=%s/systemd/private", e) < 0) {
1093 log_error("Not enough memory");
1094 r = -ENOMEM;
1095 goto fail;
1096 }
1097
1098 mkdir_parents_label(p+10, 0755);
1099 unlink(p+10);
1100 m->private_bus = dbus_server_listen(p, &error);
1101 free(p);
1102 }
1103
1104 if (!m->private_bus) {
1105 log_error("Failed to create private D-Bus server: %s", bus_error_message(&error));
1106 r = -EIO;
1107 goto fail;
1108 }
1109
1110 if (!dbus_server_set_auth_mechanisms(m->private_bus, (const char**) external_only) ||
1111 !dbus_server_set_watch_functions(m->private_bus, bus_add_watch, bus_remove_watch, bus_toggle_watch, m, NULL) ||
1112 !dbus_server_set_timeout_functions(m->private_bus, bus_add_timeout, bus_remove_timeout, bus_toggle_timeout, m, NULL)) {
1113 log_error("Not enough memory");
1114 r = -ENOMEM;
1115 goto fail;
1116 }
1117
1118 dbus_server_set_new_connection_function(m->private_bus, bus_new_connection, m, NULL);
1119
1120 log_debug("Successfully created private D-Bus server.");
1121
1122 return 0;
1123
1124 fail:
1125 bus_done_private(m);
1126 dbus_error_free(&error);
1127
1128 return r;
1129 }
1130
1131 int bus_init(Manager *m, bool try_bus_connect) {
1132 int r;
1133
1134 if (set_ensure_allocated(&m->bus_connections, trivial_hash_func, trivial_compare_func) < 0 ||
1135 set_ensure_allocated(&m->bus_connections_for_dispatch, trivial_hash_func, trivial_compare_func) < 0)
1136 goto oom;
1137
1138 if (m->name_data_slot < 0)
1139 if (!dbus_pending_call_allocate_data_slot(&m->name_data_slot))
1140 goto oom;
1141
1142 if (m->conn_data_slot < 0)
1143 if (!dbus_pending_call_allocate_data_slot(&m->conn_data_slot))
1144 goto oom;
1145
1146 if (m->subscribed_data_slot < 0)
1147 if (!dbus_connection_allocate_data_slot(&m->subscribed_data_slot))
1148 goto oom;
1149
1150 if (try_bus_connect) {
1151 if ((r = bus_init_system(m)) < 0 ||
1152 (r = bus_init_api(m)) < 0)
1153 return r;
1154 }
1155
1156 if ((r = bus_init_private(m)) < 0)
1157 return r;
1158
1159 return 0;
1160 oom:
1161 log_error("Not enough memory");
1162 return -ENOMEM;
1163 }
1164
1165 static void shutdown_connection(Manager *m, DBusConnection *c) {
1166 Set *s;
1167 Job *j;
1168 Iterator i;
1169
1170 HASHMAP_FOREACH(j, m->jobs, i) {
1171 JobBusClient *cl, *nextcl;
1172 LIST_FOREACH_SAFE(client, cl, nextcl, j->bus_client_list) {
1173 if (cl->bus == c) {
1174 LIST_REMOVE(JobBusClient, client, j->bus_client_list, cl);
1175 free(cl);
1176 }
1177 }
1178 }
1179
1180 set_remove(m->bus_connections, c);
1181 set_remove(m->bus_connections_for_dispatch, c);
1182
1183 if ((s = BUS_CONNECTION_SUBSCRIBED(m, c))) {
1184 char *t;
1185
1186 while ((t = set_steal_first(s)))
1187 free(t);
1188
1189 set_free(s);
1190 }
1191
1192 if (m->queued_message_connection == c) {
1193 m->queued_message_connection = NULL;
1194
1195 if (m->queued_message) {
1196 dbus_message_unref(m->queued_message);
1197 m->queued_message = NULL;
1198 }
1199 }
1200
1201 dbus_connection_set_dispatch_status_function(c, NULL, NULL, NULL);
1202 /* system manager cannot afford to block on DBus */
1203 if (m->running_as != MANAGER_SYSTEM)
1204 dbus_connection_flush(c);
1205 dbus_connection_close(c);
1206 dbus_connection_unref(c);
1207 }
1208
1209 static void bus_done_api(Manager *m) {
1210 if (!m->api_bus)
1211 return;
1212
1213 if (m->running_as == MANAGER_USER)
1214 shutdown_connection(m, m->api_bus);
1215
1216 m->api_bus = NULL;
1217
1218 if (m->queued_message) {
1219 dbus_message_unref(m->queued_message);
1220 m->queued_message = NULL;
1221 }
1222 }
1223
1224 static void bus_done_system(Manager *m) {
1225 if (!m->system_bus)
1226 return;
1227
1228 if (m->running_as == MANAGER_SYSTEM)
1229 bus_done_api(m);
1230
1231 shutdown_connection(m, m->system_bus);
1232 m->system_bus = NULL;
1233 }
1234
1235 static void bus_done_private(Manager *m) {
1236 if (!m->private_bus)
1237 return;
1238
1239 dbus_server_disconnect(m->private_bus);
1240 dbus_server_unref(m->private_bus);
1241 m->private_bus = NULL;
1242 }
1243
1244 void bus_done(Manager *m) {
1245 DBusConnection *c;
1246
1247 bus_done_api(m);
1248 bus_done_system(m);
1249 bus_done_private(m);
1250
1251 while ((c = set_steal_first(m->bus_connections)))
1252 shutdown_connection(m, c);
1253
1254 while ((c = set_steal_first(m->bus_connections_for_dispatch)))
1255 shutdown_connection(m, c);
1256
1257 set_free(m->bus_connections);
1258 set_free(m->bus_connections_for_dispatch);
1259
1260 if (m->name_data_slot >= 0)
1261 dbus_pending_call_free_data_slot(&m->name_data_slot);
1262
1263 if (m->conn_data_slot >= 0)
1264 dbus_pending_call_free_data_slot(&m->conn_data_slot);
1265
1266 if (m->subscribed_data_slot >= 0)
1267 dbus_connection_free_data_slot(&m->subscribed_data_slot);
1268 }
1269
1270 static void query_pid_pending_cb(DBusPendingCall *pending, void *userdata) {
1271 Manager *m = userdata;
1272 DBusMessage *reply;
1273 DBusError error;
1274 const char *name;
1275
1276 dbus_error_init(&error);
1277
1278 assert_se(name = BUS_PENDING_CALL_NAME(m, pending));
1279 assert_se(reply = dbus_pending_call_steal_reply(pending));
1280
1281 switch (dbus_message_get_type(reply)) {
1282
1283 case DBUS_MESSAGE_TYPE_ERROR:
1284
1285 assert_se(dbus_set_error_from_message(&error, reply));
1286 log_warning("GetConnectionUnixProcessID() failed: %s", bus_error_message(&error));
1287 break;
1288
1289 case DBUS_MESSAGE_TYPE_METHOD_RETURN: {
1290 uint32_t r;
1291
1292 if (!dbus_message_get_args(reply,
1293 &error,
1294 DBUS_TYPE_UINT32, &r,
1295 DBUS_TYPE_INVALID)) {
1296 log_error("Failed to parse GetConnectionUnixProcessID() reply: %s", bus_error_message(&error));
1297 break;
1298 }
1299
1300 manager_dispatch_bus_query_pid_done(m, name, (pid_t) r);
1301 break;
1302 }
1303
1304 default:
1305 assert_not_reached("Invalid reply message");
1306 }
1307
1308 dbus_message_unref(reply);
1309 dbus_error_free(&error);
1310 }
1311
1312 int bus_query_pid(Manager *m, const char *name) {
1313 DBusMessage *message = NULL;
1314 DBusPendingCall *pending = NULL;
1315 char *n = NULL;
1316
1317 assert(m);
1318 assert(name);
1319
1320 if (!(message = dbus_message_new_method_call(
1321 DBUS_SERVICE_DBUS,
1322 DBUS_PATH_DBUS,
1323 DBUS_INTERFACE_DBUS,
1324 "GetConnectionUnixProcessID")))
1325 goto oom;
1326
1327 if (!(dbus_message_append_args(
1328 message,
1329 DBUS_TYPE_STRING, &name,
1330 DBUS_TYPE_INVALID)))
1331 goto oom;
1332
1333 if (!dbus_connection_send_with_reply(m->api_bus, message, &pending, -1))
1334 goto oom;
1335
1336 if (!(n = strdup(name)))
1337 goto oom;
1338
1339 if (!dbus_pending_call_set_data(pending, m->name_data_slot, n, free))
1340 goto oom;
1341
1342 n = NULL;
1343
1344 if (!dbus_pending_call_set_notify(pending, query_pid_pending_cb, m, NULL))
1345 goto oom;
1346
1347 dbus_message_unref(message);
1348 dbus_pending_call_unref(pending);
1349
1350 return 0;
1351
1352 oom:
1353 free(n);
1354
1355 if (pending) {
1356 dbus_pending_call_cancel(pending);
1357 dbus_pending_call_unref(pending);
1358 }
1359
1360 if (message)
1361 dbus_message_unref(message);
1362
1363 return -ENOMEM;
1364 }
1365
1366 int bus_broadcast(Manager *m, DBusMessage *message) {
1367 bool oom = false;
1368 Iterator i;
1369 DBusConnection *c;
1370
1371 assert(m);
1372 assert(message);
1373
1374 SET_FOREACH(c, m->bus_connections_for_dispatch, i)
1375 if (c != m->system_bus || m->running_as == MANAGER_SYSTEM)
1376 oom = !dbus_connection_send(c, message, NULL);
1377
1378 SET_FOREACH(c, m->bus_connections, i)
1379 if (c != m->system_bus || m->running_as == MANAGER_SYSTEM)
1380 oom = !dbus_connection_send(c, message, NULL);
1381
1382 return oom ? -ENOMEM : 0;
1383 }
1384
1385 bool bus_has_subscriber(Manager *m) {
1386 Iterator i;
1387 DBusConnection *c;
1388
1389 assert(m);
1390
1391 SET_FOREACH(c, m->bus_connections_for_dispatch, i)
1392 if (bus_connection_has_subscriber(m, c))
1393 return true;
1394
1395 SET_FOREACH(c, m->bus_connections, i)
1396 if (bus_connection_has_subscriber(m, c))
1397 return true;
1398
1399 return false;
1400 }
1401
1402 bool bus_connection_has_subscriber(Manager *m, DBusConnection *c) {
1403 assert(m);
1404 assert(c);
1405
1406 return !set_isempty(BUS_CONNECTION_SUBSCRIBED(m, c));
1407 }
1408
1409 int bus_fdset_add_all(Manager *m, FDSet *fds) {
1410 Iterator i;
1411 DBusConnection *c;
1412
1413 assert(m);
1414 assert(fds);
1415
1416 /* When we are about to reexecute we add all D-Bus fds to the
1417 * set to pass over to the newly executed systemd. They won't
1418 * be used there however, except that they are closed at the
1419 * very end of deserialization, those making it possible for
1420 * clients to synchronously wait for systemd to reexec by
1421 * simply waiting for disconnection */
1422
1423 SET_FOREACH(c, m->bus_connections_for_dispatch, i) {
1424 int fd;
1425
1426 if (dbus_connection_get_unix_fd(c, &fd)) {
1427 fd = fdset_put_dup(fds, fd);
1428
1429 if (fd < 0)
1430 return fd;
1431 }
1432 }
1433
1434 SET_FOREACH(c, m->bus_connections, i) {
1435 int fd;
1436
1437 if (dbus_connection_get_unix_fd(c, &fd)) {
1438 fd = fdset_put_dup(fds, fd);
1439
1440 if (fd < 0)
1441 return fd;
1442 }
1443 }
1444
1445 return 0;
1446 }
1447
1448 void bus_broadcast_finished(
1449 Manager *m,
1450 usec_t kernel_usec,
1451 usec_t initrd_usec,
1452 usec_t userspace_usec,
1453 usec_t total_usec) {
1454
1455 DBusMessage *message;
1456
1457 assert(m);
1458
1459 message = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
1460 if (!message) {
1461 log_error("Out of memory.");
1462 return;
1463 }
1464
1465 assert_cc(sizeof(usec_t) == sizeof(uint64_t));
1466 if (!dbus_message_append_args(message,
1467 DBUS_TYPE_UINT64, &kernel_usec,
1468 DBUS_TYPE_UINT64, &initrd_usec,
1469 DBUS_TYPE_UINT64, &userspace_usec,
1470 DBUS_TYPE_UINT64, &total_usec,
1471 DBUS_TYPE_INVALID)) {
1472 log_error("Out of memory.");
1473 goto finish;
1474 }
1475
1476
1477 if (bus_broadcast(m, message) < 0) {
1478 log_error("Out of memory.");
1479 goto finish;
1480 }
1481
1482 finish:
1483 if (message)
1484 dbus_message_unref(message);
1485 }