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 : -ENOENT;
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 if (!bus->cgroup_root) {
499 r = cg_get_root_path(&bus->cgroup_root);
504 c->cgroup_root = strdup(bus->cgroup_root);
505 if (!c->cgroup_root) {
514 case KDBUS_ITEM_CAPS:
515 m = (SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_PERMITTED_CAPS |
516 SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_BOUNDING_CAPS) & mask;
519 c->capability_size = item->size - KDBUS_ITEM_HEADER_SIZE;
520 c->capability = memdup(item->data, c->capability_size);
521 if (!c->capability) {
530 case KDBUS_ITEM_SECLABEL:
531 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
532 c->label = strdup(item->str);
538 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
542 case KDBUS_ITEM_AUDIT:
543 m = (SD_BUS_CREDS_AUDIT_SESSION_ID | SD_BUS_CREDS_AUDIT_LOGIN_UID) & mask;
546 c->audit_session_id = item->audit.sessionid;
547 c->audit_login_uid = item->audit.loginuid;
552 case KDBUS_ITEM_NAME:
553 if ((mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) && service_name_is_valid(item->name.name)) {
554 r = strv_extend(&c->well_known_names, item->name.name);
558 c->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
562 case KDBUS_ITEM_CONN_NAME:
563 if ((mask & SD_BUS_CREDS_CONNECTION_NAME)) {
564 c->conn_name = strdup(item->str);
570 c->mask |= SD_BUS_CREDS_CONNECTION_NAME;
584 ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd->offset);
588 static int bus_get_owner_dbus1(
592 sd_bus_creds **creds) {
594 _cleanup_bus_message_unref_ sd_bus_message *reply_unique = NULL, *reply = NULL;
595 _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
596 const char *unique = NULL;
600 /* Only query the owner if the caller wants to know it or if
601 * the caller just wants to check whether a name exists */
602 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) || mask == 0) {
603 r = sd_bus_call_method(
605 "org.freedesktop.DBus",
606 "/org/freedesktop/DBus",
607 "org.freedesktop.DBus",
616 r = sd_bus_message_read(reply_unique, "s", &unique);
626 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) && unique) {
627 c->unique_name = strdup(unique);
631 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
634 if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_GID|
635 SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
636 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|
637 SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
638 SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)) {
641 r = sd_bus_call_method(
643 "org.freedesktop.DBus",
644 "/org/freedesktop/DBus",
645 "org.freedesktop.DBus",
646 "GetConnectionUnixProcessID",
650 unique ? unique : name);
654 r = sd_bus_message_read(reply, "u", &u);
659 if (mask & SD_BUS_CREDS_PID) {
661 c->mask |= SD_BUS_CREDS_PID;
664 reply = sd_bus_message_unref(reply);
667 if (mask & SD_BUS_CREDS_UID) {
670 r = sd_bus_call_method(
672 "org.freedesktop.DBus",
673 "/org/freedesktop/DBus",
674 "org.freedesktop.DBus",
675 "GetConnectionUnixUser",
679 unique ? unique : name);
683 r = sd_bus_message_read(reply, "u", &u);
688 c->mask |= SD_BUS_CREDS_UID;
690 reply = sd_bus_message_unref(reply);
693 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
694 const void *p = NULL;
697 r = sd_bus_call_method(
699 "org.freedesktop.DBus",
700 "/org/freedesktop/DBus",
701 "org.freedesktop.DBus",
702 "GetConnectionSELinuxSecurityContext",
706 unique ? unique : name);
710 r = sd_bus_message_read_array(reply, 'y', &p, &sz);
714 c->label = strndup(p, sz);
718 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
721 r = bus_creds_add_more(c, mask, pid, 0);
734 _public_ int sd_bus_get_owner(
738 sd_bus_creds **creds) {
740 assert_return(bus, -EINVAL);
741 assert_return(name, -EINVAL);
742 assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
743 assert_return(mask == 0 || creds, -EINVAL);
744 assert_return(!bus_pid_changed(bus), -ECHILD);
745 assert_return(service_name_is_valid(name), -EINVAL);
746 assert_return(bus->bus_client, -ENODATA);
748 if (!BUS_IS_OPEN(bus->state))
752 return bus_get_owner_kdbus(bus, name, mask, creds);
754 return bus_get_owner_dbus1(bus, name, mask, creds);
757 static int add_name_change_match(sd_bus *bus,
760 const char *old_owner,
761 const char *new_owner) {
763 uint64_t name_id = KDBUS_MATCH_ID_ANY, old_owner_id = 0, new_owner_id = 0;
764 int is_name_id = -1, r;
765 struct kdbus_item *item;
769 /* If we encounter a match that could match against
770 * NameOwnerChanged messages, then we need to create
771 * KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE} and
772 * KDBUS_ITEM_ID_{ADD,REMOVE} matches for it, possibly
773 * multiple if the match is underspecified.
775 * The NameOwnerChanged signals take three parameters with
776 * unique or well-known names, but only some forms actually
779 * WELLKNOWN, "", UNIQUE → KDBUS_ITEM_NAME_ADD
780 * WELLKNOWN, UNIQUE, "" → KDBUS_ITEM_NAME_REMOVE
781 * WELLKNOWN, UNIQUE, UNIQUE → KDBUS_ITEM_NAME_CHANGE
782 * UNIQUE, "", UNIQUE → KDBUS_ITEM_ID_ADD
783 * UNIQUE, UNIQUE, "" → KDBUS_ITEM_ID_REMOVE
785 * For the latter two the two unique names must be identical.
790 is_name_id = bus_kernel_parse_unique_name(name, &name_id);
795 if (!isempty(old_owner)) {
796 r = bus_kernel_parse_unique_name(old_owner, &old_owner_id);
801 if (is_name_id > 0 && old_owner_id != name_id)
804 old_owner_id = KDBUS_MATCH_ID_ANY;
806 if (!isempty(new_owner)) {
807 r = bus_kernel_parse_unique_name(new_owner, &new_owner_id);
812 if (is_name_id > 0 && new_owner_id != name_id)
815 new_owner_id = KDBUS_MATCH_ID_ANY;
817 if (is_name_id <= 0) {
818 struct kdbus_cmd_match *m;
821 /* If the name argument is missing or is a well-known
822 * name, then add KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE}
825 l = name ? strlen(name) + 1 : 0;
827 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
828 offsetof(struct kdbus_item, name_change) +
829 offsetof(struct kdbus_notify_name_change, name) +
838 offsetof(struct kdbus_item, name_change) +
839 offsetof(struct kdbus_notify_name_change, name) +
842 item->name_change.old.id = old_owner_id;
843 item->name_change.new.id = new_owner_id;
846 memcpy(item->name_change.name, name, l);
848 /* If the old name is unset or empty, then
849 * this can match against added names */
850 if (!old_owner || old_owner[0] == 0) {
851 item->type = KDBUS_ITEM_NAME_ADD;
853 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
858 /* If the new name is unset or empty, then
859 * this can match against removed names */
860 if (!new_owner || new_owner[0] == 0) {
861 item->type = KDBUS_ITEM_NAME_REMOVE;
863 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
868 /* The CHANGE match we need in either case, because
869 * what is reported as a name change by the kernel
870 * might just be an owner change between starter and
871 * normal clients. For userspace such a change should
872 * be considered a removal/addition, hence let's
873 * subscribe to this unconditionally. */
874 item->type = KDBUS_ITEM_NAME_CHANGE;
875 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
880 if (is_name_id != 0) {
881 struct kdbus_cmd_match *m;
884 /* If the name argument is missing or is a unique
885 * name, then add KDBUS_ITEM_ID_{ADD,REMOVE} matches
888 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
889 offsetof(struct kdbus_item, id_change) +
890 sizeof(struct kdbus_notify_id_change));
898 offsetof(struct kdbus_item, id_change) +
899 sizeof(struct kdbus_notify_id_change);
900 item->id_change.id = name_id;
902 /* If the old name is unset or empty, then this can
903 * match against added ids */
904 if (!old_owner || old_owner[0] == 0) {
905 item->type = KDBUS_ITEM_ID_ADD;
907 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
912 /* If thew new name is unset or empty, then this can
913 * match against removed ids */
914 if (!new_owner || new_owner[0] == 0) {
915 item->type = KDBUS_ITEM_ID_REMOVE;
917 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
926 int bus_add_match_internal_kernel(
929 struct bus_match_component *components,
930 unsigned n_components,
933 struct kdbus_cmd_match *m;
934 struct kdbus_item *item;
937 const char *sender = NULL;
938 size_t sender_length = 0;
939 uint64_t src_id = KDBUS_MATCH_ID_ANY;
940 bool using_bloom = false;
942 bool matches_name_change = true;
943 const char *name_change_arg[3] = {};
948 bloom = alloca0(bus->bloom_size);
950 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items));
952 for (i = 0; i < n_components; i++) {
953 struct bus_match_component *c = &components[i];
957 case BUS_MATCH_SENDER:
958 if (!streq(c->value_str, "org.freedesktop.DBus"))
959 matches_name_change = false;
961 r = bus_kernel_parse_unique_name(c->value_str, &src_id);
965 sz += ALIGN8(offsetof(struct kdbus_item, id) + sizeof(uint64_t));
967 sender = c->value_str;
968 sender_length = strlen(sender);
969 sz += ALIGN8(offsetof(struct kdbus_item, str) + sender_length + 1);
974 case BUS_MATCH_MESSAGE_TYPE:
975 if (c->value_u8 != SD_BUS_MESSAGE_SIGNAL)
976 matches_name_change = false;
978 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "message-type", bus_message_type_to_string(c->value_u8));
982 case BUS_MATCH_INTERFACE:
983 if (!streq(c->value_str, "org.freedesktop.DBus"))
984 matches_name_change = false;
986 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "interface", c->value_str);
990 case BUS_MATCH_MEMBER:
991 if (!streq(c->value_str, "NameOwnerChanged"))
992 matches_name_change = false;
994 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "member", c->value_str);
999 if (!streq(c->value_str, "/org/freedesktop/DBus"))
1000 matches_name_change = false;
1002 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path", c->value_str);
1006 case BUS_MATCH_PATH_NAMESPACE:
1007 if (!streq(c->value_str, "/")) {
1008 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, "path-slash-prefix", c->value_str);
1013 case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: {
1014 char buf[sizeof("arg")-1 + 2 + 1];
1016 if (c->type - BUS_MATCH_ARG < 3)
1017 name_change_arg[c->type - BUS_MATCH_ARG] = c->value_str;
1019 snprintf(buf, sizeof(buf), "arg%u", c->type - BUS_MATCH_ARG);
1020 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1025 case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: {
1026 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
1028 snprintf(buf, sizeof(buf), "arg%u-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
1029 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1034 case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: {
1035 char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")];
1037 snprintf(buf, sizeof(buf), "arg%u-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE);
1038 bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
1043 case BUS_MATCH_DESTINATION:
1044 /* The bloom filter does not include
1045 the destination, since it is only
1046 available for broadcast messages
1047 which do not carry a destination
1048 since they are undirected. */
1051 case BUS_MATCH_ROOT:
1052 case BUS_MATCH_VALUE:
1053 case BUS_MATCH_LEAF:
1054 case _BUS_MATCH_NODE_TYPE_MAX:
1055 case _BUS_MATCH_NODE_TYPE_INVALID:
1056 assert_not_reached("Invalid match type?");
1061 sz += ALIGN8(offsetof(struct kdbus_item, data64) + bus->bloom_size);
1070 if (src_id != KDBUS_MATCH_ID_ANY) {
1071 item->size = offsetof(struct kdbus_item, id) + sizeof(uint64_t);
1072 item->type = KDBUS_ITEM_ID;
1074 item = KDBUS_ITEM_NEXT(item);
1078 item->size = offsetof(struct kdbus_item, data64) + bus->bloom_size;
1079 item->type = KDBUS_ITEM_BLOOM_MASK;
1080 memcpy(item->data64, bloom, bus->bloom_size);
1081 item = KDBUS_ITEM_NEXT(item);
1085 item->size = offsetof(struct kdbus_item, str) + sender_length + 1;
1086 item->type = KDBUS_ITEM_NAME;
1087 memcpy(item->str, sender, sender_length + 1);
1090 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1094 if (matches_name_change) {
1096 /* If this match could theoretically match
1097 * NameOwnerChanged messages, we need to
1098 * install a second non-bloom filter explitly
1101 r = add_name_change_match(bus, cookie, name_change_arg[0], name_change_arg[1], name_change_arg[2]);
1109 #define internal_match(bus, m) \
1110 ((bus)->hello_flags & KDBUS_HELLO_MONITOR \
1111 ? (isempty(m) ? "eavesdrop='true'" : strappenda((m), ",eavesdrop='true'")) \
1114 static int bus_add_match_internal_dbus1(
1116 const char *match) {
1123 e = internal_match(bus, match);
1125 return sd_bus_call_method(
1127 "org.freedesktop.DBus",
1128 "/org/freedesktop/DBus",
1129 "org.freedesktop.DBus",
1137 int bus_add_match_internal(
1140 struct bus_match_component *components,
1141 unsigned n_components,
1148 return bus_add_match_internal_kernel(bus, 0, components, n_components, cookie);
1150 return bus_add_match_internal_dbus1(bus, match);
1153 int bus_remove_match_internal_kernel(
1158 struct kdbus_cmd_match m;
1164 m.size = offsetof(struct kdbus_cmd_match, items);
1168 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_REMOVE, &m);
1175 static int bus_remove_match_internal_dbus1(
1177 const char *match) {
1184 e = internal_match(bus, match);
1186 return sd_bus_call_method(
1188 "org.freedesktop.DBus",
1189 "/org/freedesktop/DBus",
1190 "org.freedesktop.DBus",
1198 int bus_remove_match_internal(
1207 return bus_remove_match_internal_kernel(bus, 0, cookie);
1209 return bus_remove_match_internal_dbus1(bus, match);
1212 _public_ int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) {
1213 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
1217 assert_return(bus, -EINVAL);
1218 assert_return(name, -EINVAL);
1219 assert_return(machine, -EINVAL);
1220 assert_return(!bus_pid_changed(bus), -ECHILD);
1221 assert_return(service_name_is_valid(name), -EINVAL);
1223 if (!BUS_IS_OPEN(bus->state))
1226 if (streq_ptr(name, bus->unique_name))
1227 return sd_id128_get_machine(machine);
1229 r = sd_bus_message_new_method_call(
1234 "org.freedesktop.DBus.Peer",
1239 r = sd_bus_message_set_auto_start(m, false);
1243 r = sd_bus_call(bus, m, 0, NULL, &reply);
1247 r = sd_bus_message_read(reply, "s", &mid);
1251 return sd_id128_from_string(mid, machine);