diff options
author | Jakub Hrozek <jhrozek@redhat.com> | 2016-01-13 15:04:52 +0100 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2016-01-13 15:31:29 +0100 |
commit | 17c77befe6e9bb9fd67ae5d226d7ffcc233acd43 (patch) | |
tree | f0dad0064cee388b6e299660f30eacd71a8a3e83 | |
parent | ed7a26276ad68d55bf10058dda0d617dc7666edf (diff) | |
download | sssd-sysdb.tar.gz sssd-sysdb.tar.xz sssd-sysdb.zip |
foo2sysdb
-rw-r--r-- | src/db/sysdb_ops.c | 15 | ||||
-rw-r--r-- | src/providers/simple/simple_access_check.c | 9 | ||||
-rw-r--r-- | src/tests/cmocka/test_simple_access.c | 440 | ||||
-rw-r--r-- | src/util/util_errors.c | 1 | ||||
-rw-r--r-- | src/util/util_errors.h | 1 |
5 files changed, 421 insertions, 45 deletions
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index 106ae5e2e..a1cdedc5f 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -333,8 +333,6 @@ static int sysdb_search_by_name(TALLOC_CTX *mem_ctx, size_t msgs_count = 0; char *sanitized_name; char *lc_sanitized_name; - char *fqname; - char *lc_fqname; char *filter; int ret; @@ -371,17 +369,8 @@ static int sysdb_search_by_name(TALLOC_CTX *mem_ctx, goto done; } - fqname = sss_create_internal_fqname(tmp_ctx, sanitized_name, - domain->name); - lc_fqname = sss_create_internal_fqname(tmp_ctx, lc_sanitized_name, - domain->name); - if (fqname == NULL || lc_fqname == NULL) { - ret = ENOMEM; - goto done; - } - - filter = talloc_asprintf(tmp_ctx, filter_tmpl, lc_fqname, - fqname, fqname); + filter = talloc_asprintf(tmp_ctx, filter_tmpl, lc_sanitized_name, + sanitized_name, sanitized_name); if (!filter) { ret = ENOMEM; goto done; diff --git a/src/providers/simple/simple_access_check.c b/src/providers/simple/simple_access_check.c index 14d833be2..8cb956478 100644 --- a/src/providers/simple/simple_access_check.c +++ b/src/providers/simple/simple_access_check.c @@ -720,6 +720,15 @@ struct tevent_req *simple_access_check_send(TALLOC_CTX *mem_ctx, state->access_granted = false; state->ctx = ctx; + + ret = sss_parse_internal_fqname(state, username, NULL, NULL); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Username [%s] is not in the expected format!\n", username); + ret = ERR_WRONG_NAME_FORMAT; + goto immediate; + } + state->username = talloc_strdup(state, username); if (!state->username) { ret = ENOMEM; diff --git a/src/tests/cmocka/test_simple_access.c b/src/tests/cmocka/test_simple_access.c index f3b1e0bd8..428b2e25c 100644 --- a/src/tests/cmocka/test_simple_access.c +++ b/src/tests/cmocka/test_simple_access.c @@ -34,10 +34,6 @@ #define TEST_SUBDOM_NAME "test.subdomain" #define TEST_ID_PROVIDER "ldap" -const char *ulist_1[] = {"u1", "u2", NULL}; -const char *glist_1[] = {"g1", "g2", NULL}; -const char *glist_1_case[] = {"G1", "G2", NULL}; - int sssm_simple_access_init(struct be_ctx *bectx, struct bet_ops **ops, void **pvt_data); @@ -166,42 +162,333 @@ static void simple_access_check_done(struct tevent_req *req) simple_test_ctx->tctx->done = true; } +static void run_simple_access_check(struct simple_test_ctx *simple_test_ctx, + const char *username, + int expected_rv, + bool allow_access) +{ + int ret; + struct tevent_req *req; + + simple_test_ctx->tctx->done = false; + req = simple_access_check_send(simple_test_ctx, simple_test_ctx->tctx->ev, + simple_test_ctx->ctx, username); + assert_non_null(req); + tevent_req_set_callback(req, simple_access_check_done, simple_test_ctx); + + ret = test_ev_loop(simple_test_ctx->tctx); + assert_int_equal(ret, expected_rv); + + /* otherwise the output is undefined */ + if (expected_rv == EOK) { + assert_true(simple_test_ctx->access_granted == allow_access); + } +} + static void test_both_empty(void **state) { errno_t ret; - struct tevent_req *req; struct simple_test_ctx *simple_test_ctx = \ talloc_get_type(*state, struct simple_test_ctx); ret = setup_with_params(simple_test_ctx, simple_test_ctx->tctx->dom, NULL); assert_int_equal(ret, EOK); - req = simple_access_check_send(simple_test_ctx, simple_test_ctx->tctx->ev, - simple_test_ctx->ctx, "u1"); - assert_non_null(req); - tevent_req_set_callback(req, simple_access_check_done, simple_test_ctx); + run_simple_access_check(simple_test_ctx, "u1@simple_test", EOK, true); +} - ret = test_ev_loop(simple_test_ctx->tctx); +static void test_allow_empty(void **state) +{ + errno_t ret; + struct simple_test_ctx *simple_test_ctx = \ + talloc_get_type(*state, struct simple_test_ctx); + struct sss_test_conf_param params[] = { + { "simple_deny_users", "u1, u2" }, + { NULL, NULL }, + }; + + ret = setup_with_params(simple_test_ctx, simple_test_ctx->tctx->dom, params); assert_int_equal(ret, EOK); - assert_true(simple_test_ctx->access_granted); + run_simple_access_check(simple_test_ctx, "u1@simple_test", EOK, false); + run_simple_access_check(simple_test_ctx, "u3@simple_test", EOK, true); + run_simple_access_check(simple_test_ctx, "u1", ERR_WRONG_NAME_FORMAT, false); } -static void test_allow_empty(void **state) +static void test_deny_empty(void **state) +{ + errno_t ret; + struct simple_test_ctx *simple_test_ctx = \ + talloc_get_type(*state, struct simple_test_ctx); + struct sss_test_conf_param params[] = { + { "simple_allow_users", "u1, u2" }, + { NULL, NULL }, + }; + ret = setup_with_params(simple_test_ctx, simple_test_ctx->tctx->dom, params); + assert_int_equal(ret, EOK); + + run_simple_access_check(simple_test_ctx, "u1@simple_test", EOK, true); + run_simple_access_check(simple_test_ctx, "u3@simple_test", EOK, false); +} + +static void test_both_set(void **state) { errno_t ret; - struct tevent_req *req; struct simple_test_ctx *simple_test_ctx = \ talloc_get_type(*state, struct simple_test_ctx); struct sss_test_conf_param params[] = { + { "simple_allow_users", "u1, u2" }, { "simple_deny_users", "u1, u2" }, + { NULL, NULL }, + }; + + ret = setup_with_params(simple_test_ctx, + simple_test_ctx->tctx->dom, + params); + assert_int_equal(ret, EOK); + + run_simple_access_check(simple_test_ctx, "u1@simple_test", EOK, false); + run_simple_access_check(simple_test_ctx, "u3@simple_test", EOK, false); +} + +static void test_deny_wrong_case(void **state) +{ + errno_t ret; + struct simple_test_ctx *simple_test_ctx = \ + talloc_get_type(*state, struct simple_test_ctx); + struct sss_test_conf_param params[] = { + { "simple_allow_users", "u1, u2" }, + { NULL, NULL }, + }; + + ret = setup_with_params(simple_test_ctx, + simple_test_ctx->tctx->dom, + params); + assert_int_equal(ret, EOK); + + run_simple_access_check(simple_test_ctx, "U1@simple_test", EOK, false); +} + +static void test_allow_case_insensitive(void **state) +{ + errno_t ret; + struct simple_test_ctx *simple_test_ctx = \ + talloc_get_type(*state, struct simple_test_ctx); + struct sss_test_conf_param params[] = { + { "simple_allow_users", "u1, u2" }, + { NULL, NULL }, + }; + + ret = setup_with_params(simple_test_ctx, + simple_test_ctx->tctx->dom, + params); + assert_int_equal(ret, EOK); + + simple_test_ctx->tctx->dom->case_sensitive = false; + run_simple_access_check(simple_test_ctx, "U1@simple_test", EOK, true); +} + +static void test_unknown_user(void **state) +{ + errno_t ret; + struct simple_test_ctx *simple_test_ctx = \ + talloc_get_type(*state, struct simple_test_ctx); + struct sss_test_conf_param params[] = { + { "simple_allow_users", "u1, u2" }, + { NULL, NULL }, + }; + + ret = setup_with_params(simple_test_ctx, + simple_test_ctx->tctx->dom, + params); + assert_int_equal(ret, EOK); + + run_simple_access_check(simple_test_ctx, "foo@simple_test", EOK, false); +} + +static void test_space(void **state) +{ + errno_t ret; + struct simple_test_ctx *simple_test_ctx = \ + talloc_get_type(*state, struct simple_test_ctx); + struct sss_test_conf_param params[] = { + { "simple_allow_users", "space user, another user@simple_test" }, + { NULL, NULL }, + }; + + ret = setup_with_params(simple_test_ctx, simple_test_ctx->tctx->dom, params); + assert_int_equal(ret, EOK); + + run_simple_access_check(simple_test_ctx, "space user@simple_test", EOK, true); + run_simple_access_check(simple_test_ctx, "another user@simple_test", EOK, true); + run_simple_access_check(simple_test_ctx, "not allowed@simple_test", EOK, false); +} + +static int simple_group_test_setup(void **state) +{ + int ret; + char *u1; + char *u2; + char *u3; + char *g1; + char *g2; + char *sp; + char *sp2; + char *pvt; + struct simple_test_ctx *test_ctx; + + ret = simple_test_setup((void **) &test_ctx); + if (ret != EOK) { + return 1; + } + + u1 = sss_create_internal_fqname(test_ctx, "u1", + test_ctx->be_ctx->domain->name); + u2 = sss_create_internal_fqname(test_ctx, "u2", + test_ctx->be_ctx->domain->name); + u3 = sss_create_internal_fqname(test_ctx, "u3", + test_ctx->be_ctx->domain->name); + g1 = sss_create_internal_fqname(test_ctx, "g1", + test_ctx->be_ctx->domain->name); + g2 = sss_create_internal_fqname(test_ctx, "g2", + test_ctx->be_ctx->domain->name); + sp = sss_create_internal_fqname(test_ctx, "space group", + test_ctx->be_ctx->domain->name); + sp2 = sss_create_internal_fqname(test_ctx, "another space", + test_ctx->be_ctx->domain->name); + pvt = sss_create_internal_fqname(test_ctx, "pvt", + test_ctx->be_ctx->domain->name); + if (u1 == NULL || u2 == NULL || u3 == NULL + || g1 == NULL || g2 == NULL || pvt == NULL + || sp == NULL || sp2 == NULL) { + return 1; + } + + ret = sysdb_add_group(test_ctx->be_ctx->domain, pvt, 999, NULL, 0, 0); + if (ret != EOK) return 1; + + ret = sysdb_store_user(test_ctx->be_ctx->domain, + u1, NULL, 123, 999, "u1", "/home/u1", + "/bin/bash", NULL, NULL, NULL, -1, 0); + if (ret != EOK) return 1; + + ret = sysdb_store_user(test_ctx->be_ctx->domain, + u2, NULL, 456, 999, "u1", "/home/u1", + "/bin/bash", NULL, NULL, NULL, -1, 0); + if (ret != EOK) return 1; + + ret = sysdb_store_user(test_ctx->be_ctx->domain, + u3, NULL, 789, 999, "u1", "/home/u1", + "/bin/bash", NULL, NULL, NULL, -1, 0); + if (ret != EOK) return 1; + + ret = sysdb_add_group(test_ctx->be_ctx->domain, g1, 321, NULL, 0, 0); + if (ret != EOK) return 1; + + ret = sysdb_add_group(test_ctx->be_ctx->domain, g2, 654, NULL, 0, 0); + if (ret != EOK) return 1; + + ret = sysdb_add_group(test_ctx->be_ctx->domain, sp, 1234, NULL, 0, 0); + if (ret != EOK) return 1; + + ret = sysdb_add_group(test_ctx->be_ctx->domain, sp2, 5678, NULL, 0, 0); + if (ret != EOK) return 1; + + ret = sysdb_add_group_member(test_ctx->be_ctx->domain, + g1, u1, SYSDB_MEMBER_USER, false); + if (ret != EOK) return 1; + + ret = sysdb_add_group_member(test_ctx->be_ctx->domain, + sp, u1, SYSDB_MEMBER_USER, false); + if (ret != EOK) return 1; + + ret = sysdb_add_group_member(test_ctx->be_ctx->domain, + g2, u2, SYSDB_MEMBER_USER, false); + if (ret != EOK) return 1; + + ret = sysdb_add_group_member(test_ctx->be_ctx->domain, + sp2, u2, SYSDB_MEMBER_USER, false); + if (ret != EOK) return 1; + + *state = test_ctx; + return 0; +} + +static int simple_group_test_teardown(void **state) +{ + int ret; + char *u1; + char *u2; + char *u3; + char *g1; + char *g2; + char *sp; + char *sp2; + char *pvt; + struct simple_test_ctx *test_ctx = \ + talloc_get_type(*state, struct simple_test_ctx); + + u1 = sss_create_internal_fqname(test_ctx, "u1", + test_ctx->be_ctx->domain->name); + u2 = sss_create_internal_fqname(test_ctx, "u2", + test_ctx->be_ctx->domain->name); + u3 = sss_create_internal_fqname(test_ctx, "u3", + test_ctx->be_ctx->domain->name); + g1 = sss_create_internal_fqname(test_ctx, "g1", + test_ctx->be_ctx->domain->name); + g2 = sss_create_internal_fqname(test_ctx, "g2", + test_ctx->be_ctx->domain->name); + sp = sss_create_internal_fqname(test_ctx, "space group", + test_ctx->be_ctx->domain->name); + sp2 = sss_create_internal_fqname(test_ctx, "another space", + test_ctx->be_ctx->domain->name); + pvt = sss_create_internal_fqname(test_ctx, "pvt", + test_ctx->be_ctx->domain->name); + if (u1 == NULL || u2 == NULL || u3 == NULL + || g1 == NULL || g2 == NULL || pvt == NULL + || sp == NULL || sp2 == NULL) { + return 1; + } + + ret = sysdb_delete_user(test_ctx->be_ctx->domain, u1, 0); + if (ret != EOK) return 1; + ret = sysdb_delete_user(test_ctx->be_ctx->domain, u2, 0); + if (ret != EOK) return 1; + ret = sysdb_delete_user(test_ctx->be_ctx->domain, u3, 0); + if (ret != EOK) return 1; + ret = sysdb_delete_group(test_ctx->be_ctx->domain, g1, 0); + if (ret != EOK) return 1; + ret = sysdb_delete_group(test_ctx->be_ctx->domain, g2, 0); + if (ret != EOK) return 1; + ret = sysdb_delete_group(test_ctx->be_ctx->domain, sp, 0); + if (ret != EOK) return 1; + ret = sysdb_delete_group(test_ctx->be_ctx->domain, sp2, 0); + if (ret != EOK) return 1; + ret = sysdb_delete_group(test_ctx->be_ctx->domain, pvt, 0); + if (ret != EOK) return 1; + + /* make sure there are no leftovers from previous tests */ + test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME); + talloc_free(test_ctx); + return 0; +} + +static void test_group_allow_empty(void **state) +{ + errno_t ret; + struct tevent_req *req; + struct simple_test_ctx *simple_test_ctx = \ + talloc_get_type(*state, struct simple_test_ctx); + struct sss_test_conf_param params[] = { + { "simple_deny_groups", "g1, g2" }, + { NULL, NULL }, }; ret = setup_with_params(simple_test_ctx, simple_test_ctx->tctx->dom, params); assert_int_equal(ret, EOK); req = simple_access_check_send(simple_test_ctx, simple_test_ctx->tctx->ev, - simple_test_ctx->ctx, "u1"); + simple_test_ctx->ctx, "u1@simple_test"); assert_non_null(req); tevent_req_set_callback(req, simple_access_check_done, simple_test_ctx); @@ -210,9 +497,8 @@ static void test_allow_empty(void **state) assert_false(simple_test_ctx->access_granted); simple_test_ctx->tctx->done = false; - req = simple_access_check_send(simple_test_ctx, simple_test_ctx->tctx->ev, - simple_test_ctx->ctx, "u3"); + simple_test_ctx->ctx, "u3@simple_test"); assert_non_null(req); tevent_req_set_callback(req, simple_access_check_done, simple_test_ctx); @@ -221,38 +507,96 @@ static void test_allow_empty(void **state) assert_true(simple_test_ctx->access_granted); } -static void test_deny_empty(void **state) +static void test_group_deny_empty(void **state) { errno_t ret; - struct tevent_req *req; struct simple_test_ctx *simple_test_ctx = \ talloc_get_type(*state, struct simple_test_ctx); struct sss_test_conf_param params[] = { - { "simple_allow_users", "u1, u2" }, + { "simple_allow_groups", "g1, g2" }, + { NULL, NULL }, }; ret = setup_with_params(simple_test_ctx, simple_test_ctx->tctx->dom, params); assert_int_equal(ret, EOK); - req = simple_access_check_send(simple_test_ctx, simple_test_ctx->tctx->ev, - simple_test_ctx->ctx, "u1"); - assert_non_null(req); - tevent_req_set_callback(req, simple_access_check_done, simple_test_ctx); + run_simple_access_check(simple_test_ctx, "u1@simple_test", EOK, true); + run_simple_access_check(simple_test_ctx, "u3@simple_test", EOK, false); +} - ret = test_ev_loop(simple_test_ctx->tctx); +static void test_group_both_set(void **state) +{ + errno_t ret; + struct simple_test_ctx *simple_test_ctx = \ + talloc_get_type(*state, struct simple_test_ctx); + struct sss_test_conf_param params[] = { + { "simple_allow_groups", "g1, g2" }, + { "simple_deny_groups", "g1, g2" }, + { NULL, NULL }, + }; + + ret = setup_with_params(simple_test_ctx, simple_test_ctx->tctx->dom, params); + assert_int_equal(ret, EOK); + + run_simple_access_check(simple_test_ctx, "u1@simple_test", EOK, false); + run_simple_access_check(simple_test_ctx, "u3@simple_test", EOK, false); +} + +static void test_group_deny_wrong_case(void **state) +{ + errno_t ret; + struct simple_test_ctx *simple_test_ctx = \ + talloc_get_type(*state, struct simple_test_ctx); + struct sss_test_conf_param params[] = { + { "simple_allow_groups", "G1, G2" }, + { NULL, NULL }, + }; + + ret = setup_with_params(simple_test_ctx, + simple_test_ctx->tctx->dom, + params); assert_int_equal(ret, EOK); - assert_true(simple_test_ctx->access_granted); + run_simple_access_check(simple_test_ctx, "u1@simple_test", EOK, false); +} + +static void test_group_allow_case_insensitive(void **state) +{ + errno_t ret; + struct simple_test_ctx *simple_test_ctx = \ + talloc_get_type(*state, struct simple_test_ctx); + struct sss_test_conf_param params[] = { + { "simple_allow_groups", "G1, G2" }, + { NULL, NULL }, + }; + + ret = setup_with_params(simple_test_ctx, + simple_test_ctx->tctx->dom, + params); + assert_int_equal(ret, EOK); + + /* Case-sensitive domain, wrong case */ simple_test_ctx->tctx->done = false; + simple_test_ctx->tctx->dom->case_sensitive = false; + run_simple_access_check(simple_test_ctx, "u1@simple_test", EOK, true); +} - req = simple_access_check_send(simple_test_ctx, simple_test_ctx->tctx->ev, - simple_test_ctx->ctx, "u3"); - assert_non_null(req); - tevent_req_set_callback(req, simple_access_check_done, simple_test_ctx); +static void test_group_space(void **state) +{ + errno_t ret; + struct simple_test_ctx *simple_test_ctx = \ + talloc_get_type(*state, struct simple_test_ctx); + struct sss_test_conf_param params[] = { + { "simple_allow_groups", "space group, another space@simple_test" }, + { NULL, NULL }, + }; - ret = test_ev_loop(simple_test_ctx->tctx); + ret = setup_with_params(simple_test_ctx, simple_test_ctx->tctx->dom, params); assert_int_equal(ret, EOK); - assert_false(simple_test_ctx->access_granted); + + run_simple_access_check(simple_test_ctx, "u1@simple_test", EOK, true); + run_simple_access_check(simple_test_ctx, "u2@simple_test", EOK, true); + run_simple_access_check(simple_test_ctx, "u3@simple_test", EOK, false); } int main(int argc, const char *argv[]) @@ -270,7 +614,6 @@ int main(int argc, const char *argv[]) }; const struct CMUnitTest tests[] = { - /* FIXME - group fixtures? */ cmocka_unit_test_setup_teardown(test_both_empty, simple_test_setup, simple_test_teardown), @@ -280,6 +623,39 @@ int main(int argc, const char *argv[]) cmocka_unit_test_setup_teardown(test_deny_empty, simple_test_setup, simple_test_teardown), + cmocka_unit_test_setup_teardown(test_both_set, + simple_test_setup, + simple_test_teardown), + cmocka_unit_test_setup_teardown(test_deny_wrong_case, + simple_test_setup, + simple_test_teardown), + cmocka_unit_test_setup_teardown(test_allow_case_insensitive, + simple_test_setup, + simple_test_teardown), + cmocka_unit_test_setup_teardown(test_unknown_user, + simple_test_setup, + simple_test_teardown), + cmocka_unit_test_setup_teardown(test_space, + simple_test_setup, + simple_test_teardown), + cmocka_unit_test_setup_teardown(test_group_allow_empty, + simple_group_test_setup, + simple_group_test_teardown), + cmocka_unit_test_setup_teardown(test_group_deny_empty, + simple_group_test_setup, + simple_group_test_teardown), + cmocka_unit_test_setup_teardown(test_group_both_set, + simple_group_test_setup, + simple_group_test_teardown), + cmocka_unit_test_setup_teardown(test_group_deny_wrong_case, + simple_group_test_setup, + simple_group_test_teardown), + cmocka_unit_test_setup_teardown(test_group_allow_case_insensitive, + simple_group_test_setup, + simple_group_test_teardown), + cmocka_unit_test_setup_teardown(test_group_space, + simple_group_test_setup, + simple_group_test_teardown), }; /* Set debug level to invalid value so we can decide if -d 0 was used. */ diff --git a/src/util/util_errors.c b/src/util/util_errors.c index ed19346d9..fe3bbab85 100644 --- a/src/util/util_errors.c +++ b/src/util/util_errors.c @@ -82,6 +82,7 @@ struct err_string error_to_str[] = { { "Address family not supported" }, /* ERR_ADDR_FAMILY_NOT_SUPPORTED */ { "Message sender is the bus" }, /* ERR_SBUS_SENDER_BUS */ { "Subdomain is inactive" }, /* ERR_SUBDOM_INACTIVE */ + { "Username not in the expected format" }, /* ERR_WRONG_NAME_FORMAT */ { "ERR_LAST" } /* ERR_LAST */ }; diff --git a/src/util/util_errors.h b/src/util/util_errors.h index c1d081912..a47967b1b 100644 --- a/src/util/util_errors.h +++ b/src/util/util_errors.h @@ -104,6 +104,7 @@ enum sssd_errors { ERR_ADDR_FAMILY_NOT_SUPPORTED, ERR_SBUS_SENDER_BUS, ERR_SUBDOM_INACTIVE, + ERR_WRONG_NAME_FORMAT, ERR_LAST /* ALWAYS LAST */ }; |