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