]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/bus-util.c
Merge pull request #2240 from hgwalles/coredump-delete-bug
[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;
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 field = strndupa(assignment, eq - assignment);
1413 eq ++;
1414
1415 if (streq(field, "CPUQuota")) {
1416
1417 if (isempty(eq)) {
1418
1419 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
1420 if (r < 0)
1421 return bus_log_create_error(r);
1422
1423 r = sd_bus_message_append(m, "v", "t", USEC_INFINITY);
1424
1425 } else if (endswith(eq, "%")) {
1426 double percent;
1427
1428 if (sscanf(eq, "%lf%%", &percent) != 1 || percent <= 0) {
1429 log_error("CPU quota '%s' invalid.", eq);
1430 return -EINVAL;
1431 }
1432
1433 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "CPUQuotaPerSecUSec");
1434 if (r < 0)
1435 return bus_log_create_error(r);
1436
1437 r = sd_bus_message_append(m, "v", "t", (usec_t) percent * USEC_PER_SEC / 100);
1438 } else {
1439 log_error("CPU quota needs to be in percent.");
1440 return -EINVAL;
1441 }
1442
1443 if (r < 0)
1444 return bus_log_create_error(r);
1445
1446 return 0;
1447
1448 } else if (streq(field, "EnvironmentFile")) {
1449
1450 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "EnvironmentFiles");
1451 if (r < 0)
1452 return bus_log_create_error(r);
1453
1454 r = sd_bus_message_append(m, "v", "a(sb)", 1,
1455 eq[0] == '-' ? eq + 1 : eq,
1456 eq[0] == '-');
1457 if (r < 0)
1458 return bus_log_create_error(r);
1459
1460 return 0;
1461
1462 } else if (streq(field, "RandomizedDelaySec")) {
1463 usec_t t;
1464
1465 r = parse_sec(eq, &t);
1466 if (r < 0)
1467 return log_error_errno(r, "Failed to parse RandomizedDelaySec= parameter: %s", eq);
1468
1469 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, "RandomizedDelayUSec");
1470 if (r < 0)
1471 return bus_log_create_error(r);
1472
1473 r = sd_bus_message_append(m, "v", "t", t);
1474 if (r < 0)
1475 return bus_log_create_error(r);
1476
1477 return 0;
1478 }
1479
1480 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
1481 if (r < 0)
1482 return bus_log_create_error(r);
1483
1484 if (STR_IN_SET(field,
1485 "CPUAccounting", "MemoryAccounting", "BlockIOAccounting", "TasksAccounting",
1486 "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies",
1487 "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "RemainAfterExit",
1488 "PrivateTmp", "PrivateDevices", "PrivateNetwork", "NoNewPrivileges",
1489 "SyslogLevelPrefix", "Delegate", "RemainAfterElapse")) {
1490
1491 r = parse_boolean(eq);
1492 if (r < 0)
1493 return log_error_errno(r, "Failed to parse boolean assignment %s.", assignment);
1494
1495 r = sd_bus_message_append(m, "v", "b", r);
1496
1497 } else if (streq(field, "MemoryLimit")) {
1498 uint64_t bytes;
1499
1500 if (isempty(eq) || streq(eq, "infinity"))
1501 bytes = (uint64_t) -1;
1502 else {
1503 r = parse_size(eq, 1024, &bytes);
1504 if (r < 0) {
1505 log_error("Failed to parse bytes specification %s", assignment);
1506 return -EINVAL;
1507 }
1508 }
1509
1510 r = sd_bus_message_append(m, "v", "t", bytes);
1511
1512 } else if (streq(field, "TasksMax")) {
1513 uint64_t n;
1514
1515 if (isempty(eq) || streq(eq, "infinity"))
1516 n = (uint64_t) -1;
1517 else {
1518 r = safe_atou64(eq, &n);
1519 if (r < 0) {
1520 log_error("Failed to parse maximum tasks specification %s", assignment);
1521 return -EINVAL;
1522 }
1523 }
1524
1525 r = sd_bus_message_append(m, "v", "t", n);
1526
1527 } else if (STR_IN_SET(field, "CPUShares", "StartupCPUShares")) {
1528 uint64_t u;
1529
1530 r = cg_cpu_shares_parse(eq, &u);
1531 if (r < 0) {
1532 log_error("Failed to parse %s value %s.", field, eq);
1533 return -EINVAL;
1534 }
1535
1536 r = sd_bus_message_append(m, "v", "t", u);
1537
1538 } else if (STR_IN_SET(field, "BlockIOWeight", "StartupBlockIOWeight")) {
1539 uint64_t u;
1540
1541 r = cg_cpu_shares_parse(eq, &u);
1542 if (r < 0) {
1543 log_error("Failed to parse %s value %s.", field, eq);
1544 return -EINVAL;
1545 }
1546
1547 r = sd_bus_message_append(m, "v", "t", u);
1548
1549 } else if (STR_IN_SET(field,
1550 "User", "Group", "DevicePolicy", "KillMode",
1551 "UtmpIdentifier", "UtmpMode", "PAMName", "TTYPath",
1552 "StandardInput", "StandardOutput", "StandardError",
1553 "Description", "Slice", "Type", "WorkingDirectory",
1554 "RootDirectory", "SyslogIdentifier", "ProtectSystem",
1555 "ProtectHome"))
1556 r = sd_bus_message_append(m, "v", "s", eq);
1557
1558 else if (streq(field, "SyslogLevel")) {
1559 int level;
1560
1561 level = log_level_from_string(eq);
1562 if (level < 0) {
1563 log_error("Failed to parse %s value %s.", field, eq);
1564 return -EINVAL;
1565 }
1566
1567 r = sd_bus_message_append(m, "v", "i", level);
1568
1569 } else if (streq(field, "SyslogFacility")) {
1570 int facility;
1571
1572 facility = log_facility_unshifted_from_string(eq);
1573 if (facility < 0) {
1574 log_error("Failed to parse %s value %s.", field, eq);
1575 return -EINVAL;
1576 }
1577
1578 r = sd_bus_message_append(m, "v", "i", facility);
1579
1580 } else if (streq(field, "DeviceAllow")) {
1581
1582 if (isempty(eq))
1583 r = sd_bus_message_append(m, "v", "a(ss)", 0);
1584 else {
1585 const char *path, *rwm, *e;
1586
1587 e = strchr(eq, ' ');
1588 if (e) {
1589 path = strndupa(eq, e - eq);
1590 rwm = e+1;
1591 } else {
1592 path = eq;
1593 rwm = "";
1594 }
1595
1596 if (!path_startswith(path, "/dev")) {
1597 log_error("%s is not a device file in /dev.", path);
1598 return -EINVAL;
1599 }
1600
1601 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
1602 }
1603
1604 } else if (STR_IN_SET(field, "BlockIOReadBandwidth", "BlockIOWriteBandwidth")) {
1605
1606 if (isempty(eq))
1607 r = sd_bus_message_append(m, "v", "a(st)", 0);
1608 else {
1609 const char *path, *bandwidth, *e;
1610 uint64_t bytes;
1611
1612 e = strchr(eq, ' ');
1613 if (e) {
1614 path = strndupa(eq, e - eq);
1615 bandwidth = e+1;
1616 } else {
1617 log_error("Failed to parse %s value %s.", field, eq);
1618 return -EINVAL;
1619 }
1620
1621 if (!path_startswith(path, "/dev")) {
1622 log_error("%s is not a device file in /dev.", path);
1623 return -EINVAL;
1624 }
1625
1626 r = parse_size(bandwidth, 1000, &bytes);
1627 if (r < 0) {
1628 log_error("Failed to parse byte value %s.", bandwidth);
1629 return -EINVAL;
1630 }
1631
1632 r = sd_bus_message_append(m, "v", "a(st)", 1, path, bytes);
1633 }
1634
1635 } else if (streq(field, "BlockIODeviceWeight")) {
1636
1637 if (isempty(eq))
1638 r = sd_bus_message_append(m, "v", "a(st)", 0);
1639 else {
1640 const char *path, *weight, *e;
1641 uint64_t u;
1642
1643 e = strchr(eq, ' ');
1644 if (e) {
1645 path = strndupa(eq, e - eq);
1646 weight = e+1;
1647 } else {
1648 log_error("Failed to parse %s value %s.", field, eq);
1649 return -EINVAL;
1650 }
1651
1652 if (!path_startswith(path, "/dev")) {
1653 log_error("%s is not a device file in /dev.", path);
1654 return -EINVAL;
1655 }
1656
1657 r = safe_atou64(weight, &u);
1658 if (r < 0) {
1659 log_error("Failed to parse %s value %s.", field, weight);
1660 return -EINVAL;
1661 }
1662 r = sd_bus_message_append(m, "v", "a(st)", path, u);
1663 }
1664
1665 } else if (rlimit_from_string(field) >= 0) {
1666 uint64_t rl;
1667
1668 if (streq(eq, "infinity"))
1669 rl = (uint64_t) -1;
1670 else {
1671 r = safe_atou64(eq, &rl);
1672 if (r < 0) {
1673 log_error("Invalid resource limit: %s", eq);
1674 return -EINVAL;
1675 }
1676 }
1677
1678 r = sd_bus_message_append(m, "v", "t", rl);
1679
1680 } else if (streq(field, "Nice")) {
1681 int32_t i;
1682
1683 r = safe_atoi32(eq, &i);
1684 if (r < 0) {
1685 log_error("Failed to parse %s value %s.", field, eq);
1686 return -EINVAL;
1687 }
1688
1689 r = sd_bus_message_append(m, "v", "i", i);
1690
1691 } else if (STR_IN_SET(field, "Environment", "PassEnvironment")) {
1692 const char *p;
1693
1694 r = sd_bus_message_open_container(m, 'v', "as");
1695 if (r < 0)
1696 return bus_log_create_error(r);
1697
1698 r = sd_bus_message_open_container(m, 'a', "s");
1699 if (r < 0)
1700 return bus_log_create_error(r);
1701
1702 p = eq;
1703
1704 for (;;) {
1705 _cleanup_free_ char *word = NULL;
1706
1707 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES|EXTRACT_CUNESCAPE);
1708 if (r < 0) {
1709 log_error("Failed to parse Environment value %s", eq);
1710 return -EINVAL;
1711 }
1712 if (r == 0)
1713 break;
1714
1715 if (streq(field, "Environment")) {
1716 if (!env_assignment_is_valid(word)) {
1717 log_error("Invalid environment assignment: %s", word);
1718 return -EINVAL;
1719 }
1720 } else { /* PassEnvironment */
1721 if (!env_name_is_valid(word)) {
1722 log_error("Invalid environment variable name: %s", word);
1723 return -EINVAL;
1724 }
1725 }
1726
1727 r = sd_bus_message_append_basic(m, 's', word);
1728 if (r < 0)
1729 return bus_log_create_error(r);
1730 }
1731
1732 r = sd_bus_message_close_container(m);
1733 if (r < 0)
1734 return bus_log_create_error(r);
1735
1736 r = sd_bus_message_close_container(m);
1737
1738 } else if (streq(field, "KillSignal")) {
1739 int sig;
1740
1741 sig = signal_from_string_try_harder(eq);
1742 if (sig < 0) {
1743 log_error("Failed to parse %s value %s.", field, eq);
1744 return -EINVAL;
1745 }
1746
1747 r = sd_bus_message_append(m, "v", "i", sig);
1748
1749 } else if (streq(field, "AccuracySec")) {
1750 usec_t u;
1751
1752 r = parse_sec(eq, &u);
1753 if (r < 0) {
1754 log_error("Failed to parse %s value %s", field, eq);
1755 return -EINVAL;
1756 }
1757
1758 r = sd_bus_message_append(m, "v", "t", u);
1759 } else if (streq(field, "TimerSlackNSec")) {
1760 nsec_t n;
1761
1762 r = parse_nsec(eq, &n);
1763 if (r < 0) {
1764 log_error("Failed to parse %s value %s", field, eq);
1765 return -EINVAL;
1766 }
1767
1768 r = sd_bus_message_append(m, "v", "t", n);
1769 } else if (streq(field, "OOMScoreAdjust")) {
1770 int oa;
1771
1772 r = safe_atoi(eq, &oa);
1773 if (r < 0) {
1774 log_error("Failed to parse %s value %s", field, eq);
1775 return -EINVAL;
1776 }
1777
1778 if (!oom_score_adjust_is_valid(oa)) {
1779 log_error("OOM score adjust value out of range");
1780 return -EINVAL;
1781 }
1782
1783 r = sd_bus_message_append(m, "v", "i", oa);
1784 } else if (STR_IN_SET(field, "ReadWriteDirectories", "ReadOnlyDirectories", "InaccessibleDirectories")) {
1785 const char *p;
1786
1787 r = sd_bus_message_open_container(m, 'v', "as");
1788 if (r < 0)
1789 return bus_log_create_error(r);
1790
1791 r = sd_bus_message_open_container(m, 'a', "s");
1792 if (r < 0)
1793 return bus_log_create_error(r);
1794
1795 p = eq;
1796
1797 for (;;) {
1798 _cleanup_free_ char *word = NULL;
1799 int offset;
1800
1801 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
1802 if (r < 0) {
1803 log_error("Failed to parse %s value %s", field, eq);
1804 return -EINVAL;
1805 }
1806 if (r == 0)
1807 break;
1808
1809 if (!utf8_is_valid(word)) {
1810 log_error("Failed to parse %s value %s", field, eq);
1811 return -EINVAL;
1812 }
1813
1814 offset = word[0] == '-';
1815 if (!path_is_absolute(word + offset)) {
1816 log_error("Failed to parse %s value %s", field, eq);
1817 return -EINVAL;
1818 }
1819
1820 path_kill_slashes(word + offset);
1821
1822 r = sd_bus_message_append_basic(m, 's', word);
1823 if (r < 0)
1824 return bus_log_create_error(r);
1825 }
1826
1827 r = sd_bus_message_close_container(m);
1828 if (r < 0)
1829 return bus_log_create_error(r);
1830
1831 r = sd_bus_message_close_container(m);
1832
1833 } else if (streq(field, "RuntimeDirectory")) {
1834 const char *p;
1835
1836 r = sd_bus_message_open_container(m, 'v', "as");
1837 if (r < 0)
1838 return bus_log_create_error(r);
1839
1840 r = sd_bus_message_open_container(m, 'a', "s");
1841 if (r < 0)
1842 return bus_log_create_error(r);
1843
1844 p = eq;
1845
1846 for (;;) {
1847 _cleanup_free_ char *word = NULL;
1848
1849 r = extract_first_word(&p, &word, NULL, EXTRACT_QUOTES);
1850 if (r < 0)
1851 return log_error_errno(r, "Failed to parse %s value %s", field, eq);
1852
1853 if (r == 0)
1854 break;
1855
1856 r = sd_bus_message_append_basic(m, 's', word);
1857 if (r < 0)
1858 return bus_log_create_error(r);
1859 }
1860
1861 r = sd_bus_message_close_container(m);
1862 if (r < 0)
1863 return bus_log_create_error(r);
1864
1865 r = sd_bus_message_close_container(m);
1866
1867 } else {
1868 log_error("Unknown assignment %s.", assignment);
1869 return -EINVAL;
1870 }
1871
1872 if (r < 0)
1873 return bus_log_create_error(r);
1874
1875 return 0;
1876 }
1877
1878 typedef struct BusWaitForJobs {
1879 sd_bus *bus;
1880 Set *jobs;
1881
1882 char *name;
1883 char *result;
1884
1885 sd_bus_slot *slot_job_removed;
1886 sd_bus_slot *slot_disconnected;
1887 } BusWaitForJobs;
1888
1889 static int match_disconnected(sd_bus_message *m, void *userdata, sd_bus_error *error) {
1890 assert(m);
1891
1892 log_error("Warning! D-Bus connection terminated.");
1893 sd_bus_close(sd_bus_message_get_bus(m));
1894
1895 return 0;
1896 }
1897
1898 static int match_job_removed(sd_bus_message *m, void *userdata, sd_bus_error *error) {
1899 const char *path, *unit, *result;
1900 BusWaitForJobs *d = userdata;
1901 uint32_t id;
1902 char *found;
1903 int r;
1904
1905 assert(m);
1906 assert(d);
1907
1908 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1909 if (r < 0) {
1910 bus_log_parse_error(r);
1911 return 0;
1912 }
1913
1914 found = set_remove(d->jobs, (char*) path);
1915 if (!found)
1916 return 0;
1917
1918 free(found);
1919
1920 if (!isempty(result))
1921 d->result = strdup(result);
1922
1923 if (!isempty(unit))
1924 d->name = strdup(unit);
1925
1926 return 0;
1927 }
1928
1929 void bus_wait_for_jobs_free(BusWaitForJobs *d) {
1930 if (!d)
1931 return;
1932
1933 set_free_free(d->jobs);
1934
1935 sd_bus_slot_unref(d->slot_disconnected);
1936 sd_bus_slot_unref(d->slot_job_removed);
1937
1938 sd_bus_unref(d->bus);
1939
1940 free(d->name);
1941 free(d->result);
1942
1943 free(d);
1944 }
1945
1946 int bus_wait_for_jobs_new(sd_bus *bus, BusWaitForJobs **ret) {
1947 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *d = NULL;
1948 int r;
1949
1950 assert(bus);
1951 assert(ret);
1952
1953 d = new0(BusWaitForJobs, 1);
1954 if (!d)
1955 return -ENOMEM;
1956
1957 d->bus = sd_bus_ref(bus);
1958
1959 /* When we are a bus client we match by sender. Direct
1960 * connections OTOH have no initialized sender field, and
1961 * hence we ignore the sender then */
1962 r = sd_bus_add_match(
1963 bus,
1964 &d->slot_job_removed,
1965 bus->bus_client ?
1966 "type='signal',"
1967 "sender='org.freedesktop.systemd1',"
1968 "interface='org.freedesktop.systemd1.Manager',"
1969 "member='JobRemoved',"
1970 "path='/org/freedesktop/systemd1'" :
1971 "type='signal',"
1972 "interface='org.freedesktop.systemd1.Manager',"
1973 "member='JobRemoved',"
1974 "path='/org/freedesktop/systemd1'",
1975 match_job_removed, d);
1976 if (r < 0)
1977 return r;
1978
1979 r = sd_bus_add_match(
1980 bus,
1981 &d->slot_disconnected,
1982 "type='signal',"
1983 "sender='org.freedesktop.DBus.Local',"
1984 "interface='org.freedesktop.DBus.Local',"
1985 "member='Disconnected'",
1986 match_disconnected, d);
1987 if (r < 0)
1988 return r;
1989
1990 *ret = d;
1991 d = NULL;
1992
1993 return 0;
1994 }
1995
1996 static int bus_process_wait(sd_bus *bus) {
1997 int r;
1998
1999 for (;;) {
2000 r = sd_bus_process(bus, NULL);
2001 if (r < 0)
2002 return r;
2003 if (r > 0)
2004 return 0;
2005
2006 r = sd_bus_wait(bus, (uint64_t) -1);
2007 if (r < 0)
2008 return r;
2009 }
2010 }
2011
2012 static int bus_job_get_service_result(BusWaitForJobs *d, char **result) {
2013 _cleanup_free_ char *dbus_path = NULL;
2014
2015 assert(d);
2016 assert(d->name);
2017 assert(result);
2018
2019 dbus_path = unit_dbus_path_from_name(d->name);
2020 if (!dbus_path)
2021 return -ENOMEM;
2022
2023 return sd_bus_get_property_string(d->bus,
2024 "org.freedesktop.systemd1",
2025 dbus_path,
2026 "org.freedesktop.systemd1.Service",
2027 "Result",
2028 NULL,
2029 result);
2030 }
2031
2032 static const struct {
2033 const char *result, *explanation;
2034 } explanations [] = {
2035 { "resources", "a configured resource limit was exceeded" },
2036 { "timeout", "a timeout was exceeded" },
2037 { "exit-code", "the control process exited with error code" },
2038 { "signal", "a fatal signal was delivered to the control process" },
2039 { "core-dump", "a fatal signal was delivered causing the control process to dump core" },
2040 { "watchdog", "the service failed to send watchdog ping" },
2041 { "start-limit", "start of the service was attempted too often" }
2042 };
2043
2044 static void log_job_error_with_service_result(const char* service, const char *result, const char *extra_args) {
2045 _cleanup_free_ char *service_shell_quoted = NULL, *systemctl_extra_args = NULL;
2046
2047 assert(service);
2048
2049 service_shell_quoted = shell_maybe_quote(service);
2050
2051 systemctl_extra_args = strjoin("systemctl ", extra_args, " ", NULL);
2052 if (!systemctl_extra_args) {
2053 log_oom();
2054 return;
2055 }
2056
2057 systemctl_extra_args = strstrip(systemctl_extra_args);
2058
2059 if (!isempty(result)) {
2060 unsigned i;
2061
2062 for (i = 0; i < ELEMENTSOF(explanations); ++i)
2063 if (streq(result, explanations[i].result))
2064 break;
2065
2066 if (i < ELEMENTSOF(explanations)) {
2067 log_error("Job for %s failed because %s. See \"%s status %s\" and \"journalctl -xe\" for details.\n",
2068 service,
2069 explanations[i].explanation,
2070 systemctl_extra_args,
2071 strna(service_shell_quoted));
2072
2073 goto finish;
2074 }
2075 }
2076
2077 log_error("Job for %s failed. See \"%s status %s\" and \"journalctl -xe\" for details.\n",
2078 service,
2079 systemctl_extra_args,
2080 strna(service_shell_quoted));
2081
2082 finish:
2083 /* For some results maybe additional explanation is required */
2084 if (streq_ptr(result, "start-limit"))
2085 log_info("To force a start use \"%1$s reset-failed %2$s\" followed by \"%1$s start %2$s\" again.",
2086 systemctl_extra_args,
2087 strna(service_shell_quoted));
2088 }
2089
2090 static int check_wait_response(BusWaitForJobs *d, bool quiet, const char *extra_args) {
2091 int r = 0;
2092
2093 assert(d->result);
2094
2095 if (!quiet) {
2096 if (streq(d->result, "canceled"))
2097 log_error("Job for %s canceled.", strna(d->name));
2098 else if (streq(d->result, "timeout"))
2099 log_error("Job for %s timed out.", strna(d->name));
2100 else if (streq(d->result, "dependency"))
2101 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
2102 else if (streq(d->result, "invalid"))
2103 log_error("Job for %s invalid.", strna(d->name));
2104 else if (streq(d->result, "assert"))
2105 log_error("Assertion failed on job for %s.", strna(d->name));
2106 else if (streq(d->result, "unsupported"))
2107 log_error("Operation on or unit type of %s not supported on this system.", strna(d->name));
2108 else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
2109 if (d->name) {
2110 int q;
2111 _cleanup_free_ char *result = NULL;
2112
2113 q = bus_job_get_service_result(d, &result);
2114 if (q < 0)
2115 log_debug_errno(q, "Failed to get Result property of service %s: %m", d->name);
2116
2117 log_job_error_with_service_result(d->name, result, extra_args);
2118 } else
2119 log_error("Job failed. See \"journalctl -xe\" for details.");
2120 }
2121 }
2122
2123 if (streq(d->result, "canceled"))
2124 r = -ECANCELED;
2125 else if (streq(d->result, "timeout"))
2126 r = -ETIME;
2127 else if (streq(d->result, "dependency"))
2128 r = -EIO;
2129 else if (streq(d->result, "invalid"))
2130 r = -ENOEXEC;
2131 else if (streq(d->result, "assert"))
2132 r = -EPROTO;
2133 else if (streq(d->result, "unsupported"))
2134 r = -EOPNOTSUPP;
2135 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2136 r = -EIO;
2137
2138 return r;
2139 }
2140
2141 int bus_wait_for_jobs(BusWaitForJobs *d, bool quiet, const char *extra_args) {
2142 int r = 0;
2143
2144 assert(d);
2145
2146 while (!set_isempty(d->jobs)) {
2147 int q;
2148
2149 q = bus_process_wait(d->bus);
2150 if (q < 0)
2151 return log_error_errno(q, "Failed to wait for response: %m");
2152
2153 if (d->result) {
2154 q = check_wait_response(d, quiet, extra_args);
2155 /* Return the first error as it is most likely to be
2156 * meaningful. */
2157 if (q < 0 && r == 0)
2158 r = q;
2159
2160 log_debug_errno(q, "Got result %s/%m for job %s", strna(d->result), strna(d->name));
2161 }
2162
2163 d->name = mfree(d->name);
2164 d->result = mfree(d->result);
2165 }
2166
2167 return r;
2168 }
2169
2170 int bus_wait_for_jobs_add(BusWaitForJobs *d, const char *path) {
2171 int r;
2172
2173 assert(d);
2174
2175 r = set_ensure_allocated(&d->jobs, &string_hash_ops);
2176 if (r < 0)
2177 return r;
2178
2179 return set_put_strdup(d->jobs, path);
2180 }
2181
2182 int bus_wait_for_jobs_one(BusWaitForJobs *d, const char *path, bool quiet) {
2183 int r;
2184
2185 r = bus_wait_for_jobs_add(d, path);
2186 if (r < 0)
2187 return log_oom();
2188
2189 return bus_wait_for_jobs(d, quiet, NULL);
2190 }
2191
2192 int bus_deserialize_and_dump_unit_file_changes(sd_bus_message *m, bool quiet, UnitFileChange **changes, unsigned *n_changes) {
2193 const char *type, *path, *source;
2194 int r;
2195
2196 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
2197 if (r < 0)
2198 return bus_log_parse_error(r);
2199
2200 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
2201 if (!quiet) {
2202 if (streq(type, "symlink"))
2203 log_info("Created symlink from %s to %s.", path, source);
2204 else
2205 log_info("Removed symlink %s.", path);
2206 }
2207
2208 r = unit_file_changes_add(changes, n_changes, streq(type, "symlink") ? UNIT_FILE_SYMLINK : UNIT_FILE_UNLINK, path, source);
2209 if (r < 0)
2210 return r;
2211 }
2212 if (r < 0)
2213 return bus_log_parse_error(r);
2214
2215 r = sd_bus_message_exit_container(m);
2216 if (r < 0)
2217 return bus_log_parse_error(r);
2218
2219 return 0;
2220 }
2221
2222 /**
2223 * bus_path_encode_unique() - encode unique object path
2224 * @b: bus connection or NULL
2225 * @prefix: object path prefix
2226 * @sender_id: unique-name of client, or NULL
2227 * @external_id: external ID to be chosen by client, or NULL
2228 * @ret_path: storage for encoded object path pointer
2229 *
2230 * Whenever we provide a bus API that allows clients to create and manage
2231 * server-side objects, we need to provide a unique name for these objects. If
2232 * we let the server choose the name, we suffer from a race condition: If a
2233 * client creates an object asynchronously, it cannot destroy that object until
2234 * it received the method reply. It cannot know the name of the new object,
2235 * thus, it cannot destroy it. Furthermore, it enforces a round-trip.
2236 *
2237 * Therefore, many APIs allow the client to choose the unique name for newly
2238 * created objects. There're two problems to solve, though:
2239 * 1) Object names are usually defined via dbus object paths, which are
2240 * usually globally namespaced. Therefore, multiple clients must be able
2241 * to choose unique object names without interference.
2242 * 2) If multiple libraries share the same bus connection, they must be
2243 * able to choose unique object names without interference.
2244 * The first problem is solved easily by prefixing a name with the
2245 * unique-bus-name of a connection. The server side must enforce this and
2246 * reject any other name. The second problem is solved by providing unique
2247 * suffixes from within sd-bus.
2248 *
2249 * This helper allows clients to create unique object-paths. It uses the
2250 * template '/prefix/sender_id/external_id' and returns the new path in
2251 * @ret_path (must be freed by the caller).
2252 * If @sender_id is NULL, the unique-name of @b is used. If @external_id is
2253 * NULL, this function allocates a unique suffix via @b (by requesting a new
2254 * cookie). If both @sender_id and @external_id are given, @b can be passed as
2255 * NULL.
2256 *
2257 * Returns: 0 on success, negative error code on failure.
2258 */
2259 int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path) {
2260 _cleanup_free_ char *sender_label = NULL, *external_label = NULL;
2261 char external_buf[DECIMAL_STR_MAX(uint64_t)], *p;
2262 int r;
2263
2264 assert_return(b || (sender_id && external_id), -EINVAL);
2265 assert_return(object_path_is_valid(prefix), -EINVAL);
2266 assert_return(ret_path, -EINVAL);
2267
2268 if (!sender_id) {
2269 r = sd_bus_get_unique_name(b, &sender_id);
2270 if (r < 0)
2271 return r;
2272 }
2273
2274 if (!external_id) {
2275 xsprintf(external_buf, "%"PRIu64, ++b->cookie);
2276 external_id = external_buf;
2277 }
2278
2279 sender_label = bus_label_escape(sender_id);
2280 if (!sender_label)
2281 return -ENOMEM;
2282
2283 external_label = bus_label_escape(external_id);
2284 if (!external_label)
2285 return -ENOMEM;
2286
2287 p = strjoin(prefix, "/", sender_label, "/", external_label, NULL);
2288 if (!p)
2289 return -ENOMEM;
2290
2291 *ret_path = p;
2292 return 0;
2293 }
2294
2295 /**
2296 * bus_path_decode_unique() - decode unique object path
2297 * @path: object path to decode
2298 * @prefix: object path prefix
2299 * @ret_sender: output parameter for sender-id label
2300 * @ret_external: output parameter for external-id label
2301 *
2302 * This does the reverse of bus_path_encode_unique() (see its description for
2303 * details). Both trailing labels, sender-id and external-id, are unescaped and
2304 * returned in the given output parameters (the caller must free them).
2305 *
2306 * Note that this function returns 0 if the path does not match the template
2307 * (see bus_path_encode_unique()), 1 if it matched.
2308 *
2309 * Returns: Negative error code on failure, 0 if the given object path does not
2310 * match the template (return parameters are set to NULL), 1 if it was
2311 * parsed successfully (return parameters contain allocated labels).
2312 */
2313 int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external) {
2314 const char *p, *q;
2315 char *sender, *external;
2316
2317 assert(object_path_is_valid(path));
2318 assert(object_path_is_valid(prefix));
2319 assert(ret_sender);
2320 assert(ret_external);
2321
2322 p = object_path_startswith(path, prefix);
2323 if (!p) {
2324 *ret_sender = NULL;
2325 *ret_external = NULL;
2326 return 0;
2327 }
2328
2329 q = strchr(p, '/');
2330 if (!q) {
2331 *ret_sender = NULL;
2332 *ret_external = NULL;
2333 return 0;
2334 }
2335
2336 sender = bus_label_unescape_n(p, q - p);
2337 external = bus_label_unescape(q + 1);
2338 if (!sender || !external) {
2339 free(sender);
2340 free(external);
2341 return -ENOMEM;
2342 }
2343
2344 *ret_sender = sender;
2345 *ret_external = external;
2346 return 1;
2347 }
2348
2349 bool is_kdbus_wanted(void) {
2350 _cleanup_free_ char *value = NULL;
2351 #ifdef ENABLE_KDBUS
2352 const bool configured = true;
2353 #else
2354 const bool configured = false;
2355 #endif
2356
2357 int r;
2358
2359 if (get_proc_cmdline_key("kdbus", NULL) > 0)
2360 return true;
2361
2362 r = get_proc_cmdline_key("kdbus=", &value);
2363 if (r <= 0)
2364 return configured;
2365
2366 return parse_boolean(value) == 1;
2367 }
2368
2369 bool is_kdbus_available(void) {
2370 _cleanup_close_ int fd = -1;
2371 struct kdbus_cmd cmd = { .size = sizeof(cmd), .flags = KDBUS_FLAG_NEGOTIATE };
2372
2373 if (!is_kdbus_wanted())
2374 return false;
2375
2376 fd = open("/sys/fs/kdbus/control", O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
2377 if (fd < 0)
2378 return false;
2379
2380 return ioctl(fd, KDBUS_CMD_BUS_MAKE, &cmd) >= 0;
2381 }
2382
2383 int bus_property_get_rlimit(
2384 sd_bus *bus,
2385 const char *path,
2386 const char *interface,
2387 const char *property,
2388 sd_bus_message *reply,
2389 void *userdata,
2390 sd_bus_error *error) {
2391
2392 struct rlimit *rl;
2393 uint64_t u;
2394 rlim_t x;
2395 const char *is_soft;
2396
2397 assert(bus);
2398 assert(reply);
2399 assert(userdata);
2400
2401 is_soft = endswith(property, "Soft");
2402 rl = *(struct rlimit**) userdata;
2403 if (rl)
2404 x = is_soft ? rl->rlim_cur : rl->rlim_max;
2405 else {
2406 struct rlimit buf = {};
2407 int z;
2408 const char *s;
2409
2410 s = is_soft ? strndupa(property, is_soft - property) : property;
2411
2412 z = rlimit_from_string(strstr(s, "Limit"));
2413 assert(z >= 0);
2414
2415 getrlimit(z, &buf);
2416 x = is_soft ? buf.rlim_cur : buf.rlim_max;
2417 }
2418
2419 /* rlim_t might have different sizes, let's map
2420 * RLIMIT_INFINITY to (uint64_t) -1, so that it is the same on
2421 * all archs */
2422 u = x == RLIM_INFINITY ? (uint64_t) -1 : (uint64_t) x;
2423
2424 return sd_bus_message_append(reply, "t", u);
2425 }