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)
240 r = strv_consume(x, n);
244 previous_id = name->owner_id;
247 if (name->size > sizeof(*name) && service_name_is_valid(name->name)) {
248 r = strv_extend(x, name->name);
254 r = ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd.offset);
261 static int bus_list_names_kernel(sd_bus *bus, char ***acquired, char ***activatable) {
262 _cleanup_strv_free_ char **x = NULL, **y = NULL;
266 r = kernel_get_list(bus, KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES, &x);
272 r = kernel_get_list(bus, KDBUS_NAME_LIST_ACTIVATORS, &y);
288 static int bus_list_names_dbus1(sd_bus *bus, char ***acquired, char ***activatable) {
289 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
290 _cleanup_strv_free_ char **x = NULL, **y = NULL;
294 r = sd_bus_call_method(
296 "org.freedesktop.DBus",
297 "/org/freedesktop/DBus",
298 "org.freedesktop.DBus",
306 r = sd_bus_message_read_strv(reply, &x);
310 reply = sd_bus_message_unref(reply);
314 r = sd_bus_call_method(
316 "org.freedesktop.DBus",
317 "/org/freedesktop/DBus",
318 "org.freedesktop.DBus",
319 "ListActivatableNames",
326 r = sd_bus_message_read_strv(reply, &y);
342 _public_ int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable) {
343 assert_return(bus, -EINVAL);
344 assert_return(acquired || activatable, -EINVAL);
345 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
346 assert_return(!bus_pid_changed(bus), -ECHILD);
349 return bus_list_names_kernel(bus, acquired, activatable);
351 return bus_list_names_dbus1(bus, acquired, activatable);
354 static int bus_get_owner_kdbus(
358 sd_bus_creds **creds) {
360 _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
361 struct kdbus_cmd_conn_info *cmd;
362 struct kdbus_conn_info *conn_info;
363 struct kdbus_item *item;
368 r = bus_kernel_parse_unique_name(name, &id);
372 size = offsetof(struct kdbus_cmd_conn_info, name);
376 size = offsetof(struct kdbus_cmd_conn_info, name) + strlen(name) + 1;
378 strcpy(cmd->name, name);
382 kdbus_translate_attach_flags(mask, (uint64_t*) &cmd->flags);
384 r = ioctl(bus->input_fd, KDBUS_CMD_CONN_INFO, cmd);
388 conn_info = (struct kdbus_conn_info *) ((uint8_t *) bus->kdbus_buffer + cmd->offset);
390 /* Non-activated names are considered not available */
391 if (conn_info->flags & KDBUS_HELLO_ACTIVATOR)
392 return name[0] == ':' ? -ENXIO : -ENOENT;
398 if (mask & SD_BUS_CREDS_UNIQUE_NAME) {
399 if (asprintf(&c->unique_name, ":1.%llu", (unsigned long long) conn_info->id) < 0)
402 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
405 KDBUS_ITEM_FOREACH(item, conn_info, items) {
407 switch (item->type) {
409 case KDBUS_ITEM_CREDS:
410 m = (SD_BUS_CREDS_UID | SD_BUS_CREDS_GID | SD_BUS_CREDS_PID) & mask;
413 c->uid = (uid_t) item->creds.uid;
414 c->pid = (pid_t) item->creds.pid;
415 c->gid = (gid_t) item->creds.gid;
419 if (mask & SD_BUS_CREDS_TID && item->creds.tid > 0) {
420 c->tid = (pid_t) item->creds.tid;
421 c->mask |= SD_BUS_CREDS_TID;
424 if (mask & SD_BUS_CREDS_PID_STARTTIME && item->creds.starttime > 0) {
425 c->pid_starttime = item->creds.starttime;
426 c->mask |= SD_BUS_CREDS_PID_STARTTIME;
431 case KDBUS_ITEM_PID_COMM:
432 if (mask & SD_BUS_CREDS_COMM) {
433 c->comm = strdup(item->str);
439 c->mask |= SD_BUS_CREDS_COMM;
443 case KDBUS_ITEM_TID_COMM:
444 if (mask & SD_BUS_CREDS_TID_COMM) {
445 c->tid_comm = strdup(item->str);
451 c->mask |= SD_BUS_CREDS_TID_COMM;
456 if (mask & SD_BUS_CREDS_EXE) {
457 c->exe = strdup(item->str);
463 c->mask |= SD_BUS_CREDS_EXE;
467 case KDBUS_ITEM_CMDLINE:
468 if (mask & SD_BUS_CREDS_CMDLINE) {
469 c->cmdline_size = item->size - KDBUS_ITEM_HEADER_SIZE;
470 c->cmdline = memdup(item->data, c->cmdline_size);
476 c->mask |= SD_BUS_CREDS_CMDLINE;
480 case KDBUS_ITEM_CGROUP:
481 m = (SD_BUS_CREDS_CGROUP | SD_BUS_CREDS_UNIT |
482 SD_BUS_CREDS_USER_UNIT | SD_BUS_CREDS_SLICE |
483 SD_BUS_CREDS_SESSION | SD_BUS_CREDS_OWNER_UID) & mask;
486 c->cgroup = strdup(item->str);
492 if (!bus->cgroup_root) {
493 r = cg_get_root_path(&bus->cgroup_root);
498 c->cgroup_root = strdup(bus->cgroup_root);
499 if (!c->cgroup_root) {
508 case KDBUS_ITEM_CAPS:
509 m = (SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_PERMITTED_CAPS |
510 SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_BOUNDING_CAPS) & mask;
513 c->capability_size = item->size - KDBUS_ITEM_HEADER_SIZE;
514 c->capability = memdup(item->data, c->capability_size);
515 if (!c->capability) {
524 case KDBUS_ITEM_SECLABEL:
525 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
526 c->label = strdup(item->str);
532 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
536 case KDBUS_ITEM_AUDIT:
537 m = (SD_BUS_CREDS_AUDIT_SESSION_ID | SD_BUS_CREDS_AUDIT_LOGIN_UID) & mask;
540 c->audit_session_id = item->audit.sessionid;
541 c->audit_login_uid = item->audit.loginuid;
546 case KDBUS_ITEM_NAME:
547 if ((mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) && service_name_is_valid(item->name.name)) {
548 r = strv_extend(&c->well_known_names, item->name.name);
552 c->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
556 case KDBUS_ITEM_CONN_NAME:
557 if ((mask & SD_BUS_CREDS_CONNECTION_NAME)) {
558 c->conn_name = strdup(item->str);
564 c->mask |= SD_BUS_CREDS_CONNECTION_NAME;
578 ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd->offset);
582 static int bus_get_owner_dbus1(
586 sd_bus_creds **creds) {
588 _cleanup_bus_message_unref_ sd_bus_message *reply_unique = NULL, *reply = NULL;
589 _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
590 const char *unique = NULL;
594 /* Only query the owner if the caller wants to know it or if
595 * the caller just wants to check whether a name exists */
596 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) || mask == 0) {
597 r = sd_bus_call_method(
599 "org.freedesktop.DBus",
600 "/org/freedesktop/DBus",
601 "org.freedesktop.DBus",
610 r = sd_bus_message_read(reply_unique, "s", &unique);
620 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) && unique) {
621 c->unique_name = strdup(unique);
625 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
628 if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_GID|
629 SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
630 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|
631 SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
632 SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)) {
635 r = sd_bus_call_method(
637 "org.freedesktop.DBus",
638 "/org/freedesktop/DBus",
639 "org.freedesktop.DBus",
640 "GetConnectionUnixProcessID",
644 unique ? unique : name);
648 r = sd_bus_message_read(reply, "u", &u);
653 if (mask & SD_BUS_CREDS_PID) {
655 c->mask |= SD_BUS_CREDS_PID;
658 reply = sd_bus_message_unref(reply);
661 if (mask & SD_BUS_CREDS_UID) {
664 r = sd_bus_call_method(
666 "org.freedesktop.DBus",
667 "/org/freedesktop/DBus",
668 "org.freedesktop.DBus",
669 "GetConnectionUnixUser",
673 unique ? unique : name);
677 r = sd_bus_message_read(reply, "u", &u);
682 c->mask |= SD_BUS_CREDS_UID;
684 reply = sd_bus_message_unref(reply);
687 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
688 const void *p = NULL;
691 r = sd_bus_call_method(
693 "org.freedesktop.DBus",
694 "/org/freedesktop/DBus",
695 "org.freedesktop.DBus",
696 "GetConnectionSELinuxSecurityContext",
700 unique ? unique : name);
704 r = sd_bus_message_read_array(reply, 'y', &p, &sz);
708 c->label = strndup(p, sz);
712 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
715 r = bus_creds_add_more(c, mask, pid, 0);
728 _public_ int sd_bus_get_owner(
732 sd_bus_creds **creds) {
734 assert_return(bus, -EINVAL);
735 assert_return(name, -EINVAL);
736 assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
737 assert_return(mask == 0 || creds, -EINVAL);
738 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
739 assert_return(!bus_pid_changed(bus), -ECHILD);
740 assert_return(service_name_is_valid(name), -EINVAL);
741 assert_return(bus->bus_client, -ENODATA);
744 return bus_get_owner_kdbus(bus, name, mask, creds);
746 return bus_get_owner_dbus1(bus, name, mask, creds);
749 static int add_name_change_match(sd_bus *bus,
752 const char *old_owner,
753 const char *new_owner) {
755 uint64_t name_id = KDBUS_MATCH_ID_ANY, old_owner_id = 0, new_owner_id = 0;
756 int is_name_id = -1, r;
757 struct kdbus_item *item;
761 /* If we encounter a match that could match against
762 * NameOwnerChanged messages, then we need to create
763 * KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE} and
764 * KDBUS_ITEM_ID_{ADD,REMOVE} matches for it, possibly
765 * multiple if the match is underspecified.
767 * The NameOwnerChanged signals take three parameters with
768 * unique or well-known names, but only some forms actually
771 * WELLKNOWN, "", UNIQUE → KDBUS_ITEM_NAME_ADD
772 * WELLKNOWN, UNIQUE, "" → KDBUS_ITEM_NAME_REMOVE
773 * WELLKNOWN, UNIQUE, UNIQUE → KDBUS_ITEM_NAME_CHANGE
774 * UNIQUE, "", UNIQUE → KDBUS_ITEM_ID_ADD
775 * UNIQUE, UNIQUE, "" → KDBUS_ITEM_ID_REMOVE
777 * For the latter two the two unique names must be identical.
782 is_name_id = bus_kernel_parse_unique_name(name, &name_id);
787 if (!isempty(old_owner)) {
788 r = bus_kernel_parse_unique_name(old_owner, &old_owner_id);
793 if (is_name_id > 0 && old_owner_id != name_id)
796 old_owner_id = KDBUS_MATCH_ID_ANY;
798 if (!isempty(new_owner)) {
799 r = bus_kernel_parse_unique_name(new_owner, &new_owner_id);
804 if (is_name_id > 0 && new_owner_id != name_id)
807 new_owner_id = KDBUS_MATCH_ID_ANY;
809 if (is_name_id <= 0) {
810 struct kdbus_cmd_match *m;
813 /* If the name argument is missing or is a well-known
814 * name, then add KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE}
817 l = name ? strlen(name) + 1 : 0;
819 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
820 offsetof(struct kdbus_item, name_change) +
821 offsetof(struct kdbus_notify_name_change, name) +
830 offsetof(struct kdbus_item, name_change) +
831 offsetof(struct kdbus_notify_name_change, name) +
834 item->name_change.old.id = old_owner_id;
835 item->name_change.new.id = new_owner_id;
838 memcpy(item->name_change.name, name, l);
840 /* If the old name is unset or empty, then
841 * this can match against added names */
842 if (!old_owner || old_owner[0] == 0) {
843 item->type = KDBUS_ITEM_NAME_ADD;
845 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
850 /* If the new name is unset or empty, then
851 * this can match against removed names */
852 if (!new_owner || new_owner[0] == 0) {
853 item->type = KDBUS_ITEM_NAME_REMOVE;
855 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
860 /* The CHANGE match we need in either case, because
861 * what is reported as a name change by the kernel
862 * might just be an owner change between starter and
863 * normal clients. For userspace such a change should
864 * be considered a removal/addition, hence let's
865 * subscribe to this unconditionally. */
866 item->type = KDBUS_ITEM_NAME_CHANGE;
867 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
872 if (is_name_id != 0) {
873 struct kdbus_cmd_match *m;
876 /* If the name argument is missing or is a unique
877 * name, then add KDBUS_ITEM_ID_{ADD,REMOVE} matches
880 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
881 offsetof(struct kdbus_item, id_change) +
882 sizeof(struct kdbus_notify_id_change));
890 offsetof(struct kdbus_item, id_change) +
891 sizeof(struct kdbus_notify_id_change);
892 item->id_change.id = name_id;
894 /* If the old name is unset or empty, then this can
895 * match against added ids */
896 if (!old_owner || old_owner[0] == 0) {
897 item->type = KDBUS_ITEM_ID_ADD;
899 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
904 /* If thew new name is unset or empty, then this can
905 * match against removed ids */
906 if (!new_owner || new_owner[0] == 0) {
907 item->type = KDBUS_ITEM_ID_REMOVE;
909 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
918 int bus_add_match_internal_kernel(
921 struct bus_match_component *components,
922 unsigned n_components,
925 struct kdbus_cmd_match *m;
926 struct kdbus_item *item;
929 const char *sender = NULL;
930 size_t sender_length = 0;
931 uint64_t src_id = KDBUS_MATCH_ID_ANY;
932 bool using_bloom = false;
934 bool matches_name_change = true;
935 const char *name_change_arg[3] = {};
940 bloom = alloca0(bus->bloom_size);
942 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items));
944 for (i = 0; i < n_components; i++) {
945 struct bus_match_component *c = &components[i];
949 case BUS_MATCH_SENDER:
950 if (!streq(c->value_str, "org.freedesktop.DBus"))
951 matches_name_change = false;
953 r = bus_kernel_parse_unique_name(c->value_str, &src_id);
957 sz += ALIGN8(offsetof(struct kdbus_item, id) + sizeof(uint64_t));
959 sender = c->value_str;
960 sender_length = strlen(sender);
961 sz += ALIGN8(offsetof(struct kdbus_item, str) + sender_length + 1);
966 case BUS_MATCH_MESSAGE_TYPE:
967 if (c->value_u8 != SD_BUS_MESSAGE_SIGNAL)
968 matches_name_change = false;
970 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "message-type", bus_message_type_to_string(c->value_u8));
974 case BUS_MATCH_INTERFACE:
975 if (!streq(c->value_str, "org.freedesktop.DBus"))
976 matches_name_change = false;
978 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "interface", c->value_str);
982 case BUS_MATCH_MEMBER:
983 if (!streq(c->value_str, "NameOwnerChanged"))
984 matches_name_change = false;
986 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "member", c->value_str);
991 if (!streq(c->value_str, "/org/freedesktop/DBus"))
992 matches_name_change = false;
994 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path", c->value_str);
998 case BUS_MATCH_PATH_NAMESPACE:
999 if (!streq(c->value_str, "/")) {
1000 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path-slash-prefix", c->value_str);
1005 case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: {
1006 char buf[sizeof("arg")-1 + 2 + 1];
1008 if (c->type - BUS_MATCH_ARG < 3)
1009 name_change_arg[c->type - BUS_MATCH_ARG] = c->value_str;
1011 snprintf(buf, sizeof(buf), "arg%u", c->type - BUS_MATCH_ARG);
1012 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1017 case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: {
1018 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
1020 snprintf(buf, sizeof(buf), "arg%u-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
1021 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1026 case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: {
1027 char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")];
1029 snprintf(buf, sizeof(buf), "arg%u-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE);
1030 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1035 case BUS_MATCH_DESTINATION:
1036 /* The bloom filter does not include
1037 the destination, since it is only
1038 available for broadcast messages
1039 which do not carry a destination
1040 since they are undirected. */
1043 case BUS_MATCH_ROOT:
1044 case BUS_MATCH_VALUE:
1045 case BUS_MATCH_LEAF:
1046 case _BUS_MATCH_NODE_TYPE_MAX:
1047 case _BUS_MATCH_NODE_TYPE_INVALID:
1048 assert_not_reached("Invalid match type?");
1053 sz += ALIGN8(offsetof(struct kdbus_item, data64) + bus->bloom_size);
1062 if (src_id != KDBUS_MATCH_ID_ANY) {
1063 item->size = offsetof(struct kdbus_item, id) + sizeof(uint64_t);
1064 item->type = KDBUS_ITEM_ID;
1066 item = KDBUS_ITEM_NEXT(item);
1070 item->size = offsetof(struct kdbus_item, data64) + bus->bloom_size;
1071 item->type = KDBUS_ITEM_BLOOM_MASK;
1072 memcpy(item->data64, bloom, bus->bloom_size);
1073 item = KDBUS_ITEM_NEXT(item);
1077 item->size = offsetof(struct kdbus_item, str) + sender_length + 1;
1078 item->type = KDBUS_ITEM_NAME;
1079 memcpy(item->str, sender, sender_length + 1);
1082 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1086 if (matches_name_change) {
1088 /* If this match could theoretically match
1089 * NameOwnerChanged messages, we need to
1090 * install a second non-bloom filter explitly
1093 r = add_name_change_match(bus, cookie, name_change_arg[0], name_change_arg[1], name_change_arg[2]);
1101 static int bus_add_match_internal_dbus1(
1103 const char *match) {
1108 return sd_bus_call_method(
1110 "org.freedesktop.DBus",
1111 "/org/freedesktop/DBus",
1112 "org.freedesktop.DBus",
1120 int bus_add_match_internal(
1123 struct bus_match_component *components,
1124 unsigned n_components,
1131 return bus_add_match_internal_kernel(bus, 0, components, n_components, cookie);
1133 return bus_add_match_internal_dbus1(bus, match);
1136 int bus_remove_match_internal_kernel(
1141 struct kdbus_cmd_match m;
1147 m.size = offsetof(struct kdbus_cmd_match, items);
1151 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_REMOVE, &m);
1158 static int bus_remove_match_internal_dbus1(
1160 const char *match) {
1165 return sd_bus_call_method(
1167 "org.freedesktop.DBus",
1168 "/org/freedesktop/DBus",
1169 "org.freedesktop.DBus",
1177 int bus_remove_match_internal(
1186 return bus_remove_match_internal_kernel(bus, 0, cookie);
1188 return bus_remove_match_internal_dbus1(bus, match);
1191 _public_ int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) {
1192 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
1196 assert_return(bus, -EINVAL);
1197 assert_return(name, -EINVAL);
1198 assert_return(machine, -EINVAL);
1199 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1200 assert_return(!bus_pid_changed(bus), -ECHILD);
1201 assert_return(service_name_is_valid(name), -EINVAL);
1203 if (streq_ptr(name, bus->unique_name))
1204 return sd_id128_get_machine(machine);
1206 r = sd_bus_message_new_method_call(
1211 "org.freedesktop.DBus.Peer",
1216 r = sd_bus_message_set_auto_start(m, false);
1220 r = sd_bus_call(bus, m, 0, NULL, &reply);
1224 r = sd_bus_message_read(reply, "s", &mid);
1228 return sd_id128_from_string(mid, machine);