[SSSD] [PATCH] SBUS: Allow registering paths with fallback

Jakub Hrozek jhrozek at redhat.com
Mon May 12 21:19:08 UTC 2014


Hi,

Some interfaces we support, such as domain might not be bound to a single
path, but rather anything under a path 'directory'. This patch allows the
SBUS to register a fallback path that would route any messages under a
given anchor to a handler of an interface.

Pavel Brezina had an idea of making the handler interface-driven instead
of path-driven and I would like to match the paths based on object that
were really found and exist, but I believe this patch is good enough to
allow further development on master and we can improve on it later on.
-------------- next part --------------
>From e31b22a63d412c72ebcbbb819faf84368fa06be3 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Wed, 23 Apr 2014 01:08:26 +0200
Subject: [PATCH] SBUS: Allow registering paths with fallback

Some interfaces we support, such as domain might not be bound to a
single path, but rather anything under a path 'directory'. This patch
allows the SBUS to register a fallback path that would route any
messages under a given anchor to a handler of an interface.

The fallback interface is denoted with a trailing wildcard:
    /org/sssd/anchor/*
---
 src/sbus/sssd_dbus_connection.c | 80 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 76 insertions(+), 4 deletions(-)

diff --git a/src/sbus/sssd_dbus_connection.c b/src/sbus/sssd_dbus_connection.c
index 618ca63d034affd5e4be080b160ec04abbbc4c22..63eac8ffa5728246a80daafe02f1df65b1493d87 100644
--- a/src/sbus/sssd_dbus_connection.c
+++ b/src/sbus/sssd_dbus_connection.c
@@ -37,6 +37,8 @@ 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,
@@ -355,6 +357,43 @@ 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;
+}
+
 /* Looks up a vtable func, in a struct derived from struct sbus_vtable */
 #define VTABLE_FUNC(vtable, offset) \
     (*((void **)((char *)(vtable) + (offset))))
@@ -392,7 +431,7 @@ DBusHandlerResult sbus_message_handler(DBusConnection *dbus_conn,
     }
 
     /* Validate the D-BUS path */
-    if (strcmp(path, intf_p->intf->path) != 0) {
+    if (!sbus_iface_handles_path(intf_p, path)) {
         return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     }
 
@@ -553,21 +592,38 @@ sbus_new_interface(TALLOC_CTX *mem_ctx,
     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;
+}
+
 /* Adds a new D-BUS path message handler to the connection
  * Note: this must be a unique path.
  */
 int sbus_conn_add_interface(struct sbus_connection *conn,
-                             struct sbus_interface *intf)
+                            struct sbus_interface *intf)
 {
     struct sbus_interface_p *intf_p;
     dbus_bool_t dbret;
     const char *path;
+    bool fallback;
 
     if (!conn || !intf || !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,
@@ -581,11 +637,27 @@ int sbus_conn_add_interface(struct sbus_connection *conn,
     }
     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);
 
-    dbret = dbus_connection_register_object_path(conn->dbus.conn,
-                                                 path, &dbus_object_path_vtable, 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");
-- 
1.9.0



More information about the sssd-devel mailing list