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