1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
5 #include "alloc-util.h"
6 #include "bus-control.h"
7 #include "bus-internal.h"
8 #include "bus-message.h"
12 #include "process-util.h"
13 #include "string-util.h"
15 #include "user-util.h"
17 _public_
int sd_bus_get_unique_name(sd_bus
*bus
, const char **unique
) {
20 assert_return(bus
, -EINVAL
);
21 assert_return(bus
= bus_resolve(bus
), -ENOPKG
);
22 assert_return(unique
, -EINVAL
);
23 assert_return(!bus_origin_changed(bus
), -ECHILD
);
28 r
= bus_ensure_running(bus
);
32 *unique
= bus
->unique_name
;
36 static int validate_request_name_parameters(
40 uint32_t *ret_param
) {
48 assert_return(!(flags
& ~(SD_BUS_NAME_ALLOW_REPLACEMENT
|SD_BUS_NAME_REPLACE_EXISTING
|SD_BUS_NAME_QUEUE
)), -EINVAL
);
49 assert_return(service_name_is_valid(name
), -EINVAL
);
50 assert_return(name
[0] != ':', -EINVAL
);
55 /* Don't allow requesting the special driver and local names */
56 if (STR_IN_SET(name
, "org.freedesktop.DBus", "org.freedesktop.DBus.Local"))
59 if (!BUS_IS_OPEN(bus
->state
))
62 if (flags
& SD_BUS_NAME_ALLOW_REPLACEMENT
)
63 param
|= BUS_NAME_ALLOW_REPLACEMENT
;
64 if (flags
& SD_BUS_NAME_REPLACE_EXISTING
)
65 param
|= BUS_NAME_REPLACE_EXISTING
;
66 if (!(flags
& SD_BUS_NAME_QUEUE
))
67 param
|= BUS_NAME_DO_NOT_QUEUE
;
74 _public_
int sd_bus_request_name(
79 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
80 uint32_t ret
, param
= 0;
83 assert_return(bus
, -EINVAL
);
84 assert_return(bus
= bus_resolve(bus
), -ENOPKG
);
85 assert_return(name
, -EINVAL
);
86 assert_return(!bus_origin_changed(bus
), -ECHILD
);
88 r
= validate_request_name_parameters(bus
, name
, flags
, ¶m
);
92 r
= sd_bus_call_method(
94 "org.freedesktop.DBus",
95 "/org/freedesktop/DBus",
96 "org.freedesktop.DBus",
106 r
= sd_bus_message_read(reply
, "u", &ret
);
112 case BUS_NAME_ALREADY_OWNER
:
115 case BUS_NAME_EXISTS
:
118 case BUS_NAME_IN_QUEUE
:
121 case BUS_NAME_PRIMARY_OWNER
:
128 static int default_request_name_handler(
131 sd_bus_error
*ret_error
) {
138 if (sd_bus_message_is_method_error(m
, NULL
)) {
139 log_debug_errno(sd_bus_message_get_errno(m
),
140 "Unable to request name, failing connection: %s",
141 sd_bus_message_get_error(m
)->message
);
143 bus_enter_closing(sd_bus_message_get_bus(m
));
147 r
= sd_bus_message_read(m
, "u", &ret
);
153 case BUS_NAME_ALREADY_OWNER
:
154 log_debug("Already owner of requested service name, ignoring.");
157 case BUS_NAME_IN_QUEUE
:
158 log_debug("In queue for requested service name.");
161 case BUS_NAME_PRIMARY_OWNER
:
162 log_debug("Successfully acquired requested service name.");
165 case BUS_NAME_EXISTS
:
166 log_debug("Requested service name already owned, failing connection.");
167 bus_enter_closing(sd_bus_message_get_bus(m
));
171 log_debug("Unexpected response from RequestName(), failing connection.");
172 bus_enter_closing(sd_bus_message_get_bus(m
));
176 _public_
int sd_bus_request_name_async(
178 sd_bus_slot
**ret_slot
,
181 sd_bus_message_handler_t callback
,
187 assert_return(bus
, -EINVAL
);
188 assert_return(bus
= bus_resolve(bus
), -ENOPKG
);
189 assert_return(name
, -EINVAL
);
190 assert_return(!bus_origin_changed(bus
), -ECHILD
);
192 r
= validate_request_name_parameters(bus
, name
, flags
, ¶m
);
196 return sd_bus_call_method_async(
199 "org.freedesktop.DBus",
200 "/org/freedesktop/DBus",
201 "org.freedesktop.DBus",
203 callback
?: default_request_name_handler
,
210 static int validate_release_name_parameters(
217 assert_return(service_name_is_valid(name
), -EINVAL
);
218 assert_return(name
[0] != ':', -EINVAL
);
220 if (!bus
->bus_client
)
223 /* Don't allow releasing the special driver and local names */
224 if (STR_IN_SET(name
, "org.freedesktop.DBus", "org.freedesktop.DBus.Local"))
227 if (!BUS_IS_OPEN(bus
->state
))
233 _public_
int sd_bus_release_name(
237 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
241 assert_return(bus
, -EINVAL
);
242 assert_return(bus
= bus_resolve(bus
), -ENOPKG
);
243 assert_return(name
, -EINVAL
);
244 assert_return(!bus_origin_changed(bus
), -ECHILD
);
246 r
= validate_release_name_parameters(bus
, name
);
250 r
= sd_bus_call_method(
252 "org.freedesktop.DBus",
253 "/org/freedesktop/DBus",
254 "org.freedesktop.DBus",
263 r
= sd_bus_message_read(reply
, "u", &ret
);
269 case BUS_NAME_NON_EXISTENT
:
272 case BUS_NAME_NOT_OWNER
:
275 case BUS_NAME_RELEASED
:
282 static int default_release_name_handler(
285 sd_bus_error
*ret_error
) {
292 if (sd_bus_message_is_method_error(m
, NULL
)) {
293 log_debug_errno(sd_bus_message_get_errno(m
),
294 "Unable to release name, failing connection: %s",
295 sd_bus_message_get_error(m
)->message
);
297 bus_enter_closing(sd_bus_message_get_bus(m
));
301 r
= sd_bus_message_read(m
, "u", &ret
);
307 case BUS_NAME_NON_EXISTENT
:
308 log_debug("Name asked to release is not taken currently, ignoring.");
311 case BUS_NAME_NOT_OWNER
:
312 log_debug("Name asked to release is owned by somebody else, ignoring.");
315 case BUS_NAME_RELEASED
:
316 log_debug("Name successfully released.");
320 log_debug("Unexpected response from ReleaseName(), failing connection.");
321 bus_enter_closing(sd_bus_message_get_bus(m
));
325 _public_
int sd_bus_release_name_async(
327 sd_bus_slot
**ret_slot
,
329 sd_bus_message_handler_t callback
,
334 assert_return(bus
, -EINVAL
);
335 assert_return(bus
= bus_resolve(bus
), -ENOPKG
);
336 assert_return(name
, -EINVAL
);
337 assert_return(!bus_origin_changed(bus
), -ECHILD
);
339 r
= validate_release_name_parameters(bus
, name
);
343 return sd_bus_call_method_async(
346 "org.freedesktop.DBus",
347 "/org/freedesktop/DBus",
348 "org.freedesktop.DBus",
350 callback
?: default_release_name_handler
,
356 _public_
int sd_bus_list_names(sd_bus
*bus
, char ***ret_acquired
, char ***ret_activatable
) {
357 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
358 _cleanup_strv_free_
char **x
= NULL
, **y
= NULL
;
361 assert_return(bus
, -EINVAL
);
362 assert_return(bus
= bus_resolve(bus
), -ENOPKG
);
363 assert_return(ret_acquired
|| ret_activatable
, -EINVAL
);
364 assert_return(!bus_origin_changed(bus
), -ECHILD
);
366 if (!bus
->bus_client
)
369 if (!BUS_IS_OPEN(bus
->state
))
373 r
= sd_bus_call_method(
375 "org.freedesktop.DBus",
376 "/org/freedesktop/DBus",
377 "org.freedesktop.DBus",
385 r
= sd_bus_message_read_strv(reply
, &x
);
389 reply
= sd_bus_message_unref(reply
);
392 if (ret_activatable
) {
393 r
= sd_bus_call_method(
395 "org.freedesktop.DBus",
396 "/org/freedesktop/DBus",
397 "org.freedesktop.DBus",
398 "ListActivatableNames",
405 r
= sd_bus_message_read_strv(reply
, &y
);
409 *ret_activatable
= TAKE_PTR(y
);
413 *ret_acquired
= TAKE_PTR(x
);
418 _public_
int sd_bus_get_name_creds(
422 sd_bus_creds
**ret
) {
424 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply_unique
= NULL
, *reply
= NULL
;
425 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*c
= NULL
;
429 assert_return(bus
, -EINVAL
);
430 assert_return(bus
= bus_resolve(bus
), -ENOPKG
);
431 assert_return(name
, -EINVAL
);
432 assert_return((mask
& ~SD_BUS_CREDS_AUGMENT
) <= _SD_BUS_CREDS_ALL
, -EOPNOTSUPP
);
433 assert_return(mask
== 0 || ret
, -EINVAL
);
434 assert_return(!bus_origin_changed(bus
), -ECHILD
);
435 assert_return(service_name_is_valid(name
), -EINVAL
);
437 if (!bus
->bus_client
)
440 /* Turn off augmenting if this isn't a local connection. If the connection is not local, then /proc is not
443 mask
&= ~SD_BUS_CREDS_AUGMENT
;
445 if (streq(name
, "org.freedesktop.DBus.Local"))
448 if (streq(name
, "org.freedesktop.DBus"))
449 return sd_bus_get_owner_creds(bus
, mask
, ret
);
451 if (!BUS_IS_OPEN(bus
->state
))
454 /* If the name is unique anyway, we can use it directly */
455 unique
= name
[0] == ':' ? name
: NULL
;
457 /* Only query the owner if the caller wants to know it and the name is not unique anyway, or if the caller just
458 * wants to check whether a name exists */
459 if ((FLAGS_SET(mask
, SD_BUS_CREDS_UNIQUE_NAME
) && !unique
) || mask
== 0) {
460 r
= sd_bus_call_method(
462 "org.freedesktop.DBus",
463 "/org/freedesktop/DBus",
464 "org.freedesktop.DBus",
473 r
= sd_bus_message_read(reply_unique
, "s", &unique
);
479 bool need_pid
, need_uid
, need_gids
, need_selinux
, need_separate_calls
, need_pidfd
, need_augment
;
480 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
481 _cleanup_(pidref_done
) PidRef pidref
= PIDREF_NULL
;
487 if ((mask
& SD_BUS_CREDS_UNIQUE_NAME
) && unique
) {
488 c
->unique_name
= strdup(unique
);
492 c
->mask
|= SD_BUS_CREDS_UNIQUE_NAME
;
496 (mask
& SD_BUS_CREDS_AUGMENT
) &&
497 (mask
& (SD_BUS_CREDS_UID
|SD_BUS_CREDS_SUID
|SD_BUS_CREDS_FSUID
|
498 SD_BUS_CREDS_GID
|SD_BUS_CREDS_EGID
|SD_BUS_CREDS_SGID
|SD_BUS_CREDS_FSGID
|
499 SD_BUS_CREDS_SUPPLEMENTARY_GIDS
|
500 SD_BUS_CREDS_COMM
|SD_BUS_CREDS_EXE
|SD_BUS_CREDS_CMDLINE
|
501 SD_BUS_CREDS_CGROUP
|SD_BUS_CREDS_UNIT
|SD_BUS_CREDS_USER_UNIT
|SD_BUS_CREDS_SLICE
|SD_BUS_CREDS_SESSION
|SD_BUS_CREDS_OWNER_UID
|
502 SD_BUS_CREDS_EFFECTIVE_CAPS
|SD_BUS_CREDS_PERMITTED_CAPS
|SD_BUS_CREDS_INHERITABLE_CAPS
|SD_BUS_CREDS_BOUNDING_CAPS
|
503 SD_BUS_CREDS_SELINUX_CONTEXT
|
504 SD_BUS_CREDS_AUDIT_SESSION_ID
|SD_BUS_CREDS_AUDIT_LOGIN_UID
|
505 SD_BUS_CREDS_PIDFD
));
507 need_pid
= (mask
& SD_BUS_CREDS_PID
) || need_augment
;
508 need_uid
= mask
& SD_BUS_CREDS_EUID
;
509 need_gids
= mask
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
;
510 need_selinux
= mask
& SD_BUS_CREDS_SELINUX_CONTEXT
;
511 need_pidfd
= (mask
& SD_BUS_CREDS_PIDFD
) || need_augment
;
513 if (need_pid
+ need_uid
+ need_selinux
+ need_pidfd
+ need_gids
> 1) {
515 /* If we need more than one of the credentials, then use GetConnectionCredentials() */
517 r
= sd_bus_call_method(
519 "org.freedesktop.DBus",
520 "/org/freedesktop/DBus",
521 "org.freedesktop.DBus",
522 "GetConnectionCredentials",
530 if (!sd_bus_error_has_name(&error
, SD_BUS_ERROR_UNKNOWN_METHOD
))
533 /* If we got an unknown method error, fall back to the individual calls... */
534 need_separate_calls
= true;
535 sd_bus_error_free(&error
);
538 need_separate_calls
= false;
540 r
= sd_bus_message_enter_container(reply
, 'a', "{sv}");
547 r
= sd_bus_message_enter_container(reply
, 'e', "sv");
553 r
= sd_bus_message_read(reply
, "s", &m
);
557 if (need_uid
&& streq(m
, "UnixUserID")) {
560 r
= sd_bus_message_read(reply
, "v", "u", &u
);
565 c
->mask
|= SD_BUS_CREDS_EUID
;
567 } else if (need_pid
&& streq(m
, "ProcessID")) {
570 r
= sd_bus_message_read(reply
, "v", "u", &p
);
574 if (!pidref_is_set(&pidref
))
575 pidref
= PIDREF_MAKE_FROM_PID(p
);
577 if (mask
& SD_BUS_CREDS_PID
) {
579 c
->mask
|= SD_BUS_CREDS_PID
;
582 } else if (need_selinux
&& streq(m
, "LinuxSecurityLabel")) {
583 const void *p
= NULL
;
586 r
= sd_bus_message_enter_container(reply
, 'v', "ay");
590 r
= sd_bus_message_read_array(reply
, 'y', &p
, &sz
);
594 r
= free_and_strndup(&c
->label
, p
, sz
);
598 c
->mask
|= SD_BUS_CREDS_SELINUX_CONTEXT
;
600 r
= sd_bus_message_exit_container(reply
);
603 } else if (need_pidfd
&& streq(m
, "ProcessFD")) {
606 r
= sd_bus_message_read(reply
, "v", "h", &fd
);
610 pidref_done(&pidref
);
611 r
= pidref_set_pidfd(&pidref
, fd
);
615 if (mask
& SD_BUS_CREDS_PIDFD
) {
616 fd
= fcntl(fd
, F_DUPFD_CLOEXEC
, 3);
620 close_and_replace(c
->pidfd
, fd
);
621 c
->mask
|= SD_BUS_CREDS_PIDFD
;
623 } else if (need_gids
&& streq(m
, "UnixGroupIDs")) {
625 /* Note that D-Bus actually only gives us a combined list of
626 * primary gid and supplementary gids. And we don't know
627 * which one the primary one is. We'll take the whole shebang
628 * hence and use it as the supplementary group list, and not
629 * initialize the primary gid field. This is slightly
630 * incorrect of course, but only slightly, as in effect if
631 * the primary gid is also listed in the supplementary gid
632 * it has zero effect. */
634 r
= sd_bus_message_enter_container(reply
, 'v', "au");
638 r
= sd_bus_message_enter_container(reply
, 'a', "u");
645 r
= sd_bus_message_read(reply
, "u", &u
);
651 if (!GREEDY_REALLOC(c
->supplementary_gids
, c
->n_supplementary_gids
+1))
654 c
->supplementary_gids
[c
->n_supplementary_gids
++] = (gid_t
) u
;
657 r
= sd_bus_message_exit_container(reply
);
661 r
= sd_bus_message_exit_container(reply
);
665 c
->mask
|= SD_BUS_CREDS_SUPPLEMENTARY_GIDS
;
667 r
= sd_bus_message_skip(reply
, "v");
672 r
= sd_bus_message_exit_container(reply
);
677 r
= sd_bus_message_exit_container(reply
);
681 if (need_pid
&& !pidref_is_set(&pidref
))
685 } else /* When we only need a single field, then let's use separate calls */
686 need_separate_calls
= true;
688 if (need_separate_calls
) {
692 r
= sd_bus_call_method(
694 "org.freedesktop.DBus",
695 "/org/freedesktop/DBus",
696 "org.freedesktop.DBus",
697 "GetConnectionUnixProcessID",
705 r
= sd_bus_message_read(reply
, "u", &u
);
709 if (!pidref_is_set(&pidref
))
710 pidref
= PIDREF_MAKE_FROM_PID(u
);
712 if (mask
& SD_BUS_CREDS_PID
) {
714 c
->mask
|= SD_BUS_CREDS_PID
;
717 reply
= sd_bus_message_unref(reply
);
723 r
= sd_bus_call_method(
725 "org.freedesktop.DBus",
726 "/org/freedesktop/DBus",
727 "org.freedesktop.DBus",
728 "GetConnectionUnixUser",
736 r
= sd_bus_message_read(reply
, "u", &u
);
741 c
->mask
|= SD_BUS_CREDS_EUID
;
743 reply
= sd_bus_message_unref(reply
);
747 const void *p
= NULL
;
750 r
= sd_bus_call_method(
752 "org.freedesktop.DBus",
753 "/org/freedesktop/DBus",
754 "org.freedesktop.DBus",
755 "GetConnectionSELinuxSecurityContext",
761 if (!sd_bus_error_has_name(&error
, SD_BUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN
))
764 /* no data is fine */
766 r
= sd_bus_message_read_array(reply
, 'y', &p
, &sz
);
770 c
->label
= memdup_suffix0(p
, sz
);
774 c
->mask
|= SD_BUS_CREDS_SELINUX_CONTEXT
;
779 if (pidref_is_set(&pidref
)) {
780 r
= bus_creds_add_more(c
, mask
, &pidref
, 0);
781 if (r
< 0 && r
!= -ESRCH
) /* Return the error, but ignore ESRCH which just means the process is already gone */
792 static int parse_sockaddr_string(const char *t
, char **ret_comm
, char **ret_description
) {
793 _cleanup_free_
char *comm
= NULL
, *description
= NULL
;
798 assert(ret_description
);
800 e
= strstrafter(t
, "/bus/");
802 log_debug("Didn't find /bus/ substring in peer socket address, ignoring.");
808 log_debug("Didn't find / substring after /bus/ in peer socket address, ignoring.");
813 comm
= strndup(e
, sl
- e
);
820 description
= strdup(sl
);
825 *ret_comm
= TAKE_PTR(comm
);
826 *ret_description
= TAKE_PTR(description
);
830 *ret_comm
= *ret_description
= NULL
;
834 _public_
int sd_bus_get_owner_creds(sd_bus
*bus
, uint64_t mask
, sd_bus_creds
**ret
) {
835 _cleanup_(sd_bus_creds_unrefp
) sd_bus_creds
*c
= NULL
;
836 _cleanup_(pidref_done
) PidRef pidref
= PIDREF_NULL
;
837 bool do_label
, do_groups
, do_sockaddr_peer
, do_pidfd
;
840 assert_return(bus
, -EINVAL
);
841 assert_return(bus
= bus_resolve(bus
), -ENOPKG
);
842 assert_return((mask
& ~SD_BUS_CREDS_AUGMENT
) <= _SD_BUS_CREDS_ALL
, -EOPNOTSUPP
);
843 assert_return(ret
, -EINVAL
);
844 assert_return(!bus_origin_changed(bus
), -ECHILD
);
846 if (!BUS_IS_OPEN(bus
->state
))
850 mask
&= ~SD_BUS_CREDS_AUGMENT
;
852 do_label
= bus
->label
&& (mask
& SD_BUS_CREDS_SELINUX_CONTEXT
);
853 do_groups
= bus
->n_groups
!= SIZE_MAX
&& (mask
& SD_BUS_CREDS_SUPPLEMENTARY_GIDS
);
854 do_sockaddr_peer
= bus
->sockaddr_size_peer
>= offsetof(struct sockaddr_un
, sun_path
) + 1 &&
855 bus
->sockaddr_peer
.sa
.sa_family
== AF_UNIX
&&
856 bus
->sockaddr_peer
.un
.sun_path
[0] == 0;
857 do_pidfd
= bus
->pidfd
>= 0 && (mask
& SD_BUS_CREDS_PIDFD
);
859 /* Avoid allocating anything if we have no chance of returning useful data */
860 if (!bus
->ucred_valid
&& !do_label
&& !do_groups
&& !do_sockaddr_peer
&& !do_pidfd
)
867 if (bus
->ucred_valid
) {
868 if (pid_is_valid(bus
->ucred
.pid
)) {
869 c
->pid
= bus
->ucred
.pid
;
870 c
->mask
|= SD_BUS_CREDS_PID
& mask
;
872 pidref
= PIDREF_MAKE_FROM_PID(c
->pid
);
875 if (uid_is_valid(bus
->ucred
.uid
)) {
876 c
->euid
= bus
->ucred
.uid
;
877 c
->mask
|= SD_BUS_CREDS_EUID
& mask
;
880 if (gid_is_valid(bus
->ucred
.gid
)) {
881 c
->egid
= bus
->ucred
.gid
;
882 c
->mask
|= SD_BUS_CREDS_EGID
& mask
;
887 c
->label
= strdup(bus
->label
);
891 c
->mask
|= SD_BUS_CREDS_SELINUX_CONTEXT
;
895 c
->supplementary_gids
= newdup(gid_t
, bus
->groups
, bus
->n_groups
);
896 if (!c
->supplementary_gids
)
899 c
->n_supplementary_gids
= bus
->n_groups
;
901 c
->mask
|= SD_BUS_CREDS_SUPPLEMENTARY_GIDS
;
904 if (do_sockaddr_peer
) {
905 _cleanup_free_
char *t
= NULL
;
907 assert(bus
->sockaddr_size_peer
>= offsetof(struct sockaddr_un
, sun_path
) + 1);
908 assert(bus
->sockaddr_peer
.sa
.sa_family
== AF_UNIX
);
909 assert(bus
->sockaddr_peer
.un
.sun_path
[0] == 0);
911 /* So this is an abstract namespace socket, good. Now let's find the data we are interested in */
912 r
= make_cstring(bus
->sockaddr_peer
.un
.sun_path
+ 1,
913 bus
->sockaddr_size_peer
- offsetof(struct sockaddr_un
, sun_path
) - 1,
914 MAKE_CSTRING_ALLOW_TRAILING_NUL
,
919 log_debug_errno(r
, "Can't extract string from peer socket address, ignoring: %m");
921 r
= parse_sockaddr_string(t
, &c
->comm
, &c
->description
);
926 c
->mask
|= SD_BUS_CREDS_COMM
& mask
;
929 c
->mask
|= SD_BUS_CREDS_DESCRIPTION
& mask
;
934 c
->pidfd
= fcntl(bus
->pidfd
, F_DUPFD_CLOEXEC
, 3);
938 pidref_done(&pidref
);
939 r
= pidref_set_pidfd(&pidref
, bus
->pidfd
);
943 c
->mask
|= SD_BUS_CREDS_PIDFD
;
946 r
= bus_creds_add_more(c
, mask
, &pidref
, 0);
947 if (r
< 0 && r
!= -ESRCH
) /* If the process vanished, then don't complain, just return what we got */
955 #define append_eavesdrop(bus, m) \
957 ? (isempty(m) ? "eavesdrop='true'" : strjoina((m), ",eavesdrop='true'")) \
960 int bus_add_match_internal(
963 uint64_t timeout_usec
,
964 uint64_t *ret_counter
) {
966 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
, *reply
= NULL
;
972 if (!bus
->bus_client
)
975 e
= append_eavesdrop(bus
, match
);
977 r
= sd_bus_message_new_method_call(
980 "org.freedesktop.DBus",
981 "/org/freedesktop/DBus",
982 "org.freedesktop.DBus",
987 r
= sd_bus_message_append(m
, "s", e
);
1000 /* If the caller asked for it, return the read counter of the reply */
1002 *ret_counter
= reply
->read_counter
;
1007 int bus_add_match_internal_async(
1009 sd_bus_slot
**ret_slot
,
1011 sd_bus_message_handler_t callback
,
1013 uint64_t timeout_usec
) {
1015 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
1021 if (!bus
->bus_client
)
1024 e
= append_eavesdrop(bus
, match
);
1026 r
= sd_bus_message_new_method_call(
1029 "org.freedesktop.DBus",
1030 "/org/freedesktop/DBus",
1031 "org.freedesktop.DBus",
1036 r
= sd_bus_message_append(m
, "s", e
);
1040 return sd_bus_call_async(
1049 int bus_remove_match_internal(
1051 const char *match
) {
1058 if (!bus
->bus_client
)
1061 e
= append_eavesdrop(bus
, match
);
1063 /* Fire and forget */
1065 return sd_bus_call_method_async(
1068 "org.freedesktop.DBus",
1069 "/org/freedesktop/DBus",
1070 "org.freedesktop.DBus",
1078 _public_
int sd_bus_get_name_machine_id(sd_bus
*bus
, const char *name
, sd_id128_t
*ret
) {
1079 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
1083 assert_return(bus
, -EINVAL
);
1084 assert_return(bus
= bus_resolve(bus
), -ENOPKG
);
1085 assert_return(name
, -EINVAL
);
1086 assert_return(ret
, -EINVAL
);
1087 assert_return(!bus_origin_changed(bus
), -ECHILD
);
1088 assert_return(service_name_is_valid(name
), -EINVAL
);
1090 if (!bus
->bus_client
)
1093 if (!BUS_IS_OPEN(bus
->state
))
1096 if (streq_ptr(name
, bus
->unique_name
))
1097 return sd_id128_get_machine(ret
);
1099 r
= sd_bus_message_new_method_call(
1104 "org.freedesktop.DBus.Peer",
1109 r
= sd_bus_message_set_auto_start(m
, false);
1113 r
= sd_bus_call(bus
, m
, 0, NULL
, &reply
);
1117 r
= sd_bus_message_read(reply
, "s", &mid
);
1121 return sd_id128_from_string(mid
, ret
);