chiark / gitweb /
systemctl: when "systemctl status" is called without arguments show a short overall...
[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(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 #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(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, 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, "/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, "/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, "/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, "/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, "/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, "/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, "/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, "/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, "/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, "/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                         "sender='org.freedesktop.DBus.Local',"
626                         "type='signal',"
627                         "path='/org/freedesktop/DBus/Local',"
628                         "interface='org.freedesktop.DBus.Local',"
629                         "member='Disconnected'",
630                         signal_disconnected, m);
631
632         if (r < 0) {
633                 log_error("Failed to register match for Disconnected message: %s", strerror(-r));
634                 return r;
635         }
636
637         return 0;
638 }
639
640 static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
641         _cleanup_bus_unref_ sd_bus *bus = NULL;
642         _cleanup_close_ int nfd = -1;
643         Manager *m = userdata;
644         sd_id128_t id;
645         int r;
646
647         assert(s);
648         assert(m);
649
650         nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
651         if (nfd < 0) {
652                 log_warning("Failed to accept private connection, ignoring: %m");
653                 return 0;
654         }
655
656         if (set_size(m->private_buses) >= CONNECTIONS_MAX) {
657                 log_warning("Too many concurrent connections, refusing");
658                 return 0;
659         }
660
661         r = set_ensure_allocated(&m->private_buses, trivial_hash_func, trivial_compare_func);
662         if (r < 0) {
663                 log_oom();
664                 return 0;
665         }
666
667         r = sd_bus_new(&bus);
668         if (r < 0) {
669                 log_warning("Failed to allocate new private connection bus: %s", strerror(-r));
670                 return 0;
671         }
672
673         r = sd_bus_set_fd(bus, nfd, nfd);
674         if (r < 0) {
675                 log_warning("Failed to set fd on new connection bus: %s", strerror(-r));
676                 return 0;
677         }
678
679         nfd = -1;
680
681         r = bus_check_peercred(bus);
682         if (r < 0) {
683                 log_warning("Incoming private connection from unprivileged client, refusing: %s", strerror(-r));
684                 return 0;
685         }
686
687         assert_se(sd_id128_randomize(&id) >= 0);
688
689         r = sd_bus_set_server(bus, 1, id);
690         if (r < 0) {
691                 log_warning("Failed to enable server support for new connection bus: %s", strerror(-r));
692                 return 0;
693         }
694
695         r = sd_bus_start(bus);
696         if (r < 0) {
697                 log_warning("Failed to start new connection bus: %s", strerror(-r));
698                 return 0;
699         }
700
701         r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
702         if (r < 0) {
703                 log_warning("Failed to attach new connection bus to event loop: %s", strerror(-r));
704                 return 0;
705         }
706
707         if (m->running_as == SYSTEMD_SYSTEM) {
708                 /* When we run as system instance we get the Released
709                  * signal via a direct connection */
710
711                 r = sd_bus_add_match(
712                                 bus,
713                                 "type='signal',"
714                                 "interface='org.freedesktop.systemd1.Agent',"
715                                 "member='Released',"
716                                 "path='/org/freedesktop/systemd1/agent'",
717                                 signal_agent_released, m);
718
719                 if (r < 0) {
720                         log_warning("Failed to register Released match on new connection bus: %s", strerror(-r));
721                         return 0;
722                 }
723         }
724
725         r = bus_setup_disconnected_match(m, bus);
726         if (r < 0)
727                 return 0;
728
729         r = bus_setup_api_vtables(m, bus);
730         if (r < 0) {
731                 log_warning("Failed to set up API vtables on new connection bus: %s", strerror(-r));
732                 return 0;
733         }
734
735         r = set_put(m->private_buses, bus);
736         if (r < 0) {
737                 log_warning("Failed to add new conenction bus to set: %s", strerror(-r));
738                 return 0;
739         }
740
741         bus = NULL;
742
743         log_debug("Accepted new private connection.");
744
745         return 0;
746 }
747
748 static int bus_list_names(Manager *m, sd_bus *bus) {
749         _cleanup_strv_free_ char **names = NULL;
750         char **i;
751         int r;
752
753         assert(m);
754         assert(bus);
755
756         r = sd_bus_list_names(bus, &names, NULL);
757         if (r < 0) {
758                 log_error("Failed to get initial list of names: %s", strerror(-r));
759                 return r;
760         }
761
762         /* This is a bit hacky, we say the owner of the name is the
763          * name itself, because we don't want the extra traffic to
764          * figure out the real owner. */
765         STRV_FOREACH(i, names)
766                 manager_dispatch_bus_name_owner_changed(m, *i, NULL, *i);
767
768         return 0;
769 }
770
771 static int bus_setup_api(Manager *m, sd_bus *bus) {
772         int r;
773
774         assert(m);
775         assert(bus);
776
777         r = bus_setup_api_vtables(m, bus);
778         if (r < 0)
779                 return r;
780
781         r = sd_bus_add_match(
782                         bus,
783                         "type='signal',"
784                         "sender='org.freedesktop.DBus',"
785                         "path='/org/freedesktop/DBus',"
786                         "interface='org.freedesktop.DBus',"
787                         "member='NameOwnerChanged'",
788                         signal_name_owner_changed, m);
789         if (r < 0)
790                 log_warning("Failed to subscribe to NameOwnerChanged signal: %s", strerror(-r));
791
792         r = sd_bus_add_match(
793                         bus,
794                         "type='signal',"
795                         "sender='org.freedesktop.DBus',"
796                         "path='/org/freedesktop/DBus',"
797                         "interface='org.freedesktop.systemd1.Activator',"
798                         "member='ActivationRequest'",
799                         signal_activation_request, m);
800         if (r < 0)
801                 log_warning("Failed to subscribe to activation signal: %s", strerror(-r));
802
803         /* Allow replacing of our name, to ease implementation of
804          * reexecution, where we keep the old connection open until
805          * after the new connection is set up and the name installed
806          * to allow clients to synchronously wait for reexecution to
807          * finish */
808         r = sd_bus_request_name(bus,"org.freedesktop.systemd1", SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_ALLOW_REPLACEMENT);
809         if (r < 0) {
810                 log_error("Failed to register name: %s", strerror(-r));
811                 return r;
812         }
813
814         bus_list_names(m, bus);
815
816         log_debug("Successfully connected to API bus.");
817         return 0;
818 }
819
820 static int bus_init_api(Manager *m) {
821         _cleanup_bus_unref_ sd_bus *bus = NULL;
822         int r;
823
824         if (m->api_bus)
825                 return 0;
826
827         /* The API and system bus is the same if we are running in system mode */
828         if (m->running_as == SYSTEMD_SYSTEM && m->system_bus)
829                 bus = sd_bus_ref(m->system_bus);
830         else {
831                 if (m->running_as == SYSTEMD_SYSTEM)
832                         r = sd_bus_open_system(&bus);
833                 else
834                         r = sd_bus_open_user(&bus);
835
836                 if (r < 0) {
837                         log_debug("Failed to connect to API bus, retrying later...");
838                         return 0;
839                 }
840
841                 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
842                 if (r < 0) {
843                         log_error("Failed to attach API bus to event loop: %s", strerror(-r));
844                         return 0;
845                 }
846
847                 r = bus_setup_disconnected_match(m, bus);
848                 if (r < 0)
849                         return 0;
850         }
851
852         r = bus_setup_api(m, bus);
853         if (r < 0) {
854                 log_error("Failed to set up API bus: %s", strerror(-r));
855                 return 0;
856         }
857
858         m->api_bus = bus;
859         bus = NULL;
860
861         return 0;
862 }
863
864 static int bus_setup_system(Manager *m, sd_bus *bus) {
865         int r;
866
867         assert(m);
868         assert(bus);
869
870         if (m->running_as == SYSTEMD_SYSTEM)
871                 return 0;
872
873         /* If we are a user instance we get the Released message via
874          * the system bus */
875         r = sd_bus_add_match(
876                         bus,
877                         "type='signal',"
878                         "interface='org.freedesktop.systemd1.Agent',"
879                         "member='Released',"
880                         "path='/org/freedesktop/systemd1/agent'",
881                         signal_agent_released, m);
882
883         if (r < 0)
884                 log_warning("Failed to register Released match on system bus: %s", strerror(-r));
885
886         log_debug("Successfully connected to system bus.");
887         return 0;
888 }
889
890 static int bus_init_system(Manager *m) {
891         _cleanup_bus_unref_ sd_bus *bus = NULL;
892         int r;
893
894         if (m->system_bus)
895                 return 0;
896
897         /* The API and system bus is the same if we are running in system mode */
898         if (m->running_as == SYSTEMD_SYSTEM && m->api_bus) {
899                 m->system_bus = sd_bus_ref(m->api_bus);
900                 return 0;
901         }
902
903         r = sd_bus_open_system(&bus);
904         if (r < 0) {
905                 log_debug("Failed to connect to system bus, retrying later...");
906                 return 0;
907         }
908
909         r = bus_setup_disconnected_match(m, bus);
910         if (r < 0)
911                 return 0;
912
913         r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
914         if (r < 0) {
915                 log_error("Failed to attach system bus to event loop: %s", strerror(-r));
916                 return 0;
917         }
918
919         r = bus_setup_system(m, bus);
920         if (r < 0) {
921                 log_error("Fauiled to set up system bus: %s", strerror(-r));
922                 return 0;
923         }
924
925         m->system_bus = bus;
926         bus = NULL;
927
928         return 0;
929 }
930
931 static int bus_init_private(Manager *m) {
932         _cleanup_close_ int fd = -1;
933         union sockaddr_union sa = {
934                 .un.sun_family = AF_UNIX
935         };
936         sd_event_source *s;
937         socklen_t salen;
938         int r;
939
940         assert(m);
941
942         if (m->private_listen_fd >= 0)
943                 return 0;
944
945         /* We don't need the private socket if we have kdbus */
946         if (m->kdbus_fd >= 0)
947                 return 0;
948
949         if (m->running_as == SYSTEMD_SYSTEM) {
950
951                 /* We want the private bus only when running as init */
952                 if (getpid() != 1)
953                         return 0;
954
955                 strcpy(sa.un.sun_path, "/run/systemd/private");
956                 salen = offsetof(union sockaddr_union, un.sun_path) + sizeof("/run/systemd/private") - 1;
957         } else {
958                 size_t left = sizeof(sa.un.sun_path);
959                 char *p = sa.un.sun_path;
960                 const char *e;
961
962                 e = secure_getenv("XDG_RUNTIME_DIR");
963                 if (!e) {
964                         log_error("Failed to determine XDG_RUNTIME_DIR");
965                         return -EHOSTDOWN;
966                 }
967
968                 left = strpcpy(&p, left, e);
969                 left = strpcpy(&p, left, "/systemd/private");
970
971                 salen = sizeof(sa.un) - left;
972
973                 mkdir_parents_label(sa.un.sun_path, 0755);
974         }
975
976         unlink(sa.un.sun_path);
977
978         fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
979         if (fd < 0) {
980                 log_error("Failed to allocate private socket: %m");
981                 return -errno;
982         }
983
984         r = bind(fd, &sa.sa, salen);
985         if (r < 0) {
986                 log_error("Failed to bind private socket: %m");
987                 return -errno;
988         }
989
990         r = listen(fd, SOMAXCONN);
991         if (r < 0) {
992                 log_error("Failed to make private socket listening: %m");
993                 return -errno;
994         }
995
996         r = sd_event_add_io(m->event, &s, fd, EPOLLIN, bus_on_connection, m);
997         if (r < 0) {
998                 log_error("Failed to allocate event source: %s", strerror(-r));
999                 return r;
1000         }
1001
1002         m->private_listen_fd = fd;
1003         m->private_listen_event_source = s;
1004         fd = -1;
1005
1006         log_debug("Successfully created private D-Bus server.");
1007
1008         return 0;
1009 }
1010
1011 int bus_init(Manager *m, bool try_bus_connect) {
1012         int r;
1013
1014         if (try_bus_connect) {
1015                 r = bus_init_system(m);
1016                 if (r < 0)
1017                         return r;
1018
1019                 r = bus_init_api(m);
1020                 if (r < 0)
1021                         return r;
1022         }
1023
1024         r = bus_init_private(m);
1025         if (r < 0)
1026                 return r;
1027
1028         return 0;
1029 }
1030
1031 static void destroy_bus(Manager *m, sd_bus **bus) {
1032         Iterator i;
1033         Job *j;
1034
1035         assert(m);
1036         assert(bus);
1037
1038         if (!*bus)
1039                 return;
1040
1041         /* Get rid of tracked clients on this bus */
1042         if (m->subscribed && sd_bus_track_get_bus(m->subscribed) == *bus)
1043                 m->subscribed = sd_bus_track_unref(m->subscribed);
1044
1045         HASHMAP_FOREACH(j, m->jobs, i)
1046                 if (j->subscribed && sd_bus_track_get_bus(j->subscribed) == *bus)
1047                         j->subscribed = sd_bus_track_unref(j->subscribed);
1048
1049         /* Get rid of queued message on this bus */
1050         if (m->queued_message_bus == *bus) {
1051                 m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
1052
1053                 if (m->queued_message)
1054                         m->queued_message = sd_bus_message_unref(m->queued_message);
1055         }
1056
1057         /* Possibly flush unwritten data, but only if we are
1058          * unprivileged, since we don't want to sync here */
1059         if (m->running_as != SYSTEMD_SYSTEM)
1060                 sd_bus_flush(*bus);
1061
1062         /* And destroy the object */
1063         sd_bus_close(*bus);
1064         *bus = sd_bus_unref(*bus);
1065 }
1066
1067 void bus_done(Manager *m) {
1068         sd_bus *b;
1069
1070         assert(m);
1071
1072         if (m->api_bus)
1073                 destroy_bus(m, &m->api_bus);
1074         if (m->system_bus)
1075                 destroy_bus(m, &m->system_bus);
1076         while ((b = set_steal_first(m->private_buses)))
1077                 destroy_bus(m, &b);
1078
1079         set_free(m->private_buses);
1080         m->private_buses = NULL;
1081
1082         m->subscribed = sd_bus_track_unref(m->subscribed);
1083         strv_free(m->deserialized_subscribed);
1084         m->deserialized_subscribed = NULL;
1085
1086         if (m->private_listen_event_source)
1087                 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
1088
1089         if (m->private_listen_fd >= 0) {
1090                 close_nointr_nofail(m->private_listen_fd);
1091                 m->private_listen_fd = -1;
1092         }
1093 }
1094
1095 int bus_fdset_add_all(Manager *m, FDSet *fds) {
1096         Iterator i;
1097         sd_bus *b;
1098         int fd;
1099
1100         assert(m);
1101         assert(fds);
1102
1103         /* When we are about to reexecute we add all D-Bus fds to the
1104          * set to pass over to the newly executed systemd. They won't
1105          * be used there however, except thatt they are closed at the
1106          * very end of deserialization, those making it possible for
1107          * clients to synchronously wait for systemd to reexec by
1108          * simply waiting for disconnection */
1109
1110         if (m->api_bus) {
1111                 fd = sd_bus_get_fd(m->api_bus);
1112                 if (fd >= 0) {
1113                         fd = fdset_put_dup(fds, fd);
1114                         if (fd < 0)
1115                                 return fd;
1116                 }
1117         }
1118
1119         SET_FOREACH(b, m->private_buses, i) {
1120                 fd = sd_bus_get_fd(b);
1121                 if (fd >= 0) {
1122                         fd = fdset_put_dup(fds, fd);
1123                         if (fd < 0)
1124                                 return fd;
1125                 }
1126         }
1127
1128         /* We don't offer any APIs on the system bus (well, unless it
1129          * is the same as the API bus) hence we don't bother with it
1130          * here */
1131
1132         return 0;
1133 }
1134
1135 int bus_foreach_bus(
1136                 Manager *m,
1137                 sd_bus_track *subscribed2,
1138                 int (*send_message)(sd_bus *bus, void *userdata),
1139                 void *userdata) {
1140
1141         Iterator i;
1142         sd_bus *b;
1143         int r, ret = 0;
1144
1145         /* Send to all direct busses, unconditionally */
1146         SET_FOREACH(b, m->private_buses, i) {
1147                 r = send_message(b, userdata);
1148                 if (r < 0)
1149                         ret = r;
1150         }
1151
1152         /* Send to API bus, but only if somebody is subscribed */
1153         if (sd_bus_track_count(m->subscribed) > 0 ||
1154             sd_bus_track_count(subscribed2) > 0) {
1155                 r = send_message(m->api_bus, userdata);
1156                 if (r < 0)
1157                         ret = r;
1158         }
1159
1160         return ret;
1161 }
1162
1163 void bus_track_serialize(sd_bus_track *t, FILE *f) {
1164         const char *n;
1165
1166         assert(f);
1167
1168         for (n = sd_bus_track_first(t); n; n = sd_bus_track_next(t))
1169                 fprintf(f, "subscribed=%s\n", n);
1170 }
1171
1172 int bus_track_deserialize_item(char ***l, const char *line) {
1173         const char *e;
1174
1175         assert(l);
1176         assert(line);
1177
1178         e = startswith(line, "subscribed=");
1179         if (!e)
1180                 return 0;
1181
1182         return strv_extend(l, e);
1183 }
1184
1185 int bus_track_coldplug(Manager *m, sd_bus_track **t, char ***l) {
1186         int r = 0;
1187
1188         assert(m);
1189         assert(t);
1190         assert(l);
1191
1192         if (!strv_isempty(*l) && m->api_bus) {
1193                 char **i;
1194
1195                 if (!*t) {
1196                         r = sd_bus_track_new(m->api_bus, t, NULL, NULL);
1197                         if (r < 0)
1198                                 return r;
1199                 }
1200
1201                 r = 0;
1202                 STRV_FOREACH(i, *l) {
1203                         int k;
1204
1205                         k = sd_bus_track_add_name(*t, *i);
1206                         if (k < 0)
1207                                 r = k;
1208                 }
1209         }
1210
1211         strv_free(*l);
1212         *l = NULL;
1213
1214         return r;
1215 }