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