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