r6460: Push the client credentials into NTLMSSP, allowing logins of the form
authorAndrew Bartlett <abartlet@samba.org>
Mon, 25 Apr 2005 06:33:20 +0000 (06:33 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:11:39 +0000 (13:11 -0500)
user@REALM for the first time.

Fix the build for smbencrypt.c

Andrew Bartlett

source/auth/ntlmssp/ntlmssp.c
source/auth/ntlmssp/ntlmssp.h
source/auth/ntlmssp/ntlmssp_client.c
source/auth/ntlmssp/ntlmssp_server.c
source/libcli/auth/smbencrypt.c

index d0bd98419e7e8e1116da7c5b7c622c0e342d560e..9bb0ed99faf45fc0eacdb2e84933e468e3240efe 100644 (file)
@@ -35,7 +35,7 @@
 static const struct ntlmssp_callbacks {
        enum ntlmssp_role role;
        enum ntlmssp_message_type ntlmssp_command;
-       NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state
+       NTSTATUS (*fn)(struct gensec_security *gensec_security
                       TALLOC_CTX *out_mem_ctx, 
                       DATA_BLOB in, DATA_BLOB *out);
 } ntlmssp_callbacks[] = {
@@ -89,68 +89,6 @@ void debug_ntlmssp_flags(uint32_t neg_flags)
                DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_KEY_EXCH\n"));
 }
 
-/** 
- * Set a username on an NTLMSSP context - ensures it is talloc()ed 
- *
- */
-
-NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user) 
-{
-       if (!user) {
-               /* it should be at least "" */
-               DEBUG(1, ("NTLMSSP failed to set username - cannot accept NULL username\n"));
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-       ntlmssp_state->user = talloc_strdup(ntlmssp_state, user);
-       if (!ntlmssp_state->user) {
-               return NT_STATUS_NO_MEMORY;
-       }
-       return NT_STATUS_OK;
-}
-
-/** 
- * Set a password on an NTLMSSP context - ensures it is talloc()ed 
- *
- */
-NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password) 
-{
-       if (!password) {
-               ntlmssp_state->password = NULL;
-       } else {
-               ntlmssp_state->password = talloc_strdup(ntlmssp_state, password);
-               if (!ntlmssp_state->password) {
-                       return NT_STATUS_NO_MEMORY;
-               }
-       }
-       return NT_STATUS_OK;
-}
-
-/** 
- * Set a domain on an NTLMSSP context - ensures it is talloc()ed 
- *
- */
-NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) 
-{
-       ntlmssp_state->domain = talloc_strdup(ntlmssp_state, domain);
-       if (!ntlmssp_state->domain) {
-               return NT_STATUS_NO_MEMORY;
-       }
-       return NT_STATUS_OK;
-}
-
-/** 
- * Set a workstation on an NTLMSSP context - ensures it is talloc()ed 
- *
- */
-NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char *workstation) 
-{
-       ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation);
-       if (!ntlmssp_state->workstation) {
-               return NT_STATUS_NO_MEMORY;
-       }
-       return NT_STATUS_OK;
-}
-
 /**
  *  Store a DATA_BLOB containing an NTLMSSP response, for use later.
  *  This copies the data blob
@@ -175,7 +113,8 @@ NTSTATUS ntlmssp_store_response(struct ntlmssp_state *ntlmssp_state,
  *                or NT_STATUS_OK if the user is authenticated. 
  */
 
