chiark / gitweb /
core: rewind message before forwarding it
[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 4096
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         /* only forward to system bus if running as system instance */
92         if (m->running_as != SYSTEMD_SYSTEM || !m->system_bus)
93                 return 0;
94
95         r = sd_bus_message_rewind(message, 1);
96         if (r < 0)
97                 goto exit;
98
99         r = sd_bus_send(m->system_bus, message, NULL);
100
101 exit:
102         if (r < 0)
103                 log_warning_errno(r, "Failed to forward Released message: %m");
104         return 0;
105 }
106
107 static int signal_disconnected(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
108         Manager *m = userdata;
109
110         assert(bus);
111         assert(message);
112         assert(m);
113
114         if (bus == m->api_bus)
115                 destroy_bus(m, &m->api_bus);
116         if (bus == m->system_bus)
117                 destroy_bus(m, &m->system_bus);
118         if (set_remove(m->private_buses, bus)) {
119                 log_debug("Got disconnect on private connection.");
120                 destroy_bus(m, &bus);
121         }
122
123         return 0;
124 }
125
126 static int signal_name_owner_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
127         const char *name, *old_owner, *new_owner;
128         Manager *m = userdata;
129         int r;
130
131         assert(bus);
132         assert(message);
133         assert(m);
134
135         r = sd_bus_message_read(message, "sss", &name, &old_owner, &new_owner);
136         if (r < 0) {
137                 bus_log_parse_error(r);
138                 return 0;
139         }
140
141         manager_dispatch_bus_name_owner_changed(
142                         m, name,
143                         isempty(old_owner) ? NULL : old_owner,
144                         isempty(new_owner) ? NULL : new_owner);
145
146         return 0;
147 }
148
149 static int signal_activation_request(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
150         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
151         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
152         Manager *m = userdata;
153         const char *name;
154         Unit *u;
155         int r;
156
157         assert(bus);
158         assert(message);
159         assert(m);
160
161         r = sd_bus_message_read(message, "s", &name);
162         if (r < 0) {
163                 bus_log_parse_error(r);
164                 return 0;
165         }
166
167         if (manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SERVICE) ||
168             manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SOCKET)) {
169                 r = sd_bus_error_setf(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down.");
170                 goto failed;
171         }
172
173         r = manager_load_unit(m, name, NULL, &error, &u);
174         if (r < 0)
175                 goto failed;
176
177         if (u->refuse_manual_start) {
178                 r = sd_bus_error_setf(&error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, %s may be requested by dependency only.", u->id);
179                 goto failed;
180         }
181
182         r = manager_add_job(m, JOB_START, u, JOB_REPLACE, true, &error, NULL);
183         if (r < 0)
184                 goto failed;
185
186         /* Successfully queued, that's it for us */
187         return 0;
188
189 failed:
190         if (!sd_bus_error_is_set(&error))
191                 sd_bus_error_set_errno(&error, r);
192
193         log_debug("D-Bus activation failed for %s: %s", name, bus_error_message(&error, r));
194
195         r = sd_bus_message_new_signal(bus, &reply, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Activator", "ActivationFailure");
196         if (r < 0) {
197                 bus_log_create_error(r);
198                 return 0;
199         }
200
201         r = sd_bus_message_append(reply, "sss", name, error.name, error.message);
202         if (r < 0) {
203                 bus_log_create_error(r);
204                 return 0;
205         }
206
207         r = sd_bus_send_to(bus, reply, "org.freedesktop.DBus", NULL);
208         if (r < 0)
209                 return log_error_errno(r, "Failed to respond with to bus activation request: %m");
210
211         return 0;
212 }
213
214 #ifdef HAVE_SELINUX
215 static int mac_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 = mac_selinux_access_check(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 = mac_selinux_unit_access_check(u, 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_message(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, NULL, mac_selinux_filter, m);
541         if (r < 0)
542                 return log_error_errno(r, "Failed to add SELinux access filter: %m");
543 #endif
544
545         r = sd_bus_add_object_vtable(bus, NULL, "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", bus_manager_vtable, m);
546         if (r < 0)
547                 return log_error_errno(r, "Failed to register Manager vtable: %m");
548
549         r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/job", "org.freedesktop.systemd1.Job", bus_job_vtable, bus_job_find, m);
550         if (r < 0)
551                 return log_error_errno(r, "Failed to register Job vtable: %m");
552
553         r = sd_bus_add_node_enumerator(bus, NULL, "/org/freedesktop/systemd1/job", bus_job_enumerate, m);
554         if (r < 0)
555                 return log_error_errno(r, "Failed to add job enumerator: %m");
556
557         r = sd_bus_add_fallback_vtable(bus, NULL, "/org/freedesktop/systemd1/unit", "org.freedesktop.systemd1.Unit", bus_unit_vtable, bus_unit_find, m);
558         if (r < 0)
559                 return log_error_errno(r, "Failed to register Unit vtable: %m");
560
561         r = sd_bus_add_node_enumerator(bus, NULL, "/org/freedesktop/systemd1/unit", bus_unit_enumerate, m);
562         if (r < 0)
563                 return log_error_errno(r, "Failed to add job enumerator: %m");
564
565         for (t = 0; t < _UNIT_TYPE_MAX; t++) {
566                 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);
567                 if (r < 0)
568                         return log_error_errno(r, "Failed to register type specific vtable for %s: %m", unit_vtable[t]->bus_interface);
569
570                 if (unit_vtable[t]->cgroup_context_offset > 0) {
571                         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);
572                         if (r < 0)
573                                 return log_error_errno(r, "Failed to register control group unit vtable for %s: %m", unit_vtable[t]->bus_interface);
574
575                         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);
576                         if (r < 0)
577                                 return log_error_errno(r, "Failed to register control group vtable for %s: %m", unit_vtable[t]->bus_interface);
578                 }
579
580                 if (unit_vtable[t]->exec_context_offset > 0) {
581                         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);
582                         if (r < 0)
583                                 return log_error_errno(r, "Failed to register execute vtable for %s: %m", unit_vtable[t]->bus_interface);
584                 }
585
586                 if (unit_vtable[t]->kill_context_offset > 0) {
587                         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);
588                         if (r < 0)
589                                 return log_error_errno(r, "Failed to register kill vtable for %s: %m", unit_vtable[t]->bus_interface);
590                 }
591         }
592
593         return 0;
594 }
595
596 static int bus_setup_disconnected_match(Manager *m, sd_bus *bus) {
597         int r;
598
599         assert(m);
600         assert(bus);
601
602         r = sd_bus_add_match(
603                         bus,
604                         NULL,
605                         "sender='org.freedesktop.DBus.Local',"
606                         "type='signal',"
607                         "path='/org/freedesktop/DBus/Local',"
608                         "interface='org.freedesktop.DBus.Local',"
609                         "member='Disconnected'",
610                         signal_disconnected, m);
611
612         if (r < 0)
613                 return log_error_errno(r, "Failed to register match for Disconnected message: %m");
614
615         return 0;
616 }
617
618 static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
619         _cleanup_bus_unref_ sd_bus *bus = NULL;
620         _cleanup_close_ int nfd = -1;
621         Manager *m = userdata;
622         sd_id128_t id;
623         int r;
624
625         assert(s);
626         assert(m);
627
628         nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
629         if (nfd < 0) {
630                 log_warning_errno(errno, "Failed to accept private connection, ignoring: %m");
631                 return 0;
632         }
633
634         if (set_size(m->private_buses) >= CONNECTIONS_MAX) {
635                 log_warning("Too many concurrent connections, refusing");
636                 return 0;
637         }
638
639         r = set_ensure_allocated(&m->private_buses, NULL);
640         if (r < 0) {
641                 log_oom();
642                 return 0;
643         }
644
645         r = sd_bus_new(&bus);
646         if (r < 0) {
647                 log_warning_errno(r, "Failed to allocate new private connection bus: %m");
648                 return 0;
649         }
650
651         r = sd_bus_set_fd(bus, nfd, nfd);
652         if (r < 0) {
653                 log_warning_errno(r, "Failed to set fd on new connection bus: %m");
654                 return 0;
655         }
656
657         nfd = -1;
658
659         r = bus_check_peercred(bus);
660         if (r < 0) {
661                 log_warning_errno(r, "Incoming private connection from unprivileged client, refusing: %m");
662                 return 0;
663         }
664
665         assert_se(sd_id128_randomize(&id) >= 0);
666
667         r = sd_bus_set_server(bus, 1, id);
668         if (r < 0) {
669                 log_warning_errno(r, "Failed to enable server support for new connection bus: %m");
670                 return 0;
671         }
672
673         r = sd_bus_start(bus);
674         if (r < 0) {
675                 log_warning_errno(r, "Failed to start new connection bus: %m");
676                 return 0;
677         }
678
679         r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
680         if (r < 0) {
681                 log_warning_errno(r, "Failed to attach new connection bus to event loop: %m");
682                 return 0;
683         }
684
685         if (m->running_as == SYSTEMD_SYSTEM) {
686                 /* When we run as system instance we get the Released
687                  * signal via a direct connection */
688
689                 r = sd_bus_add_match(
690                                 bus,
691                                 NULL,
692                                 "type='signal',"
693                                 "interface='org.freedesktop.systemd1.Agent',"
694                                 "member='Released',"
695                                 "path='/org/freedesktop/systemd1/agent'",
696                                 signal_agent_released, m);
697
698                 if (r < 0) {
699                         log_warning_errno(r, "Failed to register Released match on new connection bus: %m");
700                         return 0;
701                 }
702         }
703
704         r = bus_setup_disconnected_match(m, bus);
705         if (r < 0)
706                 return 0;
707
708         r = bus_setup_api_vtables(m, bus);
709         if (r < 0) {
710                 log_warning_errno(r, "Failed to set up API vtables on new connection bus: %m");
711                 return 0;
712         }
713
714         r = set_put(m->private_buses, bus);
715         if (r < 0) {
716                 log_warning_errno(r, "Failed to add new conenction bus to set: %m");
717                 return 0;
718         }
719
720         bus = NULL;
721
722         log_debug("Accepted new private connection.");
723
724         return 0;
725 }
726
727 static int bus_list_names(Manager *m, sd_bus *bus) {
728         _cleanup_strv_free_ char **names = NULL;
729         char **i;
730         int r;
731
732         assert(m);
733         assert(bus);
734
735         r = sd_bus_list_names(bus, &names, NULL);
736         if (r < 0)
737                 return log_error_errno(r, "Failed to get initial list of names: %m");
738
739         /* This is a bit hacky, we say the owner of the name is the
740          * name itself, because we don't want the extra traffic to
741          * figure out the real owner. */
742         STRV_FOREACH(i, names)
743                 manager_dispatch_bus_name_owner_changed(m, *i, NULL, *i);
744
745         return 0;
746 }
747
748 static int bus_setup_api(Manager *m, sd_bus *bus) {
749         int r;
750
751         assert(m);
752         assert(bus);
753
754         /* Let's make sure we have enough credential bits so that we can make security and selinux decisions */
755         r = sd_bus_negotiate_creds(bus, 1,
756                                    SD_BUS_CREDS_PID|SD_BUS_CREDS_UID|
757                                    SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS|
758                                    SD_BUS_CREDS_SELINUX_CONTEXT);
759         if (r < 0)
760                 log_warning_errno(r, "Failed to enable credential passing, ignoring: %m");
761
762         r = bus_setup_api_vtables(m, bus);
763         if (r < 0)
764                 return r;
765
766         r = sd_bus_add_match(
767                         bus,
768                         NULL,
769                         "type='signal',"
770                         "sender='org.freedesktop.DBus',"
771                         "path='/org/freedesktop/DBus',"
772                         "interface='org.freedesktop.DBus',"
773                         "member='NameOwnerChanged'",
774                         signal_name_owner_changed, m);
775         if (r < 0)
776                 log_warning_errno(r, "Failed to subscribe to NameOwnerChanged signal: %m");
777
778         r = sd_bus_add_match(
779                         bus,
780                         NULL,
781                         "type='signal',"
782                         "sender='org.freedesktop.DBus',"
783                         "path='/org/freedesktop/DBus',"
784                         "interface='org.freedesktop.systemd1.Activator',"
785                         "member='ActivationRequest'",
786                         signal_activation_request, m);
787         if (r < 0)
788                 log_warning_errno(r, "Failed to subscribe to activation signal: %m");
789
790         /* Allow replacing of our name, to ease implementation of
791          * reexecution, where we keep the old connection open until
792          * after the new connection is set up and the name installed
793          * to allow clients to synchronously wait for reexecution to
794          * finish */
795         r = sd_bus_request_name(bus,"org.freedesktop.systemd1", SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_ALLOW_REPLACEMENT);
796         if (r < 0)
797                 return log_error_errno(r, "Failed to register name: %m");
798
799         bus_list_names(m, bus);
800
801         log_debug("Successfully connected to API bus.");
802         return 0;
803 }
804
805 static int bus_init_api(Manager *m) {
806         _cleanup_bus_unref_ sd_bus *bus = NULL;
807         int r;
808
809         if (m->api_bus)
810                 return 0;
811
812         /* The API and system bus is the same if we are running in system mode */
813         if (m->running_as == SYSTEMD_SYSTEM && m->system_bus)
814                 bus = sd_bus_ref(m->system_bus);
815         else {
816                 if (m->running_as == SYSTEMD_SYSTEM)
817                         r = sd_bus_open_system(&bus);
818                 else
819                         r = sd_bus_open_user(&bus);
820
821                 if (r < 0) {
822                         log_debug("Failed to connect to API bus, retrying later...");
823                         return 0;
824                 }
825
826                 r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
827                 if (r < 0) {
828                         log_error_errno(r, "Failed to attach API bus to event loop: %m");
829                         return 0;
830                 }
831
832                 r = bus_setup_disconnected_match(m, bus);
833                 if (r < 0)
834                         return 0;
835         }
836
837         r = bus_setup_api(m, bus);
838         if (r < 0) {
839                 log_error_errno(r, "Failed to set up API bus: %m");
840                 return 0;
841         }
842
843         m->api_bus = bus;
844         bus = NULL;
845
846         return 0;
847 }
848
849 static int bus_setup_system(Manager *m, sd_bus *bus) {
850         int r;
851
852         assert(m);
853         assert(bus);
854
855         if (m->running_as == SYSTEMD_SYSTEM)
856                 return 0;
857
858         /* If we are a user instance we get the Released message via
859          * the system bus */
860         r = sd_bus_add_match(
861                         bus,
862                         NULL,
863                         "type='signal',"
864                         "interface='org.freedesktop.systemd1.Agent',"
865                         "member='Released',"
866                         "path='/org/freedesktop/systemd1/agent'",
867                         signal_agent_released, m);
868
869         if (r < 0)
870                 log_warning_errno(r, "Failed to register Released match on system bus: %m");
871
872         log_debug("Successfully connected to system bus.");
873         return 0;
874 }
875
876 static int bus_init_system(Manager *m) {
877         _cleanup_bus_unref_ sd_bus *bus = NULL;
878         int r;
879
880         if (m->system_bus)
881                 return 0;
882
883         /* The API and system bus is the same if we are running in system mode */
884         if (m->running_as == SYSTEMD_SYSTEM && m->api_bus) {
885                 m->system_bus = sd_bus_ref(m->api_bus);
886                 return 0;
887         }
888
889         r = sd_bus_open_system(&bus);
890         if (r < 0) {
891                 log_debug("Failed to connect to system bus, retrying later...");
892                 return 0;
893         }
894
895         r = bus_setup_disconnected_match(m, bus);
896         if (r < 0)
897                 return 0;
898
899         r = sd_bus_attach_event(bus, m->event, SD_EVENT_PRIORITY_NORMAL);
900         if (r < 0) {
901                 log_error_errno(r, "Failed to attach system bus to event loop: %m");
902                 return 0;
903         }
904
905         r = bus_setup_system(m, bus);
906         if (r < 0) {
907                 log_error_errno(r, "Failed to set up system bus: %m");
908                 return 0;
909         }
910
911         m->system_bus = bus;
912         bus = NULL;
913
914         return 0;
915 }
916
917 static int bus_init_private(Manager *m) {
918         _cleanup_close_ int fd = -1;
919         union sockaddr_union sa = {
920                 .un.sun_family = AF_UNIX
921         };
922         sd_event_source *s;
923         socklen_t salen;
924         int r;
925
926         assert(m);
927
928         if (m->private_listen_fd >= 0)
929                 return 0;
930
931         /* We don't need the private socket if we have kdbus */
932         if (m->kdbus_fd >= 0)
933                 return 0;
934
935         if (m->running_as == SYSTEMD_SYSTEM) {
936
937                 /* We want the private bus only when running as init */
938                 if (getpid() != 1)
939                         return 0;
940
941                 strcpy(sa.un.sun_path, "/run/systemd/private");
942                 salen = offsetof(union sockaddr_union, un.sun_path) + strlen("/run/systemd/private");
943         } else {
944                 size_t left = sizeof(sa.un.sun_path);
945                 char *p = sa.un.sun_path;
946                 const char *e;
947
948                 e = secure_getenv("XDG_RUNTIME_DIR");
949                 if (!e) {
950                         log_error("Failed to determine XDG_RUNTIME_DIR");
951                         return -EHOSTDOWN;
952                 }
953
954                 left = strpcpy(&p, left, e);
955                 left = strpcpy(&p, left, "/systemd/private");
956
957                 salen = sizeof(sa.un) - left;
958         }
959
960         (void) mkdir_parents_label(sa.un.sun_path, 0755);
961         (void) unlink(sa.un.sun_path);
962
963         fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
964         if (fd < 0)
965                 return log_error_errno(errno, "Failed to allocate private socket: %m");
966
967         r = bind(fd, &sa.sa, salen);
968         if (r < 0)
969                 return log_error_errno(errno, "Failed to bind private socket: %m");
970
971         r = listen(fd, SOMAXCONN);
972         if (r < 0)
973                 return log_error_errno(errno, "Failed to make private socket listening: %m");
974
975         r = sd_event_add_io(m->event, &s, fd, EPOLLIN, bus_on_connection, m);
976         if (r < 0)
977                 return log_error_errno(r, "Failed to allocate event source: %m");
978
979         m->private_listen_fd = fd;
980         m->private_listen_event_source = s;
981         fd = -1;
982
983         log_debug("Successfully created private D-Bus server.");
984
985         return 0;
986 }
987
988 int bus_init(Manager *m, bool try_bus_connect) {
989         int r;
990
991         if (try_bus_connect) {
992                 r = bus_init_system(m);
993                 if (r < 0)
994                         return r;
995
996                 r = bus_init_api(m);
997                 if (r < 0)
998                         return r;
999         }
1000
1001         r = bus_init_private(m);
1002         if (r < 0)
1003                 return r;
1004
1005         return 0;
1006 }
1007
1008 static void destroy_bus(Manager *m, sd_bus **bus) {
1009         Iterator i;
1010         Job *j;
1011
1012         assert(m);
1013         assert(bus);
1014
1015         if (!*bus)
1016                 return;
1017
1018         /* Get rid of tracked clients on this bus */
1019         if (m->subscribed && sd_bus_track_get_bus(m->subscribed) == *bus)
1020                 m->subscribed = sd_bus_track_unref(m->subscribed);
1021
1022         HASHMAP_FOREACH(j, m->jobs, i)
1023                 if (j->clients && sd_bus_track_get_bus(j->clients) == *bus)
1024                         j->clients = sd_bus_track_unref(j->clients);
1025
1026         /* Get rid of queued message on this bus */
1027         if (m->queued_message_bus == *bus) {
1028                 m->queued_message_bus = sd_bus_unref(m->queued_message_bus);
1029
1030                 if (m->queued_message)
1031                         m->queued_message = sd_bus_message_unref(m->queued_message);
1032         }
1033
1034         /* Possibly flush unwritten data, but only if we are
1035          * unprivileged, since we don't want to sync here */
1036         if (m->running_as != SYSTEMD_SYSTEM)
1037                 sd_bus_flush(*bus);
1038
1039         /* And destroy the object */
1040         sd_bus_close(*bus);
1041         *bus = sd_bus_unref(*bus);
1042 }
1043
1044 void bus_done(Manager *m) {
1045         sd_bus *b;
1046
1047         assert(m);
1048
1049         if (m->api_bus)
1050                 destroy_bus(m, &m->api_bus);
1051         if (m->system_bus)
1052                 destroy_bus(m, &m->system_bus);
1053         while ((b = set_steal_first(m->private_buses)))
1054                 destroy_bus(m, &b);
1055
1056         set_free(m->private_buses);
1057         m->private_buses = NULL;
1058
1059         m->subscribed = sd_bus_track_unref(m->subscribed);
1060         strv_free(m->deserialized_subscribed);
1061         m->deserialized_subscribed = NULL;
1062
1063         if (m->private_listen_event_source)
1064                 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
1065
1066         m->private_listen_fd = safe_close(m->private_listen_fd);
1067
1068         bus_verify_polkit_async_registry_free(m->polkit_registry);
1069 }
1070
1071 int bus_fdset_add_all(Manager *m, FDSet *fds) {
1072         Iterator i;
1073         sd_bus *b;
1074         int fd;
1075
1076         assert(m);
1077         assert(fds);
1078
1079         /* When we are about to reexecute we add all D-Bus fds to the
1080          * set to pass over to the newly executed systemd. They won't
1081          * be used there however, except thatt they are closed at the
1082          * very end of deserialization, those making it possible for
1083          * clients to synchronously wait for systemd to reexec by
1084          * simply waiting for disconnection */
1085
1086         if (m->api_bus) {
1087                 fd = sd_bus_get_fd(m->api_bus);
1088                 if (fd >= 0) {
1089                         fd = fdset_put_dup(fds, fd);
1090                         if (fd < 0)
1091                                 return fd;
1092                 }
1093         }
1094
1095         SET_FOREACH(b, m->private_buses, i) {
1096                 fd = sd_bus_get_fd(b);
1097                 if (fd >= 0) {
1098                         fd = fdset_put_dup(fds, fd);
1099                         if (fd < 0)
1100                                 return fd;
1101                 }
1102         }
1103
1104         /* We don't offer any APIs on the system bus (well, unless it
1105          * is the same as the API bus) hence we don't bother with it
1106          * here */
1107
1108         return 0;
1109 }
1110
1111 int bus_foreach_bus(
1112                 Manager *m,
1113                 sd_bus_track *subscribed2,
1114                 int (*send_message)(sd_bus *bus, void *userdata),
1115                 void *userdata) {
1116
1117         Iterator i;
1118         sd_bus *b;
1119         int r, ret = 0;
1120
1121         /* Send to all direct busses, unconditionally */
1122         SET_FOREACH(b, m->private_buses, i) {
1123                 r = send_message(b, userdata);
1124                 if (r < 0)
1125                         ret = r;
1126         }
1127
1128         /* Send to API bus, but only if somebody is subscribed */
1129         if (sd_bus_track_count(m->subscribed) > 0 ||
1130             sd_bus_track_count(subscribed2) > 0) {
1131                 r = send_message(m->api_bus, userdata);
1132                 if (r < 0)
1133                         ret = r;
1134         }
1135
1136         return ret;
1137 }
1138
1139 void bus_track_serialize(sd_bus_track *t, FILE *f) {
1140         const char *n;
1141
1142         assert(f);
1143
1144         for (n = sd_bus_track_first(t); n; n = sd_bus_track_next(t))
1145                 fprintf(f, "subscribed=%s\n", n);
1146 }
1147
1148 int bus_track_deserialize_item(char ***l, const char *line) {
1149         const char *e;
1150         int r;
1151
1152         assert(l);
1153         assert(line);
1154
1155         e = startswith(line, "subscribed=");
1156         if (!e)
1157                 return 0;
1158
1159         r = strv_extend(l, e);
1160         if (r < 0)
1161                 return r;
1162
1163         return 1;
1164 }
1165
1166 int bus_track_coldplug(Manager *m, sd_bus_track **t, char ***l) {
1167         int r = 0;
1168
1169         assert(m);
1170         assert(t);
1171         assert(l);
1172
1173         if (!strv_isempty(*l) && m->api_bus) {
1174                 char **i;
1175
1176                 if (!*t) {
1177                         r = sd_bus_track_new(m->api_bus, t, NULL, NULL);
1178                         if (r < 0)
1179                                 return r;
1180                 }
1181
1182                 r = 0;
1183                 STRV_FOREACH(i, *l) {
1184                         int k;
1185
1186                         k = sd_bus_track_add_name(*t, *i);
1187                         if (k < 0)
1188                                 r = k;
1189                 }
1190         }
1191
1192         strv_free(*l);
1193         *l = NULL;
1194
1195         return r;
1196 }
1197
1198 int bus_verify_manage_units_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
1199         return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-units", false, UID_INVALID, &m->polkit_registry, error);
1200 }
1201
1202 /* Same as bus_verify_manage_unit_async(), but checks for CAP_KILL instead of CAP_SYS_ADMIN */
1203 int bus_verify_manage_units_async_for_kill(Manager *m, sd_bus_message *call, sd_bus_error *error) {
1204         return bus_verify_polkit_async(call, CAP_KILL, "org.freedesktop.systemd1.manage-units", false, UID_INVALID, &m->polkit_registry, error);
1205 }
1206
1207 int bus_verify_manage_unit_files_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
1208         return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.manage-unit-files", false, UID_INVALID, &m->polkit_registry, error);
1209 }
1210
1211 int bus_verify_reload_daemon_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
1212         return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.reload-daemon", false, UID_INVALID, &m->polkit_registry, error);
1213 }
1214
1215 int bus_verify_set_environment_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
1216         return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.set-environment", false, UID_INVALID, &m->polkit_registry, error);
1217 }