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