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