d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina/*
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina Authors:
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina Pavel Březina <pbrezina@redhat.com>
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina Copyright (C) 2014 Red Hat
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina This program is free software; you can redistribute it and/or modify
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina it under the terms of the GNU General Public License as published by
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina the Free Software Foundation; either version 3 of the License, or
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina (at your option) any later version.
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina This program is distributed in the hope that it will be useful,
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina but WITHOUT ANY WARRANTY; without even the implied warranty of
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina GNU General Public License for more details.
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina You should have received a copy of the GNU General Public License
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina along with this program. If not, see <http://www.gnu.org/licenses/>.
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina*/
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina#include <talloc.h>
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina#include <dbus/dbus.h>
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina#include <dhash.h>
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina#include "util/util.h"
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina#include "sbus/sssd_dbus.h"
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina#include "sbus/sssd_dbus_meta.h"
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina#include "sbus/sssd_dbus_private.h"
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinastatic struct sbus_interface *
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinasbus_iface_list_lookup(struct sbus_interface_list *list,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina const char *iface)
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina{
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina struct sbus_interface_list *item;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina DLIST_FOR_EACH(item, list) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (strcmp(item->interface->vtable->meta->name, iface) == 0) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return item->interface;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina }
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina }
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return NULL;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina}
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březinastatic errno_t
21e05273eed8cc914871938061554589883e67cePavel Březinasbus_iface_list_copy(TALLOC_CTX *mem_ctx,
21e05273eed8cc914871938061554589883e67cePavel Březina struct sbus_interface_list *list,
21e05273eed8cc914871938061554589883e67cePavel Březina struct sbus_interface_list **_copy)
21e05273eed8cc914871938061554589883e67cePavel Březina{
21e05273eed8cc914871938061554589883e67cePavel Březina TALLOC_CTX *list_ctx;
21e05273eed8cc914871938061554589883e67cePavel Březina struct sbus_interface_list *new_list = NULL;
21e05273eed8cc914871938061554589883e67cePavel Březina struct sbus_interface_list *new_item;
21e05273eed8cc914871938061554589883e67cePavel Březina struct sbus_interface_list *item;
21e05273eed8cc914871938061554589883e67cePavel Březina errno_t ret;
21e05273eed8cc914871938061554589883e67cePavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březina if (list == NULL) {
21e05273eed8cc914871938061554589883e67cePavel Březina *_copy = NULL;
21e05273eed8cc914871938061554589883e67cePavel Březina return EOK;
21e05273eed8cc914871938061554589883e67cePavel Březina }
21e05273eed8cc914871938061554589883e67cePavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březina list_ctx = talloc_new(mem_ctx);
21e05273eed8cc914871938061554589883e67cePavel Březina if (list_ctx == NULL) {
21e05273eed8cc914871938061554589883e67cePavel Březina return ENOMEM;
21e05273eed8cc914871938061554589883e67cePavel Březina }
21e05273eed8cc914871938061554589883e67cePavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březina DLIST_FOR_EACH(item, list) {
21e05273eed8cc914871938061554589883e67cePavel Březina if (sbus_iface_list_lookup(new_list,
21e05273eed8cc914871938061554589883e67cePavel Březina item->interface->vtable->meta->name) != NULL) {
21e05273eed8cc914871938061554589883e67cePavel Březina /* already in list */
21e05273eed8cc914871938061554589883e67cePavel Březina continue;
21e05273eed8cc914871938061554589883e67cePavel Březina }
21e05273eed8cc914871938061554589883e67cePavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březina new_item = talloc_zero(list_ctx, struct sbus_interface_list);
21e05273eed8cc914871938061554589883e67cePavel Březina if (new_item == NULL) {
21e05273eed8cc914871938061554589883e67cePavel Březina ret = ENOMEM;
21e05273eed8cc914871938061554589883e67cePavel Březina goto done;
21e05273eed8cc914871938061554589883e67cePavel Březina }
21e05273eed8cc914871938061554589883e67cePavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březina new_item->interface = item->interface;
21e05273eed8cc914871938061554589883e67cePavel Březina DLIST_ADD(new_list, new_item);
21e05273eed8cc914871938061554589883e67cePavel Březina }
21e05273eed8cc914871938061554589883e67cePavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březina *_copy = new_list;
21e05273eed8cc914871938061554589883e67cePavel Březina ret = EOK;
21e05273eed8cc914871938061554589883e67cePavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březinadone:
21e05273eed8cc914871938061554589883e67cePavel Březina if (ret != EOK) {
21e05273eed8cc914871938061554589883e67cePavel Březina talloc_free(list_ctx);
21e05273eed8cc914871938061554589883e67cePavel Březina }
21e05273eed8cc914871938061554589883e67cePavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březina return ret;
21e05273eed8cc914871938061554589883e67cePavel Březina}
21e05273eed8cc914871938061554589883e67cePavel Březina
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina/**
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina * Object paths that represent all objects under the path:
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina * /org/object/path/~* (without tilda)
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina */
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březinastatic bool sbus_opath_is_subtree(const char *path)
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina{
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina size_t len;
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina len = strlen(path);
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina if (len < 2) {
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina return false;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina }
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina return path[len - 2] == '/' && path[len - 1] == '*';
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina}
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina/**
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina * If the path represents a subtree object path, this function will
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina * remove /~* from the end.
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina */
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březinastatic char *sbus_opath_get_base_path(TALLOC_CTX *mem_ctx,
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina const char *object_path)
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina{
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina char *tree_path;
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina size_t len;
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina tree_path = talloc_strdup(mem_ctx, object_path);
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina if (tree_path == NULL) {
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina return NULL;
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina }
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina if (!sbus_opath_is_subtree(tree_path)) {
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina return tree_path;
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina }
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina /* replace / only if it is not a root path (only slash) */
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina len = strlen(tree_path);
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina tree_path[len - 1] = '\0';
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina tree_path[len - 2] = (len - 2 != 0) ? '\0' : '/';
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina
894f09f146f0c9cda9e0f7dfe1916519d73dde72Pavel Březina return tree_path;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina}
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinastatic char *sbus_opath_parent_subtree(TALLOC_CTX *mem_ctx,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina const char *path)
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina{
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina char *subtree;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina char *slash;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* first remove /~* from the end, stop when we have reached the root i.e.
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina * subtree == "/" */
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina subtree = sbus_opath_get_base_path(mem_ctx, path);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (subtree == NULL || subtree[1] == '\0') {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return NULL;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* Find the first separator and replace the part with asterisk. */
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina slash = strrchr(subtree, '/');
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (slash == NULL) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* we cannot continue up */
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina talloc_free(subtree);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return NULL;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (*(slash + 1) == '\0') {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* this object path is invalid since it cannot end with slash */
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Invalid object path '%s'?\n", path);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina talloc_free(subtree);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return NULL;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* because object path cannot end with / there is enough space for
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina * asterisk and terminating zero */
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina *(slash + 1) = '*';
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina *(slash + 2) = '\0';
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return subtree;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina}
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina/**
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina * The following path related functions are based on similar code in
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina * storaged, just tailored to use talloc instead of glib
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina */
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březinachar *
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březinasbus_opath_escape_part(TALLOC_CTX *mem_ctx,
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina const char *object_path_part)
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina{
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina size_t n;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina char *safe_path = NULL;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina TALLOC_CTX *tmp_ctx = NULL;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina /* The path must be valid */
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (object_path_part == NULL) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina return NULL;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina tmp_ctx = talloc_new(NULL);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (tmp_ctx == NULL) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina return NULL;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina safe_path = talloc_strdup(tmp_ctx, "");
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (safe_path == NULL) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina goto done;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina /* Special case for an empty string */
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (strcmp(object_path_part, "") == 0) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina /* the for loop would just fall through */
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina safe_path = talloc_asprintf_append_buffer(safe_path, "_");
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (safe_path == NULL) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina goto done;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina for (n = 0; object_path_part[n]; n++) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina int c = object_path_part[n];
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina /* D-Bus spec says:
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina * *
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina * * Each element must only contain the ASCII characters
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina * "[A-Z][a-z][0-9]_"
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina * */
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if ((c >= 'A' && c <= 'Z')
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina || (c >= 'a' && c <= 'z')
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina || (c >= '0' && c <= '9')) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina safe_path = talloc_asprintf_append_buffer(safe_path, "%c", c);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (safe_path == NULL) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina goto done;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina } else {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina safe_path = talloc_asprintf_append_buffer(safe_path, "_%02x", c);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (safe_path == NULL) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina goto done;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina safe_path = talloc_steal(mem_ctx, safe_path);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březinadone:
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina talloc_free(tmp_ctx);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina return safe_path;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina}
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březinastatic inline int unhexchar(char c)
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina{
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (c >= '0' && c <= '9') {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina return c - '0';
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (c >= 'a' && c <= 'f') {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina return c - 'a' + 10;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (c >= 'A' && c <= 'F') {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina return c - 'A' + 10;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina return -1;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina}
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březinachar *
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březinasbus_opath_unescape_part(TALLOC_CTX *mem_ctx,
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina const char *object_path_part)
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina{
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina char *safe_path;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina const char *p;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina int a, b, c;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina TALLOC_CTX *tmp_ctx = NULL;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina tmp_ctx = talloc_new(NULL);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (tmp_ctx == NULL) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina return NULL;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina safe_path = talloc_strdup(tmp_ctx, "");
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (safe_path == NULL) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina goto done;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina /* Special case for the empty string */
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (strcmp(object_path_part, "_") == 0) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina safe_path = talloc_steal(mem_ctx, safe_path);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina goto done;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina for (p = object_path_part; *p; p++) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (*p == '_') {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina /* There must be at least two more chars after underscore */
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (p[1] == '\0' || p[2] == '\0') {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina safe_path = NULL;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina goto done;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if ((a = unhexchar(p[1])) < 0
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina || (b = unhexchar(p[2])) < 0) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina /* Invalid escape code, let's take it literal then */
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina c = '_';
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina } else {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina c = ((a << 4) | b);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina p += 2;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina } else {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina c = *p;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina safe_path = talloc_asprintf_append_buffer(safe_path, "%c", c);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (safe_path == NULL) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina goto done;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina safe_path = talloc_steal(mem_ctx, safe_path);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březinadone:
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina talloc_free(tmp_ctx);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina return safe_path;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina}
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březinachar *
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina_sbus_opath_compose(TALLOC_CTX *mem_ctx,
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina const char *base,
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina const char *part, ...)
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina{
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina char *safe_part;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina char *path = NULL;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina va_list va;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (base == NULL) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina DEBUG(SSSDBG_OP_FAILURE, "Wrong object path base!\n");
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina return NULL;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina path = talloc_strdup(mem_ctx, base);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (path == NULL) return NULL;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina va_start(va, part);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina while (part != NULL) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina safe_part = sbus_opath_escape_part(mem_ctx, part);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (safe_part == NULL) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina DEBUG(SSSDBG_OP_FAILURE, "Could not add [%s] to objpath\n", part);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina goto fail;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina path = talloc_asprintf_append(path, "/%s", safe_part);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina talloc_free(safe_part);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (path == NULL) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina goto fail;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina part = va_arg(va, const char *);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina va_end(va);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina return path;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březinafail:
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina va_end(va);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina talloc_free(path);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina return NULL;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina}
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březinaerrno_t
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březinasbus_opath_decompose(TALLOC_CTX *mem_ctx,
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina const char *object_path,
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina const char *prefix,
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina char ***_components,
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina size_t *_len)
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina{
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina TALLOC_CTX *tmp_ctx;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina const char *path;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina char **decomposed;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina char **unescaped;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina errno_t ret;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina int len;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina int i;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina tmp_ctx = talloc_new(NULL);
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina if (tmp_ctx == NULL) {
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina return ENOMEM;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina }
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina /* Strip prefix from the path. */
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina if (prefix != NULL) {
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina path = sbus_opath_strip_prefix(object_path, prefix);
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina if (path == NULL) {
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina ret = ERR_SBUS_INVALID_PATH;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina goto done;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina }
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina } else {
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina path = object_path;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina }
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina /* Split the string using / as delimiter. */
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina split_on_separator(tmp_ctx, path, '/', true, true, &decomposed, &len);
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina /* Unescape parts. */
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina unescaped = talloc_zero_array(tmp_ctx, char *, len + 1);
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina if (unescaped == NULL) {
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina ret = ENOMEM;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina goto done;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina }
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina for (i = 0; i < len; i++) {
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina unescaped[i] = sbus_opath_unescape_part(unescaped, decomposed[i]);
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina if (unescaped[i] == NULL) {
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina ret = ENOMEM;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina goto done;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina }
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina }
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina if (_components != NULL) {
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina *_components = talloc_steal(mem_ctx, unescaped);
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina }
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina if (_len != NULL) {
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina *_len = len;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina }
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina ret = EOK;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březinadone:
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina talloc_free(tmp_ctx);
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina return ret;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina}
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březinaerrno_t
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březinasbus_opath_decompose_exact(TALLOC_CTX *mem_ctx,
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina const char *object_path,
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina const char *prefix,
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina size_t expected,
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina char ***_components)
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina{
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina char **components;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina size_t len;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina errno_t ret;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina ret = sbus_opath_decompose(mem_ctx, object_path, prefix,
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina &components, &len);
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina if (ret != EOK) {
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina return ret;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina }
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina if (len != expected) {
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina talloc_free(components);
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina return ERR_SBUS_INVALID_PATH;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina }
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina if (_components != NULL) {
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina *_components = components;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina }
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina return EOK;
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina}
10a28f461c25d788ff4dcffefa881e7aa724a25dPavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březinaconst char *
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březinasbus_opath_strip_prefix(const char *object_path,
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina const char *prefix)
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina{
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina if (strncmp(object_path, prefix, strlen(prefix)) == 0) {
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina return object_path + strlen(prefix);
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina }
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina return NULL;
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina}
3a8f6b575f4019f21c9425a26f1b346c08a197aePavel Březina
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březinachar *
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březinasbus_opath_get_object_name(TALLOC_CTX *mem_ctx,
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina const char *object_path,
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina const char *base_path)
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina{
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina const char *name;
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina name = sbus_opath_strip_prefix(object_path, base_path);
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina if (name == NULL || name[0] == '\0') {
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina return NULL;
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina }
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina /* if base_path did not end with / */
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina if (name[0] == '/') {
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina name = name + 1;
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina }
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina return sbus_opath_unescape_part(mem_ctx, name);
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina}
ca6dd8e7ac91c7f8e3b4d55206d4f39791ab7149Pavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinastatic void
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinasbus_opath_hash_delete_cb(hash_entry_t *item,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina hash_destroy_enum deltype,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina void *pvt)
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina{
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina struct sbus_connection *conn;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina char *path;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina conn = talloc_get_type(pvt, struct sbus_connection);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina path = sbus_opath_get_base_path(NULL, item->key.str);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina dbus_connection_unregister_object_path(conn->dbus.conn, path);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina}
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinaerrno_t
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinasbus_opath_hash_init(TALLOC_CTX *mem_ctx,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina struct sbus_connection *conn,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina hash_table_t **_table)
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina{
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return sss_hash_create_ex(mem_ctx, 10, _table, 0, 0, 0, 0,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina sbus_opath_hash_delete_cb, conn);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina}
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinastatic errno_t
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinasbus_opath_hash_add_iface(hash_table_t *table,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina const char *object_path,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina struct sbus_interface *iface,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina bool *_path_known)
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina{
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina TALLOC_CTX *tmp_ctx = NULL;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina struct sbus_interface_list *list = NULL;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina struct sbus_interface_list *item = NULL;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina const char *iface_name = iface->vtable->meta->name;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina hash_key_t key;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina hash_value_t value;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina bool path_known;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina errno_t ret;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina int hret;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina tmp_ctx = talloc_new(NULL);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (tmp_ctx == NULL) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return ENOMEM;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina DEBUG(SSSDBG_TRACE_FUNC, "Registering interface %s with path %s\n",
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina iface_name, object_path);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* create new list item */
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina item = talloc_zero(tmp_ctx, struct sbus_interface_list);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (item == NULL) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return ENOMEM;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina item->interface = iface;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* first lookup existing list in hash table */
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina key.type = HASH_KEY_STRING;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina key.str = talloc_strdup(tmp_ctx, object_path);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (key.str == NULL) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina ret = ENOMEM;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina goto done;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina hret = hash_lookup(table, &key, &value);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (hret == HASH_SUCCESS) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* This object path has already some interface registered. We will
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina * check for existence of the interface currently being added and
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina * add it if missing. */
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina path_known = true;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina list = talloc_get_type(value.ptr, struct sbus_interface_list);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (sbus_iface_list_lookup(list, iface_name) != NULL) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina DEBUG(SSSDBG_MINOR_FAILURE, "Trying to register the same interface"
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina " twice: iface=%s, opath=%s\n", iface_name, object_path);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina ret = EEXIST;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina goto done;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina DLIST_ADD_END(list, item, struct sbus_interface_list *);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina ret = EOK;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina goto done;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina } else if (hret != HASH_ERROR_KEY_NOT_FOUND) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina ret = EIO;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina goto done;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* otherwise create new hash entry and new list */
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina path_known = false;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina list = item;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina value.type = HASH_VALUE_PTR;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina value.ptr = list;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina hret = hash_enter(table, &key, &value);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (hret != HASH_SUCCESS) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina ret = EIO;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina goto done;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina talloc_steal(table, key.str);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina ret = EOK;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinadone:
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (ret == EOK) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina talloc_steal(item, iface);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina talloc_steal(table, item);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina *_path_known = path_known;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
6170f00ee24ce38af656683e0ab8915abbf93badPavel Reichl talloc_free(tmp_ctx);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return ret;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina}
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinastatic bool
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinasbus_opath_hash_has_path(hash_table_t *table,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina const char *object_path)
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina{
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina hash_key_t key;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina key.type = HASH_KEY_STRING;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina key.str = discard_const(object_path);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return hash_has_key(table, &key);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina}
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina/**
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina * First @object_path is looked up in @table, if it is not found it steps up
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina * in the path hierarchy and try to lookup the parent node. This continues
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina * until the root is reached.
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina */
b742179ac0790068380618ab72a06af18544f09cPavel Březinastruct sbus_interface *
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinasbus_opath_hash_lookup_iface(hash_table_t *table,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina const char *object_path,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina const char *iface_name)
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina{
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina TALLOC_CTX *tmp_ctx = NULL;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina struct sbus_interface_list *list = NULL;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina struct sbus_interface *iface = NULL;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina char *lookup_path = NULL;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina hash_key_t key;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina hash_value_t value;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina int hret;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina tmp_ctx = talloc_new(NULL);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (tmp_ctx == NULL) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return NULL;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina }
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina lookup_path = talloc_strdup(tmp_ctx, object_path);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (lookup_path == NULL) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina goto done;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina while (lookup_path != NULL) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina key.type = HASH_KEY_STRING;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina key.str = lookup_path;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina hret = hash_lookup(table, &key, &value);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (hret == HASH_SUCCESS) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina list = talloc_get_type(value.ptr, struct sbus_interface_list);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina iface = sbus_iface_list_lookup(list, iface_name);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (iface != NULL) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina goto done;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina } else if (hret != HASH_ERROR_KEY_NOT_FOUND) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina DEBUG(SSSDBG_OP_FAILURE,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina "Unable to search hash table: hret=%d\n", hret);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina iface = NULL;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina goto done;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* we will not free lookup path since it is freed with tmp_ctx
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina * and the object paths are supposed to be small */
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina lookup_path = sbus_opath_parent_subtree(tmp_ctx, lookup_path);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinadone:
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina talloc_free(tmp_ctx);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return iface;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina}
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březina/**
21e05273eed8cc914871938061554589883e67cePavel Březina * Acquire list of all interfaces that are supported on given object path.
21e05273eed8cc914871938061554589883e67cePavel Březina */
21e05273eed8cc914871938061554589883e67cePavel Březinaerrno_t
21e05273eed8cc914871938061554589883e67cePavel Březinasbus_opath_hash_lookup_supported(TALLOC_CTX *mem_ctx,
21e05273eed8cc914871938061554589883e67cePavel Březina hash_table_t *table,
21e05273eed8cc914871938061554589883e67cePavel Březina const char *object_path,
21e05273eed8cc914871938061554589883e67cePavel Březina struct sbus_interface_list **_list)
21e05273eed8cc914871938061554589883e67cePavel Březina{
21e05273eed8cc914871938061554589883e67cePavel Březina TALLOC_CTX *tmp_ctx = NULL;
21e05273eed8cc914871938061554589883e67cePavel Březina TALLOC_CTX *list_ctx = NULL;
21e05273eed8cc914871938061554589883e67cePavel Březina struct sbus_interface_list *copy = NULL;
21e05273eed8cc914871938061554589883e67cePavel Březina struct sbus_interface_list *list = NULL;
21e05273eed8cc914871938061554589883e67cePavel Březina char *lookup_path = NULL;
21e05273eed8cc914871938061554589883e67cePavel Březina hash_key_t key;
21e05273eed8cc914871938061554589883e67cePavel Březina hash_value_t value;
21e05273eed8cc914871938061554589883e67cePavel Březina errno_t ret;
21e05273eed8cc914871938061554589883e67cePavel Březina int hret;
21e05273eed8cc914871938061554589883e67cePavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březina tmp_ctx = talloc_new(NULL);
21e05273eed8cc914871938061554589883e67cePavel Březina if (tmp_ctx == NULL) {
21e05273eed8cc914871938061554589883e67cePavel Březina return ENOMEM;
21e05273eed8cc914871938061554589883e67cePavel Březina }
21e05273eed8cc914871938061554589883e67cePavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březina list_ctx = talloc_new(tmp_ctx);
21e05273eed8cc914871938061554589883e67cePavel Březina if (list_ctx == NULL) {
21e05273eed8cc914871938061554589883e67cePavel Březina ret = ENOMEM;
21e05273eed8cc914871938061554589883e67cePavel Březina goto done;
21e05273eed8cc914871938061554589883e67cePavel Březina }
21e05273eed8cc914871938061554589883e67cePavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březina lookup_path = talloc_strdup(tmp_ctx, object_path);
21e05273eed8cc914871938061554589883e67cePavel Březina if (lookup_path == NULL) {
21e05273eed8cc914871938061554589883e67cePavel Březina ret = ENOMEM;
21e05273eed8cc914871938061554589883e67cePavel Březina goto done;
21e05273eed8cc914871938061554589883e67cePavel Březina }
21e05273eed8cc914871938061554589883e67cePavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březina while (lookup_path != NULL) {
21e05273eed8cc914871938061554589883e67cePavel Březina key.type = HASH_KEY_STRING;
21e05273eed8cc914871938061554589883e67cePavel Březina key.str = lookup_path;
21e05273eed8cc914871938061554589883e67cePavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březina hret = hash_lookup(table, &key, &value);
21e05273eed8cc914871938061554589883e67cePavel Březina if (hret == HASH_SUCCESS) {
21e05273eed8cc914871938061554589883e67cePavel Březina ret = sbus_iface_list_copy(list_ctx, value.ptr, &copy);
21e05273eed8cc914871938061554589883e67cePavel Březina if (ret != EOK) {
21e05273eed8cc914871938061554589883e67cePavel Březina goto done;
21e05273eed8cc914871938061554589883e67cePavel Březina }
21e05273eed8cc914871938061554589883e67cePavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březina DLIST_CONCATENATE(list, copy, struct sbus_interface_list *);
21e05273eed8cc914871938061554589883e67cePavel Březina } else if (hret != HASH_ERROR_KEY_NOT_FOUND) {
21e05273eed8cc914871938061554589883e67cePavel Březina DEBUG(SSSDBG_OP_FAILURE,
21e05273eed8cc914871938061554589883e67cePavel Březina "Unable to search hash table: hret=%d\n", hret);
21e05273eed8cc914871938061554589883e67cePavel Březina ret = EIO;
21e05273eed8cc914871938061554589883e67cePavel Březina goto done;
21e05273eed8cc914871938061554589883e67cePavel Březina }
21e05273eed8cc914871938061554589883e67cePavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březina /* we will not free lookup path since it is freed with tmp_ctx
21e05273eed8cc914871938061554589883e67cePavel Březina * and the object paths are supposed to be small */
21e05273eed8cc914871938061554589883e67cePavel Březina lookup_path = sbus_opath_parent_subtree(tmp_ctx, lookup_path);
21e05273eed8cc914871938061554589883e67cePavel Březina }
21e05273eed8cc914871938061554589883e67cePavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březina talloc_steal(mem_ctx, list_ctx);
21e05273eed8cc914871938061554589883e67cePavel Březina *_list = list;
21e05273eed8cc914871938061554589883e67cePavel Březina ret = EOK;
21e05273eed8cc914871938061554589883e67cePavel Březina
21e05273eed8cc914871938061554589883e67cePavel Březinadone:
21e05273eed8cc914871938061554589883e67cePavel Březina talloc_free(tmp_ctx);
21e05273eed8cc914871938061554589883e67cePavel Březina return ret;
21e05273eed8cc914871938061554589883e67cePavel Březina}
21e05273eed8cc914871938061554589883e67cePavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březinaerrno_t
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březinasbus_nodes_hash_init(TALLOC_CTX *mem_ctx,
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina struct sbus_connection *conn,
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina hash_table_t **_table)
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina{
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina return sss_hash_create_ex(mem_ctx, 10, _table, 0, 0, 0, 0,
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina NULL, conn);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina}
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březinastruct sbus_nodes_data {
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina sbus_nodes_fn nodes_fn;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina void *handler_data;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina};
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březinastatic errno_t
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březinasbus_nodes_hash_add(hash_table_t *table,
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina const char *object_path,
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina sbus_nodes_fn nodes_fn,
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina void *handler_data)
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina{
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina TALLOC_CTX *tmp_ctx;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina struct sbus_nodes_data *data;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina hash_key_t key;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina hash_value_t value;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina errno_t ret;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina bool has_key;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina int hret;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina tmp_ctx = talloc_new(NULL);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina if (tmp_ctx == NULL) {
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina return ENOMEM;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina }
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina key.type = HASH_KEY_STRING;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina key.str = talloc_strdup(tmp_ctx, object_path);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina if (key.str == NULL) {
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina return ENOMEM;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina }
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina has_key = hash_has_key(table, &key);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina if (has_key) {
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina ret = EEXIST;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina goto done;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina }
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina data = talloc_zero(tmp_ctx, struct sbus_nodes_data);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina if (data == NULL) {
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina ret = ENOMEM;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina goto done;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina }
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina data->handler_data = handler_data;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina data->nodes_fn = nodes_fn;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina value.type = HASH_VALUE_PTR;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina value.ptr = data;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina hret = hash_enter(table, &key, &value);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina if (hret != HASH_SUCCESS) {
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina ret = EIO;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina goto done;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina }
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina talloc_steal(table, key.str);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina talloc_steal(table, data);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina ret = EOK;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březinadone:
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina talloc_free(tmp_ctx);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina return ret;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina}
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březinaconst char **
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březinasbus_nodes_hash_lookup(TALLOC_CTX *mem_ctx,
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina hash_table_t *table,
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina const char *object_path)
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina{
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina struct sbus_nodes_data *data;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina hash_key_t key;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina hash_value_t value;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina int hret;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina key.type = HASH_KEY_STRING;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina key.str = discard_const(object_path);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina hret = hash_lookup(table, &key, &value);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina if (hret == HASH_ERROR_KEY_NOT_FOUND) {
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina return NULL;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina } else if (hret != HASH_SUCCESS) {
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina DEBUG(SSSDBG_OP_FAILURE,
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina "Unable to search hash table: hret=%d\n", hret);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina return NULL;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina }
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina data = talloc_get_type(value.ptr, struct sbus_nodes_data);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina return data->nodes_fn(mem_ctx, object_path, data->handler_data);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina}
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březinastatic struct sbus_interface *
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březinasbus_new_interface(TALLOC_CTX *mem_ctx,
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina const char *object_path,
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina struct sbus_vtable *iface_vtable,
66277b21179d95f6e96abed01a20ccbccf27ce99Pavel Březina void *handler_data)
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina{
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina struct sbus_interface *intf;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina intf = talloc_zero(mem_ctx, struct sbus_interface);
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina if (intf == NULL) {
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina DEBUG(SSSDBG_FATAL_FAILURE, "Cannot allocate a new sbus_interface.\n");
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina return NULL;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina }
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina intf->path = talloc_strdup(intf, object_path);
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina if (intf->path == NULL) {
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina DEBUG(SSSDBG_FATAL_FAILURE, "Cannot duplicate object path.\n");
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina talloc_free(intf);
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina return NULL;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina }
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina intf->vtable = iface_vtable;
66277b21179d95f6e96abed01a20ccbccf27ce99Pavel Březina intf->handler_data = handler_data;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina return intf;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina}
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinastatic DBusHandlerResult
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinasbus_message_handler(DBusConnection *dbus_conn,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina DBusMessage *message,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina void *user_data);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinastatic errno_t
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinasbus_conn_register_path(struct sbus_connection *conn,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina const char *path)
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina{
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina static DBusObjectPathVTable vtable = {NULL, sbus_message_handler,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina NULL, NULL, NULL, NULL};
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina DBusError error;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina char *reg_path = NULL;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina dbus_bool_t dbret;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina DEBUG(SSSDBG_TRACE_FUNC, "Registering object path %s with D-Bus "
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina "connection\n", path);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (sbus_opath_is_subtree(path)) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina reg_path = sbus_opath_get_base_path(conn, path);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (reg_path == NULL) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return ENOMEM;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* D-Bus does not allow to have both object path and fallback
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina * registered. Since we handle the real message handlers ourselves
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina * we will register fallback only in this case. */
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (sbus_opath_hash_has_path(conn->managed_paths, reg_path)) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina dbus_connection_unregister_object_path(conn->dbus.conn, reg_path);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina dbret = dbus_connection_register_fallback(conn->dbus.conn, reg_path,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina &vtable, conn);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina talloc_free(reg_path);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina } else {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina dbus_error_init(&error);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina dbret = dbus_connection_try_register_object_path(conn->dbus.conn, path,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina &vtable, conn, &error);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (dbus_error_is_set(&error) &&
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina strcmp(error.name, DBUS_ERROR_OBJECT_PATH_IN_USE) == 0) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* A fallback is probably already registered. Just return. */
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina dbus_error_free(&error);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return EOK;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina }
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (!dbret) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina DEBUG(SSSDBG_FATAL_FAILURE, "Unable to register object path "
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina "%s with D-Bus connection.\n", path);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return ENOMEM;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina }
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return EOK;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina}
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinaerrno_t
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinasbus_conn_register_iface(struct sbus_connection *conn,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina struct sbus_vtable *iface_vtable,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina const char *object_path,
66277b21179d95f6e96abed01a20ccbccf27ce99Pavel Březina void *handler_data)
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina{
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina struct sbus_interface *iface = NULL;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina bool path_known;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina errno_t ret;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (conn == NULL || iface_vtable == NULL || object_path == NULL) {
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina return EINVAL;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina }
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
66277b21179d95f6e96abed01a20ccbccf27ce99Pavel Březina iface = sbus_new_interface(conn, object_path, iface_vtable, handler_data);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (iface == NULL) {
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina return ENOMEM;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina ret = sbus_opath_hash_add_iface(conn->managed_paths, object_path, iface,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina &path_known);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (ret != EOK) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina talloc_free(iface);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return ret;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina }
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (path_known) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* this object path is already registered */
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return EOK;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* if ret != EOK we will still leave iface in the table, since
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina * we probably don't have enough memory to remove it correctly anyway */
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = sbus_conn_register_path(conn, object_path);
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina if (ret != EOK) {
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina return ret;
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina }
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina /* register standard interfaces with this object path as well */
b742179ac0790068380618ab72a06af18544f09cPavel Březina ret = sbus_conn_register_iface(conn, sbus_properties_vtable(),
b742179ac0790068380618ab72a06af18544f09cPavel Březina object_path, conn);
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (ret != EOK) {
b742179ac0790068380618ab72a06af18544f09cPavel Březina return ret;
b742179ac0790068380618ab72a06af18544f09cPavel Březina }
b742179ac0790068380618ab72a06af18544f09cPavel Březina
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina ret = sbus_conn_register_iface(conn, sbus_introspect_vtable(),
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina object_path, conn);
b742179ac0790068380618ab72a06af18544f09cPavel Březina if (ret != EOK) {
b742179ac0790068380618ab72a06af18544f09cPavel Březina return ret;
b742179ac0790068380618ab72a06af18544f09cPavel Březina }
80d0bd38268c02fd32f62b02ae59f19229ca1a79Pavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return ret;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina}
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březinaerrno_t
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březinasbus_conn_register_iface_map(struct sbus_connection *conn,
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březina struct sbus_iface_map *map,
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březina void *pvt)
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březina{
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březina errno_t ret;
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březina int i;
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březina
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březina for (i = 0; map[i].path != NULL; i++) {
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březina ret = sbus_conn_register_iface(conn, map[i].vtable, map[i].path, pvt);
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březina if (ret != EOK) {
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březina return ret;
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březina }
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březina }
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březina
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březina return EOK;
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březina}
397bc52dd09a8c032abc7ea47a6d81dba5957464Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březinavoid
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březinasbus_conn_register_nodes(struct sbus_connection *conn,
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina const char *path,
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina sbus_nodes_fn nodes_fn,
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina void *data)
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina{
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina errno_t ret;
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina ret = sbus_nodes_hash_add(conn->nodes_fns, path, nodes_fn, data);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina if (ret != EOK && ret != EEXIST) {
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina DEBUG(SSSDBG_MINOR_FAILURE, "Unable to register node function with "
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina "%s. Introspection may not work correctly.\n", path);
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina }
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina}
f7adbb15dbdcb79e291f7cf361a400ce25f7b382Pavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinaerrno_t
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinasbus_conn_reregister_paths(struct sbus_connection *conn)
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina{
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina hash_key_t *keys = NULL;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina unsigned long count;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina unsigned long i;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina errno_t ret;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina int hret;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina hret = hash_keys(conn->managed_paths, &count, &keys);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (hret != HASH_SUCCESS) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina ret = ENOMEM;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina goto done;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina for (i = 0; i < count; i++) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina ret = sbus_conn_register_path(conn, keys[i].str);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (ret != EOK) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina goto done;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina }
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina ret = EOK;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinadone:
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina talloc_free(keys);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return ret;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina}
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinastatic void
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinasbus_message_handler_got_caller_id(struct tevent_req *req);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinastatic DBusHandlerResult
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinasbus_message_handler(DBusConnection *dbus_conn,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina DBusMessage *message,
66277b21179d95f6e96abed01a20ccbccf27ce99Pavel Březina void *handler_data)
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina{
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina struct tevent_req *req;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina struct sbus_connection *conn;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina struct sbus_interface *iface;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina struct sbus_request *sbus_req;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina const struct sbus_method_meta *method;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina const char *iface_name;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina const char *method_name;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina const char *path;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina const char *sender;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
66277b21179d95f6e96abed01a20ccbccf27ce99Pavel Březina conn = talloc_get_type(handler_data, struct sbus_connection);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* header information */
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina iface_name = dbus_message_get_interface(message);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina method_name = dbus_message_get_member(message);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina path = dbus_message_get_path(message);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina sender = dbus_message_get_sender(message);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina DEBUG(SSSDBG_TRACE_INTERNAL, "Received SBUS method %s.%s on path %s\n",
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina iface_name, method_name, path);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* try to find the interface */
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina iface = sbus_opath_hash_lookup_iface(conn->managed_paths,
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina path, iface_name);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (iface == NULL) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina goto fail;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina method = sbus_meta_find_method(iface->vtable->meta, method_name);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (method == NULL || method->vtable_offset == 0) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina goto fail;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* we have a valid handler, create D-Bus request */
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina sbus_req = sbus_new_request(conn, iface, message);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (sbus_req == NULL) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return DBUS_HANDLER_RESULT_NEED_MEMORY;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina sbus_req->method = method;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina /* now get the sender ID */
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina req = sbus_get_sender_id_send(sbus_req, conn->ev, conn, sender);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (req == NULL) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina talloc_free(sbus_req);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return DBUS_HANDLER_RESULT_NEED_MEMORY;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina tevent_req_set_callback(req, sbus_message_handler_got_caller_id, sbus_req);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return DBUS_HANDLER_RESULT_HANDLED;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinafail: ;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina DBusMessage *reply;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "No matching handler found for method %s.%s "
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina "on path %s\n", iface_name, method_name, path);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina reply = dbus_message_new_error(message, DBUS_ERROR_UNKNOWN_METHOD, NULL);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina sbus_conn_send_reply(conn, reply);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return DBUS_HANDLER_RESULT_HANDLED;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina}
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinastatic void
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březinasbus_message_handler_got_caller_id(struct tevent_req *req)
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina{
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina struct sbus_request *sbus_req;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina const struct sbus_method_meta *method;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina sbus_msg_handler_fn handler;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina sbus_method_invoker_fn invoker;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina void *pvt;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina DBusError *error;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina errno_t ret;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina sbus_req = tevent_req_callback_data(req, struct sbus_request);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina method = sbus_req->method;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina ret = sbus_get_sender_id_recv(req, &sbus_req->client);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina if (ret != EOK) {
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to "
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina "resolve caller's ID: %s\n", sss_strerror(ret));
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina sbus_request_fail_and_finish(sbus_req, error);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina }
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina handler = VTABLE_FUNC(sbus_req->intf->vtable, method->vtable_offset);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina invoker = method->invoker;
66277b21179d95f6e96abed01a20ccbccf27ce99Pavel Březina pvt = sbus_req->intf->handler_data;
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina sbus_request_invoke_or_finish(sbus_req, handler, pvt, invoker);
46ee931314e6a5517f5c6b6b14f759364be119ccPavel Březina return;
d87e960c17d7598781cf032d06ba03a3ecadbfa2Pavel Březina}