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