chiark / gitweb /
cda1c5d5bd8c8791505c2787208f319c61ae4f95
[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 "dbus-client-track.h"
45 #include "bus-internal.h"
46 #include "selinux-access.h"
47
48 #define CONNECTIONS_MAX 512
49
50 static void destroy_bus(Manager *m, sd_bus **bus);
51
52 int bus_send_queued_message(Manager *m) {
53         int r;
54
55         assert(m);
56
57         if (!m->queued_message)
58                 return 0;
59
60         assert(m->queued_message_bus);
61
62         /* If we cannot get rid of this message we won't dispatch any
63          * D-Bus messages, so that we won't end up wanting to queue
64          * another message. */
65
66         r = sd_bus_send(m->queued_message_bus, m->queued_message, NULL);
67         if (r < 0)
68                 log_warning("Failed to send queued message: %s", strerror(-r));
69
70         m->queued_message = sd_bus_message_unref(m->queued_message);
71         m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
72
73         return 0;
74 }
75
76 static int signal_agent_released(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
77         Manager *m = userdata;
78         const char *cgroup;
79         int r;
80
81         assert(bus);
82         assert(message);
83         assert(m);
84
85         r = sd_bus_message_read(message, "s", &cgroup);
86         if (r < 0) {
87                 bus_log_parse_error(r);
88                 return 0;
89         }
90
91         manager_notify_cgroup_empty(m, cgroup);
92
93         if (m->running_as == SYSTEMD_SYSTEM && m->system_bus) {
94                 /* If we are running as system manager, forward the
95                  * message to the system bus */
96
97                 r = sd_bus_send(m->system_bus, message, NULL);
98                 if (r < 0)
99                         log_warning("Failed to forward Released message: %s", strerror(-r));
100         }
101
102         return 0;
103 }
104
105 static int signal_disconnected(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
106         Manager *m = userdata;
107
108         assert(bus);
109         assert(message);
110         assert(m);
111
112         if (bus == m->api_bus)
113                 destroy_bus(m, &m->api_bus);
114         if (bus == m->system_bus)
115                 destroy_bus(m, &m->system_bus);
116         if (set_remove(m->private_buses, bus)) {
117                 log_debug("Got disconnect on private connection.");
118                 destroy_bus(m, &bus);
119         }
120
121         return 0;
122 }
123
124 static int signal_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
125         const char *name, *old_owner, *new_owner;
126         Manager *m = userdata;
127         int r;
128
129         assert(bus);
130         assert(message);
131         assert(m);
132
133         r = sd_bus_message_read(message, "sss", &name, &old_owner, &new_owner);
134         if (r < 0) {
135                 bus_log_parse_error(r);
136                 return 0;
137         }
138
139         manager_dispatch_bus_name_owner_changed(
140                         m, name,
141                         isempty(old_owner) ? NULL : old_owner,
142                         isempty(new_owner) ? NULL : new_owner);
143
144         return 0;
145 }
146
147 static int signal_activation_request(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
148         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
149         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
150         Manager *m = userdata;
151         const char *name;
152         Unit *u;
153         int r;
154
155         assert(bus);
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_setf(&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, %u may be requested by dependency only.", u->id);
177                 goto failed;
178         }
179
180         r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &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(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure", &reply);
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(bus, reply, "org.freedesktop.DBus", NULL);
206         if (r < 0) {
207                 log_error("Failed to respond with to bus activation request: %s", strerror(-r));
208                 return r;
209         }
210
211         return 0;
212 }
213
214 static int 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 = selinux_access_check(bus, 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 = selinux_unit_access_check(u, bus, message, verb, error);
274         if (r < 0)
275                 return r;
276
277         return 0;
278 }
279
280 static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
281         Manager *m = userdata;
282         Job *j;
283         int r;
284
285         assert(bus);
286         assert(path);
287         assert(interface);
288         assert(found);
289         assert(m);
290
291         r = manager_get_job_from_dbus_path(m, path, &j);
292         if (r < 0)
293                 return 0;
294
295         *found = j;
296         return 1;
297 }
298
299 static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_bus_error *error) {
300         Unit *u;
301         int r;
302
303         assert(m);
304         assert(bus);
305         assert(path);
306
307         if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
308                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
309                 sd_bus_message *message;
310                 pid_t pid;
311
312                 message = sd_bus_get_current(bus);
313                 if (!message)
314                         return 0;
315
316                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
317                 if (r < 0)
318                         return r;
319
320                 r = sd_bus_creds_get_pid(creds, &pid);
321                 if (r < 0)
322                         return r;
323
324                 u = manager_get_unit_by_pid(m, pid);
325         } else {
326                 r = manager_load_unit_from_dbus_path(m, path, error, &u);
327                 if (r < 0)
328                         return 0;
329         }
330
331         if (!u)
332                 return 0;
333
334         *unit = u;
335         return 1;
336 }
337
338 static int bus_unit_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
339         Manager *m = userdata;
340
341         assert(bus);
342         assert(path);
343         assert(interface);
344         assert(found);
345         assert(m);
346
347         return find_unit(m, bus, path, (Unit**) found, error);
348 }
349
350 static int bus_unit_interface_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_VTABLE(u)->bus_interface))
366                 return 0;
367
368         *found = u;
369         return 1;
370 }
371
372 static int bus_unit_cgroup_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
373         Manager *m = userdata;
374         Unit *u;
375         int r;
376
377         assert(bus);
378         assert(path);
379         assert(interface);
380         assert(found);
381         assert(m);
382
383         r = find_unit(m, bus, path, &u, error);
384         if (r <= 0)
385                 return r;
386
387         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
388                 return 0;
389
390         if (!unit_get_cgroup_context(u))
391                 return 0;
392
393         *found = u;
394         return 1;
395 }
396
397 static int bus_cgroup_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
398         Manager *m = userdata;
399         CGroupContext *c;
400         Unit *u;
401         int r;
402
403         assert(bus);
404         assert(path);
405         assert(interface);
406         assert(found);
407         assert(m);
408
409         r = find_unit(m, bus, path, &u, error);
410         if (r <= 0)
411                 return r;
412
413         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
414                 return 0;
415
416         c = unit_get_cgroup_context(u);
417         if (!c)
418                 return 0;
419
420         *found = c;
421         return 1;
422 }
423
424 static int bus_exec_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
425         Manager *m = userdata;
426         ExecContext *c;
427         Unit *u;
428         int r;
429
430         assert(bus);
431         assert(path);
432         assert(interface);
433         assert(found);
434         assert(m);
435
436         r = find_unit(m, bus, path, &u, error);
437         if (r <= 0)
438                 return r;
439
440         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
441                 return 0;
442
443         c = unit_get_exec_context(u);
444         if (!c)
445                 return 0;
446
447         *found = c;
448         return 1;
449 }
450
451 static int bus_kill_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
452         Manager *m = userdata;
453         KillContext *c;
454         Unit *u;
455         int r;
456
457         assert(bus);
458         assert(path);
459         assert(interface);
460         assert(found);
461         assert(m);
462
463         r = find_unit(m, bus, path, &u, error);
464         if (r <= 0)
465                 return r;
466
467         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
468                 return 0;
469
470         c = unit_get_kill_context(u);
471         if (!c)
472                 return 0;
473
474         *found = c;
475         return 1;
476 }
477
478 static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
479         _cleanup_free_ char **l = NULL;
480         Manager *m = userdata;
481         unsigned k = 0;
482         Iterator i;
483         Job *j;
484
485         l = new0(char*, hashmap_size(m->jobs)+1);
486         if (!l)
487                 return -ENOMEM;
488
489         HASHMAP_FOREACH(j, m->jobs, i) {
490                 l[k] = job_dbus_path(j);
491                 if (!l[k])
492                         return -ENOMEM;
493
494                 k++;
495         }
496
497         assert(hashmap_size(m->jobs) == k);
498
499         *nodes = l;
500         l = NULL;
501
502         return k;
503 }
504
505 static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
506         _cleanup_free_ char **l = NULL;
507         Manager *m = userdata;
508         unsigned k = 0;
509         Iterator i;
510         Unit *u;
511
512         l = new0(char*, hashmap_size(m->units)+1);
513         if (!l)
514                 return -ENOMEM;
515
516         HASHMAP_FOREACH(u, m->units, i) {
517                 l[k] = unit_dbus_path(u);
518                 if (!l[k])
519                         return -ENOMEM;
520
521                 k++;
522         }
523
524         *nodes = l;
525         l = NULL;
526
527         return k;
528 }
529
530 static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
531         UnitType t;
532         int r;
533
534         assert(m);
535         assert(bus);
536
537         r = sd_bus_add_filter(bus, selinux_filter, m);
538         if (r < 0) {
539                 log_error("Failed to add SELinux access filter: %s", strerror(-r));
540                 return r;
541         }
542
543         r = sd_bus_add_object_vtable(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
544         if (r < 0) {
545                 log_error("Failed to register Manager vtable: %s", strerror(-r));
546                 return r;
547         }
548
549         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
550         if (r < 0) {
551                 log_error("Failed to register Job vtable: %s", strerror(-r));
552                 return r;
553         }
554
555         r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
556         if (r < 0) {
557                 log_error("Failed to add job enumerator: %s", strerror(-r));
558                 return r;
559         }
560
561         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
562         if (r < 0) {
563                 log_error("Failed to register Unit vtable: %s", strerror(-r));
564                 return r;
565         }
566
567         r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
568         if (r < 0) {
569                 log_error("Failed to add job enumerator: %s", strerror(-r));
570                 return r;
571         }
572
573         for (t = 0; t < _UNIT_TYPE_MAX; t++) {
574                 r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, unit_vtable[t]->bus_vtable, bus_unit_interface_find, m);
575                 if (r < 0)  {
576                         log_error("Failed to register type specific vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
577                         return r;
578                 }
579
580                 if (unit_vtable[t]->cgroup_context_offset > 0) {
581                         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_unit_cgroup_vtable, bus_unit_cgroup_find, m);
582                         if (r < 0) {
583                                 log_error("Failed to register control group unit vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
584                                 return r;
585                         }
586
587                         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
588                         if (r < 0) {
589                                 log_error("Failed to register control group vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
590                                 return r;
591                         }
592                 }
593
594                 if (unit_vtable[t]->exec_context_offset > 0) {
595                         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_exec_vtable, bus_exec_context_find, m);
596                         if (r < 0) {
597                                 log_error("Failed to register execute vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
598                                 return r;
599                         }
600                 }
601
602                 if (unit_vtable[t]->kill_context_offset > 0) {
603                         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_kill_vtable, bus_kill_context_find, m);
604                         if (r < 0) {
605                                 log_error("Failed to register kill vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
606                                 return r;
607                         }
608                 }
609         }
610
611         return 0;
612 }
613
614 static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
615         int r;
616
617         assert(m);
618         assert(bus);
619
620         r = sd_bus_add_match(
621                         bus,
622                         "type='signal',"
623                         "path='/org/freedesktop/DBus/Local',"
624                         "interface='org.freedesktop.DBus.Local',"
625                         "member='Disconnected'",
626                         signal_disconnected, m);
627
628         if (r < 0) {
629                 log_error("Failed to register match for Disconnected message: %s", strerror(-r));
630                 return r;
631         }
632
633         return 0;
634 }
635
636 static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
637         _cleanup_bus_unref_ sd_bus *bus = NULL;
638         _cleanup_close_ int nfd = -1;
639         Manager *m = userdata;
640         sd_id128_t id;
641         int r;
642
643         assert(s);
644         assert(m);
645
646         nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
647         if (nfd < 0) {
648                 log_warning("Failed to accept private connection, ignoring: %m");
649                 return 0;
650         }
651
652         if (set_size(m->private_buses) >= CONNECTIONS_MAX) {
653                 log_warning("Too many concurrent connections, refusing");
654                 return 0;
655         }
656
657         r = set_ensure_allocated(&m->private_buses, trivial_hash_func, trivial_compare_func);
658         if (r < 0) {
659                 log_oom();
660                 return 0;
661         }
662
663         r = sd_bus_new(&bus);
664         if (r < 0) {
665                 log_warning("Failed to allocate new private connection bus: %s", strerror(-r));
666                 return 0;
667         }
668
669         r = sd_bus_set_fd(bus, nfd, nfd);
670         if (r < 0) {
671                 log_warning("Failed to set fd on new connection bus: %s", strerror(-r));
672                 return 0;
673         }
674
675         nfd = -1;
676
677         r = bus_check_peercred(bus);
678         if (r < 0) {
679                 log_warning("Incoming private connection from unprivileged client, refusing: %s", strerror(-r));
680                 return 0;
681         }
682
683         assert_se(sd_id128_randomize(&id) >= 0);
684
685         r = sd_bus_set_server(bus, 1, id);
686         if (r < 0) {
687                 log_warning("Failed to enable server support for new connection bus: %s", strerror(-r));
688                 return 0;
689         }
690
691         r = sd_bus_start(bus);
692         if (r < 0) {
693                 log_warning("Failed to start new connection bus: %s", strerror(-r));
694                 return 0;
695         }
696
697         r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
698         if (r < 0) {
699                 log_warning("Failed to attach new connection bus to event loop: %s", strerror(-r));
700                 return 0;
701         }
702
703         if (m->running_as == SYSTEMD_SYSTEM) {
704                 /* When we run as system instance we get the Released
705                  * signal via a direct connection */
706
707                 r = sd_bus_add_match(
708                                 bus,
709                                 "type='signal',"
710                                 "interface='org.freedesktop.systemd1.Agent',"
711                                 "member='Released',"
712                                 "path='/org/freedesktop/systemd1/agent'",
713                                 signal_agent_released, m);
714
715                 if (r < 0) {
716                         log_warning("Failed to register Released match on new connection bus: %s", strerror(-r));
717                         return 0;
718                 }
719         }
720
721         r = bus_setup_disconnected_match(m, bus);
722         if (r < 0)
723                 return 0;
724
725         r = bus_setup_api_vtables(m, bus);
726         if (r < 0) {
727                 log_warning("Failed to set up API vtables on new connection bus: %s", strerror(-r));
728                 return 0;
729         }
730
731         r = set_put(m->private_buses, bus);
732         if (r < 0) {
733                 log_warning("Failed to add new conenction bus to set: %s", strerror(-r));
734                 return 0;
735         }
736
737         bus = NULL;
738
739         log_debug("Accepted new private connection.");
740
741         return 0;
742 }
743
744 static int bus_list_names(Manager *m, sd_bus *bus) {
745         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
746         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
747         const char *name;
748         int r;
749
750         assert(m);
751         assert(bus);
752
753         r = sd_bus_call_method(
754                         bus,
755                         "org.freedesktop.DBus",
756                         "/org/freedesktop/DBus",
757                         "org.freedesktop.DBus",
758                         "ListNames",
759                         &error, &reply,
760                         NULL);
761         if (r < 0) {
762                 log_error("Failed to get initial list of names: %s", bus_error_message(&error, r));
763                 return r;
764         }
765
766         r = sd_bus_message_enter_container(reply, 'a', "s");
767         if (r < 0)
768                 return bus_log_parse_error(r);
769
770         /* This is a bit hacky, we say the owner of the name is the
771          * name itself, because we don't want the extra traffic to
772          * figure out the real owner. */
773         while ((r = sd_bus_message_read(reply, "s", &name)) > 0)
774                 manager_dispatch_bus_name_owner_changed(m, name, NULL, name);
775         if (r < 0)
776                 return bus_log_parse_error(r);
777
778         r = sd_bus_message_exit_container(reply);
779         if (r < 0)
780                 return bus_log_parse_error(r);
781
782         return 0;
783 }
784
785 static int bus_setup_api(Manager *m, sd_bus *bus) {
786         int r;
787
788         assert(m);
789         assert(bus);
790
791         r = bus_setup_api_vtables(m, bus);
792         if (r < 0)
793                 return r;
794
795         r = sd_bus_add_match(
796                         bus,
797                         "type='signal',"
798                         "sender='org.freedesktop.DBus',"
799                         "path='/org/freedesktop/DBus',"
800                         "interface='org.freedesktop.DBus',"
801                         "member='NameOwnerChanged'",
802                         signal_name_owner_changed, m);
803         if (r < 0)
804                 log_warning("Failed to subscribe to NameOwnerChanged signal: %s", strerror(-r));
805
806         r = sd_bus_add_match(
807                         bus,
808                         "type='signal',"
809                         "sender='org.freedesktop.DBus',"
810                         "path='/org/freedesktop/DBus',"
811                         "interface='org.freedesktop.systemd1.Activator',"
812                         "member='ActivationRequest'",
813                         signal_activation_request, m);
814         if (r < 0)
815                 log_warning("Failed to subscribe to activation signal: %s", strerror(-r));
816
817         /* Allow replacing of our name, to ease implementation of
818          * reexecution, where we keep the old connection open until
819          * after the new connection is set up and the name installed
820          * to allow clients to synchronously wait for reexecution to
821          * finish */
822         r = sd_bus_request_name(bus,"org.freedesktop.systemd1", SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_DO_NOT_QUEUE);
823         if (r < 0) {
824                 log_error("Failed to register name: %s", strerror(-r));
825                 return r;
826         }
827
828         bus_list_names(m, bus);
829
830         log_debug("Successfully connected to API bus.");
831         return 0;
832 }
833
834 static int bus_init_api(Manager *m) {
835         _cleanup_bus_unref_ sd_bus *bus = NULL;
836         int r;
837
838         if (m->api_bus)
839                 return 0;
840
841         /* The API and system bus is the same if we are running in system mode */
842         if (m->running_as == SYSTEMD_SYSTEM && m->system_bus)
843                 bus = sd_bus_ref(m->system_bus);
844         else {
845                 if (m->running_as == SYSTEMD_SYSTEM)
846                         r = sd_bus_open_system(&bus);
847                 else
848                         r = sd_bus_open_user(&bus);
849
850                 if (r < 0) {
851                         log_debug("Failed to connect to API bus, retrying later...");
852                         return 0;
853                 }
854
855                 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
856                 if (r < 0) {
857                         log_error("Failed to attach API bus to event loop: %s", strerror(-r));
858                         return 0;
859                 }
860
861                 r = bus_setup_disconnected_match(m, bus);
862                 if (r < 0)
863                         return 0;
864         }
865
866         r = bus_setup_api(m, bus);
867         if (r < 0) {
868                 log_error("Failed to set up API bus: %s", strerror(-r));
869                 return 0;
870         }
871
872         m->api_bus = bus;
873         bus = NULL;
874
875         return 0;
876 }
877
878 static int bus_setup_system(Manager *m, sd_bus *bus) {
879         int r;
880
881         assert(m);
882         assert(bus);
883
884         if (m->running_as == SYSTEMD_SYSTEM)
885                 return 0;
886
887         /* If we are a user instance we get the Released message via
888          * the system bus */
889         r = sd_bus_add_match(
890                         bus,
891                         "type='signal',"
892                         "interface='org.freedesktop.systemd1.Agent',"
893                         "member='Released',"
894                         "path='/org/freedesktop/systemd1/agent'",
895                         signal_agent_released, m);
896
897         if (r < 0)
898                 log_warning("Failed to register Released match on system bus: %s", strerror(-r));
899
900         log_debug("Successfully connected to system bus.");
901         return 0;
902 }
903
904 static int bus_init_system(Manager *m) {
905         _cleanup_bus_unref_ sd_bus *bus = NULL;
906         int r;
907
908         if (m->system_bus)
909                 return 0;
910
911         /* The API and system bus is the same if we are running in system mode */
912         if (m->running_as == SYSTEMD_SYSTEM && m->api_bus) {
913                 m->system_bus = sd_bus_ref(m->api_bus);
914                 return 0;
915         }
916
917         r = sd_bus_open_system(&bus);
918         if (r < 0) {
919                 log_debug("Failed to connect to system bus, retrying later...");
920                 return 0;
921         }
922
923         r = bus_setup_disconnected_match(m, bus);
924         if (r < 0)
925                 return 0;
926
927         r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
928         if (r < 0) {
929                 log_error("Failed to attach system bus to event loop: %s", strerror(-r));
930                 return 0;
931         }
932
933         r = bus_setup_system(m, bus);
934         if (r < 0) {
935                 log_error("Fauiled to set up system bus: %s", strerror(-r));
936                 return 0;
937         }
938
939         m->system_bus = bus;
940         bus = NULL;
941
942         return 0;
943 }
944
945 static int bus_init_private(Manager *m) {
946         _cleanup_close_ int fd = -1;
947         union sockaddr_union sa = {
948                 .un.sun_family = AF_UNIX
949         };
950         sd_event_source *s;
951         socklen_t salen;
952         int r;
953
954         assert(m);
955
956         if (m->private_listen_fd >= 0)
957                 return 0;
958
959         if (m->running_as == SYSTEMD_SYSTEM) {
960
961                 /* We want the private bus only when running as init */
962                 if (getpid() != 1)
963                         return 0;
964
965                 strcpy(sa.un.sun_path, "/run/systemd/private");
966                 salen = offsetof(union sockaddr_union, un.sun_path) + sizeof("/run/systemd/private") - 1;
967         } else {
968                 size_t left = sizeof(sa.un.sun_path);
969                 char *p = sa.un.sun_path;
970                 const char *e;
971
972                 e = secure_getenv("XDG_RUNTIME_DIR");
973                 if (!e) {
974                         log_error("Failed to determine XDG_RUNTIME_DIR");
975                         return -EHOSTDOWN;
976                 }
977
978                 left = strpcpy(&p, left, e);
979                 left = strpcpy(&p, left, "/systemd/private");
980
981                 salen = sizeof(sa.un) - left;
982
983                 mkdir_parents_label(sa.un.sun_path, 0755);
984         }
985
986         unlink(sa.un.sun_path);
987
988         fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
989         if (fd < 0) {
990                 log_error("Failed to allocate private socket: %m");
991                 return -errno;
992         }
993
994         r = bind(fd, &sa.sa, salen);
995         if (r < 0) {
996                 log_error("Failed to bind private socket: %m");
997                 return -errno;
998         }
999
1000         r = listen(fd, SOMAXCONN);
1001         if (r < 0) {
1002                 log_error("Failed to make private socket listening: %m");
1003                 return -errno;
1004         }
1005
1006         r = sd_event_add_io(m->event, fd, EPOLLIN, bus_on_connection, m, &s);
1007         if (r < 0) {
1008                 log_error("Failed to allocate event source: %s", strerror(-r));
1009                 return r;
1010         }
1011
1012         m->private_listen_fd = fd;
1013         m->private_listen_event_source = s;
1014         fd = -1;
1015
1016         log_debug("Successfully created private D-Bus server.");
1017
1018         return 0;
1019 }
1020
1021 int bus_init(Manager *m, bool try_bus_connect) {
1022         int r;
1023
1024         if (try_bus_connect) {
1025                 r = bus_init_system(m);
1026                 if (r < 0)
1027                         return r;
1028
1029                 r = bus_init_api(m);
1030                 if (r < 0)
1031                         return r;
1032         }
1033
1034         r = bus_init_private(m);
1035         if (r < 0)
1036                 return r;
1037
1038         return 0;
1039 }
1040
1041 static void destroy_bus(Manager *m, sd_bus **bus) {
1042         Iterator i;
1043         Job *j;
1044
1045         assert(m);
1046         assert(bus);
1047
1048         if (!*bus)
1049                 return;
1050
1051         /* Get rid of tracked clients on this bus */
1052         bus_client_untrack_bus(m->subscribed, *bus);
1053         HASHMAP_FOREACH(j, m->jobs, i)
1054                 bus_client_untrack_bus(j->subscribed, *bus);
1055
1056         /* Get rid of queued message on this bus */
1057         if (m->queued_message_bus == *bus) {
1058                 m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
1059
1060                 if (m->queued_message)
1061                         m->queued_message = sd_bus_message_unref(m->queued_message);
1062         }
1063
1064         /* Possibly flush unwritten data, but only if we are
1065          * unprivileged, since we don't want to sync here */
1066         if (m->running_as != SYSTEMD_SYSTEM)
1067                 sd_bus_flush(*bus);
1068
1069         /* And destroy the object */
1070         sd_bus_close(*bus);
1071         *bus = sd_bus_unref(*bus);
1072 }
1073
1074 void bus_done(Manager *m) {
1075         sd_bus *b;
1076
1077         assert(m);
1078
1079         if (m->api_bus)
1080                 destroy_bus(m, &m->api_bus);
1081         if (m->system_bus)
1082                 destroy_bus(m, &m->system_bus);
1083         while ((b = set_steal_first(m->private_buses)))
1084                 destroy_bus(m, &b);
1085
1086         set_free(m->private_buses);
1087         set_free(m->subscribed);
1088
1089         if (m->private_listen_event_source)
1090                 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
1091
1092         if (m->private_listen_fd >= 0) {
1093                 close_nointr_nofail(m->private_listen_fd);
1094                 m->private_listen_fd = -1;
1095         }
1096 }
1097
1098 int bus_fdset_add_all(Manager *m, FDSet *fds) {
1099         Iterator i;
1100         sd_bus *b;
1101         int fd;
1102
1103         assert(m);
1104         assert(fds);
1105
1106         /* When we are about to reexecute we add all D-Bus fds to the
1107          * set to pass over to the newly executed systemd. They won't
1108          * be used there however, except thatt they are closed at the
1109          * very end of deserialization, those making it possible for
1110          * clients to synchronously wait for systemd to reexec by
1111          * simply waiting for disconnection */
1112
1113         if (m->api_bus) {
1114                 fd = sd_bus_get_fd(m->api_bus);
1115                 if (fd >= 0) {
1116                         fd = fdset_put_dup(fds, fd);
1117                         if (fd < 0)
1118                                 return fd;
1119                 }
1120         }
1121
1122         SET_FOREACH(b, m->private_buses, i) {
1123                 fd = sd_bus_get_fd(b);
1124                 if (fd >= 0) {
1125                         fd = fdset_put_dup(fds, fd);
1126                         if (fd < 0)
1127                                 return fd;
1128                 }
1129         }
1130
1131         /* We don't offer any APIs on the system bus (well, unless it
1132          * is the same as the API bus) hence we don't bother with it
1133          * here */
1134
1135         return 0;
1136 }
1137
1138 void bus_serialize(Manager *m, FILE *f) {
1139         assert(m);
1140         assert(f);
1141
1142         bus_client_track_serialize(m, f, m->subscribed);
1143 }
1144
1145 int bus_deserialize_item(Manager *m, const char *line) {
1146         assert(m);
1147         assert(line);
1148
1149         return bus_client_track_deserialize_item(m, &m->subscribed, line);
1150 }