summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/responder/ifp/ifp_components.c14
-rw-r--r--src/responder/ifp/ifp_domains.c14
-rw-r--r--src/responder/ifp/ifp_private.h11
-rw-r--r--src/responder/ifp/ifpsrv_util.c181
-rw-r--r--src/sbus/sssd_dbus.h20
-rw-r--r--src/sbus/sssd_dbus_interface.c194
-rw-r--r--src/tests/cmocka/test_ifp.c98
-rw-r--r--src/tests/cmocka/test_sbus_opath.c157
8 files changed, 385 insertions, 304 deletions
diff --git a/src/responder/ifp/ifp_components.c b/src/responder/ifp/ifp_components.c
index 2b76a480d..5847a767d 100644
--- a/src/responder/ifp/ifp_components.c
+++ b/src/responder/ifp/ifp_components.c
@@ -97,11 +97,11 @@ static errno_t check_and_get_component_from_path(TALLOC_CTX *mem_ctx,
type = COMPONENT_MONITOR;
name = "monitor";
} else {
- name = ifp_path_strip_prefix(path, PATH_RESPONDERS "/");
+ name = sbus_opath_strip_prefix(path, PATH_RESPONDERS "/");
if (name != NULL) {
type = COMPONENT_RESPONDER;
} else {
- name = ifp_path_strip_prefix(path, PATH_BACKENDS "/");
+ name = sbus_opath_strip_prefix(path, PATH_BACKENDS "/");
if (name != NULL) {
type = COMPONENT_BACKEND;
} else {
@@ -116,7 +116,7 @@ static errno_t check_and_get_component_from_path(TALLOC_CTX *mem_ctx,
goto done;
}
- safe_name = ifp_bus_path_unescape(mem_ctx, name);
+ safe_name = sbus_opath_unescape_part(mem_ctx, name);
if (safe_name == NULL) {
ret = ENOMEM;
goto done;
@@ -236,7 +236,7 @@ static errno_t list_responders(TALLOC_CTX *mem_ctx,
}
for (i = 0; i < num; i++) {
- list[i] = ifp_reply_objpath(list, PATH_RESPONDERS, svc[i]);
+ list[i] = sbus_opath_compose(list, PATH_RESPONDERS, svc[i]);
if (list[i] == NULL) {
ret = ENOMEM;
goto done;
@@ -286,7 +286,7 @@ static errno_t list_backends(TALLOC_CTX *mem_ctx,
}
for (i = 0; i < num; i++) {
- list[i] = ifp_reply_objpath(list, PATH_BACKENDS, names[i]);
+ list[i] = sbus_opath_compose(list, PATH_BACKENDS, names[i]);
if (list[i] == NULL) {
ret = ENOMEM;
goto done;
@@ -418,7 +418,7 @@ int ifp_find_responder_by_name(struct sbus_request *dbus_req,
const char *result = NULL;
if (responder_exists(arg_name)) {
- result = ifp_reply_objpath(dbus_req, PATH_RESPONDERS, arg_name);
+ result = sbus_opath_compose(dbus_req, PATH_RESPONDERS, arg_name);
if (result == NULL) {
return sbus_request_fail_and_finish(dbus_req, NULL);
}
@@ -448,7 +448,7 @@ int ifp_find_backend_by_name(struct sbus_request *dbus_req,
}
if (backend_exists(ctx->rctx->cdb, arg_name)) {
- result = ifp_reply_objpath(dbus_req, PATH_BACKENDS, arg_name);
+ result = sbus_opath_compose(dbus_req, PATH_BACKENDS, arg_name);
if (result == NULL) {
return sbus_request_fail_and_finish(dbus_req, NULL);
}
diff --git a/src/responder/ifp/ifp_domains.c b/src/responder/ifp/ifp_domains.c
index 1841cbe58..0af81af81 100644
--- a/src/responder/ifp/ifp_domains.c
+++ b/src/responder/ifp/ifp_domains.c
@@ -125,7 +125,7 @@ static void ifp_list_domains_process(struct tevent_req *req)
for (dom = ireq->ifp_ctx->rctx->domains;
dom != NULL;
dom = get_next_domain(dom, true)) {
- p = ifp_reply_objpath(ireq, INFOPIPE_DOMAIN_PATH_PFX, dom->name);
+ p = sbus_opath_compose(ireq, INFOPIPE_DOMAIN_PATH_PFX, dom->name);
if (p == NULL) {
DEBUG(SSSDBG_MINOR_FAILURE,
"Could not create path for dom %s, skipping\n", dom->name);
@@ -234,7 +234,7 @@ static void ifp_find_domain_by_name_process(struct tevent_req *req)
return;
}
- path = ifp_reply_objpath(ireq, INFOPIPE_DOMAIN_PATH_PFX, iter->name);
+ path = sbus_opath_compose(ireq, INFOPIPE_DOMAIN_PATH_PFX, iter->name);
if (path == NULL) {
DEBUG(SSSDBG_MINOR_FAILURE,
"Could not create path for domain %s, skipping\n", iter->name);
@@ -263,13 +263,13 @@ get_domain_info_from_req(struct sbus_request *dbus_req, void *data)
return NULL;
}
- raw_name = ifp_path_strip_prefix(dbus_req->path,
- INFOPIPE_DOMAIN_PATH_PFX "/");
+ raw_name = sbus_opath_strip_prefix(dbus_req->path,
+ INFOPIPE_DOMAIN_PATH_PFX "/");
if (raw_name == NULL) {
return NULL;
}
- name = ifp_bus_path_unescape(dbus_req, raw_name);
+ name = sbus_opath_unescape_part(dbus_req, raw_name);
if (name == NULL) {
return NULL;
}
@@ -536,6 +536,6 @@ void ifp_dom_get_parent_domain(struct sbus_request *dbus_req,
return;
}
- *_out = ifp_reply_objpath(dbus_req, INFOPIPE_DOMAIN_PATH_PFX,
- dom->parent->name);
+ *_out = sbus_opath_compose(dbus_req, INFOPIPE_DOMAIN_PATH_PFX,
+ dom->parent->name);
}
diff --git a/src/responder/ifp/ifp_private.h b/src/responder/ifp/ifp_private.h
index fb1639c8d..676544fad 100644
--- a/src/responder/ifp/ifp_private.h
+++ b/src/responder/ifp/ifp_private.h
@@ -68,17 +68,6 @@ errno_t ifp_req_create(struct sbus_request *dbus_req,
/* Returns an appropriate DBus error for specific ifp_req_create failures */
int ifp_req_create_handle_failure(struct sbus_request *dbus_req, errno_t err);
-const char *ifp_path_strip_prefix(const char *path, const char *prefix);
-
-char *ifp_bus_path_unescape(TALLOC_CTX *mem_ctx, const char *path);
-char *ifp_bus_path_escape(TALLOC_CTX *mem_ctx, const char *path);
-
-char *_ifp_reply_objpath(TALLOC_CTX *mem_ctx, const char *base,
- const char *part, ...);
-
-#define ifp_reply_objpath(mem_ctx, base, ...) \
- _ifp_reply_objpath(mem_ctx, base, ##__VA_ARGS__, NULL)
-
errno_t ifp_add_ldb_el_to_dict(DBusMessageIter *iter_dict,
struct ldb_message_element *el);
const char **ifp_parse_attr_list(TALLOC_CTX *mem_ctx, const char *conf_str);
diff --git a/src/responder/ifp/ifpsrv_util.c b/src/responder/ifp/ifpsrv_util.c
index 909bc5487..b6a0b168b 100644
--- a/src/responder/ifp/ifpsrv_util.c
+++ b/src/responder/ifp/ifpsrv_util.c
@@ -97,187 +97,6 @@ int ifp_req_create_handle_failure(struct sbus_request *dbus_req, errno_t err)
"Cannot create IFP request\n"));
}
-const char *ifp_path_strip_prefix(const char *path, const char *prefix)
-{
- if (strncmp(path, prefix, strlen(prefix)) == 0) {
- return path + strlen(prefix);
- }
-
- return NULL;
-}
-
-/* The following path related functions are based on similar code in
- * storaged, just tailored to use talloc instead of glib
- */
-char *ifp_bus_path_escape(TALLOC_CTX *mem_ctx, const char *path)
-{
- size_t n;
- char *safe_path = NULL;
- TALLOC_CTX *tmp_ctx = NULL;
-
- /* The path must be valid */
- if (path == NULL) {
- return NULL;
- }
-
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
- return NULL;
- }
-
- safe_path = talloc_strdup(tmp_ctx, "");
- if (safe_path == NULL) {
- goto done;
- }
-
- /* Special case for an empty string */
- if (strcmp(path, "") == 0) {
- /* the for loop would just fall through */
- safe_path = talloc_asprintf_append_buffer(safe_path, "_");
- }
-
- for (n = 0; path[n]; n++) {
- int c = path[n];
- /* D-Bus spec says:
- * *
- * * Each element must only contain the ASCII characters
- * "[A-Z][a-z][0-9]_"
- * */
- if ((c >= 'A' && c <= 'Z')
- || (c >= 'a' && c <= 'z')
- || (c >= '0' && c <= '9')) {
- safe_path = talloc_asprintf_append_buffer(safe_path, "%c", c);
- if (safe_path == NULL) {
- goto done;
- }
- } else {
- safe_path = talloc_asprintf_append_buffer(safe_path, "_%02x", c);
- if (safe_path == NULL) {
- goto done;
- }
- }
- }
-
- safe_path = talloc_steal(mem_ctx, safe_path);
-done:
- talloc_free(tmp_ctx);
- return safe_path;
-}
-
-static inline int unhexchar(char c)
-{
- if (c >= '0' && c <= '9') {
- return c - '0';
- }
-
- if (c >= 'a' && c <= 'f') {
- return c - 'a' + 10;
- }
-
- if (c >= 'A' && c <= 'F') {
- return c - 'A' + 10;
- }
-
- return -1;
-}
-
-char *ifp_bus_path_unescape(TALLOC_CTX *mem_ctx, const char *path)
-{
- char *safe_path;
- const char *p;
- int a, b, c;
- TALLOC_CTX *tmp_ctx = NULL;
-
- tmp_ctx = talloc_new(NULL);
- if (tmp_ctx == NULL) {
- return NULL;
- }
-
- safe_path = talloc_strdup(tmp_ctx, "");
- if (safe_path == NULL) {
- goto done;
- }
-
- /* Special case for the empty string */
- if (strcmp(path, "_") == 0) {
- safe_path = talloc_steal(mem_ctx, safe_path);
- goto done;
- }
-
- for (p = path; *p; p++) {
- if (*p == '_') {
- /* There must be at least two more chars after underscore */
- if (p[1] == '\0' || p[2] == '\0') {
- safe_path = NULL;
- goto done;
- }
-
- if ((a = unhexchar(p[1])) < 0
- || (b = unhexchar(p[2])) < 0) {
- /* Invalid escape code, let's take it literal then */
- c = '_';
- } else {
- c = ((a << 4) | b);
- p += 2;
- }
- } else {
- c = *p;
- }
-
- safe_path = talloc_asprintf_append_buffer(safe_path, "%c", c);
- if (safe_path == NULL) {
- goto done;
- }
- }
-
- safe_path = talloc_steal(mem_ctx, safe_path);
-done:
- talloc_free(tmp_ctx);
- return safe_path;
-}
-
-char *
-_ifp_reply_objpath(TALLOC_CTX *mem_ctx, const char *base,
- const char *part, ...)
-{
- char *safe_part;
- char *path = NULL;
- va_list va;
-
- if (base == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "Wrong object path base!\n");
- return NULL;
- }
-
- path = talloc_strdup(mem_ctx, base);
- if (path == NULL) return NULL;
-
- va_start(va, part);
- while (part != NULL) {
- safe_part = ifp_bus_path_escape(mem_ctx, part);
- if (safe_part == NULL) {
- DEBUG(SSSDBG_OP_FAILURE, "Could not add [%s] to objpath\n", part);
- goto fail;
- }
-
- path = talloc_asprintf_append(path, "/%s", safe_part);
- talloc_free(safe_part);
- if (path == NULL) {
- goto fail;
- }
-
- part = va_arg(va, const char *);
- }
- va_end(va);
-
- return path;
-
-fail:
- va_end(va);
- talloc_free(path);
- return NULL;
-}
-
errno_t ifp_add_ldb_el_to_dict(DBusMessageIter *iter_dict,
struct ldb_message_element *el)
{
diff --git a/src/sbus/sssd_dbus.h b/src/sbus/sssd_dbus.h
index 87cffe284..355d617fe 100644
--- a/src/sbus/sssd_dbus.h
+++ b/src/sbus/sssd_dbus.h
@@ -173,6 +173,26 @@ int sbus_conn_register_iface(struct sbus_connection *conn,
errno_t
sbus_conn_reregister_paths(struct sbus_connection *conn);
+char *
+sbus_opath_escape_part(TALLOC_CTX *mem_ctx,
+ const char *object_path_part);
+
+char *
+sbus_opath_unescape_part(TALLOC_CTX *mem_ctx,
+ const char *object_path_part);
+
+char *
+_sbus_opath_compose(TALLOC_CTX *mem_ctx,
+ const char *base,
+ const char *part, ...);
+
+#define sbus_opath_compose(mem_ctx, base, ...) \
+ _sbus_opath_compose(mem_ctx, base, ##__VA_ARGS__, NULL)
+
+const char *
+sbus_opath_strip_prefix(const char *object_path,
+ const char *prefix);
+
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 a528e3cc9..09e160227 100644
--- a/src/sbus/sssd_dbus_interface.c
+++ b/src/sbus/sssd_dbus_interface.c
@@ -171,6 +171,200 @@ static char *sbus_opath_parent_subtree(TALLOC_CTX *mem_ctx,
return subtree;
}
+/**
+ * The following path related functions are based on similar code in
+ * storaged, just tailored to use talloc instead of glib
+ */
+char *
+sbus_opath_escape_part(TALLOC_CTX *mem_ctx,
+ const char *object_path_part)
+{
+ size_t n;
+ char *safe_path = NULL;
+ TALLOC_CTX *tmp_ctx = NULL;
+
+ /* The path must be valid */
+ if (object_path_part == NULL) {
+ return NULL;
+ }
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return NULL;
+ }
+
+ safe_path = talloc_strdup(tmp_ctx, "");
+ if (safe_path == NULL) {
+ goto done;
+ }
+
+ /* Special case for an empty string */
+ if (strcmp(object_path_part, "") == 0) {
+ /* the for loop would just fall through */
+ safe_path = talloc_asprintf_append_buffer(safe_path, "_");
+ if (safe_path == NULL) {
+ goto done;
+ }
+ }
+
+ for (n = 0; object_path_part[n]; n++) {
+ int c = object_path_part[n];
+ /* D-Bus spec says:
+ * *
+ * * Each element must only contain the ASCII characters
+ * "[A-Z][a-z][0-9]_"
+ * */
+ if ((c >= 'A' && c <= 'Z')
+ || (c >= 'a' && c <= 'z')
+ || (c >= '0' && c <= '9')) {
+ safe_path = talloc_asprintf_append_buffer(safe_path, "%c", c);
+ if (safe_path == NULL) {
+ goto done;
+ }
+ } else {
+ safe_path = talloc_asprintf_append_buffer(safe_path, "_%02x", c);
+ if (safe_path == NULL) {
+ goto done;
+ }
+ }
+ }
+
+ safe_path = talloc_steal(mem_ctx, safe_path);
+
+done:
+ talloc_free(tmp_ctx);
+ return safe_path;
+}
+
+static inline int unhexchar(char c)
+{
+ if (c >= '0' && c <= '9') {
+ return c - '0';
+ }
+
+ if (c >= 'a' && c <= 'f') {
+ return c - 'a' + 10;
+ }
+
+ if (c >= 'A' && c <= 'F') {
+ return c - 'A' + 10;
+ }
+
+ return -1;
+}
+
+char *
+sbus_opath_unescape_part(TALLOC_CTX *mem_ctx,
+ const char *object_path_part)
+{
+ char *safe_path;
+ const char *p;
+ int a, b, c;
+ TALLOC_CTX *tmp_ctx = NULL;
+
+ tmp_ctx = talloc_new(NULL);
+ if (tmp_ctx == NULL) {
+ return NULL;
+ }
+
+ safe_path = talloc_strdup(tmp_ctx, "");
+ if (safe_path == NULL) {
+ goto done;
+ }
+
+ /* Special case for the empty string */
+ if (strcmp(object_path_part, "_") == 0) {
+ safe_path = talloc_steal(mem_ctx, safe_path);
+ goto done;
+ }
+
+ for (p = object_path_part; *p; p++) {
+ if (*p == '_') {
+ /* There must be at least two more chars after underscore */
+ if (p[1] == '\0' || p[2] == '\0') {
+ safe_path = NULL;
+ goto done;
+ }
+
+ if ((a = unhexchar(p[1])) < 0
+ || (b = unhexchar(p[2])) < 0) {
+ /* Invalid escape code, let's take it literal then */
+ c = '_';
+ } else {
+ c = ((a << 4) | b);
+ p += 2;
+ }
+ } else {
+ c = *p;
+ }
+
+ safe_path = talloc_asprintf_append_buffer(safe_path, "%c", c);
+ if (safe_path == NULL) {
+ goto done;
+ }
+ }
+
+ safe_path = talloc_steal(mem_ctx, safe_path);
+
+done:
+ talloc_free(tmp_ctx);
+ return safe_path;
+}
+
+char *
+_sbus_opath_compose(TALLOC_CTX *mem_ctx,
+ const char *base,
+ const char *part, ...)
+{
+ char *safe_part;
+ char *path = NULL;
+ va_list va;
+
+ if (base == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "Wrong object path base!\n");
+ return NULL;
+ }
+
+ path = talloc_strdup(mem_ctx, base);
+ if (path == NULL) return NULL;
+
+ va_start(va, part);
+ while (part != NULL) {
+ safe_part = sbus_opath_escape_part(mem_ctx, part);
+ if (safe_part == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "Could not add [%s] to objpath\n", part);
+ goto fail;
+ }
+
+ path = talloc_asprintf_append(path, "/%s", safe_part);
+ talloc_free(safe_part);
+ if (path == NULL) {
+ goto fail;
+ }
+
+ part = va_arg(va, const char *);
+ }
+ va_end(va);
+
+ return path;
+
+fail:
+ va_end(va);
+ talloc_free(path);
+ return NULL;
+}
+
+const char *
+sbus_opath_strip_prefix(const char *object_path,
+ const char *prefix)
+{
+ if (strncmp(object_path, prefix, strlen(prefix)) == 0) {
+ return object_path + strlen(prefix);
+ }
+
+ return NULL;
+}
+
static void
sbus_opath_hash_delete_cb(hash_entry_t *item,
hash_destroy_enum deltype,
diff --git a/src/tests/cmocka/test_ifp.c b/src/tests/cmocka/test_ifp.c
index 5793f9191..484ab8568 100644
--- a/src/tests/cmocka/test_ifp.c
+++ b/src/tests/cmocka/test_ifp.c
@@ -134,14 +134,6 @@ void ifp_test_req_wrong_uid(void **state)
assert_true(leak_check_teardown());
}
-void test_path_prefix(void **state)
-{
- const char *prefix = "foo";
-
- assert_non_null(ifp_path_strip_prefix("foobar", prefix));
- assert_null(ifp_path_strip_prefix("notfoo", prefix));
-}
-
void test_el_to_dict(void **state)
{
static struct sbus_request *sr;
@@ -362,64 +354,6 @@ void test_attr_allowed(void **state)
assert_false(ifp_attr_allowed(NULL, "name"));
}
-void test_path_escape_unescape(void **state)
-{
- char *escaped;
- char *raw;
- TALLOC_CTX *mem_ctx;
-
- assert_true(leak_check_setup());
- mem_ctx = talloc_new(global_talloc_context);
-
- escaped = ifp_bus_path_escape(mem_ctx, "noescape");
- assert_non_null(escaped);
- assert_string_equal(escaped, "noescape");
- raw = ifp_bus_path_unescape(mem_ctx, escaped);
- talloc_free(escaped);
- assert_non_null(raw);
- assert_string_equal(raw, "noescape");
- talloc_free(raw);
-
- escaped = ifp_bus_path_escape(mem_ctx, "redhat.com");
- assert_non_null(escaped);
- assert_string_equal(escaped, "redhat_2ecom"); /* dot is 0x2E in ASCII */
- raw = ifp_bus_path_unescape(mem_ctx, escaped);
- talloc_free(escaped);
- assert_non_null(raw);
- assert_string_equal(raw, "redhat.com");
- talloc_free(raw);
-
- escaped = ifp_bus_path_escape(mem_ctx, "path_with_underscore");
- assert_non_null(escaped);
- /* underscore is 0x5F in ascii */
- assert_string_equal(escaped, "path_5fwith_5funderscore");
- raw = ifp_bus_path_unescape(mem_ctx, escaped);
- talloc_free(escaped);
- assert_non_null(raw);
- assert_string_equal(raw, "path_with_underscore");
- talloc_free(raw);
-
- /* empty string */
- escaped = ifp_bus_path_escape(mem_ctx, "");
- assert_non_null(escaped);
- assert_string_equal(escaped, "_");
- raw = ifp_bus_path_unescape(mem_ctx, escaped);
- talloc_free(escaped);
- assert_non_null(raw);
- assert_string_equal(raw, "");
- talloc_free(raw);
-
- /* negative tests */
- escaped = ifp_bus_path_escape(mem_ctx, NULL);
- assert_null(escaped);
- raw = ifp_bus_path_unescape(mem_ctx, "wrongpath_");
- assert_null(raw);
-
- assert_true(leak_check_teardown());
-}
-
-#define PATH_BASE "/some/path"
-
struct ifp_test_req_ctx {
struct ifp_req *ireq;
struct sbus_request *sr;
@@ -462,32 +396,6 @@ void ifp_test_req_teardown(void **state)
assert_true(leak_check_teardown());
}
-void test_reply_path(void **state)
-{
- struct ifp_test_req_ctx *test_ctx = talloc_get_type_abort(*state,
- struct ifp_test_req_ctx);
- char *path;
-
- /* Doesn't need escaping */
- path = ifp_reply_objpath(test_ctx->ireq, PATH_BASE, "domname", NULL);
- assert_non_null(path);
- assert_string_equal(path, PATH_BASE"/domname");
- talloc_free(path);
-}
-
-void test_reply_path_escape(void **state)
-{
- struct ifp_test_req_ctx *test_ctx = talloc_get_type_abort(*state,
- struct ifp_test_req_ctx);
- char *path;
-
- /* A dot needs escaping */
- path = ifp_reply_objpath(test_ctx->ireq, PATH_BASE, "redhat.com", NULL);
- assert_non_null(path);
- assert_string_equal(path, PATH_BASE"/redhat_2ecom");
- talloc_free(path);
-}
-
int main(int argc, const char *argv[])
{
poptContext pc;
@@ -501,17 +409,11 @@ int main(int argc, const char *argv[])
const UnitTest tests[] = {
unit_test(ifp_test_req_create),
unit_test(ifp_test_req_wrong_uid),
- unit_test(test_path_prefix),
unit_test_setup_teardown(test_el_to_dict,
ifp_test_req_setup, ifp_test_req_teardown),
unit_test(test_attr_acl),
unit_test(test_attr_acl_ex),
unit_test(test_attr_allowed),
- unit_test(test_path_escape_unescape),
- unit_test_setup_teardown(test_reply_path,
- ifp_test_req_setup, ifp_test_req_teardown),
- unit_test_setup_teardown(test_reply_path_escape,
- ifp_test_req_setup, ifp_test_req_teardown),
};
/* Set debug level to invalid value so we can deside if -d 0 was used. */
diff --git a/src/tests/cmocka/test_sbus_opath.c b/src/tests/cmocka/test_sbus_opath.c
new file mode 100644
index 000000000..b526c8873
--- /dev/null
+++ b/src/tests/cmocka/test_sbus_opath.c
@@ -0,0 +1,157 @@
+/*
+ Authors:
+ Jakub Hrozek <jhrozek@redhat.com>
+ 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 <errno.h>
+#include <popt.h>
+
+#include "sbus/sssd_dbus.h"
+#include "tests/cmocka/common_mock.h"
+#include "tests/common.h"
+
+void test_sbus_opath_strip_prefix(void **state)
+{
+ const char *prefix = "/org/freedesktop/sssd/";
+ const char *path = "/org/freedesktop/sssd/infopipe";
+ const char *strip;
+
+ strip = sbus_opath_strip_prefix(path, prefix);
+ assert_non_null(prefix);
+ assert_string_equal(strip, "infopipe");
+
+ strip = sbus_opath_strip_prefix("/other/path", prefix);
+ assert_null(strip);
+}
+
+void test_sbus_opath_escape_unescape(void **state)
+{
+ char *escaped;
+ char *raw;
+ TALLOC_CTX *mem_ctx;
+
+ assert_true(leak_check_setup());
+ mem_ctx = talloc_new(global_talloc_context);
+
+ escaped = sbus_opath_escape_part(mem_ctx, "noescape");
+ assert_non_null(escaped);
+ assert_string_equal(escaped, "noescape");
+ raw = sbus_opath_unescape_part(mem_ctx, escaped);
+ talloc_free(escaped);
+ assert_non_null(raw);
+ assert_string_equal(raw, "noescape");
+ talloc_free(raw);
+
+ escaped = sbus_opath_escape_part(mem_ctx, "redhat.com");
+ assert_non_null(escaped);
+ assert_string_equal(escaped, "redhat_2ecom"); /* dot is 0x2E in ASCII */
+ raw = sbus_opath_unescape_part(mem_ctx, escaped);
+ talloc_free(escaped);
+ assert_non_null(raw);
+ assert_string_equal(raw, "redhat.com");
+ talloc_free(raw);
+
+ escaped = sbus_opath_escape_part(mem_ctx, "path_with_underscore");
+ assert_non_null(escaped);
+ /* underscore is 0x5F in ascii */
+ assert_string_equal(escaped, "path_5fwith_5funderscore");
+ raw = sbus_opath_unescape_part(mem_ctx, escaped);
+ talloc_free(escaped);
+ assert_non_null(raw);
+ assert_string_equal(raw, "path_with_underscore");
+ talloc_free(raw);
+
+ /* empty string */
+ escaped = sbus_opath_escape_part(mem_ctx, "");
+ assert_non_null(escaped);
+ assert_string_equal(escaped, "_");
+ raw = sbus_opath_unescape_part(mem_ctx, escaped);
+ talloc_free(escaped);
+ assert_non_null(raw);
+ assert_string_equal(raw, "");
+ talloc_free(raw);
+
+ /* negative tests */
+ escaped = sbus_opath_escape_part(mem_ctx, NULL);
+ assert_null(escaped);
+ raw = sbus_opath_unescape_part(mem_ctx, "wrongpath_");
+ assert_null(raw);
+
+ assert_true(leak_check_teardown());
+}
+
+void test_sbus_opath_compose(void **state)
+{
+ char *path;
+
+ /* Doesn't need escaping */
+ path = sbus_opath_compose(NULL, "/base/path", "domname");
+ assert_non_null(path);
+ assert_string_equal(path, "/base/path/domname");
+ talloc_free(path);
+}
+
+void test_sbus_opath_compose_escape(void **state)
+{
+ char *path;
+
+ /* A dot needs escaping */
+ path = sbus_opath_compose(NULL, "/base/path", "redhat.com", NULL);
+ assert_non_null(path);
+ assert_string_equal(path, "/base/path/redhat_2ecom");
+ talloc_free(path);
+}
+
+int main(int argc, const char *argv[])
+{
+ poptContext pc;
+ int opt;
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ SSSD_DEBUG_OPTS
+ POPT_TABLEEND
+ };
+
+ const UnitTest tests[] = {
+ unit_test(test_sbus_opath_strip_prefix),
+ unit_test(test_sbus_opath_escape_unescape),
+ unit_test(test_sbus_opath_compose),
+ unit_test(test_sbus_opath_compose_escape),
+ };
+
+ /* Set debug level to invalid value so we can deside if -d 0 was used. */
+ debug_level = SSSDBG_INVALID;
+
+ pc = poptGetContext(argv[0], argc, argv, long_options, 0);
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ switch(opt) {
+ default:
+ fprintf(stderr, "\nInvalid option %s: %s\n\n",
+ poptBadOption(pc, 0), poptStrerror(opt));
+ poptPrintUsage(pc, stderr, 0);
+ return 1;
+ }
+ }
+ poptFreeContext(pc);
+
+ DEBUG_CLI_INIT(debug_level);
+
+ return run_tests(tests);
+}