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",
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",
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->id != previous_id) {
236 if (asprintf(&n, ":1.%llu", (unsigned long long) name->id) < 0)
245 previous_id = name->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",
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",
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);
394 if (mask & SD_BUS_CREDS_UNIQUE_NAME) {
395 if (asprintf(&c->unique_name, ":1.%llu", (unsigned long long) conn_info->id) < 0)
398 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
401 KDBUS_ITEM_FOREACH(item, conn_info, items) {
403 switch (item->type) {
405 case KDBUS_ITEM_CREDS:
406 m = (SD_BUS_CREDS_UID | SD_BUS_CREDS_GID | SD_BUS_CREDS_PID |
407 SD_BUS_CREDS_TID | SD_BUS_CREDS_PID_STARTTIME) & mask;
410 c->uid = item->creds.uid;
411 c->pid = item->creds.pid;
412 c->gid = item->creds.gid;
413 c->tid = item->creds.tid;
414 c->pid_starttime = item->creds.starttime;
419 case KDBUS_ITEM_PID_COMM:
420 if (mask & SD_BUS_CREDS_COMM) {
421 c->comm = strdup(item->str);
427 c->mask |= SD_BUS_CREDS_COMM;
431 case KDBUS_ITEM_TID_COMM:
432 if (mask & SD_BUS_CREDS_TID_COMM) {
433 c->tid_comm = strdup(item->str);
439 c->mask |= SD_BUS_CREDS_TID_COMM;
444 if (mask & SD_BUS_CREDS_EXE) {
445 c->exe = strdup(item->str);
451 c->mask |= SD_BUS_CREDS_EXE;
455 case KDBUS_ITEM_CMDLINE:
456 if (mask & SD_BUS_CREDS_CMDLINE) {
457 c->cmdline_size = item->size - KDBUS_ITEM_HEADER_SIZE;
458 c->cmdline = memdup(item->data, c->cmdline_size);
464 c->mask |= SD_BUS_CREDS_CMDLINE;
468 case KDBUS_ITEM_CGROUP:
469 m = (SD_BUS_CREDS_CGROUP | SD_BUS_CREDS_UNIT |
470 SD_BUS_CREDS_USER_UNIT | SD_BUS_CREDS_SLICE |
471 SD_BUS_CREDS_SESSION | SD_BUS_CREDS_OWNER_UID) & mask;
474 c->cgroup = strdup(item->str);
484 case KDBUS_ITEM_CAPS:
485 m = (SD_BUS_CREDS_EFFECTIVE_CAPS | SD_BUS_CREDS_PERMITTED_CAPS |
486 SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_BOUNDING_CAPS) & mask;
489 c->capability_size = item->size - KDBUS_ITEM_HEADER_SIZE;
490 c->capability = memdup(item->data, c->capability_size);
491 if (!c->capability) {
500 case KDBUS_ITEM_SECLABEL:
501 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
502 c->label = strdup(item->str);
508 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
512 case KDBUS_ITEM_AUDIT:
513 m = (SD_BUS_CREDS_AUDIT_SESSION_ID | SD_BUS_CREDS_AUDIT_LOGIN_UID) & mask;
516 c->audit_session_id = item->audit.sessionid;
517 c->audit_login_uid = item->audit.loginuid;
522 case KDBUS_ITEM_NAME:
523 if ((mask & SD_BUS_CREDS_WELL_KNOWN_NAMES) && service_name_is_valid(item->name.name)) {
524 r = strv_extend(&c->well_known_names, item->name.name);
528 c->mask |= SD_BUS_CREDS_WELL_KNOWN_NAMES;
542 ioctl(bus->input_fd, KDBUS_CMD_FREE, &cmd->offset);
546 static int bus_get_owner_dbus1(
550 sd_bus_creds **creds) {
552 _cleanup_bus_message_unref_ sd_bus_message *reply_unique = NULL, *reply = NULL;
553 _cleanup_bus_creds_unref_ sd_bus_creds *c = NULL;
554 const char *unique = NULL;
558 /* Only query the owner if the caller wants to know it or if
559 * the caller just wants to check whether a name exists */
560 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) || mask == 0) {
561 r = sd_bus_call_method(
563 "org.freedesktop.DBus",
565 "org.freedesktop.DBus",
574 r = sd_bus_message_read(reply_unique, "s", &unique);
584 if ((mask & SD_BUS_CREDS_UNIQUE_NAME) && unique) {
585 c->unique_name = strdup(unique);
589 c->mask |= SD_BUS_CREDS_UNIQUE_NAME;
592 if (mask & (SD_BUS_CREDS_PID|SD_BUS_CREDS_PID_STARTTIME|SD_BUS_CREDS_GID|
593 SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
594 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|
595 SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
596 SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)) {
599 r = sd_bus_call_method(
601 "org.freedesktop.DBus",
603 "org.freedesktop.DBus",
604 "GetConnectionUnixProcessID",
608 unique ? unique : name);
612 r = sd_bus_message_read(reply, "u", &u);
617 if (mask & SD_BUS_CREDS_PID) {
619 c->mask |= SD_BUS_CREDS_PID;
622 reply = sd_bus_message_unref(reply);
625 if (mask & SD_BUS_CREDS_UID) {
628 r = sd_bus_call_method(
630 "org.freedesktop.DBus",
632 "org.freedesktop.DBus",
633 "GetConnectionUnixUser",
637 unique ? unique : name);
641 r = sd_bus_message_read(reply, "u", &u);
646 c->mask |= SD_BUS_CREDS_UID;
648 reply = sd_bus_message_unref(reply);
651 if (mask & SD_BUS_CREDS_SELINUX_CONTEXT) {
655 r = sd_bus_call_method(
657 "org.freedesktop.DBus",
659 "org.freedesktop.DBus",
660 "GetConnectionSELinuxSecurityContext",
664 unique ? unique : name);
668 r = sd_bus_message_read_array(reply, 'y', &p, &sz);
672 c->label = strndup(p, sz);
676 c->mask |= SD_BUS_CREDS_SELINUX_CONTEXT;
679 r = bus_creds_add_more(c, mask, pid, 0);
692 _public_ int sd_bus_get_owner(
696 sd_bus_creds **creds) {
698 assert_return(bus, -EINVAL);
699 assert_return(name, -EINVAL);
700 assert_return(mask <= _SD_BUS_CREDS_ALL, -ENOTSUP);
701 assert_return(mask == 0 || creds, -EINVAL);
702 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
703 assert_return(!bus_pid_changed(bus), -ECHILD);
704 assert_return(service_name_is_valid(name), -EINVAL);
707 return bus_get_owner_kdbus(bus, name, mask, creds);
709 return bus_get_owner_dbus1(bus, name, mask, creds);
712 static int add_name_change_match(sd_bus *bus,
715 const char *old_owner,
716 const char *new_owner) {
718 uint64_t name_id = KDBUS_MATCH_ID_ANY, old_owner_id = 0, new_owner_id = 0;
719 int is_name_id = -1, r;
720 struct kdbus_item *item;
724 /* If we encounter a match that could match against
725 * NameOwnerChanged messages, then we need to create
726 * KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE} and
727 * KDBUS_ITEM_ID_{ADD,REMOVE} matches for it, possibly
728 * multiple if the match is underspecified.
730 * The NameOwnerChanged signals take three parameters with
731 * unique or well-known names, but only some forms actually
734 * WELLKNOWN, "", UNIQUE → KDBUS_ITEM_NAME_ADD
735 * WELLKNOWN, UNIQUE, "" → KDBUS_ITEM_NAME_REMOVE
736 * WELLKNOWN, UNIQUE, UNIQUE → KDBUS_ITEM_NAME_CHANGE
737 * UNIQUE, "", UNIQUE → KDBUS_ITEM_ID_ADD
738 * UNIQUE, UNIQUE, "" → KDBUS_ITEM_ID_REMOVE
740 * For the latter two the two unique names must be identical.
745 is_name_id = bus_kernel_parse_unique_name(name, &name_id);
750 if (!isempty(old_owner)) {
751 r = bus_kernel_parse_unique_name(old_owner, &old_owner_id);
756 if (is_name_id > 0 && old_owner_id != name_id)
759 old_owner_id = KDBUS_MATCH_ID_ANY;
761 if (!isempty(new_owner)) {
762 r = bus_kernel_parse_unique_name(new_owner, &new_owner_id);
767 if (is_name_id > 0 && new_owner_id != name_id)
770 new_owner_id = KDBUS_MATCH_ID_ANY;
772 if (is_name_id <= 0) {
773 struct kdbus_cmd_match *m;
776 /* If the name argument is missing or is a well-known
777 * name, then add KDBUS_ITEM_NAME_{ADD,REMOVE,CHANGE}
780 l = name ? strlen(name) + 1 : 0;
782 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
783 offsetof(struct kdbus_item, name_change) +
784 offsetof(struct kdbus_notify_name_change, name) +
793 offsetof(struct kdbus_item, name_change) +
794 offsetof(struct kdbus_notify_name_change, name) +
797 item->name_change.old.id = old_owner_id;
798 item->name_change.new.id = new_owner_id;
801 strcpy(item->name_change.name, name);
803 /* If the old name is unset or empty, then
804 * this can match against added names */
805 if (!old_owner || old_owner[0] == 0) {
806 item->type = KDBUS_ITEM_NAME_ADD;
808 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
813 /* If the new name is unset or empty, then
814 * this can match against removed names */
815 if (!new_owner || new_owner[0] == 0) {
816 item->type = KDBUS_ITEM_NAME_REMOVE;
818 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
823 /* The CHANGE match we need in either case, because
824 * what is reported as a name change by the kernel
825 * might just be an owner change between starter and
826 * normal clients. For userspace such a change should
827 * be considered a removal/addition, hence let's
828 * subscribe to this unconditionally. */
829 item->type = KDBUS_ITEM_NAME_CHANGE;
830 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
835 if (is_name_id != 0) {
836 struct kdbus_cmd_match *m;
839 /* If the name argument is missing or is a unique
840 * name, then add KDBUS_ITEM_ID_{ADD,REMOVE} matches
843 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
844 offsetof(struct kdbus_item, id_change) +
845 sizeof(struct kdbus_notify_id_change));
852 item->size = offsetof(struct kdbus_item, id_change) + sizeof(struct kdbus_notify_id_change);
853 item->id_change.id = name_id;
855 /* If the old name is unset or empty, then this can
856 * match against added ids */
857 if (!old_owner || old_owner[0] == 0) {
858 item->type = KDBUS_ITEM_ID_ADD;
860 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
865 /* If thew new name is unset or empty, then this can
866 * match against removed ids */
867 if (!new_owner || new_owner[0] == 0) {
868 item->type = KDBUS_ITEM_ID_REMOVE;
870 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
879 int bus_add_match_internal_kernel(
882 struct bus_match_component *components,
883 unsigned n_components,
886 struct kdbus_cmd_match *m;
887 struct kdbus_item *item;
888 uint64_t bloom[BLOOM_SIZE/8];
890 const char *sender = NULL;
891 size_t sender_length = 0;
892 uint64_t src_id = KDBUS_MATCH_ID_ANY;
893 bool using_bloom = false;
895 bool matches_name_change = true;
896 const char *name_change_arg[3] = {};
903 sz = ALIGN8(offsetof(struct kdbus_cmd_match, items) +
904 offsetof(struct kdbus_item, id) + sizeof(uint64_t));
906 for (i = 0; i < n_components; i++) {
907 struct bus_match_component *c = &components[i];
911 case BUS_MATCH_SENDER:
912 if (!streq(c->value_str, "org.freedesktop.DBus"))
913 matches_name_change = false;
915 r = bus_kernel_parse_unique_name(c->value_str, &src_id);
920 sender = c->value_str;
921 sender_length = strlen(sender);
922 sz += ALIGN8(offsetof(struct kdbus_item, str) + sender_length + 1);
927 case BUS_MATCH_MESSAGE_TYPE:
928 if (c->value_u8 != SD_BUS_MESSAGE_SIGNAL)
929 matches_name_change = false;
931 bloom_add_pair(bloom, "message-type", bus_message_type_to_string(c->value_u8));
935 case BUS_MATCH_INTERFACE:
936 if (!streq(c->value_str, "org.freedesktop.DBus"))
937 matches_name_change = false;
939 bloom_add_pair(bloom, "interface", c->value_str);
943 case BUS_MATCH_MEMBER:
944 if (!streq(c->value_str, "NameOwnerChanged"))
945 matches_name_change = false;
947 bloom_add_pair(bloom, "member", c->value_str);
952 if (!streq(c->value_str, "/org/freedesktop/DBus"))
953 matches_name_change = false;
955 bloom_add_pair(bloom, "path", c->value_str);
959 case BUS_MATCH_PATH_NAMESPACE:
960 if (!streq(c->value_str, "/")) {
961 bloom_add_pair(bloom, "path-slash-prefix", c->value_str);
966 case BUS_MATCH_ARG...BUS_MATCH_ARG_LAST: {
967 char buf[sizeof("arg")-1 + 2 + 1];
969 if (c->type - BUS_MATCH_ARG < 3)
970 name_change_arg[c->type - BUS_MATCH_ARG] = c->value_str;
972 snprintf(buf, sizeof(buf), "arg%u", c->type - BUS_MATCH_ARG);
973 bloom_add_pair(bloom, buf, c->value_str);
978 case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: {
979 char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
981 snprintf(buf, sizeof(buf), "arg%u-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
982 bloom_add_pair(bloom, buf, c->value_str);
987 case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: {
988 char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")];
990 snprintf(buf, sizeof(buf), "arg%u-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE);
991 bloom_add_pair(bloom, buf, c->value_str);
996 case BUS_MATCH_DESTINATION:
997 /* The bloom filter does not include
998 the destination, since it is only
999 available for broadcast messages
1000 which do not carry a destination
1001 since they are undirected. */
1004 case BUS_MATCH_ROOT:
1005 case BUS_MATCH_VALUE:
1006 case BUS_MATCH_LEAF:
1007 case _BUS_MATCH_NODE_TYPE_MAX:
1008 case _BUS_MATCH_NODE_TYPE_INVALID:
1009 assert_not_reached("Invalid match type?");
1014 sz += ALIGN8(offsetof(struct kdbus_item, data64) + BLOOM_SIZE);
1022 item->size = offsetof(struct kdbus_item, id) + sizeof(uint64_t);
1023 item->type = KDBUS_ITEM_ID;
1027 item = KDBUS_ITEM_NEXT(item);
1028 item->size = offsetof(struct kdbus_item, data64) + BLOOM_SIZE;
1029 item->type = KDBUS_ITEM_BLOOM;
1030 memcpy(item->data64, bloom, BLOOM_SIZE);
1034 item = KDBUS_ITEM_NEXT(item);
1035 item->size = offsetof(struct kdbus_item, str) + sender_length + 1;
1036 item->type = KDBUS_ITEM_NAME;
1037 memcpy(item->str, sender, sender_length + 1);
1040 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m);
1044 if (matches_name_change) {
1046 /* If this match could theoretically match
1047 * NameOwnerChanged messages, we need to
1048 * install a second non-bloom filter explitly
1051 r = add_name_change_match(bus, cookie, name_change_arg[0], name_change_arg[1], name_change_arg[2]);
1059 static int bus_add_match_internal_dbus1(
1061 const char *match) {
1066 return sd_bus_call_method(
1068 "org.freedesktop.DBus",
1070 "org.freedesktop.DBus",
1078 int bus_add_match_internal(
1081 struct bus_match_component *components,
1082 unsigned n_components,
1089 return bus_add_match_internal_kernel(bus, 0, components, n_components, cookie);
1091 return bus_add_match_internal_dbus1(bus, match);
1094 int bus_remove_match_internal_kernel(
1099 struct kdbus_cmd_match m;
1105 m.size = offsetof(struct kdbus_cmd_match, items);
1109 r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_REMOVE, &m);
1116 static int bus_remove_match_internal_dbus1(
1118 const char *match) {
1123 return sd_bus_call_method(
1125 "org.freedesktop.DBus",
1127 "org.freedesktop.DBus",
1135 int bus_remove_match_internal(
1144 return bus_remove_match_internal_kernel(bus, 0, cookie);
1146 return bus_remove_match_internal_dbus1(bus, match);
1149 _public_ int sd_bus_get_owner_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine) {
1150 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
1154 assert_return(bus, -EINVAL);
1155 assert_return(name, -EINVAL);
1156 assert_return(machine, -EINVAL);
1157 assert_return(BUS_IS_OPEN(bus->state), -ENOTCONN);
1158 assert_return(!bus_pid_changed(bus), -ECHILD);
1159 assert_return(service_name_is_valid(name), -EINVAL);
1161 if (streq_ptr(name, bus->unique_name))
1162 return sd_id128_get_machine(machine);
1164 r = sd_bus_message_new_method_call(
1168 "org.freedesktop.DBus.Peer",
1169 "GetMachineId", &m);
1173 r = sd_bus_message_set_no_auto_start(m, true);
1177 r = sd_bus_call(bus, m, 0, NULL, &reply);
1181 r = sd_bus_message_read(reply, "s", &mid);
1185 return sd_id128_from_string(mid, machine);