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