]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/bus-util.c
hostname-util: ignore case when checking if hostname is localhost
[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 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_append_unit_property_assignment(sd_bus_message *m, const char *assignment) {
1330 const char *eq, *field;
1331 int r;
1332
1333 assert(m);
1334 assert(assignment);
1335
1336 eq = strchr(assignment, '=');
1337 if (!eq) {
1338 log_error("Not an assignment: %s", assignment);
1339 return -EINVAL;
1340 }
1341
1342 field = strndupa(assignment, eq - assignment);
1343 eq ++;
1344
1345 if (streq(field, "CPUQuota")) {
1346
1347 if (isempty(eq)) {
1348
1349 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
1350 if (r < 0)
1351 return bus_log_create_error(r);
1352
1353 r = sd_bus_message_append(m, "v", "t", USEC_INFINITY);
1354
1355 } else if (endswith(eq, "%")) {
1356 double percent;
1357
1358 if (sscanf(eq, "%lf%%", &percent) != 1 || percent <= 0) {
1359 log_error("CPU quota '%s' invalid.", eq);
1360 return -EINVAL;
1361 }
1362
1363 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
1364 if (r < 0)
1365 return bus_log_create_error(r);
1366
1367 r = sd_bus_message_append(m, "v", "t", (usec_t) percent * USEC_PER_SEC / 100);
1368 } else {
1369 log_error("CPU quota needs to be in percent.");
1370 return -EINVAL;
1371 }
1372
1373 if (r < 0)
1374 return bus_log_create_error(r);
1375
1376 return 0;
1377 }
1378
1379 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
1380 if (r < 0)
1381 return bus_log_create_error(r);
1382
1383 if (STR_IN_SET(field,
1384 "CPUAccounting", "MemoryAccounting", "BlockIOAccounting",
1385 "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies")) {
1386
1387 r = parse_boolean(eq);
1388 if (r < 0) {
1389 log_error("Failed to parse boolean assignment %s.", assignment);
1390 return -EINVAL;
1391 }
1392
1393 r = sd_bus_message_append(m, "v", "b", r);
1394
1395 } else if (streq(field, "MemoryLimit")) {
1396 off_t bytes;
1397
1398 r = parse_size(eq, 1024, &bytes);
1399 if (r < 0) {
1400 log_error("Failed to parse bytes specification %s", assignment);
1401 return -EINVAL;
1402 }
1403
1404 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
1405
1406 } else if (STR_IN_SET(field, "CPUShares", "BlockIOWeight")) {
1407 uint64_t u;
1408
1409 r = safe_atou64(eq, &u);
1410 if (r < 0) {
1411 log_error("Failed to parse %s value %s.", field, eq);
1412 return -EINVAL;
1413 }
1414
1415 r = sd_bus_message_append(m, "v", "t", u);
1416
1417 } else if (STR_IN_SET(field, "User", "Group", "DevicePolicy", "KillMode"))
1418 r = sd_bus_message_append(m, "v", "s", eq);
1419
1420 else if (streq(field, "DeviceAllow")) {
1421
1422 if (isempty(eq))
1423 r = sd_bus_message_append(m, "v", "a(ss)", 0);
1424 else {
1425 const char *path, *rwm, *e;
1426
1427 e = strchr(eq, ' ');
1428 if (e) {
1429 path = strndupa(eq, e - eq);
1430 rwm = e+1;
1431 } else {
1432 path = eq;
1433 rwm = "";
1434 }
1435
1436 if (!path_startswith(path, "/dev")) {
1437 log_error("%s is not a device file in /dev.", path);
1438 return -EINVAL;
1439 }
1440
1441 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
1442 }
1443
1444 } else if (STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1445
1446 if (isempty(eq))
1447 r = sd_bus_message_append(m, "v", "a(st)", 0);
1448 else {
1449 const char *path, *bandwidth, *e;
1450 off_t bytes;
1451
1452 e = strchr(eq, ' ');
1453 if (e) {
1454 path = strndupa(eq, e - eq);
1455 bandwidth = e+1;
1456 } else {
1457 log_error("Failed to parse %s value %s.", field, eq);
1458 return -EINVAL;
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 = parse_size(bandwidth, 1000, &bytes);
1467 if (r < 0) {
1468 log_error("Failed to parse byte value %s.", bandwidth);
1469 return -EINVAL;
1470 }
1471
1472 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
1473 }
1474
1475 } else if (streq(field, "BlockIODeviceWeight")) {
1476
1477 if (isempty(eq))
1478 r = sd_bus_message_append(m, "v", "a(st)", 0);
1479 else {
1480 const char *path, *weight, *e;
1481 uint64_t u;
1482
1483 e = strchr(eq, ' ');
1484 if (e) {
1485 path = strndupa(eq, e - eq);
1486 weight = e+1;
1487 } else {
1488 log_error("Failed to parse %s value %s.", field, eq);
1489 return -EINVAL;
1490 }
1491
1492 if (!path_startswith(path, "/dev")) {
1493 log_error("%s is not a device file in /dev.", path);
1494 return -EINVAL;
1495 }
1496
1497 r = safe_atou64(weight, &u);
1498 if (r < 0) {
1499 log_error("Failed to parse %s value %s.", field, weight);
1500 return -EINVAL;
1501 }
1502 r = sd_bus_message_append(m, "v", "a(st)", path, u);
1503 }
1504
1505 } else if (rlimit_from_string(field) >= 0) {
1506 uint64_t rl;
1507
1508 if (streq(eq, "infinity"))
1509 rl = (uint64_t) -1;
1510 else {
1511 r = safe_atou64(eq, &rl);
1512 if (r < 0) {
1513 log_error("Invalid resource limit: %s", eq);
1514 return -EINVAL;
1515 }
1516 }
1517
1518 r = sd_bus_message_append(m, "v", "t", rl);
1519
1520 } else if (streq(field, "Nice")) {
1521 int32_t i;
1522
1523 r = safe_atoi32(eq, &i);
1524 if (r < 0) {
1525 log_error("Failed to parse %s value %s.", field, eq);
1526 return -EINVAL;
1527 }
1528
1529 r = sd_bus_message_append(m, "v", "i", i);
1530
1531 } else if (streq(field, "Environment")) {
1532
1533 r = sd_bus_message_append(m, "v", "as", 1, eq);
1534
1535 } else if (streq(field, "KillSignal")) {
1536 int sig;
1537
1538 sig = signal_from_string_try_harder(eq);
1539 if (sig < 0) {
1540 log_error("Failed to parse %s value %s.", field, eq);
1541 return -EINVAL;
1542 }
1543
1544 r = sd_bus_message_append(m, "v", "i", sig);
1545
1546 } else if (streq(field, "AccuracySec")) {
1547 usec_t u;
1548
1549 r = parse_sec(eq, &u);
1550 if (r < 0) {
1551 log_error("Failed to parse %s value %s", field, eq);
1552 return -EINVAL;
1553 }
1554
1555 r = sd_bus_message_append(m, "v", "t", u);
1556
1557 } else {
1558 log_error("Unknown assignment %s.", assignment);
1559 return -EINVAL;
1560 }
1561
1562 if (r < 0)
1563 return bus_log_create_error(r);
1564
1565 return 0;
1566 }
1567
1568 typedef struct BusWaitForJobs {
1569 sd_bus *bus;
1570 Set *jobs;
1571
1572 char *name;
1573 char *result;
1574
1575 sd_bus_slot *slot_job_removed;
1576 sd_bus_slot *slot_disconnected;
1577 } BusWaitForJobs;
1578
1579 static int match_disconnected(sd_bus_message *m, void *userdata, sd_bus_error *error) {
1580 assert(m);
1581
1582 log_error("Warning! D-Bus connection terminated.");
1583 sd_bus_close(sd_bus_message_get_bus(m));
1584
1585 return 0;
1586 }
1587
1588 static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
1589 const char *path, *unit, *result;
1590 BusWaitForJobs *d = userdata;
1591 uint32_t id;
1592 char *found;
1593 int r;
1594
1595 assert(m);
1596 assert(d);
1597
1598 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1599 if (r < 0) {
1600 bus_log_parse_error(r);
1601 return 0;
1602 }
1603
1604 found = set_remove(d->jobs, (char*) path);
1605 if (!found)
1606 return 0;
1607
1608 free(found);
1609
1610 if (!isempty(result))
1611 d->result = strdup(result);
1612
1613 if (!isempty(unit))
1614 d->name = strdup(unit);
1615
1616 return 0;
1617 }
1618
1619 void bus_wait_for_jobs_free(BusWaitForJobs *d) {
1620 if (!d)
1621 return;
1622
1623 set_free_free(d->jobs);
1624
1625 sd_bus_slot_unref(d->slot_disconnected);
1626 sd_bus_slot_unref(d->slot_job_removed);
1627
1628 sd_bus_unref(d->bus);
1629
1630 free(d->name);
1631 free(d->result);
1632
1633 free(d);
1634 }
1635
1636 int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret) {
1637 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *d = NULL;
1638 int r;
1639
1640 assert(bus);
1641 assert(ret);
1642
1643 d = new0(BusWaitForJobs, 1);
1644 if (!d)
1645 return -ENOMEM;
1646
1647 d->bus = sd_bus_ref(bus);
1648
1649 /* When we are a bus client we match by sender. Direct
1650 * connections OTOH have no initialized sender field, and
1651 * hence we ignore the sender then */
1652 r = sd_bus_add_match(
1653 bus,
1654 &d->slot_job_removed,
1655 bus->bus_client ?
1656 "type='signal',"
1657 "sender='org.freedesktop.systemd1',"
1658 "interface='org.freedesktop.systemd1.Manager',"
1659 "member='JobRemoved',"
1660 "path='/org/freedesktop/systemd1'" :
1661 "type='signal',"
1662 "interface='org.freedesktop.systemd1.Manager',"
1663 "member='JobRemoved',"
1664 "path='/org/freedesktop/systemd1'",
1665 match_job_removed, d);
1666 if (r < 0)
1667 return r;
1668
1669 r = sd_bus_add_match(
1670 bus,
1671 &d->slot_disconnected,
1672 "type='signal',"
1673 "sender='org.freedesktop.DBus.Local',"
1674 "interface='org.freedesktop.DBus.Local',"
1675 "member='Disconnected'",
1676 match_disconnected, d);
1677 if (r < 0)
1678 return r;
1679
1680 *ret = d;
1681 d = NULL;
1682
1683 return 0;
1684 }
1685
1686 static int bus_process_wait(sd_bus *bus) {
1687 int r;
1688
1689 for (;;) {
1690 r = sd_bus_process(bus, NULL);
1691 if (r < 0)
1692 return r;
1693 if (r > 0)
1694 return 0;
1695
1696 r = sd_bus_wait(bus, (uint64_t) -1);
1697 if (r < 0)
1698 return r;
1699 }
1700 }
1701
1702 static int bus_job_get_service_result(BusWaitForJobs *d, char **result) {
1703 _cleanup_free_ char *dbus_path = NULL;
1704
1705 assert(d);
1706 assert(d->name);
1707 assert(result);
1708
1709 dbus_path = unit_dbus_path_from_name(d->name);
1710 if (!dbus_path)
1711 return -ENOMEM;
1712
1713 return sd_bus_get_property_string(d->bus,
1714 "org.freedesktop.systemd1",
1715 dbus_path,
1716 "org.freedesktop.systemd1.Service",
1717 "Result",
1718 NULL,
1719 result);
1720 }
1721
1722 static const struct {
1723 const char *result, *explanation;
1724 } explanations [] = {
1725 { "resources", "a configured resource limit was exceeded" },
1726 { "timeout", "a timeout was exceeded" },
1727 { "exit-code", "the control process exited with error code" },
1728 { "signal", "a fatal signal was delivered to the control process" },
1729 { "core-dump", "a fatal signal was delivered causing the control process to dump core" },
1730 { "watchdog", "the service failed to send watchdog ping" },
1731 { "start-limit", "start of the service was attempted too often" }
1732 };
1733
1734 static void log_job_error_with_service_result(const char* service, const char *result) {
1735 _cleanup_free_ char *service_shell_quoted = NULL;
1736
1737 assert(service);
1738
1739 service_shell_quoted = shell_maybe_quote(service);
1740
1741 if (!isempty(result)) {
1742 unsigned i;
1743
1744 for (i = 0; i < ELEMENTSOF(explanations); ++i)
1745 if (streq(result, explanations[i].result))
1746 break;
1747
1748 if (i < ELEMENTSOF(explanations)) {
1749 log_error("Job for %s failed because %s. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1750 service,
1751 explanations[i].explanation,
1752 strna(service_shell_quoted));
1753
1754 goto finish;
1755 }
1756 }
1757
1758 log_error("Job for %s failed. See \"systemctl status %s\" and \"journalctl -xe\" for details.\n",
1759 service,
1760 strna(service_shell_quoted));
1761
1762 finish:
1763 /* For some results maybe additional explanation is required */
1764 if (streq_ptr(result, "start-limit"))
1765 log_info("To force a start use \"systemctl reset-failed %1$s\" followed by \"systemctl start %1$s\" again.",
1766 strna(service_shell_quoted));
1767 }
1768
1769 static int check_wait_response(BusWaitForJobs *d, bool quiet) {
1770 int r = 0;
1771
1772 assert(d->result);
1773
1774 if (!quiet) {
1775 if (streq(d->result, "canceled"))
1776 log_error("Job for %s canceled.", strna(d->name));
1777 else if (streq(d->result, "timeout"))
1778 log_error("Job for %s timed out.", strna(d->name));
1779 else if (streq(d->result, "dependency"))
1780 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
1781 else if (streq(d->result, "invalid"))
1782 log_error("Job for %s invalid.", strna(d->name));
1783 else if (streq(d->result, "assert"))
1784 log_error("Assertion failed on job for %s.", strna(d->name));
1785 else if (streq(d->result, "unsupported"))
1786 log_error("Operation on or unit type of %s not supported on this system.", strna(d->name));
1787 else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
1788 if (d->name) {
1789 int q;
1790 _cleanup_free_ char *result = NULL;
1791
1792 q = bus_job_get_service_result(d, &result);
1793 if (q < 0)
1794 log_debug_errno(q, "Failed to get Result property of service %s: %m", d->name);
1795
1796 log_job_error_with_service_result(d->name, result);
1797 } else
1798 log_error("Job failed. See \"journalctl -xe\" for details.");
1799 }
1800 }
1801
1802 if (streq(d->result, "canceled"))
1803 r = -ECANCELED;
1804 else if (streq(d->result, "timeout"))
1805 r = -ETIME;
1806 else if (streq(d->result, "dependency"))
1807 r = -EIO;
1808 else if (streq(d->result, "invalid"))
1809 r = -ENOEXEC;
1810 else if (streq(d->result, "assert"))
1811 r = -EPROTO;
1812 else if (streq(d->result, "unsupported"))
1813 r = -EOPNOTSUPP;
1814 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1815 r = -EIO;
1816
1817 return r;
1818 }
1819
1820 int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet) {
1821 int r = 0;
1822
1823 assert(d);
1824
1825 while (!set_isempty(d->jobs)) {
1826 int q;
1827
1828 q = bus_process_wait(d->bus);
1829 if (q < 0)
1830 return log_error_errno(q, "Failed to wait for response: %m");
1831
1832 if (d->result) {
1833 q = check_wait_response(d, quiet);
1834 /* Return the first error as it is most likely to be
1835 * meaningful. */
1836 if (q < 0 && r == 0)
1837 r = q;
1838
1839 log_debug_errno(q, "Got result %s/%m for job %s", strna(d->result), strna(d->name));
1840 }
1841
1842 free(d->name);
1843 d->name = NULL;
1844
1845 free(d->result);
1846 d->result = NULL;
1847 }
1848
1849 return r;
1850 }
1851
1852 int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path) {
1853 int r;
1854
1855 assert(d);
1856
1857 r = set_ensure_allocated(&d->jobs, &string_hash_ops);
1858 if (r < 0)
1859 return r;
1860
1861 return set_put_strdup(d->jobs, path);
1862 }
1863
1864 int bus_wait_for_jobs_one(BusWaitForJobs *d, const char *path, bool quiet) {
1865 int r;
1866
1867 r = bus_wait_for_jobs_add(d, path);
1868 if (r < 0)
1869 return log_oom();
1870
1871 return bus_wait_for_jobs(d, quiet);
1872 }
1873
1874 int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes) {
1875 const char *type, *path, *source;
1876 int r;
1877
1878 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1879 if (r < 0)
1880 return bus_log_parse_error(r);
1881
1882 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1883 if (!quiet) {
1884 if (streq(type, "symlink"))
1885 log_info("Created symlink from %s to %s.", path, source);
1886 else
1887 log_info("Removed symlink %s.", path);
1888 }
1889
1890 r = unit_file_changes_add(changes, n_changes, streq(type, "symlink") ? UNIT_FILE_SYMLINK : UNIT_FILE_UNLINK, path, source);
1891 if (r < 0)
1892 return r;
1893 }
1894 if (r < 0)
1895 return bus_log_parse_error(r);
1896
1897 r = sd_bus_message_exit_container(m);
1898 if (r < 0)
1899 return bus_log_parse_error(r);
1900
1901 return 0;
1902 }
1903
1904 /**
1905 * bus_path_encode_unique() - encode unique object path
1906 * @b: bus connection or NULL
1907 * @prefix: object path prefix
1908 * @sender_id: unique-name of client, or NULL
1909 * @external_id: external ID to be chosen by client, or NULL
1910 * @ret_path: storage for encoded object path pointer
1911 *
1912 * Whenever we provide a bus API that allows clients to create and manage
1913 * server-side objects, we need to provide a unique name for these objects. If
1914 * we let the server choose the name, we suffer from a race condition: If a
1915 * client creates an object asynchronously, it cannot destroy that object until
1916 * it received the method reply. It cannot know the name of the new object,
1917 * thus, it cannot destroy it. Furthermore, it enforces a round-trip.
1918 *
1919 * Therefore, many APIs allow the client to choose the unique name for newly
1920 * created objects. There're two problems to solve, though:
1921 * 1) Object names are usually defined via dbus object paths, which are
1922 * usually globally namespaced. Therefore, multiple clients must be able
1923 * to choose unique object names without interference.
1924 * 2) If multiple libraries share the same bus connection, they must be
1925 * able to choose unique object names without interference.
1926 * The first problem is solved easily by prefixing a name with the
1927 * unique-bus-name of a connection. The server side must enforce this and
1928 * reject any other name. The second problem is solved by providing unique
1929 * suffixes from within sd-bus.
1930 *
1931 * This helper allows clients to create unique object-paths. It uses the
1932 * template '/prefix/sender_id/external_id' and returns the new path in
1933 * @ret_path (must be freed by the caller).
1934 * If @sender_id is NULL, the unique-name of @b is used. If @external_id is
1935 * NULL, this function allocates a unique suffix via @b (by requesting a new
1936 * cookie). If both @sender_id and @external_id are given, @b can be passed as
1937 * NULL.
1938 *
1939 * Returns: 0 on success, negative error code on failure.
1940 */
1941 int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path) {
1942 _cleanup_free_ char *sender_label = NULL, *external_label = NULL;
1943 char external_buf[DECIMAL_STR_MAX(uint64_t)], *p;
1944 int r;
1945
1946 assert_return(b || (sender_id && external_id), -EINVAL);
1947 assert_return(object_path_is_valid(prefix), -EINVAL);
1948 assert_return(ret_path, -EINVAL);
1949
1950 if (!sender_id) {
1951 r = sd_bus_get_unique_name(b, &sender_id);
1952 if (r < 0)
1953 return r;
1954 }
1955
1956 if (!external_id) {
1957 xsprintf(external_buf, "%"PRIu64, ++b->cookie);
1958 external_id = external_buf;
1959 }
1960
1961 sender_label = bus_label_escape(sender_id);
1962 if (!sender_label)
1963 return -ENOMEM;
1964
1965 external_label = bus_label_escape(external_id);
1966 if (!external_label)
1967 return -ENOMEM;
1968
1969 p = strjoin(prefix, "/", sender_label, "/", external_label, NULL);
1970 if (!p)
1971 return -ENOMEM;
1972
1973 *ret_path = p;
1974 return 0;
1975 }
1976
1977 /**
1978 * bus_path_decode_unique() - decode unique object path
1979 * @path: object path to decode
1980 * @prefix: object path prefix
1981 * @ret_sender: output parameter for sender-id label
1982 * @ret_external: output parameter for external-id label
1983 *
1984 * This does the reverse of bus_path_encode_unique() (see its description for
1985 * details). Both trailing labels, sender-id and external-id, are unescaped and
1986 * returned in the given output parameters (the caller must free them).
1987 *
1988 * Note that this function returns 0 if the path does not match the template
1989 * (see bus_path_encode_unique()), 1 if it matched.
1990 *
1991 * Returns: Negative error code on failure, 0 if the given object path does not
1992 * match the template (return parameters are set to NULL), 1 if it was
1993 * parsed successfully (return parameters contain allocated labels).
1994 */
1995 int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external) {
1996 const char *p, *q;
1997 char *sender, *external;
1998
1999 assert(object_path_is_valid(path));
2000 assert(object_path_is_valid(prefix));
2001 assert(ret_sender);
2002 assert(ret_external);
2003
2004 p = object_path_startswith(path, prefix);
2005 if (!p) {
2006 *ret_sender = NULL;
2007 *ret_external = NULL;
2008 return 0;
2009 }
2010
2011 q = strchr(p, '/');
2012 if (!q) {
2013 *ret_sender = NULL;
2014 *ret_external = NULL;
2015 return 0;
2016 }
2017
2018 sender = bus_label_unescape_n(p, q - p);
2019 external = bus_label_unescape(q + 1);
2020 if (!sender || !external) {
2021 free(sender);
2022 free(external);
2023 return -ENOMEM;
2024 }
2025
2026 *ret_sender = sender;
2027 *ret_external = external;
2028 return 1;
2029 }
2030
2031 bool is_kdbus_wanted(void) {
2032 _cleanup_free_ char *value = NULL;
2033 #ifdef ENABLE_KDBUS
2034 const bool configured = true;
2035 #else
2036 const bool configured = false;
2037 #endif
2038
2039 int r;
2040
2041 if (get_proc_cmdline_key("kdbus", NULL) > 0)
2042 return true;
2043
2044 r = get_proc_cmdline_key("kdbus=", &value);
2045 if (r <= 0)
2046 return configured;
2047
2048 return parse_boolean(value) == 1;
2049 }
2050
2051 bool is_kdbus_available(void) {
2052 _cleanup_close_ int fd = -1;
2053 struct kdbus_cmd cmd = { .size = sizeof(cmd), .flags = KDBUS_FLAG_NEGOTIATE };
2054
2055 if (!is_kdbus_wanted())
2056 return false;
2057
2058 fd = open("/sys/fs/kdbus/control", O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
2059 if (fd < 0)
2060 return false;
2061
2062 return ioctl(fd, KDBUS_CMD_BUS_MAKE, &cmd) >= 0;
2063 }