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"
36 #include "cgroup-util.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 static int bus_request_name_kernel(sd_bus *bus, const char *name, uint64_t flags) {
54 struct kdbus_cmd_name *n;
62 size = offsetof(struct kdbus_cmd_name, name) + l + 1;
65 kdbus_translate_request_name_flags(flags, (uint64_t *) &n->flags);
66 memcpy(n->name, name, l+1);
68 #ifdef HAVE_VALGRIND_MEMCHECK_H
69 VALGRIND_MAKE_MEM_DEFINED(n, n->size);
72 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_ACQUIRE, n);
76 if (n->flags & KDBUS_NAME_IN_QUEUE)
82 static int bus_request_name_dbus1(sd_bus *bus, const char *name, uint64_t flags) {
83 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
84 uint32_t ret, param = 0;
90 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
91 param |= BUS_NAME_ALLOW_REPLACEMENT;
92 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
93 param |= BUS_NAME_REPLACE_EXISTING;
94 if (!(flags & SD_BUS_NAME_QUEUE))
95 param |= BUS_NAME_DO_NOT_QUEUE;
97 r = sd_bus_call_method(
99 "org.freedesktop.DBus",
100 "/org/freedesktop/DBus",
101 "org.freedesktop.DBus",
111 r = sd_bus_message_read(reply, "u", &ret);
115 if (ret == BUS_NAME_ALREADY_OWNER)
117 else if (ret == BUS_NAME_EXISTS)
119 else if (ret == BUS_NAME_IN_QUEUE)
121 else if (ret == BUS_NAME_PRIMARY_OWNER)
127 _public_ int sd_bus_request_name(sd_bus *bus, const char *name, uint64_t flags) {
128 assert_return(bus, -EINVAL);
129 assert_return(name, -EINVAL);
130 assert_return(bus->bus_client, -EINVAL);
131 assert_return(!bus_pid_changed(bus), -ECHILD);
132 assert_return(!(flags & ~(SD_BUS_NAME_ALLOW_REPLACEMENT|SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_QUEUE)), -EINVAL);
133 assert_return(service_name_is_valid(name), -EINVAL);
134 assert_return(name[0] != ':', -EINVAL);
136 if (!BUS_IS_OPEN(bus->state))
140 return bus_request_name_kernel(bus, name, flags);
142 return bus_request_name_dbus1(bus, name, flags);
145 static int bus_release_name_kernel(sd_bus *bus, const char *name) {
146 struct kdbus_cmd_name *n;
154 n = alloca0(offsetof(struct kdbus_cmd_name, name) + l + 1);
155 n->size = offsetof(struct kdbus_cmd_name, name) + l + 1;
156 memcpy(n->name, name, l+1);
158 #ifdef HAVE_VALGRIND_MEMCHECK_H
159 VALGRIND_MAKE_MEM_DEFINED(n, n->size);
161 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_RELEASE, n);
168 static int bus_release_name_dbus1(sd_bus *bus, const char *name) {
169 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
176 r = sd_bus_call_method(
178 "org.freedesktop.DBus",
179 "/org/freedesktop/DBus",
180 "org.freedesktop.DBus",
189 r = sd_bus_message_read(reply, "u", &ret);
192 if (ret == BUS_NAME_NON_EXISTENT)
194 if (ret == BUS_NAME_NOT_OWNER)
196 if (ret == BUS_NAME_RELEASED)
202 _public_ int sd_bus_release_name(sd_bus *bus, const char *name) {
203 assert_return(bus, -EINVAL);
204 assert_return(name, -EINVAL);
205 assert_return(bus->bus_client, -EINVAL);
206 assert_return(!bus_pid_changed(bus), -ECHILD);
207 assert_return(service_name_is_valid(name), -EINVAL);
208 assert_return(name[0] != ':', -EINVAL);
210 if (!BUS_IS_OPEN(bus->state))
214 return bus_release_name_kernel(bus, name);
216 return bus_release_name_dbus1(bus, name);
219 static int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) {
220 struct kdbus_cmd_name_list cmd = {};
221 struct kdbus_name_list *name_list;
222 struct kdbus_cmd_name *name;
223 uint64_t previous_id = 0;
226 /* Caller will free half-constructed list on failure... */
230 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_LIST, &cmd);
234 name_list = (struct kdbus_name_list *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
236 KDBUS_ITEM_FOREACH(name, name_list, names) {
238 if ((flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != previous_id) {
241 if (asprintf(&n, ":1.%llu", (unsigned long long) name->owner_id) < 0)
244 r = strv_consume(x, n);
248 previous_id = name->owner_id;
251 if (name->size > sizeof(*name) && service_name_is_valid(name->name)) {
252 r = strv_extend(x, name->name);
258 r = ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd.offset);
265 static int bus_list_names_kernel(sd_bus *bus, char ***acquired, char ***activatable) {
266 _cleanup_strv_free_ char **x = NULL, **y = NULL;
270 r = kernel_get_list(bus, KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES, &x);
276 r = kernel_get_list(bus, KDBUS_NAME_LIST_ACTIVATORS, &y);
292 static int bus_list_names_dbus1(sd_bus *bus, char ***acquired, char ***activatable) {
293 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
294 _cleanup_strv_free_ char **x = NULL, **y = NULL;
298 r = sd_bus_call_method(
300 "org.freedesktop.DBus",
301 "/org/freedesktop/DBus",
302 "org.freedesktop.DBus",
310 r = sd_bus_message_read_strv(reply, &x);
314 reply = sd_bus_message_unref(reply);
318 r = sd_bus_call_method(
320 "org.freedesktop.DBus",
321 "/org/freedesktop/DBus",
322 "org.freedesktop.DBus",
323 "ListActivatableNames",
330 r = sd_bus_message_read_strv(reply, &y);
346 _public_ int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable) {
347 assert_return(bus, -EINVAL);
348 assert_return(acquired || activatable, -EINVAL);
349 assert_return(!bus_pid_changed(bus), -ECHILD);
351 if (!BUS_IS_OPEN(bus->state))
355 return bus_list_names_kernel(bus, acquired, activatable);
357 return bus_list_names_dbus1(bus, acquired, activatable);
360 static int bus_get_owner_kdbus(
364 sd_bus_creds **creds) {
366 _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
367 struct kdbus_cmd_conn_info *cmd;
368 struct kdbus_conn_info *conn_info;
369 struct kdbus_item *item;
374 r = bus_kernel_parse_unique_name(name, &id);
378 size = offsetof(struct kdbus_cmd_conn_info, name);
382 size = offsetof(struct kdbus_cmd_conn_info, name) + strlen(name) + 1;
384 strcpy(cmd->name, name);
388 kdbus_translate_attach_flags(mask, (uint64_t*) &cmd->flags);
390 r = ioctl(bus->input_fd, KDBUS_CMD_CONN_INFO, cmd);
394 conn_info = (struct kdbus_conn_info *) ((uint8_t *) bus->kdbus_buffer + cmd->offset);
396 /* Non-activated names are considered not available */
397 if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
398 return name[0] == ':' ? -ENXIO : -ESRCH;
404 if (mask & SD_BUS_CREDS_UNIQUE_NAME) {
405 if (asprintf(&c->unique_name, ":1.%llu", (unsigned long long) conn_info->id) < 0)
408 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
411 KDBUS_ITEM_FOREACH(item, conn_info, items) {
413 switch (item->type) {
415 case KDBUS_ITEM_CREDS:
416 m = (SD_BUS_CREDS_UID | SD_BUS_CREDS_GID | SD_BUS_CREDS_PID) & mask;
419 c->uid = (uid_t) item->creds.uid;
420 c->pid = (pid_t) item->creds.pid;
421 c->gid = (gid_t) item->creds.gid;
425 if (mask & SD_BUS_CREDS_TID && item->creds.tid > 0) {
426 c->tid = (pid_t) item->creds.tid;
427 c->mask |= SD_BUS_CREDS_TID;
430 if (mask & SD_BUS_CREDS_PID_STARTTIME && item->creds.starttime > 0) {
431 c->pid_starttime = item->creds.starttime;
432 c->mask |= SD_BUS_CREDS_PID_STARTTIME;
437 case KDBUS_ITEM_PID_COMM:
438 if (mask & SD_BUS_CREDS_COMM) {
439 c->comm = strdup(item->str);
445 c->mask |= SD_BUS_CREDS_COMM;
449 case KDBUS_ITEM_TID_COMM:
450 if (mask & SD_BUS_CREDS_TID_COMM) {
451 c->tid_comm = strdup(item->str);
457 c->mask |= SD_BUS_CREDS_TID_COMM;
462 if (mask & SD_BUS_CREDS_EXE) {
463 c->exe = strdup(item->str);
469 c->mask |= SD_BUS_CREDS_EXE;
473 case KDBUS_ITEM_CMDLINE:
474 if (mask & SD_BUS_CREDS_CMDLINE) {
475 c->cmdline_size = item->size - KDBUS_ITEM_HEADER_SIZE;
476 c->cmdline = memdup(item->data, c->cmdline_size);
482 c->mask |= SD_BUS_CREDS_CMDLINE;
486 case KDBUS_ITEM_CGROUP:
487 m = (SD_BUS_CREDS_CGROUP | SD_BUS_CREDS_UNIT |
488 SD_BUS_CREDS_USER_UNIT | SD_BUS_CREDS_SLICE |
489 SD_BUS_CREDS_SESSION | SD_BUS_CREDS_OWNER_UID) & mask;
492 c->cgroup = strdup(item->str);
498 r = bus_get_root_path(bus);
502 c->cgroup_root = strdup(bus->cgroup_root);
503 if (!c->cgroup_root) {
512 case KDBUS_ITEM_CAPS:
513 m = (SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_PERMITTED_CAPS |
514 SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_BOUNDING_CAPS) & mask;
517 c->capability_size = item->size - KDBUS_ITEM_HEADER_SIZE;
518 c->capability = memdup(item->data, c->capability_size);
519 if (!c->capability) {
528 case KDBUS_ITEM_SECLABEL:
529 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
530 c->label = strdup(item->str);
536 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
540 case KDBUS_ITEM_AUDIT:
541 m = (SD_BUS_CREDS_AUDIT_SESSION_ID | SD_BUS_CREDS_AUDIT_LOGIN_UID) & mask;
544 c->audit_session_id = item->audit.sessionid;
545 c->audit_login_uid = item->audit.loginuid;
550 case KDBUS_ITEM_NAME:
551 if ((mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) && service_name_is_valid(item->name.name)) {
552 r = strv_extend(&c->well_known_names, item->name.name);
556 c->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
560 case KDBUS_ITEM_CONN_NAME:
561 if ((mask & SD_BUS_CREDS_CONNECTION_NAME)) {
562 c->conn_name = strdup(item->str);
568 c->mask |= SD_BUS_CREDS_CONNECTION_NAME;
582 ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd->offset);
586 static int bus_get_owner_dbus1(
590 sd_bus_creds **creds) {
592 _cleanup_bus_message_unref_ sd_bus_message *reply_unique = NULL, *reply = NULL;
593 _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
594 const char *unique = NULL;
598 /* Only query the owner if the caller wants to know it or if
599 * the caller just wants to check whether a name exists */
600 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) || mask == 0) {
601 r = sd_bus_call_method(
603 "org.freedesktop.DBus",
604 "/org/freedesktop/DBus",
605 "org.freedesktop.DBus",
614 r = sd_bus_message_read(reply_unique, "s", &unique);
624 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) && unique) {
625 c->unique_name = strdup(unique);
629 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
632 if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_GID|
633 SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
634 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|
635 SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
636 SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)) {
639 r = sd_bus_call_method(
641 "org.freedesktop.DBus",
642 "/org/freedesktop/DBus",
643 "org.freedesktop.DBus",
644 "GetConnectionUnixProcessID",
648 unique ? unique : name);
652 r = sd_bus_message_read(reply, "u", &u);
657 if (mask & SD_BUS_CREDS_PID) {
659 c->mask |= SD_BUS_CREDS_PID;
662 reply = sd_bus_message_unref(reply);
665 if (mask & SD_BUS_CREDS_UID) {
668 r = sd_bus_call_method(
670 "org.freedesktop.DBus",
671 "/org/freedesktop/DBus",
672 "org.freedesktop.DBus",
673 "GetConnectionUnixUser",
677 unique ? unique : name);
681 r = sd_bus_message_read(reply, "u", &u);
686 c->mask |= SD_BUS_CREDS_UID;
688 reply = sd_bus_message_unref(reply);
691 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
692 const void *p = NULL;
695 r = sd_bus_call_method(
697 "org.freedesktop.DBus",
698 "/org/freedesktop/DBus",
699 "org.freedesktop.DBus",
700 "GetConnectionSELinuxSecurityContext",
704 unique ? unique : name);
708 r = sd_bus_message_read_array(reply, 'y', &p, &sz);
712 c->label = strndup(p, sz);
716 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
719 r = bus_creds_add_more(c, mask, pid, 0);
732 _public_ int sd_bus_get_owner(
736 sd_bus_creds **creds) {
738 assert_return(bus, -EINVAL);
739 assert_return(name, -EINVAL);
740 assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
741 assert_return(mask == 0 || creds, -EINVAL);
742 assert_return(!bus_pid_changed(bus), -ECHILD);
743 assert_return(service_name_is_valid(name), -EINVAL);
744 assert_return(bus->bus_client, -ENODATA);
746 if (!BUS_IS_OPEN(bus->state))
750 return bus_get_owner_kdbus(bus, name, mask, creds);
752 return bus_get_owner_dbus1(bus, name, mask, creds);
755 static int add_name_change_match(sd_bus *bus,
758 const char *old_owner,
759 const char *new_owner) {
761 uint64_t name_id = KDBUS_MATCH_ID_ANY, old_owner_id = 0, new_owner_id = 0;
762 int is_name_id = -1, r;
763 struct kdbus_item *item;
767 /* If we encounter a match that could match against
768 * NameOwnerChanged messages, then we need to create
769 * KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE} and
770 * KDBUS_ITEM_ID_{ADD,REMOVE} matches for it, possibly
771 * multiple if the match is underspecified.
773 * The NameOwnerChanged signals take three parameters with
774 * unique or well-known names, but only some forms actually
777 * WELLKNOWN, "", UNIQUE → KDBUS_ITEM_NAME_ADD
778 * WELLKNOWN, UNIQUE, "" → KDBUS_ITEM_NAME_REMOVE
779 * WELLKNOWN, UNIQUE, UNIQUE → KDBUS_ITEM_NAME_CHANGE
780 * UNIQUE, "", UNIQUE → KDBUS_ITEM_ID_ADD
781 * UNIQUE, UNIQUE, "" → KDBUS_ITEM_ID_REMOVE
783 * For the latter two the two unique names must be identical.
788 is_name_id = bus_kernel_parse_unique_name(name, &name_id);
793 if (!isempty(old_owner)) {
794 r = bus_kernel_parse_unique_name(old_owner, &old_owner_id);
799 if (is_name_id > 0 && old_owner_id != name_id)
802 old_owner_id = KDBUS_MATCH_ID_ANY;
804 if (!isempty(new_owner)) {
805 r = bus_kernel_parse_unique_name(new_owner, &new_owner_id);
810 if (is_name_id > 0 && new_owner_id != name_id)
813 new_owner_id = KDBUS_MATCH_ID_ANY;
815 if (is_name_id <= 0) {
816 struct kdbus_cmd_match *m;
819 /* If the name argument is missing or is a well-known
820 * name, then add KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE}
823 l = name ? strlen(name) + 1 : 0;
825 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
826 offsetof(struct kdbus_item, name_change) +
827 offsetof(struct kdbus_notify_name_change, name) +
836 offsetof(struct kdbus_item, name_change) +
837 offsetof(struct kdbus_notify_name_change, name) +
840 item->name_change.old.id = old_owner_id;
841 item->name_change.new.id = new_owner_id;
844 memcpy(item->name_change.name, name, l);
846 /* If the old name is unset or empty, then
847 * this can match against added names */
848 if (!old_owner || old_owner[0] == 0) {
849 item->type = KDBUS_ITEM_NAME_ADD;
851 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
856 /* If the new name is unset or empty, then
857 * this can match against removed names */
858 if (!new_owner || new_owner[0] == 0) {
859 item->type = KDBUS_ITEM_NAME_REMOVE;
861 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
866 /* The CHANGE match we need in either case, because
867 * what is reported as a name change by the kernel
868 * might just be an owner change between starter and
869 * normal clients. For userspace such a change should
870 * be considered a removal/addition, hence let's
871 * subscribe to this unconditionally. */
872 item->type = KDBUS_ITEM_NAME_CHANGE;
873 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
878 if (is_name_id != 0) {
879 struct kdbus_cmd_match *m;
882 /* If the name argument is missing or is a unique
883 * name, then add KDBUS_ITEM_ID_{ADD,REMOVE} matches
886 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
887 offsetof(struct kdbus_item, id_change) +
888 sizeof(struct kdbus_notify_id_change));
896 offsetof(struct kdbus_item, id_change) +
897 sizeof(struct kdbus_notify_id_change);
898 item->id_change.id = name_id;
900 /* If the old name is unset or empty, then this can
901 * match against added ids */
902 if (!old_owner || old_owner[0] == 0) {
903 item->type = KDBUS_ITEM_ID_ADD;
905 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
910 /* If thew new name is unset or empty, then this can
911 * match against removed ids */
912 if (!new_owner || new_owner[0] == 0) {
913 item->type = KDBUS_ITEM_ID_REMOVE;
915 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
924 int bus_add_match_internal_kernel(
926 struct bus_match_component *components,
927 unsigned n_components,
930 struct kdbus_cmd_match *m;
931 struct kdbus_item *item;
934 const char *sender = NULL;
935 size_t sender_length = 0;
936 uint64_t src_id = KDBUS_MATCH_ID_ANY;
937 bool using_bloom = false;
939 bool matches_name_change = true;
940 const char *name_change_arg[3] = {};
945 bloom = alloca0(bus->bloom_size);
947 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items));
949 for (i = 0; i < n_components; i++) {
950 struct bus_match_component *c = &components[i];
954 case BUS_MATCH_SENDER:
955 if (!streq(c->value_str, "org.freedesktop.DBus"))
956 matches_name_change = false;
958 r = bus_kernel_parse_unique_name(c->value_str, &src_id);
962 sz += ALIGN8(offsetof(struct kdbus_item, id) + sizeof(uint64_t));
964 sender = c->value_str;
965 sender_length = strlen(sender);
966 sz += ALIGN8(offsetof(struct kdbus_item, str) + sender_length + 1);
971 case BUS_MATCH_MESSAGE_TYPE:
972 if (c->value_u8 != SD_BUS_MESSAGE_SIGNAL)
973 matches_name_change = false;
975 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "message-type", bus_message_type_to_string(c->value_u8));
979 case BUS_MATCH_INTERFACE:
980 if (!streq(c->value_str, "org.freedesktop.DBus"))
981 matches_name_change = false;
983 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "interface", c->value_str);
987 case BUS_MATCH_MEMBER:
988 if (!streq(c->value_str, "NameOwnerChanged"))
989 matches_name_change = false;
991 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "member", c->value_str);
996 if (!streq(c->value_str, "/org/freedesktop/DBus"))
997 matches_name_change = false;
999 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path", c->value_str);
1003 case BUS_MATCH_PATH_NAMESPACE:
1004 if (!streq(c->value_str, "/")) {
1005 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path-slash-prefix", c->value_str);
1010 case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: {
1011 char buf[sizeof("arg")-1 + 2 + 1];
1013 if (c->type - BUS_MATCH_ARG < 3)
1014 name_change_arg[c->type - BUS_MATCH_ARG] = c->value_str;
1016 snprintf(buf, sizeof(buf), "arg%u", c->type - BUS_MATCH_ARG);
1017 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1022 case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: {
1023 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
1025 snprintf(buf, sizeof(buf), "arg%u-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
1026 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1031 case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: {
1032 char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")];
1034 snprintf(buf, sizeof(buf), "arg%u-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE);
1035 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1040 case BUS_MATCH_DESTINATION:
1041 /* The bloom filter does not include
1042 the destination, since it is only
1043 available for broadcast messages
1044 which do not carry a destination
1045 since they are undirected. */
1048 case BUS_MATCH_ROOT:
1049 case BUS_MATCH_VALUE:
1050 case BUS_MATCH_LEAF:
1051 case _BUS_MATCH_NODE_TYPE_MAX:
1052 case _BUS_MATCH_NODE_TYPE_INVALID:
1053 assert_not_reached("Invalid match type?");
1058 sz += ALIGN8(offsetof(struct kdbus_item, data64) + bus->bloom_size);
1066 if (src_id != KDBUS_MATCH_ID_ANY) {
1067 item->size = offsetof(struct kdbus_item, id) + sizeof(uint64_t);
1068 item->type = KDBUS_ITEM_ID;
1070 item = KDBUS_ITEM_NEXT(item);
1074 item->size = offsetof(struct kdbus_item, data64) + bus->bloom_size;
1075 item->type = KDBUS_ITEM_BLOOM_MASK;
1076 memcpy(item->data64, bloom, bus->bloom_size);
1077 item = KDBUS_ITEM_NEXT(item);
1081 item->size = offsetof(struct kdbus_item, str) + sender_length + 1;
1082 item->type = KDBUS_ITEM_NAME;
1083 memcpy(item->str, sender, sender_length + 1);
1086 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1090 if (matches_name_change) {
1092 /* If this match could theoretically match
1093 * NameOwnerChanged messages, we need to
1094 * install a second non-bloom filter explitly
1097 r = add_name_change_match(bus, cookie, name_change_arg[0], name_change_arg[1], name_change_arg[2]);
1105 #define internal_match(bus, m) \
1106 ((bus)->hello_flags & KDBUS_HELLO_MONITOR \
1107 ? (isempty(m) ? "eavesdrop='true'" : strappenda((m), ",eavesdrop='true'")) \
1110 static int bus_add_match_internal_dbus1(
1112 const char *match) {
1119 e = internal_match(bus, match);
1121 return sd_bus_call_method(
1123 "org.freedesktop.DBus",
1124 "/org/freedesktop/DBus",
1125 "org.freedesktop.DBus",
1133 int bus_add_match_internal(
1136 struct bus_match_component *components,
1137 unsigned n_components,
1143 return bus_add_match_internal_kernel(bus, components, n_components, cookie);
1145 return bus_add_match_internal_dbus1(bus, match);
1148 int bus_remove_match_internal_kernel(
1152 struct kdbus_cmd_match m;
1158 m.size = offsetof(struct kdbus_cmd_match, items);
1161 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_REMOVE, &m);
1168 static int bus_remove_match_internal_dbus1(
1170 const char *match) {
1177 e = internal_match(bus, match);
1179 return sd_bus_call_method(
1181 "org.freedesktop.DBus",
1182 "/org/freedesktop/DBus",
1183 "org.freedesktop.DBus",
1191 int bus_remove_match_internal(
1199 return bus_remove_match_internal_kernel(bus, cookie);
1201 return bus_remove_match_internal_dbus1(bus, match);
1204 _public_ int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) {
1205 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
1209 assert_return(bus, -EINVAL);
1210 assert_return(name, -EINVAL);
1211 assert_return(machine, -EINVAL);
1212 assert_return(!bus_pid_changed(bus), -ECHILD);
1213 assert_return(service_name_is_valid(name), -EINVAL);
1215 if (!BUS_IS_OPEN(bus->state))
1218 if (streq_ptr(name, bus->unique_name))
1219 return sd_id128_get_machine(machine);
1221 r = sd_bus_message_new_method_call(
1226 "org.freedesktop.DBus.Peer",
1231 r = sd_bus_message_set_auto_start(m, false);
1235 r = sd_bus_call(bus, m, 0, NULL, &reply);
1239 r = sd_bus_message_read(reply, "s", &mid);
1243 return sd_id128_from_string(mid, machine);