From 4af89d534d17744c54ea2408190a25c27cec18ea Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Mar 2017 11:16:36 +0100 Subject: auth4: let auth_check_password* return pauthoritative BUG: https://bugzilla.samba.org/show_bug.cgi?id=2976 Signed-off-by: Stefan Metzmacher Reviewed-by: Andrew Bartlett --- source3/auth/auth_samba4.c | 11 +++++++-- source4/auth/auth.h | 6 +++-- source4/auth/ntlm/auth.c | 32 ++++++++++++++++----------- source4/auth/ntlm/auth_simple.c | 4 +++- source4/rpc_server/netlogon/dcerpc_netlogon.c | 4 ++-- source4/smb_server/smb/sesssetup.c | 9 +++++--- 6 files changed, 43 insertions(+), 23 deletions(-) diff --git a/source3/auth/auth_samba4.c b/source3/auth/auth_samba4.c index a0d6afd32d4..138c6cd4f09 100644 --- a/source3/auth/auth_samba4.c +++ b/source3/auth/auth_samba4.c @@ -118,6 +118,7 @@ static NTSTATUS check_samba4_security(const struct auth_context *auth_context, NTSTATUS nt_status; struct auth_user_info_dc *user_info_dc; struct auth4_context *auth4_context; + uint8_t authoritative = 0; nt_status = make_auth4_context_s4(auth_context, mem_ctx, &auth4_context); if (!NT_STATUS_IS_OK(nt_status)) { @@ -132,13 +133,19 @@ static NTSTATUS check_samba4_security(const struct auth_context *auth_context, return nt_status; } - nt_status = auth_check_password(auth4_context, auth4_context, user_info, &user_info_dc); + nt_status = auth_check_password(auth4_context, auth4_context, user_info, + &user_info_dc, &authoritative); if (!NT_STATUS_IS_OK(nt_status)) { + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) && + authoritative == 0) + { + nt_status = NT_STATUS_NOT_IMPLEMENTED; + } TALLOC_FREE(auth4_context); TALLOC_FREE(frame); return nt_status; } - + nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx, user_info_dc, &info3); diff --git a/source4/auth/auth.h b/source4/auth/auth.h index 95aacfe8eef..7358f40b70d 100644 --- a/source4/auth/auth.h +++ b/source4/auth/auth.h @@ -153,7 +153,8 @@ NTSTATUS auth_context_create_for_netlogon(TALLOC_CTX *mem_ctx, NTSTATUS auth_check_password(struct auth4_context *auth_ctx, TALLOC_CTX *mem_ctx, const struct auth_usersupplied_info *user_info, - struct auth_user_info_dc **user_info_dc); + struct auth_user_info_dc **user_info_dc, + uint8_t *pauthoritative); NTSTATUS auth4_init(void); NTSTATUS auth_register(const struct auth_operations *ops); NTSTATUS server_service_auth_init(void); @@ -173,7 +174,8 @@ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, const struct auth_usersupplied_info *user_info); NTSTATUS auth_check_password_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct auth_user_info_dc **user_info_dc); + struct auth_user_info_dc **user_info_dc, + uint8_t *pauthoritative); bool auth_challenge_may_be_modified(struct auth4_context *auth_ctx); NTSTATUS auth_context_set_challenge(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by); diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c index 926bf48e192..12e26f4c1fa 100644 --- a/source4/auth/ntlm/auth.c +++ b/source4/auth/ntlm/auth.c @@ -155,7 +155,8 @@ static NTSTATUS auth_generate_session_info_principal(struct auth4_context *auth_ _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx, TALLOC_CTX *mem_ctx, const struct auth_usersupplied_info *user_info, - struct auth_user_info_dc **user_info_dc) + struct auth_user_info_dc **user_info_dc, + uint8_t *pauthoritative) { struct tevent_req *subreq; struct tevent_context *ev; @@ -178,7 +179,8 @@ _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx, return NT_STATUS_INTERNAL_ERROR; } - status = auth_check_password_recv(subreq, mem_ctx, user_info_dc); + status = auth_check_password_recv(subreq, mem_ctx, + user_info_dc, pauthoritative); TALLOC_FREE(subreq); return status; @@ -192,9 +194,10 @@ static NTSTATUS auth_check_password_wrapper(struct auth4_context *auth_ctx, { struct auth_user_info_dc *user_info_dc; NTSTATUS status; + uint8_t authoritative = 0; status = auth_check_password(auth_ctx, mem_ctx, user_info, - &user_info_dc); + &user_info_dc, &authoritative); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -225,6 +228,7 @@ struct auth_check_password_state { const struct auth_usersupplied_info *user_info; struct auth_user_info_dc *user_info_dc; struct auth_method_context *method; + uint8_t authoritative; }; static void auth_check_password_async_trigger(struct tevent_context *ev, @@ -279,6 +283,10 @@ _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx, return NULL; } + /* + * We are authoritative by default. + */ + state->authoritative = 1; state->auth_ctx = auth_ctx; state->user_info = user_info; @@ -386,13 +394,8 @@ static void auth_check_password_async_trigger(struct tevent_context *ev, } if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) { - if (!(state->user_info->flags & USER_INFO_LOCAL_SAM_ONLY)) { - /* don't expose the NT_STATUS_NOT_IMPLEMENTED - * internals, except when the caller is only probing - * one method, as they may do the fallback - */ - status = NT_STATUS_NO_SUCH_USER; - } + state->authoritative = 0; + status = NT_STATUS_NO_SUCH_USER; } if (tevent_req_nterror(req, status)) { @@ -424,20 +427,23 @@ static void auth_check_password_async_trigger(struct tevent_context *ev, _PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct auth_user_info_dc **user_info_dc) + struct auth_user_info_dc **user_info_dc, + uint8_t *pauthoritative) { struct auth_check_password_state *state = tevent_req_data(req, struct auth_check_password_state); NTSTATUS status; + *pauthoritative = state->authoritative; + if (tevent_req_is_nterror(req, &status)) { DEBUG(2,("auth_check_password_recv: " "%s authentication for user [%s\\%s] " - "FAILED with error %s\n", + "FAILED with error %s, authoritative=%u\n", (state->method ? state->method->ops->name : "NO_METHOD"), state->user_info->mapped.domain_name, state->user_info->mapped.account_name, - nt_errstr(status))); + nt_errstr(status), state->authoritative)); tevent_req_received(req); return status; } diff --git a/source4/auth/ntlm/auth_simple.c b/source4/auth/ntlm/auth_simple.c index f6dd9d0e6be..be2ff5e1690 100644 --- a/source4/auth/ntlm/auth_simple.c +++ b/source4/auth/ntlm/auth_simple.c @@ -42,6 +42,7 @@ _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, struct auth_usersupplied_info *user_info; struct auth_user_info_dc *user_info_dc; NTSTATUS nt_status; + uint8_t authoritative = 0; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { @@ -83,7 +84,8 @@ _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx, MSV1_0_CLEARTEXT_PASSWORD_ALLOWED | MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED; - nt_status = auth_check_password(auth_context, tmp_ctx, user_info, &user_info_dc); + nt_status = auth_check_password(auth_context, tmp_ctx, user_info, + &user_info_dc, &authoritative); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(tmp_ctx); return nt_status; diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index 332afd3b463..0f59a96cef6 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -982,8 +982,8 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal return NT_STATUS_INVALID_PARAMETER; } - nt_status = auth_check_password(auth_context, mem_ctx, user_info, &user_info_dc); - /* TODO: set *r->out.authoritative = 0 on specific errors */ + nt_status = auth_check_password(auth_context, mem_ctx, user_info, + &user_info_dc, r->out.authoritative); NT_STATUS_NOT_OK_RETURN(nt_status); switch (r->in.validation_level) { diff --git a/source4/smb_server/smb/sesssetup.c b/source4/smb_server/smb/sesssetup.c index e06853afcd4..e3bfcb3083d 100644 --- a/source4/smb_server/smb/sesssetup.c +++ b/source4/smb_server/smb/sesssetup.c @@ -72,9 +72,11 @@ static void sesssetup_old_send(struct tevent_req *subreq) struct auth_session_info *session_info; struct smbsrv_session *smb_sess; NTSTATUS status; + uint8_t authoritative = 0; uint32_t flags; - status = auth_check_password_recv(subreq, req, &user_info_dc); + status = auth_check_password_recv(subreq, req, &user_info_dc, + &authoritative); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) goto failed; @@ -202,11 +204,12 @@ static void sesssetup_nt1_send(struct tevent_req *subreq) struct auth_user_info_dc *user_info_dc = NULL; struct auth_session_info *session_info; struct smbsrv_session *smb_sess; - + uint8_t authoritative = 0; uint32_t flags; NTSTATUS status; - status = auth_check_password_recv(subreq, req, &user_info_dc); + status = auth_check_password_recv(subreq, req, &user_info_dc, + &authoritative); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) goto failed; -- cgit v1.2.1