]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/dbus.c
dbus: propagate errors from bus_init_system() and bus_init_api()
[thirdparty/systemd.git] / src / core / dbus.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <errno.h>
22 #include <sys/epoll.h>
23 #include <unistd.h>
24
25 #include "sd-bus.h"
26
27 #include "alloc-util.h"
28 #include "bus-common-errors.h"
29 #include "bus-error.h"
30 #include "bus-internal.h"
31 #include "bus-util.h"
32 #include "dbus-cgroup.h"
33 #include "dbus-execute.h"
34 #include "dbus-job.h"
35 #include "dbus-kill.h"
36 #include "dbus-manager.h"
37 #include "dbus-unit.h"
38 #include "dbus.h"
39 #include "fd-util.h"
40 #include "fs-util.h"
41 #include "log.h"
42 #include "missing.h"
43 #include "mkdir.h"
44 #include "selinux-access.h"
45 #include "special.h"
46 #include "string-util.h"
47 #include "strv.h"
48 #include "strxcpyx.h"
49 #include "user-util.h"
50
51 #define CONNECTIONS_MAX 4096
52
53 static void destroy_bus(Manager *m, sd_bus **bus);
54
55 int bus_send_queued_message(Manager *m) {
56 int r;
57
58 assert(m);
59
60 if (!m->queued_message)
61 return 0;
62
63 /* If we cannot get rid of this message we won't dispatch any
64 * D-Bus messages, so that we won't end up wanting to queue
65 * another message. */
66
67 r = sd_bus_send(NULL, m->queued_message, NULL);
68 if (r < 0)
69 log_warning_errno(r, "Failed to send queued message: %m");
70
71 m->queued_message = sd_bus_message_unref(m->queued_message);
72
73 return 0;
74 }
75
76 int bus_forward_agent_released(Manager *m, const char *path) {
77 int r;
78
79 assert(m);
80 assert(path);
81
82 if (!MANAGER_IS_SYSTEM(m))
83 return 0;
84
85 if (!m->system_bus)
86 return 0;
87
88 /* If we are running a system instance we forward the agent message on the system bus, so that the user
89 * instances get notified about this, too */
90
91 r = sd_bus_emit_signal(m->system_bus,
92 "/org/freedesktop/systemd1/agent",
93 "org.freedesktop.systemd1.Agent",
94 "Released",
95 "s", path);
96 if (r < 0)
97 return log_debug_errno(r, "Failed to propagate agent release message: %m");
98
99 return 1;
100 }
101
102 static int signal_agent_released(sd_bus_message *message, void *userdata, sd_bus_error *error) {
103 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
104 Manager *m = userdata;
105 const char *cgroup;
106 uid_t sender_uid;
107 int r;
108
109 assert(message);
110 assert(m);
111
112 /* only accept org.freedesktop.systemd1.Agent from UID=0 */
113 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
114 if (r < 0)
115 return r;
116
117 r = sd_bus_creds_get_euid(creds, &sender_uid);
118 if (r < 0 || sender_uid != 0)
119 return 0;
120
121 /* parse 'cgroup-empty' notification */
122 r = sd_bus_message_read(message, "s", &cgroup);
123 if (r < 0) {
124 bus_log_parse_error(r);
125 return 0;
126 }
127
128 manager_notify_cgroup_empty(m, cgroup);
129 return 0;
130 }
131
132 static int signal_disconnected(sd_bus_message *message, void *userdata, sd_bus_error *error) {
133 Manager *m = userdata;
134 sd_bus *bus;
135
136 assert(message);
137 assert(m);
138 assert_se(bus = sd_bus_message_get_bus(message));
139
140 if (bus == m->api_bus)
141 destroy_bus(m, &m->api_bus);
142 if (bus == m->system_bus)
143 destroy_bus(m, &m->system_bus);
144 if (set_remove(m->private_buses, bus)) {
145 log_debug("Got disconnect on private connection.");
146 destroy_bus(m, &bus);
147 }
148
149 return 0;
150 }
151
152 static int signal_activation_request(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
153 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
154 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
155 Manager *m = userdata;
156 const char *name;
157 Unit *u;
158 int r;
159
160 assert(message);
161 assert(m);
162
163 r = sd_bus_message_read(message, "s", &name);
164 if (r < 0) {
165 bus_log_parse_error(r);
166 return 0;
167 }
168
169 if (manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SERVICE) ||
170 manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SOCKET)) {
171 r = sd_bus_error_setf(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down.");
172 goto failed;
173 }
174
175 r = manager_load_unit(m, name, NULL, &error, &u);
176 if (r < 0)
177 goto failed;
178
179 if (u->refuse_manual_start) {
180 r = sd_bus_error_setf(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id);
181 goto failed;
182 }
183
184 r = manager_add_job(m, JOB_START, u, JOB_REPLACE, &error, NULL);
185 if (r < 0)
186 goto failed;
187
188 /* Successfully queued, that's it for us */
189 return 0;
190
191 failed:
192 if (!sd_bus_error_is_set(&error))
193 sd_bus_error_set_errno(&error, r);
194
195 log_debug("D-Bus activation failed for %s: %s", name, bus_error_message(&error, r));
196
197 r = sd_bus_message_new_signal(sd_bus_message_get_bus(message), &reply, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure");
198 if (r < 0) {
199 bus_log_create_error(r);
200 return 0;
201 }
202
203 r = sd_bus_message_append(reply, "sss", name, error.name, error.message);
204 if (r < 0) {
205 bus_log_create_error(r);
206 return 0;
207 }
208
209 r = sd_bus_send_to(NULL, reply, "org.freedesktop.DBus", NULL);
210 if (r < 0)
211 return log_error_errno(r, "Failed to respond with to bus activation request: %m");
212
213 return 0;
214 }
215
216 #if HAVE_SELINUX
217 static int mac_selinux_filter(sd_bus_message *message, void *userdata, sd_bus_error *error) {
218 Manager *m = userdata;
219 const char *verb, *path;
220 Unit *u = NULL;
221 Job *j;
222 int r;
223
224 assert(message);
225
226 /* Our own method calls are all protected individually with
227 * selinux checks, but the built-in interfaces need to be
228 * protected too. */
229
230 if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set"))
231 verb = "reload";
232 else if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", NULL) ||
233 sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", NULL) ||
234 sd_bus_message_is_method_call(message, "org.freedesktop.DBus.ObjectManager", NULL) ||
235 sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Peer", NULL))
236 verb = "status";
237 else
238 return 0;
239
240 path = sd_bus_message_get_path(message);
241
242 if (object_path_startswith("/org/freedesktop/systemd1", path)) {
243
244 r = mac_selinux_access_check(message, verb, error);
245 if (r < 0)
246 return r;
247
248 return 0;
249 }
250
251 if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
252 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
253 pid_t pid;
254
255 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
256 if (r < 0)
257 return 0;
258
259 r = sd_bus_creds_get_pid(creds, &pid);
260 if (r < 0)
261 return 0;
262
263 u = manager_get_unit_by_pid(m, pid);
264 } else {
265 r = manager_get_job_from_dbus_path(m, path, &j);
266 if (r >= 0)
267 u = j->unit;
268 else
269 manager_load_unit_from_dbus_path(m, path, NULL, &u);
270 }
271
272 if (!u)
273 return 0;
274
275 r = mac_selinux_unit_access_check(u, message, verb, error);
276 if (r < 0)
277 return r;
278
279 return 0;
280 }
281 #endif
282
283 static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
284 Manager *m = userdata;
285 Job *j;
286 int r;
287
288 assert(bus);
289 assert(path);
290 assert(interface);
291 assert(found);
292 assert(m);
293
294 r = manager_get_job_from_dbus_path(m, path, &j);
295 if (r < 0)
296 return 0;
297
298 *found = j;
299 return 1;
300 }
301
302 static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_bus_error *error) {
303 Unit *u = NULL; /* just to appease gcc, initialization is not really necessary */
304 int r;
305
306 assert(m);
307 assert(bus);
308 assert(path);
309
310 if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
311 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
312 sd_bus_message *message;
313 pid_t pid;
314
315 message = sd_bus_get_current_message(bus);
316 if (!message)
317 return 0;
318
319 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
320 if (r < 0)
321 return r;
322
323 r = sd_bus_creds_get_pid(creds, &pid);
324 if (r < 0)
325 return r;
326
327 u = manager_get_unit_by_pid(m, pid);
328 if (!u)
329 return 0;
330 } else {
331 r = manager_load_unit_from_dbus_path(m, path, error, &u);
332 if (r < 0)
333 return 0;
334 assert(u);
335 }
336
337 *unit = u;
338 return 1;
339 }
340
341 static int bus_unit_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
342 Manager *m = userdata;
343
344 assert(bus);
345 assert(path);
346 assert(interface);
347 assert(found);
348 assert(m);
349
350 return find_unit(m, bus, path, (Unit**) found, error);
351 }
352
353 static int bus_unit_interface_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
354 Manager *m = userdata;
355 Unit *u;
356 int r;
357
358 assert(bus);
359 assert(path);
360 assert(interface);
361 assert(found);
362 assert(m);
363
364 r = find_unit(m, bus, path, &u, error);
365 if (r <= 0)
366 return r;
367
368 if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type)))
369 return 0;
370
371 *found = u;
372 return 1;
373 }
374
375 static int bus_unit_cgroup_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
376 Manager *m = userdata;
377 Unit *u;
378 int r;
379
380 assert(bus);
381 assert(path);
382 assert(interface);
383 assert(found);
384 assert(m);
385
386 r = find_unit(m, bus, path, &u, error);
387 if (r <= 0)
388 return r;
389
390 if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type)))
391 return 0;
392
393 if (!UNIT_HAS_CGROUP_CONTEXT(u))
394 return 0;
395
396 *found = u;
397 return 1;
398 }
399
400 static int bus_cgroup_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
401 Manager *m = userdata;
402 CGroupContext *c;
403 Unit *u;
404 int r;
405
406 assert(bus);
407 assert(path);
408 assert(interface);
409 assert(found);
410 assert(m);
411
412 r = find_unit(m, bus, path, &u, error);
413 if (r <= 0)
414 return r;
415
416 if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type)))
417 return 0;
418
419 c = unit_get_cgroup_context(u);
420 if (!c)
421 return 0;
422
423 *found = c;
424 return 1;
425 }
426
427 static int bus_exec_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
428 Manager *m = userdata;
429 ExecContext *c;
430 Unit *u;
431 int r;
432
433 assert(bus);
434 assert(path);
435 assert(interface);
436 assert(found);
437 assert(m);
438
439 r = find_unit(m, bus, path, &u, error);
440 if (r <= 0)
441 return r;
442
443 if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type)))
444 return 0;
445
446 c = unit_get_exec_context(u);
447 if (!c)
448 return 0;
449
450 *found = c;
451 return 1;
452 }
453
454 static int bus_kill_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
455 Manager *m = userdata;
456 KillContext *c;
457 Unit *u;
458 int r;
459
460 assert(bus);
461 assert(path);
462 assert(interface);
463 assert(found);
464 assert(m);
465
466 r = find_unit(m, bus, path, &u, error);
467 if (r <= 0)
468 return r;
469
470 if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type)))
471 return 0;
472
473 c = unit_get_kill_context(u);
474 if (!c)
475 return 0;
476
477 *found = c;
478 return 1;
479 }
480
481 static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
482 _cleanup_strv_free_ char **l = NULL;
483 Manager *m = userdata;
484 unsigned k = 0;
485 Iterator i;
486 Job *j;
487
488 l = new0(char*, hashmap_size(m->jobs)+1);
489 if (!l)
490 return -ENOMEM;
491
492 HASHMAP_FOREACH(j, m->jobs, i) {
493 l[k] = job_dbus_path(j);
494 if (!l[k])
495 return -ENOMEM;
496
497 k++;
498 }
499
500 assert(hashmap_size(m->jobs) == k);
501
502 *nodes = l;
503 l = NULL;
504
505 return k;
506 }
507
508 static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
509 _cleanup_strv_free_ char **l = NULL;
510 Manager *m = userdata;
511 unsigned k = 0;
512 Iterator i;
513 Unit *u;
514
515 l = new0(char*, hashmap_size(m->units)+1);
516 if (!l)
517 return -ENOMEM;
518
519 HASHMAP_FOREACH(u, m->units, i) {
520 l[k] = unit_dbus_path(u);
521 if (!l[k])
522 return -ENOMEM;
523
524 k++;
525 }
526
527 *nodes = l;
528 l = NULL;
529
530 return k;
531 }
532
533 static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
534 UnitType t;
535 int r;
536
537 assert(m);
538 assert(bus);
539
540 #if HAVE_SELINUX
541 r = sd_bus_add_filter(bus, NULL, mac_selinux_filter, m);
542 if (r < 0)
543 return log_error_errno(r, "Failed to add SELinux access filter: %m");
544 #endif
545
546 r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
547 if (r < 0)
548 return log_error_errno(r, "Failed to register Manager vtable: %m");
549
550 r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
551 if (r < 0)
552 return log_error_errno(r, "Failed to register Job vtable: %m");
553
554 r = sd_bus_add_node_enumerator(bus, NULL, "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
555 if (r < 0)
556 return log_error_errno(r, "Failed to add job enumerator: %m");
557
558 r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
559 if (r < 0)
560 return log_error_errno(r, "Failed to register Unit vtable: %m");
561
562 r = sd_bus_add_node_enumerator(bus, NULL, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
563 if (r < 0)
564 return log_error_errno(r, "Failed to add job enumerator: %m");
565
566 for (t = 0; t < _UNIT_TYPE_MAX; t++) {
567 const char *interface;
568
569 assert_se(interface = unit_dbus_interface_from_type(t));
570
571 r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, unit_vtable[t]->bus_vtable, bus_unit_interface_find, m);
572 if (r < 0)
573 return log_error_errno(r, "Failed to register type specific vtable for %s: %m", interface);
574
575 if (unit_vtable[t]->cgroup_context_offset > 0) {
576 r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_unit_cgroup_vtable, bus_unit_cgroup_find, m);
577 if (r < 0)
578 return log_error_errno(r, "Failed to register control group unit vtable for %s: %m", interface);
579
580 r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
581 if (r < 0)
582 return log_error_errno(r, "Failed to register control group vtable for %s: %m", interface);
583 }
584
585 if (unit_vtable[t]->exec_context_offset > 0) {
586 r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_exec_vtable, bus_exec_context_find, m);
587 if (r < 0)
588 return log_error_errno(r, "Failed to register execute vtable for %s: %m", interface);
589 }
590
591 if (unit_vtable[t]->kill_context_offset > 0) {
592 r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_kill_vtable, bus_kill_context_find, m);
593 if (r < 0)
594 return log_error_errno(r, "Failed to register kill vtable for %s: %m", interface);
595 }
596 }
597
598 return 0;
599 }
600
601 static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
602 int r;
603
604 assert(m);
605 assert(bus);
606
607 r = sd_bus_match_signal_async(
608 bus,
609 NULL,
610 "org.freedesktop.DBus.Local",
611 "/org/freedesktop/DBus/Local",
612 "org.freedesktop.DBus.Local",
613 "Disconnected",
614 signal_disconnected, NULL, m);
615 if (r < 0)
616 return log_error_errno(r, "Failed to request match for Disconnected message: %m");
617
618 return 0;
619 }
620
621 static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
622 _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
623 _cleanup_close_ int nfd = -1;
624 Manager *m = userdata;
625 sd_id128_t id;
626 int r;
627
628 assert(s);
629 assert(m);
630
631 nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
632 if (nfd < 0) {
633 log_warning_errno(errno, "Failed to accept private connection, ignoring: %m");
634 return 0;
635 }
636
637 if (set_size(m->private_buses) >= CONNECTIONS_MAX) {
638 log_warning("Too many concurrent connections, refusing");
639 return 0;
640 }
641
642 r = set_ensure_allocated(&m->private_buses, NULL);
643 if (r < 0) {
644 log_oom();
645 return 0;
646 }
647
648 r = sd_bus_new(&bus);
649 if (r < 0) {
650 log_warning_errno(r, "Failed to allocate new private connection bus: %m");
651 return 0;
652 }
653
654 r = sd_bus_set_fd(bus, nfd, nfd);
655 if (r < 0) {
656 log_warning_errno(r, "Failed to set fd on new connection bus: %m");
657 return 0;
658 }
659
660 nfd = -1;
661
662 r = bus_check_peercred(bus);
663 if (r < 0) {
664 log_warning_errno(r, "Incoming private connection from unprivileged client, refusing: %m");
665 return 0;
666 }
667
668 assert_se(sd_id128_randomize(&id) >= 0);
669
670 r = sd_bus_set_server(bus, 1, id);
671 if (r < 0) {
672 log_warning_errno(r, "Failed to enable server support for new connection bus: %m");
673 return 0;
674 }
675
676 r = sd_bus_negotiate_creds(bus, 1,
677 SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|
678 SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS|
679 SD_BUS_CREDS_SELINUX_CONTEXT);
680 if (r < 0) {
681 log_warning_errno(r, "Failed to enable credentials for new connection: %m");
682 return 0;
683 }
684
685 r = sd_bus_set_sender(bus, "org.freedesktop.systemd1");
686 if (r < 0) {
687 log_warning_errno(r, "Failed to set direct connection sender: %m");
688 return 0;
689 }
690
691 r = sd_bus_start(bus);
692 if (r < 0) {
693 log_warning_errno(r, "Failed to start new connection bus: %m");
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_errno(r, "Failed to attach new connection bus to event loop: %m");
700 return 0;
701 }
702
703 r = bus_setup_disconnected_match(m, bus);
704 if (r < 0)
705 return 0;
706
707 r = bus_setup_api_vtables(m, bus);
708 if (r < 0) {
709 log_warning_errno(r, "Failed to set up API vtables on new connection bus: %m");
710 return 0;
711 }
712
713 r = set_put(m->private_buses, bus);
714 if (r < 0) {
715 log_warning_errno(r, "Failed to add new connection bus to set: %m");
716 return 0;
717 }
718
719 bus = NULL;
720
721 log_debug("Accepted new private connection.");
722
723 return 0;
724 }
725
726 int manager_sync_bus_names(Manager *m, sd_bus *bus) {
727 _cleanup_strv_free_ char **names = NULL;
728 const char *name;
729 Iterator i;
730 Unit *u;
731 int r;
732
733 assert(m);
734 assert(bus);
735
736 r = sd_bus_list_names(bus, &names, NULL);
737 if (r < 0)
738 return log_error_errno(r, "Failed to get initial list of names: %m");
739
740 /* We have to synchronize the current bus names with the
741 * list of active services. To do this, walk the list of
742 * all units with bus names. */
743 HASHMAP_FOREACH_KEY(u, name, m->watch_bus, i) {
744 Service *s = SERVICE(u);
745
746 assert(s);
747
748 if (!streq_ptr(s->bus_name, name)) {
749 log_unit_warning(u, "Bus name has changed from %s → %s, ignoring.", s->bus_name, name);
750 continue;
751 }
752
753 /* Check if a service's bus name is in the list of currently
754 * active names */
755 if (strv_contains(names, name)) {
756 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
757 const char *unique;
758
759 /* If it is, determine its current owner */
760 r = sd_bus_get_name_creds(bus, name, SD_BUS_CREDS_UNIQUE_NAME, &creds);
761 if (r < 0) {
762 log_full_errno(r == -ENXIO ? LOG_DEBUG : LOG_ERR, r, "Failed to get bus name owner %s: %m", name);
763 continue;
764 }
765
766 r = sd_bus_creds_get_unique_name(creds, &unique);
767 if (r < 0) {
768 log_full_errno(r == -ENXIO ? LOG_DEBUG : LOG_ERR, r, "Failed to get unique name for %s: %m", name);
769 continue;
770 }
771
772 /* Now, let's compare that to the previous bus owner, and
773 * if it's still the same, all is fine, so just don't
774 * bother the service. Otherwise, the name has apparently
775 * changed, so synthesize a name owner changed signal. */
776
777 if (!streq_ptr(unique, s->bus_name_owner))
778 UNIT_VTABLE(u)->bus_name_owner_change(u, name, s->bus_name_owner, unique);
779 } else {
780 /* So, the name we're watching is not on the bus.
781 * This either means it simply hasn't appeared yet,
782 * or it was lost during the daemon reload.
783 * Check if the service has a stored name owner,
784 * and synthesize a name loss signal in this case. */
785
786 if (s->bus_name_owner)
787 UNIT_VTABLE(u)->bus_name_owner_change(u, name, s->bus_name_owner, NULL);
788 }
789 }
790
791 return 0;
792 }
793
794 static int bus_setup_api(Manager *m, sd_bus *bus) {
795 Iterator i;
796 char *name;
797 Unit *u;
798 int r;
799
800 assert(m);
801 assert(bus);
802
803 /* Let's make sure we have enough credential bits so that we can make security and selinux decisions */
804 r = sd_bus_negotiate_creds(bus, 1,
805 SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|
806 SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS|
807 SD_BUS_CREDS_SELINUX_CONTEXT);
808 if (r < 0)
809 log_warning_errno(r, "Failed to enable credential passing, ignoring: %m");
810
811 r = bus_setup_api_vtables(m, bus);
812 if (r < 0)
813 return r;
814
815 HASHMAP_FOREACH_KEY(u, name, m->watch_bus, i) {
816 r = unit_install_bus_match(u, bus, name);
817 if (r < 0)
818 log_error_errno(r, "Failed to subscribe to NameOwnerChanged signal for '%s': %m", name);
819 }
820
821 r = sd_bus_match_signal_async(
822 bus,
823 NULL,
824 "org.freedesktop.DBus",
825 "/org/freedesktop/DBus",
826 "org.freedesktop.systemd1.Activator",
827 "ActivationRequest",
828 signal_activation_request, NULL, m);
829 if (r < 0)
830 log_warning_errno(r, "Failed to subscribe to activation signal: %m");
831
832 /* Allow replacing of our name, to ease implementation of reexecution, where we keep the old connection open
833 * until after the new connection is set up and the name installed to allow clients to synchronously wait for
834 * reexecution to finish */
835 r = sd_bus_request_name_async(bus, NULL, "org.freedesktop.systemd1", SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_ALLOW_REPLACEMENT, NULL, NULL);
836 if (r < 0)
837 return log_error_errno(r, "Failed to request name: %m");
838
839 r = manager_sync_bus_names(m, bus);
840 if (r < 0)
841 return r;
842
843 log_debug("Successfully connected to API bus.");
844 return 0;
845 }
846
847 static int bus_init_api(Manager *m) {
848 _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
849 int r;
850
851 if (m->api_bus)
852 return 0;
853
854 /* The API and system bus is the same if we are running in system mode */
855 if (MANAGER_IS_SYSTEM(m) && m->system_bus)
856 bus = sd_bus_ref(m->system_bus);
857 else {
858 if (MANAGER_IS_SYSTEM(m))
859 r = sd_bus_open_system(&bus);
860 else
861 r = sd_bus_open_user(&bus);
862 if (r < 0)
863 return log_error_errno(r, "Failed to connect to API bus: %m");
864
865 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
866 if (r < 0)
867 return log_error_errno(r, "Failed to attach API bus to event loop: %m");
868
869 r = bus_setup_disconnected_match(m, bus);
870 if (r < 0)
871 return r;
872 }
873
874 r = bus_setup_api(m, bus);
875 if (r < 0)
876 return log_error_errno(r, "Failed to set up API bus: %m");
877
878 m->api_bus = bus;
879 bus = NULL;
880
881 return 0;
882 }
883
884 static int bus_setup_system(Manager *m, sd_bus *bus) {
885 int r;
886
887 assert(m);
888 assert(bus);
889
890 /* if we are a user instance we get the Released message via the system bus */
891 if (MANAGER_IS_USER(m)) {
892 r = sd_bus_match_signal_async(
893 bus,
894 NULL,
895 NULL,
896 "/org/freedesktop/systemd1/agent",
897 "org.freedesktop.systemd1.Agent",
898 "Released",
899 signal_agent_released, NULL, m);
900 if (r < 0)
901 log_warning_errno(r, "Failed to request Released match on system bus: %m");
902 }
903
904 log_debug("Successfully connected to system bus.");
905 return 0;
906 }
907
908 static int bus_init_system(Manager *m) {
909 _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
910 int r;
911
912 if (m->system_bus)
913 return 0;
914
915 /* The API and system bus is the same if we are running in system mode */
916 if (MANAGER_IS_SYSTEM(m) && m->api_bus) {
917 m->system_bus = sd_bus_ref(m->api_bus);
918 return 0;
919 }
920
921 r = sd_bus_open_system(&bus);
922 if (r < 0)
923 return log_error_errno(r, "Failed to connect to system bus: %m");
924
925 r = bus_setup_disconnected_match(m, bus);
926 if (r < 0)
927 return r;
928
929 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
930 if (r < 0)
931 return log_error_errno(r, "Failed to attach system bus to event loop: %m");
932
933 r = bus_setup_system(m, bus);
934 if (r < 0)
935 return log_error_errno(r, "Failed to set up system bus: %m");
936
937 m->system_bus = bus;
938 bus = NULL;
939
940 return 0;
941 }
942
943 static int bus_init_private(Manager *m) {
944 _cleanup_close_ int fd = -1;
945 union sockaddr_union sa = {
946 .un.sun_family = AF_UNIX
947 };
948 sd_event_source *s;
949 socklen_t salen;
950 int r;
951
952 assert(m);
953
954 if (m->private_listen_fd >= 0)
955 return 0;
956
957 if (MANAGER_IS_SYSTEM(m)) {
958
959 /* We want the private bus only when running as init */
960 if (getpid_cached() != 1)
961 return 0;
962
963 strcpy(sa.un.sun_path, "/run/systemd/private");
964 salen = SOCKADDR_UN_LEN(sa.un);
965 } else {
966 size_t left = sizeof(sa.un.sun_path);
967 char *p = sa.un.sun_path;
968 const char *e;
969
970 e = secure_getenv("XDG_RUNTIME_DIR");
971 if (!e) {
972 log_error("Failed to determine XDG_RUNTIME_DIR");
973 return -EHOSTDOWN;
974 }
975
976 left = strpcpy(&p, left, e);
977 left = strpcpy(&p, left, "/systemd/private");
978
979 salen = sizeof(sa.un) - left;
980 }
981
982 (void) mkdir_parents_label(sa.un.sun_path, 0755);
983 (void) unlink(sa.un.sun_path);
984
985 fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
986 if (fd < 0)
987 return log_error_errno(errno, "Failed to allocate private socket: %m");
988
989 r = bind(fd, &sa.sa, salen);
990 if (r < 0)
991 return log_error_errno(errno, "Failed to bind private socket: %m");
992
993 r = listen(fd, SOMAXCONN);
994 if (r < 0)
995 return log_error_errno(errno, "Failed to make private socket listening: %m");
996
997 /* Generate an inotify event in case somebody waits for this socket to appear using inotify() */
998 (void) touch(sa.un.sun_path);
999
1000 r = sd_event_add_io(m->event, &s, fd, EPOLLIN, bus_on_connection, m);
1001 if (r < 0)
1002 return log_error_errno(r, "Failed to allocate event source: %m");
1003
1004 (void) sd_event_source_set_description(s, "bus-connection");
1005
1006 m->private_listen_fd = fd;
1007 m->private_listen_event_source = s;
1008 fd = -1;
1009
1010 log_debug("Successfully created private D-Bus server.");
1011
1012 return 0;
1013 }
1014
1015 int bus_init(Manager *m, bool try_bus_connect) {
1016 int r;
1017
1018 if (try_bus_connect) {
1019 r = bus_init_system(m);
1020 if (r < 0)
1021 return log_error_errno(r, "Failed to initialize D-Bus connection: %m");
1022
1023 r = bus_init_api(m);
1024 if (r < 0)
1025 return log_error_errno(r, "Error occured during D-Bus APIs initialization: %m");
1026 }
1027
1028 r = bus_init_private(m);
1029 if (r < 0)
1030 return log_error_errno(r, "Failed to create private D-Bus server: %m");
1031
1032 return 0;
1033 }
1034
1035 static void destroy_bus(Manager *m, sd_bus **bus) {
1036 Iterator i;
1037 Unit *u;
1038 Job *j;
1039
1040 assert(m);
1041 assert(bus);
1042
1043 if (!*bus)
1044 return;
1045
1046 /* Make sure all bus slots watching names are released. */
1047 HASHMAP_FOREACH(u, m->watch_bus, i) {
1048 if (!u->match_bus_slot)
1049 continue;
1050
1051 if (sd_bus_slot_get_bus(u->match_bus_slot) != *bus)
1052 continue;
1053
1054 u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot);
1055 }
1056
1057 /* Get rid of tracked clients on this bus */
1058 if (m->subscribed && sd_bus_track_get_bus(m->subscribed) == *bus)
1059 m->subscribed = sd_bus_track_unref(m->subscribed);
1060
1061 HASHMAP_FOREACH(j, m->jobs, i)
1062 if (j->bus_track && sd_bus_track_get_bus(j->bus_track) == *bus)
1063 j->bus_track = sd_bus_track_unref(j->bus_track);
1064
1065 /* Get rid of queued message on this bus */
1066 if (m->queued_message && sd_bus_message_get_bus(m->queued_message) == *bus)
1067 m->queued_message = sd_bus_message_unref(m->queued_message);
1068
1069 /* Possibly flush unwritten data, but only if we are
1070 * unprivileged, since we don't want to sync here */
1071 if (!MANAGER_IS_SYSTEM(m))
1072 sd_bus_flush(*bus);
1073
1074 /* And destroy the object */
1075 sd_bus_close(*bus);
1076 *bus = sd_bus_unref(*bus);
1077 }
1078
1079 void bus_done(Manager *m) {
1080 sd_bus *b;
1081
1082 assert(m);
1083
1084 if (m->api_bus)
1085 destroy_bus(m, &m->api_bus);
1086 if (m->system_bus)
1087 destroy_bus(m, &m->system_bus);
1088 while ((b = set_steal_first(m->private_buses)))
1089 destroy_bus(m, &b);
1090
1091 m->private_buses = set_free(m->private_buses);
1092
1093 m->subscribed = sd_bus_track_unref(m->subscribed);
1094 m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
1095
1096 if (m->private_listen_event_source)
1097 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
1098
1099 m->private_listen_fd = safe_close(m->private_listen_fd);
1100
1101 bus_verify_polkit_async_registry_free(m->polkit_registry);
1102 }
1103
1104 int bus_fdset_add_all(Manager *m, FDSet *fds) {
1105 Iterator i;
1106 sd_bus *b;
1107 int fd;
1108
1109 assert(m);
1110 assert(fds);
1111
1112 /* When we are about to reexecute we add all D-Bus fds to the
1113 * set to pass over to the newly executed systemd. They won't
1114 * be used there however, except thatt they are closed at the
1115 * very end of deserialization, those making it possible for
1116 * clients to synchronously wait for systemd to reexec by
1117 * simply waiting for disconnection */
1118
1119 if (m->api_bus) {
1120 fd = sd_bus_get_fd(m->api_bus);
1121 if (fd >= 0) {
1122 fd = fdset_put_dup(fds, fd);
1123 if (fd < 0)
1124 return fd;
1125 }
1126 }
1127
1128 SET_FOREACH(b, m->private_buses, i) {
1129 fd = sd_bus_get_fd(b);
1130 if (fd >= 0) {
1131 fd = fdset_put_dup(fds, fd);
1132 if (fd < 0)
1133 return fd;
1134 }
1135 }
1136
1137 /* We don't offer any APIs on the system bus (well, unless it
1138 * is the same as the API bus) hence we don't bother with it
1139 * here */
1140
1141 return 0;
1142 }
1143
1144 int bus_foreach_bus(
1145 Manager *m,
1146 sd_bus_track *subscribed2,
1147 int (*send_message)(sd_bus *bus, void *userdata),
1148 void *userdata) {
1149
1150 Iterator i;
1151 sd_bus *b;
1152 int r, ret = 0;
1153
1154 /* Send to all direct buses, unconditionally */
1155 SET_FOREACH(b, m->private_buses, i) {
1156 r = send_message(b, userdata);
1157 if (r < 0)
1158 ret = r;
1159 }
1160
1161 /* Send to API bus, but only if somebody is subscribed */
1162 if (sd_bus_track_count(m->subscribed) > 0 ||
1163 sd_bus_track_count(subscribed2) > 0) {
1164 r = send_message(m->api_bus, userdata);
1165 if (r < 0)
1166 ret = r;
1167 }
1168
1169 return ret;
1170 }
1171
1172 void bus_track_serialize(sd_bus_track *t, FILE *f, const char *prefix) {
1173 const char *n;
1174
1175 assert(f);
1176 assert(prefix);
1177
1178 for (n = sd_bus_track_first(t); n; n = sd_bus_track_next(t)) {
1179 int c, j;
1180
1181 c = sd_bus_track_count_name(t, n);
1182
1183 for (j = 0; j < c; j++) {
1184 fputs(prefix, f);
1185 fputc('=', f);
1186 fputs(n, f);
1187 fputc('\n', f);
1188 }
1189 }
1190 }
1191
1192 int bus_track_coldplug(Manager *m, sd_bus_track **t, bool recursive, char **l) {
1193 int r = 0;
1194
1195 assert(m);
1196 assert(t);
1197
1198 if (strv_isempty(l))
1199 return 0;
1200
1201 if (!m->api_bus)
1202 return 0;
1203
1204 if (!*t) {
1205 r = sd_bus_track_new(m->api_bus, t, NULL, NULL);
1206 if (r < 0)
1207 return r;
1208 }
1209
1210 r = sd_bus_track_set_recursive(*t, recursive);
1211 if (r < 0)
1212 return r;
1213
1214 return bus_track_add_name_many(*t, l);
1215 }
1216
1217 int bus_verify_manage_units_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
1218 return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-units", NULL, false, UID_INVALID, &m->polkit_registry, error);
1219 }
1220
1221 int bus_verify_manage_unit_files_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
1222 return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-unit-files", NULL, false, UID_INVALID, &m->polkit_registry, error);
1223 }
1224
1225 int bus_verify_reload_daemon_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
1226 return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.reload-daemon", NULL, false, UID_INVALID, &m->polkit_registry, error);
1227 }
1228
1229 int bus_verify_set_environment_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
1230 return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.set-environment", NULL, false, UID_INVALID, &m->polkit_registry, error);
1231 }