[SCM] Samba Shared Repository - branch master updated

Andreas Schneider asn at samba.org
Wed Dec 14 07:40:05 MST 2011


The branch, master has been updated
       via  be288b0 s4-torture: LookupSids3 is only available over NCACN_IP_TCP.
       via  e917c7b s4-torture: Fix schannel test against win2k8.
       via  17d1244 s4-librpc: Fix NETLOGON credential chain with Windows 2008.
      from  ffa996e s3:smb2_lock: use talloc_get_type_abort() as private_data can't be NULL

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


- Log -----------------------------------------------------------------
commit be288b0c82be3f796816e79744a79817cfcbce7f
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Dec 13 14:49:27 2011 +0100

    s4-torture: LookupSids3 is only available over NCACN_IP_TCP.
    
    Autobuild-User: Andreas Schneider <asn at cryptomilk.org>
    Autobuild-Date: Wed Dec 14 15:39:58 CET 2011 on sn-devel-104

commit e917c7b0ee4d72d6dfb1b50f1de8645063dc9df3
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Dec 13 15:20:53 2011 +0100

    s4-torture: Fix schannel test against win2k8.

commit 17d124490b79cf14e53263eaef333756e18f7ff2
Author: Andreas Schneider <asn at samba.org>
Date:   Mon Dec 12 19:28:49 2011 +0100

    s4-librpc: Fix NETLOGON credential chain with Windows 2008.
    
    Windows Server 2008 returns NT_STATUS_DOWNGRADE_DETECTED if you call
    netrServerAuthenticate2 during a domain join without setting the strong
    keys flag (128bit crypto).
    
    Only for NT4 we need to do a downgrade to the returned negotiate flags.
    
    See also 0970369ca0cb9ae465cff40e5c75739824daf1d0.

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

Summary of changes:
 librpc/rpc/rpc_common.h              |    3 ++
 source4/librpc/rpc/dcerpc_schannel.c |   49 +++++++++++++++++++++++++++------
 source4/torture/rpc/lsa.c            |    3 +-
 source4/torture/rpc/schannel.c       |    8 +++---
 source4/winbind/wb_init_domain.c     |    4 +-
 5 files changed, 51 insertions(+), 16 deletions(-)


Changeset truncated at 500 lines:

