]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/dbus.c
bus: instead of exposing the dbus1 flags when acquiring a name use our own that are...
[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
27 #include "sd-bus.h"
28 #include "log.h"
29 #include "strv.h"
30 #include "mkdir.h"
31 #include "missing.h"
32 #include "dbus-unit.h"
33 #include "dbus-job.h"
34 #include "dbus-manager.h"
35 #include "dbus-execute.h"
36 #include "dbus-kill.h"
37 #include "dbus-cgroup.h"
38 #include "special.h"
39 #include "dbus.h"
40 #include "bus-util.h"
41 #include "bus-error.h"
42 #include "bus-errors.h"
43 #include "strxcpyx.h"
44 #include "dbus-client-track.h"
45 #include "bus-internal.h"
46 #include "selinux-access.h"
47
48 #define CONNECTIONS_MAX 512
49
50 static void destroy_bus(Manager *m, sd_bus **bus);
51
52 int bus_send_queued_message(Manager *m) {
53 int r;
54
55 assert(m);
56
57 if (!m->queued_message)
58 return 0;
59
60 assert(m->queued_message_bus);
61
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
64 * another message. */
65
66 r = sd_bus_send(m->queued_message_bus, m->queued_message, NULL);
67 if (r < 0)
68 log_warning("Failed to send queued message: %s", strerror(-r));
69
70 m->queued_message = sd_bus_message_unref(m->queued_message);
71 m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
72
73 return 0;
74 }
75
76 static int signal_agent_released(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
77 Manager *m = userdata;
78 const char *cgroup;
79 int r;
80
81 assert(bus);
82 assert(message);
83 assert(m);
84
85 r = sd_bus_message_read(message, "s", &cgroup);
86 if (r < 0) {
87 bus_log_parse_error(r);
88 return 0;
89 }
90
91 manager_notify_cgroup_empty(m, cgroup);
92
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 */
96
97 r = sd_bus_send(m->system_bus, message, NULL);
98 if (r < 0)
99 log_warning("Failed to forward Released message: %s", strerror(-r));
100 }
101
102 return 0;
103 }
104
105 static int signal_disconnected(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
106 Manager *m = userdata;
107
108 assert(bus);
109 assert(message);
110 assert(m);
111
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);
119 }
120
121 return 0;
122 }
123
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;
127 int r;
128
129 assert(bus);
130 assert(message);
131 assert(m);
132
133 r = sd_bus_message_read(message, "sss", &name, &old_owner, &new_owner);
134 if (r < 0) {
135 bus_log_parse_error(r);
136 return 0;
137 }
138
139 manager_dispatch_bus_name_owner_changed(
140 m, name,
141 isempty(old_owner) ? NULL : old_owner,
142 isempty(new_owner) ? NULL : new_owner);
143
144 return 0;
145 }
146
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;
151 const char *name;
152 Unit *u;
153 int r;
154
155 assert(bus);
156 assert(message);
157 assert(m);
158
159 r = sd_bus_message_read(message, "s", &name);
160 if (r < 0) {
161 bus_log_parse_error(r);
162 return 0;
163 }
164
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.");
168 goto failed;
169 }
170
171 r = manager_load_unit(m, name, NULL, &error, &u);
172 if (r < 0)
173 goto failed;
174
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);
177 goto failed;
178 }
179
180 r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &error, NULL);
181 if (r < 0)
182 goto failed;
183
184 /* Successfully queued, that's it for us */
185 return 0;
186
187 failed:
188 if (!sd_bus_error_is_set(&error))
189 sd_bus_error_set_errno(&error, r);
190
191 log_debug("D-Bus activation failed for %s: %s", name, bus_error_message(&error, r));
192
193 r = sd_bus_message_new_signal(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure", &reply);
194 if (r < 0) {
195 bus_log_create_error(r);
196 return 0;
197 }
198
199 r = sd_bus_message_append(reply, "sss", name, error.name, error.message);
200 if (r < 0) {
201 bus_log_create_error(r);
202 return 0;
203 }
204
205 r = sd_bus_send_to(bus, reply, "org.freedesktop.DBus", NULL);
206 if (r < 0) {
207 log_error("Failed to respond with to bus activation request: %s", strerror(-r));
208 return r;
209 }
210
211 return 0;
212 }
213
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;
217 Unit *u = NULL;
218 Job *j;
219 int r;
220
221 assert(bus);
222 assert(message);
223
224 /* Our own method calls are all protected individually with
225 * selinux checks, but the built-in interfaces need to be
226 * protected too. */
227
228 if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set"))
229 verb = "reload";
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))
234 verb = "status";
235 else
236 return 0;
237
238 path = sd_bus_message_get_path(message);
239
240 if (object_path_startswith("/org/freedesktop/systemd1", path)) {
241
242 r = selinux_access_check(bus, message, verb, error);
243 if (r < 0)
244 return r;
245
246 return 0;
247 }
248
249 if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
250 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
251 pid_t pid;
252
253 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
254 if (r < 0)
255 return 0;
256
257 r = sd_bus_creds_get_pid(creds, &pid);
258 if (r < 0)
259 return 0;
260
261 u = manager_get_unit_by_pid(m, pid);
262 } else {
263 r = manager_get_job_from_dbus_path(m, path, &j);
264 if (r >= 0)
265 u = j->unit;
266 else
267 manager_load_unit_from_dbus_path(m, path, NULL, &u);
268 }
269
270 if (!u)
271 return 0;
272
273 r = selinux_unit_access_check(u, bus, message, verb, error);
274 if (r < 0)
275 return r;
276
277 return 0;
278 }
279
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;
282 Job *j;
283 int r;
284
285 assert(bus);
286 assert(path);
287 assert(interface);
288 assert(found);
289 assert(m);
290
291 r = manager_get_job_from_dbus_path(m, path, &j);
292 if (r < 0)
293 return 0;
294
295 *found = j;
296 return 1;
297 }
298
299 static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_bus_error *error) {
300 Unit *u;
301 int r;
302
303 assert(m);
304 assert(bus);
305 assert(path);
306
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;
310 pid_t pid;
311
312 message = sd_bus_get_current(bus);
313 if (!message)
314 return 0;
315
316 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
317 if (r < 0)
318 return r;
319
320 r = sd_bus_creds_get_pid(creds, &pid);
321 if (r < 0)
322 return r;
323
324 u = manager_get_unit_by_pid(m, pid);
325 } else {
326 r = manager_load_unit_from_dbus_path(m, path, error, &u);
327 if (r < 0)
328 return 0;
329 }
330
331 if (!u)
332 return 0;
333
334 *unit = u;
335 return 1;
336 }
337
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;
340
341 assert(bus);
342 assert(path);
343 assert(interface);
344 assert(found);
345 assert(m);
346
347 return find_unit(m, bus, path, (Unit**) found, error);
348 }
349
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;
352 Unit *u;
353 int r;
354
355 assert(bus);
356 assert(path);
357 assert(interface);
358 assert(found);
359 assert(m);
360
361 r = find_unit(m, bus, path, &u, error);
362 if (r <= 0)
363 return r;
364
365 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
366 return 0;
367
368 *found = u;
369 return 1;
370 }
371
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;
374 Unit *u;
375 int r;
376
377 assert(bus);
378 assert(path);
379 assert(interface);
380 assert(found);
381 assert(m);
382
383 r = find_unit(m, bus, path, &u, error);
384 if (r <= 0)
385 return r;
386
387 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
388 return 0;
389
390 if (!unit_get_cgroup_context(u))
391 return 0;
392
393 *found = u;
394 return 1;
395 }
396
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;
399 CGroupContext *c;
400 Unit *u;
401 int r;
402
403 assert(bus);
404 assert(path);
405 assert(interface);
406 assert(found);
407 assert(m);
408
409 r = find_unit(m, bus, path, &u, error);
410 if (r <= 0)
411 return r;
412
413 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
414 return 0;
415
416 c = unit_get_cgroup_context(u);
417 if (!c)
418 return 0;
419
420 *found = c;
421 return 1;
422 }
423
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;
426 ExecContext *c;
427 Unit *u;
428 int r;
429
430 assert(bus);
431 assert(path);
432 assert(interface);
433 assert(found);
434 assert(m);
435
436 r = find_unit(m, bus, path, &u, error);
437 if (r <= 0)
438 return r;
439
440 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
441 return 0;
442
443 c = unit_get_exec_context(u);
444 if (!c)
445 return 0;
446
447 *found = c;
448 return 1;
449 }
450
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;
453 KillContext *c;
454 Unit *u;
455 int r;
456
457 assert(bus);
458 assert(path);
459 assert(interface);
460 assert(found);
461 assert(m);
462
463 r = find_unit(m, bus, path, &u, error);
464 if (r <= 0)
465 return r;
466
467 if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
468 return 0;
469
470 c = unit_get_kill_context(u);
471 if (!c)
472 return 0;
473
474 *found = c;
475 return 1;
476 }
477
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;
481 unsigned k = 0;
482 Iterator i;
483 Job *j;
484
485 l = new0(char*, hashmap_size(m->jobs)+1);
486 if (!l)
487 return -ENOMEM;
488
489 HASHMAP_FOREACH(j, m->jobs, i) {
490 l[k] = job_dbus_path(j);
491 if (!l[k])
492 return -ENOMEM;
493
494 k++;
495 }
496
497 assert(hashmap_size(m->jobs) == k);
498
499 *nodes = l;
500 l = NULL;
501
502 return k;
503 }
504
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;
508 unsigned k = 0;
509 Iterator i;
510 Unit *u;
511
512 l = new0(char*, hashmap_size(m->units)+1);
513 if (!l)
514 return -ENOMEM;
515
516 HASHMAP_FOREACH(u, m->units, i) {
517 l[k] = unit_dbus_path(u);
518 if (!l[k])
519 return -ENOMEM;
520
521 k++;
522 }
523
524 *nodes = l;
525 l = NULL;
526
527 return k;
528 }
529
530 static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
531 UnitType t;
532 int r;
533
534 assert(m);
535 assert(bus);
536
537 r = sd_bus_add_filter(bus, selinux_filter, m);
538 if (r < 0) {
539 log_error("Failed to add SELinux access filter: %s", strerror(-r));
540 return r;
541 }
542
543 r = sd_bus_add_object_vtable(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
544 if (r < 0) {
545 log_error("Failed to register Manager vtable: %s", strerror(-r));
546 return r;
547 }
548
549 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
550 if (r < 0) {
551 log_error("Failed to register Job vtable: %s", strerror(-r));
552 return r;
553 }
554
555 r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
556 if (r < 0) {
557 log_error("Failed to add job enumerator: %s", strerror(-r));
558 return r;
559 }
560
561 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
562 if (r < 0) {
563 log_error("Failed to register Unit vtable: %s", strerror(-r));
564 return r;
565 }
566
567 r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
568 if (r < 0) {
569 log_error("Failed to add job enumerator: %s", strerror(-r));
570 return r;
571 }
572
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);
575 if (r < 0) {
576 log_error("Failed to register type specific vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
577 return r;
578 }
579
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);
582 if (r < 0) {
583 log_error("Failed to register control group unit vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
584 return r;
585 }
586
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);
588 if (r < 0) {
589 log_error("Failed to register control group vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
590 return r;
591 }
592 }
593
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);
596 if (r < 0) {
597 log_error("Failed to register execute vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
598 return r;
599 }
600 }
601
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);
604 if (r < 0) {
605 log_error("Failed to register kill vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
606 return r;
607 }
608 }
609 }
610
611 return 0;
612 }
613
614 static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
615 int r;
616
617 assert(m);
618 assert(bus);
619
620 r = sd_bus_add_match(
621 bus,
622 "type='signal',"
623 "path='/org/freedesktop/DBus/Local',"
624 "interface='org.freedesktop.DBus.Local',"
625 "member='Disconnected'",
626 signal_disconnected, m);
627
628 if (r < 0) {
629 log_error("Failed to register match for Disconnected message: %s", strerror(-r));
630 return r;
631 }
632
633 return 0;
634 }
635
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;
640 sd_id128_t id;
641 int r;
642
643 assert(s);
644 assert(m);
645
646 nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
647 if (nfd < 0) {
648 log_warning("Failed to accept private connection, ignoring: %m");
649 return 0;
650 }
651
652 if (set_size(m->private_buses) >= CONNECTIONS_MAX) {
653 log_warning("Too many concurrent connections, refusing");
654 return 0;
655 }
656
657 r = set_ensure_allocated(&m->private_buses, trivial_hash_func, trivial_compare_func);
658 if (r < 0) {
659 log_oom();
660 return 0;
661 }
662
663 r = sd_bus_new(&bus);
664 if (r < 0) {
665 log_warning("Failed to allocate new private connection bus: %s", strerror(-r));
666 return 0;
667 }
668
669 r = sd_bus_set_fd(bus, nfd, nfd);
670 if (r < 0) {
671 log_warning("Failed to set fd on new connection bus: %s", strerror(-r));
672 return 0;
673 }
674
675 nfd = -1;
676
677 r = bus_check_peercred(bus);
678 if (r < 0) {
679 log_warning("Incoming private connection from unprivileged client, refusing: %s", strerror(-r));
680 return 0;
681 }
682
683 assert_se(sd_id128_randomize(&id) >= 0);
684
685 r = sd_bus_set_server(bus, 1, id);
686 if (r < 0) {
687 log_warning("Failed to enable server support for new connection bus: %s", strerror(-r));
688 return 0;
689 }
690
691 r = sd_bus_start(bus);
692 if (r < 0) {
693 log_warning("Failed to start new connection bus: %s", strerror(-r));
694 return 0;
695 }
696
697 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
698 if (r < 0) {
699 log_warning("Failed to attach new connection bus to event loop: %s", strerror(-r));
700 return 0;
701 }
702
703 if (m->running_as == SYSTEMD_SYSTEM) {
704 /* When we run as system instance we get the Released
705 * signal via a direct connection */
706
707 r = sd_bus_add_match(
708 bus,
709 "type='signal',"
710 "interface='org.freedesktop.systemd1.Agent',"
711 "member='Released',"
712 "path='/org/freedesktop/systemd1/agent'",
713 signal_agent_released, m);
714
715 if (r < 0) {
716 log_warning("Failed to register Released match on new connection bus: %s", strerror(-r));
717 return 0;
718 }
719 }
720
721 r = bus_setup_disconnected_match(m, bus);
722 if (r < 0)
723 return 0;
724
725 r = bus_setup_api_vtables(m, bus);
726 if (r < 0) {
727 log_warning("Failed to set up API vtables on new connection bus: %s", strerror(-r));
728 return 0;
729 }
730
731 r = set_put(m->private_buses, bus);
732 if (r < 0) {
733 log_warning("Failed to add new conenction bus to set: %s", strerror(-r));
734 return 0;
735 }
736
737 bus = NULL;
738
739 log_debug("Accepted new private connection.");
740
741 return 0;
742 }
743
744 static int bus_list_names(Manager *m, sd_bus *bus) {
745 _cleanup_strv_free_ char **names = NULL;
746 char **i;
747 int r;
748
749 assert(m);
750 assert(bus);
751
752 r = sd_bus_list_names(bus, &names, NULL);
753 if (r < 0) {
754 log_error("Failed to get initial list of names: %s", strerror(-r));
755 return r;
756 }
757
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);
763
764 return 0;
765 }
766
767 static int bus_setup_api(Manager *m, sd_bus *bus) {
768 int r;
769
770 assert(m);
771 assert(bus);
772
773 r = bus_setup_api_vtables(m, bus);
774 if (r < 0)
775 return r;
776
777 r = sd_bus_add_match(
778 bus,
779 "type='signal',"
780 "sender='org.freedesktop.DBus',"
781 "path='/org/freedesktop/DBus',"
782 "interface='org.freedesktop.DBus',"
783 "member='NameOwnerChanged'",
784 signal_name_owner_changed, m);
785 if (r < 0)
786 log_warning("Failed to subscribe to NameOwnerChanged signal: %s", strerror(-r));
787
788 r = sd_bus_add_match(
789 bus,
790 "type='signal',"
791 "sender='org.freedesktop.DBus',"
792 "path='/org/freedesktop/DBus',"
793 "interface='org.freedesktop.systemd1.Activator',"
794 "member='ActivationRequest'",
795 signal_activation_request, m);
796 if (r < 0)
797 log_warning("Failed to subscribe to activation signal: %s", strerror(-r));
798
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
803 * finish */
804 r = sd_bus_request_name(bus,"org.freedesktop.systemd1", SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_ALLOW_REPLACEMENT);
805 if (r < 0) {
806 log_error("Failed to register name: %s", strerror(-r));
807 return r;
808 }
809
810 bus_list_names(m, bus);
811
812 log_debug("Successfully connected to API bus.");
813 return 0;
814 }
815
816 static int bus_init_api(Manager *m) {
817 _cleanup_bus_unref_ sd_bus *bus = NULL;
818 int r;
819
820 if (m->api_bus)
821 return 0;
822
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);
826 else {
827 if (m->running_as == SYSTEMD_SYSTEM)
828 r = sd_bus_open_system(&bus);
829 else
830 r = sd_bus_open_user(&bus);
831
832 if (r < 0) {
833 log_debug("Failed to connect to API bus, retrying later...");
834 return 0;
835 }
836
837 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
838 if (r < 0) {
839 log_error("Failed to attach API bus to event loop: %s", strerror(-r));
840 return 0;
841 }
842
843 r = bus_setup_disconnected_match(m, bus);
844 if (r < 0)
845 return 0;
846 }
847
848 r = bus_setup_api(m, bus);
849 if (r < 0) {
850 log_error("Failed to set up API bus: %s", strerror(-r));
851 return 0;
852 }
853
854 m->api_bus = bus;
855 bus = NULL;
856
857 return 0;
858 }
859
860 static int bus_setup_system(Manager *m, sd_bus *bus) {
861 int r;
862
863 assert(m);
864 assert(bus);
865
866 if (m->running_as == SYSTEMD_SYSTEM)
867 return 0;
868
869 /* If we are a user instance we get the Released message via
870 * the system bus */
871 r = sd_bus_add_match(
872 bus,
873 "type='signal',"
874 "interface='org.freedesktop.systemd1.Agent',"
875 "member='Released',"
876 "path='/org/freedesktop/systemd1/agent'",
877 signal_agent_released, m);
878
879 if (r < 0)
880 log_warning("Failed to register Released match on system bus: %s", strerror(-r));
881
882 log_debug("Successfully connected to system bus.");
883 return 0;
884 }
885
886 static int bus_init_system(Manager *m) {
887 _cleanup_bus_unref_ sd_bus *bus = NULL;
888 int r;
889
890 if (m->system_bus)
891 return 0;
892
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);
896 return 0;
897 }
898
899 r = sd_bus_open_system(&bus);
900 if (r < 0) {
901 log_debug("Failed to connect to system bus, retrying later...");
902 return 0;
903 }
904
905 r = bus_setup_disconnected_match(m, bus);
906 if (r < 0)
907 return 0;
908
909 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
910 if (r < 0) {
911 log_error("Failed to attach system bus to event loop: %s", strerror(-r));
912 return 0;
913 }
914
915 r = bus_setup_system(m, bus);
916 if (r < 0) {
917 log_error("Fauiled to set up system bus: %s", strerror(-r));
918 return 0;
919 }
920
921 m->system_bus = bus;
922 bus = NULL;
923
924 return 0;
925 }
926
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
931 };
932 sd_event_source *s;
933 socklen_t salen;
934 int r;
935
936 assert(m);
937
938 if (m->private_listen_fd >= 0)
939 return 0;
940
941 /* We don't need the private socket if we have kdbus */
942 if (m->kdbus_fd >= 0)
943 return 0;
944
945 if (m->running_as == SYSTEMD_SYSTEM) {
946
947 /* We want the private bus only when running as init */
948 if (getpid() != 1)
949 return 0;
950
951 strcpy(sa.un.sun_path, "/run/systemd/private");
952 salen = offsetof(union sockaddr_union, un.sun_path) + sizeof("/run/systemd/private") - 1;
953 } else {
954 size_t left = sizeof(sa.un.sun_path);
955 char *p = sa.un.sun_path;
956 const char *e;
957
958 e = secure_getenv("XDG_RUNTIME_DIR");
959 if (!e) {
960 log_error("Failed to determine XDG_RUNTIME_DIR");
961 return -EHOSTDOWN;
962 }
963
964 left = strpcpy(&p, left, e);
965 left = strpcpy(&p, left, "/systemd/private");
966
967 salen = sizeof(sa.un) - left;
968
969 mkdir_parents_label(sa.un.sun_path, 0755);
970 }
971
972 unlink(sa.un.sun_path);
973
974 fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
975 if (fd < 0) {
976 log_error("Failed to allocate private socket: %m");
977 return -errno;
978 }
979
980 r = bind(fd, &sa.sa, salen);
981 if (r < 0) {
982 log_error("Failed to bind private socket: %m");
983 return -errno;
984 }
985
986 r = listen(fd, SOMAXCONN);
987 if (r < 0) {
988 log_error("Failed to make private socket listening: %m");
989 return -errno;
990 }
991
992 r = sd_event_add_io(m->event, fd, EPOLLIN, bus_on_connection, m, &s);
993 if (r < 0) {
994 log_error("Failed to allocate event source: %s", strerror(-r));
995 return r;
996 }
997
998 m->private_listen_fd = fd;
999 m->private_listen_event_source = s;
1000 fd = -1;
1001
1002 log_debug("Successfully created private D-Bus server.");
1003
1004 return 0;
1005 }
1006
1007 int bus_init(Manager *m, bool try_bus_connect) {
1008 int r;
1009
1010 if (try_bus_connect) {
1011 r = bus_init_system(m);
1012 if (r < 0)
1013 return r;
1014
1015 r = bus_init_api(m);
1016 if (r < 0)
1017 return r;
1018 }
1019
1020 r = bus_init_private(m);
1021 if (r < 0)
1022 return r;
1023
1024 return 0;
1025 }
1026
1027 static void destroy_bus(Manager *m, sd_bus **bus) {
1028 Iterator i;
1029 Job *j;
1030
1031 assert(m);
1032 assert(bus);
1033
1034 if (!*bus)
1035 return;
1036
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);
1041
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);
1045
1046 if (m->queued_message)
1047 m->queued_message = sd_bus_message_unref(m->queued_message);
1048 }
1049
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)
1053 sd_bus_flush(*bus);
1054
1055 /* And destroy the object */
1056 sd_bus_close(*bus);
1057 *bus = sd_bus_unref(*bus);
1058 }
1059
1060 void bus_done(Manager *m) {
1061 sd_bus *b;
1062
1063 assert(m);
1064
1065 if (m->api_bus)
1066 destroy_bus(m, &m->api_bus);
1067 if (m->system_bus)
1068 destroy_bus(m, &m->system_bus);
1069 while ((b = set_steal_first(m->private_buses)))
1070 destroy_bus(m, &b);
1071
1072 set_free(m->private_buses);
1073 set_free(m->subscribed);
1074
1075 if (m->private_listen_event_source)
1076 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
1077
1078 if (m->private_listen_fd >= 0) {
1079 close_nointr_nofail(m->private_listen_fd);
1080 m->private_listen_fd = -1;
1081 }
1082 }
1083
1084 int bus_fdset_add_all(Manager *m, FDSet *fds) {
1085 Iterator i;
1086 sd_bus *b;
1087 int fd;
1088
1089 assert(m);
1090 assert(fds);
1091
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 */
1098
1099 if (m->api_bus) {
1100 fd = sd_bus_get_fd(m->api_bus);
1101 if (fd >= 0) {
1102 fd = fdset_put_dup(fds, fd);
1103 if (fd < 0)
1104 return fd;
1105 }
1106 }
1107
1108 SET_FOREACH(b, m->private_buses, i) {
1109 fd = sd_bus_get_fd(b);
1110 if (fd >= 0) {
1111 fd = fdset_put_dup(fds, fd);
1112 if (fd < 0)
1113 return fd;
1114 }
1115 }
1116
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
1119 * here */
1120
1121 return 0;
1122 }
1123
1124 void bus_serialize(Manager *m, FILE *f) {
1125 assert(m);
1126 assert(f);
1127
1128 bus_client_track_serialize(m, f, m->subscribed);
1129 }
1130
1131 int bus_deserialize_item(Manager *m, const char *line) {
1132 assert(m);
1133 assert(line);
1134
1135 return bus_client_track_deserialize_item(m, &m->subscribed, line);
1136 }