chiark / gitweb /
46a5b10974847b8384e95f4b9a7592cfa5686f95
[elogind.git] / src / bus-driverd / bus-driverd.c
1 /***
2   This file is part of systemd.
3
4   Copyright 2013 Daniel Mack
5
6   systemd is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as published by
8   the Free Software Foundation; either version 2.1 of the License, or
9   (at your option) any later version.
10
11   systemd is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14   Lesser General Public License for more details.
15
16   You should have received a copy of the GNU Lesser General Public License
17   along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <stdlib.h>
21 #include <stdbool.h>
22 #include <unistd.h>
23 #include <getopt.h>
24 #include <locale.h>
25 #include <string.h>
26 #include <poll.h>
27 #include <netdb.h>
28 #include <sys/socket.h>
29 #include <sys/un.h>
30 #include <sys/timex.h>
31 #include <sys/utsname.h>
32 #include <unistd.h>
33
34 #include "kdbus.h"
35 #include "sd-bus.h"
36 #include "bus-internal.h"
37 #include "sd-daemon.h"
38 #include "sd-event.h"
39 #include "event-util.h"
40 #include "bus-util.h"
41 #include "bus-error.h"
42 #include "bus-message.h"
43 #include "bus-kernel.h"
44 #include "socket-util.h"
45 #include "util.h"
46 #include "build.h"
47 #include "strv.h"
48 #include "sd-id128.h"
49 #include "async.h"
50 #include "hashmap.h"
51 #include "def.h"
52 #include "unit-name.h"
53 #include "bus-control.h"
54 #include "cgroup-util.h"
55
56 #define CLIENTS_MAX 1024
57 #define MATCHES_MAX 1024
58
59 typedef struct Match Match;
60 typedef struct Client Client;
61 typedef struct Context Context;
62
63 struct Match {
64         Client *client;
65         char *match;
66         uint64_t cookie;
67         LIST_FIELDS(Match, matches);
68 };
69
70 struct Client {
71         Context *context;
72         uint64_t id;
73         uint64_t next_cookie;
74         Hashmap *matches;
75         unsigned n_matches;
76         char *watch;
77 };
78
79 struct Context {
80         sd_bus *bus;
81         sd_event *event;
82         Hashmap *clients;
83 };
84
85 static void match_free(Match *m) {
86
87         if (!m)
88                 return;
89
90         if (m->client) {
91                 Match *first;
92
93                 first = hashmap_get(m->client->matches, m->match);
94                 LIST_REMOVE(matches, first, m);
95                 if (first)
96                         assert_se(hashmap_replace(m->client->matches, m->match, first) >= 0);
97                 else
98                         hashmap_remove(m->client->matches, m->match);
99
100                 m->client->n_matches--;
101         }
102
103         free(m->match);
104         free(m);
105 }
106
107 static int match_new(Client *c, struct bus_match_component *components, unsigned n_components, Match **_m) {
108         Match *m, *first;
109         int r;
110
111         assert(c);
112         assert(_m);
113
114         r = hashmap_ensure_allocated(&c->matches, string_hash_func, string_compare_func);
115         if (r < 0)
116                 return r;
117
118         m = new0(Match, 1);
119         if (!m)
120                 return -ENOMEM;
121
122         m->match = bus_match_to_string(components, n_components);
123         if (!m->match) {
124                 r = -ENOMEM;
125                 goto fail;
126         }
127
128         m->cookie = ++c->next_cookie;
129
130         first = hashmap_get(c->matches, m->match);
131         LIST_PREPEND(matches, first, m);
132         r = hashmap_replace(c->matches, m->match, first);
133         if (r == 0) {
134                 log_debug("Match '%s' already installed, ignoring request.", m->match);
135                 LIST_REMOVE(matches, first, m);
136         } else if (r < 0) {
137                 LIST_REMOVE(matches, first, m);
138                 goto fail;
139         }
140
141         m->client = c;
142         c->n_matches++;
143
144         *_m = m;
145         m = NULL;
146
147         return 0;
148
149 fail:
150         match_free(m);
151         return r;
152 }
153
154 static int on_name_owner_changed(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error);
155
156 static void client_free(Client *c) {
157         Match *m;
158
159         if (!c)
160                 return;
161
162         if (c->context) {
163                 if (c->watch)
164                         sd_bus_remove_match(c->context->bus, c->watch, on_name_owner_changed, c);
165
166                 assert_se(hashmap_remove(c->context->clients, &c->id) == c);
167         }
168
169         while ((m = hashmap_first(c->matches)))
170                 match_free(m);
171
172         hashmap_free(c->matches);
173         free(c->watch);
174
175         free(c);
176 }
177
178 static int on_name_owner_changed(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
179         Client *c = userdata;
180
181         assert(bus);
182         assert(m);
183
184         client_free(c);
185         return 0;
186 }
187
188 static int client_acquire(Context *context, uint64_t id, Client **_c) {
189         char *watch = NULL;
190         Client *c;
191         int r;
192
193         assert(context);
194         assert(_c);
195
196         c = hashmap_get(context->clients, &id);
197         if (c) {
198                 *_c = c;
199                 return 0;
200         }
201
202         if (hashmap_size(context->clients) >= CLIENTS_MAX)
203                 return -ENOBUFS;
204
205         r = hashmap_ensure_allocated(&context->clients, uint64_hash_func, uint64_compare_func);
206         if (r < 0)
207                 return r;
208
209         c = new0(Client, 1);
210         if (!c)
211                 return -ENOMEM;
212
213         c->id = id;
214
215         r = hashmap_put(context->clients, &c->id, c);
216         if (r < 0)
217                 goto fail;
218
219         c->context = context;
220
221         if (asprintf(&watch,
222                      "type='signal',"
223                      "sender='org.freedesktop.DBus',"
224                      "path='/org/freedesktop/DBus',"
225                      "interface='org.freedesktop.DBus',"
226                      "member='NameOwnerChanged',"
227                      "arg0=':1.%llu'", (unsigned long long) id) < 0) {
228                 r = -ENOMEM;
229                 goto fail;
230         }
231
232         r = sd_bus_add_match(context->bus, watch, on_name_owner_changed, c);
233         if (r < 0) {
234                 free(watch);
235                 goto fail;
236         }
237
238         c->watch = watch;
239
240         *_c = c;
241         return 0;
242
243 fail:
244         client_free(c);
245         return r;
246 }
247
248 static int driver_add_match(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
249
250         struct bus_match_component *components = NULL;
251         Context *context = userdata;
252         unsigned n_components = 0;
253         Match *m = NULL;
254         Client *c = NULL;
255         char *arg0;
256         uint64_t id;
257         int r;
258
259         assert(bus);
260         assert(message);
261         assert(context);
262
263         r = sd_bus_message_read(message, "s", &arg0);
264         if (r < 0)
265                 return r;
266
267         r = bus_kernel_parse_unique_name(message->sender, &id);
268         if (r < 0)
269                 return r;
270
271         r = client_acquire(context, id, &c);
272         if (r == -ENOBUFS)
273                 return sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Reached limit of %u clients", CLIENTS_MAX);
274         if (r < 0)
275                 return r;
276
277         if (c->n_matches >= MATCHES_MAX) {
278                 r = sd_bus_error_setf(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Reached limit of %u matches per client", MATCHES_MAX);
279                 goto fail;
280         }
281
282         r = bus_match_parse(arg0, &components, &n_components);
283         if (r < 0) {
284                 r = sd_bus_error_setf(error, SD_BUS_ERROR_MATCH_RULE_INVALID, "Match rule \"%s\" is not valid", arg0);
285                 goto fail;
286         }
287
288         r = match_new(c, components, n_components, &m);
289         if (r < 0)
290                 goto fail;
291
292         r = bus_add_match_internal_kernel(bus, id, components, n_components, m->cookie);
293         if (r < 0)
294                 goto fail;
295
296         bus_match_parse_free(components, n_components);
297
298         return sd_bus_reply_method_return(message, NULL);
299
300 fail:
301         bus_match_parse_free(components, n_components);
302
303         match_free(m);
304
305         if (c->n_matches <= 0)
306                 client_free(c);
307
308         return r;
309 }
310
311 static int driver_remove_match(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
312
313         struct bus_match_component *components = NULL;
314         _cleanup_free_ char *normalized = NULL;
315         Context *context = userdata;
316         unsigned n_components = 0;
317         Client *c = NULL;
318         Match *m = NULL;
319         char *arg0;
320         uint64_t id;
321         int r;
322
323         assert(bus);
324         assert(message);
325         assert(context);
326
327         r = sd_bus_message_read(message, "s", &arg0);
328         if (r < 0)
329                 return r;
330
331         r = bus_kernel_parse_unique_name(message->sender, &id);
332         if (r < 0)
333                 return r;
334
335         c = hashmap_get(context->clients, &id);
336         if (!c)
337                 return sd_bus_error_setf(error, SD_BUS_ERROR_MATCH_RULE_NOT_FOUND, "You have not registered any matches.");
338
339         r = bus_match_parse(arg0, &components, &n_components);
340         if (r < 0) {
341                 r = sd_bus_error_setf(error, SD_BUS_ERROR_MATCH_RULE_INVALID, "Match rule \"%s\" is not valid", arg0);
342                 goto finish;
343         }
344
345         normalized = bus_match_to_string(components, n_components);
346         if (!normalized) {
347                 r = -ENOMEM;
348                 goto finish;
349         }
350
351         m = hashmap_get(c->matches, normalized);
352         if (!m) {
353                 r = sd_bus_error_setf(error, SD_BUS_ERROR_MATCH_RULE_NOT_FOUND, "Match rule \"%s\" not found.", normalized);
354                 goto finish;
355         }
356
357         bus_remove_match_internal_kernel(bus, id, m->cookie);
358         match_free(m);
359
360         r = sd_bus_reply_method_return(message, NULL);
361
362 finish:
363         bus_match_parse_free(components, n_components);
364
365         if (c->n_matches <= 0)
366                 client_free(c);
367
368         return r;
369 }
370
371 static int get_creds(sd_bus *bus, sd_bus_message *m, uint64_t mask, sd_bus_creds **_creds, sd_bus_error *error) {
372         _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
373         const char *name;
374         int r;
375
376         assert(bus);
377         assert(m);
378         assert(_creds);
379
380         r = sd_bus_message_read(m, "s", &name);
381         if (r < 0)
382                 return r;
383
384         assert_return(service_name_is_valid(name), -EINVAL);
385
386         r = sd_bus_get_owner(bus, name, mask, &c);
387         if (r == -ENOENT || r == -ENXIO)
388                 return sd_bus_error_setf(error, SD_BUS_ERROR_NAME_HAS_NO_OWNER, "Name %s is currently not owned by anyone.", name);
389         if (r < 0)
390                 return r;
391
392         if ((c->mask & mask) != mask)
393                 return -ENOTSUP;
394
395         *_creds = c;
396         c = NULL;
397
398         return 0;
399 }
400
401 static int driver_get_security_context(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
402         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
403         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
404         int r;
405
406         r = get_creds(bus, m, SD_BUS_CREDS_SELINUX_CONTEXT, &creds, error);
407         if (r < 0)
408                 return r;
409
410         r = sd_bus_message_new_method_return(m, &reply);
411         if (r < 0)
412                 return r;
413
414         r = sd_bus_message_append_array(reply, 'y', creds->label, strlen(creds->label));
415         if (r < 0)
416                 return r;
417
418         return sd_bus_send(bus, reply, NULL);
419 }
420
421 static int driver_get_pid(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
422         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
423         int r;
424
425         r = get_creds(bus, m, SD_BUS_CREDS_PID, &creds, error);
426         if (r < 0)
427                 return r;
428
429         return sd_bus_reply_method_return(m, "u", (uint32_t) creds->pid);
430 }
431
432 static int driver_get_user(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
433         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
434         int r;
435
436         r = get_creds(bus, m, SD_BUS_CREDS_UID, &creds, error);
437         if (r < 0)
438                 return r;
439
440         return sd_bus_reply_method_return(m, "u", (uint32_t) creds->uid);
441 }
442
443 static int driver_get_name_owner(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
444         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
445         int r;
446
447         r = get_creds(bus, m, SD_BUS_CREDS_UNIQUE_NAME, &creds, error);
448         if (r < 0)
449                 return r;
450
451         return sd_bus_reply_method_return(m, "s", creds->unique_name);
452 }
453
454 static int driver_get_id(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
455         sd_id128_t server_id;
456         char buf[SD_ID128_STRING_MAX];
457         int r;
458
459         r = sd_bus_get_server_id(bus, &server_id);
460         if (r < 0)
461                 return r;
462
463         return sd_bus_reply_method_return(m, "s", sd_id128_to_string(server_id, buf));
464 }
465
466 static int driver_hello(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
467         return sd_bus_reply_method_return(m, "s", m->sender);
468 }
469
470 static int return_strv(sd_bus *bus, sd_bus_message *m, char **l) {
471         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
472         int r;
473
474         r = sd_bus_message_new_method_return(m, &reply);
475         if (r < 0)
476                 return r;
477
478         r = sd_bus_message_append_strv(reply, l);
479         if (r < 0)
480                 return r;
481
482         return sd_bus_send(bus, reply, NULL);
483 }
484
485 static int driver_list_names(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
486         _cleanup_strv_free_ char **names = NULL;
487         int r;
488
489         r = sd_bus_list_names(bus, &names, NULL);
490         if (r < 0)
491                 return r;
492
493         /* Let's sort the names list to make it stable */
494         strv_sort(names);
495
496         return return_strv(bus, m, names);
497 }
498
499 static int driver_list_activatable_names(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
500         _cleanup_strv_free_ char **names = NULL;
501         int r;
502
503         r = sd_bus_list_names(bus, NULL, &names);
504         if (r < 0)
505                 return r;
506
507         /* Let's sort the names list to make it stable */
508         strv_sort(names);
509
510         return return_strv(bus, m, names);
511 }
512
513 static int driver_list_queued_owners(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
514         struct kdbus_cmd_name_list cmd = {};
515         struct kdbus_name_list *name_list;
516         struct kdbus_cmd_name *name;
517         _cleanup_strv_free_ char **owners = NULL;
518         char *arg0;
519         int r;
520
521         r = sd_bus_message_read(m, "s", &arg0);
522         if (r < 0)
523                 return r;
524
525         assert_return(service_name_is_valid(arg0), -EINVAL);
526
527         cmd.flags = KDBUS_NAME_LIST_QUEUED;
528
529         r = ioctl(bus->input_fd, KDBUS_CMD_NAME_LIST, &cmd);
530         if (r < 0)
531                 return -errno;
532
533         name_list = (struct kdbus_name_list *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
534
535         KDBUS_ITEM_FOREACH(name, name_list, names) {
536                 char *n;
537
538                 if (name->size <= sizeof(*name))
539                         continue;
540
541                 if (!streq(name->name, arg0))
542                         continue;
543
544                 if (asprintf(&n, ":1.%llu", (unsigned long long) name->owner_id) < 0)
545                         return -ENOMEM;
546
547                 r = strv_push(&owners, n);
548                 if (r < 0) {
549                         free(n);
550                         return -ENOMEM;
551                 }
552         }
553
554         r = ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd.offset);
555         if (r < 0)
556                 return -errno;
557
558         return return_strv(bus, m, owners);
559 }
560
561 static int driver_name_has_owner(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
562         const char *name;
563         int r;
564
565         r = sd_bus_message_read(m, "s", &name);
566         if (r < 0)
567                 return r;
568
569         assert_return(service_name_is_valid(name), -EINVAL);
570
571         r = sd_bus_get_owner(bus, name, 0, NULL);
572         if (r < 0 && r != -ENOENT && r != -ENXIO)
573                 return r;
574
575         return sd_bus_reply_method_return(m, "b", r >= 0);
576 }
577
578 static int driver_request_name(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
579         struct kdbus_cmd_name *n;
580         uint32_t flags;
581         size_t size, l;
582         uint64_t id;
583         const char *name;
584         int r;
585
586         r = sd_bus_message_read(m, "su", &name, &flags);
587         if (r < 0)
588                 return r;
589
590         assert_return(service_name_is_valid(name), -EINVAL);
591         assert_return((flags & ~(BUS_NAME_ALLOW_REPLACEMENT|BUS_NAME_REPLACE_EXISTING|BUS_NAME_DO_NOT_QUEUE)) == 0, -EINVAL);
592
593         l = strlen(name);
594         size = offsetof(struct kdbus_cmd_name, name) + l + 1;
595         n = alloca0(size);
596         n->size = size;
597         memcpy(n->name, name, l+1);
598         kdbus_translate_request_name_flags(flags, (uint64_t *) &n->flags);
599
600         /* This function is open-coded because we request the name 'on behalf'
601          * of the requesting connection */
602         r = bus_kernel_parse_unique_name(m->sender, &id);
603         if (r < 0)
604                 return r;
605
606         n->owner_id = id;
607
608         r = ioctl(bus->input_fd, KDBUS_CMD_NAME_ACQUIRE, n);
609         if (r < 0) {
610                 if (errno == EEXIST)
611                         return sd_bus_reply_method_return(m, "u", BUS_NAME_EXISTS);
612                 if (errno == EALREADY)
613                         return sd_bus_reply_method_return(m, "u", BUS_NAME_ALREADY_OWNER);
614
615                 return -errno;
616         }
617
618         if (n->flags & KDBUS_NAME_IN_QUEUE)
619                 return sd_bus_reply_method_return(m, "u", BUS_NAME_IN_QUEUE);
620
621         return sd_bus_reply_method_return(m, "u", BUS_NAME_PRIMARY_OWNER);
622 }
623
624 static int driver_release_name(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
625         struct kdbus_cmd_name *n;
626         const char *name;
627         size_t l, size;
628         uint64_t id;
629         int r;
630
631         r = sd_bus_message_read(m, "s", &name);
632         if (r < 0)
633                 return r;
634
635         assert_return(service_name_is_valid(name), -EINVAL);
636
637         l = strlen(name);
638         size = offsetof(struct kdbus_cmd_name, name) + l + 1;
639         n = alloca0(size);
640         n->size = size;
641         memcpy(n->name, name, l+1);
642
643         /* This function is open-coded because we request the name 'on behalf'
644          * of the requesting connection */
645         r = bus_kernel_parse_unique_name(m->sender, &id);
646         if (r < 0)
647                 return r;
648
649         n->owner_id = id;
650
651         r = ioctl(bus->input_fd, KDBUS_CMD_NAME_RELEASE, n);
652         if (r < 0) {
653                 if (errno == ESRCH)
654                         return sd_bus_reply_method_return(m, "u", BUS_NAME_NON_EXISTENT);
655                 if (errno == EADDRINUSE)
656                         return sd_bus_reply_method_return(m, "u", BUS_NAME_NOT_OWNER);
657                 return -errno;
658         }
659
660         return sd_bus_reply_method_return(m, "u", BUS_NAME_RELEASED);
661 }
662
663 static int driver_start_service_by_name(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
664         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
665         _cleanup_strv_free_ char **t = NULL;
666         _cleanup_free_ char *path = NULL;
667         uint32_t flags;
668         char *name, *u;
669         int r;
670
671         r = sd_bus_message_read(m, "su", &name, &flags);
672         if (r < 0)
673                 return r;
674
675         assert_return(service_name_is_valid(name), -EINVAL);
676         assert_return(flags == 0, -ENOTSUP);
677
678         r = sd_bus_get_owner(bus, name, 0, NULL);
679         if (r >= 0)
680                 return sd_bus_reply_method_return(m, "u", BUS_START_REPLY_ALREADY_RUNNING);
681         if (r != -ENOENT)
682                 return r;
683
684         u = strappenda(name, ".busname");
685
686         path = unit_dbus_path_from_name(u);
687         if (!path)
688                 return -ENOMEM;
689
690         r = sd_bus_get_property_strv(
691                         bus,
692                         "org.freedesktop.systemd1",
693                         path,
694                         "org.freedesktop.systemd1.Unit",
695                         "Triggers",
696                         error,
697                         &t);
698         if (r < 0)
699                 return r;
700
701         if (!t || !t[0] || t[1])
702                 return sd_bus_error_setf(error, SD_BUS_ERROR_SERVICE_UNKNOWN, "Bus name %s not found.", name);
703
704         r = sd_bus_call_method(
705                         bus,
706                         "org.freedesktop.systemd1",
707                         "/org/freedesktop/systemd1",
708                         "org.freedesktop.systemd1.Manager",
709                         "StartUnit",
710                         error,
711                         &reply,
712                         "ss",
713                         t[0],
714                         "replace");
715         if (r < 0)
716                 return r;
717
718         return sd_bus_reply_method_return(m, "u", BUS_START_REPLY_SUCCESS);
719 }
720
721 static int driver_update_environment(sd_bus*bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
722         _cleanup_bus_message_unref_ sd_bus_message *msg = NULL;
723         _cleanup_strv_free_ char **args = NULL;
724         int r;
725
726         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{ss}");
727         if (r < 0)
728                 return r;
729
730        while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "ss")) > 0) {
731                 _cleanup_free_ char *s = NULL;
732                 const char *key;
733                 const char *value;
734
735                 r = sd_bus_message_read(m, "ss", &key, &value);
736                 if (r < 0)
737                         return r;
738
739                 s = strjoin(key, "=", value, NULL);
740                 if (!s)
741                         return ENOMEM;
742
743                 r  = strv_extend(&args, s);
744                 if (r < 0)
745                         return r;
746
747                 r = sd_bus_message_exit_container(m);
748                 if (r < 0)
749                         return r;
750         }
751
752         r = sd_bus_message_exit_container(m);
753         if (r < 0)
754                 return r;
755
756         if (!args)
757                 return -EINVAL;
758
759         r = sd_bus_message_new_method_call(
760                         bus,
761                         "org.freedesktop.systemd1",
762                         "/org/freedesktop/systemd1",
763                         "org.freedesktop.systemd1.Manager",
764                         "SetEnvironment",
765                         &msg);
766         if (r < 0)
767                 return r;
768
769         r = sd_bus_message_append_strv(msg, args);
770         if (r < 0)
771                 return r;
772
773         r = sd_bus_call(bus, msg, 0, NULL, NULL);
774         if (r < 0)
775                 return r;
776
777         return sd_bus_reply_method_return(m, NULL);
778 }
779
780 static int driver_unsupported(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
781         return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "%s() is not supported", sd_bus_message_get_member(m));
782 }
783
784 static const sd_bus_vtable driver_vtable[] = {
785         SD_BUS_VTABLE_START(0),
786         SD_BUS_METHOD("AddMatch", "s", NULL, driver_add_match, SD_BUS_VTABLE_UNPRIVILEGED),
787         SD_BUS_METHOD("GetConnectionSELinuxSecurityContext", "s", "ay", driver_get_security_context, SD_BUS_VTABLE_UNPRIVILEGED),
788         SD_BUS_METHOD("GetConnectionUnixProcessID", "s", "u", driver_get_pid, SD_BUS_VTABLE_UNPRIVILEGED),
789         SD_BUS_METHOD("GetConnectionUnixUser", "s", "u", driver_get_user, SD_BUS_VTABLE_UNPRIVILEGED),
790         SD_BUS_METHOD("GetId", NULL, "s", driver_get_id, SD_BUS_VTABLE_UNPRIVILEGED),
791         SD_BUS_METHOD("GetNameOwner", "s", "s", driver_get_name_owner, SD_BUS_VTABLE_UNPRIVILEGED),
792         SD_BUS_METHOD("Hello", NULL, "s", driver_hello, SD_BUS_VTABLE_UNPRIVILEGED),
793         SD_BUS_METHOD("ListActivatableNames", NULL, "as", driver_list_activatable_names, SD_BUS_VTABLE_UNPRIVILEGED),
794         SD_BUS_METHOD("ListNames", NULL, "as", driver_list_names, SD_BUS_VTABLE_UNPRIVILEGED),
795         SD_BUS_METHOD("ListQueuedOwners", "s", "as", driver_list_queued_owners, SD_BUS_VTABLE_UNPRIVILEGED),
796         SD_BUS_METHOD("NameHasOwner", "s", "b", driver_name_has_owner, SD_BUS_VTABLE_UNPRIVILEGED),
797         SD_BUS_METHOD("ReleaseName", "s", "u", driver_release_name, SD_BUS_VTABLE_UNPRIVILEGED),
798         SD_BUS_METHOD("ReloadConfig", NULL, NULL, driver_unsupported, SD_BUS_VTABLE_DEPRECATED),
799         SD_BUS_METHOD("RemoveMatch", "s", NULL, driver_remove_match, SD_BUS_VTABLE_UNPRIVILEGED),
800         SD_BUS_METHOD("RequestName", "su", "u", driver_request_name, SD_BUS_VTABLE_UNPRIVILEGED),
801         SD_BUS_METHOD("StartServiceByName", "su", "u", driver_start_service_by_name, SD_BUS_VTABLE_UNPRIVILEGED),
802         SD_BUS_METHOD("UpdateActivationEnvironment", "a{ss}", NULL, driver_update_environment, 0),
803         SD_BUS_SIGNAL("NameAcquired", "s", SD_BUS_VTABLE_DEPRECATED),
804         SD_BUS_SIGNAL("NameLost", "s", SD_BUS_VTABLE_DEPRECATED),
805         SD_BUS_SIGNAL("NameOwnerChanged", "sss", 0),
806         SD_BUS_VTABLE_END
807 };
808
809 static int connect_bus(Context *c) {
810         int r;
811
812         assert(c);
813
814         r = cg_pid_get_owner_uid(0, NULL);
815         if (r < 0)
816                 r = sd_bus_default_system(&c->bus);
817         else
818                 r = sd_bus_default_user(&c->bus);
819         if (r < 0) {
820                 log_error("Failed to create bus: %s", strerror(-r));
821                 return r;
822         }
823
824         if (!c->bus->is_kernel) {
825                 log_error("Not running on kdbus");
826                 return -EPERM;
827         }
828
829         r = sd_bus_add_object_vtable(c->bus, "/org/freedesktop/DBus", "org.freedesktop.DBus", driver_vtable, c);
830         if (r < 0) {
831                 log_error("Failed to add manager object vtable: %s", strerror(-r));
832                 return r;
833         }
834
835         r = sd_bus_request_name(c->bus, "org.freedesktop.DBus", 0);
836         if (r < 0) {
837                 log_error("Unable to request name: %s", strerror(-r));
838                 return r;
839         }
840
841         r = sd_bus_attach_event(c->bus, c->event, 0);
842         if (r < 0) {
843                 log_error("Error while adding bus to event loop: %s", strerror(-r));
844                 return r;
845         }
846
847         return 0;
848 }
849
850 static bool check_idle(void *userdata) {
851         Context *c = userdata;
852         assert(c);
853
854         return hashmap_isempty(c->clients);
855 }
856
857 int main(int argc, char *argv[]) {
858         Context context = {};
859         Client *c;
860         int r;
861
862         log_set_target(LOG_TARGET_AUTO);
863         log_parse_environment();
864         log_open();
865
866         if (argc != 1) {
867                 log_error("This program takes no arguments.");
868                 r = -EINVAL;
869                 goto finish;
870         }
871
872         r = sd_event_default(&context.event);
873         if (r < 0) {
874                 log_error("Failed to allocate event loop: %s", strerror(-r));
875                 goto finish;
876         }
877
878         sd_event_set_watchdog(context.event, true);
879
880         r = connect_bus(&context);
881         if (r < 0)
882                 goto finish;
883
884         r = bus_event_loop_with_idle(context.event, context.bus, "org.freedesktop.DBus", DEFAULT_EXIT_USEC, check_idle, &context);
885         if (r < 0) {
886                 log_error("Failed to run event loop: %s", strerror(-r));
887                 goto finish;
888         }
889
890 finish:
891         while ((c = hashmap_first(context.clients)))
892                 client_free(c);
893
894         sd_bus_unref(context.bus);
895         sd_event_unref(context.event);
896
897         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
898 }