[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Fri Jan 6 07:00:04 MST 2012


The branch, master has been updated
       via  fd69ebd s3-ntlmssp Remove unused ntlmssp_set_hashes() and do not set an invalid LM hash
       via  60c6611 ntlmssp: merge initial packet implementations
       via  af19532 s3-winbindd: convert cached credentials to use auth_generic/gensec for NTLMSSP
      from  662c557 s3-torture convert smb2 test to use auth_generic/gensec for NTLMSSP

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit fd69ebda26ab62333202de51d3e392af1978c544
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Dec 27 19:39:32 2011 +1100

    s3-ntlmssp Remove unused ntlmssp_set_hashes() and do not set an invalid LM hash
    
    When E_deshash() returns false, it indicates that the password is either > 14 chars
    in length, or could not be represented as an LM hash value for some other
    reason.  In this case, we should not regard the LM hash being missing
    as an error or a no-password situation.
    
    Andrew Bartlett
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    
    Autobuild-User: Stefan Metzmacher <metze at samba.org>
    Autobuild-Date: Fri Jan  6 14:59:13 CET 2012 on sn-devel-104

commit 60c66118b3a076aee59e581a263c045a205e5ed5
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Dec 27 19:16:14 2011 +1100

    ntlmssp: merge initial packet implementations
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

commit af19532d4dbbf4cd0cf7142b9469d04bd5c722a8
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Tue Dec 27 14:59:17 2011 +1100

    s3-winbindd: convert cached credentials to use auth_generic/gensec for NTLMSSP
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source3/include/proto.h                   |    3 -
 source3/libsmb/ntlmssp.c                  |   77 +++++++++++++++-------------
 source3/winbindd/winbindd_ccache_access.c |   79 +++++++++++++++++------------
 source4/auth/ntlmssp/ntlmssp_client.c     |   31 +++++++++--
 4 files changed, 113 insertions(+), 77 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index 7a7f60a..9dcd334 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -1079,9 +1079,6 @@ bool get_dc_name(const char *domain,
 /* The following definitions come from libsmb/ntlmssp.c  */
 struct ntlmssp_state;
 NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *user) ;
-NTSTATUS ntlmssp_set_hashes(struct ntlmssp_state *ntlmssp_state,
-			    const uint8_t lm_hash[16],
-			    const uint8_t nt_hash[16]) ;
 NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password) ;
 NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *domain) ;
 void ntlmssp_want_feature_list(struct ntlmssp_state *ntlmssp_state, char *feature_list);
diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c
index 01cc1cc..989f26b 100644
--- a/source3/libsmb/ntlmssp.c
+++ b/source3/libsmb/ntlmssp.c
@@ -33,7 +33,7 @@
 #include "../nsswitch/libwbclient/wbclient.h"
 
 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
-				       TALLOC_CTX *out_mem_ctx, /* Unused at this time */
+				       TALLOC_CTX *out_mem_ctx,
 				       DATA_BLOB reply, DATA_BLOB *next_request);
 static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
 				         TALLOC_CTX *out_mem_ctx, /* Unused at this time */
@@ -109,41 +109,35 @@ NTSTATUS ntlmssp_set_username(struct ntlmssp_state *ntlmssp_state, const char *u
 }
 
 /**
- * Store NT and LM hashes on an NTLMSSP context - ensures they are talloc()ed
- *
- */
-NTSTATUS ntlmssp_set_hashes(struct ntlmssp_state *ntlmssp_state,
-			    const uint8_t lm_hash[16],
-			    const uint8_t nt_hash[16])
-{
-	ntlmssp_state->lm_hash = (uint8_t *)
-		talloc_memdup(ntlmssp_state, lm_hash, 16);
-	ntlmssp_state->nt_hash = (uint8_t *)
-		talloc_memdup(ntlmssp_state, nt_hash, 16);
-	if (!ntlmssp_state->lm_hash || !ntlmssp_state->nt_hash) {
-		TALLOC_FREE(ntlmssp_state->lm_hash);
-		TALLOC_FREE(ntlmssp_state->nt_hash);
-		return NT_STATUS_NO_MEMORY;
-	}
-	return NT_STATUS_OK;
-}
-
-/**
  * Converts a password to the hashes on an NTLMSSP context.
  *
  */
 NTSTATUS ntlmssp_set_password(struct ntlmssp_state *ntlmssp_state, const char *password)
 {
+	TALLOC_FREE(ntlmssp_state->lm_hash);
+	TALLOC_FREE(ntlmssp_state->nt_hash);
 	if (!password) {
-		ntlmssp_state->lm_hash = NULL;
-		ntlmssp_state->nt_hash = NULL;
+		return NT_STATUS_OK;
 	} else {
 		uint8_t lm_hash[16];
 		uint8_t nt_hash[16];
 
-		E_deshash(password, lm_hash);
+		if (E_deshash(password, lm_hash)) {
+			ntlmssp_state->lm_hash = (uint8_t *)
+				talloc_memdup(ntlmssp_state, lm_hash, 16);
+			if (!ntlmssp_state->lm_hash) {
+				return NT_STATUS_NO_MEMORY;
+			}
+		}
+
 		E_md4hash(password, nt_hash);
-		return ntlmssp_set_hashes(ntlmssp_state, lm_hash, nt_hash);
+
+		ntlmssp_state->nt_hash = (uint8_t *)
+			talloc_memdup(ntlmssp_state, nt_hash, 16);
+		if (!ntlmssp_state->nt_hash) {
+			TALLOC_FREE(ntlmssp_state->lm_hash);
+			return NT_STATUS_NO_MEMORY;
+		}
 	}
 	return NT_STATUS_OK;
 }
