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