From 4c898e1bb31ccf2af4039a7c3c5fcd82fb5667ed Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 2 Mar 2010 22:24:47 -0500 Subject: sysdb: convert sysdb_asq_search --- src/db/sysdb.h | 20 ++-- src/db/sysdb_ops.c | 200 ++++++++----------------------------- src/providers/ipa/ipa_access.c | 219 +++++++++++++---------------------------- src/tests/sysdb-tests.c | 59 +++++------ 4 files changed, 140 insertions(+), 358 deletions(-) (limited to 'src') diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 758a3c59b..f82f31153 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -547,17 +547,15 @@ int sysdb_delete_custom(TALLOC_CTX *mem_ctx, const char *object_name, const char *subtree_name); -struct tevent_req *sysdb_asq_search_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct sss_domain_info *domain, - struct ldb_dn *base_dn, - const char *expression, - const char *asq_attribute, - const char **attrs); -int sysdb_asq_search_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - size_t *msgs_count, struct ldb_message ***msgs); +int sysdb_asq_search(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + struct ldb_dn *base_dn, + const char *expression, + const char *asq_attribute, + const char **attrs, + size_t *msgs_count, + struct ldb_message ***msgs); struct tevent_req *sysdb_search_users_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index dcc72a039..d7e547ff5 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -1786,97 +1786,30 @@ done: } /* = ASQ search request ======================================== */ -struct sysdb_asq_search_state { - struct tevent_context *ev; - struct sysdb_ctx *sysdb; - struct sysdb_handle *handle; - struct sss_domain_info *domain; - struct ldb_dn *base_dn; - const char *asq_attribute; - const char **attrs; - const char *expression; - - int msgs_count; - struct ldb_message **msgs; -}; - -void sysdb_asq_search_check_handle_done(struct tevent_req *subreq); -static void sysdb_asq_search_done(struct tevent_req *subreq); - -struct tevent_req *sysdb_asq_search_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct sysdb_ctx *sysdb, - struct sysdb_handle *handle, - struct sss_domain_info *domain, - struct ldb_dn *base_dn, - const char *expression, - const char *asq_attribute, - const char **attrs) -{ - struct tevent_req *req; - struct tevent_req *subreq; - struct sysdb_asq_search_state *state; - int ret; - - if (sysdb == NULL && handle == NULL) { - DEBUG(1, ("Sysdb context not available.\n")); - return NULL; - } - req = tevent_req_create(mem_ctx, &state, struct sysdb_asq_search_state); - if (req == NULL) { - DEBUG(1, ("tevent_req_create failed.\n")); - return NULL; - } - - state->ev = ev; - state->sysdb = (sysdb == NULL) ? handle->ctx : sysdb; - state->handle = handle; - state->domain = domain; - state->base_dn = base_dn; - state->expression = expression; - state->asq_attribute = asq_attribute; - state->attrs = attrs; - - state->msgs_count = 0; - state->msgs = NULL; - - subreq = sysdb_check_handle_send(state, state->ev, state->sysdb, - state->handle); - if (!subreq) { - DEBUG(1, ("sysdb_check_handle_send failed.\n")); - ret = ENOMEM; - goto fail; - } - tevent_req_set_callback(subreq, sysdb_asq_search_check_handle_done, req); - - return req; - -fail: - tevent_req_error(req, ret); - tevent_req_post(req, ev); - return req; -} - -void sysdb_asq_search_check_handle_done(struct tevent_req *subreq) +int sysdb_asq_search(TALLOC_CTX *mem_ctx, + struct sysdb_ctx *sysdb, + struct sss_domain_info *domain, + struct ldb_dn *base_dn, + const char *expression, + const char *asq_attribute, + const char **attrs, + size_t *msgs_count, + struct ldb_message ***msgs) { - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct sysdb_asq_search_state *state = tevent_req_data(req, - struct sysdb_asq_search_state); + TALLOC_CTX *tmpctx; struct ldb_request *ldb_req; struct ldb_control **ctrl; struct ldb_asq_control *asq_control; + struct ldb_result *res; int ret; - ret = sysdb_check_handle_recv(subreq, state, &state->handle); - talloc_zfree(subreq); - if (ret != EOK) { - tevent_req_error(req, ret); - return; + tmpctx = talloc_new(mem_ctx); + if (!tmpctx) { + return ENOMEM; } - ctrl = talloc_array(state, struct ldb_control *, 2); + ctrl = talloc_array(tmpctx, struct ldb_control *, 2); if (ctrl == NULL) { ret = ENOMEM; goto fail; @@ -1899,8 +1832,7 @@ void sysdb_asq_search_check_handle_done(struct tevent_req *subreq) } asq_control->request = 1; - asq_control->source_attribute = talloc_strdup(asq_control, - state->asq_attribute); + asq_control->source_attribute = talloc_strdup(asq_control, asq_attribute); if (asq_control->source_attribute == NULL) { ret = ENOMEM; goto fail; @@ -1908,93 +1840,39 @@ void sysdb_asq_search_check_handle_done(struct tevent_req *subreq) asq_control->src_attr_len = strlen(asq_control->source_attribute); ctrl[0]->data = asq_control; - ret = ldb_build_search_req(&ldb_req, state->handle->ctx->ldb, state, - state->base_dn, LDB_SCOPE_BASE, - state->expression, state->attrs, ctrl, - NULL, NULL, NULL); - if (ret != LDB_SUCCESS) { - ret = sysdb_error_to_errno(ret); - goto fail; + res = talloc_zero(tmpctx, struct ldb_result); + if (!res) { + return ENOMEM; } - subreq = sldb_request_send(state, state->ev, state->handle->ctx->ldb, - ldb_req); - if (!subreq) { - ret = ENOMEM; + ret = ldb_build_search_req(&ldb_req, sysdb->ldb, tmpctx, + base_dn, LDB_SCOPE_BASE, + expression, attrs, ctrl, + res, ldb_search_default_callback, NULL); + if (ret != LDB_SUCCESS) { + ret = sysdb_error_to_errno(ret); goto fail; } - tevent_req_set_callback(subreq, sysdb_asq_search_done, req); - return; - -fail: - tevent_req_error(req, ret); - return; -} - -static void sysdb_asq_search_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct sysdb_asq_search_state *state = tevent_req_data(req, - struct sysdb_asq_search_state); - struct ldb_reply *ldbreply; - int ret; - - ret = sldb_request_recv(subreq, state, &ldbreply); - /* DO NOT free the subreq here, the subrequest search is not - * finished until we get an ldbreply of type LDB_REPLY_DONE */ - if (ret != EOK) { - DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); - tevent_req_error(req, ret); - return; + ret = ldb_request(sysdb->ldb, ldb_req); + if (ret == LDB_SUCCESS) { + ret = ldb_wait(ldb_req->handle, LDB_WAIT_ALL); } - - switch (ldbreply->type) { - case LDB_REPLY_ENTRY: - state->msgs = talloc_realloc(state, state->msgs, - struct ldb_message *, - state->msgs_count + 2); - if (state->msgs == NULL) { - tevent_req_error(req, ENOMEM); - return; - } - - state->msgs[state->msgs_count + 1] = NULL; - - state->msgs[state->msgs_count] = talloc_steal(state->msgs, - ldbreply->message); - state->msgs_count++; - - talloc_zfree(ldbreply); - return; - - case LDB_REPLY_DONE: - /* now it is safe to free the subrequest, the search is complete */ - talloc_zfree(subreq); - break; - - default: - DEBUG(1, ("Unknown ldb reply type [%d].\n", ldbreply->type)); - tevent_req_error(req, EINVAL); - return; + if (ret) { + ret = sysdb_error_to_errno(ret); + goto fail; } - tevent_req_done(req); -} - -int sysdb_asq_search_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - size_t *msgs_count, struct ldb_message ***msgs) -{ - struct sysdb_asq_search_state *state = tevent_req_data(req, - struct sysdb_asq_search_state); - - TEVENT_REQ_RETURN_ON_ERROR(req); - - *msgs_count = state->msgs_count; - *msgs = talloc_move(mem_ctx, &state->msgs); + *msgs_count = res->count; + *msgs = talloc_move(mem_ctx, &res->msgs); + talloc_zfree(tmpctx); return EOK; + +fail: + DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); + talloc_zfree(tmpctx); + return ret; } /* =Search-Users-with-Custom-Filter====================================== */ diff --git a/src/providers/ipa/ipa_access.c b/src/providers/ipa/ipa_access.c index 697d2479e..12c556371 100644 --- a/src/providers/ipa/ipa_access.c +++ b/src/providers/ipa/ipa_access.c @@ -98,170 +98,112 @@ static void ipa_access_reply(struct be_req *be_req, int pam_status) } } -struct hbac_get_user_info_state { - struct tevent_context *ev; - struct be_ctx *be_ctx;; - struct sysdb_handle *handle; - const char *user; +static int hbac_get_user_info(TALLOC_CTX *memctx, + struct be_ctx *be_ctx, + const char *user, + const char **user_dn, + size_t *groups_count, + const char ***_groups) +{ + TALLOC_CTX *tmpctx; + const char *attrs[] = { SYSDB_ORIG_DN, NULL }; + struct ldb_message *user_msg; const char *user_orig_dn; - struct ldb_dn *user_dn; - size_t groups_count; + struct ldb_message **msgs; + size_t count; const char **groups; -}; - -static void search_groups_done(struct tevent_req *subreq); - -struct tevent_req *hbac_get_user_info_send(TALLOC_CTX *memctx, - struct tevent_context *ev, - struct be_ctx *be_ctx, - const char *user) -{ - struct tevent_req *req = NULL; - struct tevent_req *subreq = NULL; - struct hbac_get_user_info_state *state; int ret; - static const char *attrs[] = { SYSDB_ORIG_DN, NULL }; - struct ldb_message *user_msg; - const char *dummy; + int i; - req = tevent_req_create(memctx, &state, struct hbac_get_user_info_state); - if (req == NULL) { - DEBUG(1, ("tevent_req_create failed.\n")); - return NULL; + tmpctx = talloc_new(memctx); + if (!tmpctx) { + return ENOMEM; } - state->ev = ev; - state->be_ctx = be_ctx; - state->handle = NULL; - state->user = user; - state->user_orig_dn = NULL; - state->user_dn = NULL; - state->groups_count = 0; - state->groups = NULL; - - ret = sysdb_search_user_by_name(state, be_ctx->sysdb, + ret = sysdb_search_user_by_name(tmpctx, be_ctx->sysdb, be_ctx->domain, user, attrs, &user_msg); if (ret != EOK) { goto fail; } - DEBUG(9, ("Found user info for user [%s].\n", state->user)); - state->user_dn = talloc_steal(state, user_msg->dn); - dummy = ldb_msg_find_attr_as_string(user_msg, SYSDB_ORIG_DN, NULL); - if (dummy == NULL) { - DEBUG(1, ("Original DN of user [%s] not available.\n", state->user)); + DEBUG(9, ("Found user info for user [%s].\n", user)); + user_orig_dn = ldb_msg_find_attr_as_string(user_msg, SYSDB_ORIG_DN, NULL); + if (user_orig_dn == NULL) { + DEBUG(1, ("Original DN of user [%s] not available.\n", user)); ret = EINVAL; goto fail; } - state->user_orig_dn = talloc_strdup(state, dummy); - if (state->user_dn == NULL) { - DEBUG(1, ("talloc_strdup failed.\n")); - ret = ENOMEM; - goto fail; - } - DEBUG(9, ("Found original DN [%s] for user [%s].\n", state->user_orig_dn, - state->user)); + DEBUG(9, ("Found original DN [%s] for user [%s].\n", + user_orig_dn, user)); - subreq = sysdb_asq_search_send(state, state->ev, state->be_ctx->sysdb, NULL, - state->be_ctx->domain, state->user_dn, NULL, - SYSDB_MEMBEROF, attrs); - if (subreq == NULL) { - DEBUG(1, ("sysdb_asq_search_send failed.\n")); - ret = ENOMEM; - goto fail; - } - tevent_req_set_callback(subreq, search_groups_done, req); - - return req; - -fail: - tevent_req_error(req, ret); - tevent_req_post(req, ev); - return req; -} - -static void search_groups_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data(subreq, - struct tevent_req); - struct hbac_get_user_info_state *state = tevent_req_data(req, - struct hbac_get_user_info_state); - int ret; - int i; - struct ldb_message **msg; - - ret = sysdb_asq_search_recv(subreq, state, &state->groups_count, &msg); - talloc_zfree(subreq); + ret = sysdb_asq_search(tmpctx, be_ctx->sysdb, be_ctx->domain, + user_msg->dn, NULL, SYSDB_MEMBEROF, attrs, + &count, &msgs); if (ret != EOK) { - tevent_req_error(req, ret); - return; + DEBUG(1, ("sysdb_asq_search on user %s failed.\n", user)); + goto fail; } - if (state->groups_count == 0) { - tevent_req_done(req); - return; + if (count == 0) { + *user_dn = talloc_strdup(memctx, user_orig_dn); + if (*user_dn == NULL) { + ret = ENOMEM; + goto fail; + } + *groups_count = 0; + *_groups = NULL; + talloc_zfree(tmpctx); + return EOK; } - state->groups = talloc_array(state, const char *, state->groups_count); - if (state->groups == NULL) { + groups = talloc_array(tmpctx, const char *, count); + if (groups == NULL) { DEBUG(1, ("talloc_groups failed.\n")); ret = ENOMEM; - goto failed; + goto fail; } - for(i = 0; i < state->groups_count; i++) { - if (msg[i]->num_elements != 1) { + for(i = 0; i < count; i++) { + if (msgs[i]->num_elements != 1) { DEBUG(1, ("Unexpected number of elements.\n")); ret = EINVAL; - goto failed; + goto fail; } - if (msg[i]->elements[0].num_values != 1) { + if (msgs[i]->elements[0].num_values != 1) { DEBUG(1, ("Unexpected number of values.\n")); ret = EINVAL; - goto failed; + goto fail; } - state->groups[i] = talloc_strndup(state->groups, - (const char *) msg[i]->elements[0].values[0].data, - msg[i]->elements[0].values[0].length); - if (state->groups[i] == NULL) { + groups[i] = talloc_strndup(groups, + (const char *)msgs[i]->elements[0].values[0].data, + msgs[i]->elements[0].values[0].length); + if (groups[i] == NULL) { DEBUG(1, ("talloc_strndup failed.\n")); ret = ENOMEM; - goto failed; + goto fail; } - DEBUG(9, ("Found group [%s].\n", state->groups[i])); + DEBUG(9, ("Found group [%s].\n", groups[i])); } - tevent_req_done(req); - return; - -failed: - talloc_free(state->groups); - tevent_req_error(req, ret); - return; -} - -static int hbac_get_user_info_recv(struct tevent_req *req, TALLOC_CTX *memctx, - const char **user_dn, size_t *groups_count, - const char ***groups) -{ - struct hbac_get_user_info_state *state = tevent_req_data(req, - struct hbac_get_user_info_state); - int i; - - TEVENT_REQ_RETURN_ON_ERROR(req); - - *user_dn = talloc_steal(memctx, state->user_orig_dn); - *groups_count = state->groups_count; - for (i = 0; i < state->groups_count; i++) { - talloc_steal(memctx, state->groups[i]); + *user_dn = talloc_strdup(memctx, user_orig_dn); + if (*user_dn == NULL) { + ret = ENOMEM; + goto fail; } - *groups = talloc_steal(memctx, state->groups); + *groups_count = count; + *_groups = talloc_steal(memctx, groups); + talloc_zfree(tmpctx); return EOK; + +fail: + DEBUG(6, ("Error: %d (%s)\n", ret, strerror(ret))); + talloc_zfree(tmpctx); + return ret; } @@ -1505,7 +1447,6 @@ static int evaluate_ipa_hbac_rules(struct hbac_ctx *hbac_ctx, static void hbac_get_host_info_done(struct tevent_req *req); static void hbac_get_rules_done(struct tevent_req *req); -static void hbac_get_user_info_done(struct tevent_req *req); void ipa_access_handler(struct be_req *be_req) { @@ -1644,40 +1585,18 @@ static void hbac_get_rules_done(struct tevent_req *req) struct be_req *be_req = hbac_ctx->be_req; int ret; int pam_status = PAM_SYSTEM_ERR; + bool access_allowed = false; ret = hbac_get_rules_recv(req, hbac_ctx, &hbac_ctx->hbac_rule_count, &hbac_ctx->hbac_rule_list); talloc_zfree(req); if (ret != EOK) { - goto fail; - } - - req = hbac_get_user_info_send(hbac_ctx, be_req->be_ctx->ev, be_req->be_ctx, - pd->user); - if (req == NULL) { - DEBUG(1, ("hbac_get_user_info_send failed.\n")); - goto fail; + goto failed; } - tevent_req_set_callback(req, hbac_get_user_info_done, hbac_ctx); - return; - -fail: - ipa_access_reply(be_req, pam_status); -} - -static void hbac_get_user_info_done(struct tevent_req *req) -{ - struct hbac_ctx *hbac_ctx = tevent_req_callback_data(req, struct hbac_ctx); - struct be_req *be_req = hbac_ctx->be_req; - int ret; - int pam_status = PAM_SYSTEM_ERR; - bool access_allowed = false; - - ret = hbac_get_user_info_recv(req, hbac_ctx, &hbac_ctx->user_dn, - &hbac_ctx->groups_count, - &hbac_ctx->groups); - talloc_zfree(req); + ret = hbac_get_user_info(hbac_ctx, be_req->be_ctx, + pd->user, &hbac_ctx->user_dn, + &hbac_ctx->groups_count, &hbac_ctx->groups); if (ret != EOK) { goto failed; } diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c index 008456c21..320e6f291 100644 --- a/src/tests/sysdb-tests.c +++ b/src/tests/sysdb-tests.c @@ -2243,7 +2243,6 @@ START_TEST (test_sysdb_asq_search) { struct sysdb_test_ctx *test_ctx; struct test_data *data; - struct tevent_req *req; struct ldb_dn *user_dn; int ret; size_t msgs_count; @@ -2270,46 +2269,34 @@ START_TEST (test_sysdb_asq_search) user_dn = sysdb_user_dn(data->ctx->sysdb, data, "LOCAL", ASQ_TEST_USER); fail_unless(user_dn != NULL, "sysdb_user_dn failed"); - req = sysdb_asq_search_send(data, data->ev, test_ctx->sysdb, NULL, - test_ctx->domain, user_dn, NULL, "memberof", - data->attrlist); - if (!req) { - ret = ENOMEM; - } + ret = sysdb_asq_search(data, test_ctx->sysdb, + test_ctx->domain, user_dn, NULL, "memberof", + data->attrlist, &msgs_count, &msgs); - if (ret == EOK) { - tevent_req_set_callback(req, test_search_done, data); + fail_if(ret != EOK, "Failed to send ASQ search request.\n"); - ret = test_loop(data); + fail_unless(msgs_count == 10, "wrong number of results, " + "found [%d] expected [10]", msgs_count); - ret = sysdb_asq_search_recv(req, data, &msgs_count, &msgs); - talloc_zfree(req); - fail_unless(ret == EOK, "sysdb_asq_search_send failed"); - - fail_unless(msgs_count == 10, "wrong number of results, " - "found [%d] expected [10]", msgs_count); - - for (i = 0; i < msgs_count; i++) { - fail_unless(msgs[i]->num_elements == 1, "wrong number of elements, " - "found [%d] expected [1]", - msgs[i]->num_elements); - - fail_unless(msgs[i]->elements[0].num_values == 1, - "wrong number of values, found [%d] expected [1]", - msgs[i]->elements[0].num_values); - - gid_str = talloc_asprintf(data, "%d", 28010 + i); - fail_unless(gid_str != NULL, "talloc_asprintf failed."); - fail_unless(strncmp(gid_str, - (const char *) msgs[i]->elements[0].values[0].data, - msgs[i]->elements[0].values[0].length) == 0, - "wrong value, found [%.*s] expected [%s]", - msgs[i]->elements[0].values[0].length, - msgs[i]->elements[0].values[0].data, gid_str); - } + for (i = 0; i < msgs_count; i++) { + fail_unless(msgs[i]->num_elements == 1, "wrong number of elements, " + "found [%d] expected [1]", + msgs[i]->num_elements); + + fail_unless(msgs[i]->elements[0].num_values == 1, + "wrong number of values, found [%d] expected [1]", + msgs[i]->elements[0].num_values); + + gid_str = talloc_asprintf(data, "%d", 28010 + i); + fail_unless(gid_str != NULL, "talloc_asprintf failed."); + fail_unless(strncmp(gid_str, + (const char *) msgs[i]->elements[0].values[0].data, + msgs[i]->elements[0].values[0].length) == 0, + "wrong value, found [%.*s] expected [%s]", + msgs[i]->elements[0].values[0].length, + msgs[i]->elements[0].values[0].data, gid_str); } - fail_if(ret != EOK, "Failed to send ASQ search request.\n"); talloc_free(test_ctx); } END_TEST -- cgit