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