chiark / gitweb /
cab7628ad0d2a335881c36fcdb1322611cf5431f
[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_strv_free_ char **names = NULL;
746         char **i;
747         int r;
748
749         assert(m);
750         assert(bus);
751
752         r = sd_bus_list_names(bus, &names, NULL);
753         if (r < 0) {
754                 log_error("Failed to get initial list of names: %s", strerror(-r));
755                 return r;
756         }
757
758         /* This is a bit hacky, we say the owner of the name is the
759          * name itself, because we don't want the extra traffic to
760          * figure out the real owner. */
761         STRV_FOREACH(i, names)
762                 manager_dispatch_bus_name_owner_changed(m, *i, NULL, *i);
763
764         return 0;
765 }
766
767 static int bus_setup_api(Manager *m, sd_bus *bus) {
768         int r;
769
770         assert(m);
771         assert(bus);
772
773         r = bus_setup_api_vtables(m, bus);
774         if (r < 0)
775                 return r;
776
777         r = sd_bus_add_match(
778                         bus,
779                         "type='signal',"
780                         "sender='org.freedesktop.DBus',"
781                         "path='/org/freedesktop/DBus',"
782                         "interface='org.freedesktop.DBus',"
783                         "member='NameOwnerChanged'",
784                         signal_name_owner_changed, m);
785         if (r < 0)
786                 log_warning("Failed to subscribe to NameOwnerChanged signal: %s", strerror(-r));
787
788         r = sd_bus_add_match(
789                         bus,
790                         "type='signal',"
791                         "sender='org.freedesktop.DBus',"
792                         "path='/org/freedesktop/DBus',"
793                         "interface='org.freedesktop.systemd1.Activator',"
794                         "member='ActivationRequest'",
795                         signal_activation_request, m);
796         if (r < 0)
797                 log_warning("Failed to subscribe to activation signal: %s", strerror(-r));
798
799         /* Allow replacing of our name, to ease implementation of
800          * reexecution, where we keep the old connection open until
801          * after the new connection is set up and the name installed
802          * to allow clients to synchronously wait for reexecution to
803          * finish */
804         r = sd_bus_request_name(bus,"org.freedesktop.systemd1", SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_DO_NOT_QUEUE);
805         if (r < 0) {
806                 log_error("Failed to register name: %s", strerror(-r));
807                 return r;
808         }
809
810         bus_list_names(m, bus);
811
812         log_debug("Successfully connected to API bus.");
813         return 0;
814 }
815
816 static int bus_init_api(Manager *m) {
817         _cleanup_bus_unref_ sd_bus *bus = NULL;
818         int r;
819
820         if (m->api_bus)
821                 return 0;
822
823         /* The API and system bus is the same if we are running in system mode */
824         if (m->running_as == SYSTEMD_SYSTEM && m->system_bus)
825                 bus = sd_bus_ref(m->system_bus);
826         else {
827                 if (m->running_as == SYSTEMD_SYSTEM)
828                         r = sd_bus_open_system(&bus);
829                 else
830                         r = sd_bus_open_user(&bus);
831
832                 if (r < 0) {
833                         log_debug("Failed to connect to API bus, retrying later...");
834                         return 0;
835                 }
836
837                 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
838                 if (r < 0) {
839                         log_error("Failed to attach API bus to event loop: %s", strerror(-r));
840                         return 0;
841                 }
842
843                 r = bus_setup_disconnected_match(m, bus);
844                 if (r < 0)
845                         return 0;
846         }
847
848         r = bus_setup_api(m, bus);
849         if (r < 0) {
850                 log_error("Failed to set up API bus: %s", strerror(-r));
851                 return 0;
852         }
853
854         m->api_bus = bus;
855         bus = NULL;
856
857         return 0;
858 }
859
860 static int bus_setup_system(Manager *m, sd_bus *bus) {
861         int r;
862
863         assert(m);
864         assert(bus);
865
866         if (m->running_as == SYSTEMD_SYSTEM)
867                 return 0;
868
869         /* If we are a user instance we get the Released message via
870          * the system bus */
871         r = sd_bus_add_match(
872                         bus,
873                         "type='signal',"
874                         "interface='org.freedesktop.systemd1.Agent',"
875                         "member='Released',"
876                         "path='/org/freedesktop/systemd1/agent'",
877                         signal_agent_released, m);
878
879         if (r < 0)
880                 log_warning("Failed to register Released match on system bus: %s", strerror(-r));
881
882         log_debug("Successfully connected to system bus.");
883         return 0;
884 }
885
886 static int bus_init_system(Manager *m) {
887         _cleanup_bus_unref_ sd_bus *bus = NULL;
888         int r;
889
890         if (m->system_bus)
891                 return 0;
892
893         /* The API and system bus is the same if we are running in system mode */
894         if (m->running_as == SYSTEMD_SYSTEM && m->api_bus) {
895                 m->system_bus = sd_bus_ref(m->api_bus);
896                 return 0;
897         }
898
899         r = sd_bus_open_system(&bus);
900         if (r < 0) {
901                 log_debug("Failed to connect to system bus, retrying later...");
902                 return 0;
903         }
904
905         r = bus_setup_disconnected_match(m, bus);
906         if (r < 0)
907                 return 0;
908
909         r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
910         if (r < 0) {
911                 log_error("Failed to attach system bus to event loop: %s", strerror(-r));
912                 return 0;
913         }
914
915         r = bus_setup_system(m, bus);
916         if (r < 0) {
917                 log_error("Fauiled to set up system bus: %s", strerror(-r));
918                 return 0;
919         }
920
921         m->system_bus = bus;
922         bus = NULL;
923
924         return 0;
925 }
926
927 static int bus_init_private(Manager *m) {
928         _cleanup_close_ int fd = -1;
929         union sockaddr_union sa = {
930                 .un.sun_family = AF_UNIX
931         };
932         sd_event_source *s;
933         socklen_t salen;
934         int r;
935
936         assert(m);
937
938         if (m->private_listen_fd >= 0)
939                 return 0;
940
941         if (m->running_as == SYSTEMD_SYSTEM) {
942
943                 /* We want the private bus only when running as init */
944                 if (getpid() != 1)
945                         return 0;
946
947                 strcpy(sa.un.sun_path, "/run/systemd/private");
948                 salen = offsetof(union sockaddr_union, un.sun_path) + sizeof("/run/systemd/private") - 1;
949         } else {
950                 size_t left = sizeof(sa.un.sun_path);
951                 char *p = sa.un.sun_path;
952                 const char *e;
953
954                 e = secure_getenv("XDG_RUNTIME_DIR");
955                 if (!e) {
956                         log_error("Failed to determine XDG_RUNTIME_DIR");
957                         return -EHOSTDOWN;
958                 }
959
960                 left = strpcpy(&p, left, e);
961                 left = strpcpy(&p, left, "/systemd/private");
962
963                 salen = sizeof(sa.un) - left;
964
965                 mkdir_parents_label(sa.un.sun_path, 0755);
966         }
967
968         unlink(sa.un.sun_path);
969
970         fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
971         if (fd < 0) {
972                 log_error("Failed to allocate private socket: %m");
973                 return -errno;
974         }
975
976         r = bind(fd, &sa.sa, salen);
977         if (r < 0) {
978                 log_error("Failed to bind private socket: %m");
979                 return -errno;
980         }
981
982         r = listen(fd, SOMAXCONN);
983         if (r < 0) {
984                 log_error("Failed to make private socket listening: %m");
985                 return -errno;
986         }
987
988         r = sd_event_add_io(m->event, fd, EPOLLIN, bus_on_connection, m, &s);
989         if (r < 0) {
990                 log_error("Failed to allocate event source: %s", strerror(-r));
991                 return r;
992         }
993
994         m->private_listen_fd = fd;
995         m->private_listen_event_source = s;
996         fd = -1;
997
998         log_debug("Successfully created private D-Bus server.");
999
1000         return 0;
1001 }
1002
1003 int bus_init(Manager *m, bool try_bus_connect) {
1004         int r;
1005
1006         if (try_bus_connect) {
1007                 r = bus_init_system(m);
1008                 if (r < 0)
1009                         return r;
1010
1011                 r = bus_init_api(m);
1012                 if (r < 0)
1013                         return r;
1014         }
1015
1016         r = bus_init_private(m);
1017         if (r < 0)
1018                 return r;
1019
1020         return 0;
1021 }
1022
1023 static void destroy_bus(Manager *m, sd_bus **bus) {
1024         Iterator i;
1025         Job *j;
1026
1027         assert(m);
1028         assert(bus);
1029
1030         if (!*bus)
1031                 return;
1032
1033         /* Get rid of tracked clients on this bus */
1034         bus_client_untrack_bus(m->subscribed, *bus);
1035         HASHMAP_FOREACH(j, m->jobs, i)
1036                 bus_client_untrack_bus(j->subscribed, *bus);
1037
1038         /* Get rid of queued message on this bus */
1039         if (m->queued_message_bus == *bus) {
1040                 m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
1041
1042                 if (m->queued_message)
1043                         m->queued_message = sd_bus_message_unref(m->queued_message);
1044         }
1045
1046         /* Possibly flush unwritten data, but only if we are
1047          * unprivileged, since we don't want to sync here */
1048         if (m->running_as != SYSTEMD_SYSTEM)
1049                 sd_bus_flush(*bus);
1050
1051         /* And destroy the object */
1052         sd_bus_close(*bus);
1053         *bus = sd_bus_unref(*bus);
1054 }
1055
1056 void bus_done(Manager *m) {
1057         sd_bus *b;
1058
1059         assert(m);
1060
1061         if (m->api_bus)
1062                 destroy_bus(m, &m->api_bus);
1063         if (m->system_bus)
1064                 destroy_bus(m, &m->system_bus);
1065         while ((b = set_steal_first(m->private_buses)))
1066                 destroy_bus(m, &b);
1067
1068         set_free(m->private_buses);
1069         set_free(m->subscribed);
1070
1071         if (m->private_listen_event_source)
1072                 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
1073
1074         if (m->private_listen_fd >= 0) {
1075                 close_nointr_nofail(m->private_listen_fd);
1076                 m->private_listen_fd = -1;
1077         }
1078 }
1079
1080 int bus_fdset_add_all(Manager *m, FDSet *fds) {
1081         Iterator i;
1082         sd_bus *b;
1083         int fd;
1084
1085         assert(m);
1086         assert(fds);
1087
1088         /* When we are about to reexecute we add all D-Bus fds to the
1089          * set to pass over to the newly executed systemd. They won't
1090          * be used there however, except thatt they are closed at the
1091          * very end of deserialization, those making it possible for
1092          * clients to synchronously wait for systemd to reexec by
1093          * simply waiting for disconnection */
1094
1095         if (m->api_bus) {
1096                 fd = sd_bus_get_fd(m->api_bus);
1097                 if (fd >= 0) {
1098                         fd = fdset_put_dup(fds, fd);
1099                         if (fd < 0)
1100                                 return fd;
1101                 }
1102         }
1103
1104         SET_FOREACH(b, m->private_buses, i) {
1105                 fd = sd_bus_get_fd(b);
1106                 if (fd >= 0) {
1107                         fd = fdset_put_dup(fds, fd);
1108                         if (fd < 0)
1109                                 return fd;
1110                 }
1111         }
1112
1113         /* We don't offer any APIs on the system bus (well, unless it
1114          * is the same as the API bus) hence we don't bother with it
1115          * here */
1116
1117         return 0;
1118 }
1119
1120 void bus_serialize(Manager *m, FILE *f) {
1121         assert(m);
1122         assert(f);
1123
1124         bus_client_track_serialize(m, f, m->subscribed);
1125 }
1126
1127 int bus_deserialize_item(Manager *m, const char *line) {
1128         assert(m);
1129         assert(line);
1130
1131         return bus_client_track_deserialize_item(m, &m->subscribed, line);
1132 }