diff options
author | Andrew Tridgell <tridge@samba.org> | 2010-09-13 07:41:56 +1000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2010-09-15 15:39:34 +1000 |
commit | 5b02cf1eb0b2e524cb58ec6ed6e766c252b06af9 (patch) | |
tree | b3efcd5c6523dc88c1269099ac66054f1f029e82 /source4/auth | |
parent | 890a33c99bc0a468984c456647311db0a19528aa (diff) | |
download | samba-5b02cf1eb0b2e524cb58ec6ed6e766c252b06af9.tar.gz samba-5b02cf1eb0b2e524cb58ec6ed6e766c252b06af9.tar.bz2 samba-5b02cf1eb0b2e524cb58ec6ed6e766c252b06af9.zip |
s4-auth: allow multiple active auth backends
when we are an RODC we need to be able to allow multiple auth backends
to process a single auth request. First the sam backend will try to
authenticate, using locally stored passwords. If this backend can't
find local passwords then it will try the winbind backend and
authenticate via a writeable DC
Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'source4/auth')
-rw-r--r-- | source4/auth/ntlm/auth.c | 78 |
1 files changed, 43 insertions, 35 deletions
diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c index a977aa4c41..b34b8ac132 100644 --- a/source4/auth/ntlm/auth.c +++ b/source4/auth/ntlm/auth.c @@ -234,7 +234,6 @@ _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, struct auth_check_password_state *state; /* if all the modules say 'not for me' this is reasonable */ NTSTATUS nt_status; - struct auth_method_context *method; uint8_t chal[8]; struct auth_usersupplied_info *user_info_tmp; struct tevent_immediate *im; @@ -252,7 +251,6 @@ _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, state->auth_ctx = auth_ctx; state->user_info = user_info; - state->method = NULL; if (!user_info->mapped_state) { nt_status = map_user_info(req, lpcfg_workgroup(auth_ctx->lp_ctx), @@ -296,35 +294,11 @@ _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - for (method = auth_ctx->methods; method; method = method->next) { - NTSTATUS result; - - /* check if the module wants to chek the password */ - result = method->ops->want_check(method, req, user_info); - if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) { - DEBUG(11,("auth_check_password_send: " - "%s had nothing to say\n", - method->ops->name)); - continue; - } - - state->method = method; - - if (tevent_req_nterror(req, result)) { - return tevent_req_post(req, ev); - } - - tevent_schedule_immediate(im, - auth_ctx->event_ctx, - auth_check_password_async_trigger, - req); - - return req; - } - - /* If all the modules say 'not for me', then this is reasonable */ - tevent_req_nterror(req, NT_STATUS_NO_SUCH_USER); - return tevent_req_post(req, ev); + tevent_schedule_immediate(im, + auth_ctx->event_ctx, + auth_check_password_async_trigger, + req); + return req; } static void auth_check_password_async_trigger(struct tevent_context *ev, @@ -336,11 +310,45 @@ static void auth_check_password_async_trigger(struct tevent_context *ev, struct auth_check_password_state *state = tevent_req_data(req, struct auth_check_password_state); NTSTATUS status; + struct auth_method_context *method; + + status = NT_STATUS_OK; + + for (method=state->auth_ctx->methods; method; method = method->next) { + + /* we fill in state->method here so debug messages in + the callers know which method failed */ + state->method = method; + + /* check if the module wants to check the password */ + status = method->ops->want_check(method, req, state->user_info); + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { + DEBUG(11,("auth_check_password_send: " + "%s had nothing to say\n", + method->ops->name)); + continue; + } + + if (tevent_req_nterror(req, status)) { + return; + } + + status = method->ops->check_password(method, + state, + state->user_info, + &state->server_info); + if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { + /* the backend has handled the request */ + break; + } + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { + /* don't expose the NT_STATUS_NOT_IMPLEMENTED + internals */ + status = NT_STATUS_NO_SUCH_USER; + } - status = state->method->ops->check_password(state->method, - state, - state->user_info, - &state->server_info); if (tevent_req_nterror(req, status)) { return; } |