chiark / gitweb /
bus: properly return an error when we detect a method call timeout
[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|SD_BUS_NAME_ALLOW_REPLACEMENT);
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         /* We don't need the private socket if we have kdbus */
942         if (m->kdbus_fd >= 0)
943                 return 0;
944
945         if (m->running_as == SYSTEMD_SYSTEM) {
946
947                 /* We want the private bus only when running as init */
948                 if (getpid() != 1)
949                         return 0;
950
951                 strcpy(sa.un.sun_path, "/run/systemd/private");
952                 salen = offsetof(union sockaddr_union, un.sun_path) + sizeof("/run/systemd/private") - 1;
953         } else {
954                 size_t left = sizeof(sa.un.sun_path);
955                 char *p = sa.un.sun_path;
956                 const char *e;
957
958                 e = secure_getenv("XDG_RUNTIME_DIR");
959                 if (!e) {
960                         log_error("Failed to determine XDG_RUNTIME_DIR");
961                         return -EHOSTDOWN;
962                 }
963
964                 left = strpcpy(&p, left, e);
965                 left = strpcpy(&p, left, "/systemd/private");
966
967                 salen = sizeof(sa.un) - left;
968
969                 mkdir_parents_label(sa.un.sun_path, 0755);
970         }
971
972         unlink(sa.un.sun_path);
973
974         fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
975         if (fd < 0) {
976                 log_error("Failed to allocate private socket: %m");
977                 return -errno;
978         }
979
980         r = bind(fd, &sa.sa, salen);
981         if (r < 0) {
982                 log_error("Failed to bind private socket: %m");
983                 return -errno;
984         }
985
986         r = listen(fd, SOMAXCONN);
987         if (r < 0) {
988                 log_error("Failed to make private socket listening: %m");
989                 return -errno;
990         }
991
992         r = sd_event_add_io(m->event, fd, EPOLLIN, bus_on_connection, m, &s);
993         if (r < 0) {
994                 log_error("Failed to allocate event source: %s", strerror(-r));
995                 return r;
996         }
997
998         m->private_listen_fd = fd;
999         m->private_listen_event_source = s;
1000         fd = -1;
1001
1002         log_debug("Successfully created private D-Bus server.");
1003
1004         return 0;
1005 }
1006
1007 int bus_init(Manager *m, bool try_bus_connect) {
1008         int r;
1009
1010         if (try_bus_connect) {
1011                 r = bus_init_system(m);
1012                 if (r < 0)
1013                         return r;
1014
1015                 r = bus_init_api(m);
1016                 if (r < 0)
1017                         return r;
1018         }
1019
1020         r = bus_init_private(m);
1021         if (r < 0)
1022                 return r;
1023
1024         return 0;
1025 }
1026
1027 static void destroy_bus(Manager *m, sd_bus **bus) {
1028         Iterator i;
1029         Job *j;
1030
1031         assert(m);
1032         assert(bus);
1033
1034         if (!*bus)
1035                 return;
1036
1037         /* Get rid of tracked clients on this bus */
1038         bus_client_untrack_bus(m->subscribed, *bus);
1039         HASHMAP_FOREACH(j, m->jobs, i)
1040                 bus_client_untrack_bus(j->subscribed, *bus);
1041
1042         /* Get rid of queued message on this bus */
1043         if (m->queued_message_bus == *bus) {
1044                 m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
1045
1046                 if (m->queued_message)
1047                         m->queued_message = sd_bus_message_unref(m->queued_message);
1048         }
1049
1050         /* Possibly flush unwritten data, but only if we are
1051          * unprivileged, since we don't want to sync here */
1052         if (m->running_as != SYSTEMD_SYSTEM)
1053                 sd_bus_flush(*bus);
1054
1055         /* And destroy the object */
1056         sd_bus_close(*bus);
1057         *bus = sd_bus_unref(*bus);
1058 }
1059
1060 void bus_done(Manager *m) {
1061         sd_bus *b;
1062
1063         assert(m);
1064
1065         if (m->api_bus)
1066                 destroy_bus(m, &m->api_bus);
1067         if (m->system_bus)
1068                 destroy_bus(m, &m->system_bus);
1069         while ((b = set_steal_first(m->private_buses)))
1070                 destroy_bus(m, &b);
1071
1072         set_free(m->private_buses);
1073         set_free(m->subscribed);
1074
1075         if (m->private_listen_event_source)
1076                 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
1077
1078         if (m->private_listen_fd >= 0) {
1079                 close_nointr_nofail(m->private_listen_fd);
1080                 m->private_listen_fd = -1;
1081         }
1082 }
1083
1084 int bus_fdset_add_all(Manager *m, FDSet *fds) {
1085         Iterator i;
1086         sd_bus *b;
1087         int fd;
1088
1089         assert(m);
1090         assert(fds);
1091
1092         /* When we are about to reexecute we add all D-Bus fds to the
1093          * set to pass over to the newly executed systemd. They won't
1094          * be used there however, except thatt they are closed at the
1095          * very end of deserialization, those making it possible for
1096          * clients to synchronously wait for systemd to reexec by
1097          * simply waiting for disconnection */
1098
1099         if (m->api_bus) {
1100                 fd = sd_bus_get_fd(m->api_bus);
1101                 if (fd >= 0) {
1102                         fd = fdset_put_dup(fds, fd);
1103                         if (fd < 0)
1104                                 return fd;
1105                 }
1106         }
1107
1108         SET_FOREACH(b, m->private_buses, i) {
1109                 fd = sd_bus_get_fd(b);
1110                 if (fd >= 0) {
1111                         fd = fdset_put_dup(fds, fd);
1112                         if (fd < 0)
1113                                 return fd;
1114                 }
1115         }
1116
1117         /* We don't offer any APIs on the system bus (well, unless it
1118          * is the same as the API bus) hence we don't bother with it
1119          * here */
1120
1121         return 0;
1122 }
1123
1124 void bus_serialize(Manager *m, FILE *f) {
1125         assert(m);
1126         assert(f);
1127
1128         bus_client_track_serialize(m, f, m->subscribed);
1129 }
1130
1131 int bus_deserialize_item(Manager *m, const char *line) {
1132         assert(m);
1133         assert(line);
1134
1135         return bus_client_track_deserialize_item(m, &m->subscribed, line);
1136 }