diff options
author | Simo Sorce <ssorce@redhat.com> | 2010-04-29 12:30:05 -0400 |
---|---|---|
committer | Stephen Gallagher <sgallagh@redhat.com> | 2010-05-03 13:53:19 -0400 |
commit | 601545ddd3f65e819de307214fdde8a9181be366 (patch) | |
tree | 51219018d71a4631dbf9be2982f4236aacbf9b13 /src/providers/ldap/ldap_id.c | |
parent | 0ab5413bbbafe05c2a61d42b24e1842848bf78c2 (diff) | |
download | sssd-601545ddd3f65e819de307214fdde8a9181be366.tar.gz sssd-601545ddd3f65e819de307214fdde8a9181be366.tar.xz sssd-601545ddd3f65e819de307214fdde8a9181be366.zip |
Better handle sdap_handle memory from callers.
Always just mark the sdap_handle as not connected and let later _send()
functions to take care of freeing the handle before reconnecting.
Introduce restart functions to avoid calling _send() functions in _done()
functions error paths as this would have the same effect as directly freeing
the sdap_handle and cause access to freed memory in sdap_handle_release()
By freeing sdap_handle only in the connection _recv() function we
guarantee it can never be done within sdap_handle_release() but only
in a following event.
Diffstat (limited to 'src/providers/ldap/ldap_id.c')
-rw-r--r-- | src/providers/ldap/ldap_id.c | 56 |
1 files changed, 40 insertions, 16 deletions
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c index 4bbc07a68..c472d8b64 100644 --- a/src/providers/ldap/ldap_id.c +++ b/src/providers/ldap/ldap_id.c @@ -100,8 +100,6 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx, if (!sdap_connected(ctx)) { - if (ctx->gsh) talloc_zfree(ctx->gsh); - /* FIXME: add option to decide if tls should be used * or SASL/GSSAPI, etc ... */ subreq = sdap_cli_connect_send(state, ev, ctx->opts, @@ -323,8 +321,6 @@ struct tevent_req *groups_get_send(TALLOC_CTX *memctx, if (!sdap_connected(ctx)) { - if (ctx->gsh) talloc_zfree(ctx->gsh); - /* FIXME: add option to decide if tls should be used * or SASL/GSSAPI, etc ... */ subreq = sdap_cli_connect_send(state, ev, ctx->opts, @@ -511,8 +507,6 @@ static struct tevent_req *groups_by_user_send(TALLOC_CTX *memctx, if (!sdap_connected(ctx)) { - if (ctx->gsh) talloc_zfree(ctx->gsh); - /* FIXME: add option to decide if tls should be used * or SASL/GSSAPI, etc ... */ subreq = sdap_cli_connect_send(state, ev, ctx->opts, @@ -700,13 +694,43 @@ 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_users_done(struct tevent_req *req) { struct be_req *breq = tevent_req_callback_data(req, struct be_req); struct sdap_id_ctx *ctx; int dp_err = DP_ERR_OK; const char *error = NULL; - int ret; + int ret, err; ret = users_get_recv(req); talloc_zfree(req); @@ -720,9 +744,9 @@ static void sdap_account_info_users_done(struct tevent_req *req) ctx = talloc_get_type(breq->be_ctx->bet_info[BET_ID].pvt_bet_data, struct sdap_id_ctx); if (sdap_check_gssapi_reconnect(ctx)) { - talloc_zfree(ctx->gsh); - sdap_account_info_handler(breq); - return; + ctx->gsh->connected = false; + err = sdap_account_info_restart(breq); + if (err == EOK) return; } sdap_mark_offline(ctx); } @@ -737,7 +761,7 @@ static void sdap_account_info_groups_done(struct tevent_req *req) struct sdap_id_ctx *ctx; int dp_err = DP_ERR_OK; const char *error = NULL; - int ret; + int ret, err; ret = groups_get_recv(req); talloc_zfree(req); @@ -751,9 +775,9 @@ static void sdap_account_info_groups_done(struct tevent_req *req) ctx = talloc_get_type(breq->be_ctx->bet_info[BET_ID].pvt_bet_data, struct sdap_id_ctx); if (sdap_check_gssapi_reconnect(ctx)) { - talloc_zfree(ctx->gsh); - sdap_account_info_handler(breq); - return; + ctx->gsh->connected = false; + err = sdap_account_info_restart(breq); + if (err == EOK) return; } sdap_mark_offline(ctx); } @@ -782,8 +806,8 @@ static void sdap_account_info_initgr_done(struct tevent_req *req) ctx = talloc_get_type(breq->be_ctx->bet_info[BET_ID].pvt_bet_data, struct sdap_id_ctx); if (sdap_check_gssapi_reconnect(ctx)) { - talloc_zfree(ctx->gsh); - sdap_account_info_handler(breq); + ctx->gsh->connected = false; + sdap_account_info_restart(breq); return; } sdap_mark_offline(ctx); |