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