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>
31 #include "bus-internal.h"
32 #include "bus-message.h"
33 #include "bus-control.h"
34 #include "bus-bloom.h"
37 _public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) {
40 assert_return(bus, -EINVAL);
41 assert_return(unique, -EINVAL);
42 assert_return(!bus_pid_changed(bus), -ECHILD);
44 r = bus_ensure_running(bus);
48 *unique = bus->unique_name;
52 static int bus_request_name_kernel(sd_bus *bus, const char *name, uint64_t flags) {
53 struct kdbus_cmd_name *n;
61 n = alloca0(offsetof(struct kdbus_cmd_name, name) + l + 1);
62 n->size = offsetof(struct kdbus_cmd_name, name) + l + 1;
63 kdbus_translate_request_name_flags(flags, (uint64_t *) &n->flags);
64 memcpy(n->name, name, l+1);
66 #ifdef HAVE_VALGRIND_MEMCHECK_H
67 VALGRIND_MAKE_MEM_DEFINED(n, n->size);
70 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_ACQUIRE, n);
74 if (n->flags & KDBUS_NAME_IN_QUEUE)
80 static int bus_request_name_dbus1(sd_bus *bus, const char *name, uint64_t flags) {
81 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
82 uint32_t ret, param = 0;
88 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
89 param |= BUS_NAME_ALLOW_REPLACEMENT;
90 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
91 param |= BUS_NAME_REPLACE_EXISTING;
92 if (!(flags & SD_BUS_NAME_QUEUE))
93 param |= BUS_NAME_DO_NOT_QUEUE;
95 r = sd_bus_call_method(
97 "org.freedesktop.DBus",
99 "org.freedesktop.DBus",
109 r = sd_bus_message_read(reply, "u", &ret);
113 if (ret == BUS_NAME_ALREADY_OWNER)
115 else if (ret == BUS_NAME_EXISTS)
117 else if (ret == BUS_NAME_IN_QUEUE)
119 else if (ret == BUS_NAME_PRIMARY_OWNER)
125 _public_ int sd_bus_request_name(sd_bus *bus, const char *name, uint64_t flags) {
126 assert_return(bus, -EINVAL);
127 assert_return(name, -EINVAL);
128 assert_return(bus->bus_client, -EINVAL);
129 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
130 assert_return(!bus_pid_changed(bus), -ECHILD);
131 assert_return(!(flags & ~(SD_BUS_NAME_ALLOW_REPLACEMENT|SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_QUEUE)), -EINVAL);
134 return bus_request_name_kernel(bus, name, flags);
136 return bus_request_name_dbus1(bus, name, flags);
139 static int bus_release_name_kernel(sd_bus *bus, const char *name) {
140 struct kdbus_cmd_name *n;
148 n = alloca0(offsetof(struct kdbus_cmd_name, name) + l + 1);
149 n->size = offsetof(struct kdbus_cmd_name, name) + l + 1;
150 memcpy(n->name, name, l+1);
152 #ifdef HAVE_VALGRIND_MEMCHECK_H
153 VALGRIND_MAKE_MEM_DEFINED(n, n->size);
155 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_RELEASE, n);
162 static int bus_release_name_dbus1(sd_bus *bus, const char *name) {
163 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
170 r = sd_bus_call_method(
172 "org.freedesktop.DBus",
174 "org.freedesktop.DBus",
183 r = sd_bus_message_read(reply, "u", &ret);
186 if (ret == BUS_NAME_NON_EXISTENT)
188 if (ret == BUS_NAME_NOT_OWNER)
190 if (ret == BUS_NAME_RELEASED)
196 _public_ int sd_bus_release_name(sd_bus *bus, const char *name) {
197 assert_return(bus, -EINVAL);
198 assert_return(name, -EINVAL);
199 assert_return(bus->bus_client, -EINVAL);
200 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
201 assert_return(!bus_pid_changed(bus), -ECHILD);
204 return bus_release_name_kernel(bus, name);
206 return bus_release_name_dbus1(bus, name);
209 static int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) {
210 struct kdbus_cmd_name_list cmd = {};
211 struct kdbus_name_list *name_list;
212 struct kdbus_cmd_name *name;
213 uint64_t previous_id = 0;
216 /* Caller will free half-constructed list on failure... */
220 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_LIST, &cmd);
224 name_list = (struct kdbus_name_list *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
226 KDBUS_ITEM_FOREACH(name, name_list, names) {
228 if ((flags & KDBUS_NAME_LIST_UNIQUE) && name->id != previous_id) {
231 if (asprintf(&n, ":1.%llu", (unsigned long long) name->id) < 0)
240 previous_id = name->id;
243 if (name->size > sizeof(*name)) {
244 r = strv_extend(x, name->name);
250 r = ioctl(sd_bus_get_fd(bus), KDBUS_CMD_FREE, &cmd.offset);
257 static int bus_list_names_kernel(sd_bus *bus, char ***acquired, char ***activatable) {
258 _cleanup_strv_free_ char **x = NULL, **y = NULL;
262 r = kernel_get_list(bus, KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES, &x);
268 r = kernel_get_list(bus, KDBUS_NAME_LIST_ACTIVATORS, &y);
284 static int bus_list_names_dbus1(sd_bus *bus, char ***acquired, char ***activatable) {
285 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
286 _cleanup_strv_free_ char **x = NULL, **y = NULL;
290 r = sd_bus_call_method(
292 "org.freedesktop.DBus",
294 "org.freedesktop.DBus",
302 r = sd_bus_message_read_strv(reply, &x);
306 reply = sd_bus_message_unref(reply);
310 r = sd_bus_call_method(
312 "org.freedesktop.DBus",
314 "org.freedesktop.DBus",
315 "ListActivatableNames",
322 r = sd_bus_message_read_strv(reply, &y);
338 _public_ int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable) {
339 assert_return(bus, -EINVAL);
340 assert_return(acquired || activatable, -EINVAL);
341 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
342 assert_return(!bus_pid_changed(bus), -ECHILD);
345 return bus_list_names_kernel(bus, acquired, activatable);
347 return bus_list_names_dbus1(bus, acquired, activatable);
350 static int bus_get_owner_kdbus(
354 sd_bus_creds **creds) {
356 _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
357 struct kdbus_cmd_conn_info *cmd;
358 struct kdbus_conn_info *conn_info;
359 struct kdbus_item *item;
364 r = bus_kernel_parse_unique_name(name, &id);
368 size = offsetof(struct kdbus_cmd_conn_info, name);
372 size = offsetof(struct kdbus_cmd_conn_info, name) + strlen(name) + 1;
374 strcpy(cmd->name, name);
376 cmd->flags = KDBUS_ATTACH_NAMES;
379 r = ioctl(bus->input_fd, KDBUS_CMD_CONN_INFO, cmd);
383 conn_info = (struct kdbus_conn_info *) ((uint8_t *) bus->kdbus_buffer + cmd->offset);
389 if (mask & SD_BUS_CREDS_UNIQUE_NAME) {
390 if (asprintf(&c->unique_name, ":1.%llu", (unsigned long long) conn_info->id) < 0)
393 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
396 KDBUS_ITEM_FOREACH(item, conn_info, items) {
398 switch (item->type) {
400 case KDBUS_ITEM_CREDS:
401 m = (SD_BUS_CREDS_UID | SD_BUS_CREDS_GID | SD_BUS_CREDS_PID |
402 SD_BUS_CREDS_TID | SD_BUS_CREDS_PID_STARTTIME) & mask;
405 c->uid = item->creds.uid;
406 c->pid = item->creds.pid;
407 c->gid = item->creds.gid;
408 c->tid = item->creds.tid;
409 c->pid_starttime = item->creds.starttime;
414 case KDBUS_ITEM_PID_COMM:
415 if (mask & SD_BUS_CREDS_COMM) {
416 c->comm = strdup(item->str);
422 c->mask |= SD_BUS_CREDS_COMM;
426 case KDBUS_ITEM_TID_COMM:
427 if (mask & SD_BUS_CREDS_TID_COMM) {
428 c->tid_comm = strdup(item->str);
434 c->mask |= SD_BUS_CREDS_TID_COMM;
439 if (mask & SD_BUS_CREDS_EXE) {
440 c->exe = strdup(item->str);
446 c->mask |= SD_BUS_CREDS_EXE;
450 case KDBUS_ITEM_CMDLINE:
451 if (mask & SD_BUS_CREDS_CMDLINE) {
452 c->cmdline_size = item->size - KDBUS_ITEM_HEADER_SIZE;
453 c->cmdline = memdup(item->data, c->cmdline_size);
459 c->mask |= SD_BUS_CREDS_CMDLINE;
463 case KDBUS_ITEM_CGROUP:
464 m = (SD_BUS_CREDS_CGROUP | SD_BUS_CREDS_UNIT |
465 SD_BUS_CREDS_USER_UNIT | SD_BUS_CREDS_SLICE |
466 SD_BUS_CREDS_SESSION | SD_BUS_CREDS_OWNER_UID) & mask;
469 c->cgroup = strdup(item->str);
479 case KDBUS_ITEM_CAPS:
480 m = (SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_PERMITTED_CAPS |
481 SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_BOUNDING_CAPS) & mask;
484 c->capability_size = item->size - KDBUS_ITEM_HEADER_SIZE;
485 c->capability = memdup(item->data, c->capability_size);
486 if (!c->capability) {
495 case KDBUS_ITEM_SECLABEL:
496 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
497 c->label = strdup(item->str);
503 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
507 case KDBUS_ITEM_AUDIT:
508 m = (SD_BUS_CREDS_AUDIT_SESSION_ID | SD_BUS_CREDS_AUDIT_LOGIN_UID) & mask;
511 c->audit_session_id = item->audit.sessionid;
512 c->audit_login_uid = item->audit.loginuid;
517 case KDBUS_ITEM_NAME:
518 if (mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) {
519 r = strv_extend(&c->well_known_names, item->name.name);
523 c->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
537 ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd->offset);
541 static int bus_get_owner_dbus1(
545 sd_bus_creds **creds) {
547 _cleanup_bus_message_unref_ sd_bus_message *reply_unique = NULL, *reply = NULL;
548 _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
549 const char *unique = NULL;
553 /* Only query the owner if the caller wants to know it or if
554 * the caller just wants to check whether a name exists */
555 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) || mask == 0) {
556 r = sd_bus_call_method(
558 "org.freedesktop.DBus",
560 "org.freedesktop.DBus",
569 r = sd_bus_message_read(reply_unique, "s", &unique);
579 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) && unique) {
580 c->unique_name = strdup(unique);
584 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
587 if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_GID|
588 SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
589 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|
590 SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
591 SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)) {
594 r = sd_bus_call_method(
596 "org.freedesktop.DBus",
598 "org.freedesktop.DBus",
599 "GetConnectionUnixProcessID",
603 unique ? unique : name);
607 r = sd_bus_message_read(reply, "u", &u);
612 if (mask & SD_BUS_CREDS_PID) {
614 c->mask |= SD_BUS_CREDS_PID;
617 reply = sd_bus_message_unref(reply);
620 if (mask & SD_BUS_CREDS_UID) {
623 r = sd_bus_call_method(
625 "org.freedesktop.DBus",
627 "org.freedesktop.DBus",
628 "GetConnectionUnixUser",
632 unique ? unique : name);
636 r = sd_bus_message_read(reply, "u", &u);
641 c->mask |= SD_BUS_CREDS_UID;
643 reply = sd_bus_message_unref(reply);
646 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
650 r = sd_bus_call_method(
652 "org.freedesktop.DBus",
654 "org.freedesktop.DBus",
655 "GetConnectionSELinuxSecurityContext",
659 unique ? unique : name);
663 r = sd_bus_message_read_array(reply, 'y', &p, &sz);
667 c->label = strndup(p, sz);
671 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
674 r = bus_creds_add_more(c, mask, pid, 0);
687 _public_ int sd_bus_get_owner(
691 sd_bus_creds **creds) {
693 assert_return(bus, -EINVAL);
694 assert_return(name, -EINVAL);
695 assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
696 assert_return(mask == 0 || creds, -EINVAL);
697 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
698 assert_return(!bus_pid_changed(bus), -ECHILD);
701 return bus_get_owner_kdbus(bus, name, mask, creds);
703 return bus_get_owner_dbus1(bus, name, mask, creds);
706 static int add_name_change_match(sd_bus *bus,
709 const char *old_owner,
710 const char *new_owner) {
712 uint64_t name_id = 0, old_owner_id = 0, new_owner_id = 0;
713 int is_name_id = -1, r;
714 struct kdbus_item *item;
718 /* If we encounter a match that could match against
719 * NameOwnerChanged messages, then we need to create
720 * KDBUS_MATCH_NAME_{ADD,REMOVE,CHANGE} and
721 * KDBUS_MATCH_ID_{ADD,REMOVE} matches for it, possibly
722 * multiple if the match is underspecified.
724 * The NameOwnerChanged signals take three parameters with
725 * unique or well-known names, but only some forms actually
728 * WELLKNOWN, "", UNIQUE → KDBUS_MATCH_NAME_ADD
729 * WELLKNOWN, UNIQUE, "" → KDBUS_MATCH_NAME_REMOVE
730 * WELLKNOWN, UNIQUE, UNIQUE → KDBUS_MATCH_NAME_CHANGE
731 * UNIQUE, "", UNIQUE → KDBUS_MATCH_ID_ADD
732 * UNIQUE, UNIQUE, "" → KDBUS_MATCH_ID_REMOVE
734 * For the latter two the two unique names must be identical.
739 is_name_id = bus_kernel_parse_unique_name(name, &name_id);
744 if (!isempty(old_owner)) {
745 r = bus_kernel_parse_unique_name(old_owner, &old_owner_id);
750 if (is_name_id > 0 && old_owner_id != name_id)
754 if (!isempty(new_owner)) {
755 r = bus_kernel_parse_unique_name(new_owner, &new_owner_id);
760 if (is_name_id > 0 && new_owner_id != name_id)
764 if (is_name_id <= 0) {
765 struct kdbus_cmd_match *m;
768 /* If the name argument is missing or is a well-known
769 * name, then add KDBUS_MATCH_NAME_{ADD,REMOVE,CHANGE}
772 l = name ? strlen(name) : 0;
774 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
775 offsetof(struct kdbus_item, name_change) +
776 offsetof(struct kdbus_notify_name_change, name) +
782 m->src_id = KDBUS_SRC_ID_KERNEL;
786 offsetof(struct kdbus_item, name_change) +
787 offsetof(struct kdbus_notify_name_change, name) +
790 item->name_change.old_id = old_owner_id;
791 item->name_change.new_id = new_owner_id;
794 strcpy(item->name_change.name, name);
796 /* If the old name is unset or empty, then
797 * this can match against added names */
798 if (!old_owner || old_owner[0] == 0) {
799 item->type = KDBUS_MATCH_NAME_ADD;
801 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
806 /* If the new name is unset or empty, then
807 * this can match against removed names */
808 if (!new_owner || new_owner[0] == 0) {
809 item->type = KDBUS_MATCH_NAME_REMOVE;
811 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
816 /* If the neither name is explicitly set to
817 * the empty string, then this can match
818 * agains changed names */
819 if (!(old_owner && old_owner[0] == 0) &&
820 !(new_owner && new_owner[0] == 0)) {
821 item->type = KDBUS_MATCH_NAME_CHANGE;
823 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
829 if (is_name_id != 0) {
830 struct kdbus_cmd_match *m;
833 /* If the name argument is missing or is a unique
834 * name, then add KDBUS_MATCH_ID_{ADD,REMOVE} matches
837 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
838 offsetof(struct kdbus_item, id_change) +
839 sizeof(struct kdbus_notify_id_change));
844 m->src_id = KDBUS_SRC_ID_KERNEL;
847 item->size = offsetof(struct kdbus_item, id_change) + sizeof(struct kdbus_notify_id_change);
848 item->id_change.id = name_id;
850 /* If the old name is unset or empty, then this can
851 * match against added ids */
852 if (!old_owner || old_owner[0] == 0) {
853 item->type = KDBUS_MATCH_ID_ADD;
855 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
860 /* If thew new name is unset or empty, then this can
861 match against removed ids */
862 if (!new_owner || new_owner[0] == 0) {
863 item->type = KDBUS_MATCH_ID_REMOVE;
865 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
874 static int bus_add_match_internal_kernel(
877 struct bus_match_component *components,
878 unsigned n_components,
881 struct kdbus_cmd_match *m;
882 struct kdbus_item *item;
883 uint64_t bloom[BLOOM_SIZE/8];
885 const char *sender = NULL;
886 size_t sender_length = 0;
887 uint64_t src_id = KDBUS_MATCH_SRC_ID_ANY;
888 bool using_bloom = false;
890 bool matches_name_change = true;
891 const char *name_change_arg[3] = {};
899 sz = offsetof(struct kdbus_cmd_match, items);
901 for (i = 0; i < n_components; i++) {
902 struct bus_match_component *c = &components[i];
906 case BUS_MATCH_SENDER:
907 if (!streq(c->value_str, "org.freedesktop.DBus"))
908 matches_name_change = false;
910 r = bus_kernel_parse_unique_name(c->value_str, &src_id);
915 sender = c->value_str;
916 sender_length = strlen(sender);
917 sz += ALIGN8(offsetof(struct kdbus_item, str) + sender_length + 1);
922 case BUS_MATCH_MESSAGE_TYPE:
923 if (c->value_u8 != SD_BUS_MESSAGE_SIGNAL)
924 matches_name_change = false;
926 bloom_add_pair(bloom, "message-type", bus_message_type_to_string(c->value_u8));
930 case BUS_MATCH_INTERFACE:
931 if (!streq(c->value_str, "org.freedesktop.DBus"))
932 matches_name_change = false;
934 bloom_add_pair(bloom, "interface", c->value_str);
938 case BUS_MATCH_MEMBER:
939 if (!streq(c->value_str, "NameOwnerChanged"))
940 matches_name_change = false;
942 bloom_add_pair(bloom, "member", c->value_str);
947 if (!streq(c->value_str, "/org/freedesktop/DBus"))
948 matches_name_change = false;
950 bloom_add_pair(bloom, "path", c->value_str);
954 case BUS_MATCH_PATH_NAMESPACE:
955 if (!streq(c->value_str, "/")) {
956 bloom_add_pair(bloom, "path-slash-prefix", c->value_str);
961 case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: {
962 char buf[sizeof("arg")-1 + 2 + 1];
964 if (c->type - BUS_MATCH_ARG < 3)
965 name_change_arg[c->type - BUS_MATCH_ARG] = c->value_str;
967 snprintf(buf, sizeof(buf), "arg%u", c->type - BUS_MATCH_ARG);
968 bloom_add_pair(bloom, buf, c->value_str);
973 case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: {
974 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
976 snprintf(buf, sizeof(buf), "arg%u-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
977 bloom_add_pair(bloom, buf, c->value_str);
982 case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: {
983 char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")];
985 snprintf(buf, sizeof(buf), "arg%u-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE);
986 bloom_add_pair(bloom, buf, c->value_str);
991 case BUS_MATCH_DESTINATION:
992 /* The bloom filter does not include
993 the destination, since it is only
994 available for broadcast messages
995 which do not carry a destination
996 since they are undirected. */
1000 case BUS_MATCH_VALUE:
1001 case BUS_MATCH_LEAF:
1002 case _BUS_MATCH_NODE_TYPE_MAX:
1003 case _BUS_MATCH_NODE_TYPE_INVALID:
1004 assert_not_reached("Invalid match type?");
1009 sz += ALIGN8(offsetof(struct kdbus_item, data64) + BLOOM_SIZE);
1019 item->size = offsetof(struct kdbus_item, data64) + BLOOM_SIZE;
1020 item->type = KDBUS_MATCH_BLOOM;
1021 memcpy(item->data64, bloom, BLOOM_SIZE);
1023 item = KDBUS_ITEM_NEXT(item);
1027 item->size = offsetof(struct kdbus_item, str) + sender_length + 1;
1028 item->type = KDBUS_MATCH_SRC_NAME;
1029 memcpy(item->str, sender, sender_length + 1);
1032 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1036 if (matches_name_change) {
1038 /* If this match could theoretically match
1039 * NameOwnerChanged messages, we need to
1040 * install a second non-bloom filter explitly
1043 r = add_name_change_match(bus, cookie, name_change_arg[0], name_change_arg[1], name_change_arg[2]);
1051 static int bus_add_match_internal_dbus1(
1053 const char *match) {
1058 return sd_bus_call_method(
1060 "org.freedesktop.DBus",
1062 "org.freedesktop.DBus",
1070 int bus_add_match_internal(
1073 struct bus_match_component *components,
1074 unsigned n_components,
1081 return bus_add_match_internal_kernel(bus, match, components, n_components, cookie);
1083 return bus_add_match_internal_dbus1(bus, match);
1086 static int bus_remove_match_internal_kernel(
1091 struct kdbus_cmd_match m;
1098 m.size = offsetof(struct kdbus_cmd_match, items);
1101 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_REMOVE, &m);
1108 static int bus_remove_match_internal_dbus1(
1110 const char *match) {
1115 return sd_bus_call_method(
1117 "org.freedesktop.DBus",
1119 "org.freedesktop.DBus",
1127 int bus_remove_match_internal(
1136 return bus_remove_match_internal_kernel(bus, match, cookie);
1138 return bus_remove_match_internal_dbus1(bus, match);
1141 _public_ int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) {
1142 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
1146 assert_return(bus, -EINVAL);
1147 assert_return(name, -EINVAL);
1148 assert_return(machine, -EINVAL);
1149 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1150 assert_return(!bus_pid_changed(bus), -ECHILD);
1152 if (streq_ptr(name, bus->unique_name))
1153 return sd_id128_get_machine(machine);
1155 r = sd_bus_message_new_method_call(
1159 "org.freedesktop.DBus.Peer",
1160 "GetMachineId", &m);
1164 r = sd_bus_message_set_no_auto_start(m, true);
1168 r = sd_bus_call(bus, m, 0, NULL, &reply);
1172 r = sd_bus_message_read(reply, "s", &mid);
1176 return sd_id128_from_string(mid, machine);