1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2013 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #ifdef HAVE_VALGRIND_MEMCHECK_H
23 #include <valgrind/memcheck.h>
32 #include "bus-internal.h"
33 #include "bus-message.h"
34 #include "bus-control.h"
35 #include "bus-bloom.h"
38 _public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) {
41 assert_return(bus, -EINVAL);
42 assert_return(unique, -EINVAL);
43 assert_return(!bus_pid_changed(bus), -ECHILD);
45 r = bus_ensure_running(bus);
49 *unique = bus->unique_name;
53 _public_ int sd_bus_request_name(sd_bus *bus, const char *name, int flags) {
54 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
58 assert_return(bus, -EINVAL);
59 assert_return(name, -EINVAL);
60 assert_return(bus->bus_client, -EINVAL);
61 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
62 assert_return(!bus_pid_changed(bus), -ECHILD);
65 struct kdbus_cmd_name *n;
69 n = alloca0(offsetof(struct kdbus_cmd_name, name) + l + 1);
70 n->size = offsetof(struct kdbus_cmd_name, name) + l + 1;
71 kdbus_translate_request_name_flags(flags, (uint64_t *) &n->flags);
72 memcpy(n->name, name, l+1);
74 #ifdef HAVE_VALGRIND_MEMCHECK_H
75 VALGRIND_MAKE_MEM_DEFINED(n, n->size);
78 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_ACQUIRE, n);
80 if (errno == -EALREADY)
81 return SD_BUS_NAME_ALREADY_OWNER;
84 return SD_BUS_NAME_EXISTS;
89 if (n->flags & KDBUS_NAME_IN_QUEUE)
90 return SD_BUS_NAME_IN_QUEUE;
92 return SD_BUS_NAME_PRIMARY_OWNER;
94 r = sd_bus_call_method(
96 "org.freedesktop.DBus",
98 "org.freedesktop.DBus",
108 r = sd_bus_message_read(reply, "u", &ret);
116 _public_ int sd_bus_release_name(sd_bus *bus, const char *name) {
117 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
121 assert_return(bus, -EINVAL);
122 assert_return(name, -EINVAL);
123 assert_return(bus->bus_client, -EINVAL);
124 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
125 assert_return(!bus_pid_changed(bus), -ECHILD);
127 if (bus->is_kernel) {
128 struct kdbus_cmd_name *n;
132 n = alloca0(offsetof(struct kdbus_cmd_name, name) + l + 1);
133 n->size = offsetof(struct kdbus_cmd_name, name) + l + 1;
134 memcpy(n->name, name, l+1);
136 #ifdef HAVE_VALGRIND_MEMCHECK_H
137 VALGRIND_MAKE_MEM_DEFINED(n, n->size);
139 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_RELEASE, n);
145 r = sd_bus_call_method(
147 "org.freedesktop.DBus",
149 "org.freedesktop.DBus",
158 r = sd_bus_message_read(reply, "u", &ret);
166 _public_ int sd_bus_list_names(sd_bus *bus, char ***l) {
167 _cleanup_bus_message_unref_ sd_bus_message *reply1 = NULL, *reply2 = NULL;
171 assert_return(bus, -EINVAL);
172 assert_return(l, -EINVAL);
173 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
174 assert_return(!bus_pid_changed(bus), -ECHILD);
176 if (bus->is_kernel) {
177 _cleanup_free_ struct kdbus_cmd_name_list *cmd = NULL;
178 struct kdbus_name_list *name_list;
179 struct kdbus_cmd_name *name;
181 cmd = malloc0(sizeof(struct kdbus_cmd_name_list *));
185 cmd->flags = KDBUS_NAME_LIST_UNIQUE_NAMES;
187 r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_NAME_LIST, cmd);
191 name_list = (struct kdbus_name_list *) ((uint8_t *) bus->kdbus_buffer + cmd->offset);
193 KDBUS_PART_FOREACH(name, name_list, names) {
196 if (name->size > sizeof(*name))
199 asprintf(&n, ":1.%llu", (unsigned long long) name->id);
201 r = strv_extend(&x, n);
206 r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_FREE, &cmd->offset);
212 r = sd_bus_call_method(
214 "org.freedesktop.DBus",
216 "org.freedesktop.DBus",
224 r = sd_bus_call_method(
226 "org.freedesktop.DBus",
228 "org.freedesktop.DBus",
229 "ListActivatableNames",
236 r = bus_message_read_strv_extend(reply1, &x);
242 r = bus_message_read_strv_extend(reply2, &x);
254 static int bus_get_owner_dbus(
258 sd_bus_creds **creds) {
260 _cleanup_bus_message_unref_ sd_bus_message *reply_unique = NULL, *reply = NULL;
261 _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
262 const char *unique = NULL;
266 /* Only query the owner if the caller wants to know it or if
267 * the caller just wants to check whether a name exists */
268 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) || mask == 0) {
269 r = sd_bus_call_method(
271 "org.freedesktop.DBus",
273 "org.freedesktop.DBus",
282 r = sd_bus_message_read(reply_unique, "s", &unique);
292 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) && unique) {
293 c->unique_name = strdup(unique);
297 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
300 if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_GID|
301 SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
302 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|
303 SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
304 SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)) {
307 r = sd_bus_call_method(
309 "org.freedesktop.DBus",
311 "org.freedesktop.DBus",
312 "GetConnectionUnixProcessID",
316 unique ? unique : name);
320 r = sd_bus_message_read(reply, "u", &u);
325 if (mask & SD_BUS_CREDS_PID) {
327 c->mask |= SD_BUS_CREDS_PID;
330 reply = sd_bus_message_unref(reply);
333 if (mask & SD_BUS_CREDS_UID) {
336 r = sd_bus_call_method(
338 "org.freedesktop.DBus",
340 "org.freedesktop.DBus",
341 "GetConnectionUnixUser",
345 unique ? unique : name);
349 r = sd_bus_message_read(reply, "u", &u);
354 c->mask |= SD_BUS_CREDS_UID;
356 reply = sd_bus_message_unref(reply);
359 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
363 r = sd_bus_call_method(
365 "org.freedesktop.DBus",
367 "org.freedesktop.DBus",
368 "GetConnectionSELinuxSecurityContext",
372 unique ? unique : name);
376 r = sd_bus_message_read_array(reply, 'y', &p, &sz);
380 c->label = strndup(p, sz);
384 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
387 r = bus_creds_add_more(c, mask, pid, 0);
400 static int bus_get_owner_kdbus(
404 sd_bus_creds **creds) {
406 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
407 _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
408 struct kdbus_cmd_name_info *cmd;
409 struct kdbus_name_info *name_info;
410 struct kdbus_item *item;
415 r = bus_kernel_parse_unique_name(name, &id);
419 size = offsetof(struct kdbus_cmd_name_info, name);
423 size = offsetof(struct kdbus_cmd_name_info, name) + strlen(name) + 1;
425 strcpy(cmd->name, name);
429 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_INFO, cmd);
433 name_info = (struct kdbus_name_info *) ((uint8_t *) bus->kdbus_buffer + cmd->offset);
439 if (mask & SD_BUS_CREDS_UNIQUE_NAME) {
440 if (asprintf(&c->unique_name, ":1.%llu", (unsigned long long) name_info->id) < 0)
443 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
446 KDBUS_PART_FOREACH(item, name_info, items) {
448 switch (item->type) {
450 case KDBUS_ITEM_CREDS:
451 m = (SD_BUS_CREDS_UID | SD_BUS_CREDS_GID | SD_BUS_CREDS_PID |
452 SD_BUS_CREDS_TID | SD_BUS_CREDS_PID_STARTTIME) & mask;
455 c->uid = item->creds.uid;
456 c->pid = item->creds.pid;
457 c->gid = item->creds.gid;
458 c->tid = item->creds.tid;
459 c->pid_starttime = item->creds.starttime;
464 case KDBUS_ITEM_PID_COMM:
465 if (mask & SD_BUS_CREDS_COMM) {
466 c->comm = strdup(item->str);
472 c->mask |= SD_BUS_CREDS_COMM;
476 case KDBUS_ITEM_TID_COMM:
477 if (mask & SD_BUS_CREDS_TID_COMM) {
478 c->tid_comm = strdup(item->str);
484 c->mask |= SD_BUS_CREDS_TID_COMM;
489 if (mask & SD_BUS_CREDS_EXE) {
490 c->exe = strdup(item->str);
496 c->mask |= SD_BUS_CREDS_EXE;
500 case KDBUS_ITEM_CMDLINE:
501 if (mask & SD_BUS_CREDS_CMDLINE) {
502 c->cmdline_size = item->size - KDBUS_PART_HEADER_SIZE;
503 c->cmdline = memdup(item->data, c->cmdline_size);
509 c->mask |= SD_BUS_CREDS_CMDLINE;
513 case KDBUS_ITEM_CGROUP:
514 m = (SD_BUS_CREDS_CGROUP | SD_BUS_CREDS_UNIT |
515 SD_BUS_CREDS_USER_UNIT | SD_BUS_CREDS_SLICE |
516 SD_BUS_CREDS_SESSION | SD_BUS_CREDS_OWNER_UID) & mask;
519 c->cgroup = strdup(item->str);
529 case KDBUS_ITEM_CAPS:
530 m = (SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_PERMITTED_CAPS |
531 SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_BOUNDING_CAPS) & mask;
534 c->capability_size = item->size - KDBUS_PART_HEADER_SIZE;
535 c->capability = memdup(item->data, c->capability_size);
536 if (!c->capability) {
545 case KDBUS_ITEM_SECLABEL:
546 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
547 c->label = strdup(item->str);
553 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
557 case KDBUS_ITEM_AUDIT:
558 m = (SD_BUS_CREDS_AUDIT_SESSION_ID | SD_BUS_CREDS_AUDIT_LOGIN_UID) & mask;
561 c->audit_session_id = item->audit.sessionid;
562 c->audit_login_uid = item->audit.loginuid;
567 case KDBUS_ITEM_NAMES:
568 if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
569 c->well_known_names_size = item->size - KDBUS_PART_HEADER_SIZE;
570 c->well_known_names = memdup(item->data, c->well_known_names_size);
571 if (!c->well_known_names) {
576 c->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
590 ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd->offset);
594 _public_ int sd_bus_get_owner(
598 sd_bus_creds **creds) {
600 assert_return(bus, -EINVAL);
601 assert_return(name, -EINVAL);
602 assert_return(mask <= _SD_BUS_CREDS_MAX, -ENOTSUP);
603 assert_return(mask == 0 || creds, -EINVAL);
604 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
605 assert_return(!bus_pid_changed(bus), -ECHILD);
608 return bus_get_owner_kdbus(bus, name, mask, creds);
610 return bus_get_owner_dbus(bus, name, mask, creds);
613 static int add_name_change_match(sd_bus *bus,
616 const char *old_owner,
617 const char *new_owner) {
619 uint64_t name_id = 0, old_owner_id = 0, new_owner_id = 0;
620 int is_name_id = -1, r;
621 struct kdbus_item *item;
625 /* If we encounter a match that could match against
626 * NameOwnerChanged messages, then we need to create
627 * KDBUS_MATCH_NAME_{ADD,REMOVE,CHANGE} and
628 * KDBUS_MATCH_ID_{ADD,REMOVE} matches for it, possibly
629 * multiple if the match is underspecified.
631 * The NameOwnerChanged signals take three parameters with
632 * unique or well-known names, but only some forms actually
635 * WELLKNOWN, "", UNIQUE → KDBUS_MATCH_NAME_ADD
636 * WELLKNOWN, UNIQUE, "" → KDBUS_MATCH_NAME_REMOVE
637 * WELLKNOWN, UNIQUE, UNIQUE → KDBUS_MATCH_NAME_CHANGE
638 * UNIQUE, "", UNIQUE → KDBUS_MATCH_ID_ADD
639 * UNIQUE, UNIQUE, "" → KDBUS_MATCH_ID_REMOVE
641 * For the latter two the two unique names must be identical.
646 is_name_id = bus_kernel_parse_unique_name(name, &name_id);
652 r = bus_kernel_parse_unique_name(old_owner, &old_owner_id);
657 if (is_name_id > 0 && old_owner_id != name_id)
662 r = bus_kernel_parse_unique_name(new_owner, &new_owner_id);
667 if (is_name_id > 0 && new_owner_id != name_id)
671 if (is_name_id <= 0) {
674 /* If the name argument is missing or is a well-known
675 * name, then add KDBUS_MATCH_NAME_{ADD,REMOVE,CHANGE}
678 l = name ? strlen(name) : 0;
680 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
681 offsetof(struct kdbus_item, name_change) +
682 offsetof(struct kdbus_notify_name_change, name) +
688 struct kdbus_cmd_match match;
694 m.match.cookie = cookie;
695 m.match.src_id = KDBUS_SRC_ID_KERNEL;
697 item = m.match.items;
699 offsetof(struct kdbus_item, name_change) +
700 offsetof(struct kdbus_notify_name_change, name) +
703 item->name_change.old_id = old_owner_id;
704 item->name_change.new_id = new_owner_id;
707 strcpy(item->name_change.name, name);
709 /* If the old name is unset or empty, then
710 * this can match against added names */
711 if (!old_owner || old_owner[0] == 0) {
712 item->type = KDBUS_MATCH_NAME_ADD;
714 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
719 /* If the new name is unset or empty, then
720 * this can match against removed names */
721 if (!new_owner || new_owner[0] == 0) {
722 item->type = KDBUS_MATCH_NAME_REMOVE;
724 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
729 /* If the neither name is explicitly set to
730 * the empty string, then this can match
731 * agains changed names */
732 if (!(old_owner && old_owner[0] == 0) &&
733 !(new_owner && new_owner[0] == 0)) {
734 item->type = KDBUS_MATCH_NAME_CHANGE;
736 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
743 if (is_name_id != 0) {
745 ALIGN8(offsetof(struct kdbus_cmd_match, items) +
746 offsetof(struct kdbus_item, id_change) +
747 sizeof(struct kdbus_notify_id_change));
750 struct kdbus_cmd_match match;
753 /* If the name argument is missing or is a unique
754 * name, then add KDBUS_MATCH_ID_{ADD,REMOVE} matches
760 m.match.cookie = cookie;
761 m.match.src_id = KDBUS_SRC_ID_KERNEL;
763 item = m.match.items;
764 item->size = offsetof(struct kdbus_item, id_change) + sizeof(struct kdbus_notify_id_change);
765 item->id_change.id = name_id;
767 /* If the old name is unset or empty, then this can
768 * match against added ids */
769 if (!old_owner || old_owner[0] == 0) {
770 item->type = KDBUS_MATCH_ID_ADD;
772 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
777 /* If thew new name is unset or empty, then this can
778 match against removed ids */
779 if (!new_owner || new_owner[0] == 0) {
780 item->type = KDBUS_MATCH_ID_REMOVE;
782 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
791 int bus_add_match_internal(
794 struct bus_match_component *components,
795 unsigned n_components,
803 if (bus->is_kernel) {
804 struct kdbus_cmd_match *m;
805 struct kdbus_item *item;
806 uint64_t bloom[BLOOM_SIZE/8];
808 const char *sender = NULL;
809 size_t sender_length = 0;
810 uint64_t src_id = KDBUS_MATCH_SRC_ID_ANY;
811 bool using_bloom = false;
813 bool matches_name_change = true;
814 const char *name_change_arg[3] = {};
818 sz = offsetof(struct kdbus_cmd_match, items);
820 for (i = 0; i < n_components; i++) {
821 struct bus_match_component *c = &components[i];
825 case BUS_MATCH_SENDER:
826 if (!streq(c->value_str, "org.freedesktop.DBus"))
827 matches_name_change = false;
829 r = bus_kernel_parse_unique_name(c->value_str, &src_id);
834 sender = c->value_str;
835 sender_length = strlen(sender);
836 sz += ALIGN8(offsetof(struct kdbus_item, str) + sender_length + 1);
841 case BUS_MATCH_MESSAGE_TYPE:
842 if (c->value_u8 != SD_BUS_MESSAGE_SIGNAL)
843 matches_name_change = false;
845 bloom_add_pair(bloom, "message-type", bus_message_type_to_string(c->value_u8));
849 case BUS_MATCH_INTERFACE:
850 if (!streq(c->value_str, "org.freedesktop.DBus"))
851 matches_name_change = false;
853 bloom_add_pair(bloom, "interface", c->value_str);
857 case BUS_MATCH_MEMBER:
858 if (!streq(c->value_str, "NameOwnerChanged"))
859 matches_name_change = false;
861 bloom_add_pair(bloom, "member", c->value_str);
866 if (!streq(c->value_str, "/org/freedesktop/DBus"))
867 matches_name_change = false;
869 bloom_add_pair(bloom, "path", c->value_str);
873 case BUS_MATCH_PATH_NAMESPACE:
874 if (!streq(c->value_str, "/")) {
875 bloom_add_pair(bloom, "path-slash-prefix", c->value_str);
880 case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: {
881 char buf[sizeof("arg")-1 + 2 + 1];
883 if (c->type - BUS_MATCH_ARG < 3)
884 name_change_arg[c->type - BUS_MATCH_ARG] = c->value_str;
886 snprintf(buf, sizeof(buf), "arg%u", c->type - BUS_MATCH_ARG);
887 bloom_add_pair(bloom, buf, c->value_str);
892 case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: {
893 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
895 snprintf(buf, sizeof(buf), "arg%u-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
896 bloom_add_pair(bloom, buf, c->value_str);
901 case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: {
902 char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")];
904 snprintf(buf, sizeof(buf), "arg%u-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE);
905 bloom_add_pair(bloom, buf, c->value_str);
910 case BUS_MATCH_DESTINATION:
911 /* The bloom filter does not include
912 the destination, since it is only
913 available for broadcast messages
914 which do not carry a destination
915 since they are undirected. */
919 case BUS_MATCH_VALUE:
921 case _BUS_MATCH_NODE_TYPE_MAX:
922 case _BUS_MATCH_NODE_TYPE_INVALID:
923 assert_not_reached("Invalid match type?");
928 sz += ALIGN8(offsetof(struct kdbus_item, data64) + BLOOM_SIZE);
938 item->size = offsetof(struct kdbus_item, data64) + BLOOM_SIZE;
939 item->type = KDBUS_MATCH_BLOOM;
940 memcpy(item->data64, bloom, BLOOM_SIZE);
942 item = KDBUS_PART_NEXT(item);
946 item->size = offsetof(struct kdbus_item, str) + sender_length + 1;
947 item->type = KDBUS_MATCH_SRC_NAME;
948 memcpy(item->str, sender, sender_length + 1);
951 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
955 if (matches_name_change) {
957 /* If this match could theoretically match
958 * NameOwnerChanged messages, we need to
959 * install a second non-bloom filter explitly
962 r = add_name_change_match(bus, cookie, name_change_arg[0], name_change_arg[1], name_change_arg[2]);
969 return sd_bus_call_method(
971 "org.freedesktop.DBus",
973 "org.freedesktop.DBus",
981 int bus_remove_match_internal(
991 if (bus->is_kernel) {
992 struct kdbus_cmd_match m;
995 m.size = offsetof(struct kdbus_cmd_match, items);
998 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_REMOVE, &m);
1005 return sd_bus_call_method(
1007 "org.freedesktop.DBus",
1009 "org.freedesktop.DBus",
1018 _public_ int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) {
1019 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
1023 assert_return(bus, -EINVAL);
1024 assert_return(name, -EINVAL);
1025 assert_return(machine, -EINVAL);
1026 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1027 assert_return(!bus_pid_changed(bus), -ECHILD);
1029 if (streq_ptr(name, bus->unique_name))
1030 return sd_id128_get_machine(machine);
1032 r = sd_bus_message_new_method_call(
1036 "org.freedesktop.DBus.Peer",
1037 "GetMachineId", &m);
1041 r = sd_bus_message_set_no_auto_start(m, true);
1045 r = sd_bus_call(bus, m, 0, NULL, &reply);
1049 r = sd_bus_message_read(reply, "s", &mid);
1053 return sd_id128_from_string(mid, machine);