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