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