chiark / gitweb /
96296aa1c1fabf4f12ebb6499b5df7f5f131fbf5
[elogind.git] / src / libelogind / sd-bus / bus-util.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 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/socket.h>
23
24 #include "sd-daemon.h"
25 #include "sd-event.h"
26 #include "util.h"
27 #include "strv.h"
28 #include "macro.h"
29 #include "def.h"
30 #include "path-util.h"
31 #include "missing.h"
32 #include "set.h"
33 #include "signal-util.h"
34 #include "unit-name.h"
35
36 #include "sd-bus.h"
37 #include "bus-error.h"
38 #include "bus-label.h"
39 #include "bus-message.h"
40 #include "bus-util.h"
41 #include "bus-internal.h"
42
43 static int name_owner_change_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
44         sd_event *e = userdata;
45
46         assert(m);
47         assert(e);
48
49         sd_bus_close(sd_bus_message_get_bus(m));
50         sd_event_exit(e, 0);
51
52         return 1;
53 }
54
55 int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) {
56         _cleanup_free_ char *match = NULL;
57         const char *unique;
58         int r;
59
60         assert(e);
61         assert(bus);
62         assert(name);
63
64         /* We unregister the name here and then wait for the
65          * NameOwnerChanged signal for this event to arrive before we
66          * quit. We do this in order to make sure that any queued
67          * requests are still processed before we really exit. */
68
69         r = sd_bus_get_unique_name(bus, &unique);
70         if (r < 0)
71                 return r;
72
73         r = asprintf(&match,
74                      "sender='org.freedesktop.DBus',"
75                      "type='signal',"
76                      "interface='org.freedesktop.DBus',"
77                      "member='NameOwnerChanged',"
78                      "path='/org/freedesktop/DBus',"
79                      "arg0='%s',"
80                      "arg1='%s',"
81                      "arg2=''", name, unique);
82         if (r < 0)
83                 return -ENOMEM;
84
85         r = sd_bus_add_match(bus, NULL, match, name_owner_change_callback, e);
86         if (r < 0)
87                 return r;
88
89         r = sd_bus_release_name(bus, name);
90         if (r < 0)
91                 return r;
92
93         return 0;
94 }
95
96 int bus_event_loop_with_idle(
97                 sd_event *e,
98                 sd_bus *bus,
99                 const char *name,
100                 usec_t timeout,
101                 check_idle_t check_idle,
102                 void *userdata) {
103         bool exiting = false;
104         int r, code;
105
106         assert(e);
107         assert(bus);
108         assert(name);
109
110         for (;;) {
111                 bool idle;
112
113                 r = sd_event_get_state(e);
114                 if (r < 0)
115                         return r;
116                 if (r == SD_EVENT_FINISHED)
117                         break;
118
119                 if (check_idle)
120                         idle = check_idle(userdata);
121                 else
122                         idle = true;
123
124                 r = sd_event_run(e, exiting || !idle ? (uint64_t) -1 : timeout);
125                 if (r < 0)
126                         return r;
127
128                 if (r == 0 && !exiting && idle) {
129
130                         r = sd_bus_try_close(bus);
131                         if (r == -EBUSY)
132                                 continue;
133
134                         /* Fallback for dbus1 connections: we
135                          * unregister the name and wait for the
136                          * response to come through for it */
137                         if (r == -EOPNOTSUPP) {
138
139                                 /* Inform the service manager that we
140                                  * are going down, so that it will
141                                  * queue all further start requests,
142                                  * instead of assuming we are already
143                                  * running. */
144                                 sd_notify(false, "STOPPING=1");
145
146                                 r = bus_async_unregister_and_exit(e, bus, name);
147                                 if (r < 0)
148                                         return r;
149
150                                 exiting = true;
151                                 continue;
152                         }
153
154                         if (r < 0)
155                                 return r;
156
157                         sd_event_exit(e, 0);
158                         break;
159                 }
160         }
161
162         r = sd_event_get_exit_code(e, &code);
163         if (r < 0)
164                 return r;
165
166         return code;
167 }
168
169 int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) {
170         _cleanup_bus_message_unref_ sd_bus_message *rep = NULL;
171         int r, has_owner = 0;
172
173         assert(c);
174         assert(name);
175
176         r = sd_bus_call_method(c,
177                                "org.freedesktop.DBus",
178                                "/org/freedesktop/dbus",
179                                "org.freedesktop.DBus",
180                                "NameHasOwner",
181                                error,
182                                &rep,
183                                "s",
184                                name);
185         if (r < 0)
186                 return r;
187
188         r = sd_bus_message_read_basic(rep, 'b', &has_owner);
189         if (r < 0)
190                 return sd_bus_error_set_errno(error, r);
191
192         return has_owner;
193 }
194
195 static int check_good_user(sd_bus_message *m, uid_t good_user) {
196         _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
197         uid_t sender_uid;
198         int r;
199
200         assert(m);
201
202         if (good_user == UID_INVALID)
203                 return 0;
204
205         r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_EUID, &creds);
206         if (r < 0)
207                 return r;
208
209         /* Don't trust augmented credentials for authorization */
210         assert_return((sd_bus_creds_get_augmented_mask(creds) & SD_BUS_CREDS_EUID) == 0, -EPERM);
211
212         r = sd_bus_creds_get_euid(creds, &sender_uid);
213         if (r < 0)
214                 return r;
215
216         return sender_uid == good_user;
217 }
218
219 int bus_test_polkit(
220                 sd_bus_message *call,
221                 int capability,
222                 const char *action,
223                 uid_t good_user,
224                 bool *_challenge,
225                 sd_bus_error *e) {
226
227         int r;
228
229         assert(call);
230         assert(action);
231
232         /* Tests non-interactively! */
233
234         r = check_good_user(call, good_user);
235         if (r != 0)
236                 return r;
237
238         r = sd_bus_query_sender_privilege(call, capability);
239         if (r < 0)
240                 return r;
241         else if (r > 0)
242                 return 1;
243 #ifdef ENABLE_POLKIT
244         else {
245                 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
246                 int authorized = false, challenge = false;
247                 const char *sender;
248
249                 sender = sd_bus_message_get_sender(call);
250                 if (!sender)
251                         return -EBADMSG;
252
253                 r = sd_bus_call_method(
254                                 call->bus,
255                                 "org.freedesktop.PolicyKit1",
256                                 "/org/freedesktop/PolicyKit1/Authority",
257                                 "org.freedesktop.PolicyKit1.Authority",
258                                 "CheckAuthorization",
259                                 e,
260                                 &reply,
261                                 "(sa{sv})sa{ss}us",
262                                 "system-bus-name", 1, "name", "s", sender,
263                                 action,
264                                 0,
265                                 0,
266                                 "");
267
268                 if (r < 0) {
269                         /* Treat no PK available as access denied */
270                         if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
271                                 sd_bus_error_free(e);
272                                 return -EACCES;
273                         }
274
275                         return r;
276                 }
277
278                 r = sd_bus_message_enter_container(reply, 'r', "bba{ss}");
279                 if (r < 0)
280                         return r;
281
282                 r = sd_bus_message_read(reply, "bb", &authorized, &challenge);
283                 if (r < 0)
284                         return r;
285
286                 if (authorized)
287                         return 1;
288
289                 if (_challenge) {
290                         *_challenge = challenge;
291                         return 0;
292                 }
293         }
294 #endif
295
296         return -EACCES;
297 }
298
299 #ifdef ENABLE_POLKIT
300
301 typedef struct AsyncPolkitQuery {
302         sd_bus_message *request, *reply;
303         sd_bus_message_handler_t callback;
304         void *userdata;
305         sd_bus_slot *slot;
306         Hashmap *registry;
307 } AsyncPolkitQuery;
308
309 static void async_polkit_query_free(AsyncPolkitQuery *q) {
310
311         if (!q)
312                 return;
313
314         sd_bus_slot_unref(q->slot);
315
316         if (q->registry && q->request)
317                 hashmap_remove(q->registry, q->request);
318
319         sd_bus_message_unref(q->request);
320         sd_bus_message_unref(q->reply);
321
322         free(q);
323 }
324
325 static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
326         _cleanup_bus_error_free_ sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
327         AsyncPolkitQuery *q = userdata;
328         int r;
329
330         assert(reply);
331         assert(q);
332
333         q->slot = sd_bus_slot_unref(q->slot);
334         q->reply = sd_bus_message_ref(reply);
335
336         r = sd_bus_message_rewind(q->request, true);
337         if (r < 0) {
338                 r = sd_bus_reply_method_errno(q->request, r, NULL);
339                 goto finish;
340         }
341
342         r = q->callback(q->request, q->userdata, &error_buffer);
343         r = bus_maybe_reply_error(q->request, r, &error_buffer);
344
345 finish:
346         async_polkit_query_free(q);
347
348         return r;
349 }
350
351 #endif
352
353 int bus_verify_polkit_async(
354                 sd_bus_message *call,
355                 int capability,
356                 const char *action,
357                 bool interactive,
358                 uid_t good_user,
359                 Hashmap **registry,
360                 sd_bus_error *error) {
361
362 #ifdef ENABLE_POLKIT
363         _cleanup_bus_message_unref_ sd_bus_message *pk = NULL;
364         AsyncPolkitQuery *q;
365         const char *sender;
366         sd_bus_message_handler_t callback;
367         void *userdata;
368         int c;
369 #endif
370         int r;
371
372         assert(call);
373         assert(action);
374         assert(registry);
375
376         r = check_good_user(call, good_user);
377         if (r != 0)
378                 return r;
379
380 #ifdef ENABLE_POLKIT
381         q = hashmap_get(*registry, call);
382         if (q) {
383                 int authorized, challenge;
384
385                 /* This is the second invocation of this function, and
386                  * there's already a response from polkit, let's
387                  * process it */
388                 assert(q->reply);
389
390                 if (sd_bus_message_is_method_error(q->reply, NULL)) {
391                         const sd_bus_error *e;
392
393                         /* Copy error from polkit reply */
394                         e = sd_bus_message_get_error(q->reply);
395                         sd_bus_error_copy(error, e);
396
397                         /* Treat no PK available as access denied */
398                         if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN))
399                                 return -EACCES;
400
401                         return -sd_bus_error_get_errno(e);
402                 }
403
404                 r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}");
405                 if (r >= 0)
406                         r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge);
407
408                 if (r < 0)
409                         return r;
410
411                 if (authorized)
412                         return 1;
413
414                 if (challenge)
415                         return sd_bus_error_set(error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
416
417                 return -EACCES;
418         }
419 #endif
420
421         r = sd_bus_query_sender_privilege(call, capability);
422         if (r < 0)
423                 return r;
424         else if (r > 0)
425                 return 1;
426
427 #ifdef ENABLE_POLKIT
428         if (sd_bus_get_current_message(call->bus) != call)
429                 return -EINVAL;
430
431         callback = sd_bus_get_current_handler(call->bus);
432         if (!callback)
433                 return -EINVAL;
434
435         userdata = sd_bus_get_current_userdata(call->bus);
436
437         sender = sd_bus_message_get_sender(call);
438         if (!sender)
439                 return -EBADMSG;
440
441         c = sd_bus_message_get_allow_interactive_authorization(call);
442         if (c < 0)
443                 return c;
444         if (c > 0)
445                 interactive = true;
446
447         r = hashmap_ensure_allocated(registry, NULL);
448         if (r < 0)
449                 return r;
450
451         r = sd_bus_message_new_method_call(
452                         call->bus,
453                         &pk,
454                         "org.freedesktop.PolicyKit1",
455                         "/org/freedesktop/PolicyKit1/Authority",
456                         "org.freedesktop.PolicyKit1.Authority",
457                         "CheckAuthorization");
458         if (r < 0)
459                 return r;
460
461         r = sd_bus_message_append(
462                         pk,
463                         "(sa{sv})sa{ss}us",
464                         "system-bus-name", 1, "name", "s", sender,
465                         action,
466                         0,
467                         !!interactive,
468                         NULL);
469         if (r < 0)
470                 return r;
471
472         q = new0(AsyncPolkitQuery, 1);
473         if (!q)
474                 return -ENOMEM;
475
476         q->request = sd_bus_message_ref(call);
477         q->callback = callback;
478         q->userdata = userdata;
479
480         r = hashmap_put(*registry, call, q);
481         if (r < 0) {
482                 async_polkit_query_free(q);
483                 return r;
484         }
485
486         q->registry = *registry;
487
488         r = sd_bus_call_async(call->bus, &q->slot, pk, async_polkit_callback, q, 0);
489         if (r < 0) {
490                 async_polkit_query_free(q);
491                 return r;
492         }
493
494         return 0;
495 #endif
496
497         return -EACCES;
498 }
499
500 void bus_verify_polkit_async_registry_free(Hashmap *registry) {
501 #ifdef ENABLE_POLKIT
502         AsyncPolkitQuery *q;
503
504         while ((q = hashmap_steal_first(registry)))
505                 async_polkit_query_free(q);
506
507         hashmap_free(registry);
508 #endif
509 }
510
511 int bus_check_peercred(sd_bus *c) {
512         struct ucred ucred;
513         socklen_t l;
514         int fd;
515
516         assert(c);
517
518         fd = sd_bus_get_fd(c);
519         if (fd < 0)
520                 return fd;
521
522         l = sizeof(struct ucred);
523         if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0)
524                 return -errno;
525
526         if (l != sizeof(struct ucred))
527                 return -E2BIG;
528
529         if (ucred.uid != 0 && ucred.uid != geteuid())
530                 return -EPERM;
531
532         return 1;
533 }
534
535 int bus_open_system_systemd(sd_bus **_bus) {
536         _cleanup_bus_unref_ sd_bus *bus = NULL;
537         int r;
538
539         assert(_bus);
540
541         if (geteuid() != 0)
542                 return sd_bus_open_system(_bus);
543
544         /* If we are root and kdbus is not available, then let's talk
545          * directly to the system instance, instead of going via the
546          * bus */
547
548 #ifdef ENABLE_KDBUS
549         r = sd_bus_new(&bus);
550         if (r < 0)
551                 return r;
552
553         r = sd_bus_set_address(bus, KERNEL_SYSTEM_BUS_ADDRESS);
554         if (r < 0)
555                 return r;
556
557         bus->bus_client = true;
558
559         r = sd_bus_start(bus);
560         if (r >= 0) {
561                 *_bus = bus;
562                 bus = NULL;
563                 return 0;
564         }
565
566         bus = sd_bus_unref(bus);
567 #endif
568
569         r = sd_bus_new(&bus);
570         if (r < 0)
571                 return r;
572
573         r = sd_bus_set_address(bus, "unix:path=/run/systemd/private");
574         if (r < 0)
575                 return r;
576
577         r = sd_bus_start(bus);
578         if (r < 0)
579                 return sd_bus_open_system(_bus);
580
581         r = bus_check_peercred(bus);
582         if (r < 0)
583                 return r;
584
585         *_bus = bus;
586         bus = NULL;
587
588         return 0;
589 }
590
591 int bus_open_user_systemd(sd_bus **_bus) {
592         _cleanup_bus_unref_ sd_bus *bus = NULL;
593         _cleanup_free_ char *ee = NULL;
594         const char *e;
595         int r;
596
597         /* Try via kdbus first, and then directly */
598
599         assert(_bus);
600
601 #ifdef ENABLE_KDBUS
602         r = sd_bus_new(&bus);
603         if (r < 0)
604                 return r;
605
606         if (asprintf(&bus->address, KERNEL_USER_BUS_ADDRESS_FMT, getuid()) < 0)
607                 return -ENOMEM;
608
609         bus->bus_client = true;
610
611         r = sd_bus_start(bus);
612         if (r >= 0) {
613                 *_bus = bus;
614                 bus = NULL;
615                 return 0;
616         }
617
618         bus = sd_bus_unref(bus);
619 #endif
620
621         e = secure_getenv("XDG_RUNTIME_DIR");
622         if (!e)
623                 return sd_bus_open_user(_bus);
624
625         ee = bus_address_escape(e);
626         if (!ee)
627                 return -ENOMEM;
628
629         r = sd_bus_new(&bus);
630         if (r < 0)
631                 return r;
632
633         bus->address = strjoin("unix:path=", ee, "/systemd/private", NULL);
634         if (!bus->address)
635                 return -ENOMEM;
636
637         r = sd_bus_start(bus);
638         if (r < 0)
639                 return sd_bus_open_user(_bus);
640
641         r = bus_check_peercred(bus);
642         if (r < 0)
643                 return r;
644
645         *_bus = bus;
646         bus = NULL;
647
648         return 0;
649 }
650
651 int bus_print_property(const char *name, sd_bus_message *property, bool all) {
652         char type;
653         const char *contents;
654         int r;
655
656         assert(name);
657         assert(property);
658
659         r = sd_bus_message_peek_type(property, &type, &contents);
660         if (r < 0)
661                 return r;
662
663         switch (type) {
664
665         case SD_BUS_TYPE_STRING: {
666                 const char *s;
667
668                 r = sd_bus_message_read_basic(property, type, &s);
669                 if (r < 0)
670                         return r;
671
672                 if (all || !isempty(s)) {
673                         _cleanup_free_ char *escaped = NULL;
674
675                         escaped = xescape(s, "\n");
676                         if (!escaped)
677                                 return -ENOMEM;
678
679                         printf("%s=%s\n", name, escaped);
680                 }
681
682                 return 1;
683         }
684
685         case SD_BUS_TYPE_BOOLEAN: {
686                 int b;
687
688                 r = sd_bus_message_read_basic(property, type, &b);
689                 if (r < 0)
690                         return r;
691
692                 printf("%s=%s\n", name, yes_no(b));
693
694                 return 1;
695         }
696
697         case SD_BUS_TYPE_UINT64: {
698                 uint64_t u;
699
700                 r = sd_bus_message_read_basic(property, type, &u);
701                 if (r < 0)
702                         return r;
703
704                 /* Yes, heuristics! But we can change this check
705                  * should it turn out to not be sufficient */
706
707                 if (endswith(name, "Timestamp")) {
708                         char timestamp[FORMAT_TIMESTAMP_MAX], *t;
709
710                         t = format_timestamp(timestamp, sizeof(timestamp), u);
711                         if (t || all)
712                                 printf("%s=%s\n", name, strempty(t));
713
714                 } else if (strstr(name, "USec")) {
715                         char timespan[FORMAT_TIMESPAN_MAX];
716
717                         printf("%s=%s\n", name, format_timespan(timespan, sizeof(timespan), u, 0));
718                 } else
719                         printf("%s=%llu\n", name, (unsigned long long) u);
720
721                 return 1;
722         }
723
724         case SD_BUS_TYPE_INT64: {
725                 int64_t i;
726
727                 r = sd_bus_message_read_basic(property, type, &i);
728                 if (r < 0)
729                         return r;
730
731                 printf("%s=%lld\n", name, (long long) i);
732
733                 return 1;
734         }
735
736         case SD_BUS_TYPE_UINT32: {
737                 uint32_t u;
738
739                 r = sd_bus_message_read_basic(property, type, &u);
740                 if (r < 0)
741                         return r;
742
743                 if (strstr(name, "UMask") || strstr(name, "Mode"))
744                         printf("%s=%04o\n", name, u);
745                 else
746                         printf("%s=%u\n", name, (unsigned) u);
747
748                 return 1;
749         }
750
751         case SD_BUS_TYPE_INT32: {
752                 int32_t i;
753
754                 r = sd_bus_message_read_basic(property, type, &i);
755                 if (r < 0)
756                         return r;
757
758                 printf("%s=%i\n", name, (int) i);
759                 return 1;
760         }
761
762         case SD_BUS_TYPE_DOUBLE: {
763                 double d;
764
765                 r = sd_bus_message_read_basic(property, type, &d);
766                 if (r < 0)
767                         return r;
768
769                 printf("%s=%g\n", name, d);
770                 return 1;
771         }
772
773         case SD_BUS_TYPE_ARRAY:
774                 if (streq(contents, "s")) {
775                         bool first = true;
776                         const char *str;
777
778                         r = sd_bus_message_enter_container(property, SD_BUS_TYPE_ARRAY, contents);
779                         if (r < 0)
780                                 return r;
781
782                         while((r = sd_bus_message_read_basic(property, SD_BUS_TYPE_STRING, &str)) > 0) {
783                                 _cleanup_free_ char *escaped = NULL;
784
785                                 if (first)
786                                         printf("%s=", name);
787
788                                 escaped = xescape(str, "\n ");
789                                 if (!escaped)
790                                         return -ENOMEM;
791
792                                 printf("%s%s", first ? "" : " ", escaped);
793
794                                 first = false;
795                         }
796                         if (r < 0)
797                                 return r;
798
799                         if (first && all)
800                                 printf("%s=", name);
801                         if (!first || all)
802                                 puts("");
803
804                         r = sd_bus_message_exit_container(property);
805                         if (r < 0)
806                                 return r;
807
808                         return 1;
809
810                 } else if (streq(contents, "y")) {
811                         const uint8_t *u;
812                         size_t n;
813
814                         r = sd_bus_message_read_array(property, SD_BUS_TYPE_BYTE, (const void**) &u, &n);
815                         if (r < 0)
816                                 return r;
817
818                         if (all || n > 0) {
819                                 unsigned int i;
820
821                                 printf("%s=", name);
822
823                                 for (i = 0; i < n; i++)
824                                         printf("%02x", u[i]);
825
826                                 puts("");
827                         }
828
829                         return 1;
830
831                 } else if (streq(contents, "u")) {
832                         uint32_t *u;
833                         size_t n;
834
835                         r = sd_bus_message_read_array(property, SD_BUS_TYPE_UINT32, (const void**) &u, &n);
836                         if (r < 0)
837                                 return r;
838
839                         if (all || n > 0) {
840                                 unsigned int i;
841
842                                 printf("%s=", name);
843
844                                 for (i = 0; i < n; i++)
845                                         printf("%08x", u[i]);
846
847                                 puts("");
848                         }
849
850                         return 1;
851                 }
852
853                 break;
854         }
855
856         return 0;
857 }
858
859 int bus_print_all_properties(sd_bus *bus, const char *dest, const char *path, char **filter, bool all) {
860         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
861         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
862         int r;
863
864         assert(bus);
865         assert(path);
866
867         r = sd_bus_call_method(bus,
868                         dest,
869                         path,
870                         "org.freedesktop.DBus.Properties",
871                         "GetAll",
872                         &error,
873                         &reply,
874                         "s", "");
875         if (r < 0)
876                 return r;
877
878         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
879         if (r < 0)
880                 return r;
881
882         while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
883                 const char *name;
884                 const char *contents;
885
886                 r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &name);
887                 if (r < 0)
888                         return r;
889
890                 if (!filter || strv_find(filter, name)) {
891                         r = sd_bus_message_peek_type(reply, NULL, &contents);
892                         if (r < 0)
893                                 return r;
894
895                         r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
896                         if (r < 0)
897                                 return r;
898
899                         r = bus_print_property(name, reply, all);
900                         if (r < 0)
901                                 return r;
902                         if (r == 0) {
903                                 if (all)
904                                         printf("%s=[unprintable]\n", name);
905                                 /* skip what we didn't read */
906                                 r = sd_bus_message_skip(reply, contents);
907                                 if (r < 0)
908                                         return r;
909                         }
910
911                         r = sd_bus_message_exit_container(reply);
912                         if (r < 0)
913                                 return r;
914                 } else {
915                         r = sd_bus_message_skip(reply, "v");
916                         if (r < 0)
917                                 return r;
918                 }
919
920                 r = sd_bus_message_exit_container(reply);
921                 if (r < 0)
922                         return r;
923         }
924         if (r < 0)
925                 return r;
926
927         r = sd_bus_message_exit_container(reply);
928         if (r < 0)
929                 return r;
930
931         return 0;
932 }
933
934 int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
935         sd_id128_t *p = userdata;
936         const void *v;
937         size_t n;
938         int r;
939
940         r = sd_bus_message_read_array(m, SD_BUS_TYPE_BYTE, &v, &n);
941         if (r < 0)
942                 return r;
943
944         if (n == 0)
945                 *p = SD_ID128_NULL;
946         else if (n == 16)
947                 memcpy((*p).bytes, v, n);
948         else
949                 return -EINVAL;
950
951         return 0;
952 }
953
954 static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
955         char type;
956         int r;
957
958         r = sd_bus_message_peek_type(m, &type, NULL);
959         if (r < 0)
960                 return r;
961
962         switch (type) {
963         case SD_BUS_TYPE_STRING: {
964                 const char *s;
965                 char **p = userdata;
966
967                 r = sd_bus_message_read_basic(m, type, &s);
968                 if (r < 0)
969                         break;
970
971                 if (isempty(s))
972                         break;
973
974                 r = free_and_strdup(p, s);
975                 break;
976         }
977
978         case SD_BUS_TYPE_ARRAY: {
979                _cleanup_strv_free_ char **l = NULL;
980                char ***p = userdata;
981
982                 r = bus_message_read_strv_extend(m, &l);
983                 if (r < 0)
984                         break;
985
986                 strv_free(*p);
987                 *p = l;
988                 l = NULL;
989
990                 break;
991         }
992
993         case SD_BUS_TYPE_BOOLEAN: {
994                 unsigned b;
995                 bool *p = userdata;
996
997                 r = sd_bus_message_read_basic(m, type, &b);
998                 if (r < 0)
999                         break;
1000
1001                 *p = b;
1002
1003                 break;
1004         }
1005
1006         case SD_BUS_TYPE_UINT32: {
1007                 uint64_t u;
1008                 uint32_t *p = userdata;
1009
1010                 r = sd_bus_message_read_basic(m, type, &u);
1011                 if (r < 0)
1012                         break;
1013
1014                 *p = u;
1015
1016                 break;
1017         }
1018
1019         case SD_BUS_TYPE_UINT64: {
1020                 uint64_t t;
1021                 uint64_t *p = userdata;
1022
1023                 r = sd_bus_message_read_basic(m, type, &t);
1024                 if (r < 0)
1025                         break;
1026
1027                 *p = t;
1028
1029                 break;
1030         }
1031
1032         default:
1033                 break;
1034         }
1035
1036         return r;
1037 }
1038
1039 int bus_message_map_all_properties(
1040                 sd_bus_message *m,
1041                 const struct bus_properties_map *map,
1042                 void *userdata) {
1043
1044         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1045         int r;
1046
1047         assert(m);
1048         assert(map);
1049
1050         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
1051         if (r < 0)
1052                 return r;
1053
1054         while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1055                 const struct bus_properties_map *prop;
1056                 const char *member;
1057                 const char *contents;
1058                 void *v;
1059                 unsigned i;
1060
1061                 r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member);
1062                 if (r < 0)
1063                         return r;
1064
1065                 for (i = 0, prop = NULL; map[i].member; i++)
1066                         if (streq(map[i].member, member)) {
1067                                 prop = &map[i];
1068                                 break;
1069                         }
1070
1071                 if (prop) {
1072                         r = sd_bus_message_peek_type(m, NULL, &contents);
1073                         if (r < 0)
1074                                 return r;
1075
1076                         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
1077                         if (r < 0)
1078                                 return r;
1079
1080                         v = (uint8_t *)userdata + prop->offset;
1081                         if (map[i].set)
1082                                 r = prop->set(sd_bus_message_get_bus(m), member, m, &error, v);
1083                         else
1084                                 r = map_basic(sd_bus_message_get_bus(m), member, m, &error, v);
1085                         if (r < 0)
1086                                 return r;
1087
1088                         r = sd_bus_message_exit_container(m);
1089                         if (r < 0)
1090                                 return r;
1091                 } else {
1092                         r = sd_bus_message_skip(m, "v");
1093                         if (r < 0)
1094                                 return r;
1095                 }
1096
1097                 r = sd_bus_message_exit_container(m);
1098                 if (r < 0)
1099                         return r;
1100         }
1101         if (r < 0)
1102                 return r;
1103
1104         return sd_bus_message_exit_container(m);
1105 }
1106
1107 int bus_message_map_properties_changed(
1108                 sd_bus_message *m,
1109                 const struct bus_properties_map *map,
1110                 void *userdata) {
1111
1112         const char *member;
1113         int r, invalidated, i;
1114
1115         assert(m);
1116         assert(map);
1117
1118         r = bus_message_map_all_properties(m, map, userdata);
1119         if (r < 0)
1120                 return r;
1121
1122         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "s");
1123         if (r < 0)
1124                 return r;
1125
1126         invalidated = 0;
1127         while ((r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member)) > 0)
1128                 for (i = 0; map[i].member; i++)
1129                         if (streq(map[i].member, member)) {
1130                                 ++invalidated;
1131                                 break;
1132                         }
1133         if (r < 0)
1134                 return r;
1135
1136         r = sd_bus_message_exit_container(m);
1137         if (r < 0)
1138                 return r;
1139
1140         return invalidated;
1141 }
1142
1143 int bus_map_all_properties(
1144                 sd_bus *bus,
1145                 const char *destination,
1146                 const char *path,
1147                 const struct bus_properties_map *map,
1148                 void *userdata) {
1149
1150         _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
1151         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1152         int r;
1153
1154         assert(bus);
1155         assert(destination);
1156         assert(path);
1157         assert(map);
1158
1159         r = sd_bus_call_method(
1160                         bus,
1161                         destination,
1162                         path,
1163                         "org.freedesktop.DBus.Properties",
1164                         "GetAll",
1165                         &error,
1166                         &m,
1167                         "s", "");
1168         if (r < 0)
1169                 return r;
1170
1171         return bus_message_map_all_properties(m, map, userdata);
1172 }
1173
1174 int bus_open_transport(BusTransport transport, const char *host, bool user, sd_bus **bus) {
1175         int r;
1176
1177         assert(transport >= 0);
1178         assert(transport < _BUS_TRANSPORT_MAX);
1179         assert(bus);
1180
1181         assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
1182         assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -EOPNOTSUPP);
1183
1184         switch (transport) {
1185
1186         case BUS_TRANSPORT_LOCAL:
1187                 if (user)
1188                         r = sd_bus_default_user(bus);
1189                 else
1190                         r = sd_bus_default_system(bus);
1191
1192                 break;
1193
1194         case BUS_TRANSPORT_REMOTE:
1195                 r = sd_bus_open_system_remote(bus, host);
1196                 break;
1197
1198         case BUS_TRANSPORT_MACHINE:
1199                 r = sd_bus_open_system_machine(bus, host);
1200                 break;
1201
1202         default:
1203                 assert_not_reached("Hmm, unknown transport type.");
1204         }
1205
1206         return r;
1207 }
1208
1209 int bus_open_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) {
1210         int r;
1211
1212         assert(transport >= 0);
1213         assert(transport < _BUS_TRANSPORT_MAX);
1214         assert(bus);
1215
1216         assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
1217         assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -EOPNOTSUPP);
1218
1219         switch (transport) {
1220
1221         case BUS_TRANSPORT_LOCAL:
1222                 if (user)
1223                         r = bus_open_user_systemd(bus);
1224                 else
1225                         r = bus_open_system_systemd(bus);
1226
1227                 break;
1228
1229         case BUS_TRANSPORT_REMOTE:
1230                 r = sd_bus_open_system_remote(bus, host);
1231                 break;
1232
1233         case BUS_TRANSPORT_MACHINE:
1234                 r = sd_bus_open_system_machine(bus, host);
1235                 break;
1236
1237         default:
1238                 assert_not_reached("Hmm, unknown transport type.");
1239         }
1240
1241         return r;
1242 }
1243
1244 int bus_property_get_bool(
1245                 sd_bus *bus,
1246                 const char *path,
1247                 const char *interface,
1248                 const char *property,
1249                 sd_bus_message *reply,
1250                 void *userdata,
1251                 sd_bus_error *error) {
1252
1253         int b = *(bool*) userdata;
1254
1255         return sd_bus_message_append_basic(reply, 'b', &b);
1256 }
1257
1258 #if __SIZEOF_SIZE_T__ != 8
1259 int bus_property_get_size(
1260                 sd_bus *bus,
1261                 const char *path,
1262                 const char *interface,
1263                 const char *property,
1264                 sd_bus_message *reply,
1265                 void *userdata,
1266                 sd_bus_error *error) {
1267
1268         uint64_t sz = *(size_t*) userdata;
1269
1270         return sd_bus_message_append_basic(reply, 't', &sz);
1271 }
1272 #endif
1273
1274 #if __SIZEOF_LONG__ != 8
1275 int bus_property_get_long(
1276                 sd_bus *bus,
1277                 const char *path,
1278                 const char *interface,
1279                 const char *property,
1280                 sd_bus_message *reply,
1281                 void *userdata,
1282                 sd_bus_error *error) {
1283
1284         int64_t l = *(long*) userdata;
1285
1286         return sd_bus_message_append_basic(reply, 'x', &l);
1287 }
1288
1289 int bus_property_get_ulong(
1290                 sd_bus *bus,
1291                 const char *path,
1292                 const char *interface,
1293                 const char *property,
1294                 sd_bus_message *reply,
1295                 void *userdata,
1296                 sd_bus_error *error) {
1297
1298         uint64_t ul = *(unsigned long*) userdata;
1299
1300         return sd_bus_message_append_basic(reply, 't', &ul);
1301 }
1302 #endif
1303
1304 int bus_log_parse_error(int r) {
1305         return log_error_errno(r, "Failed to parse bus message: %m");
1306 }
1307
1308 int bus_log_create_error(int r) {
1309         return log_error_errno(r, "Failed to create bus message: %m");
1310 }
1311
1312 int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u) {
1313         assert(message);
1314         assert(u);
1315
1316         u->machine = NULL;
1317
1318         return sd_bus_message_read(
1319                         message,
1320                         "(ssssssouso)",
1321                         &u->id,
1322                         &u->description,
1323                         &u->load_state,
1324                         &u->active_state,
1325                         &u->sub_state,
1326                         &u->following,
1327                         &u->unit_path,
1328                         &u->job_id,
1329                         &u->job_type,
1330                         &u->job_path);
1331 }
1332
1333 int bus_maybe_reply_error(sd_bus_message *m, int r, sd_bus_error *error) {
1334         assert(m);
1335
1336         if (r < 0) {
1337                 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
1338                         sd_bus_reply_method_errno(m, r, error);
1339
1340         } else if (sd_bus_error_is_set(error)) {
1341                 if (m->header->type == SD_BUS_MESSAGE_METHOD_CALL)
1342                         sd_bus_reply_method_error(m, error);
1343         } else
1344                 return r;
1345
1346         log_debug("Failed to process message [type=%s sender=%s path=%s interface=%s member=%s signature=%s]: %s",
1347                   bus_message_type_to_string(m->header->type),
1348                   strna(m->sender),
1349                   strna(m->path),
1350                   strna(m->interface),
1351                   strna(m->member),
1352                   strna(m->root_container.signature),
1353                   bus_error_message(error, r));
1354
1355         return 1;
1356 }
1357
1358 int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignment) {
1359         const char *eq, *field;
1360         int r;
1361
1362         assert(m);
1363         assert(assignment);
1364
1365         eq = strchr(assignment, '=');
1366         if (!eq) {
1367                 log_error("Not an assignment: %s", assignment);
1368                 return -EINVAL;
1369         }
1370
1371         field = strndupa(assignment, eq - assignment);
1372         eq ++;
1373
1374         if (streq(field, "CPUQuota")) {
1375
1376                 if (isempty(eq)) {
1377
1378                         r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
1379                         if (r < 0)
1380                                 return bus_log_create_error(r);
1381
1382                         r = sd_bus_message_append(m, "v", "t", USEC_INFINITY);
1383
1384                 } else if (endswith(eq, "%")) {
1385                         double percent;
1386
1387                         if (sscanf(eq, "%lf%%", &percent) != 1 || percent <= 0) {
1388                                 log_error("CPU quota '%s' invalid.", eq);
1389                                 return -EINVAL;
1390                         }
1391
1392                         r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
1393                         if (r < 0)
1394                                 return bus_log_create_error(r);
1395
1396                         r = sd_bus_message_append(m, "v", "t", (usec_t) percent * USEC_PER_SEC / 100);
1397                 } else {
1398                         log_error("CPU quota needs to be in percent.");
1399                         return -EINVAL;
1400                 }
1401
1402                 if (r < 0)
1403                         return bus_log_create_error(r);
1404
1405                 return 0;
1406         }
1407
1408         r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
1409         if (r < 0)
1410                 return bus_log_create_error(r);
1411
1412         if (STR_IN_SET(field,
1413                        "CPUAccounting", "MemoryAccounting", "BlockIOAccounting",
1414                        "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies")) {
1415
1416                 r = parse_boolean(eq);
1417                 if (r < 0) {
1418                         log_error("Failed to parse boolean assignment %s.", assignment);
1419                         return -EINVAL;
1420                 }
1421
1422                 r = sd_bus_message_append(m, "v", "b", r);
1423
1424         } else if (streq(field, "MemoryLimit")) {
1425                 off_t bytes;
1426
1427                 r = parse_size(eq, 1024, &bytes);
1428                 if (r < 0) {
1429                         log_error("Failed to parse bytes specification %s", assignment);
1430                         return -EINVAL;
1431                 }
1432
1433                 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
1434
1435         } else if (STR_IN_SET(field, "CPUShares", "BlockIOWeight")) {
1436                 uint64_t u;
1437
1438                 r = safe_atou64(eq, &u);
1439                 if (r < 0) {
1440                         log_error("Failed to parse %s value %s.", field, eq);
1441                         return -EINVAL;
1442                 }
1443
1444                 r = sd_bus_message_append(m, "v", "t", u);
1445
1446         } else if (STR_IN_SET(field, "User", "Group", "DevicePolicy", "KillMode"))
1447                 r = sd_bus_message_append(m, "v", "s", eq);
1448
1449         else if (streq(field, "DeviceAllow")) {
1450
1451                 if (isempty(eq))
1452                         r = sd_bus_message_append(m, "v", "a(ss)", 0);
1453                 else {
1454                         const char *path, *rwm, *e;
1455
1456                         e = strchr(eq, ' ');
1457                         if (e) {
1458                                 path = strndupa(eq, e - eq);
1459                                 rwm = e+1;
1460                         } else {
1461                                 path = eq;
1462                                 rwm = "";
1463                         }
1464
1465                         if (!path_startswith(path, "/dev")) {
1466                                 log_error("%s is not a device file in /dev.", path);
1467                                 return -EINVAL;
1468                         }
1469
1470                         r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
1471                 }
1472
1473         } else if (STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1474
1475                 if (isempty(eq))
1476                         r = sd_bus_message_append(m, "v", "a(st)", 0);
1477                 else {
1478                         const char *path, *bandwidth, *e;
1479                         off_t bytes;
1480
1481                         e = strchr(eq, ' ');
1482                         if (e) {
1483                                 path = strndupa(eq, e - eq);
1484                                 bandwidth = e+1;
1485                         } else {
1486                                 log_error("Failed to parse %s value %s.", field, eq);
1487                                 return -EINVAL;
1488                         }
1489
1490                         if (!path_startswith(path, "/dev")) {
1491                                 log_error("%s is not a device file in /dev.", path);
1492                                 return -EINVAL;
1493                         }
1494
1495                         r = parse_size(bandwidth, 1000, &bytes);
1496                         if (r < 0) {
1497                                 log_error("Failed to parse byte value %s.", bandwidth);
1498                                 return -EINVAL;
1499                         }
1500
1501                         r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
1502                 }
1503
1504         } else if (streq(field, "BlockIODeviceWeight")) {
1505
1506                 if (isempty(eq))
1507                         r = sd_bus_message_append(m, "v", "a(st)", 0);
1508                 else {
1509                         const char *path, *weight, *e;
1510                         uint64_t u;
1511
1512                         e = strchr(eq, ' ');
1513                         if (e) {
1514                                 path = strndupa(eq, e - eq);
1515                                 weight = e+1;
1516                         } else {
1517                                 log_error("Failed to parse %s value %s.", field, eq);
1518                                 return -EINVAL;
1519                         }
1520
1521                         if (!path_startswith(path, "/dev")) {
1522                                 log_error("%s is not a device file in /dev.", path);
1523                                 return -EINVAL;
1524                         }
1525
1526                         r = safe_atou64(weight, &u);
1527                         if (r < 0) {
1528                                 log_error("Failed to parse %s value %s.", field, weight);
1529                                 return -EINVAL;
1530                         }
1531                         r = sd_bus_message_append(m, "v", "a(st)", path, u);
1532                 }
1533
1534         } else if (rlimit_from_string(field) >= 0) {
1535                 uint64_t rl;
1536
1537                 if (streq(eq, "infinity"))
1538                         rl = (uint64_t) -1;
1539                 else {
1540                         r = safe_atou64(eq, &rl);
1541                         if (r < 0) {
1542                                 log_error("Invalid resource limit: %s", eq);
1543                                 return -EINVAL;
1544                         }
1545                 }
1546
1547                 r = sd_bus_message_append(m, "v", "t", rl);
1548
1549         } else if (streq(field, "Nice")) {
1550                 int32_t i;
1551
1552                 r = safe_atoi32(eq, &i);
1553                 if (r < 0) {
1554                         log_error("Failed to parse %s value %s.", field, eq);
1555                         return -EINVAL;
1556                 }
1557
1558                 r = sd_bus_message_append(m, "v", "i", i);
1559
1560         } else if (streq(field, "Environment")) {
1561
1562                 r = sd_bus_message_append(m, "v", "as", 1, eq);
1563
1564         } else if (streq(field, "KillSignal")) {
1565                 int sig;
1566
1567                 sig = signal_from_string_try_harder(eq);
1568                 if (sig < 0) {
1569                         log_error("Failed to parse %s value %s.", field, eq);
1570                         return -EINVAL;
1571                 }
1572
1573                 r = sd_bus_message_append(m, "v", "i", sig);
1574
1575         } else if (streq(field, "AccuracySec")) {
1576                 usec_t u;
1577
1578                 r = parse_sec(eq, &u);
1579                 if (r < 0) {
1580                         log_error("Failed to parse %s value %s", field, eq);
1581                         return -EINVAL;
1582                 }
1583
1584                 r = sd_bus_message_append(m, "v", "t", u);
1585
1586         } else {
1587                 log_error("Unknown assignment %s.", assignment);
1588                 return -EINVAL;
1589         }
1590
1591         if (r < 0)
1592                 return bus_log_create_error(r);
1593
1594         return 0;
1595 }
1596
1597 typedef struct BusWaitForJobs {
1598         sd_bus *bus;
1599         Set *jobs;
1600
1601         char *name;
1602         char *result;
1603
1604         sd_bus_slot *slot_job_removed;
1605         sd_bus_slot *slot_disconnected;
1606 } BusWaitForJobs;
1607
1608 static int match_disconnected(sd_bus_message *m, void *userdata, sd_bus_error *error) {
1609         assert(m);
1610
1611         log_error("Warning! D-Bus connection terminated.");
1612         sd_bus_close(sd_bus_message_get_bus(m));
1613
1614         return 0;
1615 }
1616
1617 static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
1618         const char *path, *unit, *result;
1619         BusWaitForJobs *d = userdata;
1620         uint32_t id;
1621         char *found;
1622         int r;
1623
1624         assert(m);
1625         assert(d);
1626
1627         r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1628         if (r < 0) {
1629                 bus_log_parse_error(r);
1630                 return 0;
1631         }
1632
1633         found = set_remove(d->jobs, (char*) path);
1634         if (!found)
1635                 return 0;
1636
1637         free(found);
1638
1639         if (!isempty(result))
1640                 d->result = strdup(result);
1641
1642         if (!isempty(unit))
1643                 d->name = strdup(unit);
1644
1645         return 0;
1646 }
1647
1648 void bus_wait_for_jobs_free(BusWaitForJobs *d) {
1649         if (!d)
1650                 return;
1651
1652         set_free_free(d->jobs);
1653
1654         sd_bus_slot_unref(d->slot_disconnected);
1655         sd_bus_slot_unref(d->slot_job_removed);
1656
1657         sd_bus_unref(d->bus);
1658
1659         free(d->name);
1660         free(d->result);
1661
1662         free(d);
1663 }
1664
1665 int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret) {
1666         _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *d = NULL;
1667         int r;
1668
1669         assert(bus);
1670         assert(ret);
1671
1672         d = new0(BusWaitForJobs, 1);
1673         if (!d)
1674                 return -ENOMEM;
1675
1676         d->bus = sd_bus_ref(bus);
1677
1678         /* When we are a bus client we match by sender. Direct
1679          * connections OTOH have no initialized sender field, and
1680          * hence we ignore the sender then */
1681         r = sd_bus_add_match(
1682                         bus,
1683                         &d->slot_job_removed,
1684                         bus->bus_client ?
1685                         "type='signal',"
1686                         "sender='org.freedesktop.systemd1',"
1687                         "interface='org.freedesktop.systemd1.Manager',"
1688                         "member='JobRemoved',"
1689                         "path='/org/freedesktop/systemd1'" :
1690                         "type='signal',"
1691                         "interface='org.freedesktop.systemd1.Manager',"
1692                         "member='JobRemoved',"
1693                         "path='/org/freedesktop/systemd1'",
1694                         match_job_removed, d);
1695         if (r < 0)
1696                 return r;
1697
1698         r = sd_bus_add_match(
1699                         bus,
1700                         &d->slot_disconnected,
1701                         "type='signal',"
1702                         "sender='org.freedesktop.DBus.Local',"
1703                         "interface='org.freedesktop.DBus.Local',"
1704                         "member='Disconnected'",
1705                         match_disconnected, d);
1706         if (r < 0)
1707                 return r;
1708
1709         *ret = d;
1710         d = NULL;
1711
1712         return 0;
1713 }
1714
1715 static int bus_process_wait(sd_bus *bus) {
1716         int r;
1717
1718         for (;;) {
1719                 r = sd_bus_process(bus, NULL);
1720                 if (r < 0)
1721                         return r;
1722                 if (r > 0)
1723                         return 0;
1724
1725                 r = sd_bus_wait(bus, (uint64_t) -1);
1726                 if (r < 0)
1727                         return r;
1728         }
1729 }
1730
1731 static int bus_job_get_service_result(BusWaitForJobs *d, char **result) {
1732         _cleanup_free_ char *dbus_path = NULL;
1733
1734         assert(d);
1735         assert(d->name);
1736         assert(result);
1737
1738         dbus_path = unit_dbus_path_from_name(d->name);
1739         if (!dbus_path)
1740                 return -ENOMEM;
1741
1742         return sd_bus_get_property_string(d->bus,
1743                                           "org.freedesktop.systemd1",
1744                                           dbus_path,
1745                                           "org.freedesktop.systemd1.Service",
1746                                           "Result",
1747                                           NULL,
1748                                           result);
1749 }
1750
1751 static const struct {
1752         const char *result, *explanation;
1753 } explanations [] = {
1754         { "resources",   "a configured resource limit was exceeded" },
1755         { "timeout",     "a timeout was exceeded" },
1756         { "exit-code",   "the control process exited with error code" },
1757         { "signal",      "a fatal signal was delivered to the control process" },
1758         { "core-dump",   "a fatal signal was delivered causing the control process to dump core" },
1759         { "watchdog",    "the service failed to send watchdog ping" },
1760         { "start-limit", "start of the service was attempted too often" }
1761 };
1762
1763 static void log_job_error_with_service_result(const char* service, const char *result) {
1764         _cleanup_free_ char *service_shell_quoted = NULL;
1765
1766         assert(service);
1767
1768         service_shell_quoted = shell_maybe_quote(service);
1769
1770         if (!isempty(result)) {
1771                 unsigned i;
1772
1773                 for (i = 0; i < ELEMENTSOF(explanations); ++i)
1774                         if (streq(result, explanations[i].result))
1775                                 break;
1776
1777                 if (i < ELEMENTSOF(explanations)) {
1778                         log_error("Job for %s failed because %s. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1779                                   service,
1780                                   explanations[i].explanation,
1781                                   strna(service_shell_quoted));
1782
1783                         goto finish;
1784                 }
1785         }
1786
1787         log_error("Job for %s failed. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1788                   service,
1789                   strna(service_shell_quoted));
1790
1791 finish:
1792         /* For some results maybe additional explanation is required */
1793         if (streq_ptr(result, "start-limit"))
1794                 log_info("To force a start use \"systemctl reset-failed %1$s\" followed by \"systemctl start %1$s\" again.",
1795                          strna(service_shell_quoted));
1796 }
1797
1798 static int check_wait_response(BusWaitForJobs *d, bool quiet) {
1799         int r = 0;
1800
1801         assert(d->result);
1802
1803         if (!quiet) {
1804                 if (streq(d->result, "canceled"))
1805                         log_error("Job for %s canceled.", strna(d->name));
1806                 else if (streq(d->result, "timeout"))
1807                         log_error("Job for %s timed out.", strna(d->name));
1808                 else if (streq(d->result, "dependency"))
1809                         log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
1810                 else if (streq(d->result, "invalid"))
1811                         log_error("Job for %s invalid.", strna(d->name));
1812                 else if (streq(d->result, "assert"))
1813                         log_error("Assertion failed on job for %s.", strna(d->name));
1814                 else if (streq(d->result, "unsupported"))
1815                         log_error("Operation on or unit type of %s not supported on this system.", strna(d->name));
1816                 else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
1817                         if (d->name) {
1818                                 int q;
1819                                 _cleanup_free_ char *result = NULL;
1820
1821                                 q = bus_job_get_service_result(d, &result);
1822                                 if (q < 0)
1823                                         log_debug_errno(q, "Failed to get Result property of service %s: %m", d->name);
1824
1825                                 log_job_error_with_service_result(d->name, result);
1826                         } else
1827                                 log_error("Job failed. See \"journalctl -xe\" for details.");
1828                 }
1829         }
1830
1831         if (streq(d->result, "canceled"))
1832                 r = -ECANCELED;
1833         else if (streq(d->result, "timeout"))
1834                 r = -ETIME;
1835         else if (streq(d->result, "dependency"))
1836                 r = -EIO;
1837         else if (streq(d->result, "invalid"))
1838                 r = -ENOEXEC;
1839         else if (streq(d->result, "assert"))
1840                 r = -EPROTO;
1841         else if (streq(d->result, "unsupported"))
1842                 r = -EOPNOTSUPP;
1843         else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1844                 r = -EIO;
1845
1846         return r;
1847 }
1848
1849 int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet) {
1850         int r = 0;
1851
1852         assert(d);
1853
1854         while (!set_isempty(d->jobs)) {
1855                 int q;
1856
1857                 q = bus_process_wait(d->bus);
1858                 if (q < 0)
1859                         return log_error_errno(q, "Failed to wait for response: %m");
1860
1861                 if (d->result) {
1862                         q = check_wait_response(d, quiet);
1863                         /* Return the first error as it is most likely to be
1864                          * meaningful. */
1865                         if (q < 0 && r == 0)
1866                                 r = q;
1867
1868                         log_debug_errno(q, "Got result %s/%m for job %s", strna(d->result), strna(d->name));
1869                 }
1870
1871                 free(d->name);
1872                 d->name = NULL;
1873
1874                 free(d->result);
1875                 d->result = NULL;
1876         }
1877
1878         return r;
1879 }
1880
1881 int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path) {
1882         int r;
1883
1884         assert(d);
1885
1886         r = set_ensure_allocated(&d->jobs, &string_hash_ops);
1887         if (r < 0)
1888                 return r;
1889
1890         return set_put_strdup(d->jobs, path);
1891 }
1892
1893 int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes) {
1894         const char *type, *path, *source;
1895         int r;
1896
1897         r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1898         if (r < 0)
1899                 return bus_log_parse_error(r);
1900
1901         while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1902                 if (!quiet) {
1903                         if (streq(type, "symlink"))
1904                                 log_info("Created symlink from %s to %s.", path, source);
1905                         else
1906                                 log_info("Removed symlink %s.", path);
1907                 }
1908
1909                 r = unit_file_changes_add(changes, n_changes, streq(type, "symlink") ? UNIT_FILE_SYMLINK : UNIT_FILE_UNLINK, path, source);
1910                 if (r < 0)
1911                         return r;
1912         }
1913         if (r < 0)
1914                 return bus_log_parse_error(r);
1915
1916         r = sd_bus_message_exit_container(m);
1917         if (r < 0)
1918                 return bus_log_parse_error(r);
1919
1920         return 0;
1921 }
1922
1923 /**
1924  * bus_path_encode_unique() - encode unique object path
1925  * @b: bus connection or NULL
1926  * @prefix: object path prefix
1927  * @sender_id: unique-name of client, or NULL
1928  * @external_id: external ID to be chosen by client, or NULL
1929  * @ret_path: storage for encoded object path pointer
1930  *
1931  * Whenever we provide a bus API that allows clients to create and manage
1932  * server-side objects, we need to provide a unique name for these objects. If
1933  * we let the server choose the name, we suffer from a race condition: If a
1934  * client creates an object asynchronously, it cannot destroy that object until
1935  * it received the method reply. It cannot know the name of the new object,
1936  * thus, it cannot destroy it. Furthermore, it enforces a round-trip.
1937  *
1938  * Therefore, many APIs allow the client to choose the unique name for newly
1939  * created objects. There're two problems to solve, though:
1940  *    1) Object names are usually defined via dbus object paths, which are
1941  *       usually globally namespaced. Therefore, multiple clients must be able
1942  *       to choose unique object names without interference.
1943  *    2) If multiple libraries share the same bus connection, they must be
1944  *       able to choose unique object names without interference.
1945  * The first problem is solved easily by prefixing a name with the
1946  * unique-bus-name of a connection. The server side must enforce this and
1947  * reject any other name. The second problem is solved by providing unique
1948  * suffixes from within sd-bus.
1949  *
1950  * This helper allows clients to create unique object-paths. It uses the
1951  * template '/prefix/sender_id/external_id' and returns the new path in
1952  * @ret_path (must be freed by the caller).
1953  * If @sender_id is NULL, the unique-name of @b is used. If @external_id is
1954  * NULL, this function allocates a unique suffix via @b (by requesting a new
1955  * cookie). If both @sender_id and @external_id are given, @b can be passed as
1956  * NULL.
1957  *
1958  * Returns: 0 on success, negative error code on failure.
1959  */
1960 int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path) {
1961         _cleanup_free_ char *sender_label = NULL, *external_label = NULL;
1962         char external_buf[DECIMAL_STR_MAX(uint64_t)], *p;
1963         int r;
1964
1965         assert_return(b || (sender_id && external_id), -EINVAL);
1966         assert_return(object_path_is_valid(prefix), -EINVAL);
1967         assert_return(ret_path, -EINVAL);
1968
1969         if (!sender_id) {
1970                 r = sd_bus_get_unique_name(b, &sender_id);
1971                 if (r < 0)
1972                         return r;
1973         }
1974
1975         if (!external_id) {
1976                 xsprintf(external_buf, "%"PRIu64, ++b->cookie);
1977                 external_id = external_buf;
1978         }
1979
1980         sender_label = bus_label_escape(sender_id);
1981         if (!sender_label)
1982                 return -ENOMEM;
1983
1984         external_label = bus_label_escape(external_id);
1985         if (!external_label)
1986                 return -ENOMEM;
1987
1988         p = strjoin(prefix, "/", sender_label, "/", external_label, NULL);
1989         if (!p)
1990                 return -ENOMEM;
1991
1992         *ret_path = p;
1993         return 0;
1994 }
1995
1996 /**
1997  * bus_path_decode_unique() - decode unique object path
1998  * @path: object path to decode
1999  * @prefix: object path prefix
2000  * @ret_sender: output parameter for sender-id label
2001  * @ret_external: output parameter for external-id label
2002  *
2003  * This does the reverse of bus_path_encode_unique() (see its description for
2004  * details). Both trailing labels, sender-id and external-id, are unescaped and
2005  * returned in the given output parameters (the caller must free them).
2006  *
2007  * Note that this function returns 0 if the path does not match the template
2008  * (see bus_path_encode_unique()), 1 if it matched.
2009  *
2010  * Returns: Negative error code on failure, 0 if the given object path does not
2011  *          match the template (return parameters are set to NULL), 1 if it was
2012  *          parsed successfully (return parameters contain allocated labels).
2013  */
2014 int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external) {
2015         const char *p, *q;
2016         char *sender, *external;
2017
2018         assert(object_path_is_valid(path));
2019         assert(object_path_is_valid(prefix));
2020         assert(ret_sender);
2021         assert(ret_external);
2022
2023         p = object_path_startswith(path, prefix);
2024         if (!p) {
2025                 *ret_sender = NULL;
2026                 *ret_external = NULL;
2027                 return 0;
2028         }
2029
2030         q = strchr(p, '/');
2031         if (!q) {
2032                 *ret_sender = NULL;
2033                 *ret_external = NULL;
2034                 return 0;
2035         }
2036
2037         sender = bus_label_unescape_n(p, q - p);
2038         external = bus_label_unescape(q + 1);
2039         if (!sender || !external) {
2040                 free(sender);
2041                 free(external);
2042                 return -ENOMEM;
2043         }
2044
2045         *ret_sender = sender;
2046         *ret_external = external;
2047         return 1;
2048 }
2049
2050 bool is_kdbus_wanted(void) {
2051         _cleanup_free_ char *value = NULL;
2052         int r;
2053
2054         if (get_proc_cmdline_key("kdbus", NULL) <= 0) {
2055                 r = get_proc_cmdline_key("kdbus=", &value);
2056                 if (r <= 0 || parse_boolean(value) != 1)
2057                         return false;
2058         }
2059
2060         return true;
2061 }
2062
2063 bool is_kdbus_available(void) {
2064         _cleanup_close_ int fd = -1;
2065         struct kdbus_cmd cmd = { .size = sizeof(cmd), .flags = KDBUS_FLAG_NEGOTIATE };
2066
2067         if (!is_kdbus_wanted())
2068                 return false;
2069
2070         fd = open("/sys/fs/kdbus/control", O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
2071         if (fd < 0)
2072                 return false;
2073
2074         return ioctl(fd, KDBUS_CMD_BUS_MAKE, &cmd) >= 0;
2075 }