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