auth/credentials: cli_credentials_set_ntlm_response() pass session_keys
authorStefan Metzmacher <metze@samba.org>
Sat, 18 Dec 2021 09:40:36 +0000 (10:40 +0100)
committerJeremy Allison <jra@samba.org>
Tue, 4 Jan 2022 20:07:28 +0000 (20:07 +0000)
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 <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
auth/credentials/credentials.h
auth/credentials/credentials_internal.h
auth/credentials/credentials_ntlm.c

index 4057565ad34c9ec2243a888187266147fb24c88a..551b16118268bbf8d282cb67c85249cb8504b431 100644 (file)
@@ -230,8 +230,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,
index afbda1a4b48de83a7c825cd25ee669d21a482fdd..3b1581acb1113c00f9fbd7e3f00d834bd190628d 100644 (file)
@@ -70,7 +70,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;
index 49505f643151f1b28527322d273c1d8676353922..1c17148e647802dd7b38c2132378eecd47604187 100644 (file)
@@ -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;
        }