From ced01514d025fb0804ee60380202b3b4ca5c9500 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 18 Dec 2021 10:40:36 +0100 Subject: [PATCH 1/5] auth/credentials: cli_credentials_set_ntlm_response() pass session_keys Otherwise cli_credentials_get_ntlm_response() will return session keys with a 0 length, which leads to errors in the NTLMSSP code. This wasn't noticed as cli_credentials_set_ntlm_response() has no callers yet, but that will change in the next commits. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14932 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit 0ef1254f4428ab83ab6c8ca5e3415a1a9e069c92) --- auth/credentials/credentials.h | 6 ++- auth/credentials/credentials_internal.h | 2 + auth/credentials/credentials_ntlm.c | 65 ++++++++++++++++++++++--- 3 files changed, 64 insertions(+), 9 deletions(-) diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index 1fff37e81542..e1648677fda4 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -218,8 +218,10 @@ bool cli_credentials_set_nt_hash(struct cli_credentials *cred, bool cli_credentials_set_old_nt_hash(struct cli_credentials *cred, const struct samr_Password *nt_hash); bool cli_credentials_set_ntlm_response(struct cli_credentials *cred, - const DATA_BLOB *lm_response, - const DATA_BLOB *nt_response, + const DATA_BLOB *lm_response, + const DATA_BLOB *lm_session_key, + const DATA_BLOB *nt_response, + const DATA_BLOB *nt_session_key, enum credentials_obtained obtained); int cli_credentials_set_keytab_name(struct cli_credentials *cred, struct loadparm_context *lp_ctx, diff --git a/auth/credentials/credentials_internal.h b/auth/credentials/credentials_internal.h index 3b86b7424481..ef37c9a6eec7 100644 --- a/auth/credentials/credentials_internal.h +++ b/auth/credentials/credentials_internal.h @@ -68,7 +68,9 @@ struct cli_credentials { /* Allows NTLM pass-though authentication */ DATA_BLOB lm_response; + DATA_BLOB lm_session_key; DATA_BLOB nt_response; + DATA_BLOB nt_session_key; struct ccache_container *ccache; struct gssapi_creds_container *client_gss_creds; diff --git a/auth/credentials/credentials_ntlm.c b/auth/credentials/credentials_ntlm.c index 1bec60e5dcef..5995835e9a1d 100644 --- a/auth/credentials/credentials_ntlm.c +++ b/auth/credentials/credentials_ntlm.c @@ -69,6 +69,14 @@ _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred return NT_STATUS_NO_MEMORY; } } + if (cred->nt_session_key.length != 0) { + session_key = data_blob_dup_talloc(frame, + cred->nt_session_key); + if (session_key.data == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + } if (cred->lm_response.length != 0) { lm_response = data_blob_dup_talloc(frame, cred->lm_response); @@ -77,6 +85,14 @@ _PUBLIC_ NTSTATUS cli_credentials_get_ntlm_response(struct cli_credentials *cred return NT_STATUS_NO_MEMORY; } } + if (cred->lm_session_key.length != 0) { + lm_session_key = data_blob_dup_talloc(frame, + cred->lm_session_key); + if (lm_session_key.data == NULL) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + } if (cred->lm_response.data == NULL) { *flags = *flags & ~CLI_CRED_LANMAN_AUTH; @@ -483,19 +499,54 @@ _PUBLIC_ bool cli_credentials_set_old_nt_hash(struct cli_credentials *cred, } _PUBLIC_ bool cli_credentials_set_ntlm_response(struct cli_credentials *cred, - const DATA_BLOB *lm_response, - const DATA_BLOB *nt_response, + const DATA_BLOB *lm_response, + const DATA_BLOB *lm_session_key, + const DATA_BLOB *nt_response, + const DATA_BLOB *nt_session_key, enum credentials_obtained obtained) { if (obtained >= cred->password_obtained) { cli_credentials_set_password(cred, NULL, obtained); - if (nt_response) { - cred->nt_response = data_blob_talloc(cred, nt_response->data, nt_response->length); - talloc_steal(cred, cred->nt_response.data); + + data_blob_clear_free(&cred->lm_response); + data_blob_clear_free(&cred->lm_session_key); + data_blob_clear_free(&cred->nt_response); + data_blob_clear_free(&cred->nt_session_key); + + if (lm_response != NULL && lm_response->length != 0) { + cred->lm_response = data_blob_talloc(cred, + lm_response->data, + lm_response->length); + if (cred->lm_response.data == NULL) { + return false; + } } - if (nt_response) { - cred->lm_response = data_blob_talloc(cred, lm_response->data, lm_response->length); + if (lm_session_key != NULL && lm_session_key->length != 0) { + cred->lm_session_key = data_blob_talloc(cred, + lm_session_key->data, + lm_session_key->length); + if (cred->lm_session_key.data == NULL) { + return false; + } } + + if (nt_response != NULL && nt_response->length != 0) { + cred->nt_response = data_blob_talloc(cred, + nt_response->data, + nt_response->length); + if (cred->nt_response.data == NULL) { + return false; + } + } + if (nt_session_key != NULL && nt_session_key->length != 0) { + cred->nt_session_key = data_blob_talloc(cred, + nt_session_key->data, + nt_session_key->length); + if (cred->nt_session_key.data == NULL) { + return false; + } + } + return true; } -- 2.25.1 From 022d344f41a4c526d7e7986e21c3dabe2b32b3cc Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Dec 2021 22:28:51 +0100 Subject: [PATCH 2/5] s4:torture/rpc: add test for invalid av_pair content in LogonSamLogonEx A netapp diag tool uses a NTLMv2_CLIENT_CHALLENGE with invalid bytes as av_pair blob. Which is supposed to be ignored by DCs. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14932 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (similar to commit e7e521fe9b947e553e2bf093e93f1d66ae9c95b9) --- selftest/knownfail.d/rpc.schannel | 14 ++ source4/torture/rpc/schannel.c | 209 ++++++++++++++++++++++++++++++ 2 files changed, 223 insertions(+) create mode 100644 selftest/knownfail.d/rpc.schannel diff --git a/selftest/knownfail.d/rpc.schannel b/selftest/knownfail.d/rpc.schannel new file mode 100644 index 000000000000..f0be92f30b31 --- /dev/null +++ b/selftest/knownfail.d/rpc.schannel @@ -0,0 +1,14 @@ +^samba3.rpc.schannel.schannel.nt4_dc +^samba3.rpc.schannel.schannel.ad_dc +^samba4.rpc.schannel.on.ncalrpc.with.seal,padcheck.schannel.ad_dc_default:local +^samba4.rpc.schannel.on.ncacn_np.with.seal,padcheck.schannel.ad_dc_default +^samba4.rpc.schannel.on.ncacn_ip_tcp.with.seal,padcheck.schannel.ad_dc_default +^samba4.rpc.schannel.on.ncalrpc.with.validate.schannel.ad_dc_default:local +^samba4.rpc.schannel.on.ncacn_np.with.validate.schannel.ad_dc_default +^samba4.rpc.schannel.on.ncacn_ip_tcp.with.validate.schannel.ad_dc_default +^samba4.rpc.schannel.on.ncalrpc.with.bigendian.schannel.ad_dc_default:local +^samba4.rpc.schannel.on.ncacn_np.with.bigendian.schannel.ad_dc_default +^samba4.rpc.schannel.on.ncacn_ip_tcp.with.bigendian.schannel.ad_dc_default +^samba4.rpc.schannel.with.seal,padcheck.schannel.ad_dc +^samba4.rpc.schannel.with.validate.schannel.ad_dc +^samba4.rpc.schannel.with.bigendian.schannel.ad_dc diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c index 08a5120b66d6..a3c1766cfa2b 100644 --- a/source4/torture/rpc/schannel.c +++ b/source4/torture/rpc/schannel.c @@ -241,6 +241,211 @@ bool test_netlogon_ex_ops(struct dcerpc_pipe *p, struct torture_context *tctx, return true; } +static bool test_netlogon_ex_bug14932(struct dcerpc_pipe *p, + struct torture_context *tctx, + struct cli_credentials *credentials, + struct netlogon_creds_CredentialState *creds) +{ + NTSTATUS status; + struct netr_LogonSamLogonEx r; + struct netr_NetworkInfo ninfo; + union netr_LogonLevel logon; + union netr_Validation validation; + uint8_t authoritative = 1; + uint32_t _flags = 0; + static const char *netapp_magic = + "\x01\x01\x00\x00\x00\x00\x00\x00" + "\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f" + "\xb8\x82\x3a\xf1\xb3\xdd\x08\x15" + "\x00\x00\x00\x00\x11\xa2\x08\x81" + "\x50\x38\x22\x78\x2b\x94\x47\xfe" + "\x54\x94\x7b\xff\x17\x27\x5a\xb4" + "\xf4\x18\xba\xdc\x2c\x38\xfd\x5b" + "\xfb\x0e\xc1\x85\x1e\xcc\x92\xbb" + "\x9b\xb1\xc4\xd5\x53\x14\xff\x8c" + "\x76\x49\xf5\x45\x90\x19\xa2"; + NTTIME timestamp = BVAL(netapp_magic, 8); + DATA_BLOB names_blob = data_blob_string_const(netapp_magic + 28); + DATA_BLOB chal, lm_resp, nt_resp; + int i; + int flags = CLI_CRED_NTLM_AUTH; + struct dcerpc_binding_handle *b = p->binding_handle; + struct netr_UserSessionKey key; + struct netr_LMSessionKey LMSessKey; + uint32_t validation_levels[] = { 2, 3 }; + struct netr_SamBaseInfo *base = NULL; + const char *crypto_alg = ""; + bool can_do_validation_6 = true; + enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE; + + flags |= CLI_CRED_NTLMv2_AUTH; + + cli_credentials_get_ntlm_username_domain(popt_get_cmdline_credentials(), + tctx, + &ninfo.identity_info.account_name.string, + &ninfo.identity_info.domain_name.string); + + generate_random_buffer(ninfo.challenge, + sizeof(ninfo.challenge)); + + chal = data_blob_const(ninfo.challenge, + sizeof(ninfo.challenge)); + + status = cli_credentials_get_ntlm_response( + popt_get_cmdline_credentials(), + tctx, + &flags, + chal, + ×tamp, + names_blob, + &lm_resp, &nt_resp, + NULL, NULL); + torture_assert_ntstatus_ok(tctx, status, + "cli_credentials_get_ntlm_response failed"); + + ninfo.lm.data = lm_resp.data; + ninfo.lm.length = lm_resp.length; + + ninfo.nt.data = nt_resp.data; + ninfo.nt.length = nt_resp.length; + + ninfo.identity_info.parameter_control = 0; + ninfo.identity_info.logon_id = 0; + ninfo.identity_info.workstation.string = cli_credentials_get_workstation(credentials); + + logon.network = &ninfo; + + r.in.server_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); + r.in.computer_name = cli_credentials_get_workstation(credentials); + r.in.logon_level = NetlogonNetworkInformation; + r.in.logon= &logon; + r.in.flags = &_flags; + r.out.validation = &validation; + r.out.authoritative = &authoritative; + r.out.flags = &_flags; + + /* + - retrieve level6 + - save usrsession and lmsession key + - retrieve level 2 + - calculate, compare + - retrieve level 3 + - calculate, compare + */ + + if (creds != NULL) { + if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { + crypto_alg = "AES"; + } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { + crypto_alg = "ARCFOUR"; + } + } + + dcerpc_binding_handle_auth_info(b, NULL, &auth_level); + if (auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { + r.in.validation_level = 6; + + torture_comment(tctx, + "Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n", + ninfo.identity_info.account_name.string, crypto_alg, + r.in.validation_level); + + torture_assert_ntstatus_ok(tctx, + dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r), + "LogonSamLogonEx failed"); + } else { + torture_comment(tctx, + "Skip auth_level[%u] Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n", + auth_level, ninfo.identity_info.account_name.string, crypto_alg, + r.in.validation_level); + r.out.result = NT_STATUS_INVALID_INFO_CLASS; + } + + if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_INVALID_INFO_CLASS)) { + can_do_validation_6 = false; + } else { + torture_assert_ntstatus_ok(tctx, r.out.result, + "LogonSamLogonEx failed"); + + key = r.out.validation->sam6->base.key; + LMSessKey = r.out.validation->sam6->base.LMSessKey; + + DEBUG(1,("unencrypted session keys from validation_level 6:\n")); + dump_data(1, r.out.validation->sam6->base.key.key, 16); + dump_data(1, r.out.validation->sam6->base.LMSessKey.key, 8); + } + + for (i=0; i < ARRAY_SIZE(validation_levels); i++) { + + r.in.validation_level = validation_levels[i]; + + torture_comment(tctx, + "Testing LogonSamLogonEx with name %s using %s and validation_level: %d\n", + ninfo.identity_info.account_name.string, crypto_alg, + r.in.validation_level); + + torture_assert_ntstatus_ok(tctx, + dcerpc_netr_LogonSamLogonEx_r(b, tctx, &r), + "LogonSamLogonEx failed"); + torture_assert_ntstatus_ok(tctx, r.out.result, + "LogonSamLogonEx failed"); + + if (creds == NULL) { + /* when this test is called without creds no point in + * testing the session keys */ + continue; + } + + switch (validation_levels[i]) { + case 2: + base = &r.out.validation->sam2->base; + break; + case 3: + base = &r.out.validation->sam3->base; + break; + default: + break; + } + + DEBUG(1,("encrypted keys validation_level %d:\n", + validation_levels[i])); + dump_data(1, base->key.key, 16); + dump_data(1, base->LMSessKey.key, 8); + + if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { + netlogon_creds_aes_decrypt(creds, base->key.key, 16); + netlogon_creds_aes_decrypt(creds, base->LMSessKey.key, 8); + } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { + netlogon_creds_arcfour_crypt(creds, base->key.key, 16); + netlogon_creds_arcfour_crypt(creds, base->LMSessKey.key, 8); + } + + DEBUG(1,("decryped keys validation_level %d\n", + validation_levels[i])); + + dump_data(1, base->key.key, 16); + dump_data(1, base->LMSessKey.key, 8); + + if (!can_do_validation_6) { + /* we cant compare against unencrypted keys */ + continue; + } + + torture_assert_mem_equal(tctx, + base->key.key, + key.key, + 16, + "unexpected user session key\n"); + torture_assert_mem_equal(tctx, + base->LMSessKey.key, + LMSessKey.key, + 8, + "unexpected LM session key\n"); + } + + return true; +} + /* do some samr ops using the schannel connection */ @@ -436,6 +641,10 @@ static bool test_schannel(struct torture_context *tctx, torture_assert(tctx, test_netlogon_ex_ops(p_netlogon, tctx, credentials, creds), "Failed to process schannel secured NETLOGON EX ops"); + /* regression test for https://bugzilla.samba.org/show_bug.cgi?id=14932 */ + torture_assert(tctx, test_netlogon_ex_bug14932(p_netlogon, tctx, credentials, creds), + "Failed to process schannel secured NETLOGON EX for BUG 14932"); + /* we *MUST* use ncacn_np for openpolicy etc. */ transport = dcerpc_binding_get_transport(b); status = dcerpc_binding_set_transport(b, NCACN_NP); -- 2.25.1 From 7d9e35acac86147ab9ea925e149557e06cbdd185 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Dec 2021 17:25:06 +0100 Subject: [PATCH 3/5] libcli/auth: let NTLMv2_RESPONSE_verify_netlogon_creds ignore BUFFER_TOO_SMALL Windows doesn't complain about invalid av_pair blobs, we need to do the same. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14932 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit f123c1a171e59113feb688523b499dab0b824528) --- libcli/auth/smbencrypt.c | 26 +++++++++++++++++++++----- selftest/knownfail.d/rpc.schannel | 14 -------------- 2 files changed, 21 insertions(+), 19 deletions(-) delete mode 100644 selftest/knownfail.d/rpc.schannel diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c index 468374699f7c..ce7c32279b90 100644 --- a/libcli/auth/smbencrypt.c +++ b/libcli/auth/smbencrypt.c @@ -682,11 +682,27 @@ NTSTATUS NTLMv2_RESPONSE_verify_netlogon_creds(const char *account_name, if (!NDR_ERR_CODE_IS_SUCCESS(err)) { NTSTATUS status; status = ndr_map_error2ntstatus(err); - DEBUG(2,("Failed to parse NTLMv2_RESPONSE " - "length %u - %s - %s\n", - (unsigned)response.length, - ndr_map_error2string(err), - nt_errstr(status))); + if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) { + /* + * We are supposed to ignore invalid buffers, + * see https://bugzilla.samba.org/show_bug.cgi?id=14932 + */ + status = NT_STATUS_OK; + } + DEBUG(2,("%s: Failed to parse NTLMv2_RESPONSE length=%u " + "for user[%s\\%s] against SEC_CHAN(%u)[%s/%s] " + "in workgroup[%s] - %s %s %s\n", + __func__, + (unsigned)response.length, + account_domain, + account_name, + creds->secure_channel_type, + creds->computer_name, + creds->account_name, + workgroup, + ndr_map_error2string(err), + NT_STATUS_IS_OK(status) ? "(ignoring) =>" : "=>", + nt_errstr(status))); dump_data(2, response.data, response.length); TALLOC_FREE(frame); return status; diff --git a/selftest/knownfail.d/rpc.schannel b/selftest/knownfail.d/rpc.schannel deleted file mode 100644 index f0be92f30b31..000000000000 --- a/selftest/knownfail.d/rpc.schannel +++ /dev/null @@ -1,14 +0,0 @@ -^samba3.rpc.schannel.schannel.nt4_dc -^samba3.rpc.schannel.schannel.ad_dc -^samba4.rpc.schannel.on.ncalrpc.with.seal,padcheck.schannel.ad_dc_default:local -^samba4.rpc.schannel.on.ncacn_np.with.seal,padcheck.schannel.ad_dc_default -^samba4.rpc.schannel.on.ncacn_ip_tcp.with.seal,padcheck.schannel.ad_dc_default -^samba4.rpc.schannel.on.ncalrpc.with.validate.schannel.ad_dc_default:local -^samba4.rpc.schannel.on.ncacn_np.with.validate.schannel.ad_dc_default -^samba4.rpc.schannel.on.ncacn_ip_tcp.with.validate.schannel.ad_dc_default -^samba4.rpc.schannel.on.ncalrpc.with.bigendian.schannel.ad_dc_default:local -^samba4.rpc.schannel.on.ncacn_np.with.bigendian.schannel.ad_dc_default -^samba4.rpc.schannel.on.ncacn_ip_tcp.with.bigendian.schannel.ad_dc_default -^samba4.rpc.schannel.with.seal,padcheck.schannel.ad_dc -^samba4.rpc.schannel.with.validate.schannel.ad_dc -^samba4.rpc.schannel.with.bigendian.schannel.ad_dc -- 2.25.1 From d0bd4406bbddceec0155fc724dbbaa111d3337a0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 15 Dec 2021 17:25:06 +0100 Subject: [PATCH 4/5] libcli/auth: let NTLMv2_RESPONSE_verify_netlogon_creds ignore invalid netapp requests We should avoid spamming the logs with wellknown messages like: ndr_pull_error(Buffer Size Error): Pull bytes 39016 They just confuse admins (and developers). BUG: https://bugzilla.samba.org/show_bug.cgi?id=14932 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison (cherry picked from commit 23bedd69b2db0dd6de98ed147eddcba799694de7) --- libcli/auth/smbencrypt.c | 63 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/libcli/auth/smbencrypt.c b/libcli/auth/smbencrypt.c index ce7c32279b90..fe20fe4e2a3c 100644 --- a/libcli/auth/smbencrypt.c +++ b/libcli/auth/smbencrypt.c @@ -675,6 +675,69 @@ NTSTATUS NTLMv2_RESPONSE_verify_netlogon_creds(const char *account_name, return NT_STATUS_OK; } + if (response.length == 95) { + /* + * ndr_pull_NTLMv2_RESPONSE() fails on this strange blob, + * because the AvPairs content is not valid + * as AvLen of the first pair is 33032 (0x8108). + * + * I saw a single machine sending the following 3 times + * in a row, but I'm not sure if everything is static. + * + * Note this is NTLMv2_CLIENT_CHALLENGE only, not + * the full NTLMv2_RESPONSE (which has Response of 16 bytes + * before the NTLMv2_CLIENT_CHALLENGE). + * + * Note this code only prevents + * ndr_pull_error(Buffer Size Error): Pull bytes 39016 + * debug message for a known case, the actual + * bug is also handled below in a generic way to + * map NT_STATUS_BUFFER_TOO_SMALL to NT_STATUS_OK. + * + * See https://bugzilla.samba.org/show_bug.cgi?id=14932 + */ + static const char *netapp_magic = + "\x01\x01\x00\x00\x00\x00\x00\x00" + "\x3f\x3f\x3f\x3f\x3f\x3f\x3f\x3f" + "\xb8\x82\x3a\xf1\xb3\xdd\x08\x15" + "\x00\x00\x00\x00\x11\xa2\x08\x81" + "\x50\x38\x22\x78\x2b\x94\x47\xfe" + "\x54\x94\x7b\xff\x17\x27\x5a\xb4" + "\xf4\x18\xba\xdc\x2c\x38\xfd\x5b" + "\xfb\x0e\xc1\x85\x1e\xcc\x92\xbb" + "\x9b\xb1\xc4\xd5\x53\x14\xff\x8c" + "\x76\x49\xf5\x45\x90\x19\xa2"; + /* + * First we check the initial bytes + * and the 0x3F timestamp. + */ + cmp = memcmp(response.data + 16, + netapp_magic, + 16); + if (cmp == 0) { + /* + * Then check everything after the + * client challenge + */ + cmp = memcmp(response.data + 40, + netapp_magic + 24, + response.length - 40); + if (cmp == 0) { + DBG_DEBUG("Invalid NETAPP NTLMv2_RESPONSE " + "for user[%s\\%s] against " + "SEC_CHAN(%u)[%s/%s] " + "in workgroup[%s]\n", + account_domain, + account_name, + creds->secure_channel_type, + creds->computer_name, + creds->account_name, + workgroup); + return NT_STATUS_OK; + } + } + } + frame = talloc_stackframe(); err = ndr_pull_struct_blob(&response, frame, &v2_resp, -- 2.25.1 From eeb5cb3df37cc4f46a15c47b4e84e108093cbaae Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Dec 2021 23:32:28 +0100 Subject: [PATCH 5/5] auth/ntlmssp: make sure we return INVALID_PARAMETER for NTLMv2_RESPONSE parsing errors BUG: https://bugzilla.samba.org/show_bug.cgi?id=14932 Signed-off-by: Stefan Metzmacher Reviewed-by: Jeremy Allison Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Tue Jan 4 20:57:41 UTC 2022 on sn-devel-184 (cherry picked from commit dd9886100514941aa16af8566faf41501b601a44) --- auth/ntlmssp/ntlmssp_server.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c index 939aa0ef4aa5..ce78af1d32d0 100644 --- a/auth/ntlmssp/ntlmssp_server.c +++ b/auth/ntlmssp/ntlmssp_server.c @@ -532,6 +532,14 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_security *gensec_security, (ndr_pull_flags_fn_t)ndr_pull_NTLMv2_RESPONSE); if (!NDR_ERR_CODE_IS_SUCCESS(err)) { nt_status = ndr_map_error2ntstatus(err); + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_BUFFER_TOO_SMALL)) { + /* + * Note that invalid blobs should result in + * INVALID_PARAMETER, as demonstrated by + * smb2.session.ntlmssp_bug14932 + */ + nt_status = NT_STATUS_INVALID_PARAMETER; + } DEBUG(1,("%s: failed to parse NTLMv2_RESPONSE of length %zu for " "user=[%s] domain=[%s] workstation=[%s] - %s %s\n", __func__, ntlmssp_state->nt_resp.length, -- 2.25.1