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