summaryrefslogtreecommitdiff
path: root/src/providers
diff options
context:
space:
mode:
Diffstat (limited to 'src/providers')
-rw-r--r--src/providers/ldap/ldap_id.c175
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");
}