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