>From 5cff5263f39556da41da26d9448ce25ce96d8d03 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 16 Dec 2014 15:25:38 +0100
Subject: [PATCH 2/5] sbus: add sbus_opath_get_object_name()

This function assumes that the last component of the object path
is an object name. It will return the part unescaped.
---
 src/responder/ifp/ifp_components.c | 25 +++++++++++--------------
 src/responder/ifp/ifp_domains.c    | 10 ++--------
 src/sbus/sssd_dbus.h               |  5 +++++
 src/sbus/sssd_dbus_interface.c     | 20 ++++++++++++++++++++
 src/tests/cmocka/test_sbus_opath.c | 33 +++++++++++++++++++++++++++++----
 5 files changed, 67 insertions(+), 26 deletions(-)

diff --git a/src/responder/ifp/ifp_components.c b/src/responder/ifp/ifp_components.c
index 5847a767d220c1305f1cbd54a2361da87ca286b0..fbccc7e4be2e11699ffb5ba267db05be7d01e00d 100644
--- a/src/responder/ifp/ifp_components.c
+++ b/src/responder/ifp/ifp_components.c
@@ -85,8 +85,7 @@ static errno_t check_and_get_component_from_path(TALLOC_CTX *mem_ctx,
                                                  char **_name)
 {
     enum component_type type;
-    const char *name = NULL;
-    char *safe_name = NULL;
+    char *name = NULL;
     errno_t ret;
 
     if (confdb == NULL || path == NULL) {
@@ -95,13 +94,17 @@ static errno_t check_and_get_component_from_path(TALLOC_CTX *mem_ctx,
 
     if (strcmp(path, PATH_MONITOR) == 0) {
         type = COMPONENT_MONITOR;
-        name = "monitor";
+        name = talloc_strdup(mem_ctx, "monitor");
+        if (name == NULL) {
+            ret = ENOMEM;
+            goto done;
+        }
     } else {
-        name = sbus_opath_strip_prefix(path, PATH_RESPONDERS "/");
+        name = sbus_opath_get_object_name(mem_ctx, path, PATH_RESPONDERS);
         if (name != NULL) {
             type = COMPONENT_RESPONDER;
         } else {
-            name = sbus_opath_strip_prefix(path, PATH_BACKENDS "/");
+            name = sbus_opath_get_object_name(mem_ctx, path, PATH_BACKENDS);
             if (name != NULL) {
                 type = COMPONENT_BACKEND;
             } else {
@@ -116,24 +119,18 @@ static errno_t check_and_get_component_from_path(TALLOC_CTX *mem_ctx,
         goto done;
     }
 
-    safe_name = sbus_opath_unescape_part(mem_ctx, name);
-    if (safe_name == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-
     switch (type) {
     case COMPONENT_MONITOR:
         /* noop */
         break;
     case COMPONENT_RESPONDER:
-        if (!responder_exists(safe_name)) {
+        if (!responder_exists(name)) {
             ret = ENOENT;
             goto done;
         }
         break;
     case COMPONENT_BACKEND:
-        if (!backend_exists(confdb, safe_name)) {
+        if (!backend_exists(confdb, name)) {
             ret = ENOENT;
             goto done;
         }
@@ -145,7 +142,7 @@ static errno_t check_and_get_component_from_path(TALLOC_CTX *mem_ctx,
     }
 
     if (_name != NULL) {
-        *_name = safe_name;
+        *_name = name;
     }
 
     ret = EOK;
diff --git a/src/responder/ifp/ifp_domains.c b/src/responder/ifp/ifp_domains.c
index 0af81af817037c06111eb67b0256c87c6bb4781a..7cddb2ebcb864f0e07cad8688d69ae85942bac24 100644
--- a/src/responder/ifp/ifp_domains.c
+++ b/src/responder/ifp/ifp_domains.c
@@ -254,7 +254,6 @@ get_domain_info_from_req(struct sbus_request *dbus_req, void *data)
     struct ifp_ctx *ctx = NULL;
     struct sss_domain_info *domains = NULL;
     struct sss_domain_info *iter = NULL;
-    const char *raw_name = NULL;
     char *name = NULL;
 
     ctx = talloc_get_type(data, struct ifp_ctx);
@@ -263,13 +262,8 @@ get_domain_info_from_req(struct sbus_request *dbus_req, void *data)
         return NULL;
     }
 
-    raw_name = sbus_opath_strip_prefix(dbus_req->path,
-                                       INFOPIPE_DOMAIN_PATH_PFX "/");
-    if (raw_name == NULL) {
-        return NULL;
-    }
-
-    name = sbus_opath_unescape_part(dbus_req, raw_name);
+    name = sbus_opath_get_object_name(dbus_req, dbus_req->path,
+                                      INFOPIPE_DOMAIN_PATH_PFX);
     if (name == NULL) {
         return NULL;
     }
diff --git a/src/sbus/sssd_dbus.h b/src/sbus/sssd_dbus.h
index d76fcc28e301f350b5ccddcc0ed079a3dab5740f..c6a69e2065777385af6ff5f5ed753cd8a371c200 100644
--- a/src/sbus/sssd_dbus.h
+++ b/src/sbus/sssd_dbus.h
@@ -193,6 +193,11 @@ const char *
 sbus_opath_strip_prefix(const char *object_path,
                         const char *prefix);
 
+char *
+sbus_opath_get_object_name(TALLOC_CTX *mem_ctx,
+                           const char *object_path,
+                           const char *base_path);
+
 bool sbus_conn_disconnecting(struct sbus_connection *conn);
 
 /* max_retries < 0: retry forever
diff --git a/src/sbus/sssd_dbus_interface.c b/src/sbus/sssd_dbus_interface.c
index 3f509c96e1e59a7bc005497fb5ab63ebc9932e34..40ea4310d452726fc49d2a6c604c57e409a082b1 100644
--- a/src/sbus/sssd_dbus_interface.c
+++ b/src/sbus/sssd_dbus_interface.c
@@ -365,6 +365,26 @@ sbus_opath_strip_prefix(const char *object_path,
     return NULL;
 }
 
+char *
+sbus_opath_get_object_name(TALLOC_CTX *mem_ctx,
+                           const char *object_path,
+                           const char *base_path)
+{
+    const char *name;
+
+    name = sbus_opath_strip_prefix(object_path, base_path);
+    if (name == NULL || name[0] == '\0') {
+        return NULL;
+    }
+
+    /* if base_path did not end with / */
+    if (name[0] == '/') {
+        name = name + 1;
+    }
+
+    return sbus_opath_unescape_part(mem_ctx, name);
+}
+
 static void
 sbus_opath_hash_delete_cb(hash_entry_t *item,
                           hash_destroy_enum deltype,
diff --git a/src/tests/cmocka/test_sbus_opath.c b/src/tests/cmocka/test_sbus_opath.c
index b526c88734c626c9c1d4c69d89e05fdff9f32cb1..a91a3e2f65506567c98310520ae1b862d8ae7955 100644
--- a/src/tests/cmocka/test_sbus_opath.c
+++ b/src/tests/cmocka/test_sbus_opath.c
@@ -27,6 +27,8 @@
 #include "tests/cmocka/common_mock.h"
 #include "tests/common.h"
 
+#define BASE_PATH "/some/path"
+
 void test_sbus_opath_strip_prefix(void **state)
 {
     const char *prefix = "/org/freedesktop/sssd/";
@@ -102,9 +104,9 @@ void test_sbus_opath_compose(void **state)
     char *path;
 
     /* Doesn't need escaping */
-    path = sbus_opath_compose(NULL, "/base/path", "domname");
+    path = sbus_opath_compose(NULL, BASE_PATH, "domname");
     assert_non_null(path);
-    assert_string_equal(path, "/base/path/domname");
+    assert_string_equal(path, BASE_PATH "/domname");
     talloc_free(path);
 }
 
@@ -113,12 +115,34 @@ void test_sbus_opath_compose_escape(void **state)
     char *path;
 
     /* A dot needs escaping */
-    path = sbus_opath_compose(NULL, "/base/path", "redhat.com", NULL);
+    path = sbus_opath_compose(NULL, BASE_PATH, "redhat.com", NULL);
     assert_non_null(path);
-    assert_string_equal(path, "/base/path/redhat_2ecom");
+    assert_string_equal(path, BASE_PATH "/redhat_2ecom");
     talloc_free(path);
 }
 
+void test_sbus_opath_get_object_name(void **state)
+{
+    const char *path = BASE_PATH "/redhat_2ecom";
+    char *name;
+
+    name = sbus_opath_get_object_name(NULL, path, BASE_PATH);
+    assert_non_null(name);
+    assert_string_equal(name, "redhat.com");
+    talloc_free(name);
+
+    name = sbus_opath_get_object_name(NULL, path, BASE_PATH "/");
+    assert_non_null(name);
+    assert_string_equal(name, "redhat.com");
+    talloc_free(name);
+
+    name = sbus_opath_get_object_name(NULL, BASE_PATH, BASE_PATH);
+    assert_null(name);
+
+    name = sbus_opath_get_object_name(NULL, "invalid", BASE_PATH);
+    assert_null(name);
+}
+
 int main(int argc, const char *argv[])
 {
     poptContext pc;
@@ -134,6 +158,7 @@ int main(int argc, const char *argv[])
         unit_test(test_sbus_opath_escape_unescape),
         unit_test(test_sbus_opath_compose),
         unit_test(test_sbus_opath_compose_escape),
+        unit_test(test_sbus_opath_get_object_name)
     };
 
     /* Set debug level to invalid value so we can deside if -d 0 was used. */
-- 
1.9.3

