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