]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/dbus.c
core: service: fix error message
[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 22#include <errno.h>
07630cea 23#include <sys/epoll.h>
ea430986
LP
24#include <unistd.h>
25
718db961 26#include "sd-bus.h"
07630cea 27
b5efdb8a 28#include "alloc-util.h"
07630cea
LP
29#include "bus-common-errors.h"
30#include "bus-error.h"
31#include "bus-internal.h"
32#include "bus-util.h"
33#include "dbus-cgroup.h"
718db961 34#include "dbus-execute.h"
07630cea 35#include "dbus-job.h"
718db961 36#include "dbus-kill.h"
07630cea
LP
37#include "dbus-manager.h"
38#include "dbus-unit.h"
3ffd4af2
LP
39#include "dbus.h"
40#include "fd-util.h"
07630cea
LP
41#include "log.h"
42#include "missing.h"
43#include "mkdir.h"
44#include "selinux-access.h"
8f6df3fa 45#include "special.h"
07630cea
LP
46#include "string-util.h"
47#include "strv.h"
718db961 48#include "strxcpyx.h"
ee104e11 49#include "user-util.h"
4288f619 50
cbecf9bf 51#define CONNECTIONS_MAX 4096
5e8d1c9a 52
718db961
LP
53static void destroy_bus(Manager *m, sd_bus **bus);
54
55int bus_send_queued_message(Manager *m) {
56 int r;
8e274523 57
8e274523 58 assert(m);
2e317f52 59
718db961
LP
60 if (!m->queued_message)
61 return 0;
8e274523 62
718db961
LP
63 /* If we cannot get rid of this message we won't dispatch any
64 * D-Bus messages, so that we won't end up wanting to queue
65 * another message. */
ea430986 66
8f88ecf6 67 r = sd_bus_send(NULL, m->queued_message, NULL);
718db961 68 if (r < 0)
da927ba9 69 log_warning_errno(r, "Failed to send queued message: %m");
ea430986 70
718db961 71 m->queued_message = sd_bus_message_unref(m->queued_message);
ea430986 72
718db961 73 return 0;
ea430986
LP
74}
75
19070062 76static int signal_agent_released(sd_bus_message *message, void *userdata, sd_bus_error *error) {
0a069ce6
DH
77 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
78 const char *cgroup, *me;
718db961 79 Manager *m = userdata;
0a069ce6
DH
80 uid_t sender_uid;
81 sd_bus *bus;
718db961 82 int r;
ea430986 83
718db961 84 assert(message);
ea430986
LP
85 assert(m);
86
0a069ce6
DH
87 /* ignore recursive events sent by us on the system/user bus */
88 bus = sd_bus_message_get_bus(message);
89 if (!sd_bus_is_server(bus)) {
90 r = sd_bus_get_unique_name(bus, &me);
91 if (r < 0)
92 return r;
93
94 if (streq_ptr(sd_bus_message_get_sender(message), me))
95 return 0;
96 }
97
98 /* only accept org.freedesktop.systemd1.Agent from UID=0 */
99 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds);
100 if (r < 0)
101 return r;
102
103 r = sd_bus_creds_get_euid(creds, &sender_uid);
104 if (r < 0 || sender_uid != 0)
105 return 0;
106
107 /* parse 'cgroup-empty' notification */
718db961
LP
108 r = sd_bus_message_read(message, "s", &cgroup);
109 if (r < 0) {
110 bus_log_parse_error(r);
111 return 0;
112 }
ea430986 113
718db961 114 manager_notify_cgroup_empty(m, cgroup);
ea430986 115
a0c8526a
DH
116 /* if running as system-instance, forward under our name */
117 if (m->running_as == MANAGER_SYSTEM && m->system_bus) {
118 r = sd_bus_message_rewind(message, 1);
119 if (r >= 0)
120 r = sd_bus_send(m->system_bus, message, NULL);
121 if (r < 0)
122 log_warning_errno(r, "Failed to forward Released message: %m");
123 }
39881ed2 124
718db961
LP
125 return 0;
126}
ea430986 127
19070062 128static int signal_disconnected(sd_bus_message *message, void *userdata, sd_bus_error *error) {
718db961 129 Manager *m = userdata;
19070062 130 sd_bus *bus;
ea430986 131
718db961
LP
132 assert(message);
133 assert(m);
19070062 134 assert_se(bus = sd_bus_message_get_bus(message));
ea430986 135
718db961
LP
136 if (bus == m->api_bus)
137 destroy_bus(m, &m->api_bus);
138 if (bus == m->system_bus)
139 destroy_bus(m, &m->system_bus);
140 if (set_remove(m->private_buses, bus)) {
141 log_debug("Got disconnect on private connection.");
142 destroy_bus(m, &bus);
ea430986
LP
143 }
144
718db961 145 return 0;
ea430986
LP
146}
147
19070062 148static int signal_activation_request(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
718db961
LP
149 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
150 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
151 Manager *m = userdata;
152 const char *name;
153 Unit *u;
154 int r;
ea430986 155
718db961 156 assert(message);
ea430986
LP
157 assert(m);
158
718db961
LP
159 r = sd_bus_message_read(message, "s", &name);
160 if (r < 0) {
161 bus_log_parse_error(r);
162 return 0;
163 }
ea430986 164
718db961
LP
165 if (manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SERVICE) ||
166 manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SOCKET)) {
167 r = sd_bus_error_setf(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down.");
168 goto failed;
169 }
ea430986 170
718db961
LP
171 r = manager_load_unit(m, name, NULL, &error, &u);
172 if (r < 0)
173 goto failed;
ea430986 174
718db961 175 if (u->refuse_manual_start) {
d14ab08b 176 r = sd_bus_error_setf(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, %s may be requested by dependency only.", u->id);
718db961 177 goto failed;
ea430986
LP
178 }
179
718db961
LP
180 r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &error, NULL);
181 if (r < 0)
182 goto failed;
ea430986 183
718db961 184 /* Successfully queued, that's it for us */
ea430986 185 return 0;
ea430986 186
718db961
LP
187failed:
188 if (!sd_bus_error_is_set(&error))
189 sd_bus_error_set_errno(&error, r);
ea430986 190
718db961 191 log_debug("D-Bus activation failed for %s: %s", name, bus_error_message(&error, r));
ea430986 192
966c66e3 193 r = sd_bus_message_new_signal(sd_bus_message_get_bus(message), &reply, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure");
718db961
LP
194 if (r < 0) {
195 bus_log_create_error(r);
196 return 0;
197 }
198
fa0fed49 199 r = sd_bus_message_append(reply, "sss", name, error.name, error.message);
718db961
LP
200 if (r < 0) {
201 bus_log_create_error(r);
202 return 0;
203 }
204
966c66e3 205 r = sd_bus_send_to(NULL, reply, "org.freedesktop.DBus", NULL);
23bbb0de
MS
206 if (r < 0)
207 return log_error_errno(r, "Failed to respond with to bus activation request: %m");
ea430986 208
718db961 209 return 0;
ea430986
LP
210}
211
ad5b215d 212#ifdef HAVE_SELINUX
19070062 213static int mac_selinux_filter(sd_bus_message *message, void *userdata, sd_bus_error *error) {
969987ea
LP
214 Manager *m = userdata;
215 const char *verb, *path;
216 Unit *u = NULL;
217 Job *j;
218 int r;
219
969987ea
LP
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
21b735e7 364 if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type)))
718db961 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
21b735e7 386 if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type)))
718db961 387 return 0;
05e343b7 388
35b7ff80 389 if (!UNIT_HAS_CGROUP_CONTEXT(u))
718db961 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
21b735e7 412 if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type)))
718db961 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
21b735e7 439 if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type)))
718db961 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
21b735e7 466 if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type)))
718db961 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++) {
21b735e7
LP
563 const char *interface;
564
565 assert_se(interface = unit_dbus_interface_from_type(t));
566
567 r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, unit_vtable[t]->bus_vtable, bus_unit_interface_find, m);
23bbb0de 568 if (r < 0)
21b735e7 569 return log_error_errno(r, "Failed to register type specific vtable for %s: %m", interface);
61902ea3 570
718db961 571 if (unit_vtable[t]->cgroup_context_offset > 0) {
21b735e7 572 r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_unit_cgroup_vtable, bus_unit_cgroup_find, m);
23bbb0de 573 if (r < 0)
21b735e7 574 return log_error_errno(r, "Failed to register control group unit vtable for %s: %m", interface);
61902ea3 575
21b735e7 576 r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
23bbb0de 577 if (r < 0)
21b735e7 578 return log_error_errno(r, "Failed to register control group vtable for %s: %m", interface);
61902ea3
LP
579 }
580
718db961 581 if (unit_vtable[t]->exec_context_offset > 0) {
21b735e7 582 r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_exec_vtable, bus_exec_context_find, m);
23bbb0de 583 if (r < 0)
21b735e7 584 return log_error_errno(r, "Failed to register execute vtable for %s: %m", interface);
718db961 585 }
61902ea3 586
718db961 587 if (unit_vtable[t]->kill_context_offset > 0) {
21b735e7 588 r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", interface, bus_kill_vtable, bus_kill_context_find, m);
23bbb0de 589 if (r < 0)
21b735e7 590 return log_error_errno(r, "Failed to register kill vtable for %s: %m", interface);
718db961 591 }
61902ea3
LP
592 }
593
718db961 594 return 0;
61902ea3
LP
595}
596
718db961
LP
597static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
598 int r;
61902ea3 599
718db961
LP
600 assert(m);
601 assert(bus);
61902ea3 602
718db961
LP
603 r = sd_bus_add_match(
604 bus,
19befb2d 605 NULL,
27fc65e1 606 "sender='org.freedesktop.DBus.Local',"
718db961
LP
607 "type='signal',"
608 "path='/org/freedesktop/DBus/Local',"
609 "interface='org.freedesktop.DBus.Local',"
610 "member='Disconnected'",
611 signal_disconnected, m);
05e343b7 612
23bbb0de
MS
613 if (r < 0)
614 return log_error_errno(r, "Failed to register match for Disconnected message: %m");
05e343b7 615
718db961 616 return 0;
ea430986
LP
617}
618
718db961
LP
619static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
620 _cleanup_bus_unref_ sd_bus *bus = NULL;
621 _cleanup_close_ int nfd = -1;
6dded4c7 622 Manager *m = userdata;
718db961
LP
623 sd_id128_t id;
624 int r;
6dded4c7 625
718db961 626 assert(s);
6dded4c7
LP
627 assert(m);
628
718db961
LP
629 nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
630 if (nfd < 0) {
56f64d95 631 log_warning_errno(errno, "Failed to accept private connection, ignoring: %m");
718db961
LP
632 return 0;
633 }
6dded4c7 634
718db961
LP
635 if (set_size(m->private_buses) >= CONNECTIONS_MAX) {
636 log_warning("Too many concurrent connections, refusing");
637 return 0;
638 }
6dded4c7 639
d5099efc 640 r = set_ensure_allocated(&m->private_buses, NULL);
718db961
LP
641 if (r < 0) {
642 log_oom();
643 return 0;
644 }
6dded4c7 645
718db961
LP
646 r = sd_bus_new(&bus);
647 if (r < 0) {
da927ba9 648 log_warning_errno(r, "Failed to allocate new private connection bus: %m");
718db961
LP
649 return 0;
650 }
6dded4c7 651
718db961
LP
652 r = sd_bus_set_fd(bus, nfd, nfd);
653 if (r < 0) {
da927ba9 654 log_warning_errno(r, "Failed to set fd on new connection bus: %m");
718db961
LP
655 return 0;
656 }
6dded4c7 657
718db961 658 nfd = -1;
6dded4c7 659
718db961
LP
660 r = bus_check_peercred(bus);
661 if (r < 0) {
da927ba9 662 log_warning_errno(r, "Incoming private connection from unprivileged client, refusing: %m");
718db961
LP
663 return 0;
664 }
6dded4c7 665
718db961 666 assert_se(sd_id128_randomize(&id) >= 0);
6dded4c7 667
718db961
LP
668 r = sd_bus_set_server(bus, 1, id);
669 if (r < 0) {
da927ba9 670 log_warning_errno(r, "Failed to enable server support for new connection bus: %m");
718db961
LP
671 return 0;
672 }
6dded4c7 673
0674bbea
LP
674 r = sd_bus_negotiate_creds(bus, 1,
675 SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|
676 SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS|
677 SD_BUS_CREDS_SELINUX_CONTEXT);
678 if (r < 0) {
679 log_warning_errno(r, "Failed to enable credentials for new connection: %m");
680 return 0;
681 }
682
718db961
LP
683 r = sd_bus_start(bus);
684 if (r < 0) {
da927ba9 685 log_warning_errno(r, "Failed to start new connection bus: %m");
718db961 686 return 0;
6dded4c7
LP
687 }
688
718db961
LP
689 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
690 if (r < 0) {
da927ba9 691 log_warning_errno(r, "Failed to attach new connection bus to event loop: %m");
718db961 692 return 0;
6dded4c7
LP
693 }
694
b2c23da8 695 if (m->running_as == MANAGER_SYSTEM) {
718db961
LP
696 /* When we run as system instance we get the Released
697 * signal via a direct connection */
698
699 r = sd_bus_add_match(
700 bus,
19befb2d 701 NULL,
718db961
LP
702 "type='signal',"
703 "interface='org.freedesktop.systemd1.Agent',"
704 "member='Released',"
705 "path='/org/freedesktop/systemd1/agent'",
706 signal_agent_released, m);
707
708 if (r < 0) {
da927ba9 709 log_warning_errno(r, "Failed to register Released match on new connection bus: %m");
718db961
LP
710 return 0;
711 }
712 }
6dded4c7 713
718db961
LP
714 r = bus_setup_disconnected_match(m, bus);
715 if (r < 0)
716 return 0;
6dded4c7 717
718db961
LP
718 r = bus_setup_api_vtables(m, bus);
719 if (r < 0) {
da927ba9 720 log_warning_errno(r, "Failed to set up API vtables on new connection bus: %m");
718db961
LP
721 return 0;
722 }
6dded4c7 723
718db961
LP
724 r = set_put(m->private_buses, bus);
725 if (r < 0) {
05a08cb6 726 log_warning_errno(r, "Failed to add new connection bus to set: %m");
718db961 727 return 0;
6dded4c7
LP
728 }
729
718db961 730 bus = NULL;
6dded4c7 731
718db961 732 log_debug("Accepted new private connection.");
6dded4c7 733
8e274523
LP
734 return 0;
735}
736
718db961 737static int bus_list_names(Manager *m, sd_bus *bus) {
0e7be129
LP
738 _cleanup_strv_free_ char **names = NULL;
739 char **i;
718db961 740 int r;
5e8d1c9a
LP
741
742 assert(m);
718db961 743 assert(bus);
5e8d1c9a 744
0e7be129 745 r = sd_bus_list_names(bus, &names, NULL);
23bbb0de
MS
746 if (r < 0)
747 return log_error_errno(r, "Failed to get initial list of names: %m");
5e8d1c9a 748
718db961
LP
749 /* This is a bit hacky, we say the owner of the name is the
750 * name itself, because we don't want the extra traffic to
751 * figure out the real owner. */
bbc29086
DM
752 STRV_FOREACH(i, names) {
753 Unit *u;
754
755 u = hashmap_get(m->watch_bus, *i);
756 if (u)
757 UNIT_VTABLE(u)->bus_name_owner_change(u, *i, NULL, *i);
758 }
5e8d1c9a 759
718db961 760 return 0;
5e8d1c9a
LP
761}
762
718db961 763static int bus_setup_api(Manager *m, sd_bus *bus) {
bbc29086
DM
764 Iterator i;
765 char *name;
766 Unit *u;
718db961 767 int r;
f278026d 768
718db961
LP
769 assert(m);
770 assert(bus);
c1e1601e 771
8fd00193
LP
772 /* Let's make sure we have enough credential bits so that we can make security and selinux decisions */
773 r = sd_bus_negotiate_creds(bus, 1,
774 SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|
775 SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS|
776 SD_BUS_CREDS_SELINUX_CONTEXT);
777 if (r < 0)
da927ba9 778 log_warning_errno(r, "Failed to enable credential passing, ignoring: %m");
8fd00193 779
718db961
LP
780 r = bus_setup_api_vtables(m, bus);
781 if (r < 0)
782 return r;
cbd37330 783
bbc29086 784 HASHMAP_FOREACH_KEY(u, name, m->watch_bus, i) {
9806e87d 785 r = unit_install_bus_match(u, bus, name);
bbc29086
DM
786 if (r < 0)
787 log_error_errno(r, "Failed to subscribe to NameOwnerChanged signal: %m");
788 }
718db961
LP
789
790 r = sd_bus_add_match(
791 bus,
19befb2d 792 NULL,
718db961
LP
793 "type='signal',"
794 "sender='org.freedesktop.DBus',"
795 "path='/org/freedesktop/DBus',"
796 "interface='org.freedesktop.systemd1.Activator',"
797 "member='ActivationRequest'",
798 signal_activation_request, m);
799 if (r < 0)
da927ba9 800 log_warning_errno(r, "Failed to subscribe to activation signal: %m");
cbd37330 801
718db961
LP
802 /* Allow replacing of our name, to ease implementation of
803 * reexecution, where we keep the old connection open until
804 * after the new connection is set up and the name installed
805 * to allow clients to synchronously wait for reexecution to
806 * finish */
29a07cdb 807 r = sd_bus_request_name(bus,"org.freedesktop.systemd1", SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_ALLOW_REPLACEMENT);
23bbb0de
MS
808 if (r < 0)
809 return log_error_errno(r, "Failed to register name: %m");
53c6a358 810
718db961 811 bus_list_names(m, bus);
f278026d 812
718db961 813 log_debug("Successfully connected to API bus.");
f278026d
LP
814 return 0;
815}
816
718db961
LP
817static int bus_init_api(Manager *m) {
818 _cleanup_bus_unref_ sd_bus *bus = NULL;
f278026d
LP
819 int r;
820
718db961
LP
821 if (m->api_bus)
822 return 0;
cbd37330 823
718db961 824 /* The API and system bus is the same if we are running in system mode */
b2c23da8 825 if (m->running_as == MANAGER_SYSTEM && m->system_bus)
718db961
LP
826 bus = sd_bus_ref(m->system_bus);
827 else {
b2c23da8 828 if (m->running_as == MANAGER_SYSTEM)
718db961
LP
829 r = sd_bus_open_system(&bus);
830 else
831 r = sd_bus_open_user(&bus);
cbd37330 832
718db961
LP
833 if (r < 0) {
834 log_debug("Failed to connect to API bus, retrying later...");
835 return 0;
cbd37330
MS
836 }
837
718db961
LP
838 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
839 if (r < 0) {
da927ba9 840 log_error_errno(r, "Failed to attach API bus to event loop: %m");
718db961 841 return 0;
cbd37330
MS
842 }
843
718db961
LP
844 r = bus_setup_disconnected_match(m, bus);
845 if (r < 0)
846 return 0;
cbd37330
MS
847 }
848
718db961 849 r = bus_setup_api(m, bus);
cbd37330 850 if (r < 0) {
da927ba9 851 log_error_errno(r, "Failed to set up API bus: %m");
718db961 852 return 0;
cbd37330 853 }
cbd37330 854
718db961
LP
855 m->api_bus = bus;
856 bus = NULL;
cbd37330
MS
857
858 return 0;
cbd37330
MS
859}
860
718db961
LP
861static int bus_setup_system(Manager *m, sd_bus *bus) {
862 int r;
cbd37330 863
718db961
LP
864 assert(m);
865 assert(bus);
cbd37330 866
f5b51ea7 867 /* On kdbus or if we are a user instance we get the Released message via the system bus */
b2c23da8 868 if (m->running_as == MANAGER_USER || m->kdbus_fd >= 0) {
f5b51ea7
DH
869 r = sd_bus_add_match(
870 bus,
871 NULL,
872 "type='signal',"
873 "interface='org.freedesktop.systemd1.Agent',"
874 "member='Released',"
875 "path='/org/freedesktop/systemd1/agent'",
876 signal_agent_released, m);
877 if (r < 0)
878 log_warning_errno(r, "Failed to register Released match on system bus: %m");
879 }
718db961
LP
880
881 log_debug("Successfully connected to system bus.");
882 return 0;
cbd37330
MS
883}
884
885static int bus_init_system(Manager *m) {
718db961 886 _cleanup_bus_unref_ sd_bus *bus = NULL;
cbd37330
MS
887 int r;
888
889 if (m->system_bus)
890 return 0;
891
718db961 892 /* The API and system bus is the same if we are running in system mode */
b2c23da8 893 if (m->running_as == MANAGER_SYSTEM && m->api_bus) {
718db961
LP
894 m->system_bus = sd_bus_ref(m->api_bus);
895 return 0;
9014a8bd 896 }
8e274523 897
718db961
LP
898 r = sd_bus_open_system(&bus);
899 if (r < 0) {
900 log_debug("Failed to connect to system bus, retrying later...");
901 return 0;
902 }
cbd37330 903
718db961 904 r = bus_setup_disconnected_match(m, bus);
cbd37330 905 if (r < 0)
cbd37330
MS
906 return 0;
907
718db961
LP
908 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
909 if (r < 0) {
da927ba9 910 log_error_errno(r, "Failed to attach system bus to event loop: %m");
cbd37330
MS
911 return 0;
912 }
913
718db961
LP
914 r = bus_setup_system(m, bus);
915 if (r < 0) {
da927ba9 916 log_error_errno(r, "Failed to set up system bus: %m");
718db961 917 return 0;
cbd37330
MS
918 }
919
718db961
LP
920 m->system_bus = bus;
921 bus = NULL;
cbd37330
MS
922
923 return 0;
5e8d1c9a
LP
924}
925
926static int bus_init_private(Manager *m) {
718db961
LP
927 _cleanup_close_ int fd = -1;
928 union sockaddr_union sa = {
929 .un.sun_family = AF_UNIX
5e8d1c9a 930 };
718db961
LP
931 sd_event_source *s;
932 socklen_t salen;
933 int r;
5e8d1c9a
LP
934
935 assert(m);
936
718db961 937 if (m->private_listen_fd >= 0)
5e8d1c9a
LP
938 return 0;
939
a6aa8912
LP
940 /* We don't need the private socket if we have kdbus */
941 if (m->kdbus_fd >= 0)
942 return 0;
943
b2c23da8 944 if (m->running_as == MANAGER_SYSTEM) {
be81bfc4
LP
945
946 /* We want the private bus only when running as init */
947 if (getpid() != 1)
948 return 0;
949
718db961 950 strcpy(sa.un.sun_path, "/run/systemd/private");
f8294e41 951 salen = offsetof(union sockaddr_union, un.sun_path) + strlen("/run/systemd/private");
be81bfc4 952 } else {
718db961
LP
953 size_t left = sizeof(sa.un.sun_path);
954 char *p = sa.un.sun_path;
be81bfc4 955 const char *e;
be81bfc4 956
4db17f29 957 e = secure_getenv("XDG_RUNTIME_DIR");
718db961
LP
958 if (!e) {
959 log_error("Failed to determine XDG_RUNTIME_DIR");
960 return -EHOSTDOWN;
be81bfc4
LP
961 }
962
718db961
LP
963 left = strpcpy(&p, left, e);
964 left = strpcpy(&p, left, "/systemd/private");
92f30349 965
718db961 966 salen = sizeof(sa.un) - left;
be81bfc4 967 }
5e8d1c9a 968
f0e62e89
LP
969 (void) mkdir_parents_label(sa.un.sun_path, 0755);
970 (void) unlink(sa.un.sun_path);
718db961
LP
971
972 fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
4a62c710
MS
973 if (fd < 0)
974 return log_error_errno(errno, "Failed to allocate private socket: %m");
5e8d1c9a 975
718db961 976 r = bind(fd, &sa.sa, salen);
4a62c710
MS
977 if (r < 0)
978 return log_error_errno(errno, "Failed to bind private socket: %m");
5e8d1c9a 979
718db961 980 r = listen(fd, SOMAXCONN);
4a62c710
MS
981 if (r < 0)
982 return log_error_errno(errno, "Failed to make private socket listening: %m");
5e8d1c9a 983
151b9b96 984 r = sd_event_add_io(m->event, &s, fd, EPOLLIN, bus_on_connection, m);
23bbb0de
MS
985 if (r < 0)
986 return log_error_errno(r, "Failed to allocate event source: %m");
5e8d1c9a 987
7dfbe2e3
TG
988 (void) sd_event_source_set_description(s, "bus-connection");
989
718db961
LP
990 m->private_listen_fd = fd;
991 m->private_listen_event_source = s;
992 fd = -1;
5e8d1c9a 993
718db961 994 log_debug("Successfully created private D-Bus server.");
5e8d1c9a 995
718db961 996 return 0;
5e8d1c9a
LP
997}
998
3996fbe2 999int bus_init(Manager *m, bool try_bus_connect) {
5e8d1c9a
LP
1000 int r;
1001
3996fbe2 1002 if (try_bus_connect) {
718db961
LP
1003 r = bus_init_system(m);
1004 if (r < 0)
1005 return r;
1006
1007 r = bus_init_api(m);
1008 if (r < 0)
3996fbe2
LP
1009 return r;
1010 }
1011
6fa48533
LP
1012 r = bus_init_private(m);
1013 if (r < 0)
5e8d1c9a 1014 return r;
f278026d 1015
ea430986
LP
1016 return 0;
1017}
1018
718db961 1019static void destroy_bus(Manager *m, sd_bus **bus) {
a567261a 1020 Iterator i;
718db961 1021 Job *j;
a567261a 1022
718db961
LP
1023 assert(m);
1024 assert(bus);
5e8d1c9a 1025
718db961 1026 if (!*bus)
cbd37330 1027 return;
f278026d 1028
718db961 1029 /* Get rid of tracked clients on this bus */
8f8f05a9
LP
1030 if (m->subscribed && sd_bus_track_get_bus(m->subscribed) == *bus)
1031 m->subscribed = sd_bus_track_unref(m->subscribed);
1032
718db961 1033 HASHMAP_FOREACH(j, m->jobs, i)
b39a2770
SW
1034 if (j->clients && sd_bus_track_get_bus(j->clients) == *bus)
1035 j->clients = sd_bus_track_unref(j->clients);
c1e1601e 1036
718db961 1037 /* Get rid of queued message on this bus */
8f88ecf6
LP
1038 if (m->queued_message && sd_bus_message_get_bus(m->queued_message) == *bus)
1039 m->queued_message = sd_bus_message_unref(m->queued_message);
f278026d 1040
718db961
LP
1041 /* Possibly flush unwritten data, but only if we are
1042 * unprivileged, since we don't want to sync here */
b2c23da8 1043 if (m->running_as != MANAGER_SYSTEM)
718db961 1044 sd_bus_flush(*bus);
5e8d1c9a 1045
718db961
LP
1046 /* And destroy the object */
1047 sd_bus_close(*bus);
1048 *bus = sd_bus_unref(*bus);
5e8d1c9a
LP
1049}
1050
1051void bus_done(Manager *m) {
718db961 1052 sd_bus *b;
05e343b7
LP
1053
1054 assert(m);
05e343b7 1055
718db961
LP
1056 if (m->api_bus)
1057 destroy_bus(m, &m->api_bus);
1058 if (m->system_bus)
1059 destroy_bus(m, &m->system_bus);
1060 while ((b = set_steal_first(m->private_buses)))
1061 destroy_bus(m, &b);
05e343b7 1062
525d3cc7 1063 m->private_buses = set_free(m->private_buses);
8f8f05a9
LP
1064
1065 m->subscribed = sd_bus_track_unref(m->subscribed);
6796073e 1066 m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
05e343b7 1067
718db961
LP
1068 if (m->private_listen_event_source)
1069 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
05e343b7 1070
03e334a1 1071 m->private_listen_fd = safe_close(m->private_listen_fd);
283868e1
SW
1072
1073 bus_verify_polkit_async_registry_free(m->polkit_registry);
a567261a 1074}
b23de6af
LP
1075
1076int bus_fdset_add_all(Manager *m, FDSet *fds) {
1077 Iterator i;
718db961
LP
1078 sd_bus *b;
1079 int fd;
b23de6af
LP
1080
1081 assert(m);
1082 assert(fds);
1083
1084 /* When we are about to reexecute we add all D-Bus fds to the
1085 * set to pass over to the newly executed systemd. They won't
718db961 1086 * be used there however, except thatt they are closed at the
b23de6af 1087 * very end of deserialization, those making it possible for
44143309 1088 * clients to synchronously wait for systemd to reexec by
b23de6af
LP
1089 * simply waiting for disconnection */
1090
718db961
LP
1091 if (m->api_bus) {
1092 fd = sd_bus_get_fd(m->api_bus);
1093 if (fd >= 0) {
b23de6af 1094 fd = fdset_put_dup(fds, fd);
b23de6af
LP
1095 if (fd < 0)
1096 return fd;
1097 }
1098 }
1099
718db961
LP
1100 SET_FOREACH(b, m->private_buses, i) {
1101 fd = sd_bus_get_fd(b);
1102 if (fd >= 0) {
b23de6af 1103 fd = fdset_put_dup(fds, fd);
b23de6af
LP
1104 if (fd < 0)
1105 return fd;
1106 }
1107 }
1108
718db961
LP
1109 /* We don't offer any APIs on the system bus (well, unless it
1110 * is the same as the API bus) hence we don't bother with it
1111 * here */
6fa48533 1112
718db961 1113 return 0;
6fa48533
LP
1114}
1115
8f8f05a9
LP
1116int bus_foreach_bus(
1117 Manager *m,
1118 sd_bus_track *subscribed2,
1119 int (*send_message)(sd_bus *bus, void *userdata),
1120 void *userdata) {
1121
1122 Iterator i;
1123 sd_bus *b;
1124 int r, ret = 0;
1125
ff9b60f3 1126 /* Send to all direct buses, unconditionally */
8f8f05a9
LP
1127 SET_FOREACH(b, m->private_buses, i) {
1128 r = send_message(b, userdata);
1129 if (r < 0)
1130 ret = r;
1131 }
1132
1133 /* Send to API bus, but only if somebody is subscribed */
1134 if (sd_bus_track_count(m->subscribed) > 0 ||
1135 sd_bus_track_count(subscribed2) > 0) {
1136 r = send_message(m->api_bus, userdata);
1137 if (r < 0)
1138 ret = r;
1139 }
1140
1141 return ret;
1142}
1143
1144void bus_track_serialize(sd_bus_track *t, FILE *f) {
1145 const char *n;
1146
6fa48533
LP
1147 assert(f);
1148
8f8f05a9
LP
1149 for (n = sd_bus_track_first(t); n; n = sd_bus_track_next(t))
1150 fprintf(f, "subscribed=%s\n", n);
6fa48533
LP
1151}
1152
8f8f05a9
LP
1153int bus_track_deserialize_item(char ***l, const char *line) {
1154 const char *e;
230314d7 1155 int r;
8f8f05a9
LP
1156
1157 assert(l);
6fa48533
LP
1158 assert(line);
1159
8f8f05a9
LP
1160 e = startswith(line, "subscribed=");
1161 if (!e)
230314d7
LP
1162 return 0;
1163
1164 r = strv_extend(l, e);
1165 if (r < 0)
1166 return r;
8f8f05a9 1167
230314d7 1168 return 1;
8f8f05a9
LP
1169}
1170
1171int bus_track_coldplug(Manager *m, sd_bus_track **t, char ***l) {
1172 int r = 0;
1173
1174 assert(m);
1175 assert(t);
1176 assert(l);
1177
1178 if (!strv_isempty(*l) && m->api_bus) {
1179 char **i;
1180
1181 if (!*t) {
1182 r = sd_bus_track_new(m->api_bus, t, NULL, NULL);
1183 if (r < 0)
1184 return r;
1185 }
1186
1187 r = 0;
1188 STRV_FOREACH(i, *l) {
1189 int k;
1190
1191 k = sd_bus_track_add_name(*t, *i);
1192 if (k < 0)
1193 r = k;
1194 }
1195 }
1196
6796073e 1197 *l = strv_free(*l);
8f8f05a9
LP
1198
1199 return r;
6fa48533 1200}
283868e1 1201
1d22e906 1202int bus_verify_manage_units_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
403ed0e5 1203 return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-units", NULL, false, UID_INVALID, &m->polkit_registry, error);
283868e1
SW
1204}
1205
283868e1 1206int bus_verify_manage_unit_files_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
403ed0e5 1207 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
1208}
1209
1210int bus_verify_reload_daemon_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
403ed0e5 1211 return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.reload-daemon", NULL, false, UID_INVALID, &m->polkit_registry, error);
283868e1 1212}
1d22e906
LP
1213
1214int bus_verify_set_environment_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
403ed0e5 1215 return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.set-environment", NULL, false, UID_INVALID, &m->polkit_registry, error);
1d22e906 1216}