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