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 size = offsetof(struct kdbus_cmd_name, name) + l + 1;
64 kdbus_translate_request_name_flags(flags, (uint64_t *) &n->flags);
65 memcpy(n->name, name, l+1);
67 #ifdef HAVE_VALGRIND_MEMCHECK_H
68 VALGRIND_MAKE_MEM_DEFINED(n, n->size);
71 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_ACQUIRE, n);
75 if (n->flags & KDBUS_NAME_IN_QUEUE)
81 static int bus_request_name_dbus1(sd_bus *bus, const char *name, uint64_t flags) {
82 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
83 uint32_t ret, param = 0;
89 if (flags & SD_BUS_NAME_ALLOW_REPLACEMENT)
90 param |= BUS_NAME_ALLOW_REPLACEMENT;
91 if (flags & SD_BUS_NAME_REPLACE_EXISTING)
92 param |= BUS_NAME_REPLACE_EXISTING;
93 if (!(flags & SD_BUS_NAME_QUEUE))
94 param |= BUS_NAME_DO_NOT_QUEUE;
96 r = sd_bus_call_method(
98 "org.freedesktop.DBus",
99 "/org/freedesktop/DBus",
100 "org.freedesktop.DBus",
110 r = sd_bus_message_read(reply, "u", &ret);
114 if (ret == BUS_NAME_ALREADY_OWNER)
116 else if (ret == BUS_NAME_EXISTS)
118 else if (ret == BUS_NAME_IN_QUEUE)
120 else if (ret == BUS_NAME_PRIMARY_OWNER)
126 _public_ int sd_bus_request_name(sd_bus *bus, const char *name, uint64_t flags) {
127 assert_return(bus, -EINVAL);
128 assert_return(name, -EINVAL);
129 assert_return(bus->bus_client, -EINVAL);
130 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
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);
137 return bus_request_name_kernel(bus, name, flags);
139 return bus_request_name_dbus1(bus, name, flags);
142 static int bus_release_name_kernel(sd_bus *bus, const char *name) {
143 struct kdbus_cmd_name *n;
151 n = alloca0(offsetof(struct kdbus_cmd_name, name) + l + 1);
152 n->size = offsetof(struct kdbus_cmd_name, name) + l + 1;
153 memcpy(n->name, name, l+1);
155 #ifdef HAVE_VALGRIND_MEMCHECK_H
156 VALGRIND_MAKE_MEM_DEFINED(n, n->size);
158 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_RELEASE, n);
165 static int bus_release_name_dbus1(sd_bus *bus, const char *name) {
166 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
173 r = sd_bus_call_method(
175 "org.freedesktop.DBus",
176 "/org/freedesktop/DBus",
177 "org.freedesktop.DBus",
186 r = sd_bus_message_read(reply, "u", &ret);
189 if (ret == BUS_NAME_NON_EXISTENT)
191 if (ret == BUS_NAME_NOT_OWNER)
193 if (ret == BUS_NAME_RELEASED)
199 _public_ int sd_bus_release_name(sd_bus *bus, const char *name) {
200 assert_return(bus, -EINVAL);
201 assert_return(name, -EINVAL);
202 assert_return(bus->bus_client, -EINVAL);
203 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
204 assert_return(!bus_pid_changed(bus), -ECHILD);
205 assert_return(service_name_is_valid(name), -EINVAL);
206 assert_return(name[0] != ':', -EINVAL);
209 return bus_release_name_kernel(bus, name);
211 return bus_release_name_dbus1(bus, name);
214 static int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) {
215 struct kdbus_cmd_name_list cmd = {};
216 struct kdbus_name_list *name_list;
217 struct kdbus_cmd_name *name;
218 uint64_t previous_id = 0;
221 /* Caller will free half-constructed list on failure... */
225 r = ioctl(bus->input_fd, KDBUS_CMD_NAME_LIST, &cmd);
229 name_list = (struct kdbus_name_list *) ((uint8_t *) bus->kdbus_buffer + cmd.offset);
231 KDBUS_ITEM_FOREACH(name, name_list, names) {
233 if ((flags & KDBUS_NAME_LIST_UNIQUE) && name->owner_id != previous_id) {
236 if (asprintf(&n, ":1.%llu", (unsigned long long) name->owner_id) < 0)
245 previous_id = name->owner_id;
248 if (name->size > sizeof(*name) && service_name_is_valid(name->name)) {
249 r = strv_extend(x, name->name);
255 r = ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd.offset);
262 static int bus_list_names_kernel(sd_bus *bus, char ***acquired, char ***activatable) {
263 _cleanup_strv_free_ char **x = NULL, **y = NULL;
267 r = kernel_get_list(bus, KDBUS_NAME_LIST_UNIQUE | KDBUS_NAME_LIST_NAMES, &x);
273 r = kernel_get_list(bus, KDBUS_NAME_LIST_ACTIVATORS, &y);
289 static int bus_list_names_dbus1(sd_bus *bus, char ***acquired, char ***activatable) {
290 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
291 _cleanup_strv_free_ char **x = NULL, **y = NULL;
295 r = sd_bus_call_method(
297 "org.freedesktop.DBus",
298 "/org/freedesktop/DBus",
299 "org.freedesktop.DBus",
307 r = sd_bus_message_read_strv(reply, &x);
311 reply = sd_bus_message_unref(reply);
315 r = sd_bus_call_method(
317 "org.freedesktop.DBus",
318 "/org/freedesktop/DBus",
319 "org.freedesktop.DBus",
320 "ListActivatableNames",
327 r = sd_bus_message_read_strv(reply, &y);
343 _public_ int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable) {
344 assert_return(bus, -EINVAL);
345 assert_return(acquired || activatable, -EINVAL);
346 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
347 assert_return(!bus_pid_changed(bus), -ECHILD);
350 return bus_list_names_kernel(bus, acquired, activatable);
352 return bus_list_names_dbus1(bus, acquired, activatable);
355 static int bus_get_owner_kdbus(
359 sd_bus_creds **creds) {
361 _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
362 struct kdbus_cmd_conn_info *cmd;
363 struct kdbus_conn_info *conn_info;
364 struct kdbus_item *item;
369 r = bus_kernel_parse_unique_name(name, &id);
373 size = offsetof(struct kdbus_cmd_conn_info, name);
377 size = offsetof(struct kdbus_cmd_conn_info, name) + strlen(name) + 1;
379 strcpy(cmd->name, name);
381 cmd->flags = KDBUS_ATTACH_NAMES;
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 |
411 SD_BUS_CREDS_TID | SD_BUS_CREDS_PID_STARTTIME) & mask;
414 c->uid = item->creds.uid;
415 c->pid = item->creds.pid;
416 c->gid = item->creds.gid;
417 c->tid = item->creds.tid;
418 c->pid_starttime = item->creds.starttime;
423 case KDBUS_ITEM_PID_COMM:
424 if (mask & SD_BUS_CREDS_COMM) {
425 c->comm = strdup(item->str);
431 c->mask |= SD_BUS_CREDS_COMM;
435 case KDBUS_ITEM_TID_COMM:
436 if (mask & SD_BUS_CREDS_TID_COMM) {
437 c->tid_comm = strdup(item->str);
443 c->mask |= SD_BUS_CREDS_TID_COMM;
448 if (mask & SD_BUS_CREDS_EXE) {
449 c->exe = strdup(item->str);
455 c->mask |= SD_BUS_CREDS_EXE;
459 case KDBUS_ITEM_CMDLINE:
460 if (mask & SD_BUS_CREDS_CMDLINE) {
461 c->cmdline_size = item->size - KDBUS_ITEM_HEADER_SIZE;
462 c->cmdline = memdup(item->data, c->cmdline_size);
468 c->mask |= SD_BUS_CREDS_CMDLINE;
472 case KDBUS_ITEM_CGROUP:
473 m = (SD_BUS_CREDS_CGROUP | SD_BUS_CREDS_UNIT |
474 SD_BUS_CREDS_USER_UNIT | SD_BUS_CREDS_SLICE |
475 SD_BUS_CREDS_SESSION | SD_BUS_CREDS_OWNER_UID) & mask;
478 c->cgroup = strdup(item->str);
488 case KDBUS_ITEM_CAPS:
489 m = (SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_PERMITTED_CAPS |
490 SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_BOUNDING_CAPS) & mask;
493 c->capability_size = item->size - KDBUS_ITEM_HEADER_SIZE;
494 c->capability = memdup(item->data, c->capability_size);
495 if (!c->capability) {
504 case KDBUS_ITEM_SECLABEL:
505 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
506 c->label = strdup(item->str);
512 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
516 case KDBUS_ITEM_AUDIT:
517 m = (SD_BUS_CREDS_AUDIT_SESSION_ID | SD_BUS_CREDS_AUDIT_LOGIN_UID) & mask;
520 c->audit_session_id = item->audit.sessionid;
521 c->audit_login_uid = item->audit.loginuid;
526 case KDBUS_ITEM_NAME:
527 if ((mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) && service_name_is_valid(item->name.name)) {
528 r = strv_extend(&c->well_known_names, item->name.name);
532 c->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
546 ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd->offset);
550 static int bus_get_owner_dbus1(
554 sd_bus_creds **creds) {
556 _cleanup_bus_message_unref_ sd_bus_message *reply_unique = NULL, *reply = NULL;
557 _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
558 const char *unique = NULL;
562 /* Only query the owner if the caller wants to know it or if
563 * the caller just wants to check whether a name exists */
564 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) || mask == 0) {
565 r = sd_bus_call_method(
567 "org.freedesktop.DBus",
568 "/org/freedesktop/DBus",
569 "org.freedesktop.DBus",
578 r = sd_bus_message_read(reply_unique, "s", &unique);
588 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) && unique) {
589 c->unique_name = strdup(unique);
593 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
596 if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_GID|
597 SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
598 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|
599 SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
600 SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)) {
603 r = sd_bus_call_method(
605 "org.freedesktop.DBus",
606 "/org/freedesktop/DBus",
607 "org.freedesktop.DBus",
608 "GetConnectionUnixProcessID",
612 unique ? unique : name);
616 r = sd_bus_message_read(reply, "u", &u);
621 if (mask & SD_BUS_CREDS_PID) {
623 c->mask |= SD_BUS_CREDS_PID;
626 reply = sd_bus_message_unref(reply);
629 if (mask & SD_BUS_CREDS_UID) {
632 r = sd_bus_call_method(
634 "org.freedesktop.DBus",
635 "/org/freedesktop/DBus",
636 "org.freedesktop.DBus",
637 "GetConnectionUnixUser",
641 unique ? unique : name);
645 r = sd_bus_message_read(reply, "u", &u);
650 c->mask |= SD_BUS_CREDS_UID;
652 reply = sd_bus_message_unref(reply);
655 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
659 r = sd_bus_call_method(
661 "org.freedesktop.DBus",
662 "/org/freedesktop/DBus",
663 "org.freedesktop.DBus",
664 "GetConnectionSELinuxSecurityContext",
668 unique ? unique : name);
672 r = sd_bus_message_read_array(reply, 'y', &p, &sz);
676 c->label = strndup(p, sz);
680 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
683 r = bus_creds_add_more(c, mask, pid, 0);
696 _public_ int sd_bus_get_owner(
700 sd_bus_creds **creds) {
702 assert_return(bus, -EINVAL);
703 assert_return(name, -EINVAL);
704 assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
705 assert_return(mask == 0 || creds, -EINVAL);
706 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
707 assert_return(!bus_pid_changed(bus), -ECHILD);
708 assert_return(service_name_is_valid(name), -EINVAL);
709 assert_return(bus->bus_client, -ENODATA);
712 return bus_get_owner_kdbus(bus, name, mask, creds);
714 return bus_get_owner_dbus1(bus, name, mask, creds);
717 static int add_name_change_match(sd_bus *bus,
720 const char *old_owner,
721 const char *new_owner) {
723 uint64_t name_id = KDBUS_MATCH_ID_ANY, old_owner_id = 0, new_owner_id = 0;
724 int is_name_id = -1, r;
725 struct kdbus_item *item;
729 /* If we encounter a match that could match against
730 * NameOwnerChanged messages, then we need to create
731 * KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE} and
732 * KDBUS_ITEM_ID_{ADD,REMOVE} matches for it, possibly
733 * multiple if the match is underspecified.
735 * The NameOwnerChanged signals take three parameters with
736 * unique or well-known names, but only some forms actually
739 * WELLKNOWN, "", UNIQUE → KDBUS_ITEM_NAME_ADD
740 * WELLKNOWN, UNIQUE, "" → KDBUS_ITEM_NAME_REMOVE
741 * WELLKNOWN, UNIQUE, UNIQUE → KDBUS_ITEM_NAME_CHANGE
742 * UNIQUE, "", UNIQUE → KDBUS_ITEM_ID_ADD
743 * UNIQUE, UNIQUE, "" → KDBUS_ITEM_ID_REMOVE
745 * For the latter two the two unique names must be identical.
750 is_name_id = bus_kernel_parse_unique_name(name, &name_id);
755 if (!isempty(old_owner)) {
756 r = bus_kernel_parse_unique_name(old_owner, &old_owner_id);
761 if (is_name_id > 0 && old_owner_id != name_id)
764 old_owner_id = KDBUS_MATCH_ID_ANY;
766 if (!isempty(new_owner)) {
767 r = bus_kernel_parse_unique_name(new_owner, &new_owner_id);
772 if (is_name_id > 0 && new_owner_id != name_id)
775 new_owner_id = KDBUS_MATCH_ID_ANY;
777 if (is_name_id <= 0) {
778 struct kdbus_cmd_match *m;
781 /* If the name argument is missing or is a well-known
782 * name, then add KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE}
785 l = name ? strlen(name) + 1 : 0;
787 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
788 offsetof(struct kdbus_item, name_change) +
789 offsetof(struct kdbus_notify_name_change, name) +
798 offsetof(struct kdbus_item, name_change) +
799 offsetof(struct kdbus_notify_name_change, name) +
802 item->name_change.old.id = old_owner_id;
803 item->name_change.new.id = new_owner_id;
806 memcpy(item->name_change.name, name, l);
808 /* If the old name is unset or empty, then
809 * this can match against added names */
810 if (!old_owner || old_owner[0] == 0) {
811 item->type = KDBUS_ITEM_NAME_ADD;
813 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
818 /* If the new name is unset or empty, then
819 * this can match against removed names */
820 if (!new_owner || new_owner[0] == 0) {
821 item->type = KDBUS_ITEM_NAME_REMOVE;
823 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
828 /* The CHANGE match we need in either case, because
829 * what is reported as a name change by the kernel
830 * might just be an owner change between starter and
831 * normal clients. For userspace such a change should
832 * be considered a removal/addition, hence let's
833 * subscribe to this unconditionally. */
834 item->type = KDBUS_ITEM_NAME_CHANGE;
835 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
840 if (is_name_id != 0) {
841 struct kdbus_cmd_match *m;
844 /* If the name argument is missing or is a unique
845 * name, then add KDBUS_ITEM_ID_{ADD,REMOVE} matches
848 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
849 offsetof(struct kdbus_item, id_change) +
850 sizeof(struct kdbus_notify_id_change));
858 offsetof(struct kdbus_item, id_change) +
859 sizeof(struct kdbus_notify_id_change);
860 item->id_change.id = name_id;
862 /* If the old name is unset or empty, then this can
863 * match against added ids */
864 if (!old_owner || old_owner[0] == 0) {
865 item->type = KDBUS_ITEM_ID_ADD;
867 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
872 /* If thew new name is unset or empty, then this can
873 * match against removed ids */
874 if (!new_owner || new_owner[0] == 0) {
875 item->type = KDBUS_ITEM_ID_REMOVE;
877 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
886 int bus_add_match_internal_kernel(
889 struct bus_match_component *components,
890 unsigned n_components,
893 struct kdbus_cmd_match *m;
894 struct kdbus_item *item;
895 uint64_t bloom[BLOOM_SIZE/8];
897 const char *sender = NULL;
898 size_t sender_length = 0;
899 uint64_t src_id = KDBUS_MATCH_ID_ANY;
900 bool using_bloom = false;
902 bool matches_name_change = true;
903 const char *name_change_arg[3] = {};
910 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items));
912 for (i = 0; i < n_components; i++) {
913 struct bus_match_component *c = &components[i];
917 case BUS_MATCH_SENDER:
918 if (!streq(c->value_str, "org.freedesktop.DBus"))
919 matches_name_change = false;
921 r = bus_kernel_parse_unique_name(c->value_str, &src_id);
925 sz += ALIGN8(offsetof(struct kdbus_item, id) + sizeof(uint64_t));
927 sender = c->value_str;
928 sender_length = strlen(sender);
929 sz += ALIGN8(offsetof(struct kdbus_item, str) + sender_length + 1);
934 case BUS_MATCH_MESSAGE_TYPE:
935 if (c->value_u8 != SD_BUS_MESSAGE_SIGNAL)
936 matches_name_change = false;
938 bloom_add_pair(bloom, "message-type", bus_message_type_to_string(c->value_u8));
942 case BUS_MATCH_INTERFACE:
943 if (!streq(c->value_str, "org.freedesktop.DBus"))
944 matches_name_change = false;
946 bloom_add_pair(bloom, "interface", c->value_str);
950 case BUS_MATCH_MEMBER:
951 if (!streq(c->value_str, "NameOwnerChanged"))
952 matches_name_change = false;
954 bloom_add_pair(bloom, "member", c->value_str);
959 if (!streq(c->value_str, "/org/freedesktop/DBus"))
960 matches_name_change = false;
962 bloom_add_pair(bloom, "path", c->value_str);
966 case BUS_MATCH_PATH_NAMESPACE:
967 if (!streq(c->value_str, "/")) {
968 bloom_add_pair(bloom, "path-slash-prefix", c->value_str);
973 case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: {
974 char buf[sizeof("arg")-1 + 2 + 1];
976 if (c->type - BUS_MATCH_ARG < 3)
977 name_change_arg[c->type - BUS_MATCH_ARG] = c->value_str;
979 snprintf(buf, sizeof(buf), "arg%u", c->type - BUS_MATCH_ARG);
980 bloom_add_pair(bloom, buf, c->value_str);
985 case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: {
986 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
988 snprintf(buf, sizeof(buf), "arg%u-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
989 bloom_add_pair(bloom, buf, c->value_str);
994 case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: {
995 char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")];
997 snprintf(buf, sizeof(buf), "arg%u-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE);
998 bloom_add_pair(bloom, buf, c->value_str);
1003 case BUS_MATCH_DESTINATION:
1004 /* The bloom filter does not include
1005 the destination, since it is only
1006 available for broadcast messages
1007 which do not carry a destination
1008 since they are undirected. */
1011 case BUS_MATCH_ROOT:
1012 case BUS_MATCH_VALUE:
1013 case BUS_MATCH_LEAF:
1014 case _BUS_MATCH_NODE_TYPE_MAX:
1015 case _BUS_MATCH_NODE_TYPE_INVALID:
1016 assert_not_reached("Invalid match type?");
1021 sz += ALIGN8(offsetof(struct kdbus_item, data64) + BLOOM_SIZE);
1030 if (src_id != KDBUS_MATCH_ID_ANY) {
1031 item->size = offsetof(struct kdbus_item, id) + sizeof(uint64_t);
1032 item->type = KDBUS_ITEM_ID;
1034 item = KDBUS_ITEM_NEXT(item);
1038 item->size = offsetof(struct kdbus_item, data64) + BLOOM_SIZE;
1039 item->type = KDBUS_ITEM_BLOOM;
1040 memcpy(item->data64, bloom, BLOOM_SIZE);
1041 item = KDBUS_ITEM_NEXT(item);
1045 item->size = offsetof(struct kdbus_item, str) + sender_length + 1;
1046 item->type = KDBUS_ITEM_NAME;
1047 memcpy(item->str, sender, sender_length + 1);
1050 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1054 if (matches_name_change) {
1056 /* If this match could theoretically match
1057 * NameOwnerChanged messages, we need to
1058 * install a second non-bloom filter explitly
1061 r = add_name_change_match(bus, cookie, name_change_arg[0], name_change_arg[1], name_change_arg[2]);
1069 static int bus_add_match_internal_dbus1(
1071 const char *match) {
1076 return sd_bus_call_method(
1078 "org.freedesktop.DBus",
1079 "/org/freedesktop/DBus",
1080 "org.freedesktop.DBus",
1088 int bus_add_match_internal(
1091 struct bus_match_component *components,
1092 unsigned n_components,
1099 return bus_add_match_internal_kernel(bus, 0, components, n_components, cookie);
1101 return bus_add_match_internal_dbus1(bus, match);
1104 int bus_remove_match_internal_kernel(
1109 struct kdbus_cmd_match m;
1115 m.size = offsetof(struct kdbus_cmd_match, items);
1119 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_REMOVE, &m);
1126 static int bus_remove_match_internal_dbus1(
1128 const char *match) {
1133 return sd_bus_call_method(
1135 "org.freedesktop.DBus",
1136 "/org/freedesktop/DBus",
1137 "org.freedesktop.DBus",
1145 int bus_remove_match_internal(
1154 return bus_remove_match_internal_kernel(bus, 0, cookie);
1156 return bus_remove_match_internal_dbus1(bus, match);
1159 _public_ int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) {
1160 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
1164 assert_return(bus, -EINVAL);
1165 assert_return(name, -EINVAL);
1166 assert_return(machine, -EINVAL);
1167 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1168 assert_return(!bus_pid_changed(bus), -ECHILD);
1169 assert_return(service_name_is_valid(name), -EINVAL);
1171 if (streq_ptr(name, bus->unique_name))
1172 return sd_id128_get_machine(machine);
1174 r = sd_bus_message_new_method_call(
1178 "org.freedesktop.DBus.Peer",
1179 "GetMachineId", &m);
1183 r = sd_bus_message_set_no_auto_start(m, true);
1187 r = sd_bus_call(bus, m, 0, NULL, &reply);
1191 r = sd_bus_message_read(reply, "s", &mid);
1195 return sd_id128_from_string(mid, machine);