From 6e0fa4cf34ffb9a3f453269f8bd19b4aaf4be030 Mon Sep 17 00:00:00 2001 From: Isaac Boukris Date: Wed, 20 Nov 2019 15:28:39 +0100 Subject: [PATCH 182/187] smbdes: convert E_old_pw_hash to use gnutls Signed-off-by: Isaac Boukris Reviewed-by: Andrew Bartlett (cherry picked from commit dce944e8a1119034f184336f6b71a28080152a0a) --- libcli/auth/proto.h | 2 +- libcli/auth/smbdes.c | 12 +++- libcli/auth/tests/test_gnutls.c | 4 +- source3/libsmb/clirap.c | 6 +- source3/rpc_client/cli_samr.c | 66 +++++++++++++++++--- source3/rpc_server/samr/srv_samr_chgpasswd.c | 18 +++++- source3/utils/ntlm_auth.c | 14 ++++- source4/libnet/libnet_passwd.c | 30 +++++++-- source4/rpc_server/samr/samr_password.c | 16 ++++- 9 files changed, 140 insertions(+), 28 deletions(-) diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h index 2ea4eca822a..5e88d7527fd 100644 --- a/libcli/auth/proto.h +++ b/libcli/auth/proto.h @@ -225,7 +225,7 @@ int des_crypt56_gnutls(uint8_t out[8], const uint8_t in[8], const uint8_t key[7] enum samba_gnutls_direction encrypt); int E_P16(const uint8_t *p14,uint8_t *p16); int E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24); -void E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out); +int E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out); int des_crypt128(uint8_t out[8], const uint8_t in[8], const uint8_t key[16]); void des_crypt112(uint8_t out[8], const uint8_t in[8], const uint8_t key[14], int forw); void des_crypt112_16(uint8_t out[16], const uint8_t in[16], const uint8_t key[14], int forw); diff --git a/libcli/auth/smbdes.c b/libcli/auth/smbdes.c index 6a4f4d1d42a..ec922da4727 100644 --- a/libcli/auth/smbdes.c +++ b/libcli/auth/smbdes.c @@ -391,10 +391,16 @@ int E_P24(const uint8_t *p21, const uint8_t *c8, uint8_t *p24) return des_crypt56_gnutls(p24+16, c8, p21+14, SAMBA_GNUTLS_ENCRYPT); } -void E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out) +int E_old_pw_hash( uint8_t *p14, const uint8_t *in, uint8_t *out) { - des_crypt56(out, in, p14, 1); - des_crypt56(out+8, in+8, p14+7, 1); + int ret; + + ret = des_crypt56_gnutls(out, in, p14, SAMBA_GNUTLS_ENCRYPT); + if (ret != 0) { + return ret; + } + + return des_crypt56_gnutls(out+8, in+8, p14+7, SAMBA_GNUTLS_ENCRYPT); } /* des encryption with a 128 bit key */ diff --git a/libcli/auth/tests/test_gnutls.c b/libcli/auth/tests/test_gnutls.c index d9acfb67075..087afee09db 100644 --- a/libcli/auth/tests/test_gnutls.c +++ b/libcli/auth/tests/test_gnutls.c @@ -343,8 +343,10 @@ static void torture_gnutls_E_old_pw_hash(void **state) 0x37, 0xEF, 0xBE, 0x58, 0xC2, 0x59, 0x33, 0xEC }; uint8_t crypt[16]; + int rc; - E_old_pw_hash(key, clear, crypt); + rc = E_old_pw_hash(key, clear, crypt); + assert_int_equal(rc, 0); assert_memory_equal(crypt, crypt_expected, 16); } diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index c0b9dcdff39..bf2a9ed4fdc 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -569,7 +569,11 @@ bool cli_oem_change_password(struct cli_state *cli, const char *user, const char */ E_deshash(new_password, new_pw_hash); - E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]); + rc = E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]); + if (rc != 0) { + DBG_ERR("E_old_pw_hash failed: %s\n", gnutls_strerror(rc)); + return false; + } data_len = 532; diff --git a/source3/rpc_client/cli_samr.c b/source3/rpc_client/cli_samr.c index 452e9593f6a..8a151c751f5 100644 --- a/source3/rpc_client/cli_samr.c +++ b/source3/rpc_client/cli_samr.c @@ -39,6 +39,7 @@ NTSTATUS dcerpc_samr_chgpasswd_user(struct dcerpc_binding_handle *h, NTSTATUS *presult) { NTSTATUS status; + int rc; struct samr_Password hash1, hash2, hash3, hash4, hash5, hash6; uint8_t old_nt_hash[16] = {0}; @@ -54,12 +55,36 @@ NTSTATUS dcerpc_samr_chgpasswd_user(struct dcerpc_binding_handle *h, E_deshash(oldpassword, old_lm_hash); E_deshash(newpassword, new_lm_hash); - E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash); - E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash); - E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash); - E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash); - E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash); - E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash); + rc = E_old_pw_hash(new_lm_hash, old_lm_hash, hash1.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto done; + } + rc = E_old_pw_hash(old_lm_hash, new_lm_hash, hash2.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto done; + } + rc = E_old_pw_hash(new_nt_hash, old_nt_hash, hash3.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto done; + } + rc = E_old_pw_hash(old_nt_hash, new_nt_hash, hash4.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto done; + } + rc = E_old_pw_hash(old_lm_hash, new_nt_hash, hash5.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto done; + } + rc = E_old_pw_hash(old_nt_hash, new_lm_hash, hash6.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto done; + } status = dcerpc_samr_ChangePasswordUser(h, mem_ctx, @@ -76,6 +101,7 @@ NTSTATUS dcerpc_samr_chgpasswd_user(struct dcerpc_binding_handle *h, &hash6, presult); +done: ZERO_ARRAY(old_nt_hash); ZERO_ARRAY(old_lm_hash); ZERO_ARRAY(new_nt_hash); @@ -117,6 +143,7 @@ NTSTATUS dcerpc_samr_chgpasswd_user2(struct dcerpc_binding_handle *h, NTSTATUS *presult) { NTSTATUS status; + int rc; struct samr_CryptPassword new_nt_password; struct samr_CryptPassword new_lm_password; struct samr_Password old_nt_hash_enc; @@ -153,7 +180,11 @@ NTSTATUS dcerpc_samr_chgpasswd_user2(struct dcerpc_binding_handle *h, return status; } - E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash); + rc = E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto done; + } } else { ZERO_STRUCT(new_lm_password); ZERO_STRUCT(old_lanman_hash_enc); @@ -165,7 +196,11 @@ NTSTATUS dcerpc_samr_chgpasswd_user2(struct dcerpc_binding_handle *h, if (!NT_STATUS_IS_OK(status)) { return status; } - E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash); + rc = E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto done; + } status = dcerpc_samr_ChangePasswordUser2(h, mem_ctx, @@ -178,6 +213,7 @@ NTSTATUS dcerpc_samr_chgpasswd_user2(struct dcerpc_binding_handle *h, &old_lanman_hash_enc, presult); +done: ZERO_STRUCT(new_nt_password); ZERO_STRUCT(new_lm_password); ZERO_STRUCT(old_nt_hash_enc); @@ -312,6 +348,7 @@ NTSTATUS dcerpc_samr_chgpasswd_user3(struct dcerpc_binding_handle *h, NTSTATUS *presult) { NTSTATUS status; + int rc; struct samr_CryptPassword new_nt_password; struct samr_CryptPassword new_lm_password; @@ -350,7 +387,11 @@ NTSTATUS dcerpc_samr_chgpasswd_user3(struct dcerpc_binding_handle *h, return status; } - E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash); + rc = E_old_pw_hash(new_nt_hash, old_lanman_hash, old_lanman_hash_enc.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto done; + } } else { ZERO_STRUCT(new_lm_password); ZERO_STRUCT(old_lanman_hash_enc); @@ -363,7 +404,11 @@ NTSTATUS dcerpc_samr_chgpasswd_user3(struct dcerpc_binding_handle *h, return status; } - E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash); + rc = E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto done; + } status = dcerpc_samr_ChangePasswordUser3(h, mem_ctx, @@ -379,6 +424,7 @@ NTSTATUS dcerpc_samr_chgpasswd_user3(struct dcerpc_binding_handle *h, reject, presult); +done: ZERO_STRUCT(new_nt_password); ZERO_STRUCT(new_lm_password); ZERO_STRUCT(old_nt_hash_enc); diff --git a/source3/rpc_server/samr/srv_samr_chgpasswd.c b/source3/rpc_server/samr/srv_samr_chgpasswd.c index 8c9cf73bdd8..79d4b3068e5 100644 --- a/source3/rpc_server/samr/srv_samr_chgpasswd.c +++ b/source3/rpc_server/samr/srv_samr_chgpasswd.c @@ -804,7 +804,11 @@ static NTSTATUS check_oem_password(const char *user, /* * check the NT verifier */ - E_old_pw_hash(new_nt_hash, nt_pw, verifier); + rc = E_old_pw_hash(new_nt_hash, nt_pw, verifier); + if (rc != 0) { + NTSTATUS status = NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER; + return gnutls_error_to_ntstatus(rc, status); + } if (memcmp(verifier, old_nt_hash_encrypted, 16)) { DEBUG(0, ("check_oem_password: old nt " "password doesn't match.\n")); @@ -831,7 +835,11 @@ static NTSTATUS check_oem_password(const char *user, /* * check the lm verifier */ - E_old_pw_hash(new_nt_hash, lanman_pw, verifier); + rc = E_old_pw_hash(new_nt_hash, lanman_pw, verifier); + if (rc != 0) { + NTSTATUS status = NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER; + return gnutls_error_to_ntstatus(rc, status); + } if (memcmp(verifier, old_lm_hash_encrypted, 16)) { DEBUG(0,("check_oem_password: old lm password doesn't match.\n")); return NT_STATUS_WRONG_PASSWORD; @@ -851,7 +859,11 @@ static NTSTATUS check_oem_password(const char *user, /* * check the lm verifier */ - E_old_pw_hash(new_lm_hash, lanman_pw, verifier); + rc = E_old_pw_hash(new_lm_hash, lanman_pw, verifier); + if (rc != 0) { + NTSTATUS status = NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER; + return gnutls_error_to_ntstatus(rc, status); + } if (memcmp(verifier, old_lm_hash_encrypted, 16)) { DEBUG(0,("check_oem_password: old lm password doesn't match.\n")); return NT_STATUS_WRONG_PASSWORD; diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 8a6218ac9ec..22258b3b84c 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -1993,8 +1993,13 @@ static void manage_ntlm_change_password_1_request(enum stdio_helper_mode stdio_h gnutls_cipher_deinit(cipher_hnd); return; } - E_old_pw_hash(new_nt_hash, old_lm_hash, + rc = E_old_pw_hash(new_nt_hash, old_lm_hash, old_lm_hash_enc.data); + if (rc != 0) { + DBG_ERR("E_old_pw_hash failed: %s\n", + gnutls_strerror(rc)); + return; + } } else { new_lm_pswd.data = NULL; new_lm_pswd.length = 0; @@ -2012,8 +2017,13 @@ static void manage_ntlm_change_password_1_request(enum stdio_helper_mode stdio_h if (rc < 0) { return; } - E_old_pw_hash(new_nt_hash, old_nt_hash, + rc = E_old_pw_hash(new_nt_hash, old_nt_hash, old_nt_hash_enc.data); + if (rc != 0) { + DBG_ERR("E_old_pw_hash failed: %s\n", + gnutls_strerror(rc)); + return; + } ZERO_ARRAY(old_nt_hash); ZERO_ARRAY(old_lm_hash); diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c index 704a94a5864..868f9442cd0 100644 --- a/source4/libnet/libnet_passwd.c +++ b/source4/libnet/libnet_passwd.c @@ -115,7 +115,11 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT goto disconnect; } - E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); + rc = E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto disconnect; + } encode_pw_buffer(nt_pass.data, r->samr.in.newpassword, STR_UNICODE); @@ -137,7 +141,11 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT goto disconnect; } - E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); + rc = E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto disconnect; + } pw3.in.server = &server; pw3.in.account = &account; @@ -189,7 +197,11 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT goto disconnect; } - E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); + rc = E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto disconnect; + } encode_pw_buffer(nt_pass.data, r->samr.in.newpassword, STR_UNICODE); @@ -210,7 +222,11 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT goto disconnect; } - E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); + rc = E_old_pw_hash(new_nt_hash, old_nt_hash, nt_verifier.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto disconnect; + } pw2.in.server = &server; pw2.in.account = &account; @@ -260,7 +276,11 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT goto disconnect; } - E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); + rc = E_old_pw_hash(new_lm_hash, old_lm_hash, lm_verifier.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto disconnect; + } oe2.in.server = &a_server; oe2.in.account = &a_account; diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c index b04e37f06f3..4fa00bf6360 100644 --- a/source4/rpc_server/samr/samr_password.c +++ b/source4/rpc_server/samr/samr_password.c @@ -235,7 +235,11 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, new_unicode_password.length = unicode_pw_len; E_deshash(new_pass, new_lm_hash); - E_old_pw_hash(new_lm_hash, lm_pwd->hash, lm_verifier.hash); + rc = E_old_pw_hash(new_lm_hash, lm_pwd->hash, lm_verifier.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto failed; + } if (memcmp(lm_verifier.hash, r->in.hash->hash, 16) != 0) { authsam_update_bad_pwd_count(sam_ctx, res[0], ldb_get_default_basedn(sam_ctx)); status = NT_STATUS_WRONG_PASSWORD; @@ -442,6 +446,10 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, mdfour(new_nt_hash, new_password.data, new_password.length); E_old_pw_hash(new_nt_hash, nt_pwd->hash, nt_verifier.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto failed; + } if (memcmp(nt_verifier.hash, r->in.nt_verifier->hash, 16) != 0) { status = NT_STATUS_WRONG_PASSWORD; goto failed; @@ -460,7 +468,11 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, new_password.length, (void **)&new_pass, &converted_size)) { E_deshash(new_pass, new_lm_hash); - E_old_pw_hash(new_nt_hash, lm_pwd->hash, lm_verifier.hash); + rc = E_old_pw_hash(new_nt_hash, lm_pwd->hash, lm_verifier.hash); + if (rc != 0) { + status = gnutls_error_to_ntstatus(rc, NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER); + goto failed; + } if (memcmp(lm_verifier.hash, r->in.lm_verifier->hash, 16) != 0) { status = NT_STATUS_WRONG_PASSWORD; goto failed; -- 2.23.0