/
githubmirror
/
sssd
Обзор
Документация
Войти
/
githubmirror
/
sssd
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/tests/cmocka/test_responder_cache_req.c
4 528 строк
155 KB
Alexey Tikhonov
ENUMERATION: drop support of enumeration for IPA/AD
22 сен 2025, 11:02
22 сен 2025, 11:02
e60fcdd
Код
Авторство
О чём код?
/* Authors: 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 <tevent.h> #include <errno.h> #include <popt.h> #include "tests/cmocka/common_mock.h" #include "tests/cmocka/common_mock_resp.h" #include "db/sysdb.h" #include "responder/common/cache_req/cache_req.h" #include "providers/ipa/ipa_subdomains.h" #define LDAP_ID_PROVIDER "ldap" #define TESTS_PATH "tp_" BASE_FILE_STEM #define TEST_CONF_DB "test_responder_cache_req_conf.ldb" #define TEST_DOM_NAME "responder_cache_req_test" #define TEST_USER_PREFIX "test*" #define TEST_NO_USER_PREFIX "nosuchuser*" #define TEST_GROUP_PREFIX "test-group*" #define TEST_NO_GROUP_PREFIX "nosuchgroup*" struct test_user { const char *short_name; const char *upn; const char *sid; uid_t uid; gid_t gid; } users[] = {{"test-user1", "upn1@upndomain.com", "S-1-5-21-3623811015-3361044348-30300820-1001", 3001, 3001}, {"test-user2", "upn2@upndomain.com", "S-1-5-21-3623811015-3361044348-30300820-1002", 3002, 3002}}; struct test_group { const char *short_name; const char *sid; gid_t gid; } groups[] = {{"test-group1", "S-1-5-21-3623811015-3361044348-30300820-2001", 4001}, {"test-group2", "S-1-5-21-3623811015-3361044348-30300820-2002", 4002}}; #define new_single_domain_test(test) \ cmocka_unit_test_setup_teardown(test_ ## test, \ test_single_domain_setup, \ test_single_domain_teardown) #define new_single_domain_id_limit_test(test) \ cmocka_unit_test_setup_teardown(test_ ## test, \ test_single_domain_id_limits_setup, \ test_single_domain_teardown) #define new_multi_domain_test(test) \ cmocka_unit_test_setup_teardown(test_ ## test, \ test_multi_domain_setup, \ test_multi_domain_teardown) #define new_subdomain_test(test) \ cmocka_unit_test_setup_teardown(test_ ## test, \ test_subdomain_setup, \ test_subdomain_teardown) #define run_cache_req(ctx, send_fn, done_fn, dom, crp, lookup, expret) do { \ TALLOC_CTX *req_mem_ctx; \ struct tevent_req *req; \ errno_t ret; \ \ req_mem_ctx = talloc_new(global_talloc_context); \ check_leaks_push(req_mem_ctx); \ \ req = send_fn(req_mem_ctx, ctx->tctx->ev, ctx->rctx, \ ctx->ncache, crp, \ (dom == NULL ? NULL : dom->name), lookup); \ assert_non_null(req); \ tevent_req_set_callback(req, done_fn, ctx); \ \ ret = test_ev_loop(ctx->tctx); \ assert_int_equal(ret, expret); \ assert_true(check_leaks_pop(req_mem_ctx)); \ \ talloc_free(req_mem_ctx); \ } while (0) #define run_cache_req_domtype(ctx, send_fn, done_fn, dom, crp, domtype, lookup, expret) do { \ TALLOC_CTX *req_mem_ctx; \ struct tevent_req *req; \ errno_t ret; \ \ req_mem_ctx = talloc_new(global_talloc_context); \ check_leaks_push(req_mem_ctx); \ \ req = send_fn(req_mem_ctx, ctx->tctx->ev, ctx->rctx, \ ctx->ncache, crp, \ domtype, \ (dom == NULL ? NULL : dom->name), lookup); \ assert_non_null(req); \ tevent_req_set_callback(req, done_fn, ctx); \ \ ret = test_ev_loop(ctx->tctx); \ assert_int_equal(ret, expret); \ assert_true(check_leaks_pop(req_mem_ctx)); \ \ talloc_free(req_mem_ctx); \ } while (0) struct cache_req_test_ctx { struct sss_test_ctx *tctx; struct resp_ctx *rctx; struct sss_nc_ctx *ncache; struct sss_domain_info *subdomain; struct cache_req_result *result; bool dp_called; /* NOTE: Please, instead of adding new create_[user|group] bool, * use bitshift. */ bool create_user1; bool create_user2; bool create_group1; bool create_group2; bool create_subgroup1; bool create_subuser1; }; const char *domains[] = {"responder_cache_req_test_a", "responder_cache_req_test_b", "responder_cache_req_test_c", "responder_cache_req_test_d", NULL}; const char *subdomain_name = "responder_cache_req_test_a_sub"; struct cli_protocol_version *register_cli_protocol_version(void) { static struct cli_protocol_version version[] = { { 0, NULL, NULL } }; return version; } static void cache_req_user_by_name_test_done(struct tevent_req *req) { struct cache_req_test_ctx *ctx = NULL; ctx = tevent_req_callback_data(req, struct cache_req_test_ctx); ctx->tctx->error = cache_req_user_by_name_recv(ctx, req, &ctx->result); talloc_zfree(req); ctx->tctx->done = true; } static void cache_req_user_by_id_test_done(struct tevent_req *req) { struct cache_req_test_ctx *ctx = NULL; ctx = tevent_req_callback_data(req, struct cache_req_test_ctx); ctx->tctx->error = cache_req_user_by_id_recv(ctx, req, &ctx->result); talloc_zfree(req); ctx->tctx->done = true; } static void cache_req_group_by_name_test_done(struct tevent_req *req) { struct cache_req_test_ctx *ctx = NULL; ctx = tevent_req_callback_data(req, struct cache_req_test_ctx); ctx->tctx->error = cache_req_group_by_name_recv(ctx, req, &ctx->result); talloc_zfree(req); ctx->tctx->done = true; } static void cache_req_group_by_id_test_done(struct tevent_req *req) { struct cache_req_test_ctx *ctx = NULL; ctx = tevent_req_callback_data(req, struct cache_req_test_ctx); ctx->tctx->error = cache_req_group_by_id_recv(ctx, req, &ctx->result); talloc_zfree(req); ctx->tctx->done = true; } static void cache_req_object_by_sid_test_done(struct tevent_req *req) { struct cache_req_test_ctx *ctx = NULL; ctx = tevent_req_callback_data(req, struct cache_req_test_ctx); ctx->tctx->error = cache_req_object_by_sid_recv(ctx, req, &ctx->result); talloc_zfree(req); ctx->tctx->done = true; } static void cache_req_object_by_id_test_done(struct tevent_req *req) { struct cache_req_test_ctx *ctx = NULL; ctx = tevent_req_callback_data(req, struct cache_req_test_ctx); ctx->tctx->error = cache_req_object_by_id_recv(ctx, req, &ctx->result); talloc_zfree(req); ctx->tctx->done = true; } static void prepare_user(struct sss_domain_info *domain, struct test_user *user, uint64_t timeout, time_t transaction_time) { struct sysdb_attrs *attrs; errno_t ret; char *fqname; attrs = sysdb_new_attrs(NULL); assert_non_null(attrs); ret = sysdb_attrs_add_string(attrs, SYSDB_UPN, user->upn); assert_int_equal(ret, EOK); ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, user->sid); assert_int_equal(ret, EOK); fqname = sss_create_internal_fqname(attrs, user->short_name, domain->name); assert_non_null(fqname); ret = sysdb_store_user(domain, fqname, "pwd", user->uid, user->gid, NULL, NULL, NULL, "cn=origdn,dc=test", attrs, NULL, timeout, transaction_time); talloc_free(fqname); assert_int_equal(ret, EOK); talloc_free(attrs); } static void run_user_by_name(struct cache_req_test_ctx *test_ctx, struct sss_domain_info *domain, int cache_refresh_percent, errno_t exp_ret) { run_cache_req_domtype(test_ctx, cache_req_user_by_name_send, cache_req_user_by_name_test_done, domain, cache_refresh_percent, CACHE_REQ_POSIX_DOM, users[0].short_name, exp_ret); } static void run_user_by_upn(struct cache_req_test_ctx *test_ctx, struct sss_domain_info *domain, int cache_refresh_percent, errno_t exp_ret) { run_cache_req_domtype(test_ctx, cache_req_user_by_name_send, cache_req_user_by_name_test_done, domain, cache_refresh_percent, CACHE_REQ_POSIX_DOM, users[0].upn, exp_ret); } static void run_user_by_id(struct cache_req_test_ctx *test_ctx, struct sss_domain_info *domain, int cache_refresh_percent, errno_t exp_ret) { run_cache_req(test_ctx, cache_req_user_by_id_send, cache_req_user_by_id_test_done, domain, cache_refresh_percent, users[0].uid, exp_ret); } static void run_user_by_name_with_requested_domains(struct cache_req_test_ctx *test_ctx, struct sss_domain_info *domain, char **requested_domains, int cache_refresh_percent, errno_t exp_ret) { TALLOC_CTX *req_mem_ctx; struct tevent_req *req; errno_t ret; struct cache_req_data *data; req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); data = cache_req_data_name(req_mem_ctx, CACHE_REQ_USER_BY_NAME, users[0].short_name); assert_non_null(data); cache_req_data_set_requested_domains(data, requested_domains); req = cache_req_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, test_ctx->ncache, cache_refresh_percent, CACHE_REQ_POSIX_DOM, (domain == NULL ? NULL : domain->name), data); assert_non_null(req); talloc_steal(req, data); assert_non_null(req); tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, exp_ret); assert_true(check_leaks_pop(req_mem_ctx)); talloc_free(req_mem_ctx); } static void assert_msg_has_shortname(struct cache_req_test_ctx *test_ctx, struct ldb_message *msg, const char *check_name) { const char *ldbname; char *shortname; errno_t ret; ldbname = ldb_msg_find_attr_as_string(msg, SYSDB_NAME, NULL); assert_non_null(ldbname); ret = sss_parse_internal_fqname(test_ctx, ldbname, &shortname, NULL); assert_int_equal(ret, EOK); assert_string_equal(shortname, check_name); talloc_free(shortname); } static void check_user(struct cache_req_test_ctx *test_ctx, struct test_user *user, struct sss_domain_info *exp_dom) { const char *ldbupn; const char *ldbsid; uid_t ldbuid; assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, 1); assert_non_null(test_ctx->result->msgs); assert_non_null(test_ctx->result->msgs[0]); assert_msg_has_shortname(test_ctx, test_ctx->result->msgs[0], user->short_name); ldbupn = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0], SYSDB_UPN, NULL); assert_non_null(ldbupn); assert_string_equal(ldbupn, user->upn); ldbsid = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0], SYSDB_SID_STR, NULL); assert_non_null(ldbsid); assert_string_equal(ldbsid, user->sid); ldbuid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0], SYSDB_UIDNUM, 0); assert_int_equal(ldbuid, user->uid); assert_non_null(test_ctx->result->domain); assert_string_equal(exp_dom->name, test_ctx->result->domain->name); } static void prepare_group(struct sss_domain_info *domain, struct test_group *group, uint64_t timeout, time_t transaction_time) { struct sysdb_attrs *attrs; char *fqname; errno_t ret; attrs = sysdb_new_attrs(NULL); assert_non_null(attrs); ret = sysdb_attrs_add_string(attrs, SYSDB_SID_STR, group->sid); assert_int_equal(ret, EOK); fqname = sss_create_internal_fqname(attrs, group->short_name, domain->name); assert_non_null(fqname); ret = sysdb_store_group(domain, fqname, group->gid, attrs, timeout, transaction_time); talloc_free(fqname); assert_int_equal(ret, EOK); talloc_free(attrs); } static void run_group_by_name(struct cache_req_test_ctx *test_ctx, struct sss_domain_info *domain, int cache_refresh_percent, errno_t exp_ret) { run_cache_req_domtype(test_ctx, cache_req_group_by_name_send, cache_req_group_by_name_test_done, domain, cache_refresh_percent, CACHE_REQ_POSIX_DOM, groups[0].short_name, exp_ret); } static void run_group_by_id(struct cache_req_test_ctx *test_ctx, struct sss_domain_info *domain, int cache_refresh_percent, errno_t exp_ret) { run_cache_req(test_ctx, cache_req_group_by_id_send, cache_req_group_by_id_test_done, domain, cache_refresh_percent, groups[0].gid, exp_ret); } static void check_group(struct cache_req_test_ctx *test_ctx, struct test_group *group, struct sss_domain_info *exp_dom) { const char *ldbsid; gid_t ldbgid; assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, 1); assert_non_null(test_ctx->result->msgs); assert_non_null(test_ctx->result->msgs[0]); assert_msg_has_shortname(test_ctx, test_ctx->result->msgs[0], group->short_name); ldbsid = ldb_msg_find_attr_as_string(test_ctx->result->msgs[0], SYSDB_SID_STR, NULL); assert_non_null(ldbsid); assert_string_equal(ldbsid, group->sid); ldbgid = ldb_msg_find_attr_as_uint(test_ctx->result->msgs[0], SYSDB_GIDNUM, 0); assert_int_equal(ldbgid, group->gid); assert_non_null(test_ctx->result->domain); assert_string_equal(exp_dom->name, test_ctx->result->domain->name); } static void run_object_by_sid(struct cache_req_test_ctx *test_ctx, struct sss_domain_info *domain, const char *sid, const char **attrs, int cache_refresh_percent, errno_t exp_ret) { TALLOC_CTX *req_mem_ctx; struct tevent_req *req; errno_t ret; req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); req = cache_req_object_by_sid_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, test_ctx->ncache, cache_refresh_percent, (domain == NULL ? NULL : domain->name), sid, attrs); assert_non_null(req); tevent_req_set_callback(req, cache_req_object_by_sid_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, exp_ret); assert_true(check_leaks_pop(req_mem_ctx)); talloc_free(req_mem_ctx); } static void run_object_by_id(struct cache_req_test_ctx *test_ctx, struct sss_domain_info *domain, id_t id, const char **attrs, int cache_refresh_percent, errno_t exp_ret) { TALLOC_CTX *req_mem_ctx; struct tevent_req *req; errno_t ret; req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); req = cache_req_object_by_id_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, test_ctx->ncache, cache_refresh_percent, (domain == NULL ? NULL : domain->name), id, attrs); assert_non_null(req); tevent_req_set_callback(req, cache_req_object_by_id_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, exp_ret); assert_true(check_leaks_pop(req_mem_ctx)); talloc_free(req_mem_ctx); } struct tevent_req * __wrap_sss_dp_get_account_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, struct sss_domain_info *dom, bool fast_reply, enum sss_dp_acct_type type, const char *opt_name, uint32_t opt_id, const char *extra) { struct cache_req_test_ctx *ctx = NULL; ctx = sss_mock_ptr_type(struct cache_req_test_ctx*); ctx->dp_called = true; if (ctx->create_user1) { prepare_user(ctx->tctx->dom, &users[0], 1000, time(NULL)); } if (ctx->create_user2) { prepare_user(ctx->tctx->dom, &users[1], 1000, time(NULL)); } if (ctx->create_group1) { prepare_group(ctx->tctx->dom, &groups[0], 1000, time(NULL)); } if (ctx->create_group2) { prepare_group(ctx->tctx->dom, &groups[1], 1000, time(NULL)); } if (ctx->create_subgroup1) { struct sss_domain_info *domain = NULL; domain = find_domain_by_name(ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); prepare_group(domain, &groups[0], 1000, time(NULL)); } if (ctx->create_subuser1) { struct sss_domain_info *domain = NULL; domain = find_domain_by_name(ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); prepare_user(domain, &users[0], 1000, time(NULL)); } return test_req_succeed_send(mem_ctx, rctx->ev); } static int test_single_domain_setup_common(void **state, struct sss_test_conf_param *params, const char *id_provider) { struct cache_req_test_ctx *test_ctx = NULL; errno_t ret; assert_true(leak_check_setup()); test_dom_suite_setup(TESTS_PATH); test_ctx = talloc_zero(global_talloc_context, struct cache_req_test_ctx); assert_non_null(test_ctx); *state = test_ctx; test_ctx->tctx = create_dom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME, id_provider, params); assert_non_null(test_ctx->tctx); test_ctx->rctx = mock_rctx(test_ctx, test_ctx->tctx->ev, test_ctx->tctx->dom, NULL); assert_non_null(test_ctx->rctx); ret = sss_ncache_init(test_ctx, 10, &test_ctx->ncache); assert_int_equal(ret, EOK); check_leaks_push(test_ctx); return 0; } int test_single_domain_setup(void **state) { return test_single_domain_setup_common(state, NULL, LDAP_ID_PROVIDER); } int test_single_domain_teardown(void **state) { struct cache_req_test_ctx *test_ctx; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); talloc_zfree(test_ctx->result); assert_true(check_leaks_pop(test_ctx)); talloc_zfree(test_ctx); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); assert_true(leak_check_teardown()); return 0; } int test_single_domain_id_limits_setup(void **state) { struct sss_test_conf_param params[] = { { "min_id", "100" }, { "max_id", "10000" }, { NULL, NULL }, /* Sentinel */ }; return test_single_domain_setup_common(state, params, LDAP_ID_PROVIDER); } static int test_multi_domain_setup(void **state) { struct cache_req_test_ctx *test_ctx = NULL; errno_t ret; assert_true(leak_check_setup()); test_dom_suite_setup(TESTS_PATH); test_ctx = talloc_zero(global_talloc_context, struct cache_req_test_ctx); assert_non_null(test_ctx); *state = test_ctx; test_ctx->tctx = create_multidom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB, domains, LDAP_ID_PROVIDER, NULL); assert_non_null(test_ctx->tctx); test_ctx->rctx = mock_rctx(test_ctx, test_ctx->tctx->ev, test_ctx->tctx->dom, NULL); assert_non_null(test_ctx->rctx); ret = sss_ncache_init(test_ctx, 10, &test_ctx->ncache); assert_int_equal(ret, EOK); reset_ldb_errstrings(test_ctx->tctx->dom); check_leaks_push(test_ctx); return 0; } void test_user_by_id_below_id_range(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Test. */ run_cache_req(test_ctx, cache_req_user_by_id_send, cache_req_user_by_id_test_done, test_ctx->tctx->dom, 0, 10, ENOENT); assert_false(test_ctx->dp_called); } void test_user_by_id_above_id_range(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Test. */ run_cache_req(test_ctx, cache_req_user_by_id_send, cache_req_user_by_id_test_done, test_ctx->tctx->dom, 0, 100000, ENOENT); assert_false(test_ctx->dp_called); } static int test_multi_domain_teardown(void **state) { struct cache_req_test_ctx *test_ctx; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); talloc_zfree(test_ctx->result); reset_ldb_errstrings(test_ctx->tctx->dom); assert_true(check_leaks_pop(test_ctx)); talloc_zfree(test_ctx); test_multidom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, domains); assert_true(leak_check_teardown()); return 0; } int test_subdomain_setup(void **state) { struct cache_req_test_ctx *test_ctx = NULL; int ret; const char *const testdom[4] = { subdomain_name, "TEST_A.SUB", "test_a", "S-3" }; assert_true(leak_check_setup()); test_dom_suite_setup(TESTS_PATH); test_ctx = talloc_zero(global_talloc_context, struct cache_req_test_ctx); assert_non_null(test_ctx); *state = test_ctx; test_ctx->tctx = create_dom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME, LDAP_ID_PROVIDER, NULL); assert_non_null(test_ctx->tctx); test_ctx->rctx = mock_rctx(test_ctx, test_ctx->tctx->ev, test_ctx->tctx->dom, NULL); assert_non_null(test_ctx->rctx); ret = sss_ncache_init(test_ctx, 10, &test_ctx->ncache); assert_int_equal(ret, EOK); test_ctx->subdomain = new_subdomain(test_ctx, test_ctx->tctx->dom, testdom[0], testdom[1], testdom[2], testdom[0], testdom[3], MPG_DISABLED, NULL, NULL, 0, IPA_TRUST_UNKNOWN, test_ctx->tctx->confdb, true); assert_non_null(test_ctx->subdomain); ret = sysdb_subdomain_store(test_ctx->tctx->sysdb, testdom[0], testdom[1], testdom[2], testdom[0], testdom[3], MPG_DISABLED, NULL, 0, IPA_TRUST_UNKNOWN, NULL); assert_int_equal(ret, EOK); ret = sysdb_update_subdomains(test_ctx->tctx->dom, test_ctx->tctx->confdb); assert_int_equal(ret, EOK); *state = test_ctx; check_leaks_push(test_ctx); return 0; } int test_subdomain_teardown(void **state) { struct cache_req_test_ctx *test_ctx; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); talloc_zfree(test_ctx->result); talloc_zfree(test_ctx->rctx->cr_domains); assert_true(check_leaks_pop(test_ctx)); talloc_zfree(test_ctx); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); assert_true(leak_check_teardown()); return 0; } void test_user_by_name_multiple_domains_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_user(domain, &users[0], 1000, time(NULL)); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); mock_parse_inp(users[0].short_name, NULL, ERR_OK); /* Test. */ run_user_by_name(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); } void test_user_by_name_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); mock_parse_inp(users[0].short_name, NULL, ERR_OK); /* Test. */ run_user_by_name(test_ctx, NULL, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_user_by_name_multiple_domains_parse(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; char *input_fqn; char *fqname; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Add user to the first domain with different uid then test user. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_a", true); assert_non_null(domain); fqname = sss_create_internal_fqname(test_ctx, users[0].short_name, domain->name); assert_non_null(fqname); ret = sysdb_store_user(domain, fqname, "pwd", 2000, 1000, NULL, NULL, NULL, "cn=test-user,dc=test", NULL, NULL, 1000, time(NULL)); talloc_zfree(fqname); assert_int_equal(ret, EOK); /* Add test user to the last domain. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_user(domain, &users[0], 1000, time(NULL)); /* Append domain name to the username to form the qualified input. * We don't use the internal fqname here on purpose, because this is * the user's input. */ input_fqn = talloc_asprintf(test_ctx, "%s@%s", users[0].short_name, "responder_cache_req_test_d"); assert_non_null(input_fqn); /* Mock values. */ mock_parse_inp(users[0].short_name, "responder_cache_req_test_d", ERR_OK); /* Test. */ req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); req = cache_req_user_by_name_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, test_ctx->ncache, CACHE_REQ_POSIX_DOM, 0, NULL, input_fqn); assert_non_null(req); tevent_req_set_callback(req, cache_req_user_by_name_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_false(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); assert_non_null(test_ctx->result->lookup_name); assert_string_equal(input_fqn, test_ctx->result->lookup_name); talloc_free(input_fqn); } void test_user_by_name_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx->tctx->dom, &users[0], 1000, time(NULL)); /* Mock values */ mock_parse_inp(users[0].short_name, NULL, ERR_OK); /* Test. */ run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_user_by_name_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx->tctx->dom, &users[0], -1000, time(NULL)); /* Mock values */ mock_parse_inp(users[0].short_name, NULL, ERR_OK); /* Mock values. */ /* DP should be contacted */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_user_by_name_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx->tctx->dom, &users[0], 50, time(NULL) - 26); /* Mock values. */ /* DP should be contacted without callback */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_parse_inp(users[0].short_name, NULL, ERR_OK); /* Test. */ run_user_by_name(test_ctx, test_ctx->tctx->dom, 50, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_user_by_name_ncache(void **state) { struct cache_req_test_ctx *test_ctx = NULL; errno_t ret; char *fqname; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ fqname = sss_create_internal_fqname(test_ctx, users[0].short_name, test_ctx->tctx->dom->name); assert_non_null(fqname); ret = sss_ncache_set_user(test_ctx->ncache, false, test_ctx->tctx->dom, fqname); talloc_free(fqname); assert_int_equal(ret, EOK); /* Mock values */ mock_parse_inp(users[0].short_name, NULL, ERR_OK); /* Test. */ run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_user_by_name_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(users[0].short_name, NULL, ERR_OK); test_ctx->create_user1 = true; test_ctx->create_user2 = false; /* Test. */ run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_user_by_name_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(users[0].short_name, NULL, ERR_OK); /* Test. */ run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_user_by_name_missing_notfound_cache_first(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); test_ctx->rctx->cache_first = true; /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(users[0].short_name, NULL, ERR_OK); /* Test. */ run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_user_by_name_missing_notfound_full_name(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(users[0].short_name, TEST_DOM_NAME, ERR_OK); /* Test. */ run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_user_by_name_missing_notfound_cache_first_full_name(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); test_ctx->rctx->cache_first = true; /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(users[0].short_name, TEST_DOM_NAME, ERR_OK); /* Test. */ run_user_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_user_by_name_multiple_domains_requested_domains_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; char *requested_domains[2] = { discard_const("responder_cache_req_test_d"), NULL}; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_user(domain, &users[0], 1000, time(NULL)); /* Mock values. */ mock_parse_inp(users[0].short_name, NULL, ERR_OK); /* Test. */ run_user_by_name_with_requested_domains(test_ctx, NULL, requested_domains, 0, ERR_OK); /* The backend will not be called during this test because the user is * already cached in the requested domain. */ check_user(test_ctx, &users[0], domain); } void test_user_by_name_multiple_domains_requested_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; char *requested_domains[2] = { discard_const("responder_cache_req_test_a"), NULL}; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_user(domain, &users[0], 1000, time(NULL)); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); mock_parse_inp(users[0].short_name, NULL, ERR_OK); /* Test. */ run_user_by_name_with_requested_domains(test_ctx, NULL, requested_domains, 0, ENOENT); /* The requested domain is not the domain the user was added to, so we * expect ENOENT and that the backend is called. */ assert_true(test_ctx->dp_called); } void test_user_by_upn_multiple_domains_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_user(domain, &users[0], 1000, time(NULL)); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND); /* Test. */ run_user_by_upn(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); } void test_user_by_upn_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND); /* Test. */ run_user_by_upn(test_ctx, NULL, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_user_by_upn_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx->tctx->dom, &users[0], 1000, time(NULL)); /* Mock values. */ mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND); /* Test. */ run_user_by_upn(test_ctx, NULL, 0, ERR_OK); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_user_by_upn_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx->tctx->dom, &users[0], -1000, time(NULL)); /* Mock values. */ /* DP should be contacted */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND); /* Test. */ run_user_by_upn(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_user_by_upn_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx->tctx->dom, &users[0], 50, time(NULL) - 26); /* Mock values. */ /* DP should be contacted without callback */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND); /* Test. */ run_user_by_upn(test_ctx, NULL, 50, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_user_by_upn_ncache(void **state) { struct cache_req_test_ctx *test_ctx = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user's UPN. */ ret = sss_ncache_set_upn(test_ctx->ncache, false, test_ctx->tctx->dom, users[0].upn); assert_int_equal(ret, EOK); /* Mock values. */ mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND); /* Test. */ run_user_by_upn(test_ctx, NULL, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_user_by_upn_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND); test_ctx->create_user1 = true; test_ctx->create_user2 = false; /* Test. */ run_user_by_upn(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_user_by_upn_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(NULL, NULL, ERR_DOMAIN_NOT_FOUND); /* Test. */ run_user_by_upn(test_ctx, NULL, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_user_by_id_multiple_domains_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_user(domain, &users[0], 1000, time(NULL)); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); /* Test. */ run_user_by_id(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); } void test_user_by_id_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); /* Test. */ run_user_by_id(test_ctx, NULL, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_user_by_id_multiple_domains_locator_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, "responder_cache_req_test_d"); assert_non_null(locator_domain); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_user(domain, &users[0], 1000, time(NULL)); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, EOK); /* Test. */ run_user_by_id(test_ctx, NULL, 0, ERR_OK); /* Even though the locator tells us to skip all domains except d, the domains * are standalone and the result of the locator request is only valid within * the subdomains */ assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); talloc_free(tmp_ctx); } void test_user_by_id_multiple_domains_locator_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, "responder_cache_req_test_d"); assert_non_null(locator_domain); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_user(domain, &users[0], -1000, time(NULL)); will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, EOK); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); /* Test. */ run_user_by_id(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); talloc_free(tmp_ctx); } void test_user_by_id_sub_domains_locator_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); prepare_user(domain, &users[0], 1000, time(NULL)); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ run_user_by_id(test_ctx, NULL, 0, ERR_OK); /* Even though the ID is present in the last domain, * we're not calling sss_dp_get_account_send, * because the locator will cause cache_req to skip * all domains except _d */ assert_false(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); talloc_free(tmp_ctx); } void test_user_by_id_sub_domains_locator_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); prepare_user(domain, &users[0], -1000, time(NULL)); /* Note - DP will only be called once (so, we're not using will_return_always) * because the locator will tell us which domain to look into. For the recv * function, we use always b/c internally it mocks several values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ run_user_by_id(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); talloc_free(tmp_ctx); } void test_user_by_id_sub_domains_locator_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); prepare_user(domain, &users[0], 50, time(NULL) - 26); /* Note - DP will only be called once and we're not waiting * for the results (so, we're not mocking _recv) */ will_return(__wrap_sss_dp_get_account_send, test_ctx); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ run_user_by_id(test_ctx, NULL, 50, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); talloc_free(tmp_ctx); } void test_user_by_id_sub_domains_locator_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Note - DP will only be called once (so, we're not using will_return_always) * because the locator will tell us which domain to look into. For the recv * function, we use always b/c internally it mocks several values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ test_ctx->create_subuser1 = true; run_user_by_id(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); check_user(test_ctx, &users[0], domain); talloc_free(tmp_ctx); } void test_group_by_id_below_id_range(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Test. */ run_cache_req(test_ctx, cache_req_group_by_id_send, cache_req_group_by_id_test_done, test_ctx->tctx->dom, 0, 10, ENOENT); assert_false(test_ctx->dp_called); } void test_group_by_id_above_id_range(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Test. */ run_cache_req(test_ctx, cache_req_group_by_id_send, cache_req_group_by_id_test_done, test_ctx->tctx->dom, 0, 100000, ENOENT); assert_false(test_ctx->dp_called); } void test_user_by_id_sub_domains_locator_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); will_return(sss_dp_get_account_domain_recv, ERR_NOT_FOUND); /* Test. */ run_user_by_id(test_ctx, NULL, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_user_by_id_sub_domains_locator_cache_expired_two_calls(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); test_ctx->create_subuser1 = true; prepare_user(domain, &users[0], -1000, time(NULL)); /* Note - DP will only be called once (so, we're not using will_return_always) * because the locator will tell us which domain to look into. For the recv * function, we use always b/c internally it mocks several values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ run_user_by_id(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); /* Request the same user again */ test_ctx->tctx->done = false; talloc_zfree(test_ctx->result); run_user_by_id(test_ctx, NULL, 0, ERR_OK); check_user(test_ctx, &users[0], domain); talloc_free(tmp_ctx); } void test_user_by_id_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx->tctx->dom, &users[0], 1000, time(NULL)); /* Test. */ run_user_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_user_by_id_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx->tctx->dom, &users[0], -1000, time(NULL)); /* Mock values. */ /* DP should be contacted. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_user_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_user_by_id_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx->tctx->dom, &users[0], 50, time(NULL) - 26); /* Mock values. */ /* DP should be contacted without callback */ will_return(__wrap_sss_dp_get_account_send, test_ctx); /* Test. */ run_user_by_id(test_ctx, test_ctx->tctx->dom, 50, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_user_by_id_ncache(void **state) { struct cache_req_test_ctx *test_ctx = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ ret = sss_ncache_set_uid(test_ctx->ncache, false, NULL, users[0].uid); assert_int_equal(ret, EOK); /* Test. */ run_user_by_id(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_user_by_id_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); test_ctx->create_user1 = true; test_ctx->create_user2 = false; /* Test. */ run_user_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_user_by_id_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_user_by_id(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_group_by_name_multiple_domains_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_group(domain, &groups[0], 1000, time(NULL)); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); mock_parse_inp(groups[0].short_name, NULL, ERR_OK); /* Test. */ run_group_by_name(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); } void test_group_by_name_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); mock_parse_inp(groups[0].short_name, NULL, ERR_OK); /* Test. */ run_group_by_name(test_ctx, NULL, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_group_by_name_multiple_domains_parse(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; char *input_fqn; char *fqname; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Add group to the first domain. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_a", true); assert_non_null(domain); fqname = sss_create_internal_fqname(test_ctx, users[0].short_name, domain->name); assert_non_null(fqname); ret = sysdb_store_group(domain, fqname, 2000, NULL, 1000, time(NULL)); talloc_zfree(fqname); assert_int_equal(ret, EOK); /* Add group to the last domain, with different gid. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_group(domain, &groups[0], 1000, time(NULL)); /* Append domain name to the groupname. * We don't use the internal fqname here on purpose, because this is * the user's input. */ input_fqn = talloc_asprintf(test_ctx, "%s@%s", groups[0].short_name, "responder_cache_req_test_d"); assert_non_null(input_fqn); /* Test. */ req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); mock_parse_inp(groups[0].short_name, "responder_cache_req_test_d", ERR_OK); req = cache_req_group_by_name_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, test_ctx->ncache, 0, CACHE_REQ_POSIX_DOM, NULL, input_fqn); assert_non_null(req); tevent_req_set_callback(req, cache_req_group_by_name_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_false(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); assert_non_null(test_ctx->result->lookup_name); assert_string_equal(input_fqn, test_ctx->result->lookup_name); talloc_free(input_fqn); } void test_group_by_name_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ prepare_group(test_ctx->tctx->dom, &groups[0], 1000, time(NULL)); /* Mock values */ mock_parse_inp(groups[0].short_name, NULL, ERR_OK); /* Test. */ run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); check_group(test_ctx, &groups[0], test_ctx->tctx->dom); } void test_group_by_name_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ prepare_group(test_ctx->tctx->dom, &groups[0], -1000, time(NULL)); /* Mock values. */ /* DP should be contacted */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(groups[0].short_name, NULL, ERR_OK); /* Test. */ run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], test_ctx->tctx->dom); } void test_group_by_name_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ prepare_group(test_ctx->tctx->dom, &groups[0], 50, time(NULL) - 26); /* Mock values. */ /* DP should be contacted without callback */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_parse_inp(groups[0].short_name, NULL, ERR_OK); /* Test. */ run_group_by_name(test_ctx, test_ctx->tctx->dom, 50, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], test_ctx->tctx->dom); } void test_group_by_name_ncache(void **state) { struct cache_req_test_ctx *test_ctx = NULL; errno_t ret; char *fqname; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ fqname = sss_create_internal_fqname(test_ctx, groups[0].short_name, test_ctx->tctx->dom->name); assert_non_null(fqname); ret = sss_ncache_set_group(test_ctx->ncache, false, test_ctx->tctx->dom, fqname); talloc_free(fqname); assert_int_equal(ret, EOK); /* Mock values */ mock_parse_inp(groups[0].short_name, NULL, ERR_OK); /* Test. */ run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_group_by_name_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(groups[0].short_name, NULL, ERR_OK); test_ctx->create_group1 = true; test_ctx->create_group2 = false; /* Test. */ run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], test_ctx->tctx->dom); } void test_group_by_name_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(groups[0].short_name, NULL, ERR_OK); /* Test. */ run_group_by_name(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_group_by_id_multiple_domains_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_group(domain, &groups[0], 1000, time(NULL)); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); /* Test. */ run_group_by_id(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); } void test_group_by_id_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); /* Test. */ run_group_by_id(test_ctx, NULL, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_group_by_id_multiple_domains_outside_id_range(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; struct sss_domain_info *domain_a = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); domain_a = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_a", true); assert_non_null(domain_a); domain_a->id_min = 1; domain_a->id_max = 100; /* Setup group. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_group(domain, &groups[0], 1000, time(NULL)); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); /* Test. */ run_group_by_id(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); } void test_group_by_id_multiple_domains_locator_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, "responder_cache_req_test_d"); assert_non_null(locator_domain); /* Setup group. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_group(domain, &groups[0], 1000, time(NULL)); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, EOK); /* Test. */ run_group_by_id(test_ctx, NULL, 0, ERR_OK); /* Even though the locator tells us to skip all domains except d, the domains * are standalone and the result of the locator request is only valid within * the subdomains */ assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); talloc_free(tmp_ctx); } void test_group_by_id_multiple_domains_locator_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, "responder_cache_req_test_d"); assert_non_null(locator_domain); /* Setup group. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_group(domain, &groups[0], -1000, time(NULL)); will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, EOK); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); /* Test. */ run_group_by_id(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); talloc_free(tmp_ctx); } void test_group_by_id_sub_domains_locator_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Setup group. */ domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); prepare_group(domain, &groups[0], 1000, time(NULL)); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ run_group_by_id(test_ctx, NULL, 0, ERR_OK); /* Even though the ID is present in the last domain, * we're not calling sss_dp_get_account_send, * because the locator will cause cache_req to skip * all domains except _d */ assert_false(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); talloc_free(tmp_ctx); } void test_group_by_id_sub_domains_locator_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Setup group. */ domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); prepare_group(domain, &groups[0], -1000, time(NULL)); /* Note - DP will only be called once (so, we're not using will_return_always) * because the locator will tell us which domain to look into. For the recv * function, we use always b/c internally it mocks several values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ run_group_by_id(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); talloc_free(tmp_ctx); } void test_group_by_id_sub_domains_locator_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Setup group. */ domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); prepare_group(domain, &groups[0], 50, time(NULL) - 26); /* Note - DP will only be called once and we're not waiting * for the results (so, we're not mocking _recv) */ will_return(__wrap_sss_dp_get_account_send, test_ctx); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ run_group_by_id(test_ctx, NULL, 50, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); talloc_free(tmp_ctx); } void test_group_by_id_sub_domains_locator_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Note - DP will only be called once (so, we're not using will_return_always) * because the locator will tell us which domain to look into. For the recv * function, we use always b/c internally it mocks several values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ test_ctx->create_subgroup1 = true; run_group_by_id(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); check_group(test_ctx, &groups[0], domain); talloc_free(tmp_ctx); } void test_group_by_id_sub_domains_locator_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); will_return(sss_dp_get_account_domain_recv, ERR_NOT_FOUND); /* Test. */ run_group_by_id(test_ctx, NULL, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_group_by_id_sub_domains_locator_cache_expired_two_calls(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Setup group. */ domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); test_ctx->create_subgroup1 = true; prepare_group(domain, &groups[0], -1000, time(NULL)); /* Note - DP will only be called once (so, we're not using will_return_always) * because the locator will tell us which domain to look into. For the recv * function, we use always b/c internally it mocks several values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ run_group_by_id(test_ctx, NULL, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); /* Request the same group again */ test_ctx->tctx->done = false; talloc_zfree(test_ctx->result); run_group_by_id(test_ctx, NULL, 0, ERR_OK); check_group(test_ctx, &groups[0], domain); talloc_free(tmp_ctx); } void test_group_by_id_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ prepare_group(test_ctx->tctx->dom, &groups[0], 1000, time(NULL)); /* Test. */ run_group_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); check_group(test_ctx, &groups[0], test_ctx->tctx->dom); } void test_group_by_id_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ prepare_group(test_ctx->tctx->dom, &groups[0], -1000, time(NULL)); /* Mock values. */ /* DP should be contacted */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_group_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], test_ctx->tctx->dom); } void test_group_by_id_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ prepare_group(test_ctx->tctx->dom, &groups[0], 50, time(NULL) - 26); /* Mock values. */ /* DP should be contacted without callback */ will_return(__wrap_sss_dp_get_account_send, test_ctx); /* Test. */ run_group_by_id(test_ctx, test_ctx->tctx->dom, 50, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], test_ctx->tctx->dom); } void test_group_by_id_ncache(void **state) { struct cache_req_test_ctx *test_ctx = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup group. */ ret = sss_ncache_set_gid(test_ctx->ncache, false, NULL, groups[0].gid); assert_int_equal(ret, EOK); /* Test. */ run_group_by_id(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_group_by_id_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); test_ctx->create_group1 = true; test_ctx->create_group2 = false; /* Test. */ run_group_by_id(test_ctx, test_ctx->tctx->dom, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], test_ctx->tctx->dom); } void test_group_by_id_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_group_by_id(test_ctx, test_ctx->tctx->dom, 0, ENOENT); assert_true(test_ctx->dp_called); } static void cache_req_user_by_filter_test_done(struct tevent_req *req) { struct cache_req_test_ctx *ctx = NULL; ctx = tevent_req_callback_data(req, struct cache_req_test_ctx); ctx->tctx->error = cache_req_user_by_filter_recv(ctx, req, &ctx->result); talloc_zfree(req); ctx->tctx->done = true; } void test_user_by_recent_filter_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); test_ctx->create_user1 = true; test_ctx->create_user2 = false; prepare_user(test_ctx->tctx->dom, &users[1], 1000, time(NULL) - 1); req_mem_ctx = talloc_new(test_ctx->tctx); check_leaks_push(req_mem_ctx); /* Mock values */ /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(TEST_USER_PREFIX, NULL, ERR_OK); /* User TEST_USER is created with a DP callback. */ req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, CACHE_REQ_POSIX_DOM, test_ctx->tctx->dom->name, NULL, TEST_USER_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_user_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, 1); assert_msg_has_shortname(test_ctx, test_ctx->result->msgs[0], users[0].short_name); } void test_users_by_recent_filter_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; size_t num_users = 2; const char **user_names; const char *ldb_results[num_users]; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); test_ctx->create_user1 = true; test_ctx->create_user2 = true; req_mem_ctx = talloc_new(test_ctx->tctx); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(TEST_USER_PREFIX, NULL, ERR_OK); /* User TEST_USER1 and TEST_USER2 are created with a DP callback. */ req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, CACHE_REQ_POSIX_DOM, test_ctx->tctx->dom->name, NULL, TEST_USER_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_user_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, 2); user_names = talloc_zero_array(test_ctx, const char *, num_users); assert_non_null(user_names); user_names[0] = sss_create_internal_fqname(user_names, users[0].short_name, test_ctx->result->domain->name); assert_non_null(user_names[0]); user_names[1] = sss_create_internal_fqname(user_names, users[1].short_name, test_ctx->result->domain->name); assert_non_null(user_names[1]); for (int i = 0; i < num_users; ++i) { ldb_results[i] = ldb_msg_find_attr_as_string(test_ctx->result->msgs[i], SYSDB_NAME, NULL); assert_non_null(ldb_results[i]); } assert_string_not_equal(ldb_results[0], ldb_results[1]); assert_true(are_values_in_array(user_names, num_users, ldb_results, num_users)); talloc_free(req_mem_ctx); talloc_free(user_names); } void test_users_by_filter_filter_old(void **state) { struct cache_req_test_ctx *test_ctx = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); test_ctx->create_user1 = true; test_ctx->create_user2 = false; /* This user was updated in distant past, so it won't be reported by * the filter search */ prepare_user(test_ctx->tctx->dom, &users[1], 1000, 1); req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(TEST_USER_PREFIX, NULL, ERR_OK); req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, CACHE_REQ_POSIX_DOM, test_ctx->tctx->dom->name, NULL, TEST_USER_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_user_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, 1); assert_msg_has_shortname(test_ctx, test_ctx->result->msgs[0], users[0].short_name); } /* This test uses a "files" provider */ void test_users_by_filter_filter_files(void **state) { struct cache_req_test_ctx *test_ctx = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); test_ctx->create_user1 = false; test_ctx->create_user2 = false; /* This user was updated in distant past but will still be reported */ prepare_user(test_ctx->tctx->dom, &users[0], 1000, 1); req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); /* Filters only go to DP when /etc/passwd and /etc/group were modified */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(TEST_USER_PREFIX, NULL, ERR_OK); req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, CACHE_REQ_POSIX_DOM, test_ctx->tctx->dom->name, NULL, TEST_USER_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_user_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, 1); assert_msg_has_shortname(test_ctx, test_ctx->result->msgs[0], users[0].short_name); } void test_users_by_filter_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(TEST_NO_USER_PREFIX, NULL, ERR_OK); req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, CACHE_REQ_POSIX_DOM, test_ctx->tctx->dom->name, NULL, TEST_NO_USER_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_user_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ENOENT); assert_true(check_leaks_pop(req_mem_ctx)); } /* * Given two users are present * When the users are searched by filtering domains * Then the two users are returned correctly. */ static void test_users_by_filter_multiple_domains_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; size_t num_users = 2; const char **input_dns = NULL; const char **user_names = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); test_ctx->create_user1 = true; test_ctx->create_user2 = true; domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); /* Generate DN for user1 */ input_dns = talloc_zero_array(test_ctx, const char *, num_users); assert_non_null(input_dns); input_dns[0] = talloc_asprintf(input_dns, "cn=%s,dc=test", users[0].short_name); assert_non_null(input_dns[0]); /* Generate internal FQDN for user1 */ user_names = talloc_zero_array(test_ctx, const char *, num_users); assert_non_null(user_names); user_names[0] = sss_create_internal_fqname(user_names, users[0].short_name, domain->name); assert_non_null(user_names[0]); ret = sysdb_store_user(domain, user_names[0], "pwd", 1000, 1000, NULL, NULL, NULL, input_dns[0], NULL, NULL, 1000, time(NULL)); assert_int_equal(ret, EOK); /* Generate DN for user2 */ input_dns[1] = talloc_asprintf(input_dns, "cn=%s,dc=test", users[1].short_name); assert_non_null(input_dns[1]); /* Generate internal FQDN for user2 */ user_names[1] = sss_create_internal_fqname(user_names, users[1].short_name, domain->name); assert_non_null(user_names[1]); ret = sysdb_store_user(domain, user_names[1], "pwd", 1001, 1001, NULL, NULL, NULL, input_dns[1], NULL, NULL, 1000, time(NULL)); assert_int_equal(ret, EOK); req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(TEST_USER_PREFIX, NULL, ERR_OK); req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, CACHE_REQ_POSIX_DOM, test_ctx->tctx->dom->name, NULL, TEST_USER_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_user_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, num_users); for (int i = 0; i < num_users; ++i) { assert_msg_has_shortname(test_ctx, test_ctx->result->msgs[i], users[i].short_name); } talloc_free(user_names); talloc_free(input_dns); } void test_users_by_filter_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); mock_parse_inp(TEST_NO_USER_PREFIX, NULL, ERR_OK); req = cache_req_user_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, CACHE_REQ_POSIX_DOM, domain->name, NULL, TEST_NO_USER_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_user_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ENOENT); assert_true(check_leaks_pop(req_mem_ctx)); } static void cache_req_group_by_filter_test_done(struct tevent_req *req) { struct cache_req_test_ctx *ctx = NULL; ctx = tevent_req_callback_data(req, struct cache_req_test_ctx); ctx->tctx->error = cache_req_group_by_filter_recv(ctx, req, &ctx->result); talloc_zfree(req); ctx->tctx->done = true; } void test_group_by_recent_filter_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); test_ctx->create_group1 = true; test_ctx->create_group2 = false; prepare_group(test_ctx->tctx->dom, &groups[1], 1001, time(NULL) - 1); req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(TEST_USER_PREFIX, NULL, ERR_OK); /* Group TEST_GROUP is created with a DP callback. */ req = cache_req_group_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, CACHE_REQ_POSIX_DOM, test_ctx->tctx->dom->name, TEST_USER_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_group_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, 1); assert_msg_has_shortname(test_ctx, test_ctx->result->msgs[0], groups[0].short_name); } void test_groups_by_recent_filter_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; TALLOC_CTX *req_mem_ctx = NULL; TALLOC_CTX *tmp_ctx = NULL; struct tevent_req *req = NULL; const char **group_names = NULL; const char **ldb_results = NULL; const char *ldbname = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); test_ctx->create_group1 = true; test_ctx->create_group2 = true; prepare_group(test_ctx->tctx->dom, &groups[1], 1001, time(NULL) - 1); req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); mock_parse_inp(TEST_USER_PREFIX, NULL, ERR_OK); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Group TEST_GROUP1 and TEST_GROUP2 are created with a DP callback. */ req = cache_req_group_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, CACHE_REQ_POSIX_DOM, test_ctx->tctx->dom->name, TEST_USER_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_group_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, 2); tmp_ctx = talloc_new(req_mem_ctx); group_names = talloc_array(tmp_ctx, const char *, 2); assert_non_null(group_names); group_names[0] = sss_create_internal_fqname(group_names, groups[0].short_name, test_ctx->result->domain->name); assert_non_null(group_names[0]); group_names[1] = sss_create_internal_fqname(group_names, groups[1].short_name, test_ctx->result->domain->name); assert_non_null(group_names[1]); ldb_results = talloc_array(tmp_ctx, const char *, 2); assert_non_null(ldb_results); for (int i = 0; i < 2; ++i) { ldbname = ldb_msg_find_attr_as_string(test_ctx->result->msgs[i], SYSDB_NAME, NULL); assert_non_null(ldbname); ldb_results[i] = ldbname; } assert_string_not_equal(ldb_results[0], ldb_results[1]); assert_true(tc_are_values_in_array(group_names, ldb_results)); talloc_zfree(tmp_ctx); } void test_groups_by_filter_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(TEST_NO_GROUP_PREFIX, NULL, ERR_OK); req = cache_req_group_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, CACHE_REQ_POSIX_DOM, test_ctx->tctx->dom->name, TEST_NO_GROUP_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_group_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ENOENT); assert_true(check_leaks_pop(req_mem_ctx)); } void test_groups_by_filter_files(void **state) { struct cache_req_test_ctx *test_ctx; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); test_ctx->create_group1 = true; req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(TEST_GROUP_PREFIX, NULL, ERR_OK); req = cache_req_group_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, CACHE_REQ_POSIX_DOM, test_ctx->tctx->dom->name, TEST_GROUP_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_group_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, 1); assert_msg_has_shortname(test_ctx, test_ctx->result->msgs[0], groups[0].short_name); } /* * Given two groups are present * When the groups are searched by filtering domains * Then the two groups are returned correctly. */ void test_groups_by_filter_multiple_domains_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; size_t num_groups = 2; const char **group_names = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); test_ctx->create_group1 = true; test_ctx->create_group2 = true; domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); /* Generate internal FQDN for group1 */ group_names = talloc_zero_array(test_ctx, const char *, num_groups); assert_non_null(group_names); group_names[0] = sss_create_internal_fqname(group_names, groups[0].short_name, domain->name); assert_non_null(group_names[0]); ret = sysdb_store_group(domain, group_names[0], 1000, NULL, 1000, time(NULL)); assert_int_equal(ret, EOK); /* Generate internal FQDN for group2 */ group_names[1] = sss_create_internal_fqname(group_names, groups[1].short_name, domain->name); assert_non_null(group_names[1]); ret = sysdb_store_group(domain, group_names[1], 1001, NULL, 1001, time(NULL)); assert_int_equal(ret, EOK); req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); mock_parse_inp(TEST_USER_PREFIX, NULL, ERR_OK); req = cache_req_group_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, CACHE_REQ_POSIX_DOM, test_ctx->tctx->dom->name, TEST_USER_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_group_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ERR_OK); assert_true(check_leaks_pop(req_mem_ctx)); assert_non_null(test_ctx->result); assert_int_equal(test_ctx->result->count, num_groups); assert_msg_has_shortname(test_ctx, test_ctx->result->msgs[0], groups[1].short_name); assert_msg_has_shortname(test_ctx, test_ctx->result->msgs[1], groups[0].short_name); talloc_free(group_names); } void test_groups_by_filter_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; TALLOC_CTX *req_mem_ctx = NULL; struct tevent_req *req = NULL; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); req_mem_ctx = talloc_new(global_talloc_context); check_leaks_push(req_mem_ctx); /* Filters always go to DP */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); mock_parse_inp(TEST_NO_GROUP_PREFIX, NULL, ERR_OK); req = cache_req_group_by_filter_send(req_mem_ctx, test_ctx->tctx->ev, test_ctx->rctx, CACHE_REQ_POSIX_DOM, domain->name, TEST_NO_GROUP_PREFIX); assert_non_null(req); tevent_req_set_callback(req, cache_req_group_by_filter_test_done, test_ctx); ret = test_ev_loop(test_ctx->tctx); assert_int_equal(ret, ENOENT); assert_true(check_leaks_pop(req_mem_ctx)); } void test_object_by_sid_user_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx->tctx->dom, &users[0], 1000, time(NULL)); /* Test. */ run_object_by_sid(test_ctx, test_ctx->tctx->dom, users[0].sid, attrs, 0, ERR_OK); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_object_by_sid_user_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx->tctx->dom, &users[0], -1000, time(NULL)); /* Mock values. */ /* DP should be contacted */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_object_by_sid(test_ctx, test_ctx->tctx->dom, users[0].sid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_object_by_sid_user_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = NULL; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx->tctx->dom, &users[0], 50, time(NULL) - 26); /* Mock values. */ /* DP should be contacted without callback */ will_return(__wrap_sss_dp_get_account_send, test_ctx); /* Test. */ run_object_by_sid(test_ctx, test_ctx->tctx->dom, users[0].sid, attrs, 50, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_object_by_sid_user_ncache(void **state) { struct cache_req_test_ctx *test_ctx = NULL; const char *attrs[] = SYSDB_PW_ATTRS; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ ret = sss_ncache_set_sid(test_ctx->ncache, false, test_ctx->tctx->dom, users[0].sid); assert_int_equal(ret, EOK); /* Test. */ run_object_by_sid(test_ctx, test_ctx->tctx->dom, users[0].sid, attrs, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_object_by_sid_user_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); test_ctx->create_user1 = true; test_ctx->create_user2 = false; /* Test. */ run_object_by_sid(test_ctx, test_ctx->tctx->dom, users[0].sid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_object_by_sid_user_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_object_by_sid(test_ctx, test_ctx->tctx->dom, users[0].sid, attrs, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_object_by_sid_user_multiple_domains_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_user(domain, &users[0], 1000, time(NULL)); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); /* Test. */ run_object_by_sid(test_ctx, NULL, users[0].sid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); } void test_object_by_sid_user_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); /* Test. */ run_object_by_sid(test_ctx, NULL, users[0].sid, attrs, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_object_by_sid_group_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); const char **attrs = SYSDB_GRSRC_ATTRS(test_ctx->tctx->dom); /* Setup user. */ prepare_group(test_ctx->tctx->dom, &groups[0], 1000, time(NULL)); /* Test. */ run_object_by_sid(test_ctx, test_ctx->tctx->dom, groups[0].sid, attrs, 0, ERR_OK); check_group(test_ctx, &groups[0], test_ctx->tctx->dom); } void test_object_by_sid_group_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); const char **attrs = SYSDB_GRSRC_ATTRS(test_ctx->tctx->dom); /* Setup user. */ prepare_group(test_ctx->tctx->dom, &groups[0], -1000, time(NULL)); /* Mock values. */ /* DP should be contacted */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_object_by_sid(test_ctx, test_ctx->tctx->dom, groups[0].sid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], test_ctx->tctx->dom); } void test_object_by_sid_group_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); const char **attrs = SYSDB_GRSRC_ATTRS(test_ctx->tctx->dom); /* Setup user. */ prepare_group(test_ctx->tctx->dom, &groups[0], 50, time(NULL) - 26); /* Mock values. */ /* DP should be contacted without callback */ will_return(__wrap_sss_dp_get_account_send, test_ctx); /* Test. */ run_object_by_sid(test_ctx, test_ctx->tctx->dom, groups[0].sid, attrs, 50, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], test_ctx->tctx->dom); } void test_object_by_sid_group_ncache(void **state) { struct cache_req_test_ctx *test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); const char **attrs = SYSDB_GRSRC_ATTRS(test_ctx->tctx->dom); errno_t ret; /* Setup user. */ ret = sss_ncache_set_sid(test_ctx->ncache, false, test_ctx->tctx->dom, groups[0].sid); assert_int_equal(ret, EOK); /* Test. */ run_object_by_sid(test_ctx, test_ctx->tctx->dom, groups[0].sid, attrs, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_object_by_sid_group_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); const char **attrs = SYSDB_GRSRC_ATTRS(test_ctx->tctx->dom); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); test_ctx->create_group1 = true; test_ctx->create_group2 = false; /* Test. */ run_object_by_sid(test_ctx, test_ctx->tctx->dom, groups[0].sid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], test_ctx->tctx->dom); } void test_object_by_sid_group_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); const char **attrs = SYSDB_GRSRC_ATTRS(test_ctx->tctx->dom); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_object_by_sid(test_ctx, test_ctx->tctx->dom, groups[0].sid, attrs, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_object_by_sid_group_multiple_domains_found(void **state) { struct cache_req_test_ctx *test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); struct sss_domain_info *domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); const char **attrs = SYSDB_GRSRC_ATTRS(domain); /* Setup user. */ prepare_group(domain, &groups[0], 1000, time(NULL)); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); /* Test. */ run_object_by_sid(test_ctx, NULL, groups[0].sid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); } void test_object_by_sid_group_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); const char **attrs = SYSDB_GRSRC_ATTRS(test_ctx->tctx->dom); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); /* Test. */ run_object_by_sid(test_ctx, NULL, groups[0].sid, attrs, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_object_by_id_user_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx->tctx->dom, &users[0], 1000, time(NULL)); /* Test. */ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_object_by_id_user_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx->tctx->dom, &users[0], -1000, time(NULL)); /* Mock values. */ /* DP should be contacted */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_object_by_id_user_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = NULL; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ prepare_user(test_ctx->tctx->dom, &users[0], 50, time(NULL) - 26); /* Mock values. */ /* DP should be contacted without callback */ will_return(__wrap_sss_dp_get_account_send, test_ctx); /* Test. */ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 50, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_object_by_id_user_ncache(void **state) { struct cache_req_test_ctx *test_ctx = NULL; const char *attrs[] = SYSDB_PW_ATTRS; errno_t ret; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. We explicitly add the UID into BOTH UID and GID * namespaces, because otherwise the cache_req plugin would * search the Data Provider anyway, because it can't be sure * the object can be of the other type or not */ ret = sss_ncache_set_uid(test_ctx->ncache, false, test_ctx->tctx->dom, users[0].uid); assert_int_equal(ret, EOK); ret = sss_ncache_set_gid(test_ctx->ncache, false, test_ctx->tctx->dom, users[0].uid); assert_int_equal(ret, EOK); /* Test. */ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_object_by_id_user_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); test_ctx->create_user1 = true; test_ctx->create_user2 = false; /* Test. */ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], test_ctx->tctx->dom); } void test_object_by_id_user_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_object_by_id_user_multiple_domains_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_user(domain, &users[0], 1000, time(NULL)); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); /* Test. */ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); } void test_object_by_id_user_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); /* Test. */ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_object_by_id_group_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); const char **attrs = SYSDB_GRSRC_ATTRS(test_ctx->tctx->dom); /* Setup user. */ prepare_group(test_ctx->tctx->dom, &groups[0], 1000, time(NULL)); /* Test. */ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); check_group(test_ctx, &groups[0], test_ctx->tctx->dom); } void test_object_by_id_group_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); const char **attrs = SYSDB_GRSRC_ATTRS(test_ctx->tctx->dom); /* Setup user. */ prepare_group(test_ctx->tctx->dom, &groups[0], -1000, time(NULL)); /* Mock values. */ /* DP should be contacted */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], test_ctx->tctx->dom); } void test_object_by_id_group_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); const char **attrs = SYSDB_GRSRC_ATTRS(test_ctx->tctx->dom); /* Setup user. */ prepare_group(test_ctx->tctx->dom, &groups[0], 50, time(NULL) - 26); /* Mock values. */ /* DP should be contacted without callback */ will_return(__wrap_sss_dp_get_account_send, test_ctx); /* Test. */ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 50, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], test_ctx->tctx->dom); } void test_object_by_id_group_ncache(void **state) { struct cache_req_test_ctx *test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); const char **attrs = SYSDB_GRSRC_ATTRS(test_ctx->tctx->dom); errno_t ret; /* Setup group. We explicitly add the UID into BOTH UID and GID * namespaces, because otherwise the cache_req plugin would * search the Data Provider anyway, because it can't be sure * the object can be of the other type or not */ ret = sss_ncache_set_uid(test_ctx->ncache, false, test_ctx->tctx->dom, groups[0].gid); assert_int_equal(ret, EOK); ret = sss_ncache_set_gid(test_ctx->ncache, false, test_ctx->tctx->dom, groups[0].gid); assert_int_equal(ret, EOK); assert_int_equal(ret, EOK); /* Test. */ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_object_by_id_group_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); const char **attrs = SYSDB_GRSRC_ATTRS(test_ctx->tctx->dom); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); test_ctx->create_group1 = true; test_ctx->create_group2 = false; /* Test. */ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], test_ctx->tctx->dom); } void test_object_by_id_group_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); const char **attrs = SYSDB_GRSRC_ATTRS(test_ctx->tctx->dom); /* Mock values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); mock_account_recv_simple(); /* Test. */ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_object_by_id_group_multiple_domains_found(void **state) { struct cache_req_test_ctx *test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); struct sss_domain_info *domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); const char **attrs = SYSDB_GRSRC_ATTRS(domain); /* Setup user. */ prepare_group(domain, &groups[0], 1000, time(NULL)); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); /* Test. */ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); } void test_object_by_id_group_multiple_domains_notfound(void **state) { struct cache_req_test_ctx *test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); const char **attrs = SYSDB_GRSRC_ATTRS(test_ctx->tctx->dom); /* Mock values. */ will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); /* Test. */ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ENOENT); assert_true(test_ctx->dp_called); } void test_object_by_id_user_multiple_domains_locator_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, "responder_cache_req_test_d"); assert_non_null(locator_domain); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_user(domain, &users[0], 1000, time(NULL)); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, EOK); /* Test. */ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); /* Even though the locator tells us to skip all domains except d, the domains * are standalone and the result of the locator request is only valid within * the subdomains */ assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); talloc_free(tmp_ctx); } void test_object_by_id_user_multiple_domains_locator_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, "responder_cache_req_test_d"); assert_non_null(locator_domain); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_user(domain, &users[0], -1000, time(NULL)); will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, EOK); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); /* Test. */ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); talloc_free(tmp_ctx); } void test_object_by_id_user_sub_domains_locator_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); prepare_user(domain, &users[0], 1000, time(NULL)); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); /* Even though the ID is present in the last domain, * we're not calling sss_dp_get_account_send, * because the locator will cause cache_req to skip * all domains except _d */ assert_false(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); talloc_free(tmp_ctx); } void test_object_by_id_user_sub_domains_locator_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); prepare_user(domain, &users[0], -1000, time(NULL)); /* Note - DP will only be called once (so, we're not using will_return_always) * because the locator will tell us which domain to look into. For the recv * function, we use always b/c internally it mocks several values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); talloc_free(tmp_ctx); } void test_object_by_id_user_sub_domains_locator_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); prepare_user(domain, &users[0], 50, time(NULL) - 26); /* Note - DP will only be called once and we're not waiting * for the results (so, we're not mocking _recv) */ will_return(__wrap_sss_dp_get_account_send, test_ctx); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 50, ERR_OK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); talloc_free(tmp_ctx); } void test_object_by_id_user_sub_domains_locator_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Note - DP will only be called once (so, we're not using will_return_always) * because the locator will tell us which domain to look into. For the recv * function, we use always b/c internally it mocks several values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ test_ctx->create_subuser1 = true; run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); check_user(test_ctx, &users[0], domain); talloc_free(tmp_ctx); } void test_object_by_id_user_sub_domains_locator_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); will_return(sss_dp_get_account_domain_recv, ERR_NOT_FOUND); /* The test won't even ask the DP for the object, just iterate * over the domains using the negative cache and quit */ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_object_by_id_user_sub_domains_locator_cache_expired_two_calls(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Setup user. */ domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); test_ctx->create_subuser1 = true; prepare_user(domain, &users[0], -1000, time(NULL)); /* Note - DP will only be called once (so, we're not using will_return_always) * because the locator will tell us which domain to look into. For the recv * function, we use always b/c internally it mocks several values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, EOK); assert_true(test_ctx->dp_called); check_user(test_ctx, &users[0], domain); /* Request the same user again */ test_ctx->tctx->done = false; talloc_zfree(test_ctx->result); run_object_by_id(test_ctx, NULL, users[0].uid, attrs, 0, EOK); check_user(test_ctx, &users[0], domain); talloc_free(tmp_ctx); } void test_object_by_id_group_multiple_domains_locator_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, "responder_cache_req_test_d"); assert_non_null(locator_domain); /* Setup group. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_group(domain, &groups[0], 1000, time(NULL)); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, EOK); /* Test. */ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); /* Even though the locator tells us to skip all domains except d, the domains * are standalone and the result of the locator request is only valid within * the subdomains */ assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); talloc_free(tmp_ctx); } void test_object_by_id_group_multiple_domains_locator_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, "responder_cache_req_test_d"); assert_non_null(locator_domain); /* Setup group. */ domain = find_domain_by_name(test_ctx->tctx->dom, "responder_cache_req_test_d", true); assert_non_null(domain); prepare_group(domain, &groups[0], -1000, time(NULL)); will_return_always(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, EOK); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); will_return_always(sss_dp_get_account_domain_recv, ERR_GET_ACCT_DOM_NOT_SUPPORTED); /* Test. */ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); talloc_free(tmp_ctx); } void test_object_by_id_group_sub_domains_locator_cache_valid(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Setup group. */ domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); prepare_group(domain, &groups[0], 1000, time(NULL)); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); /* Even though the ID is present in the last domain, * we're not calling sss_dp_get_account_send, * because the locator will cause cache_req to skip * all domains except _d */ assert_false(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); talloc_free(tmp_ctx); } void test_object_by_id_group_sub_domains_locator_cache_expired(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Setup group. */ domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); prepare_group(domain, &groups[0], -1000, time(NULL)); /* Note - DP will only be called once (so, we're not using will_return_always) * because the locator will tell us which domain to look into. For the recv * function, we use always b/c internally it mocks several values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); talloc_free(tmp_ctx); } void test_object_by_id_group_sub_domains_locator_cache_midpoint(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Setup group. */ domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); prepare_group(domain, &groups[0], 50, time(NULL) - 26); /* Note - DP will only be called once and we're not waiting * for the results (so, we're not mocking _recv) */ will_return(__wrap_sss_dp_get_account_send, test_ctx); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 50, ERR_OK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); talloc_free(tmp_ctx); } void test_object_by_id_group_sub_domains_locator_missing_found(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Note - DP will only be called once (so, we're not using will_return_always) * because the locator will tell us which domain to look into. For the recv * function, we use always b/c internally it mocks several values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ test_ctx->create_subgroup1 = true; run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ERR_OK); assert_true(test_ctx->dp_called); domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); check_group(test_ctx, &groups[0], domain); talloc_free(tmp_ctx); } void test_object_by_id_group_sub_domains_locator_missing_notfound(void **state) { struct cache_req_test_ctx *test_ctx = NULL; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); will_return(sss_dp_get_account_domain_recv, ERR_NOT_FOUND); /* The test won't even ask the DP for the object, just iterate * over the domains using the negative cache and quit */ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, ENOENT); assert_false(test_ctx->dp_called); } void test_object_by_id_group_sub_domains_locator_cache_expired_two_calls(void **state) { struct cache_req_test_ctx *test_ctx = NULL; struct sss_domain_info *domain = NULL; const char *locator_domain; TALLOC_CTX *tmp_ctx; const char *attrs[] = SYSDB_PW_ATTRS; test_ctx = talloc_get_type_abort(*state, struct cache_req_test_ctx); tmp_ctx = talloc_new(test_ctx); assert_non_null(tmp_ctx); /* Has to be a talloc ptr, not just const, so it's stealable inside cache_req */ locator_domain = talloc_strdup(tmp_ctx, subdomain_name); assert_non_null(locator_domain); /* Setup group. */ domain = find_domain_by_name(test_ctx->tctx->dom, subdomain_name, true); assert_non_null(domain); test_ctx->create_subgroup1 = true; prepare_group(domain, &groups[0], -1000, time(NULL)); /* Note - DP will only be called once (so, we're not using will_return_always) * because the locator will tell us which domain to look into. For the recv * function, we use always b/c internally it mocks several values. */ will_return(__wrap_sss_dp_get_account_send, test_ctx); will_return_always(sss_dp_get_account_recv, 0); will_return(sss_dp_get_account_domain_recv, EOK); will_return(sss_dp_get_account_domain_recv, locator_domain); /* Test. */ run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, EOK); assert_true(test_ctx->dp_called); check_group(test_ctx, &groups[0], domain); /* Request the same group again */ test_ctx->tctx->done = false; talloc_zfree(test_ctx->result); run_object_by_id(test_ctx, NULL, groups[0].gid, attrs, 0, EOK); check_group(test_ctx, &groups[0], domain); talloc_free(tmp_ctx); } int main(int argc, const char *argv[]) { poptContext pc; int opt; struct poptOption long_options[] = { POPT_AUTOHELP SSSD_DEBUG_OPTS POPT_TABLEEND }; const struct CMUnitTest tests[] = { new_single_domain_test(user_by_name_cache_valid), new_single_domain_test(user_by_name_cache_expired), new_single_domain_test(user_by_name_cache_midpoint), new_single_domain_test(user_by_name_ncache), new_single_domain_test(user_by_name_missing_found), new_single_domain_test(user_by_name_missing_notfound), new_single_domain_test(user_by_name_missing_notfound_cache_first), new_single_domain_test(user_by_name_missing_notfound_full_name), new_single_domain_test(user_by_name_missing_notfound_cache_first_full_name), new_multi_domain_test(user_by_name_multiple_domains_found), new_multi_domain_test(user_by_name_multiple_domains_notfound), new_multi_domain_test(user_by_name_multiple_domains_parse), new_multi_domain_test(user_by_name_multiple_domains_requested_domains_found), new_multi_domain_test(user_by_name_multiple_domains_requested_domains_notfound), new_single_domain_test(user_by_upn_cache_valid), new_single_domain_test(user_by_upn_cache_expired), new_single_domain_test(user_by_upn_cache_midpoint), new_single_domain_test(user_by_upn_ncache), new_single_domain_test(user_by_upn_missing_found), new_single_domain_test(user_by_upn_missing_notfound), new_multi_domain_test(user_by_upn_multiple_domains_found), new_multi_domain_test(user_by_upn_multiple_domains_notfound), new_single_domain_test(user_by_id_cache_valid), new_single_domain_test(user_by_id_cache_expired), new_single_domain_test(user_by_id_cache_midpoint), new_single_domain_test(user_by_id_ncache), new_single_domain_test(user_by_id_missing_found), new_single_domain_test(user_by_id_missing_notfound), new_multi_domain_test(user_by_id_multiple_domains_found), new_multi_domain_test(user_by_id_multiple_domains_notfound), new_single_domain_id_limit_test(user_by_id_below_id_range), new_single_domain_id_limit_test(user_by_id_above_id_range), new_single_domain_test(group_by_name_cache_valid), new_single_domain_test(group_by_name_cache_expired), new_single_domain_test(group_by_name_cache_midpoint), new_single_domain_test(group_by_name_ncache), new_single_domain_test(group_by_name_missing_found), new_single_domain_test(group_by_name_missing_notfound), new_multi_domain_test(group_by_name_multiple_domains_found), new_multi_domain_test(group_by_name_multiple_domains_notfound), new_multi_domain_test(group_by_name_multiple_domains_parse), new_single_domain_id_limit_test(group_by_id_below_id_range), new_single_domain_id_limit_test(group_by_id_above_id_range), new_single_domain_test(group_by_id_cache_valid), new_single_domain_test(group_by_id_cache_expired), new_single_domain_test(group_by_id_cache_midpoint), new_single_domain_test(group_by_id_ncache), new_single_domain_test(group_by_id_missing_found), new_single_domain_test(group_by_id_missing_notfound), new_multi_domain_test(group_by_id_multiple_domains_found), new_multi_domain_test(group_by_id_multiple_domains_notfound), new_multi_domain_test(group_by_id_multiple_domains_outside_id_range), new_multi_domain_test(group_by_id_multiple_domains_locator_cache_valid), new_multi_domain_test(group_by_id_multiple_domains_locator_cache_expired), new_subdomain_test(group_by_id_sub_domains_locator_cache_valid), new_subdomain_test(group_by_id_sub_domains_locator_cache_expired), new_subdomain_test(group_by_id_sub_domains_locator_cache_midpoint), new_subdomain_test(group_by_id_sub_domains_locator_missing_found), new_subdomain_test(group_by_id_sub_domains_locator_missing_notfound), new_subdomain_test(group_by_id_sub_domains_locator_cache_expired_two_calls), new_multi_domain_test(user_by_id_multiple_domains_locator_cache_valid), new_multi_domain_test(user_by_id_multiple_domains_locator_cache_expired), new_subdomain_test(user_by_id_sub_domains_locator_cache_valid), new_subdomain_test(user_by_id_sub_domains_locator_cache_expired), new_subdomain_test(user_by_id_sub_domains_locator_cache_midpoint), new_subdomain_test(user_by_id_sub_domains_locator_missing_found), new_subdomain_test(user_by_id_sub_domains_locator_missing_notfound), new_subdomain_test(user_by_id_sub_domains_locator_cache_expired_two_calls), new_single_domain_test(user_by_recent_filter_valid), new_single_domain_test(users_by_recent_filter_valid), new_single_domain_test(group_by_recent_filter_valid), new_single_domain_test(groups_by_recent_filter_valid), new_single_domain_test(users_by_filter_filter_old), new_single_domain_test(users_by_filter_notfound), new_multi_domain_test(users_by_filter_multiple_domains_valid), new_multi_domain_test(users_by_filter_multiple_domains_notfound), new_single_domain_test(groups_by_filter_notfound), new_multi_domain_test(groups_by_filter_multiple_domains_valid), new_multi_domain_test(groups_by_filter_multiple_domains_notfound), new_single_domain_test(object_by_sid_user_cache_valid), new_single_domain_test(object_by_sid_user_cache_expired), new_single_domain_test(object_by_sid_user_cache_midpoint), new_single_domain_test(object_by_sid_user_ncache), new_single_domain_test(object_by_sid_user_missing_found), new_single_domain_test(object_by_sid_user_missing_notfound), new_multi_domain_test(object_by_sid_user_multiple_domains_found), new_multi_domain_test(object_by_sid_user_multiple_domains_notfound), new_single_domain_test(object_by_sid_group_cache_valid), new_single_domain_test(object_by_sid_group_cache_expired), new_single_domain_test(object_by_sid_group_cache_midpoint), new_single_domain_test(object_by_sid_group_ncache), new_single_domain_test(object_by_sid_group_missing_found), new_single_domain_test(object_by_sid_group_missing_notfound), new_multi_domain_test(object_by_sid_group_multiple_domains_found), new_multi_domain_test(object_by_sid_group_multiple_domains_notfound), new_single_domain_test(object_by_id_user_cache_valid), new_single_domain_test(object_by_id_user_cache_expired), new_single_domain_test(object_by_id_user_cache_midpoint), new_single_domain_test(object_by_id_user_ncache), new_single_domain_test(object_by_id_user_missing_found), new_single_domain_test(object_by_id_user_missing_notfound), new_multi_domain_test(object_by_id_user_multiple_domains_found), new_multi_domain_test(object_by_id_user_multiple_domains_notfound), new_single_domain_test(object_by_id_group_cache_valid), new_single_domain_test(object_by_id_group_cache_expired), new_single_domain_test(object_by_id_group_cache_midpoint), new_single_domain_test(object_by_id_group_ncache), new_single_domain_test(object_by_id_group_missing_found), new_single_domain_test(object_by_id_group_missing_notfound), new_multi_domain_test(object_by_id_group_multiple_domains_found), new_multi_domain_test(object_by_id_group_multiple_domains_notfound), new_multi_domain_test(object_by_id_user_multiple_domains_locator_cache_valid), new_multi_domain_test(object_by_id_user_multiple_domains_locator_cache_expired), new_subdomain_test(object_by_id_user_sub_domains_locator_cache_valid), new_subdomain_test(object_by_id_user_sub_domains_locator_cache_expired), new_subdomain_test(object_by_id_user_sub_domains_locator_cache_midpoint), new_subdomain_test(object_by_id_user_sub_domains_locator_missing_found), new_subdomain_test(object_by_id_user_sub_domains_locator_missing_notfound), new_subdomain_test(object_by_id_user_sub_domains_locator_cache_expired_two_calls), new_multi_domain_test(object_by_id_group_multiple_domains_locator_cache_valid), new_multi_domain_test(object_by_id_group_multiple_domains_locator_cache_expired), new_subdomain_test(object_by_id_group_sub_domains_locator_cache_valid), new_subdomain_test(object_by_id_group_sub_domains_locator_cache_expired), new_subdomain_test(object_by_id_group_sub_domains_locator_cache_midpoint), new_subdomain_test(object_by_id_group_sub_domains_locator_missing_found), new_subdomain_test(object_by_id_group_sub_domains_locator_missing_notfound), new_subdomain_test(object_by_id_group_sub_domains_locator_cache_expired_two_calls), }; /* Set debug level to invalid value so we can decide 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(); test_multidom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, domains); test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); return cmocka_run_group_tests(tests, NULL, NULL); }