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