chiark / gitweb /
util: fix handling of trailing whitespace in split_quoted()
[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                 pid_t pid;
251
252                 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
253                 if (r < 0)
254                         return 0;
255
256                 u = manager_get_unit_by_pid(m, pid);
257         } else {
258                 r = manager_get_job_from_dbus_path(m, path, &j);
259                 if (r >= 0)
260                         u = j->unit;
261                 else
262                         manager_load_unit_from_dbus_path(m, path, NULL, &u);
263         }
264
265         if (!u)
266                 return 0;
267
268         r = selinux_unit_access_check(u, bus, message, verb, error);
269         if (r < 0)
270                 return r;
271
272         return 0;
273 }
274
275 static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
276         Manager *m = userdata;
277         Job *j;
278         int r;
279
280         assert(bus);
281         assert(path);
282         assert(interface);
283         assert(found);
284         assert(m);
285
286         r = manager_get_job_from_dbus_path(m, path, &j);
287         if (r < 0)
288                 return 0;
289
290         *found = j;
291         return 1;
292 }
293
294 static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_bus_error *error) {
295         Unit *u;
296         int r;
297
298         assert(m);
299         assert(bus);
300         assert(path);
301
302         if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
303                 sd_bus_message *message;
304                 pid_t pid;
305
306                 message = sd_bus_get_current(bus);
307                 if (!message)
308                         return 0;
309
310                 r = sd_bus_get_owner_pid(bus, sd_bus_message_get_sender(message), &pid);
311                 if (r < 0)
312                         return 0;
313
314                 u = manager_get_unit_by_pid(m, pid);
315         } else {
316                 r = manager_load_unit_from_dbus_path(m, path, error, &u);
317                 if (r < 0)
318                         return 0;
319         }
320
321         if (!u)
322                 return 0;
323
324         *unit = u;
325         return 1;
326 }
327
328 static int bus_unit_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
329         Manager *m = userdata;
330
331         assert(bus);
332         assert(path);
333         assert(interface);
334         assert(found);
335         assert(m);
336
337         return find_unit(m, bus, path, (Unit**) found, error);
338 }
339
340 static int bus_unit_interface_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
341         Manager *m = userdata;
342         Unit *u;
343         int r;
344
345         assert(bus);
346         assert(path);
347         assert(interface);
348         assert(found);
349         assert(m);
350
351         r = find_unit(m, bus, path, &u, error);
352         if (r <= 0)
353                 return r;
354
355         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
356                 return 0;
357
358         *found = u;
359         return 1;
360 }
361
362 static int bus_unit_cgroup_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
363         Manager *m = userdata;
364         Unit *u;
365         int r;
366
367         assert(bus);
368         assert(path);
369         assert(interface);
370         assert(found);
371         assert(m);
372
373         r = find_unit(m, bus, path, &u, error);
374         if (r <= 0)
375                 return r;
376
377         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
378                 return 0;
379
380         if (!unit_get_cgroup_context(u))
381                 return 0;
382
383         *found = u;
384         return 1;
385 }
386
387 static int bus_cgroup_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
388         Manager *m = userdata;
389         CGroupContext *c;
390         Unit *u;
391         int r;
392
393         assert(bus);
394         assert(path);
395         assert(interface);
396         assert(found);
397         assert(m);
398
399         r = find_unit(m, bus, path, &u, error);
400         if (r <= 0)
401                 return r;
402
403         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
404                 return 0;
405
406         c = unit_get_cgroup_context(u);
407         if (!c)
408                 return 0;
409
410         *found = c;
411         return 1;
412 }
413
414 static int bus_exec_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
415         Manager *m = userdata;
416         ExecContext *c;
417         Unit *u;
418         int r;
419
420         assert(bus);
421         assert(path);
422         assert(interface);
423         assert(found);
424         assert(m);
425
426         r = find_unit(m, bus, path, &u, error);
427         if (r <= 0)
428                 return r;
429
430         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
431                 return 0;
432
433         c = unit_get_exec_context(u);
434         if (!c)
435                 return 0;
436
437         *found = c;
438         return 1;
439 }
440
441 static int bus_kill_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
442         Manager *m = userdata;
443         KillContext *c;
444         Unit *u;
445         int r;
446
447         assert(bus);
448         assert(path);
449         assert(interface);
450         assert(found);
451         assert(m);
452
453         r = find_unit(m, bus, path, &u, error);
454         if (r <= 0)
455                 return r;
456
457         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
458                 return 0;
459
460         c = unit_get_kill_context(u);
461         if (!c)
462                 return 0;
463
464         *found = c;
465         return 1;
466 }
467
468 static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
469         _cleanup_free_ char **l = NULL;
470         Manager *m = userdata;
471         unsigned k = 0;
472         Iterator i;
473         Job *j;
474
475         l = new0(char*, hashmap_size(m->jobs)+1);
476         if (!l)
477                 return -ENOMEM;
478
479         HASHMAP_FOREACH(j, m->jobs, i) {
480                 l[k] = job_dbus_path(j);
481                 if (!l[k])
482                         return -ENOMEM;
483
484                 k++;
485         }
486
487         assert(hashmap_size(m->jobs) == k);
488
489         *nodes = l;
490         l = NULL;
491
492         return k;
493 }
494
495 static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
496         _cleanup_free_ char **l = NULL;
497         Manager *m = userdata;
498         unsigned k = 0;
499         Iterator i;
500         Unit *u;
501
502         l = new0(char*, hashmap_size(m->units)+1);
503         if (!l)
504                 return -ENOMEM;
505
506         HASHMAP_FOREACH(u, m->units, i) {
507                 l[k] = unit_dbus_path(u);
508                 if (!l[k])
509                         return -ENOMEM;
510
511                 k++;
512         }
513
514         *nodes = l;
515         l = NULL;
516
517         return k;
518 }
519
520 static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
521         UnitType t;
522         int r;
523
524         assert(m);
525         assert(bus);
526
527         r = sd_bus_add_filter(bus, selinux_filter, m);
528         if (r < 0) {
529                 log_error("Failed to add SELinux access filter: %s", strerror(-r));
530                 return r;
531         }
532
533         r = sd_bus_add_object_vtable(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
534         if (r < 0) {
535                 log_error("Failed to register Manager vtable: %s", strerror(-r));
536                 return r;
537         }
538
539         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
540         if (r < 0) {
541                 log_error("Failed to register Job vtable: %s", strerror(-r));
542                 return r;
543         }
544
545         r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
546         if (r < 0) {
547                 log_error("Failed to add job enumerator: %s", strerror(-r));
548                 return r;
549         }
550
551         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
552         if (r < 0) {
553                 log_error("Failed to register Unit vtable: %s", strerror(-r));
554                 return r;
555         }
556
557         r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
558         if (r < 0) {
559                 log_error("Failed to add job enumerator: %s", strerror(-r));
560                 return r;
561         }
562
563         for (t = 0; t < _UNIT_TYPE_MAX; t++) {
564                 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);
565                 if (r < 0)  {
566                         log_error("Failed to register type specific vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
567                         return r;
568                 }
569
570                 if (unit_vtable[t]->cgroup_context_offset > 0) {
571                         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);
572                         if (r < 0) {
573                                 log_error("Failed to register control group unit vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
574                                 return r;
575                         }
576
577                         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
578                         if (r < 0) {
579                                 log_error("Failed to register control group vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
580                                 return r;
581                         }
582                 }
583
584                 if (unit_vtable[t]->exec_context_offset > 0) {
585                         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_exec_vtable, bus_exec_context_find, m);
586                         if (r < 0) {
587                                 log_error("Failed to register execute vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
588                                 return r;
589                         }
590                 }
591
592                 if (unit_vtable[t]->kill_context_offset > 0) {
593                         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_kill_vtable, bus_kill_context_find, m);
594                         if (r < 0) {
595                                 log_error("Failed to register kill vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
596                                 return r;
597                         }
598                 }
599         }
600
601         return 0;
602 }
603
604 static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
605         int r;
606
607         assert(m);
608         assert(bus);
609
610         r = sd_bus_add_match(
611                         bus,
612                         "type='signal',"
613                         "path='/org/freedesktop/DBus/Local',"
614                         "interface='org.freedesktop.DBus.Local',"
615                         "member='Disconnected'",
616                         signal_disconnected, m);
617
618         if (r < 0) {
619                 log_error("Failed to register match for Disconnected message: %s", strerror(-r));
620                 return r;
621         }
622
623         return 0;
624 }
625
626 static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
627         _cleanup_bus_unref_ sd_bus *bus = NULL;
628         _cleanup_close_ int nfd = -1;
629         Manager *m = userdata;
630         sd_id128_t id;
631         int r;
632
633         assert(s);
634         assert(m);
635
636         nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
637         if (nfd < 0) {
638                 log_warning("Failed to accept private connection, ignoring: %m");
639                 return 0;
640         }
641
642         if (set_size(m->private_buses) >= CONNECTIONS_MAX) {
643                 log_warning("Too many concurrent connections, refusing");
644                 return 0;
645         }
646
647         r = set_ensure_allocated(&m->private_buses, trivial_hash_func, trivial_compare_func);
648         if (r < 0) {
649                 log_oom();
650                 return 0;
651         }
652
653         r = sd_bus_new(&bus);
654         if (r < 0) {
655                 log_warning("Failed to allocate new private connection bus: %s", strerror(-r));
656                 return 0;
657         }
658
659         r = sd_bus_set_fd(bus, nfd, nfd);
660         if (r < 0) {
661                 log_warning("Failed to set fd on new connection bus: %s", strerror(-r));
662                 return 0;
663         }
664
665         nfd = -1;
666
667         r = bus_check_peercred(bus);
668         if (r < 0) {
669                 log_warning("Incoming private connection from unprivileged client, refusing: %s", strerror(-r));
670                 return 0;
671         }
672
673         assert_se(sd_id128_randomize(&id) >= 0);
674
675         r = sd_bus_set_server(bus, 1, id);
676         if (r < 0) {
677                 log_warning("Failed to enable server support for new connection bus: %s", strerror(-r));
678                 return 0;
679         }
680
681         r = sd_bus_start(bus);
682         if (r < 0) {
683                 log_warning("Failed to start new connection bus: %s", strerror(-r));
684                 return 0;
685         }
686
687         r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
688         if (r < 0) {
689                 log_warning("Failed to attach new connection bus to event loop: %s", strerror(-r));
690                 return 0;
691         }
692
693         if (m->running_as == SYSTEMD_SYSTEM) {
694                 /* When we run as system instance we get the Released
695                  * signal via a direct connection */
696
697                 r = sd_bus_add_match(
698                                 bus,
699                                 "type='signal',"
700                                 "interface='org.freedesktop.systemd1.Agent',"
701                                 "member='Released',"
702                                 "path='/org/freedesktop/systemd1/agent'",
703                                 signal_agent_released, m);
704
705                 if (r < 0) {
706                         log_warning("Failed to register Released match on new connection bus: %s", strerror(-r));
707                         return 0;
708                 }
709         }
710
711         r = bus_setup_disconnected_match(m, bus);
712         if (r < 0)
713                 return 0;
714
715         r = bus_setup_api_vtables(m, bus);
716         if (r < 0) {
717                 log_warning("Failed to set up API vtables on new connection bus: %s", strerror(-r));
718                 return 0;
719         }
720
721         r = set_put(m->private_buses, bus);
722         if (r < 0) {
723                 log_warning("Failed to add new conenction bus to set: %s", strerror(-r));
724                 return 0;
725         }
726
727         bus = NULL;
728
729         log_debug("Accepted new private connection.");
730
731         return 0;
732 }
733
734 static int bus_list_names(Manager *m, sd_bus *bus) {
735         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
736         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
737         const char *name;
738         int r;
739
740         assert(m);
741         assert(bus);
742
743         r = sd_bus_call_method(
744                         bus,
745                         "org.freedesktop.DBus",
746                         "/org/freedesktop/DBus",
747                         "org.freedesktop.DBus",
748                         "ListNames",
749                         &error, &reply,
750                         NULL);
751         if (r < 0) {
752                 log_error("Failed to get initial list of names: %s", bus_error_message(&error, r));
753                 return r;
754         }
755
756         r = sd_bus_message_enter_container(reply, 'a', "s");
757         if (r < 0)
758                 return bus_log_parse_error(r);
759
760         /* This is a bit hacky, we say the owner of the name is the
761          * name itself, because we don't want the extra traffic to
762          * figure out the real owner. */
763         while ((r = sd_bus_message_read(reply, "s", &name)) > 0)
764                 manager_dispatch_bus_name_owner_changed(m, name, NULL, name);
765         if (r < 0)
766                 return bus_log_parse_error(r);
767
768         r = sd_bus_message_exit_container(reply);
769         if (r < 0)
770                 return bus_log_parse_error(r);
771
772         return 0;
773 }
774
775 static int bus_setup_api(Manager *m, sd_bus *bus) {
776         int r;
777
778         assert(m);
779         assert(bus);
780
781         r = bus_setup_api_vtables(m, bus);
782         if (r < 0)
783                 return r;
784
785         r = sd_bus_add_match(
786                         bus,
787                         "type='signal',"
788                         "sender='org.freedesktop.DBus',"
789                         "path='/org/freedesktop/DBus',"
790                         "interface='org.freedesktop.DBus',"
791                         "member='NameOwnerChanged'",
792                         signal_name_owner_changed, m);
793         if (r < 0)
794                 log_warning("Failed to subscribe to NameOwnerChanged signal: %s", strerror(-r));
795
796         r = sd_bus_add_match(
797                         bus,
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_ALLOW_REPLACEMENT|SD_BUS_NAME_REPLACE_EXISTING);
813         if (r < 0) {
814                 log_error("Failed to register name: %s", strerror(-r));
815                 return r;
816         }
817
818         if (r != SD_BUS_NAME_PRIMARY_OWNER) {
819                 log_error("Failed to acquire name.");
820                 return -EEXIST;
821         }
822
823         bus_list_names(m, bus);
824
825         log_debug("Successfully connected to API bus.");
826         return 0;
827 }
828
829 static int bus_init_api(Manager *m) {
830         _cleanup_bus_unref_ sd_bus *bus = NULL;
831         int r;
832
833         if (m->api_bus)
834                 return 0;
835
836         /* The API and system bus is the same if we are running in system mode */
837         if (m->running_as == SYSTEMD_SYSTEM && m->system_bus)
838                 bus = sd_bus_ref(m->system_bus);
839         else {
840                 if (m->running_as == SYSTEMD_SYSTEM)
841                         r = sd_bus_open_system(&bus);
842                 else
843                         r = sd_bus_open_user(&bus);
844
845                 if (r < 0) {
846                         log_debug("Failed to connect to API bus, retrying later...");
847                         return 0;
848                 }
849
850                 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
851                 if (r < 0) {
852                         log_error("Failed to attach API bus to event loop: %s", strerror(-r));
853                         return 0;
854                 }
855
856                 r = bus_setup_disconnected_match(m, bus);
857                 if (r < 0)
858                         return 0;
859         }
860
861         r = bus_setup_api(m, bus);
862         if (r < 0) {
863                 log_error("Failed to set up API bus: %s", strerror(-r));
864                 return 0;
865         }
866
867         m->api_bus = bus;
868         bus = NULL;
869
870         return 0;
871 }
872
873 static int bus_setup_system(Manager *m, sd_bus *bus) {
874         int r;
875
876         assert(m);
877         assert(bus);
878
879         if (m->running_as == SYSTEMD_SYSTEM)
880                 return 0;
881
882         /* If we are a user instance we get the Released message via
883          * the system bus */
884         r = sd_bus_add_match(
885                         bus,
886                         "type='signal',"
887                         "interface='org.freedesktop.systemd1.Agent',"
888                         "member='Released',"
889                         "path='/org/freedesktop/systemd1/agent'",
890                         signal_agent_released, m);
891
892         if (r < 0)
893                 log_warning("Failed to register Released match on system bus: %s", strerror(-r));
894
895         log_debug("Successfully connected to system bus.");
896         return 0;
897 }
898
899 static int bus_init_system(Manager *m) {
900         _cleanup_bus_unref_ sd_bus *bus = NULL;
901         int r;
902
903         if (m->system_bus)
904                 return 0;
905
906         /* The API and system bus is the same if we are running in system mode */
907         if (m->running_as == SYSTEMD_SYSTEM && m->api_bus) {
908                 m->system_bus = sd_bus_ref(m->api_bus);
909                 return 0;
910         }
911
912         r = sd_bus_open_system(&bus);
913         if (r < 0) {
914                 log_debug("Failed to connect to system bus, retrying later...");
915                 return 0;
916         }
917
918         r = bus_setup_disconnected_match(m, bus);
919         if (r < 0)
920                 return 0;
921
922         r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
923         if (r < 0) {
924                 log_error("Failed to attach system bus to event loop: %s", strerror(-r));
925                 return 0;
926         }
927
928         r = bus_setup_system(m, bus);
929         if (r < 0) {
930                 log_error("Fauiled to set up system bus: %s", strerror(-r));
931                 return 0;
932         }
933
934         m->system_bus = bus;
935         bus = NULL;
936
937         return 0;
938 }
939
940 static int bus_init_private(Manager *m) {
941         _cleanup_close_ int fd = -1;
942         union sockaddr_union sa = {
943                 .un.sun_family = AF_UNIX
944         };
945         sd_event_source *s;
946         socklen_t salen;
947         int r;
948
949         assert(m);
950
951         if (m->private_listen_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) + sizeof("/run/systemd/private") - 1;
962         } else {
963                 size_t left = sizeof(sa.un.sun_path);
964                 char *p = sa.un.sun_path;
965                 const char *e;
966
967                 e = secure_getenv("XDG_RUNTIME_DIR");
968                 if (!e) {
969                         log_error("Failed to determine XDG_RUNTIME_DIR");
970                         return -EHOSTDOWN;
971                 }
972
973                 left = strpcpy(&p, left, e);
974                 left = strpcpy(&p, left, "/systemd/private");
975
976                 salen = sizeof(sa.un) - left;
977
978                 mkdir_parents_label(sa.un.sun_path, 0755);
979         }
980
981         unlink(sa.un.sun_path);
982
983         fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
984         if (fd < 0) {
985                 log_error("Failed to allocate private socket: %m");
986                 return -errno;
987         }
988
989         r = bind(fd, &sa.sa, salen);
990         if (r < 0) {
991                 log_error("Failed to bind private socket: %m");
992                 return -errno;
993         }
994
995         r = listen(fd, SOMAXCONN);
996         if (r < 0) {
997                 log_error("Failed to make private socket listening: %m");
998                 return -errno;
999         }
1000
1001         r = sd_event_add_io(m->event, fd, EPOLLIN, bus_on_connection, m, &s);
1002         if (r < 0) {
1003                 log_error("Failed to allocate event source: %s", strerror(-r));
1004                 return r;
1005         }
1006
1007         m->private_listen_fd = fd;
1008         m->private_listen_event_source = s;
1009         fd = -1;
1010
1011         log_debug("Successfully created private D-Bus server.");
1012
1013         return 0;
1014 }
1015
1016 int bus_init(Manager *m, bool try_bus_connect) {
1017         int r;
1018
1019         if (try_bus_connect) {
1020                 r = bus_init_system(m);
1021                 if (r < 0)
1022                         return r;
1023
1024                 r = bus_init_api(m);
1025                 if (r < 0)
1026                         return r;
1027         }
1028
1029         r = bus_init_private(m);
1030         if (r < 0)
1031                 return r;
1032
1033         return 0;
1034 }
1035
1036 static void destroy_bus(Manager *m, sd_bus **bus) {
1037         Iterator i;
1038         Job *j;
1039
1040         assert(m);
1041         assert(bus);
1042
1043         if (!*bus)
1044                 return;
1045
1046         /* Get rid of tracked clients on this bus */
1047         bus_client_untrack_bus(m->subscribed, *bus);
1048         HASHMAP_FOREACH(j, m->jobs, i)
1049                 bus_client_untrack_bus(j->subscribed, *bus);
1050
1051         /* Get rid of queued message on this bus */
1052         if (m->queued_message_bus == *bus) {
1053                 m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
1054
1055                 if (m->queued_message)
1056                         m->queued_message = sd_bus_message_unref(m->queued_message);
1057         }
1058
1059         /* Possibly flush unwritten data, but only if we are
1060          * unprivileged, since we don't want to sync here */
1061         if (m->running_as != SYSTEMD_SYSTEM)
1062                 sd_bus_flush(*bus);
1063
1064         /* And destroy the object */
1065         sd_bus_close(*bus);
1066         *bus = sd_bus_unref(*bus);
1067 }
1068
1069 void bus_done(Manager *m) {
1070         sd_bus *b;
1071
1072         assert(m);
1073
1074         if (m->api_bus)
1075                 destroy_bus(m, &m->api_bus);
1076         if (m->system_bus)
1077                 destroy_bus(m, &m->system_bus);
1078         while ((b = set_steal_first(m->private_buses)))
1079                 destroy_bus(m, &b);
1080
1081         set_free(m->private_buses);
1082         set_free(m->subscribed);
1083
1084         if (m->private_listen_event_source)
1085                 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
1086
1087         if (m->private_listen_fd >= 0) {
1088                 close_nointr_nofail(m->private_listen_fd);
1089                 m->private_listen_fd = -1;
1090         }
1091 }
1092
1093 int bus_fdset_add_all(Manager *m, FDSet *fds) {
1094         Iterator i;
1095         sd_bus *b;
1096         int fd;
1097
1098         assert(m);
1099         assert(fds);
1100
1101         /* When we are about to reexecute we add all D-Bus fds to the
1102          * set to pass over to the newly executed systemd. They won't
1103          * be used there however, except thatt they are closed at the
1104          * very end of deserialization, those making it possible for
1105          * clients to synchronously wait for systemd to reexec by
1106          * simply waiting for disconnection */
1107
1108         if (m->api_bus) {
1109                 fd = sd_bus_get_fd(m->api_bus);
1110                 if (fd >= 0) {
1111                         fd = fdset_put_dup(fds, fd);
1112                         if (fd < 0)
1113                                 return fd;
1114                 }
1115         }
1116
1117         SET_FOREACH(b, m->private_buses, i) {
1118                 fd = sd_bus_get_fd(b);
1119                 if (fd >= 0) {
1120                         fd = fdset_put_dup(fds, fd);
1121                         if (fd < 0)
1122                                 return fd;
1123                 }
1124         }
1125
1126         /* We don't offer any APIs on the system bus (well, unless it
1127          * is the same as the API bus) hence we don't bother with it
1128          * here */
1129
1130         return 0;
1131 }
1132
1133 void bus_serialize(Manager *m, FILE *f) {
1134         assert(m);
1135         assert(f);
1136
1137         bus_client_track_serialize(m, f, m->subscribed);
1138 }
1139
1140 int bus_deserialize_item(Manager *m, const char *line) {
1141         assert(m);
1142         assert(line);
1143
1144         return bus_client_track_deserialize_item(m, &m->subscribed, line);
1145 }