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