[samba/f13/master] More fixes for winbind schannel.

Guenther Deschner gd at fedoraproject.org
Fri Aug 27 11:34:50 UTC 2010


commit 70e2c068a60224457790ecc92d00e72846f13371
Author: Günther Deschner <gd at samba.org>
Date:   Tue Aug 24 15:41:03 2010 +0200

    More fixes for winbind schannel.
    
    Guenther

 samba-3.5.4-winbind-schannel.patch |  235 ++++++++++++++++++++++++++++++++++++
 samba.spec                         |    5 +-
 2 files changed, 239 insertions(+), 1 deletions(-)
---
diff --git a/samba-3.5.4-winbind-schannel.patch b/samba-3.5.4-winbind-schannel.patch
index 5256091..210523d 100644
--- a/samba-3.5.4-winbind-schannel.patch
+++ b/samba-3.5.4-winbind-schannel.patch
@@ -65,3 +65,238 @@ index ee9a656..f8e49cc 100644
 -- 
 1.7.2.1
 
+From fb4d65af7405d0f78674aaea66005e048e2a0536 Mon Sep 17 00:00:00 2001
+From: Jeremy Allison <jra at samba.org>
+Date: Mon, 23 Aug 2010 13:05:56 -0700
+Subject: [PATCH 1/2] Final part of fix for bug #7636 - winbind internal error, backtrace.
+
+Ensure cm_get_schannel_creds() returns NTSTATUS.
+
+Jeremy.
+(cherry picked from commit 33060f67be100836d381a74bced351c6579cc58d)
+---
+ source3/winbindd/winbindd_cm.c |   29 ++++++++++++++++++-----------
+ 1 files changed, 18 insertions(+), 11 deletions(-)
+
+diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
+index f8e49cc..f466a94 100644
+--- a/source3/winbindd/winbindd_cm.c
++++ b/source3/winbindd/winbindd_cm.c
+@@ -2016,30 +2016,30 @@ static void set_dc_type_and_flags( struct winbindd_domain *domain )
+ /**********************************************************************
+ ***********************************************************************/
+
+-static bool cm_get_schannel_creds(struct winbindd_domain *domain,
++static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
+				   struct netlogon_creds_CredentialState **ppdc)
+ {
+-	NTSTATUS result;
++	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+	struct rpc_pipe_client *netlogon_pipe;
+
+	if (lp_client_schannel() == False) {
+-		return False;
++		return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;;
+	}
+
+	result = cm_connect_netlogon(domain, &netlogon_pipe);
+	if (!NT_STATUS_IS_OK(result)) {
+-		return False;
++		return result;
+	}
+
+	/* Return a pointer to the struct netlogon_creds_CredentialState from the
+	   netlogon pipe. */
+
+	if (!domain->conn.netlogon_pipe->dc) {
+-		return false;
++		return NT_STATUS_INTERNAL_ERROR; /* This shouldn't happen. */
+	}
+
+	*ppdc = domain->conn.netlogon_pipe->dc;
+-	return True;
++	return NT_STATUS_OK;
+ }
+
+ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
+@@ -2136,10 +2136,13 @@ NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
+
+	/* Fall back to schannel if it's a W2K pre-SP1 box. */
+
+-	if (!cm_get_schannel_creds(domain, &p_creds)) {
++	result = cm_get_schannel_creds(domain, &p_creds);
++	if (!NT_STATUS_IS_OK(result)) {
+		/* If this call fails - conn->cli can now be NULL ! */
+		DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
+-			   "for domain %s, trying anon\n", domain->name));
++			   "for domain %s (error %s), trying anon\n",
++			domain->name,
++			nt_errstr(result) ));
+		goto anonymous;
+	}
+	result = cli_rpc_pipe_open_schannel_with_key
+@@ -2252,7 +2255,8 @@ NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
+
+	TALLOC_FREE(conn->lsa_pipe_tcp);
+
+-	if (!cm_get_schannel_creds(domain, &creds)) {
++	status = cm_get_schannel_creds(domain, &creds);
++	if (!NT_STATUS_IS_OK(status)) {
+		goto done;
+	}
+
+@@ -2344,10 +2348,13 @@ NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
+
+	/* Fall back to schannel if it's a W2K pre-SP1 box. */
+
+-	if (!cm_get_schannel_creds(domain, &p_creds)) {
++	result = cm_get_schannel_creds(domain, &p_creds);
++	if (!NT_STATUS_IS_OK(result)) {
+		/* If this call fails - conn->cli can now be NULL ! */
+		DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
+-			   "for domain %s, trying anon\n", domain->name));
++			   "for domain %s (error %s), trying anon\n",
++			domain->name,
++			nt_errstr(result) ));
+		goto anonymous;
+	}
+	result = cli_rpc_pipe_open_schannel_with_key
+--
+1.7.2.1
+
+
+From 703ce6f46e3d58476e0a31c8b258d7d194ea0315 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
+Date: Mon, 23 Aug 2010 16:02:23 +0200
+Subject: [PATCH 2/2] s3-dcerpc: avoid talloc_move on schannel creds in cli_rpc_pipe_open_schannel_with_key().
+
+Initially, the schannel creds were talloc memduped, then, during the netlogon
+creds client merge (baf7274fed2f1ae7a9e3a57160bf5471566e636c) they were first
+talloc_referenced and then later (53765c81f726a8c056cc4e57004592dd489975c9)
+talloc_moved.
+
+The issue with using talloc_move here is that users of that function in winbind
+will only be able to have two schanneled connections, as the cached schannel
+credentials pointer from the netlogon pipe will be set to NULL. Do a deep copy
+of the struct instead.
+
+Guenther
+(cherry picked from commit 898c6123355a3a11ec17f0396c4cb3018c75c184)
+---
+ libcli/auth/credentials.c     |   46 ++++++++++++++++++++++++++++++++++++++++-
+ libcli/auth/proto.h           |    2 +
+ source3/rpc_client/cli_pipe.c |   10 ++++++--
+ 3 files changed, 54 insertions(+), 4 deletions(-)
+
+diff --git a/libcli/auth/credentials.c b/libcli/auth/credentials.c
+index 87d1866..504f594 100644
+--- a/libcli/auth/credentials.c
++++ b/libcli/auth/credentials.c
+@@ -24,6 +24,7 @@
+ #include "system/time.h"
+ #include "../lib/crypto/crypto.h"
+ #include "libcli/auth/libcli_auth.h"
++#include "../libcli/security/dom_sid.h"
+
+ static void netlogon_creds_step_crypt(struct netlogon_creds_CredentialState *creds,
+				      const struct netr_Credential *in,
+@@ -202,7 +203,7 @@ struct netlogon_creds_CredentialState *netlogon_creds_client_init(TALLOC_CTX *me
+								  struct netr_Credential *initial_credential,
+								  uint32_t negotiate_flags)
+ {
+-	struct netlogon_creds_CredentialState *creds = talloc(mem_ctx, struct netlogon_creds_CredentialState);
++	struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState);
+
+	if (!creds) {
+		return NULL;
+@@ -453,3 +454,46 @@ void netlogon_creds_decrypt_samlogon(struct netlogon_creds_CredentialState *cred
+	}
+ }
+
++/*
++  copy a netlogon_creds_CredentialState struct
++*/
++
++struct netlogon_creds_CredentialState *netlogon_creds_copy(TALLOC_CTX *mem_ctx,
++							   struct netlogon_creds_CredentialState *creds_in)
++{
++	struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState);
++
++	if (!creds) {
++		return NULL;
++	}
++
++	creds->sequence			= creds_in->sequence;
++	creds->negotiate_flags		= creds_in->negotiate_flags;
++	creds->secure_channel_type	= creds_in->secure_channel_type;
++
++	creds->computer_name = talloc_strdup(creds, creds_in->computer_name);
++	if (!creds->computer_name) {
++		talloc_free(creds);
++		return NULL;
++	}
++	creds->account_name = talloc_strdup(creds, creds_in->account_name);
++	if (!creds->account_name) {
++		talloc_free(creds);
++		return NULL;
++	}
++
++	if (creds_in->sid) {
++		creds->sid = dom_sid_dup(creds, creds_in->sid);
++		if (!creds->sid) {
++			talloc_free(creds);
++			return NULL;
++		}
++	}
++
++	memcpy(creds->session_key, creds_in->session_key, sizeof(creds->session_key));
++	memcpy(creds->seed.data, creds_in->seed.data, sizeof(creds->seed.data));
++	memcpy(creds->client.data, creds_in->client.data, sizeof(creds->client.data));
++	memcpy(creds->server.data, creds_in->server.data, sizeof(creds->server.data));
++
++	return creds;
++}
+diff --git a/libcli/auth/proto.h b/libcli/auth/proto.h
+index e09cdee..c3878f5 100644
+--- a/libcli/auth/proto.h
++++ b/libcli/auth/proto.h
+@@ -35,6 +35,8 @@ void netlogon_creds_client_authenticator(struct netlogon_creds_CredentialState *
+				struct netr_Authenticator *next);
+ bool netlogon_creds_client_check(struct netlogon_creds_CredentialState *creds,
+			const struct netr_Credential *received_credentials);
++struct netlogon_creds_CredentialState *netlogon_creds_copy(TALLOC_CTX *mem_ctx,
++							   struct netlogon_creds_CredentialState *creds_in);
+
+ /*****************************************************************
+ The above functions are common to the client and server interface
+diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
+index ee60c1d..06b9c5d 100644
+--- a/source3/rpc_client/cli_pipe.c
++++ b/source3/rpc_client/cli_pipe.c
+@@ -3213,7 +3213,7 @@ NTSTATUS rpccli_schannel_bind_data(TALLOC_CTX *mem_ctx, const char *domain,
+	result->a_u.schannel_auth->state = SCHANNEL_STATE_START;
+	result->a_u.schannel_auth->seq_num = 0;
+	result->a_u.schannel_auth->initiator = true;
+-	result->a_u.schannel_auth->creds = creds;
++	result->a_u.schannel_auth->creds = netlogon_creds_copy(result, creds);
+
+	*presult = result;
+	return NT_STATUS_OK;
+@@ -4044,9 +4044,13 @@ NTSTATUS cli_rpc_pipe_open_schannel_with_key(struct cli_state *cli,
+
+	/*
+	 * The credentials on a new netlogon pipe are the ones we are passed
+-	 * in - reference them in
++	 * in - copy them over
+	 */
+-	result->dc = talloc_move(result, pdc);
++	result->dc = netlogon_creds_copy(result, *pdc);
++	if (result->dc == NULL) {
++		TALLOC_FREE(result);
++		return NT_STATUS_NO_MEMORY;
++	}
+
+	DEBUG(10,("cli_rpc_pipe_open_schannel_with_key: opened pipe %s to machine %s "
+		  "for domain %s and bound using schannel.\n",
+--
+1.7.2.1
diff --git a/samba.spec b/samba.spec
index a768f79..746d67b 100644
--- a/samba.spec
+++ b/samba.spec
@@ -1,4 +1,4 @@
-%define main_release 65
+%define main_release 66
 %define samba_version 3.5.4
 %define tdb_version 1.2.1
 %define talloc_version 2.0.1
@@ -654,6 +654,9 @@ exit 0
 %{_datadir}/pixmaps/samba/logo-small.png
 
 %changelog
+* Tue Aug 24 2010 Guenther Deschner <gdeschner at redhat.com> - 3.5.4-66
+- More fixes for winbind schannel
+
 * Thu Aug 19 2010 Guenther Deschner <gdeschner at redhat.com> - 3.5.4-65
 - Fix winbind default domain
 - related: #618201


More information about the scm-commits mailing list