From 457d7dc822de590ab024cef8df66135445a4b377 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Mon, 30 Nov 2009 10:48:02 +0100 Subject: Add sysdb_search_custom request --- server/db/sysdb.h | 11 ++- server/db/sysdb_ops.c | 97 ++++++++++++++++++++++--- server/tests/sysdb-tests.c | 172 +++++++++++++++++++++++++++++---------------- 3 files changed, 206 insertions(+), 74 deletions(-) (limited to 'server') diff --git a/server/db/sysdb.h b/server/db/sysdb.h index bc2bf66a..9348c57f 100644 --- a/server/db/sysdb.h +++ b/server/db/sysdb.h @@ -538,6 +538,14 @@ struct tevent_req *sysdb_store_custom_send(TALLOC_CTX *mem_ctx, struct sysdb_attrs *attrs); int sysdb_store_custom_recv(struct tevent_req *req); +struct tevent_req *sysdb_search_custom_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sysdb_ctx *sysdb, + struct sysdb_handle *handle, + struct sss_domain_info *domain, + const char *filter, + const char *subtree_name, + const char **attrs); struct tevent_req *sysdb_search_custom_by_name_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sysdb_ctx *sysdb, @@ -548,7 +556,8 @@ struct tevent_req *sysdb_search_custom_by_name_send(TALLOC_CTX *mem_ctx, const char **attrs); int sysdb_search_custom_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct ldb_message **msg); + size_t *msgs_count, + struct ldb_message ***msg); struct tevent_req *sysdb_delete_custom_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, diff --git a/server/db/sysdb_ops.c b/server/db/sysdb_ops.c index da53fd3b..c237473f 100644 --- a/server/db/sysdb_ops.c +++ b/server/db/sysdb_ops.c @@ -3395,7 +3395,12 @@ struct tevent_req *sysdb_check_handle_send(TALLOC_CTX *mem_ctx, if (handle != NULL) { state->handle = talloc_memdup(state, handle, sizeof(struct sysdb_handle)); - tevent_req_done(req); + if (state->handle == NULL) { + DEBUG(1, ("talloc_memdup failed.\n")); + tevent_req_error(req, ENOMEM); + } else { + tevent_req_done(req); + } tevent_req_post(req, ev); return req; } @@ -3457,6 +3462,7 @@ struct sysdb_search_custom_state { const char **attrs; const char *filter; int scope; + bool expect_not_more_than_one; size_t msgs_count; struct ldb_message **msgs; @@ -3465,6 +3471,70 @@ struct sysdb_search_custom_state { static void sysdb_search_custom_check_handle_done(struct tevent_req *subreq); static void sysdb_search_custom_done(struct tevent_req *subreq); +struct tevent_req *sysdb_search_custom_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct sysdb_ctx *sysdb, + struct sysdb_handle *handle, + struct sss_domain_info *domain, + const char *filter, + const char *subtree_name, + const char **attrs) +{ + struct tevent_req *req, *subreq; + struct sysdb_search_custom_state *state; + int ret; + + if (sysdb == NULL && handle == NULL) return NULL; + + if (filter == NULL || subtree_name == NULL) return NULL; + + req = tevent_req_create(mem_ctx, &state, struct sysdb_search_custom_state); + if (req == NULL) { + DEBUG(1, ("tevent_req_create failed.\n")); + return NULL; + } + + state->ev = ev; + state->handle = handle; + state->attrs = attrs; + state->filter = filter; + state->scope = LDB_SCOPE_SUBTREE; + state->expect_not_more_than_one = false; + state->msgs_count = 0; + state->msgs = NULL; + + if (sysdb == NULL) { + sysdb = handle->ctx; + } + state->basedn = sysdb_custom_subtree_dn(sysdb, state, domain->name, + subtree_name); + if (state->basedn == NULL) { + DEBUG(1, ("sysdb_custom_subtree_dn failed.\n")); + ret = ENOMEM; + goto fail; + } + if (!ldb_dn_validate(state->basedn)) { + DEBUG(1, ("Failed to create DN.\n")); + ret = EINVAL; + goto fail; + } + + subreq = sysdb_check_handle_send(state, state->ev, sysdb, state->handle); + if (!subreq) { + DEBUG(1, ("sysdb_check_handle_send failed.\n")); + ret = ENOMEM; + goto fail; + } + tevent_req_set_callback(subreq, sysdb_search_custom_check_handle_done, req); + + return req; + +fail: + tevent_req_error(req, ret); + tevent_req_post(req, ev); + return req; +} + struct tevent_req *sysdb_search_custom_by_name_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct sysdb_ctx *sysdb, @@ -3493,6 +3563,7 @@ struct tevent_req *sysdb_search_custom_by_name_send(TALLOC_CTX *mem_ctx, state->attrs = attrs; state->filter = NULL; state->scope = LDB_SCOPE_BASE; + state->expect_not_more_than_one = true; state->msgs_count = 0; state->msgs = NULL; @@ -3571,24 +3642,27 @@ static void sysdb_search_custom_done(struct tevent_req *subreq) return; } + if (state->expect_not_more_than_one && state->msgs_count > 1) { + DEBUG(1, ("More than one result found.\n")); + tevent_req_error(req, EFAULT); + return; + } + tevent_req_done(req); } int sysdb_search_custom_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct ldb_message **msg) + size_t *msgs_count, + struct ldb_message ***msgs) { struct sysdb_search_custom_state *state = tevent_req_data(req, struct sysdb_search_custom_state); TEVENT_REQ_RETURN_ON_ERROR(req); - if (state->msgs_count > 1) { - DEBUG(1, ("More than one result found.\n")); - return EFAULT; - } - - *msg = talloc_move(mem_ctx, &state->msgs[0]); + *msgs_count = state->msgs_count; + *msgs = talloc_move(mem_ctx, &state->msgs); return EOK; } @@ -3690,13 +3764,14 @@ static void sysdb_store_custom_check_done(struct tevent_req *subreq) struct sysdb_store_custom_state); int ret; int i; - struct ldb_message *resp; + size_t resp_count = 0; + struct ldb_message **resp; struct ldb_message *msg; struct ldb_request *ldbreq; struct ldb_message_element *el; bool add_object = false; - ret = sysdb_search_custom_recv(subreq, state, &resp); + ret = sysdb_search_custom_recv(subreq, state, &resp_count, &resp); talloc_zfree(subreq); if (ret != EOK && ret != ENOENT) { tevent_req_error(req, ret); @@ -3727,7 +3802,7 @@ static void sysdb_store_custom_check_done(struct tevent_req *subreq) if (add_object) { msg->elements[i].flags = LDB_FLAG_MOD_ADD; } else { - el = ldb_msg_find_element(resp, state->attrs->a[i].name); + el = ldb_msg_find_element(resp[0], state->attrs->a[i].name); if (el == NULL) { msg->elements[i].flags = LDB_FLAG_MOD_ADD; } else { diff --git a/server/tests/sysdb-tests.c b/server/tests/sysdb-tests.c index d4f0e2fd..3bf6ddc3 100644 --- a/server/tests/sysdb-tests.c +++ b/server/tests/sysdb-tests.c @@ -879,68 +879,10 @@ static void test_store_custom_done(struct tevent_req *subreq) return test_return(data, ret); } -static void test_search_custom_by_name_done(struct tevent_req *subreq) +static void test_search_custom_done(struct tevent_req *req) { - struct test_data *data = tevent_req_callback_data(subreq, struct test_data); - int ret; - - ret = sysdb_search_custom_recv(subreq, data, &data->msg); - talloc_zfree(subreq); - if (ret != EOK) { - data->error = ret; - goto done; - } - - fail_unless(data->msg->num_elements == 1, - "Wrong number of results, expected [1] got [%d]", - data->msg->num_elements); - fail_unless(strcmp(data->msg->elements[0].name, TEST_ATTR_NAME) == 0, - "Wrong attribute name"); - fail_unless(data->msg->elements[0].num_values == 1, - "Wrong number of attribute values"); - fail_unless(strncmp((const char *)data->msg->elements[0].values[0].data, - TEST_ATTR_VALUE, data->msg->elements[0].values[0].length) == 0, - "Wrong attribute value"); - -done: - data->finished = true; - return; -} - -static void test_search_custom_update_done(struct tevent_req *subreq) -{ - struct test_data *data = tevent_req_callback_data(subreq, struct test_data); - int ret; - struct ldb_message_element *el; - - ret = sysdb_search_custom_recv(subreq, data, &data->msg); - talloc_zfree(subreq); - if (ret != EOK) { - data->error = ret; - goto done; - } - - fail_unless(data->msg->num_elements == 2, - "Wrong number of results, expected [1] got [%d]", - data->msg->num_elements); - - el = ldb_msg_find_element(data->msg, TEST_ATTR_NAME); - fail_unless(el != NULL, "Attribute [%s] not found", TEST_ATTR_NAME); - fail_unless(el->num_values == 1, "Wrong number ([%d] instead of 1) " - "of attribute values for [%s]", el->num_values, TEST_ATTR_NAME); - fail_unless(strncmp((const char *) el->values[0].data, TEST_ATTR_UPDATE_VALUE, - el->values[0].length) == 0, - "Wrong attribute value"); - - el = ldb_msg_find_element(data->msg, TEST_ATTR_ADD_NAME); - fail_unless(el != NULL, "Attribute [%s] not found", TEST_ATTR_ADD_NAME); - fail_unless(el->num_values == 1, "Wrong number ([%d] instead of 1) " - "of attribute values for [%s]", el->num_values, TEST_ATTR_ADD_NAME); - fail_unless(strncmp((const char *) el->values[0].data, TEST_ATTR_ADD_VALUE, - el->values[0].length) == 0, - "Wrong attribute value"); + struct test_data *data = tevent_req_callback_data(req, struct test_data); -done: data->finished = true; return; } @@ -1993,9 +1935,29 @@ START_TEST (test_sysdb_search_custom_by_name) } if (ret == EOK) { - tevent_req_set_callback(subreq, test_search_custom_by_name_done, data); + tevent_req_set_callback(subreq, test_search_custom_done, data); ret = test_loop(data); + + ret = sysdb_search_custom_recv(subreq, data, &data->msgs_count, + &data->msgs); + talloc_zfree(subreq); + fail_unless(ret == EOK, "sysdb_search_custom_by_name_send failed"); + + fail_unless(data->msgs_count == 1, + "Wrong number of objects, exptected [1] got [%d]", + data->msgs_count); + fail_unless(data->msgs[0]->num_elements == 1, + "Wrong number of results, expected [1] got [%d]", + data->msgs[0]->num_elements); + fail_unless(strcmp(data->msgs[0]->elements[0].name, TEST_ATTR_NAME) == 0, + "Wrong attribute name"); + fail_unless(data->msgs[0]->elements[0].num_values == 1, + "Wrong number of attribute values"); + fail_unless(strncmp((const char *)data->msgs[0]->elements[0].values[0].data, + TEST_ATTR_VALUE, + data->msgs[0]->elements[0].values[0].length) == 0, + "Wrong attribute value"); } fail_if(ret != EOK, "Could not search custom object"); @@ -2066,6 +2028,7 @@ START_TEST (test_sysdb_search_custom_update) struct tevent_req *subreq; int ret; char *object_name; + struct ldb_message_element *el; /* Setup */ ret = setup_sysdb_tests(&test_ctx); @@ -2098,9 +2061,93 @@ START_TEST (test_sysdb_search_custom_update) } if (ret == EOK) { - tevent_req_set_callback(subreq, test_search_custom_update_done, data); + tevent_req_set_callback(subreq, test_search_custom_done, data); + + ret = test_loop(data); + + ret = sysdb_search_custom_recv(subreq, data, &data->msgs_count, + &data->msgs); + talloc_zfree(subreq); + fail_unless(ret == EOK, "sysdb_search_custom_by_name_send failed"); + + fail_unless(data->msgs_count == 1, + "Wrong number of objects, exptected [1] got [%d]", + data->msgs_count); + fail_unless(data->msgs[0]->num_elements == 2, + "Wrong number of results, expected [2] got [%d]", + data->msgs[0]->num_elements); + + el = ldb_msg_find_element(data->msgs[0], TEST_ATTR_NAME); + fail_unless(el != NULL, "Attribute [%s] not found", TEST_ATTR_NAME); + fail_unless(el->num_values == 1, "Wrong number ([%d] instead of 1) " + "of attribute values for [%s]", el->num_values, TEST_ATTR_NAME); + fail_unless(strncmp((const char *) el->values[0].data, TEST_ATTR_UPDATE_VALUE, + el->values[0].length) == 0, + "Wrong attribute value"); + + el = ldb_msg_find_element(data->msgs[0], TEST_ATTR_ADD_NAME); + fail_unless(el != NULL, "Attribute [%s] not found", TEST_ATTR_ADD_NAME); + fail_unless(el->num_values == 1, "Wrong number ([%d] instead of 1) " + "of attribute values for [%s]", el->num_values, TEST_ATTR_ADD_NAME); + fail_unless(strncmp((const char *) el->values[0].data, TEST_ATTR_ADD_VALUE, + el->values[0].length) == 0, + "Wrong attribute value"); + + } + + fail_if(ret != EOK, "Could not search custom object"); + talloc_free(test_ctx); +} +END_TEST + +START_TEST (test_sysdb_search_custom) +{ + struct sysdb_test_ctx *test_ctx; + struct test_data *data; + struct tevent_req *subreq; + int ret; + const char *filter = "(distinguishedName=*)"; + + /* 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); + fail_unless(data != NULL, "talloc_zero failed"); + data->ctx = test_ctx; + data->ev = test_ctx->ev; + data->attrlist = talloc_array(test_ctx, const char *, 3); + fail_unless(data->attrlist != NULL, "talloc_array failed"); + data->attrlist[0] = TEST_ATTR_NAME; + data->attrlist[1] = TEST_ATTR_ADD_NAME; + data->attrlist[2] = NULL; + + subreq = sysdb_search_custom_send(data, data->ev, + data->ctx->sysdb, NULL, + data->ctx->domain, + filter, + CUSTOM_TEST_CONTAINER, + data->attrlist); + if (!subreq) { + ret = ENOMEM; + } + + if (ret == EOK) { + tevent_req_set_callback(subreq, test_search_custom_done, data); ret = test_loop(data); + + ret = sysdb_search_custom_recv(subreq, data, &data->msgs_count, + &data->msgs); + talloc_zfree(subreq); + fail_unless(ret == EOK, "sysdb_search_custom_send failed"); + + fail_unless(data->msgs_count == 10, + "Wrong number of objects, exptected [10] got [%d]", + data->msgs_count); } fail_if(ret != EOK, "Could not search custom object"); @@ -2484,6 +2531,7 @@ Suite *create_sysdb_suite(void) tcase_add_test(tc_sysdb, test_sysdb_search_custom_by_name); tcase_add_test(tc_sysdb, test_sysdb_update_custom); tcase_add_test(tc_sysdb, test_sysdb_search_custom_update); + tcase_add_test(tc_sysdb, test_sysdb_search_custom); tcase_add_test(tc_sysdb, test_sysdb_delete_custom); /* test recursive delete */ -- cgit