]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/bus-util.c
Merge pull request #8106 from dqminh/route-expires-kernel
[thirdparty/systemd.git] / src / shared / bus-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2013 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <inttypes.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/ioctl.h>
28 #include <sys/resource.h>
29 #include <sys/socket.h>
30 #include <unistd.h>
31
32 #include "sd-bus-protocol.h"
33 #include "sd-bus.h"
34 #include "sd-daemon.h"
35 #include "sd-event.h"
36 #include "sd-id128.h"
37
38 #include "alloc-util.h"
39 #include "bus-internal.h"
40 #include "bus-label.h"
41 #include "bus-message.h"
42 #include "bus-util.h"
43 #include "cap-list.h"
44 #include "cgroup-util.h"
45 #include "def.h"
46 #include "escape.h"
47 #include "fd-util.h"
48 #include "missing.h"
49 #include "mount-util.h"
50 #include "nsflags.h"
51 #include "parse-util.h"
52 #include "proc-cmdline.h"
53 #include "rlimit-util.h"
54 #include "stdio-util.h"
55 #include "strv.h"
56 #include "user-util.h"
57
58 static int name_owner_change_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
59 sd_event *e = userdata;
60
61 assert(m);
62 assert(e);
63
64 sd_bus_close(sd_bus_message_get_bus(m));
65 sd_event_exit(e, 0);
66
67 return 1;
68 }
69
70 int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) {
71 const char *match;
72 const char *unique;
73 int r;
74
75 assert(e);
76 assert(bus);
77 assert(name);
78
79 /* We unregister the name here and then wait for the
80 * NameOwnerChanged signal for this event to arrive before we
81 * quit. We do this in order to make sure that any queued
82 * requests are still processed before we really exit. */
83
84 r = sd_bus_get_unique_name(bus, &unique);
85 if (r < 0)
86 return r;
87
88 match = strjoina(
89 "sender='org.freedesktop.DBus',"
90 "type='signal',"
91 "interface='org.freedesktop.DBus',"
92 "member='NameOwnerChanged',"
93 "path='/org/freedesktop/DBus',"
94 "arg0='", name, "',",
95 "arg1='", unique, "',",
96 "arg2=''");
97
98 r = sd_bus_add_match_async(bus, NULL, match, name_owner_change_callback, NULL, e);
99 if (r < 0)
100 return r;
101
102 r = sd_bus_release_name_async(bus, NULL, name, NULL, NULL);
103 if (r < 0)
104 return r;
105
106 return 0;
107 }
108
109 int bus_event_loop_with_idle(
110 sd_event *e,
111 sd_bus *bus,
112 const char *name,
113 usec_t timeout,
114 check_idle_t check_idle,
115 void *userdata) {
116 bool exiting = false;
117 int r, code;
118
119 assert(e);
120 assert(bus);
121 assert(name);
122
123 for (;;) {
124 bool idle;
125
126 r = sd_event_get_state(e);
127 if (r < 0)
128 return r;
129 if (r == SD_EVENT_FINISHED)
130 break;
131
132 if (check_idle)
133 idle = check_idle(userdata);
134 else
135 idle = true;
136
137 r = sd_event_run(e, exiting || !idle ? (uint64_t) -1 : timeout);
138 if (r < 0)
139 return r;
140
141 if (r == 0 && !exiting && idle) {
142
143 r = sd_bus_try_close(bus);
144 if (r == -EBUSY)
145 continue;
146
147 /* Fallback for dbus1 connections: we
148 * unregister the name and wait for the
149 * response to come through for it */
150 if (r == -EOPNOTSUPP) {
151
152 /* Inform the service manager that we
153 * are going down, so that it will
154 * queue all further start requests,
155 * instead of assuming we are already
156 * running. */
157 sd_notify(false, "STOPPING=1");
158
159 r = bus_async_unregister_and_exit(e, bus, name);
160 if (r < 0)
161 return r;
162
163 exiting = true;
164 continue;
165 }
166
167 if (r < 0)
168 return r;
169
170 sd_event_exit(e, 0);
171 break;
172 }
173 }
174
175 r = sd_event_get_exit_code(e, &code);
176 if (r < 0)
177 return r;
178
179 return code;
180 }
181
182 int bus_name_has_owner(sd_bus *c, const char *name, sd_bus_error *error) {
183 _cleanup_(sd_bus_message_unrefp) sd_bus_message *rep = NULL;
184 int r, has_owner = 0;
185
186 assert(c);
187 assert(name);
188
189 r = sd_bus_call_method(c,
190 "org.freedesktop.DBus",
191 "/org/freedesktop/dbus",
192 "org.freedesktop.DBus",
193 "NameHasOwner",
194 error,
195 &rep,
196 "s",
197 name);
198 if (r < 0)
199 return r;
200
201 r = sd_bus_message_read_basic(rep, 'b', &has_owner);
202 if (r < 0)
203 return sd_bus_error_set_errno(error, r);
204
205 return has_owner;
206 }
207
208 static int check_good_user(sd_bus_message *m, uid_t good_user) {
209 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
210 uid_t sender_uid;
211 int r;
212
213 assert(m);
214
215 if (good_user == UID_INVALID)
216 return 0;
217
218 r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_EUID, &creds);
219 if (r < 0)
220 return r;
221
222 /* Don't trust augmented credentials for authorization */
223 assert_return((sd_bus_creds_get_augmented_mask(creds) & SD_BUS_CREDS_EUID) == 0, -EPERM);
224
225 r = sd_bus_creds_get_euid(creds, &sender_uid);
226 if (r < 0)
227 return r;
228
229 return sender_uid == good_user;
230 }
231
232 int bus_test_polkit(
233 sd_bus_message *call,
234 int capability,
235 const char *action,
236 const char **details,
237 uid_t good_user,
238 bool *_challenge,
239 sd_bus_error *e) {
240
241 int r;
242
243 assert(call);
244 assert(action);
245
246 /* Tests non-interactively! */
247
248 r = check_good_user(call, good_user);
249 if (r != 0)
250 return r;
251
252 r = sd_bus_query_sender_privilege(call, capability);
253 if (r < 0)
254 return r;
255 else if (r > 0)
256 return 1;
257 #if ENABLE_POLKIT
258 else {
259 _cleanup_(sd_bus_message_unrefp) sd_bus_message *request = NULL;
260 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
261 int authorized = false, challenge = false;
262 const char *sender, **k, **v;
263
264 sender = sd_bus_message_get_sender(call);
265 if (!sender)
266 return -EBADMSG;
267
268 r = sd_bus_message_new_method_call(
269 call->bus,
270 &request,
271 "org.freedesktop.PolicyKit1",
272 "/org/freedesktop/PolicyKit1/Authority",
273 "org.freedesktop.PolicyKit1.Authority",
274 "CheckAuthorization");
275 if (r < 0)
276 return r;
277
278 r = sd_bus_message_append(
279 request,
280 "(sa{sv})s",
281 "system-bus-name", 1, "name", "s", sender,
282 action);
283 if (r < 0)
284 return r;
285
286 r = sd_bus_message_open_container(request, 'a', "{ss}");
287 if (r < 0)
288 return r;
289
290 STRV_FOREACH_PAIR(k, v, details) {
291 r = sd_bus_message_append(request, "{ss}", *k, *v);
292 if (r < 0)
293 return r;
294 }
295
296 r = sd_bus_message_close_container(request);
297 if (r < 0)
298 return r;
299
300 r = sd_bus_message_append(request, "us", 0, NULL);
301 if (r < 0)
302 return r;
303
304 r = sd_bus_call(call->bus, request, 0, e, &reply);
305 if (r < 0) {
306 /* Treat no PK available as access denied */
307 if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) {
308 sd_bus_error_free(e);
309 return -EACCES;
310 }
311
312 return r;
313 }
314
315 r = sd_bus_message_enter_container(reply, 'r', "bba{ss}");
316 if (r < 0)
317 return r;
318
319 r = sd_bus_message_read(reply, "bb", &authorized, &challenge);
320 if (r < 0)
321 return r;
322
323 if (authorized)
324 return 1;
325
326 if (_challenge) {
327 *_challenge = challenge;
328 return 0;
329 }
330 }
331 #endif
332
333 return -EACCES;
334 }
335
336 #if ENABLE_POLKIT
337
338 typedef struct AsyncPolkitQuery {
339 sd_bus_message *request, *reply;
340 sd_bus_message_handler_t callback;
341 void *userdata;
342 sd_bus_slot *slot;
343 Hashmap *registry;
344 } AsyncPolkitQuery;
345
346 static void async_polkit_query_free(AsyncPolkitQuery *q) {
347
348 if (!q)
349 return;
350
351 sd_bus_slot_unref(q->slot);
352
353 if (q->registry && q->request)
354 hashmap_remove(q->registry, q->request);
355
356 sd_bus_message_unref(q->request);
357 sd_bus_message_unref(q->reply);
358
359 free(q);
360 }
361
362 static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) {
363 _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL;
364 AsyncPolkitQuery *q = userdata;
365 int r;
366
367 assert(reply);
368 assert(q);
369
370 q->slot = sd_bus_slot_unref(q->slot);
371 q->reply = sd_bus_message_ref(reply);
372
373 r = sd_bus_message_rewind(q->request, true);
374 if (r < 0) {
375 r = sd_bus_reply_method_errno(q->request, r, NULL);
376 goto finish;
377 }
378
379 r = q->callback(q->request, q->userdata, &error_buffer);
380 r = bus_maybe_reply_error(q->request, r, &error_buffer);
381
382 finish:
383 async_polkit_query_free(q);
384
385 return r;
386 }
387
388 #endif
389
390 int bus_verify_polkit_async(
391 sd_bus_message *call,
392 int capability,
393 const char *action,
394 const char **details,
395 bool interactive,
396 uid_t good_user,
397 Hashmap **registry,
398 sd_bus_error *error) {
399
400 #if ENABLE_POLKIT
401 _cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL;
402 AsyncPolkitQuery *q;
403 const char *sender, **k, **v;
404 sd_bus_message_handler_t callback;
405 void *userdata;
406 int c;
407 #endif
408 int r;
409
410 assert(call);
411 assert(action);
412 assert(registry);
413
414 r = check_good_user(call, good_user);
415 if (r != 0)
416 return r;
417
418 #if ENABLE_POLKIT
419 q = hashmap_get(*registry, call);
420 if (q) {
421 int authorized, challenge;
422
423 /* This is the second invocation of this function, and
424 * there's already a response from polkit, let's
425 * process it */
426 assert(q->reply);
427
428 if (sd_bus_message_is_method_error(q->reply, NULL)) {
429 const sd_bus_error *e;
430
431 /* Copy error from polkit reply */
432 e = sd_bus_message_get_error(q->reply);
433 sd_bus_error_copy(error, e);
434
435 /* Treat no PK available as access denied */
436 if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN))
437 return -EACCES;
438
439 return -sd_bus_error_get_errno(e);
440 }
441
442 r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}");
443 if (r >= 0)
444 r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge);
445
446 if (r < 0)
447 return r;
448
449 if (authorized)
450 return 1;
451
452 if (challenge)
453 return sd_bus_error_set(error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required.");
454
455 return -EACCES;
456 }
457 #endif
458
459 r = sd_bus_query_sender_privilege(call, capability);
460 if (r < 0)
461 return r;
462 else if (r > 0)
463 return 1;
464
465 #if ENABLE_POLKIT
466 if (sd_bus_get_current_message(call->bus) != call)
467 return -EINVAL;
468
469 callback = sd_bus_get_current_handler(call->bus);
470 if (!callback)
471 return -EINVAL;
472
473 userdata = sd_bus_get_current_userdata(call->bus);
474
475 sender = sd_bus_message_get_sender(call);
476 if (!sender)
477 return -EBADMSG;
478
479 c = sd_bus_message_get_allow_interactive_authorization(call);
480 if (c < 0)
481 return c;
482 if (c > 0)
483 interactive = true;
484
485 r = hashmap_ensure_allocated(registry, NULL);
486 if (r < 0)
487 return r;
488
489 r = sd_bus_message_new_method_call(
490 call->bus,
491 &pk,
492 "org.freedesktop.PolicyKit1",
493 "/org/freedesktop/PolicyKit1/Authority",
494 "org.freedesktop.PolicyKit1.Authority",
495 "CheckAuthorization");
496 if (r < 0)
497 return r;
498
499 r = sd_bus_message_append(
500 pk,
501 "(sa{sv})s",
502 "system-bus-name", 1, "name", "s", sender,
503 action);
504 if (r < 0)
505 return r;
506
507 r = sd_bus_message_open_container(pk, 'a', "{ss}");
508 if (r < 0)
509 return r;
510
511 STRV_FOREACH_PAIR(k, v, details) {
512 r = sd_bus_message_append(pk, "{ss}", *k, *v);
513 if (r < 0)
514 return r;
515 }
516
517 r = sd_bus_message_close_container(pk);
518 if (r < 0)
519 return r;
520
521 r = sd_bus_message_append(pk, "us", !!interactive, NULL);
522 if (r < 0)
523 return r;
524
525 q = new0(AsyncPolkitQuery, 1);
526 if (!q)
527 return -ENOMEM;
528
529 q->request = sd_bus_message_ref(call);
530 q->callback = callback;
531 q->userdata = userdata;
532
533 r = hashmap_put(*registry, call, q);
534 if (r < 0) {
535 async_polkit_query_free(q);
536 return r;
537 }
538
539 q->registry = *registry;
540
541 r = sd_bus_call_async(call->bus, &q->slot, pk, async_polkit_callback, q, 0);
542 if (r < 0) {
543 async_polkit_query_free(q);
544 return r;
545 }
546
547 return 0;
548 #endif
549
550 return -EACCES;
551 }
552
553 void bus_verify_polkit_async_registry_free(Hashmap *registry) {
554 #if ENABLE_POLKIT
555 hashmap_free_with_destructor(registry, async_polkit_query_free);
556 #endif
557 }
558
559 int bus_check_peercred(sd_bus *c) {
560 struct ucred ucred;
561 int fd, r;
562
563 assert(c);
564
565 fd = sd_bus_get_fd(c);
566 if (fd < 0)
567 return fd;
568
569 r = getpeercred(fd, &ucred);
570 if (r < 0)
571 return r;
572
573 if (ucred.uid != 0 && ucred.uid != geteuid())
574 return -EPERM;
575
576 return 1;
577 }
578
579 int bus_connect_system_systemd(sd_bus **_bus) {
580 _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
581 int r;
582
583 assert(_bus);
584
585 if (geteuid() != 0)
586 return sd_bus_default_system(_bus);
587
588 /* If we are root then let's talk directly to the system
589 * instance, instead of going via the bus */
590
591 r = sd_bus_new(&bus);
592 if (r < 0)
593 return r;
594
595 r = sd_bus_set_address(bus, "unix:path=/run/systemd/private");
596 if (r < 0)
597 return r;
598
599 r = sd_bus_start(bus);
600 if (r < 0)
601 return sd_bus_default_system(_bus);
602
603 r = bus_check_peercred(bus);
604 if (r < 0)
605 return r;
606
607 *_bus = bus;
608 bus = NULL;
609
610 return 0;
611 }
612
613 int bus_connect_user_systemd(sd_bus **_bus) {
614 _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
615 _cleanup_free_ char *ee = NULL;
616 const char *e;
617 int r;
618
619 assert(_bus);
620
621 e = secure_getenv("XDG_RUNTIME_DIR");
622 if (!e)
623 return sd_bus_default_user(_bus);
624
625 ee = bus_address_escape(e);
626 if (!ee)
627 return -ENOMEM;
628
629 r = sd_bus_new(&bus);
630 if (r < 0)
631 return r;
632
633 bus->address = strjoin("unix:path=", ee, "/systemd/private");
634 if (!bus->address)
635 return -ENOMEM;
636
637 r = sd_bus_start(bus);
638 if (r < 0)
639 return sd_bus_default_user(_bus);
640
641 r = bus_check_peercred(bus);
642 if (r < 0)
643 return r;
644
645 *_bus = bus;
646 bus = NULL;
647
648 return 0;
649 }
650
651 #define print_property(name, fmt, ...) \
652 do { \
653 if (value) \
654 printf(fmt "\n", __VA_ARGS__); \
655 else \
656 printf("%s=" fmt "\n", name, __VA_ARGS__); \
657 } while (0)
658
659 int bus_print_property(const char *name, sd_bus_message *m, bool value, bool all) {
660 char type;
661 const char *contents;
662 int r;
663
664 assert(name);
665 assert(m);
666
667 r = sd_bus_message_peek_type(m, &type, &contents);
668 if (r < 0)
669 return r;
670
671 switch (type) {
672
673 case SD_BUS_TYPE_STRING: {
674 const char *s;
675
676 r = sd_bus_message_read_basic(m, type, &s);
677 if (r < 0)
678 return r;
679
680 if (all || !isempty(s)) {
681 bool good;
682
683 /* This property has a single value, so we need to take
684 * care not to print a new line, everything else is OK. */
685 good = !strchr(s, '\n');
686 print_property(name, "%s", good ? s : "[unprintable]");
687 }
688
689 return 1;
690 }
691
692 case SD_BUS_TYPE_BOOLEAN: {
693 int b;
694
695 r = sd_bus_message_read_basic(m, type, &b);
696 if (r < 0)
697 return r;
698
699 print_property(name, "%s", yes_no(b));
700
701 return 1;
702 }
703
704 case SD_BUS_TYPE_UINT64: {
705 uint64_t u;
706
707 r = sd_bus_message_read_basic(m, type, &u);
708 if (r < 0)
709 return r;
710
711 /* Yes, heuristics! But we can change this check
712 * should it turn out to not be sufficient */
713
714 if (endswith(name, "Timestamp") || STR_IN_SET(name, "NextElapseUSecRealtime", "LastTriggerUSec")) {
715 char timestamp[FORMAT_TIMESTAMP_MAX], *t;
716
717 t = format_timestamp(timestamp, sizeof(timestamp), u);
718 if (t || all)
719 print_property(name, "%s", strempty(t));
720
721 } else if (strstr(name, "USec")) {
722 char timespan[FORMAT_TIMESPAN_MAX];
723
724 print_property(name, "%s", format_timespan(timespan, sizeof(timespan), u, 0));
725 } else if (streq(name, "RestrictNamespaces")) {
726 _cleanup_free_ char *s = NULL;
727 const char *result;
728
729 if ((u & NAMESPACE_FLAGS_ALL) == 0)
730 result = "yes";
731 else if ((u & NAMESPACE_FLAGS_ALL) == NAMESPACE_FLAGS_ALL)
732 result = "no";
733 else {
734 r = namespace_flag_to_string_many(u, &s);
735 if (r < 0)
736 return r;
737
738 result = s;
739 }
740
741 print_property(name, "%s", result);
742
743 } else if (streq(name, "MountFlags")) {
744 const char *result;
745
746 result = mount_propagation_flags_to_string(u);
747 if (!result)
748 return -EINVAL;
749
750 print_property(name, "%s", result);
751
752 } else if (STR_IN_SET(name, "CapabilityBoundingSet", "AmbientCapabilities")) {
753 _cleanup_free_ char *s = NULL;
754
755 r = capability_set_to_string_alloc(u, &s);
756 if (r < 0)
757 return r;
758
759 print_property(name, "%s", s);
760
761 } else if ((STR_IN_SET(name, "CPUWeight", "StartupCPUWeight", "IOWeight", "StartupIOWeight") && u == CGROUP_WEIGHT_INVALID) ||
762 (STR_IN_SET(name, "CPUShares", "StartupCPUShares") && u == CGROUP_CPU_SHARES_INVALID) ||
763 (STR_IN_SET(name, "BlockIOWeight", "StartupBlockIOWeight") && u == CGROUP_BLKIO_WEIGHT_INVALID) ||
764 (STR_IN_SET(name, "MemoryCurrent", "TasksCurrent") && u == (uint64_t) -1) ||
765 (endswith(name, "NSec") && u == (uint64_t) -1))
766
767 print_property(name, "%s", "[not set]");
768
769 else if ((STR_IN_SET(name, "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit") && u == CGROUP_LIMIT_MAX) ||
770 (STR_IN_SET(name, "TasksMax", "DefaultTasksMax") && u == (uint64_t) -1) ||
771 (startswith(name, "Limit") && u == (uint64_t) -1) ||
772 (startswith(name, "DefaultLimit") && u == (uint64_t) -1))
773
774 print_property(name, "%s", "infinity");
775 else
776 print_property(name, "%"PRIu64, u);
777
778 return 1;
779 }
780
781 case SD_BUS_TYPE_INT64: {
782 int64_t i;
783
784 r = sd_bus_message_read_basic(m, type, &i);
785 if (r < 0)
786 return r;
787
788 print_property(name, "%"PRIi64, i);
789
790 return 1;
791 }
792
793 case SD_BUS_TYPE_UINT32: {
794 uint32_t u;
795
796 r = sd_bus_message_read_basic(m, type, &u);
797 if (r < 0)
798 return r;
799
800 if (strstr(name, "UMask") || strstr(name, "Mode"))
801 print_property(name, "%04o", u);
802 else if (streq(name, "UID")) {
803 if (u == UID_INVALID)
804 print_property(name, "%s", "[not set]");
805 else
806 print_property(name, "%"PRIu32, u);
807 } else if (streq(name, "GID")) {
808 if (u == GID_INVALID)
809 print_property(name, "%s", "[not set]");
810 else
811 print_property(name, "%"PRIu32, u);
812 } else
813 print_property(name, "%"PRIu32, u);
814
815 return 1;
816 }
817
818 case SD_BUS_TYPE_INT32: {
819 int32_t i;
820
821 r = sd_bus_message_read_basic(m, type, &i);
822 if (r < 0)
823 return r;
824
825 print_property(name, "%"PRIi32, i);
826 return 1;
827 }
828
829 case SD_BUS_TYPE_DOUBLE: {
830 double d;
831
832 r = sd_bus_message_read_basic(m, type, &d);
833 if (r < 0)
834 return r;
835
836 print_property(name, "%g", d);
837 return 1;
838 }
839
840 case SD_BUS_TYPE_ARRAY:
841 if (streq(contents, "s")) {
842 bool first = true;
843 const char *str;
844
845 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, contents);
846 if (r < 0)
847 return r;
848
849 while ((r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &str)) > 0) {
850 bool good;
851
852 if (first && !value)
853 printf("%s=", name);
854
855 /* This property has multiple space-separated values, so
856 * neither spaces not newlines can be allowed in a value. */
857 good = str[strcspn(str, " \n")] == '\0';
858
859 printf("%s%s", first ? "" : " ", good ? str : "[unprintable]");
860
861 first = false;
862 }
863 if (r < 0)
864 return r;
865
866 if (first && all && !value)
867 printf("%s=", name);
868 if (!first || all)
869 puts("");
870
871 r = sd_bus_message_exit_container(m);
872 if (r < 0)
873 return r;
874
875 return 1;
876
877 } else if (streq(contents, "y")) {
878 const uint8_t *u;
879 size_t n;
880
881 r = sd_bus_message_read_array(m, SD_BUS_TYPE_BYTE, (const void**) &u, &n);
882 if (r < 0)
883 return r;
884
885 if (all || n > 0) {
886 unsigned int i;
887
888 if (!value)
889 printf("%s=", name);
890
891 for (i = 0; i < n; i++)
892 printf("%02x", u[i]);
893
894 puts("");
895 }
896
897 return 1;
898
899 } else if (streq(contents, "u")) {
900 uint32_t *u;
901 size_t n;
902
903 r = sd_bus_message_read_array(m, SD_BUS_TYPE_UINT32, (const void**) &u, &n);
904 if (r < 0)
905 return r;
906
907 if (all || n > 0) {
908 unsigned int i;
909
910 if (!value)
911 printf("%s=", name);
912
913 for (i = 0; i < n; i++)
914 printf("%08x", u[i]);
915
916 puts("");
917 }
918
919 return 1;
920 }
921
922 break;
923 }
924
925 return 0;
926 }
927
928 int bus_message_print_all_properties(
929 sd_bus_message *m,
930 bus_message_print_t func,
931 char **filter,
932 bool value,
933 bool all,
934 Set **found_properties) {
935
936 int r;
937
938 assert(m);
939
940 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
941 if (r < 0)
942 return r;
943
944 while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
945 const char *name;
946 const char *contents;
947
948 r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &name);
949 if (r < 0)
950 return r;
951
952 if (found_properties) {
953 r = set_ensure_allocated(found_properties, &string_hash_ops);
954 if (r < 0)
955 return log_oom();
956
957 r = set_put(*found_properties, name);
958 if (r < 0 && r != EEXIST)
959 return log_oom();
960 }
961
962 if (!filter || strv_find(filter, name)) {
963 r = sd_bus_message_peek_type(m, NULL, &contents);
964 if (r < 0)
965 return r;
966
967 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
968 if (r < 0)
969 return r;
970
971 if (func)
972 r = func(name, m, value, all);
973 if (!func || r == 0)
974 r = bus_print_property(name, m, value, all);
975 if (r < 0)
976 return r;
977 if (r == 0) {
978 if (all)
979 printf("%s=[unprintable]\n", name);
980 /* skip what we didn't read */
981 r = sd_bus_message_skip(m, contents);
982 if (r < 0)
983 return r;
984 }
985
986 r = sd_bus_message_exit_container(m);
987 if (r < 0)
988 return r;
989 } else {
990 r = sd_bus_message_skip(m, "v");
991 if (r < 0)
992 return r;
993 }
994
995 r = sd_bus_message_exit_container(m);
996 if (r < 0)
997 return r;
998 }
999 if (r < 0)
1000 return r;
1001
1002 r = sd_bus_message_exit_container(m);
1003 if (r < 0)
1004 return r;
1005
1006 return 0;
1007 }
1008
1009 int bus_print_all_properties(
1010 sd_bus *bus,
1011 const char *dest,
1012 const char *path,
1013 bus_message_print_t func,
1014 char **filter,
1015 bool value,
1016 bool all,
1017 Set **found_properties) {
1018
1019 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1020 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1021 int r;
1022
1023 assert(bus);
1024 assert(path);
1025
1026 r = sd_bus_call_method(bus,
1027 dest,
1028 path,
1029 "org.freedesktop.DBus.Properties",
1030 "GetAll",
1031 &error,
1032 &reply,
1033 "s", "");
1034 if (r < 0)
1035 return r;
1036
1037 return bus_message_print_all_properties(reply, func, filter, value, all, found_properties);
1038 }
1039
1040 int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
1041 sd_id128_t *p = userdata;
1042 const void *v;
1043 size_t n;
1044 int r;
1045
1046 r = sd_bus_message_read_array(m, SD_BUS_TYPE_BYTE, &v, &n);
1047 if (r < 0)
1048 return r;
1049
1050 if (n == 0)
1051 *p = SD_ID128_NULL;
1052 else if (n == 16)
1053 memcpy((*p).bytes, v, n);
1054 else
1055 return -EINVAL;
1056
1057 return 0;
1058 }
1059
1060 static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata, bool copy_string) {
1061 char type;
1062 int r;
1063
1064 r = sd_bus_message_peek_type(m, &type, NULL);
1065 if (r < 0)
1066 return r;
1067
1068 switch (type) {
1069
1070 case SD_BUS_TYPE_STRING: {
1071 const char **p = userdata;
1072 const char *s;
1073
1074 r = sd_bus_message_read_basic(m, type, &s);
1075 if (r < 0)
1076 return r;
1077
1078 if (isempty(s))
1079 s = NULL;
1080
1081 if (copy_string)
1082 return free_and_strdup((char **) userdata, s);
1083
1084 *p = s;
1085 return 0;
1086 }
1087
1088 case SD_BUS_TYPE_ARRAY: {
1089 _cleanup_strv_free_ char **l = NULL;
1090 char ***p = userdata;
1091
1092 r = bus_message_read_strv_extend(m, &l);
1093 if (r < 0)
1094 return r;
1095
1096 strv_free(*p);
1097 *p = l;
1098 l = NULL;
1099 return 0;
1100 }
1101
1102 case SD_BUS_TYPE_BOOLEAN: {
1103 unsigned b;
1104 bool *p = userdata;
1105
1106 r = sd_bus_message_read_basic(m, type, &b);
1107 if (r < 0)
1108 return r;
1109
1110 *p = !!b;
1111 return 0;
1112 }
1113
1114 case SD_BUS_TYPE_INT32:
1115 case SD_BUS_TYPE_UINT32: {
1116 uint32_t u, *p = userdata;
1117
1118 r = sd_bus_message_read_basic(m, type, &u);
1119 if (r < 0)
1120 return r;
1121
1122 *p = u;
1123 return 0;
1124 }
1125
1126 case SD_BUS_TYPE_INT64:
1127 case SD_BUS_TYPE_UINT64: {
1128 uint64_t t, *p = userdata;
1129
1130 r = sd_bus_message_read_basic(m, type, &t);
1131 if (r < 0)
1132 return r;
1133
1134 *p = t;
1135 return 0;
1136 }
1137
1138 case SD_BUS_TYPE_DOUBLE: {
1139 double d, *p = userdata;
1140
1141 r = sd_bus_message_read_basic(m, type, &d);
1142 if (r < 0)
1143 return r;
1144
1145 *p = d;
1146 return 0;
1147 }}
1148
1149 return -EOPNOTSUPP;
1150 }
1151
1152 int bus_message_map_all_properties(
1153 sd_bus_message *m,
1154 const struct bus_properties_map *map,
1155 bool copy_string,
1156 sd_bus_error *error,
1157 void *userdata) {
1158
1159 int r;
1160
1161 assert(m);
1162 assert(map);
1163
1164 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
1165 if (r < 0)
1166 return r;
1167
1168 while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1169 const struct bus_properties_map *prop;
1170 const char *member;
1171 const char *contents;
1172 void *v;
1173 unsigned i;
1174
1175 r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member);
1176 if (r < 0)
1177 return r;
1178
1179 for (i = 0, prop = NULL; map[i].member; i++)
1180 if (streq(map[i].member, member)) {
1181 prop = &map[i];
1182 break;
1183 }
1184
1185 if (prop) {
1186 r = sd_bus_message_peek_type(m, NULL, &contents);
1187 if (r < 0)
1188 return r;
1189
1190 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
1191 if (r < 0)
1192 return r;
1193
1194 v = (uint8_t *)userdata + prop->offset;
1195 if (map[i].set)
1196 r = prop->set(sd_bus_message_get_bus(m), member, m, error, v);
1197 else
1198 r = map_basic(sd_bus_message_get_bus(m), member, m, error, v, copy_string);
1199 if (r < 0)
1200 return r;
1201
1202 r = sd_bus_message_exit_container(m);
1203 if (r < 0)
1204 return r;
1205 } else {
1206 r = sd_bus_message_skip(m, "v");
1207 if (r < 0)
1208 return r;
1209 }
1210
1211 r = sd_bus_message_exit_container(m);
1212 if (r < 0)
1213 return r;
1214 }
1215 if (r < 0)
1216 return r;
1217
1218 return sd_bus_message_exit_container(m);
1219 }
1220
1221 int bus_message_map_properties_changed(
1222 sd_bus_message *m,
1223 const struct bus_properties_map *map,
1224 bool copy_string,
1225 sd_bus_error *error,
1226 void *userdata) {
1227
1228 const char *member;
1229 int r, invalidated, i;
1230
1231 assert(m);
1232 assert(map);
1233
1234 r = bus_message_map_all_properties(m, map, copy_string, error, userdata);
1235 if (r < 0)
1236 return r;
1237
1238 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "s");
1239 if (r < 0)
1240 return r;
1241
1242 invalidated = 0;
1243 while ((r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &member)) > 0)
1244 for (i = 0; map[i].member; i++)
1245 if (streq(map[i].member, member)) {
1246 ++invalidated;
1247 break;
1248 }
1249 if (r < 0)
1250 return r;
1251
1252 r = sd_bus_message_exit_container(m);
1253 if (r < 0)
1254 return r;
1255
1256 return invalidated;
1257 }
1258
1259 int bus_map_all_properties(
1260 sd_bus *bus,
1261 const char *destination,
1262 const char *path,
1263 const struct bus_properties_map *map,
1264 sd_bus_error *error,
1265 sd_bus_message **reply,
1266 void *userdata) {
1267
1268 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
1269 int r;
1270
1271 assert(bus);
1272 assert(destination);
1273 assert(path);
1274 assert(map);
1275
1276 r = sd_bus_call_method(
1277 bus,
1278 destination,
1279 path,
1280 "org.freedesktop.DBus.Properties",
1281 "GetAll",
1282 error,
1283 &m,
1284 "s", "");
1285 if (r < 0)
1286 return r;
1287
1288 r = bus_message_map_all_properties(m, map, !reply, error, userdata);
1289 if (r < 0)
1290 return r;
1291
1292 if (reply)
1293 *reply = sd_bus_message_ref(m);
1294
1295 return r;
1296 }
1297
1298 int bus_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **ret) {
1299 _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
1300 int r;
1301
1302 assert(transport >= 0);
1303 assert(transport < _BUS_TRANSPORT_MAX);
1304 assert(ret);
1305
1306 assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
1307 assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -EOPNOTSUPP);
1308
1309 switch (transport) {
1310
1311 case BUS_TRANSPORT_LOCAL:
1312 if (user)
1313 r = sd_bus_default_user(&bus);
1314 else
1315 r = sd_bus_default_system(&bus);
1316
1317 break;
1318
1319 case BUS_TRANSPORT_REMOTE:
1320 r = sd_bus_open_system_remote(&bus, host);
1321 break;
1322
1323 case BUS_TRANSPORT_MACHINE:
1324 r = sd_bus_open_system_machine(&bus, host);
1325 break;
1326
1327 default:
1328 assert_not_reached("Hmm, unknown transport type.");
1329 }
1330 if (r < 0)
1331 return r;
1332
1333 r = sd_bus_set_exit_on_disconnect(bus, true);
1334 if (r < 0)
1335 return r;
1336
1337 *ret = bus;
1338 bus = NULL;
1339
1340 return 0;
1341 }
1342
1343 int bus_connect_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) {
1344 int r;
1345
1346 assert(transport >= 0);
1347 assert(transport < _BUS_TRANSPORT_MAX);
1348 assert(bus);
1349
1350 assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
1351 assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -EOPNOTSUPP);
1352
1353 switch (transport) {
1354
1355 case BUS_TRANSPORT_LOCAL:
1356 if (user)
1357 r = bus_connect_user_systemd(bus);
1358 else
1359 r = bus_connect_system_systemd(bus);
1360
1361 break;
1362
1363 case BUS_TRANSPORT_REMOTE:
1364 r = sd_bus_open_system_remote(bus, host);
1365 break;
1366
1367 case BUS_TRANSPORT_MACHINE:
1368 r = sd_bus_open_system_machine(bus, host);
1369 break;
1370
1371 default:
1372 assert_not_reached("Hmm, unknown transport type.");
1373 }
1374
1375 return r;
1376 }
1377
1378 int bus_property_get_bool(
1379 sd_bus *bus,
1380 const char *path,
1381 const char *interface,
1382 const char *property,
1383 sd_bus_message *reply,
1384 void *userdata,
1385 sd_bus_error *error) {
1386
1387 int b = *(bool*) userdata;
1388
1389 return sd_bus_message_append_basic(reply, 'b', &b);
1390 }
1391
1392 int bus_property_set_bool(
1393 sd_bus *bus,
1394 const char *path,
1395 const char *interface,
1396 const char *property,
1397 sd_bus_message *value,
1398 void *userdata,
1399 sd_bus_error *error) {
1400
1401 int b, r;
1402
1403 r = sd_bus_message_read(value, "b", &b);
1404 if (r < 0)
1405 return r;
1406
1407 *(bool *) userdata = !!b;
1408 return 0;
1409 }
1410
1411 int bus_property_get_id128(
1412 sd_bus *bus,
1413 const char *path,
1414 const char *interface,
1415 const char *property,
1416 sd_bus_message *reply,
1417 void *userdata,
1418 sd_bus_error *error) {
1419
1420 sd_id128_t *id = userdata;
1421
1422 if (sd_id128_is_null(*id)) /* Add an empty array if the ID is zero */
1423 return sd_bus_message_append(reply, "ay", 0);
1424 else
1425 return sd_bus_message_append_array(reply, 'y', id->bytes, 16);
1426 }
1427
1428 #if __SIZEOF_SIZE_T__ != 8
1429 int bus_property_get_size(
1430 sd_bus *bus,
1431 const char *path,
1432 const char *interface,
1433 const char *property,
1434 sd_bus_message *reply,
1435 void *userdata,
1436 sd_bus_error *error) {
1437
1438 uint64_t sz = *(size_t*) userdata;
1439
1440 return sd_bus_message_append_basic(reply, 't', &sz);
1441 }
1442 #endif
1443
1444 #if __SIZEOF_LONG__ != 8
1445 int bus_property_get_long(
1446 sd_bus *bus,
1447 const char *path,
1448 const char *interface,
1449 const char *property,
1450 sd_bus_message *reply,
1451 void *userdata,
1452 sd_bus_error *error) {
1453
1454 int64_t l = *(long*) userdata;
1455
1456 return sd_bus_message_append_basic(reply, 'x', &l);
1457 }
1458
1459 int bus_property_get_ulong(
1460 sd_bus *bus,
1461 const char *path,
1462 const char *interface,
1463 const char *property,
1464 sd_bus_message *reply,
1465 void *userdata,
1466 sd_bus_error *error) {
1467
1468 uint64_t ul = *(unsigned long*) userdata;
1469
1470 return sd_bus_message_append_basic(reply, 't', &ul);
1471 }
1472 #endif
1473
1474 int bus_log_parse_error(int r) {
1475 return log_error_errno(r, "Failed to parse bus message: %m");
1476 }
1477
1478 int bus_log_create_error(int r) {
1479 return log_error_errno(r, "Failed to create bus message: %m");
1480 }
1481
1482 /**
1483 * bus_path_encode_unique() - encode unique object path
1484 * @b: bus connection or NULL
1485 * @prefix: object path prefix
1486 * @sender_id: unique-name of client, or NULL
1487 * @external_id: external ID to be chosen by client, or NULL
1488 * @ret_path: storage for encoded object path pointer
1489 *
1490 * Whenever we provide a bus API that allows clients to create and manage
1491 * server-side objects, we need to provide a unique name for these objects. If
1492 * we let the server choose the name, we suffer from a race condition: If a
1493 * client creates an object asynchronously, it cannot destroy that object until
1494 * it received the method reply. It cannot know the name of the new object,
1495 * thus, it cannot destroy it. Furthermore, it enforces a round-trip.
1496 *
1497 * Therefore, many APIs allow the client to choose the unique name for newly
1498 * created objects. There're two problems to solve, though:
1499 * 1) Object names are usually defined via dbus object paths, which are
1500 * usually globally namespaced. Therefore, multiple clients must be able
1501 * to choose unique object names without interference.
1502 * 2) If multiple libraries share the same bus connection, they must be
1503 * able to choose unique object names without interference.
1504 * The first problem is solved easily by prefixing a name with the
1505 * unique-bus-name of a connection. The server side must enforce this and
1506 * reject any other name. The second problem is solved by providing unique
1507 * suffixes from within sd-bus.
1508 *
1509 * This helper allows clients to create unique object-paths. It uses the
1510 * template '/prefix/sender_id/external_id' and returns the new path in
1511 * @ret_path (must be freed by the caller).
1512 * If @sender_id is NULL, the unique-name of @b is used. If @external_id is
1513 * NULL, this function allocates a unique suffix via @b (by requesting a new
1514 * cookie). If both @sender_id and @external_id are given, @b can be passed as
1515 * NULL.
1516 *
1517 * Returns: 0 on success, negative error code on failure.
1518 */
1519 int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path) {
1520 _cleanup_free_ char *sender_label = NULL, *external_label = NULL;
1521 char external_buf[DECIMAL_STR_MAX(uint64_t)], *p;
1522 int r;
1523
1524 assert_return(b || (sender_id && external_id), -EINVAL);
1525 assert_return(object_path_is_valid(prefix), -EINVAL);
1526 assert_return(ret_path, -EINVAL);
1527
1528 if (!sender_id) {
1529 r = sd_bus_get_unique_name(b, &sender_id);
1530 if (r < 0)
1531 return r;
1532 }
1533
1534 if (!external_id) {
1535 xsprintf(external_buf, "%"PRIu64, ++b->cookie);
1536 external_id = external_buf;
1537 }
1538
1539 sender_label = bus_label_escape(sender_id);
1540 if (!sender_label)
1541 return -ENOMEM;
1542
1543 external_label = bus_label_escape(external_id);
1544 if (!external_label)
1545 return -ENOMEM;
1546
1547 p = strjoin(prefix, "/", sender_label, "/", external_label);
1548 if (!p)
1549 return -ENOMEM;
1550
1551 *ret_path = p;
1552 return 0;
1553 }
1554
1555 /**
1556 * bus_path_decode_unique() - decode unique object path
1557 * @path: object path to decode
1558 * @prefix: object path prefix
1559 * @ret_sender: output parameter for sender-id label
1560 * @ret_external: output parameter for external-id label
1561 *
1562 * This does the reverse of bus_path_encode_unique() (see its description for
1563 * details). Both trailing labels, sender-id and external-id, are unescaped and
1564 * returned in the given output parameters (the caller must free them).
1565 *
1566 * Note that this function returns 0 if the path does not match the template
1567 * (see bus_path_encode_unique()), 1 if it matched.
1568 *
1569 * Returns: Negative error code on failure, 0 if the given object path does not
1570 * match the template (return parameters are set to NULL), 1 if it was
1571 * parsed successfully (return parameters contain allocated labels).
1572 */
1573 int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external) {
1574 const char *p, *q;
1575 char *sender, *external;
1576
1577 assert(object_path_is_valid(path));
1578 assert(object_path_is_valid(prefix));
1579 assert(ret_sender);
1580 assert(ret_external);
1581
1582 p = object_path_startswith(path, prefix);
1583 if (!p) {
1584 *ret_sender = NULL;
1585 *ret_external = NULL;
1586 return 0;
1587 }
1588
1589 q = strchr(p, '/');
1590 if (!q) {
1591 *ret_sender = NULL;
1592 *ret_external = NULL;
1593 return 0;
1594 }
1595
1596 sender = bus_label_unescape_n(p, q - p);
1597 external = bus_label_unescape(q + 1);
1598 if (!sender || !external) {
1599 free(sender);
1600 free(external);
1601 return -ENOMEM;
1602 }
1603
1604 *ret_sender = sender;
1605 *ret_external = external;
1606 return 1;
1607 }
1608
1609 int bus_property_get_rlimit(
1610 sd_bus *bus,
1611 const char *path,
1612 const char *interface,
1613 const char *property,
1614 sd_bus_message *reply,
1615 void *userdata,
1616 sd_bus_error *error) {
1617
1618 struct rlimit *rl;
1619 uint64_t u;
1620 rlim_t x;
1621 const char *is_soft;
1622
1623 assert(bus);
1624 assert(reply);
1625 assert(userdata);
1626
1627 is_soft = endswith(property, "Soft");
1628 rl = *(struct rlimit**) userdata;
1629 if (rl)
1630 x = is_soft ? rl->rlim_cur : rl->rlim_max;
1631 else {
1632 struct rlimit buf = {};
1633 int z;
1634 const char *s;
1635
1636 s = is_soft ? strndupa(property, is_soft - property) : property;
1637
1638 z = rlimit_from_string(strstr(s, "Limit"));
1639 assert(z >= 0);
1640
1641 getrlimit(z, &buf);
1642 x = is_soft ? buf.rlim_cur : buf.rlim_max;
1643 }
1644
1645 /* rlim_t might have different sizes, let's map
1646 * RLIMIT_INFINITY to (uint64_t) -1, so that it is the same on
1647 * all archs */
1648 u = x == RLIM_INFINITY ? (uint64_t) -1 : (uint64_t) x;
1649
1650 return sd_bus_message_append(reply, "t", u);
1651 }
1652
1653 int bus_track_add_name_many(sd_bus_track *t, char **l) {
1654 int r = 0;
1655 char **i;
1656
1657 assert(t);
1658
1659 /* Continues adding after failure, and returns the first failure. */
1660
1661 STRV_FOREACH(i, l) {
1662 int k;
1663
1664 k = sd_bus_track_add_name(t, *i);
1665 if (k < 0 && r >= 0)
1666 r = k;
1667 }
1668
1669 return r;
1670 }
1671
1672 int bus_open_system_watch_bind(sd_bus **ret) {
1673 _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
1674 const char *e;
1675 int r;
1676
1677 assert(ret);
1678
1679 /* Match like sd_bus_open_system(), but with the "watch_bind" feature and the Connected() signal turned on. */
1680
1681 r = sd_bus_new(&bus);
1682 if (r < 0)
1683 return r;
1684
1685 e = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
1686 if (!e)
1687 e = DEFAULT_SYSTEM_BUS_ADDRESS;
1688
1689 r = sd_bus_set_address(bus, e);
1690 if (r < 0)
1691 return r;
1692
1693 r = sd_bus_set_bus_client(bus, true);
1694 if (r < 0)
1695 return r;
1696
1697 r = sd_bus_set_trusted(bus, true);
1698 if (r < 0)
1699 return r;
1700
1701 r = sd_bus_negotiate_creds(bus, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS);
1702 if (r < 0)
1703 return r;
1704
1705 r = sd_bus_set_watch_bind(bus, true);
1706 if (r < 0)
1707 return r;
1708
1709 r = sd_bus_set_connected_signal(bus, true);
1710 if (r < 0)
1711 return r;
1712
1713 r = sd_bus_start(bus);
1714 if (r < 0)
1715 return r;
1716
1717 *ret = bus;
1718 bus = NULL;
1719
1720 return 0;
1721 }