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_IS_OPEN(bus->state), -ENOTCONN);
132 assert_return(!bus_pid_changed(bus), -ECHILD);
133 assert_return(!(flags & ~(SD_BUS_NAME_ALLOW_REPLACEMENT|SD_BUS_NAME_REPLACE_EXISTING|SD_BUS_NAME_QUEUE)), -EINVAL);
134 assert_return(service_name_is_valid(name), -EINVAL);
135 assert_return(name[0] != ':', -EINVAL);
138 return bus_request_name_kernel(bus, name, flags);
140 return bus_request_name_dbus1(bus, name, flags);
143 static int bus_release_name_kernel(sd_bus *bus, const char *name) {
144 struct kdbus_cmd_name *n;
152 n = alloca0(offsetof(struct kdbus_cmd_name, name) + l + 1);
153 n->size = offsetof(struct kdbus_cmd_name, name) + l + 1;
154 memcpy(n->name, name, l+1);
156 #ifdef HAVE_VALGRIND_MEMCHECK_H
157 VALGRIND_MAKE_MEM_DEFINED(n, n->size);
159 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_RELEASE, n);
166 static int bus_release_name_dbus1(sd_bus *bus, const char *name) {
167 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
174 r = sd_bus_call_method(
176 "org.freedesktop.DBus",
177 "/org/freedesktop/DBus",
178 "org.freedesktop.DBus",
187 r = sd_bus_message_read(reply, "u", &ret);
190 if (ret == BUS_NAME_NON_EXISTENT)
192 if (ret == BUS_NAME_NOT_OWNER)
194 if (ret == BUS_NAME_RELEASED)
200 _public_ int sd_bus_release_name(sd_bus *bus, const char *name) {
201 assert_return(bus, -EINVAL);
202 assert_return(name, -EINVAL);
203 assert_return(bus->bus_client, -EINVAL);
204 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
205 assert_return(!bus_pid_changed(bus), -ECHILD);
206 assert_return(service_name_is_valid(name), -EINVAL);
207 assert_return(name[0] != ':', -EINVAL);
210 return bus_release_name_kernel(bus, name);
212 return bus_release_name_dbus1(bus, name);
215 static int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) {
216 struct kdbus_cmd_name_list cmd = {};
217 struct kdbus_name_list *name_list;
218 struct kdbus_cmd_name *name;
219 uint64_t previous_id = 0;
222 /* Caller will free half-constructed list on failure... */
226 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_LIST, &cmd);
230 name_list = (struct kdbus_name_list *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
232 KDBUS_ITEM_FOREACH(name, name_list, names) {
234 if ((flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != previous_id) {
237 if (asprintf(&n, ":1.%llu", (unsigned long long) name->owner_id) < 0)
246 previous_id = name->owner_id;
249 if (name->size > sizeof(*name) && service_name_is_valid(name->name)) {
250 r = strv_extend(x, name->name);
256 r = ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd.offset);
263 static int bus_list_names_kernel(sd_bus *bus, char ***acquired, char ***activatable) {
264 _cleanup_strv_free_ char **x = NULL, **y = NULL;
268 r = kernel_get_list(bus, KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES, &x);
274 r = kernel_get_list(bus, KDBUS_NAME_LIST_ACTIVATORS, &y);
290 static int bus_list_names_dbus1(sd_bus *bus, char ***acquired, char ***activatable) {
291 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
292 _cleanup_strv_free_ char **x = NULL, **y = NULL;
296 r = sd_bus_call_method(
298 "org.freedesktop.DBus",
299 "/org/freedesktop/DBus",
300 "org.freedesktop.DBus",
308 r = sd_bus_message_read_strv(reply, &x);
312 reply = sd_bus_message_unref(reply);
316 r = sd_bus_call_method(
318 "org.freedesktop.DBus",
319 "/org/freedesktop/DBus",
320 "org.freedesktop.DBus",
321 "ListActivatableNames",
328 r = sd_bus_message_read_strv(reply, &y);
344 _public_ int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable) {
345 assert_return(bus, -EINVAL);
346 assert_return(acquired || activatable, -EINVAL);
347 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
348 assert_return(!bus_pid_changed(bus), -ECHILD);
351 return bus_list_names_kernel(bus, acquired, activatable);
353 return bus_list_names_dbus1(bus, acquired, activatable);
356 static int bus_get_owner_kdbus(
360 sd_bus_creds **creds) {
362 _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
363 struct kdbus_cmd_conn_info *cmd;
364 struct kdbus_conn_info *conn_info;
365 struct kdbus_item *item;
370 r = bus_kernel_parse_unique_name(name, &id);
374 size = offsetof(struct kdbus_cmd_conn_info, name);
378 size = offsetof(struct kdbus_cmd_conn_info, name) + strlen(name) + 1;
380 strcpy(cmd->name, name);
384 kdbus_translate_attach_flags(mask, (uint64_t*) &cmd->flags);
386 r = ioctl(bus->input_fd, KDBUS_CMD_CONN_INFO, cmd);
390 conn_info = (struct kdbus_conn_info *) ((uint8_t *) bus->kdbus_buffer + cmd->offset);
392 /* Non-activated names are considered not available */
393 if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
394 return name[0] == ':' ? -ENXIO : -ENOENT;
400 if (mask & SD_BUS_CREDS_UNIQUE_NAME) {
401 if (asprintf(&c->unique_name, ":1.%llu", (unsigned long long) conn_info->id) < 0)
404 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
407 KDBUS_ITEM_FOREACH(item, conn_info, items) {
409 switch (item->type) {
411 case KDBUS_ITEM_CREDS:
412 m = (SD_BUS_CREDS_UID | SD_BUS_CREDS_GID | SD_BUS_CREDS_PID) & mask;
415 c->uid = (uid_t) item->creds.uid;
416 c->pid = (pid_t) item->creds.pid;
417 c->gid = (gid_t) item->creds.gid;
421 if (mask & SD_BUS_CREDS_TID && item->creds.tid > 0) {
422 c->tid = (pid_t) item->creds.tid;
423 c->mask |= SD_BUS_CREDS_TID;
426 if (mask & SD_BUS_CREDS_PID_STARTTIME && item->creds.starttime > 0) {
427 c->pid_starttime = item->creds.starttime;
428 c->mask |= SD_BUS_CREDS_PID_STARTTIME;
433 case KDBUS_ITEM_PID_COMM:
434 if (mask & SD_BUS_CREDS_COMM) {
435 c->comm = strdup(item->str);
441 c->mask |= SD_BUS_CREDS_COMM;
445 case KDBUS_ITEM_TID_COMM:
446 if (mask & SD_BUS_CREDS_TID_COMM) {
447 c->tid_comm = strdup(item->str);
453 c->mask |= SD_BUS_CREDS_TID_COMM;
458 if (mask & SD_BUS_CREDS_EXE) {
459 c->exe = strdup(item->str);
465 c->mask |= SD_BUS_CREDS_EXE;
469 case KDBUS_ITEM_CMDLINE:
470 if (mask & SD_BUS_CREDS_CMDLINE) {
471 c->cmdline_size = item->size - KDBUS_ITEM_HEADER_SIZE;
472 c->cmdline = memdup(item->data, c->cmdline_size);
478 c->mask |= SD_BUS_CREDS_CMDLINE;
482 case KDBUS_ITEM_CGROUP:
483 m = (SD_BUS_CREDS_CGROUP | SD_BUS_CREDS_UNIT |
484 SD_BUS_CREDS_USER_UNIT | SD_BUS_CREDS_SLICE |
485 SD_BUS_CREDS_SESSION | SD_BUS_CREDS_OWNER_UID) & mask;
488 c->cgroup = strdup(item->str);
494 if (!bus->cgroup_root) {
495 r = cg_get_root_path(&bus->cgroup_root);
500 c->cgroup_root = strdup(bus->cgroup_root);
501 if (!c->cgroup_root) {
510 case KDBUS_ITEM_CAPS:
511 m = (SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_PERMITTED_CAPS |
512 SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_BOUNDING_CAPS) & mask;
515 c->capability_size = item->size - KDBUS_ITEM_HEADER_SIZE;
516 c->capability = memdup(item->data, c->capability_size);
517 if (!c->capability) {
526 case KDBUS_ITEM_SECLABEL:
527 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
528 c->label = strdup(item->str);
534 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
538 case KDBUS_ITEM_AUDIT:
539 m = (SD_BUS_CREDS_AUDIT_SESSION_ID | SD_BUS_CREDS_AUDIT_LOGIN_UID) & mask;
542 c->audit_session_id = item->audit.sessionid;
543 c->audit_login_uid = item->audit.loginuid;
548 case KDBUS_ITEM_NAME:
549 if ((mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) && service_name_is_valid(item->name.name)) {
550 r = strv_extend(&c->well_known_names, item->name.name);
554 c->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
558 case KDBUS_ITEM_CONN_NAME:
559 if ((mask & SD_BUS_CREDS_CONNECTION_NAME)) {
560 c->conn_name = strdup(item->str);
566 c->mask |= SD_BUS_CREDS_CONNECTION_NAME;
580 ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd->offset);
584 static int bus_get_owner_dbus1(
588 sd_bus_creds **creds) {
590 _cleanup_bus_message_unref_ sd_bus_message *reply_unique = NULL, *reply = NULL;
591 _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
592 const char *unique = NULL;
596 /* Only query the owner if the caller wants to know it or if
597 * the caller just wants to check whether a name exists */
598 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) || mask == 0) {
599 r = sd_bus_call_method(
601 "org.freedesktop.DBus",
602 "/org/freedesktop/DBus",
603 "org.freedesktop.DBus",
612 r = sd_bus_message_read(reply_unique, "s", &unique);
622 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) && unique) {
623 c->unique_name = strdup(unique);
627 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
630 if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_GID|
631 SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
632 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|
633 SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
634 SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)) {
637 r = sd_bus_call_method(
639 "org.freedesktop.DBus",
640 "/org/freedesktop/DBus",
641 "org.freedesktop.DBus",
642 "GetConnectionUnixProcessID",
646 unique ? unique : name);
650 r = sd_bus_message_read(reply, "u", &u);
655 if (mask & SD_BUS_CREDS_PID) {
657 c->mask |= SD_BUS_CREDS_PID;
660 reply = sd_bus_message_unref(reply);
663 if (mask & SD_BUS_CREDS_UID) {
666 r = sd_bus_call_method(
668 "org.freedesktop.DBus",
669 "/org/freedesktop/DBus",
670 "org.freedesktop.DBus",
671 "GetConnectionUnixUser",
675 unique ? unique : name);
679 r = sd_bus_message_read(reply, "u", &u);
684 c->mask |= SD_BUS_CREDS_UID;
686 reply = sd_bus_message_unref(reply);
689 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
690 const void *p = NULL;
693 r = sd_bus_call_method(
695 "org.freedesktop.DBus",
696 "/org/freedesktop/DBus",
697 "org.freedesktop.DBus",
698 "GetConnectionSELinuxSecurityContext",
702 unique ? unique : name);
706 r = sd_bus_message_read_array(reply, 'y', &p, &sz);
710 c->label = strndup(p, sz);
714 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
717 r = bus_creds_add_more(c, mask, pid, 0);
730 _public_ int sd_bus_get_owner(
734 sd_bus_creds **creds) {
736 assert_return(bus, -EINVAL);
737 assert_return(name, -EINVAL);
738 assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
739 assert_return(mask == 0 || creds, -EINVAL);
740 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
741 assert_return(!bus_pid_changed(bus), -ECHILD);
742 assert_return(service_name_is_valid(name), -EINVAL);
743 assert_return(bus->bus_client, -ENODATA);
746 return bus_get_owner_kdbus(bus, name, mask, creds);
748 return bus_get_owner_dbus1(bus, name, mask, creds);
751 static int add_name_change_match(sd_bus *bus,
754 const char *old_owner,
755 const char *new_owner) {
757 uint64_t name_id = KDBUS_MATCH_ID_ANY, old_owner_id = 0, new_owner_id = 0;
758 int is_name_id = -1, r;
759 struct kdbus_item *item;
763 /* If we encounter a match that could match against
764 * NameOwnerChanged messages, then we need to create
765 * KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE} and
766 * KDBUS_ITEM_ID_{ADD,REMOVE} matches for it, possibly
767 * multiple if the match is underspecified.
769 * The NameOwnerChanged signals take three parameters with
770 * unique or well-known names, but only some forms actually
773 * WELLKNOWN, "", UNIQUE → KDBUS_ITEM_NAME_ADD
774 * WELLKNOWN, UNIQUE, "" → KDBUS_ITEM_NAME_REMOVE
775 * WELLKNOWN, UNIQUE, UNIQUE → KDBUS_ITEM_NAME_CHANGE
776 * UNIQUE, "", UNIQUE → KDBUS_ITEM_ID_ADD
777 * UNIQUE, UNIQUE, "" → KDBUS_ITEM_ID_REMOVE
779 * For the latter two the two unique names must be identical.
784 is_name_id = bus_kernel_parse_unique_name(name, &name_id);
789 if (!isempty(old_owner)) {
790 r = bus_kernel_parse_unique_name(old_owner, &old_owner_id);
795 if (is_name_id > 0 && old_owner_id != name_id)
798 old_owner_id = KDBUS_MATCH_ID_ANY;
800 if (!isempty(new_owner)) {
801 r = bus_kernel_parse_unique_name(new_owner, &new_owner_id);
806 if (is_name_id > 0 && new_owner_id != name_id)
809 new_owner_id = KDBUS_MATCH_ID_ANY;
811 if (is_name_id <= 0) {
812 struct kdbus_cmd_match *m;
815 /* If the name argument is missing or is a well-known
816 * name, then add KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE}
819 l = name ? strlen(name) + 1 : 0;
821 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
822 offsetof(struct kdbus_item, name_change) +
823 offsetof(struct kdbus_notify_name_change, name) +
832 offsetof(struct kdbus_item, name_change) +
833 offsetof(struct kdbus_notify_name_change, name) +
836 item->name_change.old.id = old_owner_id;
837 item->name_change.new.id = new_owner_id;
840 memcpy(item->name_change.name, name, l);
842 /* If the old name is unset or empty, then
843 * this can match against added names */
844 if (!old_owner || old_owner[0] == 0) {
845 item->type = KDBUS_ITEM_NAME_ADD;
847 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
852 /* If the new name is unset or empty, then
853 * this can match against removed names */
854 if (!new_owner || new_owner[0] == 0) {
855 item->type = KDBUS_ITEM_NAME_REMOVE;
857 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
862 /* The CHANGE match we need in either case, because
863 * what is reported as a name change by the kernel
864 * might just be an owner change between starter and
865 * normal clients. For userspace such a change should
866 * be considered a removal/addition, hence let's
867 * subscribe to this unconditionally. */
868 item->type = KDBUS_ITEM_NAME_CHANGE;
869 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
874 if (is_name_id != 0) {
875 struct kdbus_cmd_match *m;
878 /* If the name argument is missing or is a unique
879 * name, then add KDBUS_ITEM_ID_{ADD,REMOVE} matches
882 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
883 offsetof(struct kdbus_item, id_change) +
884 sizeof(struct kdbus_notify_id_change));
892 offsetof(struct kdbus_item, id_change) +
893 sizeof(struct kdbus_notify_id_change);
894 item->id_change.id = name_id;
896 /* If the old name is unset or empty, then this can
897 * match against added ids */
898 if (!old_owner || old_owner[0] == 0) {
899 item->type = KDBUS_ITEM_ID_ADD;
901 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
906 /* If thew new name is unset or empty, then this can
907 * match against removed ids */
908 if (!new_owner || new_owner[0] == 0) {
909 item->type = KDBUS_ITEM_ID_REMOVE;
911 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
920 int bus_add_match_internal_kernel(
923 struct bus_match_component *components,
924 unsigned n_components,
927 struct kdbus_cmd_match *m;
928 struct kdbus_item *item;
931 const char *sender = NULL;
932 size_t sender_length = 0;
933 uint64_t src_id = KDBUS_MATCH_ID_ANY;
934 bool using_bloom = false;
936 bool matches_name_change = true;
937 const char *name_change_arg[3] = {};
942 bloom = alloca0(bus->bloom_size);
944 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items));
946 for (i = 0; i < n_components; i++) {
947 struct bus_match_component *c = &components[i];
951 case BUS_MATCH_SENDER:
952 if (!streq(c->value_str, "org.freedesktop.DBus"))
953 matches_name_change = false;
955 r = bus_kernel_parse_unique_name(c->value_str, &src_id);
959 sz += ALIGN8(offsetof(struct kdbus_item, id) + sizeof(uint64_t));
961 sender = c->value_str;
962 sender_length = strlen(sender);
963 sz += ALIGN8(offsetof(struct kdbus_item, str) + sender_length + 1);
968 case BUS_MATCH_MESSAGE_TYPE:
969 if (c->value_u8 != SD_BUS_MESSAGE_SIGNAL)
970 matches_name_change = false;
972 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "message-type", bus_message_type_to_string(c->value_u8));
976 case BUS_MATCH_INTERFACE:
977 if (!streq(c->value_str, "org.freedesktop.DBus"))
978 matches_name_change = false;
980 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "interface", c->value_str);
984 case BUS_MATCH_MEMBER:
985 if (!streq(c->value_str, "NameOwnerChanged"))
986 matches_name_change = false;
988 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "member", c->value_str);
993 if (!streq(c->value_str, "/org/freedesktop/DBus"))
994 matches_name_change = false;
996 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path", c->value_str);
1000 case BUS_MATCH_PATH_NAMESPACE:
1001 if (!streq(c->value_str, "/")) {
1002 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path-slash-prefix", c->value_str);
1007 case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: {
1008 char buf[sizeof("arg")-1 + 2 + 1];
1010 if (c->type - BUS_MATCH_ARG < 3)
1011 name_change_arg[c->type - BUS_MATCH_ARG] = c->value_str;
1013 snprintf(buf, sizeof(buf), "arg%u", c->type - BUS_MATCH_ARG);
1014 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1019 case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: {
1020 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
1022 snprintf(buf, sizeof(buf), "arg%u-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
1023 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1028 case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: {
1029 char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")];
1031 snprintf(buf, sizeof(buf), "arg%u-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE);
1032 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1037 case BUS_MATCH_DESTINATION:
1038 /* The bloom filter does not include
1039 the destination, since it is only
1040 available for broadcast messages
1041 which do not carry a destination
1042 since they are undirected. */
1045 case BUS_MATCH_ROOT:
1046 case BUS_MATCH_VALUE:
1047 case BUS_MATCH_LEAF:
1048 case _BUS_MATCH_NODE_TYPE_MAX:
1049 case _BUS_MATCH_NODE_TYPE_INVALID:
1050 assert_not_reached("Invalid match type?");
1055 sz += ALIGN8(offsetof(struct kdbus_item, data64) + bus->bloom_size);
1064 if (src_id != KDBUS_MATCH_ID_ANY) {
1065 item->size = offsetof(struct kdbus_item, id) + sizeof(uint64_t);
1066 item->type = KDBUS_ITEM_ID;
1068 item = KDBUS_ITEM_NEXT(item);
1072 item->size = offsetof(struct kdbus_item, data64) + bus->bloom_size;
1073 item->type = KDBUS_ITEM_BLOOM_MASK;
1074 memcpy(item->data64, bloom, bus->bloom_size);
1075 item = KDBUS_ITEM_NEXT(item);
1079 item->size = offsetof(struct kdbus_item, str) + sender_length + 1;
1080 item->type = KDBUS_ITEM_NAME;
1081 memcpy(item->str, sender, sender_length + 1);
1084 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1088 if (matches_name_change) {
1090 /* If this match could theoretically match
1091 * NameOwnerChanged messages, we need to
1092 * install a second non-bloom filter explitly
1095 r = add_name_change_match(bus, cookie, name_change_arg[0], name_change_arg[1], name_change_arg[2]);
1103 static int bus_add_match_internal_dbus1(
1105 const char *match) {
1110 return sd_bus_call_method(
1112 "org.freedesktop.DBus",
1113 "/org/freedesktop/DBus",
1114 "org.freedesktop.DBus",
1122 int bus_add_match_internal(
1125 struct bus_match_component *components,
1126 unsigned n_components,
1133 return bus_add_match_internal_kernel(bus, 0, components, n_components, cookie);
1135 return bus_add_match_internal_dbus1(bus, match);
1138 int bus_remove_match_internal_kernel(
1143 struct kdbus_cmd_match m;
1149 m.size = offsetof(struct kdbus_cmd_match, items);
1153 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_REMOVE, &m);
1160 static int bus_remove_match_internal_dbus1(
1162 const char *match) {
1167 return sd_bus_call_method(
1169 "org.freedesktop.DBus",
1170 "/org/freedesktop/DBus",
1171 "org.freedesktop.DBus",
1179 int bus_remove_match_internal(
1188 return bus_remove_match_internal_kernel(bus, 0, cookie);
1190 return bus_remove_match_internal_dbus1(bus, match);
1193 _public_ int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) {
1194 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
1198 assert_return(bus, -EINVAL);
1199 assert_return(name, -EINVAL);
1200 assert_return(machine, -EINVAL);
1201 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1202 assert_return(!bus_pid_changed(bus), -ECHILD);
1203 assert_return(service_name_is_valid(name), -EINVAL);
1205 if (streq_ptr(name, bus->unique_name))
1206 return sd_id128_get_machine(machine);
1208 r = sd_bus_message_new_method_call(
1213 "org.freedesktop.DBus.Peer",
1218 r = sd_bus_message_set_auto_start(m, false);
1222 r = sd_bus_call(bus, m, 0, NULL, &reply);
1226 r = sd_bus_message_read(reply, "s", &mid);
1230 return sd_id128_from_string(mid, machine);