diff options
author | Pavel Březina <pbrezina@redhat.com> | 2015-05-20 14:14:53 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2015-06-18 16:44:07 +0200 |
commit | f7adbb15dbdcb79e291f7cf361a400ce25f7b382 (patch) | |
tree | 44581d061f7c2ee1a1e00e24820c1be88654b990 /src | |
parent | c5184e9eeb0fd0bc4749677d2f74256515199b46 (diff) | |
download | sssd-f7adbb15dbdcb79e291f7cf361a400ce25f7b382.tar.gz sssd-f7adbb15dbdcb79e291f7cf361a400ce25f7b382.tar.xz sssd-f7adbb15dbdcb79e291f7cf361a400ce25f7b382.zip |
SBUS: Add support for <node /> in introspection
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/sbus/sssd_dbus.h | 10 | ||||
-rw-r--r-- | src/sbus/sssd_dbus_connection.c | 7 | ||||
-rw-r--r-- | src/sbus/sssd_dbus_interface.c | 115 | ||||
-rw-r--r-- | src/sbus/sssd_dbus_introspect.c | 41 | ||||
-rw-r--r-- | src/sbus/sssd_dbus_private.h | 11 | ||||
-rw-r--r-- | src/tests/sbus_tests.c | 2 |
6 files changed, 181 insertions, 5 deletions
diff --git a/src/sbus/sssd_dbus.h b/src/sbus/sssd_dbus.h index 61c18ae28..818070fa5 100644 --- a/src/sbus/sssd_dbus.h +++ b/src/sbus/sssd_dbus.h @@ -80,6 +80,10 @@ typedef void (*sbus_conn_reconn_callback_fn)(struct sbus_connection *, int, void */ typedef int (*sbus_server_conn_init_fn)(struct sbus_connection *, void *); +typedef const char ** (* sbus_nodes_fn)(TALLOC_CTX *mem_ctx, + const char *path, + void *data); + enum { SBUS_CONN_TYPE_PRIVATE = 1, SBUS_CONN_TYPE_SHARED, @@ -177,6 +181,12 @@ int sbus_conn_register_iface(struct sbus_connection *conn, const char *object_path, void *handler_data); +void +sbus_conn_register_nodes(struct sbus_connection *conn, + const char *path, + sbus_nodes_fn nodes_fn, + void *data); + errno_t sbus_conn_reregister_paths(struct sbus_connection *conn); diff --git a/src/sbus/sssd_dbus_connection.c b/src/sbus/sssd_dbus_connection.c index 8ff279c1b..d0df95bb2 100644 --- a/src/sbus/sssd_dbus_connection.c +++ b/src/sbus/sssd_dbus_connection.c @@ -168,6 +168,13 @@ int sbus_init_connection(TALLOC_CTX *ctx, return EIO; } + ret = sbus_nodes_hash_init(conn, conn, &conn->nodes_fns); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create node functions hash table\n"); + talloc_free(conn); + return EIO; + } + ret = sss_hash_create(conn, 32, &conn->clients); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create clients hash table\n"); diff --git a/src/sbus/sssd_dbus_interface.c b/src/sbus/sssd_dbus_interface.c index 1651478a8..f8046c7c1 100644 --- a/src/sbus/sssd_dbus_interface.c +++ b/src/sbus/sssd_dbus_interface.c @@ -732,6 +732,106 @@ done: return ret; } +errno_t +sbus_nodes_hash_init(TALLOC_CTX *mem_ctx, + struct sbus_connection *conn, + hash_table_t **_table) +{ + return sss_hash_create_ex(mem_ctx, 10, _table, 0, 0, 0, 0, + NULL, conn); +} + +struct sbus_nodes_data { + sbus_nodes_fn nodes_fn; + void *handler_data; +}; + +static errno_t +sbus_nodes_hash_add(hash_table_t *table, + const char *object_path, + sbus_nodes_fn nodes_fn, + void *handler_data) +{ + TALLOC_CTX *tmp_ctx; + struct sbus_nodes_data *data; + hash_key_t key; + hash_value_t value; + errno_t ret; + bool has_key; + int hret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + return ENOMEM; + } + + key.type = HASH_KEY_STRING; + key.str = talloc_strdup(tmp_ctx, object_path); + if (key.str == NULL) { + return ENOMEM; + } + + has_key = hash_has_key(table, &key); + if (has_key) { + ret = EEXIST; + goto done; + } + + data = talloc_zero(tmp_ctx, struct sbus_nodes_data); + if (data == NULL) { + ret = ENOMEM; + goto done; + } + + data->handler_data = handler_data; + data->nodes_fn = nodes_fn; + + value.type = HASH_VALUE_PTR; + value.ptr = data; + + hret = hash_enter(table, &key, &value); + if (hret != HASH_SUCCESS) { + ret = EIO; + goto done; + } + + talloc_steal(table, key.str); + talloc_steal(table, data); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} + +const char ** +sbus_nodes_hash_lookup(TALLOC_CTX *mem_ctx, + hash_table_t *table, + const char *object_path) +{ + struct sbus_nodes_data *data; + hash_key_t key; + hash_value_t value; + int hret; + + key.type = HASH_KEY_STRING; + key.str = discard_const(object_path); + + hret = hash_lookup(table, &key, &value); + if (hret == HASH_ERROR_KEY_NOT_FOUND) { + return NULL; + } else if (hret != HASH_SUCCESS) { + DEBUG(SSSDBG_OP_FAILURE, + "Unable to search hash table: hret=%d\n", hret); + return NULL; + } + + data = talloc_get_type(value.ptr, struct sbus_nodes_data); + + return data->nodes_fn(mem_ctx, object_path, data->handler_data); +} + static struct sbus_interface * sbus_new_interface(TALLOC_CTX *mem_ctx, const char *object_path, @@ -870,6 +970,21 @@ sbus_conn_register_iface(struct sbus_connection *conn, return ret; } +void +sbus_conn_register_nodes(struct sbus_connection *conn, + const char *path, + sbus_nodes_fn nodes_fn, + void *data) +{ + errno_t ret; + + ret = sbus_nodes_hash_add(conn->nodes_fns, path, nodes_fn, data); + if (ret != EOK && ret != EEXIST) { + DEBUG(SSSDBG_MINOR_FAILURE, "Unable to register node function with " + "%s. Introspection may not work correctly.\n", path); + } +} + errno_t sbus_conn_reregister_paths(struct sbus_connection *conn) { diff --git a/src/sbus/sssd_dbus_introspect.c b/src/sbus/sssd_dbus_introspect.c index 34279c8d4..a66432dd9 100644 --- a/src/sbus/sssd_dbus_introspect.c +++ b/src/sbus/sssd_dbus_introspect.c @@ -34,7 +34,7 @@ "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n" \ " \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n" -#define FMT_NODE "<node>\n" +#define FMT_NODE "<node name=\"%s\">\n" #define FMT_IFACE " <interface name=\"%s\">\n" #define FMT_METHOD " <method name=\"%s\">\n" #define FMT_METHOD_NOARG " <method name=\"%s\" />\n" @@ -46,6 +46,7 @@ #define FMT_SIGNAL_CLOSE " </signal>\n" #define FMT_PROPERTY " <property name=\"%s\" type=\"%s\" access=\"%s\" />\n" #define FMT_IFACE_CLOSE " </interface>\n" +#define FMT_CHILD_NODE " <node name=\"%s\" />\n" #define FMT_NODE_CLOSE "</node>\n" #define WRITE_OR_FAIL(file, ret, label, fmt, ...) do { \ @@ -294,8 +295,31 @@ done: return ret; } +static int +sbus_introspect_generate_nodes(FILE *file, const char **nodes) +{ + int ret; + int i; + + if (nodes == NULL) { + return EOK; + } + + for (i = 0; nodes[i] != NULL; i++) { + WRITE_OR_FAIL(file, ret, done, FMT_CHILD_NODE, nodes[i]); + } + + ret = EOK; + +done: + return ret; +} + static char * -sbus_introspect_generate(TALLOC_CTX *mem_ctx, struct sbus_interface_list *list) +sbus_introspect_generate(TALLOC_CTX *mem_ctx, + const char *node, + const char **nodes, + struct sbus_interface_list *list) { struct sbus_interface_list *item; char *introspect = NULL; @@ -310,7 +334,7 @@ sbus_introspect_generate(TALLOC_CTX *mem_ctx, struct sbus_interface_list *list) } WRITE_OR_FAIL(memstream, ret, done, FMT_DOCTYPE); - WRITE_OR_FAIL(memstream, ret, done, FMT_NODE); + WRITE_OR_FAIL(memstream, ret, done, FMT_NODE, node); DLIST_FOR_EACH(item, list) { ret = sbus_introspect_generate_iface(memstream, item->interface); @@ -319,6 +343,11 @@ sbus_introspect_generate(TALLOC_CTX *mem_ctx, struct sbus_interface_list *list) } } + ret = sbus_introspect_generate_nodes(memstream, nodes); + if (ret != EOK) { + goto done; + } + WRITE_OR_FAIL(memstream, ret, done, FMT_NODE_CLOSE); fflush(memstream); @@ -341,6 +370,7 @@ sbus_introspect(struct sbus_request *sbus_req, void *pvt) DBusError *error; struct sbus_interface_list *list; struct sbus_connection *conn; + const char **nodes; char *introspect; errno_t ret; @@ -354,7 +384,10 @@ sbus_introspect(struct sbus_request *sbus_req, void *pvt) return sbus_request_fail_and_finish(sbus_req, error); } - introspect = sbus_introspect_generate(sbus_req, list); + nodes = sbus_nodes_hash_lookup(sbus_req, conn->nodes_fns, sbus_req->path); + + introspect = sbus_introspect_generate(sbus_req, sbus_req->path, + nodes, list); if (introspect == NULL) { ret = ENOMEM; goto done; diff --git a/src/sbus/sssd_dbus_private.h b/src/sbus/sssd_dbus_private.h index 24b6bec18..0493e1536 100644 --- a/src/sbus/sssd_dbus_private.h +++ b/src/sbus/sssd_dbus_private.h @@ -48,6 +48,7 @@ struct sbus_connection { int disconnect; hash_table_t *managed_paths; + hash_table_t *nodes_fns; /* reconnect settings */ int retries; @@ -129,6 +130,16 @@ sbus_opath_hash_lookup_supported(TALLOC_CTX *mem_ctx, const char *object_path, struct sbus_interface_list **_list); +errno_t +sbus_nodes_hash_init(TALLOC_CTX *mem_ctx, + struct sbus_connection *conn, + hash_table_t **_table); + +const char ** +sbus_nodes_hash_lookup(TALLOC_CTX *mem_ctx, + hash_table_t *table, + const char *object_path); + void sbus_request_invoke_or_finish(struct sbus_request *dbus_req, sbus_msg_handler_fn handler_fn, diff --git a/src/tests/sbus_tests.c b/src/tests/sbus_tests.c index 47d0556cf..598cc536d 100644 --- a/src/tests/sbus_tests.c +++ b/src/tests/sbus_tests.c @@ -47,7 +47,7 @@ #define PILOT_IFACE_INTROSPECT \ "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n" \ " \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n" \ - "<node>\n" \ + "<node name=\"/test/leela\">\n" \ " <interface name=\"org.freedesktop.DBus.Introspectable\">\n" \ " <method name=\"Introspect\">\n" \ " <arg type=\"s\" name=\"data\" direction=\"out\" />\n" \ |