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