From c29db055a7052c25c9d4d1adfe1afff5c32f65ec Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 17 Jun 2017 00:05:22 +0200 Subject: [PATCH] s4:auth/ntlm: allow auth_operations to specify check_password_send/recv() This prepares real async handling in the backends. Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Tue Jun 27 21:09:08 CEST 2017 on sn-devel-144 --- source4/auth/auth.h | 9 ++++++++- source4/auth/ntlm/auth.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/source4/auth/auth.h b/source4/auth/auth.h index 2dc0d8c7997..f88489b6f60 100644 --- a/source4/auth/auth.h +++ b/source4/auth/auth.h @@ -65,7 +65,14 @@ struct auth_operations { const struct auth_usersupplied_info *user_info, struct auth_user_info_dc **interim_info, bool *authoritative); - + struct tevent_req *(*check_password_send)(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct auth_method_context *ctx, + const struct auth_usersupplied_info *user_info); + NTSTATUS (*check_password_recv)(struct tevent_req *subreq, + TALLOC_CTX *mem_ctx, + struct auth_user_info_dc **interim_info, + bool *authoritative); /* Lookup a 'session info interim' return based only on the principal or DN */ NTSTATUS (*get_user_info_dc_principal)(TALLOC_CTX *mem_ctx, diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c index 285edd92ecc..0e76348e385 100644 --- a/source4/auth/ntlm/auth.c +++ b/source4/auth/ntlm/auth.c @@ -187,6 +187,7 @@ _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx, } struct auth_check_password_state { + struct tevent_context *ev; struct auth4_context *auth_ctx; const struct auth_usersupplied_info *user_info; struct auth_user_info_dc *user_info_dc; @@ -247,6 +248,7 @@ _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, /* * We are authoritative by default. */ + state->ev = ev; state->auth_ctx = auth_ctx; state->user_info = user_info; state->authoritative = 1; @@ -319,6 +321,8 @@ _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, return req; } +static void auth_check_password_done(struct tevent_req *subreq); + static void auth_check_password_next(struct tevent_req *req) { struct auth_check_password_state *state = @@ -349,6 +353,20 @@ static void auth_check_password_next(struct tevent_req *req) return; } + if (state->method->ops->check_password_send != NULL) { + subreq = state->method->ops->check_password_send(state, + state->ev, + state->method, + state->user_info); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, + auth_check_password_done, + req); + return; + } + if (state->method->ops->check_password == NULL) { tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); return; @@ -378,6 +396,40 @@ static void auth_check_password_next(struct tevent_req *req) tevent_req_done(req); } +static void auth_check_password_done(struct tevent_req *subreq) +{ + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + struct auth_check_password_state *state = + tevent_req_data(req, + struct auth_check_password_state); + bool authoritative = true; + NTSTATUS status; + + status = state->method->ops->check_password_recv(subreq, state, + &state->user_info_dc, + &authoritative); + TALLOC_FREE(subreq); + if (!authoritative || + NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { + DEBUG(11,("auth_check_password_send: " + "%s passes to the next method\n", + state->method->ops->name)); + state->method = state->method->next; + auth_check_password_next(req); + return; + } + + /* the backend has handled the request */ + + if (tevent_req_nterror(req, status)) { + return; + } + + tevent_req_done(req); +} + /** * Check a user's Plaintext, LM or NTLM password. * async receive function -- 2.11.4.GIT