diff options
Diffstat (limited to 'src/providers')
-rw-r--r-- | src/providers/ldap/ldap_id.c | 175 |
1 files changed, 67 insertions, 108 deletions
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c index 951abf48..d52dcec5 100644 --- a/src/providers/ldap/ldap_id.c +++ b/src/providers/ldap/ldap_id.c @@ -490,10 +490,14 @@ int groups_get_recv(struct tevent_req *req, int *dp_error_out) struct groups_by_user_state { struct tevent_context *ev; struct sdap_id_ctx *ctx; + struct sdap_id_op *op; const char *name; const char **attrs; + + int dp_error; }; +static int groups_by_user_retry(struct tevent_req *req); static void groups_by_user_connect_done(struct tevent_req *subreq); static void groups_by_user_done(struct tevent_req *subreq); @@ -502,7 +506,7 @@ static struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, struct sdap_id_ctx *ctx, const char *name) { - struct tevent_req *req, *subreq; + struct tevent_req *req; struct groups_by_user_state *state; int ret; @@ -511,39 +515,25 @@ static struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, state->ev = ev; state->ctx = ctx; + state->dp_error = DP_ERR_FATAL; + + state->op = sdap_id_op_create(state, state->ctx->conn_cache); + if (!state->op) { + DEBUG(2, ("sdap_id_op_create failed\n")); + ret = ENOMEM; + goto fail; + } + state->name = name; ret = build_attrs_from_map(state, ctx->opts->group_map, SDAP_OPTS_GROUP, &state->attrs); if (ret != EOK) goto fail; - if (!sdap_connected(ctx)) { - - /* FIXME: add option to decide if tls should be used - * or SASL/GSSAPI, etc ... */ - subreq = sdap_cli_connect_send(state, ev, ctx->opts, - ctx->be, ctx->service, - &ctx->rootDSE); - if (!subreq) { - ret = ENOMEM; - goto fail; - } - - tevent_req_set_callback(subreq, groups_by_user_connect_done, req); - - return req; - } - - subreq = sdap_get_initgr_send(state, state->ev, - state->ctx->be->domain, - state->ctx->be->sysdb, - state->ctx->opts, state->ctx->gsh, - state->name, state->attrs); - if (!subreq) { - ret = ENOMEM; + ret = groups_by_user_retry(req); + if (ret != EOK) { goto fail; } - tevent_req_set_callback(subreq, groups_by_user_done, req); return req; @@ -553,21 +543,36 @@ fail: return req; } +static int groups_by_user_retry(struct tevent_req *req) +{ + struct groups_by_user_state *state = tevent_req_data(req, + struct groups_by_user_state); + struct tevent_req *subreq; + int ret = EOK; + + subreq = sdap_id_op_connect_send(state->op, state, &ret); + if (!subreq) { + return ret; + } + + tevent_req_set_callback(subreq, groups_by_user_connect_done, req); + return EOK; +} + static void groups_by_user_connect_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); struct groups_by_user_state *state = tevent_req_data(req, struct groups_by_user_state); + int dp_error = DP_ERR_FATAL; int ret; - ret = sdap_cli_connect_recv(subreq, state->ctx, - &state->ctx->gsh, &state->ctx->rootDSE); + ret = sdap_id_op_connect_recv(subreq, &dp_error); talloc_zfree(subreq); - if (ret) { - if (ret == ENOTSUP) { - DEBUG(0, ("Authentication mechanism not Supported by server")); - } + + if (ret != EOK) { + state->dp_error = dp_error; tevent_req_error(req, ret); return; } @@ -575,7 +580,7 @@ static void groups_by_user_connect_done(struct tevent_req *subreq) subreq = sdap_get_initgr_send(state, state->ev, state->ctx->be->domain, state->ctx->be->sysdb, - state->ctx->opts, state->ctx->gsh, + state->ctx->opts, sdap_id_op_handle(state->op), state->name, state->attrs); if (!subreq) { tevent_req_error(req, ENOMEM); @@ -588,11 +593,28 @@ static void groups_by_user_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, struct tevent_req); + struct groups_by_user_state *state = tevent_req_data(req, + struct groups_by_user_state); + int dp_error = DP_ERR_FATAL; int ret; ret = sdap_get_initgr_recv(subreq); talloc_zfree(subreq); - if (ret) { + ret = sdap_id_op_done(state->op, ret, &dp_error); + + if (dp_error == DP_ERR_OK && ret != EOK) { + /* retry */ + ret = groups_by_user_retry(req); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + return; + } + + if (ret && ret != ENOENT) { + state->dp_error = dp_error; tevent_req_error(req, ret); return; } @@ -600,8 +622,15 @@ static void groups_by_user_done(struct tevent_req *subreq) tevent_req_done(req); } -int groups_by_user_recv(struct tevent_req *req) +int groups_by_user_recv(struct tevent_req *req, int *dp_error_out) { + struct groups_by_user_state *state = tevent_req_data(req, + struct groups_by_user_state); + + if (dp_error_out) { + *dp_error_out = state->dp_error; + } + TEVENT_REQ_RETURN_ON_ERROR(req); return EOK; @@ -706,76 +735,6 @@ void sdap_account_info_handler(struct be_req *breq) if (ret != EOK) return sdap_handler_done(breq, DP_ERR_FATAL, ret, err); } -static void sdap_account_info_immediate(struct tevent_context *ctx, - struct tevent_immediate *im, - void *private_data) -{ - struct be_req *breq = talloc_get_type(private_data, struct be_req); - - sdap_account_info_handler(breq); -} - -static int sdap_account_info_restart(struct be_req *breq) -{ - struct tevent_immediate *im; - - breq->restarts++; - if (breq->restarts > MAX_BE_REQ_RESTARTS) { - return ELOOP; - } - - im = tevent_create_immediate(breq); - if (!im) { - return ENOMEM; - } - - /* schedule a completely new event to avoid deep recursions */ - tevent_schedule_immediate(im, breq->be_ctx->ev, - sdap_account_info_immediate, breq); - - return EOK; -} - -static void sdap_account_info_common_done(int ret, struct be_req *breq, - const char *str_on_err) -{ - struct sdap_id_ctx *ctx; - int dp_err = DP_ERR_OK; - const char *errstr = NULL; - errno_t err; - - if (ret != EOK) { - dp_err = DP_ERR_FATAL; - errstr = str_on_err; - - if (ret == ETIMEDOUT || ret == EFAULT || ret == EIO) { - ctx = talloc_get_type(breq->be_ctx->bet_info[BET_ID].pvt_bet_data, - struct sdap_id_ctx); - if (sdap_check_gssapi_reconnect(ctx)) { - if (ctx->gsh) { - /* Mark the connection as false so we don't try to use an - * invalid connection by mistake later. - * If the global sdap handler is NULL, it's ok not to do - * anything here. It's always checked by sdap_connected() - * before being used. - */ - ctx->gsh->connected = false; - } - err = sdap_account_info_restart(breq); - if (err == EOK) return; - } - - /* Couldn't reconnect, that was our last try - * Go offline now - */ - dp_err = DP_ERR_OFFLINE; - sdap_mark_offline(ctx); - } - } - - sdap_handler_done(breq, dp_err, ret, errstr); -} - static void sdap_account_info_complete(struct be_req *breq, int dp_error, int ret, const char *default_error_text) { @@ -825,11 +784,11 @@ static void sdap_account_info_groups_done(struct tevent_req *req) static void sdap_account_info_initgr_done(struct tevent_req *req) { struct be_req *breq = tevent_req_callback_data(req, struct be_req); - int ret; + int ret, dp_error; - ret = groups_by_user_recv(req); + ret = groups_by_user_recv(req, &dp_error); talloc_zfree(req); - sdap_account_info_common_done(ret, breq, "Init Groups Failed"); + sdap_account_info_complete(breq, dp_error, ret, "Init Groups Failed"); } |