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