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