@@ -374,11 +368,22 @@ NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx,
  */
 
 static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
-				  TALLOC_CTX *out_mem_ctx, /* Unused at this time */
-				  DATA_BLOB reply, DATA_BLOB *next_request)
+				       TALLOC_CTX *out_mem_ctx,
+				       DATA_BLOB in, DATA_BLOB *out)
 {
+	const char *domain = ntlmssp_state->client.netbios_domain;
+	const char *workstation = ntlmssp_state->client.netbios_name;
 	NTSTATUS status;
 
+	/* These don't really matter in the initial packet, so don't panic if they are not set */
+	if (!domain) {
+		domain = "";
+	}
+
+	if (!workstation) {
+		workstation = "";
+	}
+
 	if (ntlmssp_state->unicode) {
 		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
 	} else {
@@ -390,15 +395,17 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
 	}
 
 	/* generate the ntlmssp negotiate packet */
-	status = msrpc_gen(ntlmssp_state, next_request, "CddAA",
+	status = msrpc_gen(out_mem_ctx,
+		  out, "CddAA",
 		  "NTLMSSP",
 		  NTLMSSP_NEGOTIATE,
 		  ntlmssp_state->neg_flags,
-		  ntlmssp_state->client.netbios_domain,
-		  ntlmssp_state->client.netbios_name);
+		  domain,
+		  workstation);
+
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0, ("ntlmssp_client_initial: failed to generate "
-			"ntlmssp negotiate packet\n"));
+			  "ntlmssp negotiate packet\n"));
 		return status;
 	}
 
@@ -407,7 +414,7 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
 			talloc_tos(), struct NEGOTIATE_MESSAGE);
 		if (negotiate != NULL) {
 			status = ntlmssp_pull_NEGOTIATE_MESSAGE(
-				next_request, negotiate, negotiate);
+				out, negotiate, negotiate);
 			if (NT_STATUS_IS_OK(status)) {
 				NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
 						negotiate);
@@ -580,7 +587,7 @@ noccache:
 		return NT_STATUS_INVALID_PARAMETER;
 	}
 
