]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/shared/bus-util.c
tree-wide: use TAKE_PTR() and TAKE_FD() macros
[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 = TAKE_PTR(bus);
608
609 return 0;
610 }
611
612 int bus_connect_user_systemd(sd_bus **_bus) {
613 _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
614 _cleanup_free_ char *ee = NULL;
615 const char *e;
616 int r;
617
618 assert(_bus);
619
620 e = secure_getenv("XDG_RUNTIME_DIR");
621 if (!e)
622 return sd_bus_default_user(_bus);
623
624 ee = bus_address_escape(e);
625 if (!ee)
626 return -ENOMEM;
627
628 r = sd_bus_new(&bus);
629 if (r < 0)
630 return r;
631
632 bus->address = strjoin("unix:path=", ee, "/systemd/private");
633 if (!bus->address)
634 return -ENOMEM;
635
636 r = sd_bus_start(bus);
637 if (r < 0)
638 return sd_bus_default_user(_bus);
639
640 r = bus_check_peercred(bus);
641 if (r < 0)
642 return r;
643
644 *_bus = TAKE_PTR(bus);
645
646 return 0;
647 }
648
649 #define print_property(name, fmt, ...) \
650 do { \
651 if (value) \
652 printf(fmt "\n", __VA_ARGS__); \
653 else \
654 printf("%s=" fmt "\n", name, __VA_ARGS__); \
655 } while (0)
656
657 int bus_print_property(const char *name, sd_bus_message *m, bool value, bool all) {
658 char type;
659 const char *contents;
660 int r;
661
662 assert(name);
663 assert(m);
664
665 r = sd_bus_message_peek_type(m, &type, &contents);
666 if (r < 0)
667 return r;
668
669 switch (type) {
670
671 case SD_BUS_TYPE_STRING: {
672 const char *s;
673
674 r = sd_bus_message_read_basic(m, type, &s);
675 if (r < 0)
676 return r;
677
678 if (all || !isempty(s)) {
679 bool good;
680
681 /* This property has a single value, so we need to take
682 * care not to print a new line, everything else is OK. */
683 good = !strchr(s, '\n');
684 print_property(name, "%s", good ? s : "[unprintable]");
685 }
686
687 return 1;
688 }
689
690 case SD_BUS_TYPE_BOOLEAN: {
691 int b;
692
693 r = sd_bus_message_read_basic(m, type, &b);
694 if (r < 0)
695 return r;
696
697 print_property(name, "%s", yes_no(b));
698
699 return 1;
700 }
701
702 case SD_BUS_TYPE_UINT64: {
703 uint64_t u;
704
705 r = sd_bus_message_read_basic(m, type, &u);
706 if (r < 0)
707 return r;
708
709 /* Yes, heuristics! But we can change this check
710 * should it turn out to not be sufficient */
711
712 if (endswith(name, "Timestamp") || STR_IN_SET(name, "NextElapseUSecRealtime", "LastTriggerUSec")) {
713 char timestamp[FORMAT_TIMESTAMP_MAX], *t;
714
715 t = format_timestamp(timestamp, sizeof(timestamp), u);
716 if (t || all)
717 print_property(name, "%s", strempty(t));
718
719 } else if (strstr(name, "USec")) {
720 char timespan[FORMAT_TIMESPAN_MAX];
721
722 print_property(name, "%s", format_timespan(timespan, sizeof(timespan), u, 0));
723 } else if (streq(name, "RestrictNamespaces")) {
724 _cleanup_free_ char *s = NULL;
725 const char *result;
726
727 if ((u & NAMESPACE_FLAGS_ALL) == 0)
728 result = "yes";
729 else if ((u & NAMESPACE_FLAGS_ALL) == NAMESPACE_FLAGS_ALL)
730 result = "no";
731 else {
732 r = namespace_flag_to_string_many(u, &s);
733 if (r < 0)
734 return r;
735
736 result = s;
737 }
738
739 print_property(name, "%s", result);
740
741 } else if (streq(name, "MountFlags")) {
742 const char *result;
743
744 result = mount_propagation_flags_to_string(u);
745 if (!result)
746 return -EINVAL;
747
748 print_property(name, "%s", result);
749
750 } else if (STR_IN_SET(name, "CapabilityBoundingSet", "AmbientCapabilities")) {
751 _cleanup_free_ char *s = NULL;
752
753 r = capability_set_to_string_alloc(u, &s);
754 if (r < 0)
755 return r;
756
757 print_property(name, "%s", s);
758
759 } else if ((STR_IN_SET(name, "CPUWeight", "StartupCPUWeight", "IOWeight", "StartupIOWeight") && u == CGROUP_WEIGHT_INVALID) ||
760 (STR_IN_SET(name, "CPUShares", "StartupCPUShares") && u == CGROUP_CPU_SHARES_INVALID) ||
761 (STR_IN_SET(name, "BlockIOWeight", "StartupBlockIOWeight") && u == CGROUP_BLKIO_WEIGHT_INVALID) ||
762 (STR_IN_SET(name, "MemoryCurrent", "TasksCurrent") && u == (uint64_t) -1) ||
763 (endswith(name, "NSec") && u == (uint64_t) -1))
764
765 print_property(name, "%s", "[not set]");
766
767 else if ((STR_IN_SET(name, "MemoryLow", "MemoryHigh", "MemoryMax", "MemorySwapMax", "MemoryLimit") && u == CGROUP_LIMIT_MAX) ||
768 (STR_IN_SET(name, "TasksMax", "DefaultTasksMax") && u == (uint64_t) -1) ||
769 (startswith(name, "Limit") && u == (uint64_t) -1) ||
770 (startswith(name, "DefaultLimit") && u == (uint64_t) -1))
771
772 print_property(name, "%s", "infinity");
773 else
774 print_property(name, "%"PRIu64, u);
775
776 return 1;
777 }
778
779 case SD_BUS_TYPE_INT64: {
780 int64_t i;
781
782 r = sd_bus_message_read_basic(m, type, &i);
783 if (r < 0)
784 return r;
785
786 print_property(name, "%"PRIi64, i);
787
788 return 1;
789 }
790
791 case SD_BUS_TYPE_UINT32: {
792 uint32_t u;
793
794 r = sd_bus_message_read_basic(m, type, &u);
795 if (r < 0)
796 return r;
797
798 if (strstr(name, "UMask") || strstr(name, "Mode"))
799 print_property(name, "%04o", u);
800 else if (streq(name, "UID")) {
801 if (u == UID_INVALID)
802 print_property(name, "%s", "[not set]");
803 else
804 print_property(name, "%"PRIu32, u);
805 } else if (streq(name, "GID")) {
806 if (u == GID_INVALID)
807 print_property(name, "%s", "[not set]");
808 else
809 print_property(name, "%"PRIu32, u);
810 } else
811 print_property(name, "%"PRIu32, u);
812
813 return 1;
814 }
815
816 case SD_BUS_TYPE_INT32: {
817 int32_t i;
818
819 r = sd_bus_message_read_basic(m, type, &i);
820 if (r < 0)
821 return r;
822
823 print_property(name, "%"PRIi32, i);
824 return 1;
825 }
826
827 case SD_BUS_TYPE_DOUBLE: {
828 double d;
829
830 r = sd_bus_message_read_basic(m, type, &d);
831 if (r < 0)
832 return r;
833
834 print_property(name, "%g", d);
835 return 1;
836 }
837
838 case SD_BUS_TYPE_ARRAY:
839 if (streq(contents, "s")) {
840 bool first = true;
841 const char *str;
842
843 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, contents);
844 if (r < 0)
845 return r;
846
847 while ((r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &str)) > 0) {
848 bool good;
849
850 if (first && !value)
851 printf("%s=", name);
852
853 /* This property has multiple space-separated values, so
854 * neither spaces not newlines can be allowed in a value. */
855 good = str[strcspn(str, " \n")] == '\0';
856
857 printf("%s%s", first ? "" : " ", good ? str : "[unprintable]");
858
859 first = false;
860 }
861 if (r < 0)
862 return r;
863
864 if (first && all && !value)
865 printf("%s=", name);
866 if (!first || all)
867 puts("");
868
869 r = sd_bus_message_exit_container(m);
870 if (r < 0)
871 return r;
872
873 return 1;
874
875 } else if (streq(contents, "y")) {
876 const uint8_t *u;
877 size_t n;
878
879 r = sd_bus_message_read_array(m, SD_BUS_TYPE_BYTE, (const void**) &u, &n);
880 if (r < 0)
881 return r;
882
883 if (all || n > 0) {
884 unsigned int i;
885
886 if (!value)
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(m, 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 if (!value)
909 printf("%s=", name);
910
911 for (i = 0; i < n; i++)
912 printf("%08x", u[i]);
913
914 puts("");
915 }
916
917 return 1;
918 }
919
920 break;
921 }
922
923 return 0;
924 }
925
926 int bus_message_print_all_properties(
927 sd_bus_message *m,
928 bus_message_print_t func,
929 char **filter,
930 bool value,
931 bool all,
932 Set **found_properties) {
933
934 int r;
935
936 assert(m);
937
938 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{sv}");
939 if (r < 0)
940 return r;
941
942 while ((r = sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
943 const char *name;
944 const char *contents;
945
946 r = sd_bus_message_read_basic(m, SD_BUS_TYPE_STRING, &name);
947 if (r < 0)
948 return r;
949
950 if (found_properties) {
951 r = set_ensure_allocated(found_properties, &string_hash_ops);
952 if (r < 0)
953 return log_oom();
954
955 r = set_put(*found_properties, name);
956 if (r < 0 && r != EEXIST)
957 return log_oom();
958 }
959
960 if (!filter || strv_find(filter, name)) {
961 r = sd_bus_message_peek_type(m, NULL, &contents);
962 if (r < 0)
963 return r;
964
965 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_VARIANT, contents);
966 if (r < 0)
967 return r;
968
969 if (func)
970 r = func(name, m, value, all);
971 if (!func || r == 0)
972 r = bus_print_property(name, m, value, all);
973 if (r < 0)
974 return r;
975 if (r == 0) {
976 if (all)
977 printf("%s=[unprintable]\n", name);
978 /* skip what we didn't read */
979 r = sd_bus_message_skip(m, contents);
980 if (r < 0)
981 return r;
982 }
983
984 r = sd_bus_message_exit_container(m);
985 if (r < 0)
986 return r;
987 } else {
988 r = sd_bus_message_skip(m, "v");
989 if (r < 0)
990 return r;
991 }
992
993 r = sd_bus_message_exit_container(m);
994 if (r < 0)
995 return r;
996 }
997 if (r < 0)
998 return r;
999
1000 r = sd_bus_message_exit_container(m);
1001 if (r < 0)
1002 return r;
1003
1004 return 0;
1005 }
1006
1007 int bus_print_all_properties(
1008 sd_bus *bus,
1009 const char *dest,
1010 const char *path,
1011 bus_message_print_t func,
1012 char **filter,
1013 bool value,
1014 bool all,
1015 Set **found_properties) {
1016
1017 _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
1018 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
1019 int r;
1020
1021 assert(bus);
1022 assert(path);
1023
1024 r = sd_bus_call_method(bus,
1025 dest,
1026 path,
1027 "org.freedesktop.DBus.Properties",
1028 "GetAll",
1029 &error,
1030 &reply,
1031 "s", "");
1032 if (r < 0)
1033 return r;
1034
1035 return bus_message_print_all_properties(reply, func, filter, value, all, found_properties);
1036 }
1037
1038 int bus_map_id128(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
1039 sd_id128_t *p = userdata;
1040 const void *v;
1041 size_t n;
1042 int r;
1043
1044 r = sd_bus_message_read_array(m, SD_BUS_TYPE_BYTE, &v, &n);
1045 if (r < 0)
1046 return r;
1047
1048 if (n == 0)
1049 *p = SD_ID128_NULL;
1050 else if (n == 16)
1051 memcpy((*p).bytes, v, n);
1052 else
1053 return -EINVAL;
1054
1055 return 0;
1056 }
1057
1058 static int map_basic(sd_bus *bus, const char *member, sd_bus_message *m, unsigned flags, sd_bus_error *error, void *userdata) {
1059 char type;
1060 int r;
1061
1062 r = sd_bus_message_peek_type(m, &type, NULL);
1063 if (r < 0)
1064 return r;
1065
1066 switch (type) {
1067
1068 case SD_BUS_TYPE_STRING: {
1069 const char **p = userdata;
1070 const char *s;
1071
1072 r = sd_bus_message_read_basic(m, type, &s);
1073 if (r < 0)
1074 return r;
1075
1076 if (isempty(s))
1077 s = NULL;
1078
1079 if (flags & BUS_MAP_STRDUP)
1080 return free_and_strdup((char **) userdata, s);
1081
1082 *p = s;
1083 return 0;
1084 }
1085
1086 case SD_BUS_TYPE_ARRAY: {
1087 _cleanup_strv_free_ char **l = NULL;
1088 char ***p = userdata;
1089
1090 r = bus_message_read_strv_extend(m, &l);
1091 if (r < 0)
1092 return r;
1093
1094 strv_free(*p);
1095 *p = TAKE_PTR(l);
1096 return 0;
1097 }
1098
1099 case SD_BUS_TYPE_BOOLEAN: {
1100 int b;
1101
1102 r = sd_bus_message_read_basic(m, type, &b);
1103 if (r < 0)
1104 return r;
1105
1106 if (flags & BUS_MAP_BOOLEAN_AS_BOOL)
1107 * (bool*) userdata = !!b;
1108 else
1109 * (int*) userdata = b;
1110
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 unsigned flags,
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, flags, error, v);
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 unsigned flags,
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, flags, 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 unsigned flags,
1265 sd_bus_error *error,
1266 sd_bus_message **reply,
1267 void *userdata) {
1268
1269 _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
1270 int r;
1271
1272 assert(bus);
1273 assert(destination);
1274 assert(path);
1275 assert(map);
1276 assert(reply || (flags & BUS_MAP_STRDUP));
1277
1278 r = sd_bus_call_method(
1279 bus,
1280 destination,
1281 path,
1282 "org.freedesktop.DBus.Properties",
1283 "GetAll",
1284 error,
1285 &m,
1286 "s", "");
1287 if (r < 0)
1288 return r;
1289
1290 r = bus_message_map_all_properties(m, map, flags, error, userdata);
1291 if (r < 0)
1292 return r;
1293
1294 if (reply)
1295 *reply = sd_bus_message_ref(m);
1296
1297 return r;
1298 }
1299
1300 int bus_connect_transport(BusTransport transport, const char *host, bool user, sd_bus **ret) {
1301 _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
1302 int r;
1303
1304 assert(transport >= 0);
1305 assert(transport < _BUS_TRANSPORT_MAX);
1306 assert(ret);
1307
1308 assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
1309 assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -EOPNOTSUPP);
1310
1311 switch (transport) {
1312
1313 case BUS_TRANSPORT_LOCAL:
1314 if (user)
1315 r = sd_bus_default_user(&bus);
1316 else
1317 r = sd_bus_default_system(&bus);
1318
1319 break;
1320
1321 case BUS_TRANSPORT_REMOTE:
1322 r = sd_bus_open_system_remote(&bus, host);
1323 break;
1324
1325 case BUS_TRANSPORT_MACHINE:
1326 r = sd_bus_open_system_machine(&bus, host);
1327 break;
1328
1329 default:
1330 assert_not_reached("Hmm, unknown transport type.");
1331 }
1332 if (r < 0)
1333 return r;
1334
1335 r = sd_bus_set_exit_on_disconnect(bus, true);
1336 if (r < 0)
1337 return r;
1338
1339 *ret = TAKE_PTR(bus);
1340
1341 return 0;
1342 }
1343
1344 int bus_connect_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus) {
1345 int r;
1346
1347 assert(transport >= 0);
1348 assert(transport < _BUS_TRANSPORT_MAX);
1349 assert(bus);
1350
1351 assert_return((transport == BUS_TRANSPORT_LOCAL) == !host, -EINVAL);
1352 assert_return(transport == BUS_TRANSPORT_LOCAL || !user, -EOPNOTSUPP);
1353
1354 switch (transport) {
1355
1356 case BUS_TRANSPORT_LOCAL:
1357 if (user)
1358 r = bus_connect_user_systemd(bus);
1359 else
1360 r = bus_connect_system_systemd(bus);
1361
1362 break;
1363
1364 case BUS_TRANSPORT_REMOTE:
1365 r = sd_bus_open_system_remote(bus, host);
1366 break;
1367
1368 case BUS_TRANSPORT_MACHINE:
1369 r = sd_bus_open_system_machine(bus, host);
1370 break;
1371
1372 default:
1373 assert_not_reached("Hmm, unknown transport type.");
1374 }
1375
1376 return r;
1377 }
1378
1379 int bus_property_get_bool(
1380 sd_bus *bus,
1381 const char *path,
1382 const char *interface,
1383 const char *property,
1384 sd_bus_message *reply,
1385 void *userdata,
1386 sd_bus_error *error) {
1387
1388 int b = *(bool*) userdata;
1389
1390 return sd_bus_message_append_basic(reply, 'b', &b);
1391 }
1392
1393 int bus_property_set_bool(
1394 sd_bus *bus,
1395 const char *path,
1396 const char *interface,
1397 const char *property,
1398 sd_bus_message *value,
1399 void *userdata,
1400 sd_bus_error *error) {
1401
1402 int b, r;
1403
1404 r = sd_bus_message_read(value, "b", &b);
1405 if (r < 0)
1406 return r;
1407
1408 *(bool *) userdata = !!b;
1409 return 0;
1410 }
1411
1412 int bus_property_get_id128(
1413 sd_bus *bus,
1414 const char *path,
1415 const char *interface,
1416 const char *property,
1417 sd_bus_message *reply,
1418 void *userdata,
1419 sd_bus_error *error) {
1420
1421 sd_id128_t *id = userdata;
1422
1423 if (sd_id128_is_null(*id)) /* Add an empty array if the ID is zero */
1424 return sd_bus_message_append(reply, "ay", 0);
1425 else
1426 return sd_bus_message_append_array(reply, 'y', id->bytes, 16);
1427 }
1428
1429 #if __SIZEOF_SIZE_T__ != 8
1430 int bus_property_get_size(
1431 sd_bus *bus,
1432 const char *path,
1433 const char *interface,
1434 const char *property,
1435 sd_bus_message *reply,
1436 void *userdata,
1437 sd_bus_error *error) {
1438
1439 uint64_t sz = *(size_t*) userdata;
1440
1441 return sd_bus_message_append_basic(reply, 't', &sz);
1442 }
1443 #endif
1444
1445 #if __SIZEOF_LONG__ != 8
1446 int bus_property_get_long(
1447 sd_bus *bus,
1448 const char *path,
1449 const char *interface,
1450 const char *property,
1451 sd_bus_message *reply,
1452 void *userdata,
1453 sd_bus_error *error) {
1454
1455 int64_t l = *(long*) userdata;
1456
1457 return sd_bus_message_append_basic(reply, 'x', &l);
1458 }
1459
1460 int bus_property_get_ulong(
1461 sd_bus *bus,
1462 const char *path,
1463 const char *interface,
1464 const char *property,
1465 sd_bus_message *reply,
1466 void *userdata,
1467 sd_bus_error *error) {
1468
1469 uint64_t ul = *(unsigned long*) userdata;
1470
1471 return sd_bus_message_append_basic(reply, 't', &ul);
1472 }
1473 #endif
1474
1475 int bus_log_parse_error(int r) {
1476 return log_error_errno(r, "Failed to parse bus message: %m");
1477 }
1478
1479 int bus_log_create_error(int r) {
1480 return log_error_errno(r, "Failed to create bus message: %m");
1481 }
1482
1483 /**
1484 * bus_path_encode_unique() - encode unique object path
1485 * @b: bus connection or NULL
1486 * @prefix: object path prefix
1487 * @sender_id: unique-name of client, or NULL
1488 * @external_id: external ID to be chosen by client, or NULL
1489 * @ret_path: storage for encoded object path pointer
1490 *
1491 * Whenever we provide a bus API that allows clients to create and manage
1492 * server-side objects, we need to provide a unique name for these objects. If
1493 * we let the server choose the name, we suffer from a race condition: If a
1494 * client creates an object asynchronously, it cannot destroy that object until
1495 * it received the method reply. It cannot know the name of the new object,
1496 * thus, it cannot destroy it. Furthermore, it enforces a round-trip.
1497 *
1498 * Therefore, many APIs allow the client to choose the unique name for newly
1499 * created objects. There're two problems to solve, though:
1500 * 1) Object names are usually defined via dbus object paths, which are
1501 * usually globally namespaced. Therefore, multiple clients must be able
1502 * to choose unique object names without interference.
1503 * 2) If multiple libraries share the same bus connection, they must be
1504 * able to choose unique object names without interference.
1505 * The first problem is solved easily by prefixing a name with the
1506 * unique-bus-name of a connection. The server side must enforce this and
1507 * reject any other name. The second problem is solved by providing unique
1508 * suffixes from within sd-bus.
1509 *
1510 * This helper allows clients to create unique object-paths. It uses the
1511 * template '/prefix/sender_id/external_id' and returns the new path in
1512 * @ret_path (must be freed by the caller).
1513 * If @sender_id is NULL, the unique-name of @b is used. If @external_id is
1514 * NULL, this function allocates a unique suffix via @b (by requesting a new
1515 * cookie). If both @sender_id and @external_id are given, @b can be passed as
1516 * NULL.
1517 *
1518 * Returns: 0 on success, negative error code on failure.
1519 */
1520 int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path) {
1521 _cleanup_free_ char *sender_label = NULL, *external_label = NULL;
1522 char external_buf[DECIMAL_STR_MAX(uint64_t)], *p;
1523 int r;
1524
1525 assert_return(b || (sender_id && external_id), -EINVAL);
1526 assert_return(object_path_is_valid(prefix), -EINVAL);
1527 assert_return(ret_path, -EINVAL);
1528
1529 if (!sender_id) {
1530 r = sd_bus_get_unique_name(b, &sender_id);
1531 if (r < 0)
1532 return r;
1533 }
1534
1535 if (!external_id) {
1536 xsprintf(external_buf, "%"PRIu64, ++b->cookie);
1537 external_id = external_buf;
1538 }
1539
1540 sender_label = bus_label_escape(sender_id);
1541 if (!sender_label)
1542 return -ENOMEM;
1543
1544 external_label = bus_label_escape(external_id);
1545 if (!external_label)
1546 return -ENOMEM;
1547
1548 p = strjoin(prefix, "/", sender_label, "/", external_label);
1549 if (!p)
1550 return -ENOMEM;
1551
1552 *ret_path = p;
1553 return 0;
1554 }
1555
1556 /**
1557 * bus_path_decode_unique() - decode unique object path
1558 * @path: object path to decode
1559 * @prefix: object path prefix
1560 * @ret_sender: output parameter for sender-id label
1561 * @ret_external: output parameter for external-id label
1562 *
1563 * This does the reverse of bus_path_encode_unique() (see its description for
1564 * details). Both trailing labels, sender-id and external-id, are unescaped and
1565 * returned in the given output parameters (the caller must free them).
1566 *
1567 * Note that this function returns 0 if the path does not match the template
1568 * (see bus_path_encode_unique()), 1 if it matched.
1569 *
1570 * Returns: Negative error code on failure, 0 if the given object path does not
1571 * match the template (return parameters are set to NULL), 1 if it was
1572 * parsed successfully (return parameters contain allocated labels).
1573 */
1574 int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external) {
1575 const char *p, *q;
1576 char *sender, *external;
1577
1578 assert(object_path_is_valid(path));
1579 assert(object_path_is_valid(prefix));
1580 assert(ret_sender);
1581 assert(ret_external);
1582
1583 p = object_path_startswith(path, prefix);
1584 if (!p) {
1585 *ret_sender = NULL;
1586 *ret_external = NULL;
1587 return 0;
1588 }
1589
1590 q = strchr(p, '/');
1591 if (!q) {
1592 *ret_sender = NULL;
1593 *ret_external = NULL;
1594 return 0;
1595 }
1596
1597 sender = bus_label_unescape_n(p, q - p);
1598 external = bus_label_unescape(q + 1);
1599 if (!sender || !external) {
1600 free(sender);
1601 free(external);
1602 return -ENOMEM;
1603 }
1604
1605 *ret_sender = sender;
1606 *ret_external = external;
1607 return 1;
1608 }
1609
1610 int bus_property_get_rlimit(
1611 sd_bus *bus,
1612 const char *path,
1613 const char *interface,
1614 const char *property,
1615 sd_bus_message *reply,
1616 void *userdata,
1617 sd_bus_error *error) {
1618
1619 struct rlimit *rl;
1620 uint64_t u;
1621 rlim_t x;
1622 const char *is_soft;
1623
1624 assert(bus);
1625 assert(reply);
1626 assert(userdata);
1627
1628 is_soft = endswith(property, "Soft");
1629 rl = *(struct rlimit**) userdata;
1630 if (rl)
1631 x = is_soft ? rl->rlim_cur : rl->rlim_max;
1632 else {
1633 struct rlimit buf = {};
1634 int z;
1635 const char *s;
1636
1637 s = is_soft ? strndupa(property, is_soft - property) : property;
1638
1639 z = rlimit_from_string(strstr(s, "Limit"));
1640 assert(z >= 0);
1641
1642 getrlimit(z, &buf);
1643 x = is_soft ? buf.rlim_cur : buf.rlim_max;
1644 }
1645
1646 /* rlim_t might have different sizes, let's map
1647 * RLIMIT_INFINITY to (uint64_t) -1, so that it is the same on
1648 * all archs */
1649 u = x == RLIM_INFINITY ? (uint64_t) -1 : (uint64_t) x;
1650
1651 return sd_bus_message_append(reply, "t", u);
1652 }
1653
1654 int bus_track_add_name_many(sd_bus_track *t, char **l) {
1655 int r = 0;
1656 char **i;
1657
1658 assert(t);
1659
1660 /* Continues adding after failure, and returns the first failure. */
1661
1662 STRV_FOREACH(i, l) {
1663 int k;
1664
1665 k = sd_bus_track_add_name(t, *i);
1666 if (k < 0 && r >= 0)
1667 r = k;
1668 }
1669
1670 return r;
1671 }
1672
1673 int bus_open_system_watch_bind(sd_bus **ret) {
1674 _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
1675 const char *e;
1676 int r;
1677
1678 assert(ret);
1679
1680 /* Match like sd_bus_open_system(), but with the "watch_bind" feature and the Connected() signal turned on. */
1681
1682 r = sd_bus_new(&bus);
1683 if (r < 0)
1684 return r;
1685
1686 e = secure_getenv("DBUS_SYSTEM_BUS_ADDRESS");
1687 if (!e)
1688 e = DEFAULT_SYSTEM_BUS_ADDRESS;
1689
1690 r = sd_bus_set_address(bus, e);
1691 if (r < 0)
1692 return r;
1693
1694 r = sd_bus_set_bus_client(bus, true);
1695 if (r < 0)
1696 return r;
1697
1698 r = sd_bus_set_trusted(bus, true);
1699 if (r < 0)
1700 return r;
1701
1702 r = sd_bus_negotiate_creds(bus, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS);
1703 if (r < 0)
1704 return r;
1705
1706 r = sd_bus_set_watch_bind(bus, true);
1707 if (r < 0)
1708 return r;
1709
1710 r = sd_bus_set_connected_signal(bus, true);
1711 if (r < 0)
1712 return r;
1713
1714 r = sd_bus_start(bus);
1715 if (r < 0)
1716 return r;
1717
1718 *ret = TAKE_PTR(bus);
1719
1720 return 0;
1721 }