diff options
Diffstat (limited to 'src/providers/ldap/sdap_async_enum.c')
-rw-r--r-- | src/providers/ldap/sdap_async_enum.c | 96 |
1 files changed, 94 insertions, 2 deletions
diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c index cbc56be20..0c20afa9d 100644 --- a/src/providers/ldap/sdap_async_enum.c +++ b/src/providers/ldap/sdap_async_enum.c @@ -68,6 +68,8 @@ static errno_t sdap_dom_enum_ex_retry(struct tevent_req *req, tevent_req_fn tcb); static bool sdap_dom_enum_ex_connected(struct tevent_req *subreq); static void sdap_dom_enum_ex_get_users(struct tevent_req *subreq); +static void sdap_dom_enum_ex_posix_check_done(struct tevent_req *subreq); +static errno_t sdap_dom_enum_search_users(struct tevent_req *req); static void sdap_dom_enum_ex_users_done(struct tevent_req *subreq); static void sdap_dom_enum_ex_get_groups(struct tevent_req *subreq); static void sdap_dom_enum_ex_groups_done(struct tevent_req *subreq); @@ -178,19 +180,109 @@ static void sdap_dom_enum_ex_get_users(struct tevent_req *subreq) struct tevent_req); struct sdap_dom_enum_ex_state *state = tevent_req_data(req, struct sdap_dom_enum_ex_state); + bool use_id_mapping; + errno_t ret; if (sdap_dom_enum_ex_connected(subreq) == false) { return; } + use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping( + state->ctx->opts->idmap_ctx, + state->sdom->dom->name, + state->sdom->dom->domain_id); + + /* If POSIX attributes have been requested with an AD server and we + * have no idea about POSIX attributes support, run a one-time check + */ + if (use_id_mapping == false && + state->ctx->opts->schema_type == SDAP_SCHEMA_AD && + state->ctx->srv_opts && + state->ctx->srv_opts->posix_checked == false) { + subreq = sdap_posix_check_send(state, state->ev, state->ctx->opts, + sdap_id_op_handle(state->user_op), + state->sdom->user_search_bases, + dp_opt_get_int(state->ctx->opts->basic, + SDAP_SEARCH_TIMEOUT)); + if (subreq == NULL) { + tevent_req_error(req, ENOMEM); + return; + } + tevent_req_set_callback(subreq, + sdap_dom_enum_ex_posix_check_done, req); + return; + } + + + ret = sdap_dom_enum_search_users(req); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + /* Execution resumes in sdap_dom_enum_ex_users_done */ +} + +static void sdap_dom_enum_ex_posix_check_done(struct tevent_req *subreq) +{ + errno_t ret; + bool has_posix; + int dp_error; + + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct sdap_dom_enum_ex_state *state = tevent_req_data(req, + struct sdap_dom_enum_ex_state); + + ret = sdap_posix_check_recv(subreq, &has_posix); + talloc_zfree(subreq); + if (ret != EOK) { + /* We can only finish the id_op on error as the connection + * is re-used by the user search + */ + ret = sdap_id_op_done(state->user_op, ret, &dp_error); + if (dp_error == DP_ERR_OK && ret != EOK) { + /* retry */ + ret = sdap_dom_enum_ex_retry(req, state->user_op, + sdap_dom_enum_ex_get_users); + if (ret != EOK) { + tevent_req_error(req, ret); + } + return; + } + } + + state->ctx->srv_opts->posix_checked = true; + + /* If the check ran to completion, we know for certain about the attributes + */ + if (has_posix == false) { + tevent_req_error(req, ERR_NO_POSIX); + return; + } + + + ret = sdap_dom_enum_search_users(req); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + /* Execution resumes in sdap_dom_enum_ex_users_done */ +} + +static errno_t sdap_dom_enum_search_users(struct tevent_req *req) +{ + struct sdap_dom_enum_ex_state *state = tevent_req_data(req, + struct sdap_dom_enum_ex_state); + struct tevent_req *subreq; + subreq = enum_users_send(state, state->ev, state->ctx, state->sdom, state->user_op, state->purge); if (subreq == NULL) { - tevent_req_error(req, ENOMEM); - return; + return ENOMEM; } tevent_req_set_callback(subreq, sdap_dom_enum_ex_users_done, req); + return EOK; } static void sdap_dom_enum_ex_users_done(struct tevent_req *subreq) |