chiark / gitweb /
core: refuse doing %h, %s, %U specifier resolving in PID 1
[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 #ifdef HAVE_SELINUX
215 static int selinux_filter(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
216         Manager *m = userdata;
217         const char *verb, *path;
218         Unit *u = NULL;
219         Job *j;
220         int r;
221
222         assert(bus);
223         assert(message);
224
225         /* Our own method calls are all protected individually with
226          * selinux checks, but the built-in interfaces need to be
227          * protected too. */
228
229         if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", "Set"))
230                 verb = "reload";
231         else if (sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", NULL) ||
232                  sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Properties", NULL) ||
233                  sd_bus_message_is_method_call(message, "org.freedesktop.DBus.ObjectManager", NULL) ||
234                  sd_bus_message_is_method_call(message, "org.freedesktop.DBus.Peer", NULL))
235                 verb = "status";
236         else
237                 return 0;
238
239         path = sd_bus_message_get_path(message);
240
241         if (object_path_startswith("/org/freedesktop/systemd1", path)) {
242
243                 r = selinux_access_check(bus, message, verb, error);
244                 if (r < 0)
245                         return r;
246
247                 return 0;
248         }
249
250         if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
251                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
252                 pid_t pid;
253
254                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
255                 if (r < 0)
256                         return 0;
257
258                 r = sd_bus_creds_get_pid(creds, &pid);
259                 if (r < 0)
260                         return 0;
261
262                 u = manager_get_unit_by_pid(m, pid);
263         } else {
264                 r = manager_get_job_from_dbus_path(m, path, &j);
265                 if (r >= 0)
266                         u = j->unit;
267                 else
268                         manager_load_unit_from_dbus_path(m, path, NULL, &u);
269         }
270
271         if (!u)
272                 return 0;
273
274         r = selinux_unit_access_check(u, bus, message, verb, error);
275         if (r < 0)
276                 return r;
277
278         return 0;
279 }
280 #endif
281
282 static int bus_job_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
283         Manager *m = userdata;
284         Job *j;
285         int r;
286
287         assert(bus);
288         assert(path);
289         assert(interface);
290         assert(found);
291         assert(m);
292
293         r = manager_get_job_from_dbus_path(m, path, &j);
294         if (r < 0)
295                 return 0;
296
297         *found = j;
298         return 1;
299 }
300
301 static int find_unit(Manager *m, sd_bus *bus, const char *path, Unit **unit, sd_bus_error *error) {
302         Unit *u;
303         int r;
304
305         assert(m);
306         assert(bus);
307         assert(path);
308
309         if (streq_ptr(path, "/org/freedesktop/systemd1/unit/self")) {
310                 _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
311                 sd_bus_message *message;
312                 pid_t pid;
313
314                 message = sd_bus_get_current(bus);
315                 if (!message)
316                         return 0;
317
318                 r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
319                 if (r < 0)
320                         return r;
321
322                 r = sd_bus_creds_get_pid(creds, &pid);
323                 if (r < 0)
324                         return r;
325
326                 u = manager_get_unit_by_pid(m, pid);
327         } else {
328                 r = manager_load_unit_from_dbus_path(m, path, error, &u);
329                 if (r < 0)
330                         return 0;
331         }
332
333         if (!u)
334                 return 0;
335
336         *unit = u;
337         return 1;
338 }
339
340 static int bus_unit_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
341         Manager *m = userdata;
342
343         assert(bus);
344         assert(path);
345         assert(interface);
346         assert(found);
347         assert(m);
348
349         return find_unit(m, bus, path, (Unit**) found, error);
350 }
351
352 static int bus_unit_interface_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
353         Manager *m = userdata;
354         Unit *u;
355         int r;
356
357         assert(bus);
358         assert(path);
359         assert(interface);
360         assert(found);
361         assert(m);
362
363         r = find_unit(m, bus, path, &u, error);
364         if (r <= 0)
365                 return r;
366
367         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
368                 return 0;
369
370         *found = u;
371         return 1;
372 }
373
374 static int bus_unit_cgroup_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
375         Manager *m = userdata;
376         Unit *u;
377         int r;
378
379         assert(bus);
380         assert(path);
381         assert(interface);
382         assert(found);
383         assert(m);
384
385         r = find_unit(m, bus, path, &u, error);
386         if (r <= 0)
387                 return r;
388
389         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
390                 return 0;
391
392         if (!unit_get_cgroup_context(u))
393                 return 0;
394
395         *found = u;
396         return 1;
397 }
398
399 static int bus_cgroup_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
400         Manager *m = userdata;
401         CGroupContext *c;
402         Unit *u;
403         int r;
404
405         assert(bus);
406         assert(path);
407         assert(interface);
408         assert(found);
409         assert(m);
410
411         r = find_unit(m, bus, path, &u, error);
412         if (r <= 0)
413                 return r;
414
415         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
416                 return 0;
417
418         c = unit_get_cgroup_context(u);
419         if (!c)
420                 return 0;
421
422         *found = c;
423         return 1;
424 }
425
426 static int bus_exec_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
427         Manager *m = userdata;
428         ExecContext *c;
429         Unit *u;
430         int r;
431
432         assert(bus);
433         assert(path);
434         assert(interface);
435         assert(found);
436         assert(m);
437
438         r = find_unit(m, bus, path, &u, error);
439         if (r <= 0)
440                 return r;
441
442         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
443                 return 0;
444
445         c = unit_get_exec_context(u);
446         if (!c)
447                 return 0;
448
449         *found = c;
450         return 1;
451 }
452
453 static int bus_kill_context_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
454         Manager *m = userdata;
455         KillContext *c;
456         Unit *u;
457         int r;
458
459         assert(bus);
460         assert(path);
461         assert(interface);
462         assert(found);
463         assert(m);
464
465         r = find_unit(m, bus, path, &u, error);
466         if (r <= 0)
467                 return r;
468
469         if (!streq_ptr(interface, UNIT_VTABLE(u)->bus_interface))
470                 return 0;
471
472         c = unit_get_kill_context(u);
473         if (!c)
474                 return 0;
475
476         *found = c;
477         return 1;
478 }
479
480 static int bus_job_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
481         _cleanup_free_ char **l = NULL;
482         Manager *m = userdata;
483         unsigned k = 0;
484         Iterator i;
485         Job *j;
486
487         l = new0(char*, hashmap_size(m->jobs)+1);
488         if (!l)
489                 return -ENOMEM;
490
491         HASHMAP_FOREACH(j, m->jobs, i) {
492                 l[k] = job_dbus_path(j);
493                 if (!l[k])
494                         return -ENOMEM;
495
496                 k++;
497         }
498
499         assert(hashmap_size(m->jobs) == k);
500
501         *nodes = l;
502         l = NULL;
503
504         return k;
505 }
506
507 static int bus_unit_enumerate(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
508         _cleanup_free_ char **l = NULL;
509         Manager *m = userdata;
510         unsigned k = 0;
511         Iterator i;
512         Unit *u;
513
514         l = new0(char*, hashmap_size(m->units)+1);
515         if (!l)
516                 return -ENOMEM;
517
518         HASHMAP_FOREACH(u, m->units, i) {
519                 l[k] = unit_dbus_path(u);
520                 if (!l[k])
521                         return -ENOMEM;
522
523                 k++;
524         }
525
526         *nodes = l;
527         l = NULL;
528
529         return k;
530 }
531
532 static int bus_setup_api_vtables(Manager *m, sd_bus *bus) {
533         UnitType t;
534         int r;
535
536         assert(m);
537         assert(bus);
538
539 #ifdef HAVE_SELINUX
540         r = sd_bus_add_filter(bus, selinux_filter, m);
541         if (r < 0) {
542                 log_error("Failed to add SELinux access filter: %s", strerror(-r));
543                 return r;
544         }
545 #endif
546
547         r = sd_bus_add_object_vtable(bus, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
548         if (r < 0) {
549                 log_error("Failed to register Manager vtable: %s", strerror(-r));
550                 return r;
551         }
552
553         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
554         if (r < 0) {
555                 log_error("Failed to register Job vtable: %s", strerror(-r));
556                 return r;
557         }
558
559         r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
560         if (r < 0) {
561                 log_error("Failed to add job enumerator: %s", strerror(-r));
562                 return r;
563         }
564
565         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
566         if (r < 0) {
567                 log_error("Failed to register Unit vtable: %s", strerror(-r));
568                 return r;
569         }
570
571         r = sd_bus_add_node_enumerator(bus, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
572         if (r < 0) {
573                 log_error("Failed to add job enumerator: %s", strerror(-r));
574                 return r;
575         }
576
577         for (t = 0; t < _UNIT_TYPE_MAX; t++) {
578                 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);
579                 if (r < 0)  {
580                         log_error("Failed to register type specific vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
581                         return r;
582                 }
583
584                 if (unit_vtable[t]->cgroup_context_offset > 0) {
585                         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);
586                         if (r < 0) {
587                                 log_error("Failed to register control group unit vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
588                                 return r;
589                         }
590
591                         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_cgroup_vtable, bus_cgroup_context_find, m);
592                         if (r < 0) {
593                                 log_error("Failed to register control group vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
594                                 return r;
595                         }
596                 }
597
598                 if (unit_vtable[t]->exec_context_offset > 0) {
599                         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_exec_vtable, bus_exec_context_find, m);
600                         if (r < 0) {
601                                 log_error("Failed to register execute vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
602                                 return r;
603                         }
604                 }
605
606                 if (unit_vtable[t]->kill_context_offset > 0) {
607                         r = sd_bus_add_fallback_vtable(bus, "/org/freedesktop/systemd1/unit", unit_vtable[t]->bus_interface, bus_kill_vtable, bus_kill_context_find, m);
608                         if (r < 0) {
609                                 log_error("Failed to register kill vtable for %s: %s", unit_vtable[t]->bus_interface, strerror(-r));
610                                 return r;
611                         }
612                 }
613         }
614
615         return 0;
616 }
617
618 static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
619         int r;
620
621         assert(m);
622         assert(bus);
623
624         r = sd_bus_add_match(
625                         bus,
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, fd, EPOLLIN, bus_on_connection, m, &s);
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         bus_client_untrack_bus(m->subscribed, *bus);
1043         HASHMAP_FOREACH(j, m->jobs, i)
1044                 bus_client_untrack_bus(j->subscribed, *bus);
1045
1046         /* Get rid of queued message on this bus */
1047         if (m->queued_message_bus == *bus) {
1048                 m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
1049
1050                 if (m->queued_message)
1051                         m->queued_message = sd_bus_message_unref(m->queued_message);
1052         }
1053
1054         /* Possibly flush unwritten data, but only if we are
1055          * unprivileged, since we don't want to sync here */
1056         if (m->running_as != SYSTEMD_SYSTEM)
1057                 sd_bus_flush(*bus);
1058
1059         /* And destroy the object */
1060         sd_bus_close(*bus);
1061         *bus = sd_bus_unref(*bus);
1062 }
1063
1064 void bus_done(Manager *m) {
1065         sd_bus *b;
1066
1067         assert(m);
1068
1069         if (m->api_bus)
1070                 destroy_bus(m, &m->api_bus);
1071         if (m->system_bus)
1072                 destroy_bus(m, &m->system_bus);
1073         while ((b = set_steal_first(m->private_buses)))
1074                 destroy_bus(m, &b);
1075
1076         set_free(m->private_buses);
1077         set_free(m->subscribed);
1078
1079         if (m->private_listen_event_source)
1080                 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
1081
1082         if (m->private_listen_fd >= 0) {
1083                 close_nointr_nofail(m->private_listen_fd);
1084                 m->private_listen_fd = -1;
1085         }
1086 }
1087
1088 int bus_fdset_add_all(Manager *m, FDSet *fds) {
1089         Iterator i;
1090         sd_bus *b;
1091         int fd;
1092
1093         assert(m);
1094         assert(fds);
1095
1096         /* When we are about to reexecute we add all D-Bus fds to the
1097          * set to pass over to the newly executed systemd. They won't
1098          * be used there however, except thatt they are closed at the
1099          * very end of deserialization, those making it possible for
1100          * clients to synchronously wait for systemd to reexec by
1101          * simply waiting for disconnection */
1102
1103         if (m->api_bus) {
1104                 fd = sd_bus_get_fd(m->api_bus);
1105                 if (fd >= 0) {
1106                         fd = fdset_put_dup(fds, fd);
1107                         if (fd < 0)
1108                                 return fd;
1109                 }
1110         }
1111
1112         SET_FOREACH(b, m->private_buses, i) {
1113                 fd = sd_bus_get_fd(b);
1114                 if (fd >= 0) {
1115                         fd = fdset_put_dup(fds, fd);
1116                         if (fd < 0)
1117                                 return fd;
1118                 }
1119         }
1120
1121         /* We don't offer any APIs on the system bus (well, unless it
1122          * is the same as the API bus) hence we don't bother with it
1123          * here */
1124
1125         return 0;
1126 }
1127
1128 void bus_serialize(Manager *m, FILE *f) {
1129         assert(m);
1130         assert(f);
1131
1132         bus_client_track_serialize(m, f, m->subscribed);
1133 }
1134
1135 int bus_deserialize_item(Manager *m, const char *line) {
1136         assert(m);
1137         assert(line);
1138
1139         return bus_client_track_deserialize_item(m, &m->subscribed, line);
1140 }