diff options
author | Jakub Hrozek <jhrozek@redhat.com> | 2015-05-26 12:40:33 +0200 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2015-06-14 21:44:39 +0200 |
commit | 89ddc9ed474e9ac2b1e7bccb0a58610babf26cf8 (patch) | |
tree | 780876e8d274177f2ac16ba2adfa3f6f4db2c0c0 | |
parent | 27e89b6925334565c73c407a9ae2809358789c81 (diff) | |
download | sssd-89ddc9ed474e9ac2b1e7bccb0a58610babf26cf8.tar.gz sssd-89ddc9ed474e9ac2b1e7bccb0a58610babf26cf8.tar.xz sssd-89ddc9ed474e9ac2b1e7bccb0a58610babf26cf8.zip |
IPA: Split two functions to new module ipa_subdomains_utils.c
These functions will be later reused by the subdomains_server.c module.
Splitting them into a separate subdomains_utils.c module will make sure
there are no cyclic dependencies and the functions are testable in
isolation.
Reviewed-by: Sumit Bose <sbose@redhat.com>
-rw-r--r-- | Makefile.am | 18 | ||||
-rw-r--r-- | src/providers/ipa/ipa_subdomains.c | 47 | ||||
-rw-r--r-- | src/providers/ipa/ipa_subdomains.h | 6 | ||||
-rw-r--r-- | src/providers/ipa/ipa_subdomains_utils.c | 100 | ||||
-rw-r--r-- | src/tests/cmocka/test_ipa_subdomains_utils.c | 227 |
5 files changed, 356 insertions, 42 deletions
diff --git a/Makefile.am b/Makefile.am index b85290896..816f18e4c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -226,6 +226,7 @@ if HAVE_CMOCKA test_sbus_opath \ test_fo_srv \ pam-srv-tests \ + test_ipa_subdom_util \ $(NULL) if HAVE_LIBRESOLV @@ -2418,6 +2419,22 @@ test_fo_srv_LDADD = \ libsss_test_common.la \ $(NULL) +test_ipa_subdom_util_SOURCES = \ + src/tests/cmocka/test_ipa_subdomains_utils.c \ + src/providers/ipa/ipa_subdomains_utils.c \ + $(NULL) +test_ipa_subdom_util_CFLAGS = \ + $(AM_CFLAGS) \ + $(NULL) +test_ipa_subdom_util_LDADD = \ + $(CMOCKA_LIBS) \ + $(POPT_LIBS) \ + $(TALLOC_LIBS) \ + $(LDB_LIBS) \ + $(SSSD_INTERNAL_LTLIBS) \ + libsss_test_common.la \ + $(NULL) + endif # HAVE_CMOCKA noinst_PROGRAMS = pam_test_client @@ -2761,6 +2778,7 @@ libsss_ipa_la_SOURCES = \ src/providers/ipa/ipa_subdomains.c \ src/providers/ipa/ipa_subdomains_id.c \ src/providers/ipa/ipa_subdomains_server.c \ + src/providers/ipa/ipa_subdomains_utils.c \ src/providers/ipa/ipa_subdomains_ext_groups.c \ src/providers/ipa/ipa_views.c \ src/providers/ipa/ipa_utils.c \ diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c index 2a898d7eb..5a3f90fe3 100644 --- a/src/providers/ipa/ipa_subdomains.c +++ b/src/providers/ipa/ipa_subdomains.c @@ -328,56 +328,18 @@ static errno_t ipa_subdom_get_forest(TALLOC_CTX *mem_ctx, char **_forest) { int ret; - const char *orig_dn; struct ldb_dn *dn = NULL; const struct ldb_val *val; char *forest = NULL; - ret = sysdb_attrs_get_string(attrs, SYSDB_ORIG_DN, &orig_dn); - if (ret) { - DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); - goto done; - } - DEBUG(SSSDBG_TRACE_ALL, "Checking if we need the forest name for [%s].\n", - orig_dn); - - dn = ldb_dn_new(mem_ctx, ldb_ctx, orig_dn); + dn = ipa_subdom_ldb_dn(mem_ctx, ldb_ctx, attrs); if (dn == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n"); - goto done; - } - - if (!ldb_dn_validate(dn)) { - DEBUG(SSSDBG_OP_FAILURE, "Original DN [%s] is not a valid DN.\n", - orig_dn); - ret = EINVAL; - goto done; - } - - if (ldb_dn_get_comp_num(dn) < 5) { - /* We are only interested in the member domain objects. In IPA the - * forest root object is stored as e.g. - * cn=AD.DOM,cn=ad,cn=trusts,dc=example,dc=com. Member domains in the - * forest are children of the forest root object e.g. - * cn=SUB.AD.DOM,cn=AD.DOM,cn=ad,cn=trusts,dc=example,dc=com. Since - * the forest name is not stored in the member objects we derive it - * from the RDN of the forest root object. */ - ret = EOK; - goto done; - } - - val = ldb_dn_get_component_val(dn, 3); - if (strncasecmp("trusts", (const char *) val->data, val->length) != 0) { - DEBUG(SSSDBG_TRACE_FUNC, - "4th component is not 'trust', nothing to do.\n"); - ret = EOK; + DEBUG(SSSDBG_OP_FAILURE, "ipa_subdom_ldb_dn failed.\n"); + ret = EIO; goto done; } - val = ldb_dn_get_component_val(dn, 2); - if (strncasecmp("ad", (const char *) val->data, val->length) != 0) { - DEBUG(SSSDBG_TRACE_FUNC, - "3rd component is not 'ad', nothing to do.\n"); + if (ipa_subdom_is_member_dom(dn) == false) { ret = EOK; goto done; } @@ -390,6 +352,7 @@ static errno_t ipa_subdom_get_forest(TALLOC_CTX *mem_ctx, goto done; } + ret = EOK; done: talloc_free(dn); diff --git a/src/providers/ipa/ipa_subdomains.h b/src/providers/ipa/ipa_subdomains.h index d92bd01e8..94027c091 100644 --- a/src/providers/ipa/ipa_subdomains.h +++ b/src/providers/ipa/ipa_subdomains.h @@ -59,6 +59,12 @@ void ipa_ad_subdom_remove(struct be_ctx *be_ctx, int ipa_ad_subdom_init(struct be_ctx *be_ctx, struct ipa_id_ctx *id_ctx); +struct ldb_dn *ipa_subdom_ldb_dn(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb_ctx, + struct sysdb_attrs *attrs); + +bool ipa_subdom_is_member_dom(struct ldb_dn *dn); + /* struct for external group memberships, defined in * ipa_subdomains_ext_groups.c */ struct ipa_ext_groups; diff --git a/src/providers/ipa/ipa_subdomains_utils.c b/src/providers/ipa/ipa_subdomains_utils.c new file mode 100644 index 000000000..27fc0a4d1 --- /dev/null +++ b/src/providers/ipa/ipa_subdomains_utils.c @@ -0,0 +1,100 @@ +/* + SSSD + + IPA Subdomains Module - utilities + + Authors: + Sumit Bose <sbose@redhat.com> + + Copyright (C) 2015 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 "providers/ipa/ipa_subdomains.h" +#include "providers/ipa/ipa_common.h" +#include "providers/ipa/ipa_id.h" + +struct ldb_dn *ipa_subdom_ldb_dn(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb_ctx, + struct sysdb_attrs *attrs) +{ + int ret; + const char *orig_dn; + struct ldb_dn *dn = NULL; + + if (attrs == NULL || ldb_ctx == NULL) { + return NULL; + } + + ret = sysdb_attrs_get_string(attrs, SYSDB_ORIG_DN, &orig_dn); + if (ret) { + DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed: %d\n", ret); + return NULL; + } + + dn = ldb_dn_new(mem_ctx, ldb_ctx, orig_dn); + if (dn == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n"); + return NULL; + } + + if (!ldb_dn_validate(dn)) { + DEBUG(SSSDBG_OP_FAILURE, "Original DN [%s] is not a valid DN.\n", + orig_dn); + talloc_free(dn); + return NULL; + } + + return dn; +} + +bool ipa_subdom_is_member_dom(struct ldb_dn *dn) +{ + const struct ldb_val *val; + + if (dn == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Wrong input!\n"); + return false; + } + + if (ldb_dn_get_comp_num(dn) < 5) { + /* We are only interested in the member domain objects. In IPA the + * forest root object is stored as e.g. + * cn=AD.DOM,cn=ad,cn=trusts,dc=example,dc=com. Member domains in the + * forest are children of the forest root object e.g. + * cn=SUB.AD.DOM,cn=AD.DOM,cn=ad,cn=trusts,dc=example,dc=com. Since + * the forest name is not stored in the member objects we derive it + * from the RDN of the forest root object. */ + DEBUG(SSSDBG_TRACE_FUNC, + "DN too short, not a member domain\n"); + return false; + } + + val = ldb_dn_get_component_val(dn, 3); + if (strncasecmp("trusts", (const char *) val->data, val->length) != 0) { + DEBUG(SSSDBG_TRACE_FUNC, + "4th component is not 'trust', not a member domain\n"); + return false; + } + + val = ldb_dn_get_component_val(dn, 2); + if (strncasecmp("ad", (const char *) val->data, val->length) != 0) { + DEBUG(SSSDBG_TRACE_FUNC, + "3rd component is not 'ad', not a member domain\n"); + return false; + } + + return true; +} diff --git a/src/tests/cmocka/test_ipa_subdomains_utils.c b/src/tests/cmocka/test_ipa_subdomains_utils.c new file mode 100644 index 000000000..acf8c19a2 --- /dev/null +++ b/src/tests/cmocka/test_ipa_subdomains_utils.c @@ -0,0 +1,227 @@ +/* + Authors: + Jakub Hrozek <jhrozek@redhat.com> + + Copyright (C) 2015 Red Hat + + SSSD tests: IPA subdomain util tests + + 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 <tevent.h> +#include <errno.h> +#include <popt.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <sys/types.h> +#include <stdarg.h> +#include <stdlib.h> + +#include "providers/ipa/ipa_subdomains.h" +#include "tests/cmocka/common_mock.h" +#include "tests/cmocka/common_mock_resp.h" + +struct test_ipa_subdom_ctx { + struct ldb_context *ldb; +}; + +static int test_ipa_subdom_setup(void **state) +{ + struct test_ipa_subdom_ctx *test_ctx; + + assert_true(leak_check_setup()); + + test_ctx = talloc_zero(global_talloc_context, struct test_ipa_subdom_ctx); + assert_non_null(test_ctx); + + test_ctx->ldb = ldb_init(test_ctx, NULL); + assert_non_null(test_ctx->ldb); + + check_leaks_push(test_ctx); + *state = test_ctx; + return 0; +} + +static int test_ipa_subdom_teardown(void **state) +{ + struct test_ipa_subdom_ctx *test_ctx; + + test_ctx = talloc_get_type(*state, struct test_ipa_subdom_ctx); + assert_non_null(test_ctx); + + assert_true(check_leaks_pop(test_ctx) == true); + talloc_free(test_ctx); + assert_true(leak_check_teardown()); + return 0; +} + +static struct sysdb_attrs *dn_attrs(TALLOC_CTX *mem_ctx, const char *dn) +{ + struct sysdb_attrs *attrs; + int rv; + + attrs = sysdb_new_attrs(mem_ctx); + assert_non_null(attrs); + + rv = sysdb_attrs_add_string(attrs, SYSDB_ORIG_DN, dn); + assert_int_equal(rv, EOK); + + return attrs; +} + +static void test_ipa_subdom_ldb_dn(void **state) +{ + struct ldb_dn *dn; + struct sysdb_attrs *attrs; + struct test_ipa_subdom_ctx *test_ctx; + + test_ctx = talloc_get_type(*state, struct test_ipa_subdom_ctx); + assert_non_null(test_ctx); + + attrs = dn_attrs(test_ctx, "dc=foo,dc=bar"); + assert_non_null(attrs); + + dn = ipa_subdom_ldb_dn(test_ctx, test_ctx->ldb, attrs); + assert_non_null(dn); + assert_string_equal(ldb_dn_get_linearized(dn), "dc=foo,dc=bar"); + + talloc_free(dn); + talloc_free(attrs); +} + +static void test_ipa_subdom_ldb_dn_fail(void **state) +{ + struct ldb_dn *dn; + struct sysdb_attrs *attrs; + struct test_ipa_subdom_ctx *test_ctx; + + test_ctx = talloc_get_type(*state, struct test_ipa_subdom_ctx); + assert_non_null(test_ctx); + + attrs = dn_attrs(test_ctx, "notadn"); + assert_non_null(attrs); + + dn = ipa_subdom_ldb_dn(test_ctx, NULL, NULL); + assert_null(dn); + + dn = ipa_subdom_ldb_dn(test_ctx, test_ctx->ldb, attrs); + assert_null(dn); + talloc_free(attrs); + + attrs = sysdb_new_attrs(test_ctx); + assert_non_null(attrs); + dn = ipa_subdom_ldb_dn(test_ctx, test_ctx->ldb, attrs); + assert_null(dn); + talloc_free(attrs); +} + +static struct ldb_dn *get_dn(TALLOC_CTX *mem_ctx, + struct ldb_context *ldb, + const char *strdn) +{ + struct ldb_dn *dn; + struct sysdb_attrs *attrs; + + attrs = dn_attrs(mem_ctx, strdn); + assert_non_null(attrs); + + dn = ipa_subdom_ldb_dn(mem_ctx, ldb, attrs); + talloc_free(attrs); + assert_non_null(dn); + + return dn; +} + +static void test_ipa_subdom_is_member_dom(void **state) +{ + struct ldb_dn *dn; + struct test_ipa_subdom_ctx *test_ctx; + bool is_member; + + test_ctx = talloc_get_type(*state, struct test_ipa_subdom_ctx); + + dn = get_dn(test_ctx, test_ctx->ldb, + "cn=SUB.AD.DOM,cn=AD.DOM,cn=ad,cn=trusts,dc=example,dc=com"); + is_member = ipa_subdom_is_member_dom(dn); + talloc_free(dn); + assert_true(is_member); + + dn = get_dn(test_ctx, test_ctx->ldb, + "cn=AD.DOM,cn=ad,cn=trusts,dc=example,dc=com"); + is_member = ipa_subdom_is_member_dom(dn); + talloc_free(dn); + assert_false(is_member); + + dn = get_dn(test_ctx, test_ctx->ldb, + "cn=SUB.AD.DOM,cn=AD.DOM,cn=ad,cn=XXX,dc=example,dc=com"); + is_member = ipa_subdom_is_member_dom(dn); + talloc_free(dn); + assert_false(is_member); + + dn = get_dn(test_ctx, test_ctx->ldb, + "cn=SUB.AD.DOM,cn=AD.DOM,cn=YYY,cn=trusts,dc=example,dc=com"); + is_member = ipa_subdom_is_member_dom(dn); + talloc_free(dn); + assert_false(is_member); +} + +int main(int argc, const char *argv[]) +{ + int rv; + poptContext pc; + int opt; + struct poptOption long_options[] = { + POPT_AUTOHELP + SSSD_DEBUG_OPTS + POPT_TABLEEND + }; + + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown(test_ipa_subdom_ldb_dn, + test_ipa_subdom_setup, + test_ipa_subdom_teardown), + cmocka_unit_test_setup_teardown(test_ipa_subdom_ldb_dn_fail, + test_ipa_subdom_setup, + test_ipa_subdom_teardown), + cmocka_unit_test_setup_teardown(test_ipa_subdom_is_member_dom, + test_ipa_subdom_setup, + test_ipa_subdom_teardown), + }; + + /* 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); + + /* Even though normally the tests should clean up after themselves + * they might not after a failed run. Remove the old db to be sure */ + tests_set_cwd(); + + rv = cmocka_run_group_tests(tests, NULL, NULL); + return rv; +} |