From: Andreas Schneider Date: Wed, 29 May 2019 12:46:17 +0000 (+0200) Subject: libcli:auth: Return NTSTATUS for netlogon_creds_arcfour_crypt() X-Git-Tag: ldb-2.0.5~166 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=67e6a9af2c688ce89c87b0ed381274b3c12c37a9;p=thirdparty%2Fsamba.git libcli:auth: Return NTSTATUS for netlogon_creds_arcfour_crypt() Signed-off-by: Andreas Schneider Reviewed-by: Andrew Bartlett --- diff --git a/auth/credentials/credentials.c b/auth/credentials/credentials.c index befce2c2119..5ebec483705 100644 --- a/auth/credentials/credentials.c +++ b/auth/credentials/credentials.c @@ -1317,6 +1317,8 @@ _PUBLIC_ NTSTATUS netlogon_creds_session_encrypt( struct netlogon_creds_CredentialState *state, DATA_BLOB data) { + NTSTATUS status; + if (data.data == NULL || data.length == 0) { DBG_ERR("Nothing to encrypt " "data.data == NULL or data.length == 0"); @@ -1335,9 +1337,12 @@ _PUBLIC_ NTSTATUS netlogon_creds_session_encrypt( data.data, data.length); } else if (state->negotiate_flags & NETLOGON_NEG_ARCFOUR) { - netlogon_creds_arcfour_crypt(state, - data.data, - data.length); + status = netlogon_creds_arcfour_crypt(state, + data.data, + data.length); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } else { DBG_ERR("Unsupported encryption option negotiated"); return NT_STATUS_NOT_SUPPORTED; diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c index 175c5ee6039..319dacdac0b 100644 --- a/libcli/auth/credentials.c +++ b/libcli/auth/credentials.c @@ -262,7 +262,9 @@ void netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds, st /* ARCFOUR encrypt/decrypt a password buffer using the session key */ -void netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len) +NTSTATUS netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds, + uint8_t *data, + size_t len) { gnutls_cipher_hd_t cipher_hnd = NULL; gnutls_datum_t session_key = { @@ -276,12 +278,19 @@ void netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds, &session_key, NULL); if (rc < 0) { - return; + return gnutls_error_to_ntstatus(rc, + NT_STATUS_CRYPTO_SYSTEM_INVALID); } - gnutls_cipher_encrypt(cipher_hnd, - data, - len); + rc = gnutls_cipher_encrypt(cipher_hnd, + data, + len); gnutls_cipher_deinit(cipher_hnd); + if (rc < 0) { + return gnutls_error_to_ntstatus(rc, + NT_STATUS_CRYPTO_SYSTEM_INVALID); + } + + return NT_STATUS_OK; } /* @@ -591,6 +600,7 @@ static NTSTATUS netlogon_creds_crypt_samlogon_validation(struct netlogon_creds_C bool do_encrypt) { struct netr_SamBaseInfo *base = NULL; + NTSTATUS status; if (validation == NULL) { return NT_STATUS_INVALID_PARAMETER; @@ -654,16 +664,22 @@ static NTSTATUS netlogon_creds_crypt_samlogon_validation(struct netlogon_creds_C } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */ if (!all_zero(base->key.key, sizeof(base->key.key))) { - netlogon_creds_arcfour_crypt(creds, - base->key.key, - sizeof(base->key.key)); + status = netlogon_creds_arcfour_crypt(creds, + base->key.key, + sizeof(base->key.key)); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } if (!all_zero(base->LMSessKey.key, sizeof(base->LMSessKey.key))) { - netlogon_creds_arcfour_crypt(creds, - base->LMSessKey.key, - sizeof(base->LMSessKey.key)); + status = netlogon_creds_arcfour_crypt(creds, + base->LMSessKey.key, + sizeof(base->LMSessKey.key)); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } } else { /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */ @@ -707,6 +723,8 @@ static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_Creden union netr_LogonLevel *logon, bool do_encrypt) { + NTSTATUS status; + if (logon == NULL) { return NT_STATUS_INVALID_PARAMETER; } @@ -745,12 +763,22 @@ static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_Creden h = logon->password->lmpassword.hash; if (!all_zero(h, 16)) { - netlogon_creds_arcfour_crypt(creds, h, 16); + status = netlogon_creds_arcfour_crypt(creds, + h, + 16); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } h = logon->password->ntpassword.hash; if (!all_zero(h, 16)) { - netlogon_creds_arcfour_crypt(creds, h, 16); + status = netlogon_creds_arcfour_crypt(creds, + h, + 16); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } } else { struct samr_Password *p; @@ -794,9 +822,12 @@ static NTSTATUS netlogon_creds_crypt_samlogon_logon(struct netlogon_creds_Creden logon->generic->length); } } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { - netlogon_creds_arcfour_crypt(creds, - logon->generic->data, - logon->generic->length); + status = netlogon_creds_arcfour_crypt(creds, + logon->generic->data, + logon->generic->length); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } else { /* Using DES to verify kerberos tickets makes no sense */ } diff --git a/libcli/auth/netlogon_creds_cli.c b/libcli/auth/netlogon_creds_cli.c index 8dce4cc30e1..50a5f50a57d 100644 --- a/libcli/auth/netlogon_creds_cli.c +++ b/libcli/auth/netlogon_creds_cli.c @@ -1992,9 +1992,13 @@ static void netlogon_creds_cli_ServerPasswordSet_locked(struct tevent_req *subre state->samr_crypt_password.data, 516); } else { - netlogon_creds_arcfour_crypt(&state->tmp_creds, - state->samr_crypt_password.data, - 516); + status = netlogon_creds_arcfour_crypt(&state->tmp_creds, + state->samr_crypt_password.data, + 516); + if (tevent_req_nterror(req, status)) { + netlogon_creds_cli_ServerPasswordSet_cleanup(req, status); + return; + } } memcpy(state->netr_crypt_password.data, @@ -3685,9 +3689,13 @@ static void netlogon_creds_cli_SendToSam_locked(struct tevent_req *subreq) state->opaque.data, state->opaque.length); } else { - netlogon_creds_arcfour_crypt(&state->tmp_creds, - state->opaque.data, - state->opaque.length); + status = netlogon_creds_arcfour_crypt(&state->tmp_creds, + state->opaque.data, + state->opaque.length); + if (tevent_req_nterror(req, status)) { + netlogon_creds_cli_SendToSam_cleanup(req, status); + return; + } } subreq = dcerpc_netr_NetrLogonSendToSam_send(state, state->ev, diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h index 0ae5cbc4ed3..afd7f0d148d 100644 --- a/libcli/auth/proto.h +++ b/libcli/auth/proto.h @@ -15,7 +15,9 @@ void netlogon_creds_des_encrypt_LMKey(struct netlogon_creds_CredentialState *cre void netlogon_creds_des_decrypt_LMKey(struct netlogon_creds_CredentialState *creds, struct netr_LMSessionKey *key); void netlogon_creds_des_encrypt(struct netlogon_creds_CredentialState *creds, struct samr_Password *pass); void netlogon_creds_des_decrypt(struct netlogon_creds_CredentialState *creds, struct samr_Password *pass); -void netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len); +NTSTATUS netlogon_creds_arcfour_crypt(struct netlogon_creds_CredentialState *creds, + uint8_t *data, + size_t len); void netlogon_creds_aes_encrypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len); void netlogon_creds_aes_decrypt(struct netlogon_creds_CredentialState *creds, uint8_t *data, size_t len); diff --git a/libcli/samsync/decrypt.c b/libcli/samsync/decrypt.c index f5ea4cc70fc..5cda966fb42 100644 --- a/libcli/samsync/decrypt.c +++ b/libcli/samsync/decrypt.c @@ -69,9 +69,18 @@ static NTSTATUS fix_user(TALLOC_CTX *mem_ctx, DATA_BLOB data; struct netr_USER_KEYS keys; enum ndr_err_code ndr_err; + NTSTATUS status; + data.data = user->user_private_info.SensitiveData; data.length = user->user_private_info.DataLength; - netlogon_creds_arcfour_crypt(creds, data.data, data.length); + + status = netlogon_creds_arcfour_crypt(creds, + data.data, + data.length); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + user->user_private_info.SensitiveData = data.data; user->user_private_info.DataLength = data.length; @@ -125,11 +134,21 @@ static NTSTATUS fix_secret(TALLOC_CTX *mem_ctx, struct netr_DELTA_ENUM *delta) { struct netr_DELTA_SECRET *secret = delta->delta_union.secret; - netlogon_creds_arcfour_crypt(creds, secret->current_cipher.cipher_data, - secret->current_cipher.maxlen); + NTSTATUS status; - netlogon_creds_arcfour_crypt(creds, secret->old_cipher.cipher_data, - secret->old_cipher.maxlen); + status = netlogon_creds_arcfour_crypt(creds, + secret->current_cipher.cipher_data, + secret->current_cipher.maxlen); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + status = netlogon_creds_arcfour_crypt(creds, + secret->old_cipher.cipher_data, + secret->old_cipher.maxlen); + if (!NT_STATUS_IS_OK(status)) { + return status; + } return NT_STATUS_OK; } diff --git a/source3/rpc_client/init_netlogon.c b/source3/rpc_client/init_netlogon.c index 4d9157bbb8c..26deaba8065 100644 --- a/source3/rpc_client/init_netlogon.c +++ b/source3/rpc_client/init_netlogon.c @@ -31,13 +31,19 @@ void init_netr_CryptPassword(const char *pwd, struct netr_CryptPassword *pwd_buf) { struct samr_CryptPassword password_buf; + NTSTATUS status; encode_pw_buffer(password_buf.data, pwd, STR_UNICODE); if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { netlogon_creds_aes_encrypt(creds, password_buf.data, 516); } else { - netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); + status = netlogon_creds_arcfour_crypt(creds, + password_buf.data, + 516); + if (!NT_STATUS_IS_OK(status)) { + return; + } } memcpy(pwd_buf->data, password_buf.data, 512); pwd_buf->length = IVAL(password_buf.data, 512); diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c index 7a50e456ec6..c9aaa90cbb9 100644 --- a/source3/rpc_server/netlogon/srv_netlog_nt.c +++ b/source3/rpc_server/netlogon/srv_netlog_nt.c @@ -1361,7 +1361,12 @@ NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p, if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { netlogon_creds_aes_decrypt(creds, password_buf.data, 516); } else { - netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); + status = netlogon_creds_arcfour_crypt(creds, + password_buf.data, + 516); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } if (!decode_pw_buffer(p->mem_ctx, diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c index b99964ebb8f..ac745e32b02 100644 --- a/source4/rpc_server/netlogon/dcerpc_netlogon.c +++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c @@ -749,7 +749,12 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { netlogon_creds_aes_decrypt(creds, password_buf.data, 516); } else { - netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); + nt_status = netlogon_creds_arcfour_crypt(creds, + password_buf.data, + 516); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } } switch (creds->secure_channel_type) { @@ -2800,7 +2805,12 @@ static NTSTATUS dcesrv_netr_NetrLogonSendToSam(struct dcesrv_call_state *dce_cal if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { netlogon_creds_aes_decrypt(creds, r->in.opaque_buffer, r->in.buffer_len); } else { - netlogon_creds_arcfour_crypt(creds, r->in.opaque_buffer, r->in.buffer_len); + nt_status = netlogon_creds_arcfour_crypt(creds, + r->in.opaque_buffer, + r->in.buffer_len); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } } decrypted_blob.data = r->in.opaque_buffer;