diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/db/sysdb.h | 8 | ||||
-rw-r--r-- | src/db/sysdb_ops.c | 175 | ||||
-rw-r--r-- | src/tests/sysdb-tests.c | 72 |
3 files changed, 255 insertions, 0 deletions
diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 04ce49e66..cb3d4238e 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -483,6 +483,14 @@ struct tevent_req *sysdb_add_group_send(TALLOC_CTX *mem_ctx, int cache_timeout); int sysdb_add_group_recv(struct tevent_req *req); +/* Add a incomplete, expired group */ +struct tevent_req *sysdb_add_incomplete_group_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sysdb_handle *handle, + struct sss_domain_info *domain, + const char *name, gid_t gid); +int sysdb_add_incomplete_group_recv(struct tevent_req *req); + /* mod_op must be either LDB_FLAG_MOD_ADD or LDB_FLAG_MOD_DELETE */ struct tevent_req *sysdb_mod_group_member_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index 7ab53e17d..e5219cded 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -2448,6 +2448,181 @@ int sysdb_add_group_recv(struct tevent_req *req) } +/* =Add-A-Incomplete-Group====================================================== */ + +struct sysdb_add_incomplete_group_state { + struct tevent_context *ev; + struct sysdb_handle *handle; + struct sss_domain_info *domain; + + const char *name; + gid_t gid; +}; + +static void sysdb_add_incomplete_group_user_check(struct tevent_req *subreq); +static void sysdb_add_incomplete_group_basic_done(struct tevent_req *subreq); +static void sysdb_add_incomplete_group_set_attrs_done(struct tevent_req *subreq); + +struct tevent_req *sysdb_add_incomplete_group_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sysdb_handle *handle, + struct sss_domain_info *domain, + const char *name, gid_t gid) +{ + struct tevent_req *req, *subreq; + struct sysdb_add_incomplete_group_state *state; + int ret; + + req = tevent_req_create(mem_ctx, &state, + struct sysdb_add_incomplete_group_state); + if (!req) return NULL; + + state->ev = ev; + state->handle = handle; + state->domain = domain; + state->name = name; + state->gid = gid; + + if (handle->ctx->mpg) { + /* In MPG domains you can't have groups with the same name as users, + * search if a user with the same name exists. + * Don't worry about groups, if we try to add a group with the same + * name the operation will fail */ + + subreq = sysdb_search_user_by_name_send(state, ev, NULL, handle, + domain, name, NULL); + if (!subreq) { + ERROR_OUT(ret, ENOMEM, fail); + } + tevent_req_set_callback(subreq, sysdb_add_incomplete_group_user_check, req); + return req; + } + + /* try to add the group */ + subreq = sysdb_add_basic_group_send(state, ev, handle, + domain, name, gid); + if (!subreq) { + ERROR_OUT(ret, ENOMEM, fail); + } + tevent_req_set_callback(subreq, sysdb_add_incomplete_group_basic_done, req); + return req; + +fail: + DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); + tevent_req_error(req, ret); + tevent_req_post(req, ev); + return req; +} + +static void sysdb_add_incomplete_group_user_check(struct tevent_req *subreq) +{ + + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct sysdb_add_incomplete_group_state *state = tevent_req_data(req, + struct sysdb_add_incomplete_group_state); + struct ldb_message *msg; + int ret; + + /* We can succeed only if we get an ENOENT error, which means no users + * with the same name exist. + * If any other error is returned fail as well. */ + ret = sysdb_search_user_recv(subreq, state, &msg); + talloc_zfree(subreq); + if (ret != ENOENT) { + if (ret == EOK) ret = EEXIST; + tevent_req_error(req, ret); + return; + } + + /* try to add the group */ + subreq = sysdb_add_basic_group_send(state, state->ev, + state->handle, state->domain, + state->name, state->gid); + if (!subreq) { + DEBUG(6, ("Error: Out of memory\n")); + tevent_req_error(req, ENOMEM); + return; + } + tevent_req_set_callback(subreq, sysdb_add_incomplete_group_basic_done, req); +} + +static void sysdb_add_incomplete_group_basic_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct sysdb_add_incomplete_group_state *state = tevent_req_data(req, + struct sysdb_add_incomplete_group_state); + int ret; + struct sysdb_attrs *attrs; + time_t now; + + ret = sysdb_add_basic_group_recv(subreq); + talloc_zfree(subreq); + if (ret) { + DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); + tevent_req_error(req, ret); + return; + } + + attrs = sysdb_new_attrs(state); + if (!attrs) { + DEBUG(6, ("Error: Out of memory\n")); + tevent_req_error(req, ENOMEM); + return; + } + + now = time(NULL); + + ret = sysdb_attrs_add_time_t(attrs, SYSDB_LAST_UPDATE, now); + if (ret) { + DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); + tevent_req_error(req, ret); + return; + } + + ret = sysdb_attrs_add_time_t(attrs, SYSDB_CACHE_EXPIRE, + now-1); + if (ret) { + DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); + tevent_req_error(req, ret); + return; + } + + subreq = sysdb_set_group_attr_send(state, state->ev, + state->handle, state->domain, + state->name, attrs, + SYSDB_MOD_REP); + if (!subreq) { + DEBUG(6, ("Error: Out of memory\n")); + tevent_req_error(req, ENOMEM); + return; + } + tevent_req_set_callback(subreq, sysdb_add_incomplete_group_set_attrs_done, req); +} + +static void sysdb_add_incomplete_group_set_attrs_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + int ret; + + ret = sysdb_set_group_attr_recv(subreq); + talloc_zfree(subreq); + if (ret) { + DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); + tevent_req_error(req, ret); + return; + } + + tevent_req_done(req); +} + +int sysdb_add_incomplete_group_recv(struct tevent_req *req) +{ + return sysdb_op_default_recv(req); +} + /* =Add-Or-Remove-Group-Memeber=========================================== */ /* mod_op must be either SYSDB_MOD_ADD or SYSDB_MOD_DEL */ diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c index 5bdc00547..d4d031b98 100644 --- a/src/tests/sysdb-tests.c +++ b/src/tests/sysdb-tests.c @@ -511,6 +511,39 @@ static void test_store_group_done(struct tevent_req *subreq) return test_return(data, ret); } +static void test_add_incomplete_group_done(struct tevent_req *subreq); + +static void test_add_incomplete_group(struct tevent_req *req) +{ + struct test_data *data = tevent_req_callback_data(req, struct test_data); + struct tevent_req *subreq; + int ret; + + ret = sysdb_transaction_recv(req, data, &data->handle); + if (ret != EOK) { + return test_return(data, ret); + } + + subreq = sysdb_add_incomplete_group_send(data, data->ev, data->handle, + data->ctx->domain, data->groupname, + data->gid); + if (!subreq) { + test_return(data, ret); + } + tevent_req_set_callback(subreq, test_add_incomplete_group_done, data); +} + +static void test_add_incomplete_group_done(struct tevent_req *subreq) +{ + struct test_data *data = tevent_req_callback_data(subreq, struct test_data); + int ret; + + ret = sysdb_add_group_recv(subreq); + talloc_zfree(subreq); + + return test_return(data, ret); +} + static void test_remove_group_done(struct tevent_req *subreq); static void test_remove_group(struct tevent_req *req) @@ -1179,6 +1212,41 @@ START_TEST (test_sysdb_store_group) } END_TEST +START_TEST (test_sysdb_add_incomplete_group) +{ + struct sysdb_test_ctx *test_ctx; + struct test_data *data; + struct tevent_req *req; + int ret; + + /* Setup */ + ret = setup_sysdb_tests(&test_ctx); + if (ret != EOK) { + fail("Could not set up the test"); + return; + } + + data = talloc_zero(test_ctx, struct test_data); + data->ctx = test_ctx; + data->ev = test_ctx->ev; + data->gid = _i; + data->groupname = talloc_asprintf(data, "testgroup%d", _i); + + req = sysdb_transaction_send(data, data->ev, test_ctx->sysdb); + if (!req) { + ret = ENOMEM; + } + + if (ret == EOK) { + tevent_req_set_callback(req, test_add_incomplete_group, data); + ret = test_loop(data); + } + + fail_if(ret != EOK, "Could not store incomplete group #%d", _i); + talloc_free(test_ctx); +} +END_TEST + START_TEST (test_sysdb_remove_local_user) { struct sysdb_test_ctx *test_ctx; @@ -3372,6 +3440,10 @@ Suite *create_sysdb_suite(void) /* Create a new group */ tcase_add_loop_test(tc_sysdb, test_sysdb_store_group, 28010, 28020); + /* Create and remove a incomplete group */ + tcase_add_loop_test(tc_sysdb, test_sysdb_add_incomplete_group, 28020, 28030); + tcase_add_loop_test(tc_sysdb, test_sysdb_remove_local_group, 28020, 28030); + /* Verify the groups were added */ /* Verify the groups can be queried by GID */ |