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