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