[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Fri Feb 4 10:12:01 MST 2011


The branch, master has been updated
       via  f60398d s3-winbindd: let winbind try to use samlogon validation level 6. (bug #7945)
       via  ac4127a s3-auth: add copy_netr_SamBaseInfo().
      from  e9c45a3 s3:lib/addrchange: set ctx->sock to -1 after close

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


- Log -----------------------------------------------------------------
commit f60398d7b20869d7b09d81854f3727fdcd897430
Author: Günther Deschner <gd at samba.org>
Date:   Fri Jan 7 17:28:29 2011 +0100

    s3-winbindd: let winbind try to use samlogon validation level 6. (bug #7945)
    
    The benefit of this that it makes us more robust to secure channel resets
    triggered from tools outside the winbind process. Long term we need to have a
    shared tdb secure channel store though as well.
    
    Guenther
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>
    
    Autobuild-User: Stefan Metzmacher <metze at samba.org>
    Autobuild-Date: Fri Feb  4 18:11:04 CET 2011 on sn-devel-104

commit ac4127a9f432f762cb728c161d7fbf80de31b60e
Author: Günther Deschner <gd at samba.org>
Date:   Tue Jan 11 15:08:41 2011 +0100

    s3-auth: add copy_netr_SamBaseInfo().
    
    Guenther
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

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

Summary of changes:
 source3/Makefile.in                |    3 +-
 source3/auth/auth_domain.c         |    1 +
 source3/auth/auth_netlogond.c      |    1 +
 source3/auth/server_info.c         |   62 +++--------------------------------
 source3/rpc_client/cli_netlogon.c  |   62 +++++++++++++++++++++++++++++++++--
 source3/rpc_client/cli_netlogon.h  |    2 +
 source3/rpc_client/util_netlogon.c |   63 ++++++++++++++++++++++++++++++++++++
 source3/rpc_client/util_netlogon.h |    5 +++
 source3/winbindd/winbindd.h        |    1 +
 source3/winbindd/winbindd_cm.c     |    1 +
 source3/winbindd/winbindd_pam.c    |   59 ++++++++++++++++++++++++++++++++-
 source3/wscript_build              |    2 +-
 12 files changed, 198 insertions(+), 64 deletions(-)
 create mode 100644 source3/rpc_client/util_netlogon.c
 create mode 100644 source3/rpc_client/util_netlogon.h


Changeset truncated at 500 lines:

diff --git a/source3/Makefile.in b/source3/Makefile.in
index 09cd713..ebfee9f 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -375,7 +375,8 @@ LIBCLI_SAMR_OBJ = librpc/gen_ndr/ndr_samr_c.o \
 		  rpc_client/cli_samr.o
 
 LIBCLI_NETLOGON_OBJ = librpc/gen_ndr/ndr_netlogon_c.o \
-		      rpc_client/cli_netlogon.o
+		      rpc_client/cli_netlogon.o \
+		      rpc_client/util_netlogon.o
 
 LIBCLI_EPMAPPER_OBJ = librpc/gen_ndr/ndr_epmapper_c.o
 
diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c
index 0f541cd..05421de 100644
--- a/source3/auth/auth_domain.c
+++ b/source3/auth/auth_domain.c
@@ -309,6 +309,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
 						      user_info->client.domain_name,       /* domain name */
 						      user_info->workstation_name,         /* workstation name */
 						      chal,                                /* 8 byte challenge. */
+						      3,				   /* validation level */
 						      user_info->password.response.lanman, /* lanman 24 byte response */
 						      user_info->password.response.nt,     /* nt 24 byte response */
 						      &info3);                             /* info3 out */
diff --git a/source3/auth/auth_netlogond.c b/source3/auth/auth_netlogond.c
index 889371c..1e3ccb1 100644
--- a/source3/auth/auth_netlogond.c
+++ b/source3/auth/auth_netlogond.c
@@ -88,6 +88,7 @@ static NTSTATUS netlogond_validate(TALLOC_CTX *mem_ctx,
 		user_info->client.domain_name,         /* domain name */
 		user_info->workstation_name,           /* workstation name */
 		(uchar *)auth_context->challenge.data, /* 8 byte challenge. */
+		3,				       /* validation level */
 		user_info->password.response.lanman,   /* lanman 24 byte response */
 		user_info->password.response.nt,       /* nt 24 byte response */
 		&info3);                               /* info3 out */
diff --git a/source3/auth/server_info.c b/source3/auth/server_info.c
index 01c7a96..0f62983 100644
--- a/source3/auth/server_info.c
+++ b/source3/auth/server_info.c
@@ -21,6 +21,7 @@
 #include "../lib/crypto/arcfour.h"
 #include "../librpc/gen_ndr/netlogon.h"
 #include "../libcli/security/security.h"
+#include "rpc_client/util_netlogon.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_AUTH
@@ -490,66 +491,15 @@ struct netr_SamInfo3 *copy_netr_SamInfo3(TALLOC_CTX *mem_ctx,
 {
 	struct netr_SamInfo3 *info3;
 	unsigned int i;
+	NTSTATUS status;
 
 	info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
 	if (!info3) return NULL;
 
-	/* first copy all, then realloc pointers */
-	info3->base = orig->base;
-
-	if (orig->base.account_name.string) {
-		info3->base.account_name.string	=
-			talloc_strdup(info3, orig->base.account_name.string);
-		RET_NOMEM(info3->base.account_name.string);
-	}
-	if (orig->base.full_name.string) {
-		info3->base.full_name.string =
-			talloc_strdup(info3, orig->base.full_name.string);
-		RET_NOMEM(info3->base.full_name.string);
-	}
-	if (orig->base.logon_script.string) {
-		info3->base.logon_script.string =
-			talloc_strdup(info3, orig->base.logon_script.string);
-		RET_NOMEM(info3->base.logon_script.string);
-	}
-	if (orig->base.profile_path.string) {
-		info3->base.profile_path.string	=
-			talloc_strdup(info3, orig->base.profile_path.string);
-		RET_NOMEM(info3->base.profile_path.string);
-	}
-	if (orig->base.home_directory.string) {
-		info3->base.home_directory.string =
-			talloc_strdup(info3, orig->base.home_directory.string);
-		RET_NOMEM(info3->base.home_directory.string);
-	}
-	if (orig->base.home_drive.string) {
-		info3->base.home_drive.string =
-			talloc_strdup(info3, orig->base.home_drive.string);
-		RET_NOMEM(info3->base.home_drive.string);
-	}
-
-	if (orig->base.groups.count) {
-		info3->base.groups.rids = (struct samr_RidWithAttribute *)
-			talloc_memdup(info3, orig->base.groups.rids,
-				(sizeof(struct samr_RidWithAttribute) *
-					orig->base.groups.count));
-		RET_NOMEM(info3->base.groups.rids);
-	}
-
-	if (orig->base.logon_server.string) {
-		info3->base.logon_server.string =
-			talloc_strdup(info3, orig->base.logon_server.string);
-		RET_NOMEM(info3->base.logon_server.string);
-	}
-	if (orig->base.domain.string) {
-		info3->base.domain.string =
-			talloc_strdup(info3, orig->base.domain.string);
-		RET_NOMEM(info3->base.domain.string);
-	}
-
-	if (orig->base.domain_sid) {
-		info3->base.domain_sid = dom_sid_dup(info3, orig->base.domain_sid);
-		RET_NOMEM(info3->base.domain_sid);
+	status = copy_netr_SamBaseInfo(info3, &orig->base, &info3->base);
+	if (!NT_STATUS_IS_OK(status)) {
+		TALLOC_FREE(info3);
+		return NULL;
 	}
 
 	if (orig->sidcount) {
diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index 914bfd3..f34d794 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -25,6 +25,8 @@
 #include "../librpc/gen_ndr/ndr_netlogon_c.h"
 #include "rpc_client/cli_netlogon.h"
 #include "rpc_client/init_netlogon.h"
+#include "rpc_client/util_netlogon.h"
+#include "../libcli/security/security.h"
 
 /****************************************************************************
  Wrapper function that uses the auth and auth2 calls to set up a NETLOGON
@@ -298,6 +300,52 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli,
 	return result;
 }
 
+static NTSTATUS map_validation_to_info3(TALLOC_CTX *mem_ctx,
+					uint16_t validation_level,
+					union netr_Validation *validation,
+					struct netr_SamInfo3 **info3_p)
+{
+	struct netr_SamInfo3 *info3;
+	NTSTATUS status;
+
+	if (validation == NULL) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	switch (validation_level) {
+	case 3:
+		if (validation->sam3 == NULL) {
+			return NT_STATUS_INVALID_PARAMETER;
+		}
+
+		info3 = talloc_move(mem_ctx, &validation->sam3);
+		break;
+	case 6:
+		if (validation->sam6 == NULL) {
+			return NT_STATUS_INVALID_PARAMETER;
+		}
+
+		info3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
+		if (info3 == NULL) {
+			return NT_STATUS_NO_MEMORY;
+		}
+		status = copy_netr_SamBaseInfo(info3, &validation->sam6->base, &info3->base);
+		if (!NT_STATUS_IS_OK(status)) {
+			TALLOC_FREE(info3);
+			return status;
+		}
+
+		info3->sidcount = validation->sam6->sidcount;
+		info3->sids = talloc_move(info3, &validation->sam6->sids);
+		break;
+	default:
+		return NT_STATUS_BAD_VALIDATION_CLASS;
+	}
+
+	*info3_p = info3;
+
+	return NT_STATUS_OK;
+}
 
 /**
  * Logon domain user with an 'network' SAM logon
@@ -313,13 +361,13 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
 					   const char *domain,
 					   const char *workstation,
 					   const uint8 chal[8],
+					   uint16_t validation_level,
 					   DATA_BLOB lm_response,
 					   DATA_BLOB nt_response,
 					   struct netr_SamInfo3 **info3)
 {
 	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
 	NTSTATUS status;
-	int validation_level = 3;
 	const char *workstation_name_slash;
 	const char *server_name_slash;
 	struct netr_Authenticator clnt_creds;
@@ -417,7 +465,10 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
 
 	netlogon_creds_decrypt_samlogon(cli->dc, validation_level, &validation);
 
-	*info3 = validation.sam3;
+	result = map_validation_to_info3(mem_ctx, validation_level, &validation, info3);
+	if (!NT_STATUS_IS_OK(result)) {
+		return result;
+	}
 
 	return result;
 }
@@ -430,13 +481,13 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli,
 					      const char *domain,
 					      const char *workstation,
 					      const uint8 chal[8],
+					      uint16_t validation_level,
 					      DATA_BLOB lm_response,
 					      DATA_BLOB nt_response,
 					      struct netr_SamInfo3 **info3)
 {
 	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
 	NTSTATUS status;
-	int validation_level = 3;
 	const char *workstation_name_slash;
 	const char *server_name_slash;
 	union netr_LogonLevel *logon = NULL;
@@ -522,7 +573,10 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli,
 
 	netlogon_creds_decrypt_samlogon(cli->dc, validation_level, &validation);
 
-	*info3 = validation.sam3;
+	result = map_validation_to_info3(mem_ctx, validation_level, &validation, info3);
+	if (!NT_STATUS_IS_OK(result)) {
+		return result;
+	}
 
 	return result;
 }
diff --git a/source3/rpc_client/cli_netlogon.h b/source3/rpc_client/cli_netlogon.h
index bb38b75..808a428 100644
--- a/source3/rpc_client/cli_netlogon.h
+++ b/source3/rpc_client/cli_netlogon.h
@@ -25,6 +25,7 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli,
 					   const char *domain,
 					   const char *workstation,
 					   const uint8 chal[8],
+					   uint16_t validation_level,
 					   DATA_BLOB lm_response,
 					   DATA_BLOB nt_response,
 					   struct netr_SamInfo3 **info3);
@@ -36,6 +37,7 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli,
 					      const char *domain,
 					      const char *workstation,
 					      const uint8 chal[8],
+					      uint16_t validation_level,
 					      DATA_BLOB lm_response,
 					      DATA_BLOB nt_response,
 					      struct netr_SamInfo3 **info3);
diff --git a/source3/rpc_client/util_netlogon.c b/source3/rpc_client/util_netlogon.c
new file mode 100644
index 0000000..558a4da
--- /dev/null
+++ b/source3/rpc_client/util_netlogon.c
@@ -0,0 +1,63 @@
+/*
+   Unix SMB/CIFS implementation.
+   Authentication utility functions
+   Copyright (C) Volker Lendecke 2010
+
+   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
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "../librpc/gen_ndr/netlogon.h"
+#include "../libcli/security/security.h"
+#include "rpc_client/util_netlogon.h"
+
+#define COPY_LSA_STRING(mem_ctx, in, out, name) do { \
+	if (in->name.string) { \
+		out->name.string = talloc_strdup(mem_ctx, in->name.string); \
+		NT_STATUS_HAVE_NO_MEMORY(out->name.string); \
+	} \
+} while (0)
+
+NTSTATUS copy_netr_SamBaseInfo(TALLOC_CTX *mem_ctx,
+			       const struct netr_SamBaseInfo *in,
+			       struct netr_SamBaseInfo *out)
+{
+	/* first copy all, then realloc pointers */
+	*out = *in;
+
+	COPY_LSA_STRING(mem_ctx, in, out, account_name);
+	COPY_LSA_STRING(mem_ctx, in, out, full_name);
+	COPY_LSA_STRING(mem_ctx, in, out, logon_script);
+	COPY_LSA_STRING(mem_ctx, in, out, profile_path);
+	COPY_LSA_STRING(mem_ctx, in, out, home_directory);
+	COPY_LSA_STRING(mem_ctx, in, out, home_drive);
+
+	if (in->groups.count) {
+		out->groups.rids = (struct samr_RidWithAttribute *)
+			talloc_memdup(mem_ctx, in->groups.rids,
+				(sizeof(struct samr_RidWithAttribute) *
+					in->groups.count));
+		NT_STATUS_HAVE_NO_MEMORY(out->groups.rids);
+	}
+
+	COPY_LSA_STRING(mem_ctx, in, out, logon_server);
+	COPY_LSA_STRING(mem_ctx, in, out, domain);
+
+	if (in->domain_sid) {
+		out->domain_sid = dom_sid_dup(mem_ctx, in->domain_sid);
+		NT_STATUS_HAVE_NO_MEMORY(out->domain_sid);
+	}
+
+	return NT_STATUS_OK;
+}
diff --git a/source3/rpc_client/util_netlogon.h b/source3/rpc_client/util_netlogon.h
new file mode 100644
index 0000000..42e4326
--- /dev/null
+++ b/source3/rpc_client/util_netlogon.h
@@ -0,0 +1,5 @@
+/* The following definitions come from rpc_client/util_netlogon.c  */
+
+NTSTATUS copy_netr_SamBaseInfo(TALLOC_CTX *mem_ctx,
+			       const struct netr_SamBaseInfo *in,
+			       struct netr_SamBaseInfo *out);
diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h
index 3217acc..a32c78f 100644
--- a/source3/winbindd/winbindd.h
+++ b/source3/winbindd/winbindd.h
@@ -169,6 +169,7 @@ struct winbindd_domain {
 				  * we don't have to try _ex every time. */
 
 	bool can_do_ncacn_ip_tcp;
+	bool can_do_validation6;
 
 	/* Lookup methods for this domain (LDAP or RPC) */
 	struct winbindd_methods *methods;
diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c
index c692ffe..c53a553 100644
--- a/source3/winbindd/winbindd_cm.c
+++ b/source3/winbindd/winbindd_cm.c
@@ -2086,6 +2086,7 @@ done:
 		  domain->name, domain->active_directory ? "" : "NOT "));
 
 	domain->can_do_ncacn_ip_tcp = domain->active_directory;
+	domain->can_do_validation6 = domain->active_directory;
 
 	TALLOC_FREE(cli);
 
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 760fa3b..68fa01f 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1148,6 +1148,8 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
 
 	do {
 		struct rpc_pipe_client *netlogon_pipe;
+		const struct pipe_auth_data *auth;
+		uint32_t neg_flags = 0;
 
 		ZERO_STRUCTP(info3);
 		retry = false;
@@ -1159,6 +1161,10 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
 				  nt_errstr(result)));
 			return result;
 		}
+		auth = netlogon_pipe->auth;
+		if (netlogon_pipe->dc) {
+			neg_flags = netlogon_pipe->dc->negotiate_flags;
+		}
 
 		/* It is really important to try SamLogonEx here,
 		 * because in a clustered environment, we want to use
@@ -1179,8 +1185,35 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
 		 * wrapping SamLogon context.
 		 *
 		 *  -- abartlet 21 April 2008
+		 *
+		 * It's also important to use NetlogonValidationSamInfo4 (6),
+		 * because it relies on the rpc transport encryption
+		 * and avoids using the global netlogon schannel
+		 * session key to en/decrypt secret information
+		 * like the user_session_key for network logons.
+		 *
+		 * [MS-APDS] 3.1.5.2 NTLM Network Logon
+		 * says NETLOGON_NEG_CROSS_FOREST_TRUSTS and
+		 * NETLOGON_NEG_AUTHENTICATED_RPC set together
+		 * are the indication that the server supports
+		 * NetlogonValidationSamInfo4 (6). And it must only
+		 * be used if "SealSecureChannel" is used.
+		 *
+		 * -- metze 4 February 2011
 		 */
 
+		if (auth == NULL) {
+			domain->can_do_validation6 = false;
+		} else if (auth->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
+			domain->can_do_validation6 = false;
+		} else if (auth->auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {
+			domain->can_do_validation6 = false;
+		} else if (!(neg_flags & NETLOGON_NEG_CROSS_FOREST_TRUSTS)) {
+			domain->can_do_validation6 = false;
+		} else if (!(neg_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
+			domain->can_do_validation6 = false;
+		}
+
 		if (domain->can_do_samlogon_ex) {
 			result = rpccli_netlogon_sam_network_logon_ex(
 					netlogon_pipe,
@@ -1191,6 +1224,7 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
 					domainname,	/* target domain */
 					workstation,	/* workstation */
 					chal,
+					domain->can_do_validation6 ? 6 : 3,
 					lm_response,
 					nt_response,
 					info3);
@@ -1204,22 +1238,43 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
 					domainname,	/* target domain */
 					workstation,	/* workstation */
 					chal,
+					domain->can_do_validation6 ? 6 : 3,
 					lm_response,
 					nt_response,
 					info3);
 		}
 
-		attempts += 1;
-
 		if ((NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR)
 		    && domain->can_do_samlogon_ex) {
 			DEBUG(3, ("Got a DC that can not do NetSamLogonEx, "
 				  "retrying with NetSamLogon\n"));
 			domain->can_do_samlogon_ex = false;
+			/*
+			 * It's likely that the server also does not support
+			 * validation level 6
+			 */
+			domain->can_do_validation6 = false;
 			retry = true;
 			continue;
 		}
 
+		if (domain->can_do_validation6 &&
+		    (NT_STATUS_EQUAL(result, NT_STATUS_INVALID_INFO_CLASS) ||
+		     NT_STATUS_EQUAL(result, NT_STATUS_INVALID_PARAMETER) ||
+		     NT_STATUS_EQUAL(result, NT_STATUS_BUFFER_TOO_SMALL))) {
+			DEBUG(3,("Got a DC that can not do validation level 6, "
+				  "retrying with level 3\n"));
+			domain->can_do_validation6 = false;
+			retry = true;
+			continue;
+		}
+
+		/*
+		 * we increment this after the "feature negotiation"
+		 * for can_do_samlogon_ex and can_do_validation6
+		 */
+		attempts += 1;
+
 		/* We have to try a second time as cm_connect_netlogon
 		   might not yet have noticed that the DC has killed
 		   our connection. */
diff --git a/source3/wscript_build b/source3/wscript_build
index 611e28d..91af048 100644
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -43,7 +43,7 @@ LIBCLI_LSA_SRC = '''rpc_client/cli_lsarpc.c'''
 
 LIBCLI_SAMR_SRC = 'rpc_client/cli_samr.c'
 
-LIBRPCCLI_NETLOGON_SRC = 'rpc_client/cli_netlogon.c'
+LIBRPCCLI_NETLOGON_SRC = 'rpc_client/cli_netlogon.c rpc_client/util_netlogon.c'
 
 # this includes only the low level parse code, not stuff
 # that requires knowledge of security contexts


-- 
Samba Shared Repository


More information about the samba-cvs mailing list