diff options
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | src/sbus/sssd_dbus_connection.c | 189 | ||||
-rw-r--r-- | src/sbus/sssd_dbus_interface.c | 203 | ||||
-rw-r--r-- | src/sbus/sssd_dbus_private.h | 17 |
4 files changed, 220 insertions, 190 deletions
diff --git a/Makefile.am b/Makefile.am index ca8921bb1..fc03b11e1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -709,6 +709,7 @@ libsss_util_la_SOURCES = \ src/sbus/sssd_dbus_common.c \ src/sbus/sssd_dbus_connection.c \ src/sbus/sssd_dbus_meta.c \ + src/sbus/sssd_dbus_interface.c \ src/sbus/sssd_dbus_introspect.c \ src/sbus/sssd_dbus_properties.c \ src/sbus/sssd_dbus_request.c \ diff --git a/src/sbus/sssd_dbus_connection.c b/src/sbus/sssd_dbus_connection.c index 7fded56bc..d27fd2fad 100644 --- a/src/sbus/sssd_dbus_connection.c +++ b/src/sbus/sssd_dbus_connection.c @@ -30,21 +30,6 @@ /* Types */ struct dbus_ctx_list; -static DBusObjectPathVTable dbus_object_path_vtable = - { NULL, sbus_message_handler, NULL, NULL, NULL, NULL }; - -struct sbus_interface_p { - struct sbus_interface_p *prev, *next; - struct sbus_connection *conn; - struct sbus_interface *intf; - - const char *reg_path; -}; - -static bool path_in_interface_list(struct sbus_interface_p *list, - const char *path); -static void sbus_unreg_object_paths(struct sbus_connection *conn); - static int sbus_auto_reconnect(struct sbus_connection *conn); static void sbus_dispatch(struct tevent_context *ev, @@ -357,43 +342,6 @@ void sbus_disconnect(struct sbus_connection *conn) DEBUG(SSSDBG_TRACE_FUNC ,"Disconnected %p\n", conn->dbus.conn); } -static bool sbus_fb_path_has_prefix(const char *path, const char *prefix) -{ - /* strlen-1 because we don't want to match the trailing '*' */ - if (strncmp(path, prefix, strlen(prefix)-1) == 0) { - return true; - } - - return false; -} - -static bool sbus_path_has_fallback(const char *path) -{ - char *wildcard; - - wildcard = strrchr(path, '*'); - if (wildcard != NULL) { - /* This path was registered as fallback */ - if (*(wildcard + 1) != '\0') { - /* Wildcard is only allowed as the last character in the path */ - return false; - } - return true; - } - - return false; -} - -static bool sbus_iface_handles_path(struct sbus_interface_p *intf_p, - const char *path) -{ - if (sbus_path_has_fallback(intf_p->intf->path)) { - return sbus_fb_path_has_prefix(path, intf_p->intf->path); - } - - return strcmp(path, intf_p->intf->path) == 0; -} - static void sbus_handler_got_caller_id(struct tevent_req *req); /* messsage_handler @@ -565,143 +513,6 @@ fail: sbus_request_finish(dbus_req, reply); } -static struct sbus_interface * -sbus_new_interface(TALLOC_CTX *mem_ctx, - const char *object_path, - struct sbus_vtable *iface_vtable, - void *instance_data) -{ - struct sbus_interface *intf; - - intf = talloc_zero(mem_ctx, struct sbus_interface); - if (intf == NULL) { - DEBUG(SSSDBG_FATAL_FAILURE, "Cannot allocate a new sbus_interface.\n"); - return NULL; - } - - intf->path = talloc_strdup(intf, object_path); - if (intf->path == NULL) { - DEBUG(SSSDBG_FATAL_FAILURE, "Cannot duplicate object path.\n"); - talloc_free(intf); - return NULL; - } - - intf->vtable = iface_vtable; - intf->instance_data = instance_data; - return intf; -} - -static char *sbus_iface_get_reg_path(TALLOC_CTX *mem_ctx, - const char *path, - bool fallback) -{ - char *reg_path; - - reg_path = talloc_strdup(mem_ctx, path); - if (reg_path == NULL) return NULL; - - if (fallback) { - reg_path[strlen(path)-1] = '\0'; - } - return reg_path; -} - -int sbus_conn_register_iface(struct sbus_connection *conn, - struct sbus_vtable *iface_vtable, - const char *object_path, - void *pvt) -{ - struct sbus_interface_p *intf_p; - struct sbus_interface *intf; - dbus_bool_t dbret; - const char *path; - bool fallback; - - intf = sbus_new_interface(conn, object_path, iface_vtable, pvt); - if (intf == NULL) { - return ENOMEM; - } - - if (!conn || !intf->vtable || !intf->vtable->meta) { - return EINVAL; - } - - path = intf->path; - fallback = sbus_path_has_fallback(path); - - if (path_in_interface_list(conn->intf_list, path)) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Cannot add method context with identical path.\n"); - return EINVAL; - } - - intf_p = talloc_zero(conn, struct sbus_interface_p); - if (!intf_p) { - return ENOMEM; - } - intf_p->conn = conn; - intf_p->intf = intf; - intf_p->reg_path = sbus_iface_get_reg_path(intf_p, path, fallback); - if (intf_p->reg_path == NULL) { - return ENOMEM; - } - - DLIST_ADD(conn->intf_list, intf_p); - - DEBUG(SSSDBG_TRACE_LIBS, "Will register path %s with%s fallback\n", - intf_p->reg_path, fallback ? "" : "out"); - - if (fallback) { - dbret = dbus_connection_register_fallback(conn->dbus.conn, - intf_p->reg_path, - &dbus_object_path_vtable, - intf_p); - } else { - dbret = dbus_connection_register_object_path(conn->dbus.conn, - intf_p->reg_path, - &dbus_object_path_vtable, - intf_p); - } - if (!dbret) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Could not register object path to the connection.\n"); - return ENOMEM; - } - - return EOK; -} - -static bool path_in_interface_list(struct sbus_interface_p *list, - const char *path) -{ - struct sbus_interface_p *iter; - - if (!list || !path) { - return false; - } - - iter = list; - while (iter != NULL) { - if (strcmp(iter->intf->path, path) == 0) { - return true; - } - iter = iter->next; - } - - return false; -} - -static void sbus_unreg_object_paths(struct sbus_connection *conn) -{ - struct sbus_interface_p *iter = conn->intf_list; - - while (iter != NULL) { - dbus_connection_unregister_object_path(conn->dbus.conn, - iter->intf->path); - iter = iter->next; - } -} - static void sbus_reconnect(struct tevent_context *ev, struct tevent_timer *te, struct timeval tv, void *data) diff --git a/src/sbus/sssd_dbus_interface.c b/src/sbus/sssd_dbus_interface.c new file mode 100644 index 000000000..ab1bdbe9b --- /dev/null +++ b/src/sbus/sssd_dbus_interface.c @@ -0,0 +1,203 @@ +/* + Authors: + Pavel Březina <pbrezina@redhat.com> + + Copyright (C) 2014 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <talloc.h> +#include <dbus/dbus.h> + +#include "util/util.h" +#include "sbus/sssd_dbus.h" +#include "sbus/sssd_dbus_private.h" + +DBusObjectPathVTable dbus_object_path_vtable = + { NULL, sbus_message_handler, NULL, NULL, NULL, NULL }; + +static char *sbus_iface_get_reg_path(TALLOC_CTX *mem_ctx, + const char *path, + bool fallback) +{ + char *reg_path; + + reg_path = talloc_strdup(mem_ctx, path); + if (reg_path == NULL) return NULL; + + if (fallback) { + reg_path[strlen(path)-1] = '\0'; + } + return reg_path; +} + +static bool path_in_interface_list(struct sbus_interface_p *list, + const char *path) +{ + struct sbus_interface_p *iter; + + if (!list || !path) { + return false; + } + + iter = list; + while (iter != NULL) { + if (strcmp(iter->intf->path, path) == 0) { + return true; + } + iter = iter->next; + } + + return false; +} + +void sbus_unreg_object_paths(struct sbus_connection *conn) +{ + struct sbus_interface_p *iter = conn->intf_list; + + while (iter != NULL) { + dbus_connection_unregister_object_path(conn->dbus.conn, + iter->intf->path); + iter = iter->next; + } +} + +static bool sbus_fb_path_has_prefix(const char *path, const char *prefix) +{ + /* strlen-1 because we don't want to match the trailing '*' */ + if (strncmp(path, prefix, strlen(prefix)-1) == 0) { + return true; + } + + return false; +} + +static bool sbus_path_has_fallback(const char *path) +{ + char *wildcard; + + wildcard = strrchr(path, '*'); + if (wildcard != NULL) { + /* This path was registered as fallback */ + if (*(wildcard + 1) != '\0') { + /* Wildcard is only allowed as the last character in the path */ + return false; + } + return true; + } + + return false; +} + +bool sbus_iface_handles_path(struct sbus_interface_p *intf_p, + const char *path) +{ + if (sbus_path_has_fallback(intf_p->intf->path)) { + return sbus_fb_path_has_prefix(path, intf_p->intf->path); + } + + return strcmp(path, intf_p->intf->path) == 0; +} + +static struct sbus_interface * +sbus_new_interface(TALLOC_CTX *mem_ctx, + const char *object_path, + struct sbus_vtable *iface_vtable, + void *instance_data) +{ + struct sbus_interface *intf; + + intf = talloc_zero(mem_ctx, struct sbus_interface); + if (intf == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Cannot allocate a new sbus_interface.\n"); + return NULL; + } + + intf->path = talloc_strdup(intf, object_path); + if (intf->path == NULL) { + DEBUG(SSSDBG_FATAL_FAILURE, "Cannot duplicate object path.\n"); + talloc_free(intf); + return NULL; + } + + intf->vtable = iface_vtable; + intf->instance_data = instance_data; + return intf; +} + +int sbus_conn_register_iface(struct sbus_connection *conn, + struct sbus_vtable *iface_vtable, + const char *object_path, + void *pvt) +{ + struct sbus_interface_p *intf_p; + struct sbus_interface *intf; + dbus_bool_t dbret; + const char *path; + bool fallback; + + intf = sbus_new_interface(conn, object_path, iface_vtable, pvt); + if (intf == NULL) { + return ENOMEM; + } + + if (!conn || !intf->vtable || !intf->vtable->meta) { + return EINVAL; + } + + path = intf->path; + fallback = sbus_path_has_fallback(path); + + if (path_in_interface_list(conn->intf_list, path)) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Cannot add method context with identical path.\n"); + return EINVAL; + } + + intf_p = talloc_zero(conn, struct sbus_interface_p); + if (!intf_p) { + return ENOMEM; + } + intf_p->conn = conn; + intf_p->intf = intf; + intf_p->reg_path = sbus_iface_get_reg_path(intf_p, path, fallback); + if (intf_p->reg_path == NULL) { + return ENOMEM; + } + + DLIST_ADD(conn->intf_list, intf_p); + + DEBUG(SSSDBG_TRACE_LIBS, "Will register path %s with%s fallback\n", + intf_p->reg_path, fallback ? "" : "out"); + + if (fallback) { + dbret = dbus_connection_register_fallback(conn->dbus.conn, + intf_p->reg_path, + &dbus_object_path_vtable, + intf_p); + } else { + dbret = dbus_connection_register_object_path(conn->dbus.conn, + intf_p->reg_path, + &dbus_object_path_vtable, + intf_p); + } + if (!dbret) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Could not register object path to the connection.\n"); + return ENOMEM; + } + + return EOK; +} diff --git a/src/sbus/sssd_dbus_private.h b/src/sbus/sssd_dbus_private.h index 624448d30..fc63405a1 100644 --- a/src/sbus/sssd_dbus_private.h +++ b/src/sbus/sssd_dbus_private.h @@ -35,9 +35,16 @@ enum dbus_conn_type { SBUS_CONNECTION }; -struct sbus_interface_p; struct sbus_watch_ctx; +struct sbus_interface_p { + struct sbus_interface_p *prev, *next; + struct sbus_connection *conn; + struct sbus_interface *intf; + + const char *reg_path; +}; + struct sbus_connection { struct tevent_context *ev; @@ -68,6 +75,8 @@ struct sbus_connection { struct sbus_watch_ctx *watch_list; }; +extern DBusObjectPathVTable dbus_object_path_vtable; + /* =Watches=============================================================== */ struct sbus_watch_ctx { @@ -103,6 +112,12 @@ struct sbus_request * sbus_new_request(struct sbus_connection *conn, struct sbus_interface *intf, DBusMessage *message); +/* =Interface=and=object=paths============================================ */ + +void sbus_unreg_object_paths(struct sbus_connection *conn); +bool sbus_iface_handles_path(struct sbus_interface_p *intf_p, + const char *path); + /* =Interface=introspection=============================================== */ extern const struct sbus_method_meta introspect_method; |