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