diff options
Diffstat (limited to '')
-rw-r--r-- | src/tests/common_dom.c | 427 |
1 files changed, 427 insertions, 0 deletions
diff --git a/src/tests/common_dom.c b/src/tests/common_dom.c new file mode 100644 index 0000000..267d5f5 --- /dev/null +++ b/src/tests/common_dom.c @@ -0,0 +1,427 @@ +/* + Authors: + Jakub Hrozek <jhrozek@redhat.com> + + Copyright (C) 2013 Red Hat + + SSSD tests: Common utilities for tests that exercise domains + + 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 <ldb_module.h> + +/* Including private header makes sure we can initialize test domains. */ +#include "db/sysdb_private.h" +#include "tests/common.h" + +static errno_t +mock_confdb(TALLOC_CTX *mem_ctx, + const char *tests_path, + const char *cdb_file, + struct confdb_ctx **_cdb) +{ + TALLOC_CTX *tmp_ctx = NULL; + struct confdb_ctx *cdb = NULL; + char *cdb_path = NULL; + errno_t ret; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); + return ENOMEM; + } + + cdb_path = talloc_asprintf(tmp_ctx, "%s/%s", tests_path, cdb_file); + if (cdb_path == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed\n"); + ret = ENOMEM; + goto done; + } + + /* connect to the confdb */ + ret = confdb_init(tmp_ctx, &cdb, cdb_path); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "confdb_init failed: %d\n", ret); + goto done; + } + + *_cdb = talloc_steal(mem_ctx, cdb); + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} + +static errno_t +mock_confdb_domain(TALLOC_CTX *mem_ctx, + struct confdb_ctx *cdb, + const char *db_path, + const char *name, + const char *id_provider, + struct sss_test_conf_param *params, + char **_cdb_path) +{ + TALLOC_CTX *tmp_ctx = NULL; + const char *val[2] = {NULL, NULL}; + char *cdb_path = NULL; + char **array = NULL; + char *list = NULL; + bool exists = false; + errno_t ret; + int i; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); + return ENOMEM; + } + + /* get current domain list */ + ret = confdb_get_string(cdb, tmp_ctx, "config/sssd", "domains", + NULL, &list); + if (ret != EOK) { + goto done; + } + + /* check if the domain is already in */ + if (list != NULL) { + ret = split_on_separator(tmp_ctx, list, ',', true, true, &array, NULL); + if (ret != EOK) { + goto done; + } + + for (i = 0; array[i] != NULL; i++) { + if (strcmp(array[i], name) == 0) { + exists = true; + break; + } + } + } + + /* add domain to the list of enabled domains */ + if (!exists) { + if (list == NULL) { + list = talloc_strdup(tmp_ctx, name); + } else { + list = talloc_asprintf_append(list, ", %s", name); + } + + if (list == NULL) { + ret = ENOMEM; + goto done; + } + + val[0] = list; + ret = confdb_add_param(cdb, true, "config/sssd", "domains", val); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to change domain list [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + } + + /* create domain section */ + cdb_path = talloc_asprintf(tmp_ctx, CONFDB_DOMAIN_PATH_TMPL, name); + if (cdb_path == NULL) { + ret = ENOMEM; + goto done; + } + + val[0] = id_provider; + ret = confdb_add_param(cdb, true, cdb_path, "id_provider", val); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add id_provider [%d]: %s\n", + ret, sss_strerror(ret)); + goto done; + } + + if (params != NULL) { + for (i = 0; params[i].key != NULL; i++) { + val[0] = params[i].value; + ret = confdb_add_param(cdb, true, cdb_path, params[i].key, val); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add parameter %s [%d]: " + "%s\n", params[i].key, ret, sss_strerror(ret)); + goto done; + } + } + } + + if (_cdb_path != NULL) { + *_cdb_path = talloc_steal(mem_ctx, cdb_path); + } + + ret = EOK; + +done: + talloc_free(tmp_ctx); + return ret; +} + +void reset_ldb_errstrings(struct sss_domain_info *dom) +{ + ldb_reset_err_string(sysdb_ctx_get_ldb(dom->sysdb)); + if (dom->sysdb->ldb_ts) { + ldb_reset_err_string(dom->sysdb->ldb_ts); + } +} + +static errno_t +mock_domain(TALLOC_CTX *mem_ctx, + struct confdb_ctx *cdb, + const char *db_path, + const char *name, + struct sss_domain_info **_domain) +{ + struct sss_domain_info *domain = NULL; + errno_t ret; + + /* initialize sysdb */ + ret = sssd_domain_init(mem_ctx, cdb, name, db_path, &domain); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "sssd_domain_init() of %s failed " + "[%d]: %s\n", name, ret, sss_strerror(ret)); + goto done; + } + + reset_ldb_errstrings(domain); + + /* init with an AD-style regex to be able to test flat name */ + ret = sss_names_init_from_args(domain, + SSS_IPA_AD_DEFAULT_RE, + "%1$s@%2$s", &domain->names); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "cannot create names context\n"); + goto done; + } + + if (_domain != NULL) { + *_domain = domain; + } + + ret = EOK; + +done: + if (ret != EOK) { + talloc_free(domain); + } + return ret; +} + +struct sss_test_ctx * +create_multidom_test_ctx(TALLOC_CTX *mem_ctx, + const char *tests_path, + const char *cdb_file, + const char **domains, + const char *id_provider, + struct sss_test_conf_param **params) +{ + struct sss_domain_info *domain = NULL; + struct sss_test_ctx *test_ctx = NULL; + char *cdb_path = NULL; + errno_t ret; + int i; + + test_ctx = create_ev_test_ctx(mem_ctx); + if (test_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "create_ev_test_ctx() failed\n"); + goto fail; + } + + ret = mock_confdb(test_ctx, tests_path, cdb_file, &test_ctx->confdb); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to initialize confdb [%d]: %s\n", + ret, sss_strerror(ret)); + goto fail; + } + + /* create confdb objects for the domains */ + for (i = 0; domains[i] != NULL; i++) { + ret = mock_confdb_domain(test_ctx, test_ctx->confdb, tests_path, + domains[i], id_provider, params != NULL ? params[i] : NULL, + (cdb_path == NULL ? &cdb_path : NULL)); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to initialize confdb domain " + "[%d]: %s\n", ret, sss_strerror(ret)); + goto fail; + } + } + + /* initialize domain list and sysdb of the domains */ + for (i = 0; domains[i] != NULL; i++) { + ret = mock_domain(test_ctx, test_ctx->confdb, tests_path, domains[i], + (domain == NULL ? &domain : NULL)); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add new domain [%d]: %s\n", + ret, sss_strerror(ret)); + goto fail; + } + } + + /* the first domain we obtained is already head of the complete list */ + test_ctx->dom = domain; + + /* set data from the first domain */ + test_ctx->sysdb = test_ctx->dom->sysdb; + test_ctx->nctx = test_ctx->dom->names; + test_ctx->conf_dom_path = cdb_path; + + return test_ctx; + +fail: + talloc_free(test_ctx); + return NULL; +} + + +struct sss_test_ctx * +create_dom_test_ctx(TALLOC_CTX *mem_ctx, + const char *tests_path, + const char *confdb_path, + const char *domain_name, + const char *id_provider, + struct sss_test_conf_param *params) +{ + const char *domains[] = {domain_name, NULL}; + + return create_multidom_test_ctx(mem_ctx, tests_path, confdb_path, domains, + id_provider, ¶ms); +} + +void test_multidom_suite_cleanup(const char *tests_path, + const char *cdb_file, + const char **domains) +{ + TALLOC_CTX *tmp_ctx = NULL; + char *cdb_path = NULL; + char *sysdb_path = NULL; + char *sysdb_ts_path = NULL; + errno_t ret; + int i; + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); + return; + } + + if (cdb_file != NULL) { + cdb_path = talloc_asprintf(tmp_ctx, "%s/%s", tests_path, cdb_file); + if (cdb_path == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Could not contruct cdb path\n"); + goto done; + } + + errno = 0; + ret = unlink(cdb_path); + if (ret != 0 && errno != ENOENT) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, "Could not delete the test config " + "ldb file [%d]: (%s)\n", ret, sss_strerror(ret)); + } + } + + if (domains != NULL) { + for (i = 0; domains[i] != NULL; i++) { + if (strcmp(domains[i], "FILES") == 0) { + /* files domain */ + ret = sysdb_get_db_file(tmp_ctx, "FILES", domains[i], tests_path, + &sysdb_path, &sysdb_ts_path); + if (ret != EOK) { + goto done; + } + } else { + /* The mocked database doesn't really care about its provider type, just + * distinguishes between a local and non-local databases + */ + ret = sysdb_get_db_file(tmp_ctx, "fake_nonlocal", domains[i], tests_path, + &sysdb_path, &sysdb_ts_path); + if (ret != EOK) { + goto done; + } + } + if (sysdb_path == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct sysdb path\n"); + goto done; + } + + errno = 0; + ret = unlink(sysdb_path); + if (ret != 0 && errno != ENOENT) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, "Could not delete the test domain " + "ldb file [%d]: (%s)\n", ret, sss_strerror(ret)); + } + + if (sysdb_ts_path) { + errno = 0; + ret = unlink(sysdb_ts_path); + if (ret != 0 && errno != ENOENT) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, "Could not delete the test domain " + "ldb timestamp file [%d]: (%s)\n", ret, sss_strerror(ret)); + } + } + + talloc_zfree(sysdb_path); + + } + } + + errno = 0; + ret = rmdir(tests_path); + if (ret != 0 && errno != ENOENT) { + ret = errno; + DEBUG(SSSDBG_CRIT_FAILURE, "Could not delete the test dir (%d) (%s)\n", + ret, sss_strerror(ret)); + } + +done: + talloc_free(tmp_ctx); +} + +void test_dom_suite_cleanup(const char *tests_path, + const char *cdb_file, + const char *domain) +{ + const char *domains[] = {domain, NULL}; + + test_multidom_suite_cleanup(tests_path, cdb_file, domains); +} + +struct sss_domain_info *named_domain(TALLOC_CTX *mem_ctx, + const char *name, + struct sss_domain_info *parent) +{ + struct sss_domain_info *dom = NULL; + + dom = talloc_zero(mem_ctx, struct sss_domain_info); + if (dom == NULL) { + return NULL; + } + + dom->name = talloc_strdup(dom, name); + if (dom->name == NULL) { + talloc_free(dom); + return NULL; + } + + dom->parent = parent; + + return dom; +} |