From 0809696dbf3f551c0fbd37154025053b55fa07ee Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 14 Dec 2009 20:32:47 +1100 Subject: [PATCH] s4:auth Change 'get_challenge' API to be more like Samba3 It is just easier to fill in the known to be 8 byte challenge than stuff about with allocated pointers. Andrew Bartlett --- source4/auth/auth.h | 6 +++--- source4/auth/ntlm/auth.c | 25 ++++++++----------------- source4/auth/ntlm/auth_proto.h | 2 +- source4/auth/ntlm/auth_server.c | 7 +++++-- source4/auth/ntlm/auth_util.c | 12 ++++++------ source4/auth/ntlm/auth_winbind.c | 6 +++--- source4/auth/ntlmssp/ntlmssp_server.c | 7 +++++-- source4/smb_server/smb/negprot.c | 5 +---- 8 files changed, 32 insertions(+), 38 deletions(-) diff --git a/source4/auth/auth.h b/source4/auth/auth.h index c31ed2f5fdc..c625c87f39a 100644 --- a/source4/auth/auth.h +++ b/source4/auth/auth.h @@ -135,7 +135,7 @@ struct auth_operations { * security=server, and makes a number of compromises to allow * that. It is not compatible with being a PDC. */ - NTSTATUS (*get_challenge)(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *challenge); + NTSTATUS (*get_challenge)(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]); /* Given the user supplied info, check if this backend want to handle the password checking */ @@ -190,7 +190,7 @@ struct auth_context { const struct auth_usersupplied_info *user_info, struct auth_serversupplied_info **server_info); - NTSTATUS (*get_challenge)(struct auth_context *auth_ctx, const uint8_t **_chal); + NTSTATUS (*get_challenge)(struct auth_context *auth_ctx, uint8_t chal[8]); bool (*challenge_may_be_modified)(struct auth_context *auth_ctx); @@ -226,7 +226,7 @@ struct ldb_context; struct ldb_dn; struct gensec_security; -NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, const uint8_t **_chal); +NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, uint8_t chal[8]); NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx, uint32_t logon_parameters, diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c index 5520c9d01f1..d0c8ed3a682 100644 --- a/source4/auth/ntlm/auth.c +++ b/source4/auth/ntlm/auth.c @@ -51,42 +51,34 @@ bool auth_challenge_may_be_modified(struct auth_context *auth_ctx) Try to get a challenge out of the various authentication modules. Returns a const char of length 8 bytes. ****************************************************************************/ -_PUBLIC_ NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, const uint8_t **_chal) +_PUBLIC_ NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, uint8_t chal[8]) { NTSTATUS nt_status; struct auth_method_context *method; - if (auth_ctx->challenge.data.length) { + if (auth_ctx->challenge.data.length == 8) { DEBUG(5, ("auth_get_challenge: returning previous challenge by module %s (normal)\n", auth_ctx->challenge.set_by)); - *_chal = auth_ctx->challenge.data.data; + memcpy(chal, auth_ctx->challenge.data.data, 8); return NT_STATUS_OK; } for (method = auth_ctx->methods; method; method = method->next) { - DATA_BLOB challenge = data_blob(NULL,0); - - nt_status = method->ops->get_challenge(method, auth_ctx, &challenge); + nt_status = method->ops->get_challenge(method, auth_ctx, chal); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) { continue; } NT_STATUS_NOT_OK_RETURN(nt_status); - if (challenge.length != 8) { - DEBUG(0, ("auth_get_challenge: invalid challenge (length %u) by mothod [%s]\n", - (unsigned)challenge.length, method->ops->name)); - return NT_STATUS_INTERNAL_ERROR; - } - - auth_ctx->challenge.data = challenge; + auth_ctx->challenge.data = data_blob_talloc(auth_ctx, chal, 8); + NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.data.data); auth_ctx->challenge.set_by = method->ops->name; break; } if (!auth_ctx->challenge.set_by) { - uint8_t chal[8]; generate_random_buffer(chal, 8); auth_ctx->challenge.data = data_blob_talloc(auth_ctx, chal, 8); @@ -99,7 +91,6 @@ _PUBLIC_ NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, const uint8_ DEBUG(10,("auth_get_challenge: challenge set by %s\n", auth_ctx->challenge.set_by)); - *_chal = auth_ctx->challenge.data.data; return NT_STATUS_OK; } @@ -256,7 +247,7 @@ _PUBLIC_ void auth_check_password_send(struct auth_context *auth_ctx, /* if all the modules say 'not for me' this is reasonable */ NTSTATUS nt_status; struct auth_method_context *method; - const uint8_t *challenge; + uint8_t chal[8]; struct auth_usersupplied_info *user_info_tmp; struct auth_check_password_request *req = NULL; @@ -283,7 +274,7 @@ _PUBLIC_ void auth_check_password_send(struct auth_context *auth_ctx, DEBUGADD(3,("auth_check_password_send: mapped user is: [%s]\\[%s]@[%s]\n", user_info->mapped.domain_name, user_info->mapped.account_name, user_info->workstation_name)); - nt_status = auth_get_challenge(auth_ctx, &challenge); + nt_status = auth_get_challenge(auth_ctx, chal); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("auth_check_password_send: Invalid challenge (length %u) stored for this auth context set_by %s - cannot continue: %s\n", (unsigned)auth_ctx->challenge.data.length, auth_ctx->challenge.set_by, nt_errstr(nt_status))); diff --git a/source4/auth/ntlm/auth_proto.h b/source4/auth/ntlm/auth_proto.h index 572c1a4ca7d..5e8c725ea0a 100644 --- a/source4/auth/ntlm/auth_proto.h +++ b/source4/auth/ntlm/auth_proto.h @@ -23,7 +23,7 @@ NTSTATUS server_service_auth_init(void); /* The following definitions come from auth/ntlm/auth_util.c */ -NTSTATUS auth_get_challenge_not_implemented(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *challenge); +NTSTATUS auth_get_challenge_not_implemented(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]); /**************************************************************************** Create an auth_usersupplied_data structure after appropriate mapping. diff --git a/source4/auth/ntlm/auth_server.c b/source4/auth/ntlm/auth_server.c index 12849aa4202..ae7b7dd3a89 100644 --- a/source4/auth/ntlm/auth_server.c +++ b/source4/auth/ntlm/auth_server.c @@ -40,7 +40,7 @@ static NTSTATUS server_want_check(struct auth_method_context *ctx, /** * The challenge from the target server, when operating in security=server **/ -static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *_blob) +static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]) { struct smb_composite_connect io; struct smbcli_options smb_options; @@ -88,7 +88,10 @@ static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX ctx->auth_ctx->event_ctx); NT_STATUS_NOT_OK_RETURN(status); - *_blob = io.out.tree->session->transport->negotiate.secblob; + if (io.out.tree->session->transport->negotiate.secblob.length != 8) { + return NT_STATUS_INTERNAL_ERROR; + } + memcpy(chal, io.out.tree->session->transport->negotiate.secblob.data, 8); ctx->private_data = talloc_steal(ctx, io.out.tree->session); return NT_STATUS_OK; } diff --git a/source4/auth/ntlm/auth_util.c b/source4/auth/ntlm/auth_util.c index 5543cbebeac..92df0bfe802 100644 --- a/source4/auth/ntlm/auth_util.c +++ b/source4/auth/ntlm/auth_util.c @@ -29,7 +29,7 @@ /* this default function can be used by mostly all backends * which don't want to set a challenge */ -NTSTATUS auth_get_challenge_not_implemented(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *challenge) +NTSTATUS auth_get_challenge_not_implemented(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]) { /* we don't want to set a challenge */ return NT_STATUS_NOT_IMPLEMENTED; @@ -122,7 +122,7 @@ NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_contex } case AUTH_PASSWORD_HASH: { - const uint8_t *challenge; + uint8_t chal[8]; DATA_BLOB chall_blob; user_info_temp = talloc(mem_ctx, struct auth_usersupplied_info); if (!user_info_temp) { @@ -134,12 +134,12 @@ NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_contex *user_info_temp = *user_info_in; user_info_temp->mapped_state = to_state; - nt_status = auth_get_challenge(auth_context, &challenge); + nt_status = auth_get_challenge(auth_context, chal); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } - chall_blob = data_blob_talloc(mem_ctx, challenge, 8); + chall_blob = data_blob_talloc(mem_ctx, chal, 8); if (lp_client_ntlmv2_auth(auth_context->lp_ctx)) { DATA_BLOB names_blob = NTLMv2_generate_names_blob(mem_ctx, lp_netbios_name(auth_context->lp_ctx), lp_workgroup(auth_context->lp_ctx)); DATA_BLOB lmv2_response, ntlmv2_response, lmv2_session_key, ntlmv2_session_key; @@ -162,12 +162,12 @@ NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth_context *auth_contex data_blob_free(&ntlmv2_session_key); } else { DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24); - SMBOWFencrypt(user_info_in->password.hash.nt->hash, challenge, blob.data); + SMBOWFencrypt(user_info_in->password.hash.nt->hash, chal, blob.data); user_info_temp->password.response.nt = blob; if (lp_client_lanman_auth(auth_context->lp_ctx) && user_info_in->password.hash.lanman) { DATA_BLOB lm_blob = data_blob_talloc(mem_ctx, NULL, 24); - SMBOWFencrypt(user_info_in->password.hash.lanman->hash, challenge, blob.data); + SMBOWFencrypt(user_info_in->password.hash.lanman->hash, chal, blob.data); user_info_temp->password.response.lanman = lm_blob; } else { /* if not sending the LM password, send the NT password twice */ diff --git a/source4/auth/ntlm/auth_winbind.c b/source4/auth/ntlm/auth_winbind.c index 568226dd879..173a8953906 100644 --- a/source4/auth/ntlm/auth_winbind.c +++ b/source4/auth/ntlm/auth_winbind.c @@ -271,7 +271,7 @@ static NTSTATUS winbind_check_password(struct auth_method_context *ctx, s->req.in.logon.password= password_info; } else { struct netr_NetworkInfo *network_info; - const uint8_t *challenge; + uint8_t chal[8]; status = encrypt_user_info(s, ctx->auth_ctx, AUTH_PASSWORD_RESPONSE, user_info, &user_info_new); @@ -281,10 +281,10 @@ static NTSTATUS winbind_check_password(struct auth_method_context *ctx, network_info = talloc(s, struct netr_NetworkInfo); NT_STATUS_HAVE_NO_MEMORY(network_info); - status = auth_get_challenge(ctx->auth_ctx, &challenge); + status = auth_get_challenge(ctx->auth_ctx, chal); NT_STATUS_NOT_OK_RETURN(status); - memcpy(network_info->challenge, challenge, sizeof(network_info->challenge)); + memcpy(network_info->challenge, chal, sizeof(network_info->challenge)); network_info->nt.length = user_info->password.response.nt.length; network_info->nt.data = user_info->password.response.nt.data; diff --git a/source4/auth/ntlmssp/ntlmssp_server.c b/source4/auth/ntlmssp/ntlmssp_server.c index 94de920772d..281ffbfa6de 100644 --- a/source4/auth/ntlmssp/ntlmssp_server.c +++ b/source4/auth/ntlmssp/ntlmssp_server.c @@ -600,9 +600,12 @@ NTSTATUS ntlmssp_server_auth(struct gensec_security *gensec_security, static const uint8_t *auth_ntlmssp_get_challenge(const struct gensec_ntlmssp_state *gensec_ntlmssp_state) { NTSTATUS status; - const uint8_t *chal; + uint8_t *chal = talloc_array(gensec_ntlmssp_state, uint8_t, 8); + if (!chal) { + return NULL; + } - status = gensec_ntlmssp_state->auth_context->get_challenge(gensec_ntlmssp_state->auth_context, &chal); + status = gensec_ntlmssp_state->auth_context->get_challenge(gensec_ntlmssp_state->auth_context, chal); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("auth_ntlmssp_get_challenge: failed to get challenge: %s\n", nt_errstr(status))); diff --git a/source4/smb_server/smb/negprot.c b/source4/smb_server/smb/negprot.c index ab763e39c36..fe6cd68f6e6 100644 --- a/source4/smb_server/smb/negprot.c +++ b/source4/smb_server/smb/negprot.c @@ -33,7 +33,6 @@ static NTSTATUS get_challenge(struct smbsrv_connection *smb_conn, uint8_t buff[8]) { NTSTATUS nt_status; - const uint8_t *challenge; /* muliple negprots are not premitted */ if (smb_conn->negotiate.auth_context) { @@ -53,14 +52,12 @@ static NTSTATUS get_challenge(struct smbsrv_connection *smb_conn, uint8_t buff[8 return nt_status; } - nt_status = auth_get_challenge(smb_conn->negotiate.auth_context, &challenge); + nt_status = auth_get_challenge(smb_conn->negotiate.auth_context, buff); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("auth_get_challenge() returned %s", nt_errstr(nt_status))); return nt_status; } - memcpy(buff, challenge, 8); - return NT_STATUS_OK; } -- 2.34.1