diff --git a/librpc/rpc/rpc_common.h b/librpc/rpc/rpc_common.h
index 44c3cfd..a28835f 100644
--- a/librpc/rpc/rpc_common.h
+++ b/librpc/rpc/rpc_common.h
@@ -107,6 +107,9 @@ struct dcerpc_binding {
 /* specify binding interface */
 #define	DCERPC_LOCALADDRESS            (1<<22)
 
+/* handle upgrades or downgrades automatically */
+#define DCERPC_SCHANNEL_AUTO           (1<<23)
+
 /* The following definitions come from ../librpc/rpc/dcerpc_error.c  */
 
 const char *dcerpc_errstr(TALLOC_CTX *mem_ctx, uint32_t fault_code);
diff --git a/source4/librpc/rpc/dcerpc_schannel.c b/source4/librpc/rpc/dcerpc_schannel.c
index fc56ecc..9501e3e 100644
--- a/source4/librpc/rpc/dcerpc_schannel.c
+++ b/source4/librpc/rpc/dcerpc_schannel.c
@@ -36,9 +36,11 @@ struct schannel_key_state {
 	struct dcerpc_pipe *pipe;
 	struct dcerpc_pipe *pipe2;
 	struct dcerpc_binding *binding;
+	bool dcerpc_schannel_auto;
 	struct cli_credentials *credentials;
 	struct netlogon_creds_CredentialState *creds;
-	uint32_t negotiate_flags;
+	uint32_t local_negotiate_flags;
+	uint32_t remote_negotiate_flags;
 	struct netr_Credential credentials1;
 	struct netr_Credential credentials2;
 	struct netr_Credential credentials3;
@@ -176,16 +178,17 @@ static void continue_srv_challenge(struct tevent_req *subreq)
 	s->a.in.secure_channel_type =
 		cli_credentials_get_secure_channel_type(s->credentials);
 	s->a.in.computer_name    = cli_credentials_get_workstation(s->credentials);
-	s->a.in.negotiate_flags  = &s->negotiate_flags;
+	s->a.in.negotiate_flags  = &s->local_negotiate_flags;
 	s->a.in.credentials      = &s->credentials3;
-	s->a.out.negotiate_flags = &s->negotiate_flags;
+	s->a.out.negotiate_flags = &s->remote_negotiate_flags;
 	s->a.out.return_credentials     = &s->credentials3;
 
 	s->creds = netlogon_creds_client_init(s, 
 					      s->a.in.account_name, 
 					      s->a.in.computer_name,
 					      &s->credentials1, &s->credentials2,
-					      s->mach_pwd, &s->credentials3, s->negotiate_flags);
+					      s->mach_pwd, &s->credentials3,
+					      s->local_negotiate_flags);
 	if (composite_nomem(s->creds, c)) {
 		return;
 	}
@@ -218,6 +221,30 @@ static void continue_srv_auth2(struct tevent_req *subreq)
 	TALLOC_FREE(subreq);
 	if (!composite_is_ok(c)) return;
 
+	/*
+	 * Strong keys could be unsupported (NT4) or disables. So retry with the
+	 * flags returned by the server. - asn
+	 */
+	if (NT_STATUS_EQUAL(s->a.out.result, NT_STATUS_ACCESS_DENIED) &&
+	    s->dcerpc_schannel_auto &&
+	    (s->local_negotiate_flags & NETLOGON_NEG_STRONG_KEYS)) {
+		DEBUG(3, ("Server doesn't support strong keys, "
+			  "downgrade and retry!\n"));
+		s->local_negotiate_flags = s->remote_negotiate_flags;
+
+		generate_random_buffer(s->credentials1.data,
+				       sizeof(s->credentials1.data));
+
+		subreq = dcerpc_netr_ServerReqChallenge_r_send(s,
+							       c->event_ctx,
+							       s->pipe2->binding_handle,
+							       &s->r);
+		if (composite_nomem(subreq, c)) return;
+
+		tevent_req_set_callback(subreq, continue_srv_challenge, c);
+		return;
+	}
+
 	/* verify credentials */
 	if (!netlogon_creds_client_check(s->creds, s->a.out.return_credentials)) {
 		composite_error(c, NT_STATUS_UNSUCCESSFUL);
@@ -256,15 +283,19 @@ struct composite_context *dcerpc_schannel_key_send(TALLOC_CTX *mem_ctx,
 	/* store parameters in the state structure */
 	s->pipe        = p;
 	s->credentials = credentials;
+	s->local_negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
 
 	/* allocate credentials */
 	/* type of authentication depends on schannel type */
 	if (schannel_type == SEC_CHAN_RODC) {
-		s->negotiate_flags = NETLOGON_NEG_AUTH2_RODC_FLAGS;
-	} else if (s->pipe->conn->flags & DCERPC_SCHANNEL_128) {
-		s->negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
-	} else {
-		s->negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
+		s->local_negotiate_flags = NETLOGON_NEG_AUTH2_RODC_FLAGS;
+	}
+	if (s->pipe->conn->flags & DCERPC_SCHANNEL_128) {
+		s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
+	}
+	if (s->pipe->conn->flags & DCERPC_SCHANNEL_AUTO) {
+		s->local_negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
+		s->dcerpc_schannel_auto = true;
 	}
 
 	/* allocate binding structure */
diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c
index f444ef2..f420ec1 100644
--- a/source4/torture/rpc/lsa.c
+++ b/source4/torture/rpc/lsa.c
@@ -753,7 +753,8 @@ bool test_many_LookupSids(struct dcerpc_pipe *p,
 			return false;
 		}
 	} else if (p->conn->security_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL &&
-		   p->conn->security_state.auth_info->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY) {
+		   p->conn->security_state.auth_info->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY &&
+		   (p->binding->transport == NCACN_IP_TCP || p->binding->transport == NCALRPC)) {
 		struct lsa_LookupSids3 r;
 		struct lsa_RefDomainList *domains = NULL;
 		struct lsa_TransNameArray2 names;
diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c
index 2874eaf..7eb5148 100644
--- a/source4/torture/rpc/schannel.c
+++ b/source4/torture/rpc/schannel.c
@@ -426,12 +426,12 @@ bool torture_rpc_schannel(struct torture_context *torture)
 		uint16_t acct_flags;
 		uint32_t dcerpc_flags;
 	} tests[] = {
-		{ ACB_WSTRUST,   DCERPC_SCHANNEL | DCERPC_SIGN},
-		{ ACB_WSTRUST,   DCERPC_SCHANNEL | DCERPC_SEAL},
+		{ ACB_WSTRUST,   DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_AUTO},
+		{ ACB_WSTRUST,   DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_AUTO},
 		{ ACB_WSTRUST,   DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128},
 		{ ACB_WSTRUST,   DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_128 },
-		{ ACB_SVRTRUST,  DCERPC_SCHANNEL | DCERPC_SIGN },
-		{ ACB_SVRTRUST,  DCERPC_SCHANNEL | DCERPC_SEAL },
+		{ ACB_SVRTRUST,  DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_AUTO},
+		{ ACB_SVRTRUST,  DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_AUTO},
 		{ ACB_SVRTRUST,  DCERPC_SCHANNEL | DCERPC_SIGN | DCERPC_SCHANNEL_128 },
 		{ ACB_SVRTRUST,  DCERPC_SCHANNEL | DCERPC_SEAL | DCERPC_SCHANNEL_128 }
 	};
diff --git a/source4/winbind/wb_init_domain.c b/source4/winbind/wb_init_domain.c
index 9847afb..9d807d8 100644
--- a/source4/winbind/wb_init_domain.c
+++ b/source4/winbind/wb_init_domain.c
@@ -154,7 +154,7 @@ struct composite_context *wb_init_domain_send(TALLOC_CTX *mem_ctx,
 	     (lpcfg_server_role(service->task->lp_ctx) == ROLE_DOMAIN_CONTROLLER)) &&
 	    (dom_sid_equal(state->domain->info->sid,
 			   state->service->primary_sid))) {
-		state->domain->netlogon_binding->flags |= DCERPC_SCHANNEL | DCERPC_SCHANNEL_128;
+		state->domain->netlogon_binding->flags |= DCERPC_SCHANNEL | DCERPC_SCHANNEL_AUTO;
 
 		/* For debugging, it can be a real pain if all the traffic is encrypted */
 		if (lpcfg_winbind_sealed_pipes(service->task->lp_ctx)) {
@@ -236,7 +236,7 @@ static bool retry_with_schannel(struct init_domain_state *state,
 		 * NTLMSSP binds */
 
 		/* Try again with schannel */
-		binding->flags |= DCERPC_SCHANNEL;
+		binding->flags |= DCERPC_SCHANNEL | DCERPC_SCHANNEL_AUTO;
 
 		/* Try again, likewise on the same IPC$ share, 
 		   secured with SCHANNEL */


-- 
Samba Shared Repository


More information about the samba-cvs mailing list