chiark / gitweb /
dbus: return non-zero return value in the case that prefix won't match
[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 mac_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 = mac_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 = mac_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, mac_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, NULL);
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
979         (void) mkdir_parents_label(sa.un.sun_path, 0755);
980         (void) unlink(sa.un.sun_path);
981
982         fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
983         if (fd < 0) {
984                 log_error("Failed to allocate private socket: %m");
985                 return -errno;
986         }
987
988         r = bind(fd, &sa.sa, salen);
989         if (r < 0) {
990                 log_error("Failed to bind private socket: %m");
991                 return -errno;
992         }
993
994         r = listen(fd, SOMAXCONN);
995         if (r < 0) {
996                 log_error("Failed to make private socket listening: %m");
997                 return -errno;
998         }
999
1000         r = sd_event_add_io(m->event, &s, fd, EPOLLIN, bus_on_connection, m);
1001         if (r < 0) {
1002                 log_error("Failed to allocate event source: %s", strerror(-r));
1003                 return r;
1004         }
1005
1006         m->private_listen_fd = fd;
1007         m->private_listen_event_source = s;
1008         fd = -1;
1009
1010         log_debug("Successfully created private D-Bus server.");
1011
1012         return 0;
1013 }
1014
1015 int bus_init(Manager *m, bool try_bus_connect) {
1016         int r;
1017
1018         if (try_bus_connect) {
1019                 r = bus_init_system(m);
1020                 if (r < 0)
1021                         return r;
1022
1023                 r = bus_init_api(m);
1024                 if (r < 0)
1025                         return r;
1026         }
1027
1028         r = bus_init_private(m);
1029         if (r < 0)
1030                 return r;
1031
1032         return 0;
1033 }
1034
1035 static void destroy_bus(Manager *m, sd_bus **bus) {
1036         Iterator i;
1037         Job *j;
1038
1039         assert(m);
1040         assert(bus);
1041
1042         if (!*bus)
1043                 return;
1044
1045         /* Get rid of tracked clients on this bus */
1046         if (m->subscribed && sd_bus_track_get_bus(m->subscribed) == *bus)
1047                 m->subscribed = sd_bus_track_unref(m->subscribed);
1048
1049         HASHMAP_FOREACH(j, m->jobs, i)
1050                 if (j->clients && sd_bus_track_get_bus(j->clients) == *bus)
1051                         j->clients = sd_bus_track_unref(j->clients);
1052
1053         /* Get rid of queued message on this bus */
1054         if (m->queued_message_bus == *bus) {
1055                 m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
1056
1057                 if (m->queued_message)
1058                         m->queued_message = sd_bus_message_unref(m->queued_message);
1059         }
1060
1061         /* Possibly flush unwritten data, but only if we are
1062          * unprivileged, since we don't want to sync here */
1063         if (m->running_as != SYSTEMD_SYSTEM)
1064                 sd_bus_flush(*bus);
1065
1066         /* And destroy the object */
1067         sd_bus_close(*bus);
1068         *bus = sd_bus_unref(*bus);
1069 }
1070
1071 void bus_done(Manager *m) {
1072         sd_bus *b;
1073
1074         assert(m);
1075
1076         if (m->api_bus)
1077                 destroy_bus(m, &m->api_bus);
1078         if (m->system_bus)
1079                 destroy_bus(m, &m->system_bus);
1080         while ((b = set_steal_first(m->private_buses)))
1081                 destroy_bus(m, &b);
1082
1083         set_free(m->private_buses);
1084         m->private_buses = NULL;
1085
1086         m->subscribed = sd_bus_track_unref(m->subscribed);
1087         strv_free(m->deserialized_subscribed);
1088         m->deserialized_subscribed = NULL;
1089
1090         if (m->private_listen_event_source)
1091                 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
1092
1093         m->private_listen_fd = safe_close(m->private_listen_fd);
1094
1095         bus_verify_polkit_async_registry_free(m->polkit_registry);
1096 }
1097
1098 int bus_fdset_add_all(Manager *m, FDSet *fds) {
1099         Iterator i;
1100         sd_bus *b;
1101         int fd;
1102
1103         assert(m);
1104         assert(fds);
1105
1106         /* When we are about to reexecute we add all D-Bus fds to the
1107          * set to pass over to the newly executed systemd. They won't
1108          * be used there however, except thatt they are closed at the
1109          * very end of deserialization, those making it possible for
1110          * clients to synchronously wait for systemd to reexec by
1111          * simply waiting for disconnection */
1112
1113         if (m->api_bus) {
1114                 fd = sd_bus_get_fd(m->api_bus);
1115                 if (fd >= 0) {
1116                         fd = fdset_put_dup(fds, fd);
1117                         if (fd < 0)
1118                                 return fd;
1119                 }
1120         }
1121
1122         SET_FOREACH(b, m->private_buses, i) {
1123                 fd = sd_bus_get_fd(b);
1124                 if (fd >= 0) {
1125                         fd = fdset_put_dup(fds, fd);
1126                         if (fd < 0)
1127                                 return fd;
1128                 }
1129         }
1130
1131         /* We don't offer any APIs on the system bus (well, unless it
1132          * is the same as the API bus) hence we don't bother with it
1133          * here */
1134
1135         return 0;
1136 }
1137
1138 int bus_foreach_bus(
1139                 Manager *m,
1140                 sd_bus_track *subscribed2,
1141                 int (*send_message)(sd_bus *bus, void *userdata),
1142                 void *userdata) {
1143
1144         Iterator i;
1145         sd_bus *b;
1146         int r, ret = 0;
1147
1148         /* Send to all direct busses, unconditionally */
1149         SET_FOREACH(b, m->private_buses, i) {
1150                 r = send_message(b, userdata);
1151                 if (r < 0)
1152                         ret = r;
1153         }
1154
1155         /* Send to API bus, but only if somebody is subscribed */
1156         if (sd_bus_track_count(m->subscribed) > 0 ||
1157             sd_bus_track_count(subscribed2) > 0) {
1158                 r = send_message(m->api_bus, userdata);
1159                 if (r < 0)
1160                         ret = r;
1161         }
1162
1163         return ret;
1164 }
1165
1166 void bus_track_serialize(sd_bus_track *t, FILE *f) {
1167         const char *n;
1168
1169         assert(f);
1170
1171         for (n = sd_bus_track_first(t); n; n = sd_bus_track_next(t))
1172                 fprintf(f, "subscribed=%s\n", n);
1173 }
1174
1175 int bus_track_deserialize_item(char ***l, const char *line) {
1176         const char *e;
1177
1178         assert(l);
1179         assert(line);
1180
1181         e = startswith(line, "subscribed=");
1182         if (!e)
1183                 return -EINVAL;
1184
1185         return strv_extend(l, e);
1186 }
1187
1188 int bus_track_coldplug(Manager *m, sd_bus_track **t, char ***l) {
1189         int r = 0;
1190
1191         assert(m);
1192         assert(t);
1193         assert(l);
1194
1195         if (!strv_isempty(*l) && m->api_bus) {
1196                 char **i;
1197
1198                 if (!*t) {
1199                         r = sd_bus_track_new(m->api_bus, t, NULL, NULL);
1200                         if (r < 0)
1201                                 return r;
1202                 }
1203
1204                 r = 0;
1205                 STRV_FOREACH(i, *l) {
1206                         int k;
1207
1208                         k = sd_bus_track_add_name(*t, *i);
1209                         if (k < 0)
1210                                 r = k;
1211                 }
1212         }
1213
1214         strv_free(*l);
1215         *l = NULL;
1216
1217         return r;
1218 }
1219
1220 int bus_verify_manage_unit_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
1221         return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-units", false, &m->polkit_registry, error);
1222 }
1223
1224 /* Same as bus_verify_manage_unit_async(), but checks for CAP_KILL instead of CAP_SYS_ADMIN */
1225 int bus_verify_manage_unit_async_for_kill(Manager *m, sd_bus_message *call, sd_bus_error *error) {
1226         return bus_verify_polkit_async(call, CAP_KILL, "org.freedesktop.systemd1.manage-units", false, &m->polkit_registry, error);
1227 }
1228
1229 int bus_verify_manage_unit_files_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
1230         return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-unit-files", false, &m->polkit_registry, error);
1231 }
1232
1233 int bus_verify_reload_daemon_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
1234         return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.reload-daemon", false, &m->polkit_registry, error);
1235 }