-	if (!ntlmssp_state->nt_hash || !ntlmssp_state->lm_hash) {
+	if (!ntlmssp_state->nt_hash) {
 		static const uint8_t zeros[16] = {0, };
 		/* do nothing - blobs are zero length */
 
@@ -644,7 +651,7 @@ noccache:
 		dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
 	} else {
 		/* lanman auth is insecure, it may be disabled */
-		if (lp_client_lanman_auth()) {
+		if (lp_client_lanman_auth() && ntlmssp_state->lm_hash) {
 			lm_response = data_blob_talloc(ntlmssp_state,
 						       NULL, 24);
 			SMBencrypt_hash(ntlmssp_state->lm_hash,challenge_blob.data,
@@ -657,7 +664,7 @@ noccache:
 
 		session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
 		if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
-		    && lp_client_lanman_auth()) {
+		    && lp_client_lanman_auth() && ntlmssp_state->lm_hash) {
 			SMBsesskeygen_lm_sess_key(ntlmssp_state->lm_hash, lm_response.data,
 					session_key.data);
 			dump_data_pw("LM session key\n", session_key.data, session_key.length);
diff --git a/source3/winbindd/winbindd_ccache_access.c b/source3/winbindd/winbindd_ccache_access.c
index 37e8eee..411b2b4 100644
--- a/source3/winbindd/winbindd_ccache_access.c
+++ b/source3/winbindd/winbindd_ccache_access.c
@@ -6,6 +6,7 @@
    Copyright (C) Robert O'Callahan 2006
    Copyright (C) Jeremy Allison 2006 (minor fixes to fit into Samba and
 				      protect against integer wrap).
+   Copyright (C) Andrew Bartlett 2011
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -23,7 +24,8 @@
 
 #include "includes.h"
 #include "winbindd.h"
-#include "../auth/ntlmssp/ntlmssp.h"
+#include "auth/gensec/gensec.h"
+#include "auth_generic.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
@@ -41,24 +43,19 @@ static bool client_can_access_ccache_entry(uid_t client_uid,
 	return False;
 }
 
-static NTSTATUS do_ntlm_auth_with_hashes(const char *username,
-					const char *domain,
-					const unsigned char lm_hash[LM_HASH_LEN],
-					const unsigned char nt_hash[NT_HASH_LEN],
-					const DATA_BLOB initial_msg,
-					const DATA_BLOB challenge_msg,
-					DATA_BLOB *auth_msg,
-					uint8_t session_key[16])
+static NTSTATUS do_ntlm_auth_with_stored_pw(const char *username,
+					    const char *domain,
+					    const char *password,
+					    const DATA_BLOB initial_msg,
+					    const DATA_BLOB challenge_msg,
+					    DATA_BLOB *auth_msg,
+					    uint8_t session_key[16])
 {
 	NTSTATUS status;
-	struct ntlmssp_state *ntlmssp_state = NULL;
-	DATA_BLOB dummy_msg, reply;
+	struct auth_generic_state *auth_generic_state = NULL;
+	DATA_BLOB dummy_msg, reply, session_key_blob;
 
-	status = ntlmssp_client_start(NULL,
-				      lp_netbios_name(),
-				      lp_workgroup(),
-				      lp_client_ntlmv2_auth(),
-				      &ntlmssp_state);
+	status = auth_generic_client_prepare(NULL, &auth_generic_state);
 
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(1, ("Could not start NTLMSSP client: %s\n",
@@ -66,7 +63,7 @@ static NTSTATUS do_ntlm_auth_with_hashes(const char *username,
 		goto done;
 	}
 
-	status = ntlmssp_set_username(ntlmssp_state, username);
+	status = auth_generic_set_username(auth_generic_state, username);
 
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(1, ("Could not set username: %s\n",
@@ -74,7 +71,7 @@ static NTSTATUS do_ntlm_auth_with_hashes(const char *username,
 		goto done;
 	}
 
-	status = ntlmssp_set_domain(ntlmssp_state, domain);
+	status = auth_generic_set_domain(auth_generic_state, domain);
 
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(1, ("Could not set domain: %s\n",
@@ -82,15 +79,22 @@ static NTSTATUS do_ntlm_auth_with_hashes(const char *username,
 		goto done;
 	}
 
-	status = ntlmssp_set_hashes(ntlmssp_state, lm_hash, nt_hash);
+	status = auth_generic_set_password(auth_generic_state, password);
 
 	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(1, ("Could not set hashes: %s\n",
+		DEBUG(1, ("Could not set password: %s\n",
 			nt_errstr(status)));
 		goto done;
 	}
 
-	ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
+	gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SESSION_KEY);
+
+	status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP);
+	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(1, ("Could not start NTLMSSP mech: %s\n",
+			nt_errstr(status)));
+		goto done;
+	}
 
 	/* We need to get our protocol handler into the right state. So first
 	   we ask it to generate the initial message. Actually the client has already
@@ -104,8 +108,8 @@ static NTSTATUS do_ntlm_auth_with_hashes(const char *username,
 	*/
 	dummy_msg = data_blob_null;
 	reply = data_blob_null;
-	status = ntlmssp_update(ntlmssp_state, dummy_msg, &reply);
-	data_blob_free(&dummy_msg);
+	status = gensec_update(auth_generic_state->gensec_security,
+			       talloc_tos(), NULL, dummy_msg, &reply);
 	data_blob_free(&reply);
 
 	if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
@@ -115,8 +119,8 @@ static NTSTATUS do_ntlm_auth_with_hashes(const char *username,
 	}
 
 	/* Now we are ready to handle the server's actual response. */
-	status = ntlmssp_update(ntlmssp_state, challenge_msg, &reply);
-
+	status = gensec_update(auth_generic_state->gensec_security,
+			       NULL, NULL, challenge_msg, &reply);
 	if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
 		DEBUG(1, ("We didn't get a response to the challenge! [%s]\n",
 			nt_errstr(status)));
@@ -124,19 +128,28 @@ static NTSTATUS do_ntlm_auth_with_hashes(const char *username,
 		goto done;
 	}
 
-	if (ntlmssp_state->session_key.length != 16) {
-		DEBUG(1, ("invalid session key length %d\n",
-			  (int)ntlmssp_state->session_key.length));
+	status = gensec_session_key(auth_generic_state->gensec_security,
+				    talloc_tos(), &session_key_blob);
+	if (!NT_STATUS_EQUAL(status, NT_STATUS_OK)) {
+		DEBUG(1, ("We didn't get the session key we requested! [%s]\n",
+			nt_errstr(status)));
 		data_blob_free(&reply);
 		goto done;
 	}
 
-	*auth_msg = data_blob(reply.data, reply.length);
-	memcpy(session_key, ntlmssp_state->session_key.data, 16);
+	if (session_key_blob.length != 16) {
+		DEBUG(1, ("invalid session key length %d\n",
+			  (int)session_key_blob.length));
+		data_blob_free(&reply);
+		goto done;
+	}
+	memcpy(session_key, session_key_blob.data, 16);
+	data_blob_free(&session_key_blob);
+	*auth_msg = reply;
 	status = NT_STATUS_OK;
 
 done:
-	TALLOC_FREE(ntlmssp_state);
+	TALLOC_FREE(auth_generic_state);
 	return status;
 }
 
@@ -257,8 +270,8 @@ void winbindd_ccache_ntlm_auth(struct winbindd_cli_state *state)
 		state->request->extra_data.data + initial_blob_len,
 		state->request->data.ccache_ntlm_auth.challenge_blob_len);
 
-	result = do_ntlm_auth_with_hashes(
-		name_user, name_domain, entry->lm_hash, entry->nt_hash,
+	result = do_ntlm_auth_with_stored_pw(
+		name_user, name_domain, entry->pass,
 		initial, challenge, &auth,
 		state->response->data.ccache_ntlm_auth.session_key);
 
diff --git a/source4/auth/ntlmssp/ntlmssp_client.c b/source4/auth/ntlmssp/ntlmssp_client.c
index d5ece11..6e372dc 100644
--- a/source4/auth/ntlmssp/ntlmssp_client.c
+++ b/source4/auth/ntlmssp/ntlmssp_client.c
@@ -32,6 +32,8 @@ struct auth_session_info;
 #include "auth/gensec/gensec.h"
 #include "param/param.h"
 #include "auth/ntlmssp/ntlmssp_private.h"
+#include "../librpc/gen_ndr/ndr_ntlmssp.h"
+#include "../auth/ntlmssp/ntlmssp_ndr.h"
 
 /*********************************************************************
  Client side NTLMSSP
@@ -55,8 +57,8 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security,
 		talloc_get_type_abort(gensec_security->private_data,
 				      struct gensec_ntlmssp_context);
 	struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
-	const char *domain = ntlmssp_state->domain;
-	const char *workstation = cli_credentials_get_workstation(gensec_security->credentials);
+	const char *domain = ntlmssp_state->client.netbios_domain;
+	const char *workstation = ntlmssp_state->client.netbios_name;
 	NTSTATUS status;
 
 	/* These don't really matter in the initial packet, so don't panic if they are not set */
@@ -73,24 +75,40 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security,
 	} else {
 		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
 	}
-	
+
 	if (ntlmssp_state->use_ntlmv2) {
 		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
 	}
 
 	/* generate the ntlmssp negotiate packet */
-	status = msrpc_gen(out_mem_ctx, 
+	status = msrpc_gen(out_mem_ctx,
 		  out, "CddAA",
 		  "NTLMSSP",
 		  NTLMSSP_NEGOTIATE,
 		  ntlmssp_state->neg_flags,
-		  domain, 
+		  domain,
 		  workstation);
 
 	if (!NT_STATUS_IS_OK(status)) {
+		DEBUG(0, ("ntlmssp_client_initial: failed to generate "
+			  "ntlmssp negotiate packet\n"));
 		return status;
 	}
 
+	if (DEBUGLEVEL >= 10) {
+		struct NEGOTIATE_MESSAGE *negotiate = talloc(
+			talloc_tos(), struct NEGOTIATE_MESSAGE);
+		if (negotiate != NULL) {
+			status = ntlmssp_pull_NEGOTIATE_MESSAGE(
+				out, negotiate, negotiate);
+			if (NT_STATUS_IS_OK(status)) {
+				NDR_PRINT_DEBUG(NEGOTIATE_MESSAGE,
+						negotiate);
+			}
+			TALLOC_FREE(negotiate);
+		}
+	}
+
 	ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
 
 	return NT_STATUS_MORE_PROCESSING_REQUIRED;
@@ -349,7 +367,8 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
 
 	ntlmssp_state->role = NTLMSSP_CLIENT;
 
-	ntlmssp_state->domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);
+	ntlmssp_state->client.netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);
+	ntlmssp_state->client.netbios_name = cli_credentials_get_workstation(gensec_security->credentials);
 
 	ntlmssp_state->unicode = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "unicode", true);
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list