-static NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, 
+static NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, 
+                                     TALLOC_CTX *out_mem_ctx, 
                                      const DATA_BLOB in, DATA_BLOB *out) 
 {
        struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
@@ -236,7 +175,7 @@ static NTSTATUS gensec_ntlmssp_update(struct gensec_security *gensec_security, T
        for (i=0; i < ARRAY_SIZE(ntlmssp_callbacks); i++) {
                if (ntlmssp_callbacks[i].role == ntlmssp_state->role 
                    && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) {
-                       status = ntlmssp_callbacks[i].fn(ntlmssp_state, out_mem_ctx, input, out);
+                       status = ntlmssp_callbacks[i].fn(gensec_security, out_mem_ctx, input, out);
                        break;
                }
        }
index 0fe04a7c0f5274d82c93e8707479b905a1ce4d14..7e7aeaad98590a81fc81d03364172d80f859a439 100644 (file)
@@ -96,7 +96,6 @@ struct ntlmssp_state
        char *user;
        char *domain;
        const char *workstation;
-       char *password;
        char *server_domain;
 
        DATA_BLOB internal_chal; /* Random challenge as supplied to the client for NTLM authentication */
index bbde1d954b0dd6df4f31edbd38e3035b93387276..dcd52af1f563c8b6f0c0251c008e14718b04b249 100644 (file)
  * @return Errors or NT_STATUS_OK. 
  */
 
-NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state
+NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security
                                TALLOC_CTX *out_mem_ctx, 
                                DATA_BLOB in, DATA_BLOB *out) 
 {
+       struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
+       struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state;
+
        if (ntlmssp_state->unicode) {
                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
        } else {
@@ -62,7 +65,7 @@ NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
                  NTLMSSP_NEGOTIATE,
                  ntlmssp_state->neg_flags,
                  ntlmssp_state->get_domain(), 
-                 ntlmssp_state->workstation);
+                 cli_credentials_get_workstation(gensec_security->credentials));
 
        ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
 
@@ -78,10 +81,12 @@ NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
  * @return Errors or NT_STATUS_OK. 
  */
 
-NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state
+NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security
                                  TALLOC_CTX *out_mem_ctx,
                                  const DATA_BLOB in, DATA_BLOB *out) 
 {
+       struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
+       struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state;
        uint32_t chal_flags, ntlmssp_command, unkn1, unkn2;
        DATA_BLOB server_domain_blob;
        DATA_BLOB challenge_blob;
@@ -97,6 +102,8 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
        DATA_BLOB encrypted_session_key = data_blob(NULL, 0);
        NTSTATUS nt_status;
 
+       const char *user, *domain, *password;
+
        if (!msrpc_parse(ntlmssp_state, 
                         &in, "CdBd",
                         "NTLMSSP",
@@ -156,7 +163,21 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       if (!ntlmssp_state->password) {
+       /* Correctly handle username in the original form of user@REALM, which is valid */
+       if (gensec_security->credentials->realm_obtained
+           > gensec_security->credentials->domain_obtained) {
+               user = talloc_asprintf(out_mem_ctx, "%s@%s", 
+                                      cli_credentials_get_username(gensec_security->credentials), 
+                                      cli_credentials_get_realm(gensec_security->credentials));
+               domain = NULL;
+       } else {
+               user = cli_credentials_get_username(gensec_security->credentials);
+               domain = cli_credentials_get_domain(gensec_security->credentials);
+       }
+
+       password = cli_credentials_get_password(gensec_security->credentials);
+
+       if (!password) {
                static const uint8_t zeros[16];
                /* do nothing - blobs are zero length */
 
@@ -177,9 +198,9 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
                /* TODO: if the remote server is standalone, then we should replace 'domain'
                   with the server name as supplied above */
                
-               if (!SMBNTLMv2encrypt(ntlmssp_state->user, 
-                                     ntlmssp_state->domain, 
-                                     ntlmssp_state->password, &challenge_blob, 
+               if (!SMBNTLMv2encrypt(user, 
+                                     domain, 
+                                     password, &challenge_blob, 
                                      &struct_blob, 
                                      &lm_response, &nt_response, 
                                      NULL, &session_key)) {
@@ -197,7 +218,7 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
                uint8_t session_nonce[16];
                uint8_t session_nonce_hash[16];
                uint8_t user_session_key[16];
-               E_md4hash(ntlmssp_state->password, nt_hash);
+               E_md4hash(password, nt_hash);
                
                lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
                generate_random_buffer(lm_response.data, 8);
@@ -216,7 +237,7 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
                dump_data(5, session_nonce_hash, 8);
                
                nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
-               SMBNTencrypt(ntlmssp_state->password,
+               SMBNTencrypt(password,
                             session_nonce_hash,
                             nt_response.data);
 
@@ -233,9 +254,9 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
 
                if (ntlmssp_state->use_nt_response) {
                        nt_response = data_blob_talloc(ntlmssp_state, NULL, 24);
-                       SMBNTencrypt(ntlmssp_state->password,challenge_blob.data,
+                       SMBNTencrypt(password,challenge_blob.data,
                                     nt_response.data);
-                       E_md4hash(ntlmssp_state->password, nt_hash);
+                       E_md4hash(password, nt_hash);
                        session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
                        SMBsesskeygen_ntv1(nt_hash, session_key.data);
                        dump_data_pw("NT session key:\n", session_key.data, session_key.length);
@@ -244,7 +265,7 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
                /* lanman auth is insecure, it may be disabled */
                if (lp_client_lanman_auth()) {
                        lm_response = data_blob_talloc(ntlmssp_state, NULL, 24);
-                       if (!SMBencrypt(ntlmssp_state->password,challenge_blob.data,
+                       if (!SMBencrypt(password,challenge_blob.data,
                                        lm_response.data)) {
                                /* If the LM password was too long (and therefore the LM hash being
                                   of the first 14 chars only), don't send it */
@@ -253,7 +274,7 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
                                /* LM Key is incompatible with 'long' passwords */
                                ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
                        } else {
-                               E_deshash(ntlmssp_state->password, lm_hash);
+                               E_deshash(password, lm_hash);
                                lm_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
                                memcpy(lm_session_key.data, lm_hash, 8);
                                memset(&lm_session_key.data[8], '\0', 8);
@@ -310,9 +331,9 @@ NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
                       NTLMSSP_AUTH, 
                       lm_response.data, lm_response.length,
                       nt_response.data, nt_response.length,
-                      ntlmssp_state->domain, 
-                      ntlmssp_state->user, 
-                      ntlmssp_state->workstation, 
+                      domain, 
+                      user, 
+                      cli_credentials_get_workstation(gensec_security->credentials),
                       encrypted_session_key.data, encrypted_session_key.length,
                       ntlmssp_state->neg_flags)) {
                
@@ -351,7 +372,6 @@ static NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state *
 
        (*ntlmssp_state)->role = NTLMSSP_CLIENT;
 
-       (*ntlmssp_state)->workstation = lp_netbios_name();
        (*ntlmssp_state)->get_domain = lp_workgroup;
 
        (*ntlmssp_state)->unicode = lp_parm_bool(-1, "ntlmssp_client", "unicode", True);
@@ -392,7 +412,6 @@ static NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state *
 NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
 {
        struct gensec_ntlmssp_state *gensec_ntlmssp_state;
-       const char *password = NULL;
        NTSTATUS nt_status;
 
        nt_status = gensec_ntlmssp_start(gensec_security);
@@ -422,22 +441,6 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
                gensec_ntlmssp_state->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
        }
 
-       nt_status = ntlmssp_set_domain(gensec_ntlmssp_state->ntlmssp_state, 
-                                      cli_credentials_get_domain(gensec_security->credentials));
-       NT_STATUS_NOT_OK_RETURN(nt_status);
-       
-       nt_status = ntlmssp_set_username(gensec_ntlmssp_state->ntlmssp_state, 
-                                        cli_credentials_get_username(gensec_security->credentials));
-       NT_STATUS_NOT_OK_RETURN(nt_status);
-
-       password = cli_credentials_get_password(gensec_security->credentials);
-
-       nt_status = ntlmssp_set_password(gensec_ntlmssp_state->ntlmssp_state, password);
-       NT_STATUS_NOT_OK_RETURN(nt_status);
-
-       nt_status = ntlmssp_set_workstation(gensec_ntlmssp_state->ntlmssp_state,
-                                           cli_credentials_get_workstation(gensec_security->credentials));
-
        gensec_security->private_data = gensec_ntlmssp_state;
 
        return NT_STATUS_OK;
index d1e97aeb1fdbcf1a2a5e9ea79649d5222174292e..852d32ed2b6f1771fd9a76d7448e170674024e07 100644 (file)
 #include "lib/crypto/crypto.h"
 #include "pstring.h"
 
+/** 
+ * Set a username on an NTLMSSP context - ensures it is talloc()ed 
+ *
+ */
+
+static NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user) 
+{
+       if (!user) {
+               /* it should be at least "" */
+               DEBUG(1, ("NTLMSSP failed to set username - cannot accept NULL username\n"));
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+       ntlmssp_state->user = talloc_strdup(ntlmssp_state, user);
+       if (!ntlmssp_state->user) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       return NT_STATUS_OK;
+}
+
+/** 
+ * Set a domain on an NTLMSSP context - ensures it is talloc()ed 
+ *
+ */
+static NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) 
+{
+       ntlmssp_state->domain = talloc_strdup(ntlmssp_state, domain);
+       if (!ntlmssp_state->domain) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       return NT_STATUS_OK;
+}
+
+/** 
+ * Set a workstation on an NTLMSSP context - ensures it is talloc()ed 
+ *
+ */
+static NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char *workstation) 
+{
+       ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation);
+       if (!ntlmssp_state->workstation) {
+               return NT_STATUS_NO_MEMORY;
+       }
+       return NT_STATUS_OK;
+}
+
 /**
  * Default challenge generation code.
  *
@@ -102,10 +147,12 @@ static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
  * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent. 
  */
 
-NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
+NTSTATUS ntlmssp_server_negotiate(struct gensec_security *gensec_security, 
                                  TALLOC_CTX *out_mem_ctx, 
                                  const DATA_BLOB in, DATA_BLOB *out) 
 {
+       struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
+       struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state;
        DATA_BLOB struct_blob;
        fstring dnsname, dnsdomname;
        uint32_t neg_flags = 0;
@@ -516,10 +563,12 @@ static NTSTATUS ntlmssp_server_postauth(struct ntlmssp_state *ntlmssp_state,
  * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. 
  */
 
-NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
+NTSTATUS ntlmssp_server_auth(struct gensec_security *gensec_security, 
                             TALLOC_CTX *out_mem_ctx, 
                             const DATA_BLOB in, DATA_BLOB *out) 
 {
+       struct gensec_ntlmssp_state *gensec_ntlmssp_state = gensec_security->private_data;
+       struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp_state->ntlmssp_state;
        DATA_BLOB user_session_key = data_blob(NULL, 0);
        DATA_BLOB lm_session_key = data_blob(NULL, 0);
        NTSTATUS nt_status;
index f2b6eb00d7f4ee7d29de0969943b1972b0fc4031..3a4a724789f37c1dc60d734651ce4bef10195920 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "includes.h"
 #include "system/time.h"
-#include "auth/auth.h"
+#include "auth/ntlmssp/ntlmssp.h"
 #include "lib/crypto/crypto.h"
 #include "pstring.h"