[PATCH] Correctly handle !authoritative in the rpc-based auth backends

Stefan Metzmacher metze at samba.org
Thu Mar 23 16:51:10 UTC 2017


Hi,

>> To make progress, could we skip this part until we get a test to cover
>> the different values, and keep this patch set to just the "no behaviour
>> change"?
> 
> Ok, here's part one for https://bugzilla.samba.org/show_bug.cgi?id=2976

Here's part 2 that also fixes
https://bugzilla.samba.org/show_bug.cgi?id=12709
https://bugzilla.samba.org/show_bug.cgi?id=12710

And the fixes for (with the manpage change still TODO)
https://bugzilla.samba.org/show_bug.cgi?id=8630

metze
-------------- next part --------------
From b31f271232a78a19f5c2c888b29db4f4538e2702 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 22 Mar 2017 10:37:22 +0100
Subject: [PATCH 01/12] auth4: add a "sam_failtrusts" module

This fails the authentication for any known domain with
NT_STATUS_NO_TRUST_LSA_SECRET.

This will be used on an AD_DC to fail authentication
for users of trusted domains sanely, instead of silently
mapping them to local users.

This is just a temporary solution, until we have full
async support in the gensec/auth4.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=2976
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12709

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/auth/ntlm/auth_sam.c | 96 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 95 insertions(+), 1 deletion(-)

diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c
index 391492a..413f188 100644
--- a/source4/auth/ntlm/auth_sam.c
+++ b/source4/auth/ntlm/auth_sam.c
@@ -689,7 +689,89 @@ static NTSTATUS authsam_want_check(struct auth_method_context *ctx,
 	return NT_STATUS_NOT_IMPLEMENTED;
 }
 
-				   
+static NTSTATUS authsam_failtrusts_want_check(struct auth_method_context *ctx,
+					      TALLOC_CTX *mem_ctx,
+					      const struct auth_usersupplied_info *user_info)
+{
+	const char *effective_domain = user_info->mapped.domain_name;
+	struct dsdb_trust_routing_table *trt = NULL;
+	const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
+	NTSTATUS status;
+
+	/* check whether or not we service this domain/workgroup name */
+	switch (lpcfg_server_role(ctx->auth_ctx->lp_ctx)) {
+	case ROLE_ACTIVE_DIRECTORY_DC:
+		/* handled later */
+		break;
+
+	default:
+		DBG_ERR("lpcfg_server_role() has an undefined value\n");
+		return NT_STATUS_NOT_IMPLEMENTED;
+	}
+
+	/*
+	 * Now we handle the AD DC case...
+	 */
+	if (!user_info->mapped.account_name || !*user_info->mapped.account_name) {
+		return NT_STATUS_NOT_IMPLEMENTED;
+	}
+
+	if (effective_domain == NULL || strequal(effective_domain, "")) {
+		const char *p = NULL;
+
+		p = strchr_m(user_info->mapped.account_name, '@');
+		if (p != NULL) {
+			effective_domain = p + 1;
+		}
+	}
+
+	if (effective_domain == NULL || strequal(effective_domain, "")) {
+		DBG_DEBUG("%s is not a trusted domain\n",
+			  effective_domain);
+		return NT_STATUS_NOT_IMPLEMENTED;
+	}
+
+	/*
+	 * as last option we check the routing table if the
+	 * domain is within our forest.
+	 */
+	status = dsdb_trust_routing_table_load(ctx->auth_ctx->sam_ctx,
+					       mem_ctx, &trt);
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_ERR("authsam_check_password: dsdb_trust_routing_table_load() %s\n",
+			 nt_errstr(status));
+		return status;
+	}
+
+	tdo = dsdb_trust_routing_by_name(trt, effective_domain);
+	if (tdo == NULL) {
+		DBG_DEBUG("%s is not a known TLN (DC)\n",
+			  effective_domain);
+		TALLOC_FREE(trt);
+		return NT_STATUS_NOT_IMPLEMENTED;
+	}
+
+	/*
+	 * We now about the domain...
+	 */
+	TALLOC_FREE(trt);
+	return NT_STATUS_OK;
+}
+
+static NTSTATUS authsam_failtrusts_check_password(struct auth_method_context *ctx,
+						  TALLOC_CTX *mem_ctx,
+						  const struct auth_usersupplied_info *user_info,
+						  struct auth_user_info_dc **user_info_dc)
+{
+	/*
+	 * This should a good error for now,
+	 * until this module gets removed
+	 * and we have a full async path
+	 * to winbind.
+	 */
+	return NT_STATUS_NO_TRUST_LSA_SECRET;
+}
+
 /* Wrapper for the auth subsystem pointer */
 static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx,
 							  struct auth4_context *auth_context,
@@ -714,6 +796,12 @@ static const struct auth_operations sam_ops = {
 	.get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper,
 };
 
+static const struct auth_operations sam_failtrusts_ops = {
+	.name		           = "sam_failtrusts",
+	.want_check	           = authsam_failtrusts_want_check,
+	.check_password	           = authsam_failtrusts_check_password,
+};
+
 _PUBLIC_ NTSTATUS auth4_sam_init(void);
 _PUBLIC_ NTSTATUS auth4_sam_init(void)
 {
@@ -731,5 +819,11 @@ _PUBLIC_ NTSTATUS auth4_sam_init(void)
 		return ret;
 	}
 
+	ret = auth_register(&sam_failtrusts_ops);
+	if (!NT_STATUS_IS_OK(ret)) {
+		DEBUG(0,("Failed to register 'sam_failtrusts' auth backend!\n"));
+		return ret;
+	}
+
 	return ret;
 }
-- 
1.9.1


From be9d4ef0f58cd4b0c470e580a76c3e6dc6702c3b Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 14:54:16 +0100
Subject: [PATCH 02/12] auth4: use "anonymous sam winbind_rodc sam_failtrusts
 sam_ignoredomain" as AD_DC

It's better to consistently fail authentications for users
of trusted domains (on a RWDC) with NT_STATUS_NO_TRUST_LSA_SECRET,
instead of silently mapping them to local users, by accident.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=2976
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12709

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/auth/ntlm/auth.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
index ee98cac..f8c8dc9 100644
--- a/source4/auth/ntlm/auth.c
+++ b/source4/auth/ntlm/auth.c
@@ -633,7 +633,20 @@ const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *
 	case ROLE_DOMAIN_BDC:
 	case ROLE_DOMAIN_PDC:
 	case ROLE_ACTIVE_DIRECTORY_DC:
-		auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain winbind_rodc", NULL);
+		/*
+		 * TODO: we should replace "winbind_rodc sam_failtrusts" with "winbind"
+		 * if everything (gensec/auth4) is fully async without nested
+		 * event loops!
+		 *
+		 * But for now we'll fail authentications for trusted
+		 * domain consistently with NT_STATUS_NO_TRUST_LSA_SECRET,
+		 * instead of silently mapping to local users.
+		 */
+		auth_methods = str_list_make(mem_ctx,
+					     "anonymous sam "
+					     "winbind_rodc sam_failtrusts "
+					     "sam_ignoredomain",
+					     NULL);
 		break;
 	}
 	return discard_const_p(const char *, auth_methods);
-- 
1.9.1


From 84f54dc4788d82bf1826db1f373169ef5be81e3b Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 22 Mar 2017 10:45:25 +0100
Subject: [PATCH 03/12] auth4: use "anonymous sam winbind sam_ignoredomain"
 with ROLE_DOMAIN_MEMBER

We hopefully remove this role in future, but for now we should do this
correct and fallback to sam_ignoredomain at the end of the auth chain.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=2976
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12709

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/auth/ntlm/auth.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
index f8c8dc9..6b032c6 100644
--- a/source4/auth/ntlm/auth.c
+++ b/source4/auth/ntlm/auth.c
@@ -628,7 +628,7 @@ const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *
 		auth_methods = str_list_make(mem_ctx, "anonymous sam_ignoredomain", NULL);
 		break;
 	case ROLE_DOMAIN_MEMBER:
-		auth_methods = str_list_make(mem_ctx, "anonymous sam winbind", NULL);
+		auth_methods = str_list_make(mem_ctx, "anonymous sam winbind sam_ignoredomain", NULL);
 		break;
 	case ROLE_DOMAIN_BDC:
 	case ROLE_DOMAIN_PDC:
-- 
1.9.1


From fe1759366c96b94c42f6711a12708234cb6450a0 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 14:57:33 +0100
Subject: [PATCH 04/12] auth4: let authsam_check_password_internals use
 crack_name_to_nt4_name() for upn's

Currently the caller does this before calling the auth backends,
but that should change in order to support trusted domains correctly.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=2976
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12709

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/auth/ntlm/auth_sam.c | 38 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c
index 413f188..8477c53 100644
--- a/source4/auth/ntlm/auth_sam.c
+++ b/source4/auth/ntlm/auth_sam.c
@@ -580,6 +580,7 @@ static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx
 	struct ldb_dn *domain_dn;
 	DATA_BLOB user_sess_key, lm_sess_key;
 	TALLOC_CTX *tmp_ctx;
+	const char *p = NULL;
 
 	if (ctx->auth_ctx->sam_ctx == NULL) {
 		DEBUG(0, ("No SAM available, cannot log in users\n"));
@@ -602,6 +603,43 @@ static NTSTATUS authsam_check_password_internals(struct auth_method_context *ctx
 		return NT_STATUS_NO_SUCH_DOMAIN;
 	}
 
+	p = strchr_m(account_name, '@');
+	if (p != NULL) {
+		const char *nt4_domain = NULL;
+		const char *nt4_account = NULL;
+		bool is_my_domain = false;
+
+		nt_status = crack_name_to_nt4_name(mem_ctx,
+						   ctx->auth_ctx->event_ctx,
+						   ctx->auth_ctx->lp_ctx,
+						   /*
+						    * DRSUAPI_DS_NAME_FORMAT_UPN_FOR_LOGON ?
+						    */
+						   DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
+						   account_name,
+						   &nt4_domain, &nt4_account);
+		if (!NT_STATUS_IS_OK(nt_status)) {
+			talloc_free(tmp_ctx);
+			return NT_STATUS_NO_SUCH_USER;
+		}
+
+		is_my_domain = lpcfg_is_mydomain(ctx->auth_ctx->lp_ctx, nt4_domain);
+		if (!is_my_domain) {
+			/*
+			 * This is a user within our forest,
+			 * but in a different domain,
+			 * we're not authoritative
+			 */
+			talloc_free(tmp_ctx);
+			return NT_STATUS_NOT_IMPLEMENTED;
+		}
+
+		/*
+		 * Let's use the NT4 account name for the lookup.
+		 */
+		account_name = nt4_account;
+	}
+
 	nt_status = authsam_search_account(tmp_ctx, ctx->auth_ctx->sam_ctx, account_name, domain_dn, &msg);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		talloc_free(tmp_ctx);
-- 
1.9.1


From 59758b73d188adf5b690400089ce674efd8e8194 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 16:31:02 +0100
Subject: [PATCH 05/12] auth4: improve authsam_want_check for upn
 authentication

We need to check if the upn suffix is within our forest.
The check if it's within our domain is done in
authsam_check_password_internals() after calling
crack_name_to_nt4_name().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=2976
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12709

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/auth/ntlm/auth_sam.c | 123 ++++++++++++++++++++++++++++++++++++-------
 1 file changed, 103 insertions(+), 20 deletions(-)

diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c
index 8477c53..1c7fd90 100644
--- a/source4/auth/ntlm/auth_sam.c
+++ b/source4/auth/ntlm/auth_sam.c
@@ -690,41 +690,124 @@ static NTSTATUS authsam_want_check(struct auth_method_context *ctx,
 				   TALLOC_CTX *mem_ctx,
 				   const struct auth_usersupplied_info *user_info)
 {
-	bool is_local_name, is_my_domain;
+	const char *effective_domain = user_info->mapped.domain_name;
+	bool is_local_name = false;
+	bool is_my_domain = false;
+	const char *p = NULL;
+	struct dsdb_trust_routing_table *trt = NULL;
+	const struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
+	NTSTATUS status;
 
 	if (!user_info->mapped.account_name || !*user_info->mapped.account_name) {
 		return NT_STATUS_NOT_IMPLEMENTED;
 	}
 
 	is_local_name = lpcfg_is_myname(ctx->auth_ctx->lp_ctx,
-				  user_info->mapped.domain_name);
-	is_my_domain  = lpcfg_is_mydomain(ctx->auth_ctx->lp_ctx,
-				       user_info->mapped.domain_name); 
+					effective_domain);
 
 	/* check whether or not we service this domain/workgroup name */
 	switch (lpcfg_server_role(ctx->auth_ctx->lp_ctx)) {
-		case ROLE_STANDALONE:
-			return NT_STATUS_OK;
+	case ROLE_STANDALONE:
+		return NT_STATUS_OK;
 
-		case ROLE_DOMAIN_MEMBER:
-			if (!is_local_name) {
-				DEBUG(6,("authsam_check_password: %s is not one of my local names (DOMAIN_MEMBER)\n",
-					user_info->mapped.domain_name));
-				return NT_STATUS_NOT_IMPLEMENTED;
-			}
+	case ROLE_DOMAIN_MEMBER:
+		if (is_local_name) {
 			return NT_STATUS_OK;
+		}
 
-		case ROLE_ACTIVE_DIRECTORY_DC:
-			if (!is_local_name && !is_my_domain) {
-				DEBUG(6,("authsam_check_password: %s is not one of my local names or domain name (DC)\n",
-					user_info->mapped.domain_name));
-				return NT_STATUS_NOT_IMPLEMENTED;
-			}
+		DBG_DEBUG("%s is not one of my local names (DOMAIN_MEMBER)\n",
+			  effective_domain);
+		return NT_STATUS_NOT_IMPLEMENTED;
+
+	case ROLE_ACTIVE_DIRECTORY_DC:
+		/* handled later */
+		break;
+
+	default:
+		DBG_ERR("lpcfg_server_role() has an undefined value\n");
+		return NT_STATUS_INVALID_SERVER_STATE;
+	}
+
+	/*
+	 * Now we handle the AD DC case...
+	 */
+
+	is_my_domain = lpcfg_is_my_domain_or_realm(ctx->auth_ctx->lp_ctx,
+						   effective_domain);
+	if (is_my_domain) {
+		return NT_STATUS_OK;
+	}
+
+	if (user_info->mapped_state) {
+		/*
+		 * The caller already did a cracknames call.
+		 */
+		DBG_DEBUG("%s is not one domain name (DC)\n",
+			  effective_domain);
+		return NT_STATUS_NOT_IMPLEMENTED;
+	}
+
+	if (effective_domain != NULL && !strequal(effective_domain, "")) {
+		DBG_DEBUG("%s is not one domain name (DC)\n",
+			  effective_domain);
+		return NT_STATUS_NOT_IMPLEMENTED;
+	}
+
+	p = strchr_m(user_info->mapped.account_name, '@');
+	if (p == NULL) {
+		if (effective_domain == NULL) {
 			return NT_STATUS_OK;
+		}
+		DEBUG(6,("authsam_check_password: '' without upn not handled (DC)\n"));
+		return NT_STATUS_NOT_IMPLEMENTED;
+	}
+
+	effective_domain = p + 1;
+	is_my_domain = lpcfg_is_my_domain_or_realm(ctx->auth_ctx->lp_ctx,
+						   effective_domain);
+	if (is_my_domain) {
+		return NT_STATUS_OK;
 	}
 
-	DEBUG(6,("authsam_check_password: lpcfg_server_role() has an undefined value\n"));
-	return NT_STATUS_NOT_IMPLEMENTED;
+	if (strequal(effective_domain, "")) {
+		DBG_DEBUG("authsam_check_password: upn without realm (DC)\n");
+		return NT_STATUS_NOT_IMPLEMENTED;
+	}
+
+	/*
+	 * as last option we check the routing table if the
+	 * domain is within our forest.
+	 */
+	status = dsdb_trust_routing_table_load(ctx->auth_ctx->sam_ctx,
+					       mem_ctx, &trt);
+	if (!NT_STATUS_IS_OK(status)) {
+		DBG_ERR("authsam_check_password: dsdb_trust_routing_table_load() %s\n",
+			 nt_errstr(status));
+		return status;
+	}
+
+	tdo = dsdb_trust_routing_by_name(trt, effective_domain);
+	if (tdo == NULL) {
+		DBG_DEBUG("%s is not a known TLN (DC)\n",
+			  effective_domain);
+		TALLOC_FREE(trt);
+		return NT_STATUS_NOT_IMPLEMENTED;
+	}
+
+	if (!(tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST)) {
+		DBG_DEBUG("%s is not a TLN in our forest (DC)\n",
+			  effective_domain);
+		TALLOC_FREE(trt);
+		return NT_STATUS_NOT_IMPLEMENTED;
+	}
+
+	/*
+	 * This principal is within our forest.
+	 * we'll later do a crack_name_to_nt4_name()
+	 * to check if it's in our domain.
+	 */
+	TALLOC_FREE(trt);
+	return NT_STATUS_OK;
 }
 
 static NTSTATUS authsam_failtrusts_want_check(struct auth_method_context *ctx,
-- 
1.9.1


From 5cec96d07e14632d12b3cfaa2e4564f9db91f5a3 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 16:19:10 +0100
Subject: [PATCH 06/12] auth4: avoid map_user_info() in
 auth_check_password_send()

The cracknames call is done in the "sam" backend now.

In order to support trusted domains correctly, the backends
need to get the raw values from the client.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=2976
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12709

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/auth/ntlm/auth.c | 35 +++++++++++++++++++++++++----------
 1 file changed, 25 insertions(+), 10 deletions(-)

diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
index 6b032c6..d4bc145 100644
--- a/source4/auth/ntlm/auth.c
+++ b/source4/auth/ntlm/auth.c
@@ -291,24 +291,39 @@ _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx,
 	state->user_info	= user_info;
 
 	if (!user_info->mapped_state) {
-		int server_role = lpcfg_server_role(auth_ctx->lp_ctx);
 		struct auth_usersupplied_info *user_info_tmp;
 
-		nt_status = map_user_info(
-			auth_ctx->sam_ctx, req,
-			server_role == ROLE_ACTIVE_DIRECTORY_DC,
-			lpcfg_workgroup(auth_ctx->lp_ctx),
-			user_info, &user_info_tmp);
-
-		if (tevent_req_nterror(req, nt_status)) {
-			return tevent_req_post(req, ev);
+		/*
+		 * We don't really do any mapping here.
+		 *
+		 * So ee don't set user_info->mapped_state,
+		 * but we set mapped.domain_name and
+		 * mapped.account_name to the client
+		 * provided values.
+		 *
+		 * It's up to the backends to do mappings
+		 * for their authentication.
+		 */
+		user_info_tmp = talloc_zero(state, struct auth_usersupplied_info);
+		if (tevent_req_nomem(user_info_tmp, req)) {
+			return tevent_req_post(req, ev);;
 		}
+
+		/*
+		 * The lifetime of user_info is longer than
+		 * user_info_tmp, so we don't need to copy the
+		 * strings.
+		 */
+		*user_info_tmp = *user_info;
+		user_info_tmp->mapped.domain_name = user_info->client.domain_name;
+		user_info_tmp->mapped.account_name = user_info->client.account_name;
+
 		user_info = user_info_tmp;
 		state->user_info = user_info_tmp;
 	}
 
 	DEBUGADD(3,("auth_check_password_send: "
-		    "mapped user is: [%s]\\[%s]@[%s]\n",
+		    "user is: [%s]\\[%s]@[%s]\n",
 		    user_info->mapped.domain_name,
 		    user_info->mapped.account_name,
 		    user_info->workstation_name));
-- 
1.9.1


From d0f7ac65f3a8b98a7d78ed1f69edb0e7c3c38da8 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 16:21:05 +0100
Subject: [PATCH 07/12] auth4: remove unused map_user_info[_cracknames]()

BUG: https://bugzilla.samba.org/show_bug.cgi?id=2976
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12709

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/auth/ntlm/auth_util.c | 259 ------------------------------------------
 1 file changed, 259 deletions(-)

diff --git a/source4/auth/ntlm/auth_util.c b/source4/auth/ntlm/auth_util.c
index e3d196c..7feb20b 100644
--- a/source4/auth/ntlm/auth_util.c
+++ b/source4/auth/ntlm/auth_util.c
@@ -41,265 +41,6 @@ NTSTATUS auth_get_challenge_not_implemented(struct auth_method_context *ctx, TAL
 /****************************************************************************
  Create an auth_usersupplied_data structure after appropriate mapping.
 ****************************************************************************/
-static NTSTATUS map_user_info_cracknames(struct ldb_context *sam_ctx,
-					 TALLOC_CTX *mem_ctx,
-					 const char *default_domain,
-					 const struct auth_usersupplied_info *user_info,
-					 struct auth_usersupplied_info **user_info_mapped)
-{
-	char *domain;
-	char *account_name;
-	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
-	WERROR werr;
-	struct drsuapi_DsNameInfo1 info1;
-
-	DEBUG(5,("map_user_info_cracknames: Mapping user [%s]\\[%s] from workstation [%s]\n",
-		 user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name));
-
-	account_name = talloc_strdup(tmp_ctx, user_info->client.account_name);
-	if (!account_name) {
-		talloc_free(tmp_ctx);
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	/* use cracknames to work out what domain is being
-	   asked for */
-	if (strchr_m(user_info->client.account_name, '@') != NULL) {
-		werr = DsCrackNameOneName(sam_ctx, tmp_ctx, 0,
-					  DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL,
-					  DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
-					  user_info->client.account_name,
-					  &info1);
-		if (!W_ERROR_IS_OK(werr)) {
-			DEBUG(2,("map_user_info: Failed cracknames of account '%s'\n",
-				 user_info->client.account_name));
-			talloc_free(tmp_ctx);
-			return werror_to_ntstatus(werr);
-		}
-		switch (info1.status) {
-		case DRSUAPI_DS_NAME_STATUS_OK:
-			break;
-		case DRSUAPI_DS_NAME_STATUS_NOT_FOUND:
-			DEBUG(2,("map_user_info: Cracknames of account '%s' -> NOT_FOUND\n",
-				 user_info->client.account_name));
-			talloc_free(tmp_ctx);
-			return NT_STATUS_NO_SUCH_USER;
-		case DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY:
-			DEBUG(2,("map_user_info: Cracknames of account '%s' -> DOMAIN_ONLY\n",
-				 user_info->client.account_name));
-			talloc_free(tmp_ctx);
-			return NT_STATUS_NO_SUCH_USER;
-		case DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE:
-			DEBUG(2,("map_user_info: Cracknames of account '%s' -> NOT_UNIQUE\n",
-				 user_info->client.account_name));
-			talloc_free(tmp_ctx);
-			return NT_STATUS_NO_SUCH_USER;
-		case DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR:
-			DEBUG(2,("map_user_info: Cracknames of account '%s' -> RESOLVE_ERROR\n",
-				 user_info->client.account_name));
-			talloc_free(tmp_ctx);
-			return NT_STATUS_NO_SUCH_USER;
-		default:
-			DEBUG(2,("map_user_info: Cracknames of account '%s' -> unknown error %u\n",
-				 user_info->client.account_name, info1.status));
-			talloc_free(tmp_ctx);
-			return NT_STATUS_NO_SUCH_USER;
-		}
-		/* info1.result_name is in DOMAIN\username
-		 * form, which we need to split up into the
-		 * user_info_mapped structure
-		 */
-		domain = talloc_strdup(tmp_ctx, info1.result_name);
-		if (domain == NULL) {
-			talloc_free(tmp_ctx);
-			return NT_STATUS_NO_MEMORY;
-		}
-		account_name = strchr_m(domain, '\\');
-		if (account_name == NULL) {
-			DEBUG(2,("map_user_info: Cracknames of account '%s' gave invalid result '%s'\n",
-				 user_info->client.account_name, info1.result_name));
-			talloc_free(tmp_ctx);
-			return NT_STATUS_NO_SUCH_USER;
-		}
-		*account_name = 0;
-		account_name = talloc_strdup(tmp_ctx, account_name+1);
-		if (account_name == NULL) {
-			talloc_free(tmp_ctx);
-			return NT_STATUS_NO_MEMORY;
-		}
-	} else {
-		const char *domain_name = default_domain;
-		if (user_info->client.domain_name && *user_info->client.domain_name) {
-			domain_name = user_info->client.domain_name;
-		}
-		domain_name = talloc_asprintf(tmp_ctx, "%s\\", domain_name);
-		if (domain_name == NULL) {
-			talloc_free(tmp_ctx);
-			return NT_STATUS_NO_MEMORY;
-		}
-		werr = DsCrackNameOneName(sam_ctx, mem_ctx, 0,
-					  DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
-					  DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT,
-					  domain_name,
-					  &info1);
-		if (!W_ERROR_IS_OK(werr)) {
-			DEBUG(2,("map_user_info: Failed cracknames of domain '%s'\n",
-				 domain_name));
-			talloc_free(tmp_ctx);
-			return werror_to_ntstatus(werr);
-		}
-
-		/* we use the account_name as-is, but get the
-		 * domain name from cracknames if possible */
-		account_name = talloc_strdup(mem_ctx, user_info->client.account_name);
-		if (account_name == NULL) {
-			talloc_free(tmp_ctx);
-			return NT_STATUS_NO_MEMORY;
-		}
-
-		switch (info1.status) {
-		case DRSUAPI_DS_NAME_STATUS_OK:
-		case DRSUAPI_DS_NAME_STATUS_DOMAIN_ONLY:
-			domain = talloc_strdup(tmp_ctx, info1.result_name);
-			if (domain == NULL) {
-				talloc_free(tmp_ctx);
-				return NT_STATUS_NO_MEMORY;
-			}
-			if (domain[strlen_m(domain)-1] == '\\') {
-				domain[strlen_m(domain)-1] = 0;
-			}
-			break;
-		case DRSUAPI_DS_NAME_STATUS_NOT_FOUND:
-			/* the domain is unknown - use the
-			   default domain */
-			domain = talloc_strdup(tmp_ctx, default_domain);
-			break;
-		case DRSUAPI_DS_NAME_STATUS_NOT_UNIQUE:
-			DEBUG(2,("map_user_info: Cracknames of domain '%s' -> NOT_UNIQUE\n",
-				 domain_name));
-			talloc_free(tmp_ctx);
-			return NT_STATUS_NO_SUCH_USER;
-		case DRSUAPI_DS_NAME_STATUS_RESOLVE_ERROR:
-			DEBUG(2,("map_user_info: Cracknames of domain '%s' -> RESOLVE_ERROR\n",
-				 domain_name));
-			talloc_free(tmp_ctx);
-			return NT_STATUS_NO_SUCH_USER;
-		default:
-			DEBUG(2,("map_user_info: Cracknames of account '%s' -> unknown error %u\n",
-				 domain_name, info1.status));
-			talloc_free(tmp_ctx);
-			return NT_STATUS_NO_SUCH_USER;
-		}
-		/* domain and account_name are filled in above */
-	}
-
-	*user_info_mapped = talloc_zero(mem_ctx, struct auth_usersupplied_info);
-	if (!*user_info_mapped) {
-		talloc_free(tmp_ctx);
-		return NT_STATUS_NO_MEMORY;
-	}
-	if (!talloc_reference(*user_info_mapped, user_info)) {
-		talloc_free(tmp_ctx);
-		return NT_STATUS_NO_MEMORY;
-	}
-	**user_info_mapped = *user_info;
-	(*user_info_mapped)->mapped_state = true;
-	(*user_info_mapped)->mapped.domain_name = talloc_strdup(*user_info_mapped, domain);
-	(*user_info_mapped)->mapped.account_name = talloc_strdup(*user_info_mapped, account_name);
-	talloc_free(tmp_ctx);
-	if (!(*user_info_mapped)->mapped.domain_name
-	    || !(*user_info_mapped)->mapped.account_name) {
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	return NT_STATUS_OK;
-}
-
-
-/****************************************************************************
- Create an auth_usersupplied_data structure after appropriate mapping.
-****************************************************************************/
-NTSTATUS map_user_info(struct ldb_context *sam_ctx,
-		       TALLOC_CTX *mem_ctx,
-		       bool is_ad_dc,
-		       const char *default_domain,
-		       const struct auth_usersupplied_info *user_info,
-		       struct auth_usersupplied_info **user_info_mapped)
-{
-	char *domain;
-	char *account_name;
-	char *d;
-	TALLOC_CTX *tmp_ctx;
-
-	if (is_ad_dc) {
-		/* if possible, use cracknames to parse the
-		   domain/account */
-		return map_user_info_cracknames(sam_ctx, mem_ctx, default_domain, user_info, user_info_mapped);
-	}
-
-	DEBUG(0,("map_user_info: Mapping user [%s]\\[%s] from workstation [%s] default_domain=%s\n",
-		 user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name,
-		 default_domain));
-
-	tmp_ctx = talloc_new(mem_ctx);
-
-	account_name = talloc_strdup(tmp_ctx, user_info->client.account_name);
-	if (!account_name) {
-		talloc_free(tmp_ctx);
-		return NT_STATUS_NO_MEMORY;
-	}
-	
-	/* don't allow "" as a domain, fixes a Win9X bug where it
-	   doesn't supply a domain for logon script 'net use'
-	   commands.  */
-
-	/* Split user at realm names into user and realm components.
-	 * This is TODO to fix with proper userprincipalname
-	 * support */
-	if (user_info->client.domain_name && *user_info->client.domain_name) {
-		domain = talloc_strdup(tmp_ctx, user_info->client.domain_name);
-	} else if (strchr_m(user_info->client.account_name, '@')) {
-		d = strchr_m(account_name, '@');
-		if (!d) {
-			talloc_free(tmp_ctx);
-			return NT_STATUS_INTERNAL_ERROR;
-		}
-		d[0] = '\0';
-		d++;
-		domain = d;
-	} else {
-		domain = talloc_strdup(tmp_ctx, default_domain);
-	}
-
-	if (domain == NULL) {
-		talloc_free(tmp_ctx);
-		return NT_STATUS_NO_MEMORY;
-	}
-	*user_info_mapped = talloc_zero(mem_ctx, struct auth_usersupplied_info);
-	if (!*user_info_mapped) {
-		talloc_free(tmp_ctx);
-		return NT_STATUS_NO_MEMORY;
-	}
-	if (!talloc_reference(*user_info_mapped, user_info)) {
-		talloc_free(tmp_ctx);
-		return NT_STATUS_NO_MEMORY;
-	}
-	**user_info_mapped = *user_info;
-	(*user_info_mapped)->mapped_state = true;
-	(*user_info_mapped)->mapped.domain_name = talloc_strdup(*user_info_mapped, domain);
-	(*user_info_mapped)->mapped.account_name = talloc_strdup(*user_info_mapped, account_name);
-	talloc_free(tmp_ctx);
-	if (!(*user_info_mapped)->mapped.domain_name 
-	    || !(*user_info_mapped)->mapped.account_name) {
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	return NT_STATUS_OK;
-}
-
-/****************************************************************************
- Create an auth_usersupplied_data structure after appropriate mapping.
-****************************************************************************/
 
 NTSTATUS encrypt_user_info(TALLOC_CTX *mem_ctx, struct auth4_context *auth_context, 
 			   enum auth_password_state to_state,
-- 
1.9.1


From a099c500dc6e8f3acd4edd0ee65498d35407afa0 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 19:35:24 +0100
Subject: [PATCH 08/12] auth4: use "sam winbind_rodc sam_failtrusts" for the
 netlogon authentication

We should not do anonymous authentication nor a fallback that
ignores the domain part.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=2976
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12710

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/auth/ntlm/auth.c | 35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
index d4bc145..bc775ce 100644
--- a/source4/auth/ntlm/auth.c
+++ b/source4/auth/ntlm/auth.c
@@ -699,7 +699,40 @@ _PUBLIC_ NTSTATUS auth_context_create_for_netlogon(TALLOC_CTX *mem_ctx,
 						   struct loadparm_context *lp_ctx,
 						   struct auth4_context **auth_ctx)
 {
-	return auth_context_create(mem_ctx, ev, msg, lp_ctx, auth_ctx);
+	NTSTATUS status;
+	char **_auth_methods = NULL;
+	const char **auth_methods = NULL;
+
+	/*
+	 * As 'auth methods' is deprecated it will be removed
+	 * in future releases again, but for now give
+	 * admins the flexibility to configure, the behavior
+	 * from Samba 4.6: "auth methods = anonymous sam_ignoredomain",
+	 * for a while.
+	 */
+	auth_methods = lpcfg_auth_methods(lp_ctx);
+	if (auth_methods != NULL) {
+		DBG_NOTICE("using deprecated 'auth methods' values.\n");
+	} else {
+		/*
+		 * We can remove "winbind_rodc sam_failtrusts",
+		 * when we made the netlogon retries to
+		 * to contact winbind via irpc.
+		 */
+		_auth_methods = str_list_make(mem_ctx,
+				"sam "
+				"winbind_rodc sam_failtrusts",
+				NULL);
+		if (_auth_methods == NULL) {
+			return NT_STATUS_NO_MEMORY;
+		}
+		auth_methods = discard_const_p(const char *, _auth_methods);
+	}
+
+	status = auth_context_create_methods(mem_ctx, auth_methods, ev, msg,
+					     lp_ctx, NULL, auth_ctx);
+	talloc_free(_auth_methods);
+	return status;
 }
 
 /* the list of currently registered AUTH backends */
-- 
1.9.1


From 8aa57f83eb3b233ac8e6dd363fe8dde2407c6c8c Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 16 Mar 2017 15:45:32 +0100
Subject: [PATCH 09/12] auth3: add "sam_netlogon3" which only reacts on
 lp_workgroup() as NT4 PDC/BDC

This will be used in the s3 netlogon server in future.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=2976
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12710

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/auth/auth_sam.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c
index 5b53bca..634386f 100644
--- a/source3/auth/auth_sam.c
+++ b/source3/auth/auth_sam.c
@@ -125,9 +125,73 @@ static NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *par
 	return NT_STATUS_OK;
 }
 
+static NTSTATUS auth_sam_netlogon3_auth(const struct auth_context *auth_context,
+					void *my_private_data,
+					TALLOC_CTX *mem_ctx,
+					const struct auth_usersupplied_info *user_info,
+					struct auth_serversupplied_info **server_info)
+{
+	bool is_my_domain;
+
+	if (!user_info || !auth_context) {
+		return NT_STATUS_LOGON_FAILURE;
+	}
+
+	DBG_DEBUG("Check auth for: [%s]\\[%s]\n",
+		  user_info->mapped.domain_name,
+		  user_info->mapped.account_name);
+
+	/* check whether or not we service this domain/workgroup name */
+
+	switch (lp_server_role()) {
+	case ROLE_DOMAIN_PDC:
+	case ROLE_DOMAIN_BDC:
+		break;
+	default:
+		DBG_ERR("Invalid server role\n");
+		return NT_STATUS_INVALID_SERVER_STATE;
+	}
+
+	is_my_domain = strequal(user_info->mapped.domain_name, lp_workgroup());
+	if (!is_my_domain) {
+		DBG_INFO("%s is not our domain name (DC for %s)\n",
+			 user_info->mapped.domain_name, lp_workgroup());
+		return NT_STATUS_NOT_IMPLEMENTED;
+	}
+
+	return check_sam_security(&auth_context->challenge, mem_ctx,
+				  user_info, server_info);
+}
+
+/* module initialisation */
+static NTSTATUS auth_init_sam_netlogon3(struct auth_context *auth_context,
+					const char *param, auth_methods **auth_method)
+{
+	struct auth_methods *result;
+
+	if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
+	    && !lp_parm_bool(-1, "server role check", "inhibit", false)) {
+		DEBUG(0, ("server role = 'active directory domain controller' "
+			  "not compatible with running the auth_sam module.\n"));
+		DEBUGADD(0, ("You should not set 'auth methods' when "
+			     "running the AD DC.\n"));
+		exit(1);
+	}
+
+	result = talloc_zero(auth_context, struct auth_methods);
+	if (result == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+	result->auth = auth_sam_netlogon3_auth;
+	result->name = "sam_netlogon3";
+	*auth_method = result;
+	return NT_STATUS_OK;
+}
+
 NTSTATUS auth_sam_init(void)
 {
 	smb_register_auth(AUTH_INTERFACE_VERSION, "sam", auth_init_sam);
 	smb_register_auth(AUTH_INTERFACE_VERSION, "sam_ignoredomain", auth_init_sam_ignoredomain);
+	smb_register_auth(AUTH_INTERFACE_VERSION, "sam_netlogon3", auth_init_sam_netlogon3);
 	return NT_STATUS_OK;
 }
-- 
1.9.1


From 7862afccbee9ac7fcc00dd03bb205548e396f0ea Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 16:51:45 +0100
Subject: [PATCH 10/12] auth3: only use "sam_netlogon3 winbind:trustdomain" in
 make_auth3_context_for_netlogon

If some needs the old behavior for a while, the deprecated
"auth methods = guest sam winbind:trustdomain" option can be used.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=2976
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12710

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/auth/auth.c | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index e2e99a1..6488722 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -538,7 +538,36 @@ NTSTATUS make_auth3_context_for_ntlm(TALLOC_CTX *mem_ctx,
 NTSTATUS make_auth3_context_for_netlogon(TALLOC_CTX *mem_ctx,
 					 struct auth_context **auth_context)
 {
-	return make_auth_context_subsystem(mem_ctx, auth_context);
+	const char *methods = NULL;
+	NTSTATUS nt_status;
+
+	/*
+	 * We do the lp_auth_methods check before
+	 * the lp_server_role check in order to
+	 * backward compatible. The "auth methods" option
+	 * is deprecated now, so this will go away in a future
+	 * release.
+	 */
+	if (lp_auth_methods()) {
+		DBG_INFO("Using specified auth order for netlogon\n");
+		nt_status = make_auth_context_text_list(
+			mem_ctx, auth_context,
+			discard_const_p(char *, lp_auth_methods()));
+		return nt_status;
+	}
+
+	switch (lp_server_role()) {
+	case ROLE_DOMAIN_BDC:
+	case ROLE_DOMAIN_PDC:
+		methods = "sam_netlogon3 winbind:trustdomain";
+		break;
+
+	default:
+		DBG_ERR("Invalid server role!\n");
+		return NT_STATUS_INVALID_SERVER_STATE;
+	}
+
+	return make_auth_context_specific(mem_ctx, auth_context, methods);
 }
 
 NTSTATUS make_auth3_context_for_winbind(TALLOC_CTX *mem_ctx,
-- 
1.9.1


From 71a3d73471f542c8de06657ddf27230815f1a89e Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 16:53:27 +0100
Subject: [PATCH 11/12] auth3: merge make_auth_context_subsystem() into
 make_auth3_context_for_ntlm()

make_auth3_context_for_ntlm() was the only caller of
make_auth_context_subsystem().

BUG: https://bugzilla.samba.org/show_bug.cgi?id=2976
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12710

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/auth/auth.c | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 6488722..1984368 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -479,8 +479,8 @@ static NTSTATUS make_auth_context_specific(TALLOC_CTX *mem_ctx,
  Make a auth_context struct for the auth subsystem
 ***************************************************************************/
 
-static NTSTATUS make_auth_context_subsystem(TALLOC_CTX *mem_ctx,
-					    struct auth_context **auth_context)
+NTSTATUS make_auth3_context_for_ntlm(TALLOC_CTX *mem_ctx,
+				     struct auth_context **auth_context)
 {
 	const char *methods = NULL;
 	NTSTATUS nt_status;
@@ -529,12 +529,6 @@ static NTSTATUS make_auth_context_subsystem(TALLOC_CTX *mem_ctx,
 	return make_auth_context_specific(mem_ctx, auth_context, methods);
 }
 
-NTSTATUS make_auth3_context_for_ntlm(TALLOC_CTX *mem_ctx,
-				     struct auth_context **auth_context)
-{
-	return make_auth_context_subsystem(mem_ctx, auth_context);
-}
-
 NTSTATUS make_auth3_context_for_netlogon(TALLOC_CTX *mem_ctx,
 					 struct auth_context **auth_context)
 {
-- 
1.9.1


From 9fcfc1927c960b86fe4daf8269d9fd8205df5e4b Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sun, 19 Feb 2017 15:37:51 +0100
Subject: [PATCH 12/12] SIGN-OFF auth3: fallback to "sam_ignoredomain" in
 make_auth3_context_for_ntlm()

This is in the spirit of the "map untrusted to domain" parameter: We
fall back to the local SAM when we get a non-authoritative NO_SUCH_USER
from our domain controller. With this change we can implement
"map untrusted to domain = auto".

We should not strictly need 'sam' before 'winbind', but it makes
it clearer to read and has the same effect.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=2976
BUG: https://bugzilla.samba.org/show_bug.cgi?id=8630

TODO Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/auth/auth.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 1984368..5f74951 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -505,17 +505,17 @@ NTSTATUS make_auth3_context_for_ntlm(TALLOC_CTX *mem_ctx,
 	switch (lp_server_role()) {
 	case ROLE_DOMAIN_MEMBER:
 		DEBUG(5,("Making default auth method list for server role = 'domain member'\n"));
-		methods = "guest sam winbind:ntdomain";
+		methods = "guest sam winbind:ntdomain sam_ignoredomain";
 		break;
 	case ROLE_DOMAIN_BDC:
 	case ROLE_DOMAIN_PDC:
 		DEBUG(5,("Making default auth method list for DC\n"));
-		methods = "guest sam winbind:trustdomain";
+		methods = "guest sam winbind:trustdomain sam_ignoredomain";
 		break;
 	case ROLE_STANDALONE:
 		DEBUG(5,("Making default auth method list for server role = 'standalone server', encrypt passwords = yes\n"));
 		if (lp_encrypt_passwords()) {
-			methods = "guest sam";
+			methods = "guest sam_ignoredomain";
 		} else {
 			DEBUG(5,("Making default auth method list for server role = 'standalone server', encrypt passwords = no\n"));
 			methods = "guest unix";
-- 
1.9.1

-------------- next part --------------
From a27c1c6a1ca5ce36f5fcbb374186c83695e64e06 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 16 Mar 2017 15:09:26 +0100
Subject: [PATCH 1/4] auth3: call is_trusted_domain() as the last condition
 make_user_info_map()

We should avoid contacting winbind if we already know the domain is our
local sam or our primary domain.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=8630

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/auth/auth_util.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 5d9f0e0..43e073b 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -132,9 +132,11 @@ NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
 	 * non-domain member box will also map to WORKSTATION\user.
 	 * This also deals with the client passing in a "" domain */
 
-	if (!upn_form && !is_trusted_domain(domain) &&
+	if (!upn_form &&
 	    !strequal(domain, my_sam_name()) &&
-	    !strequal(domain, get_global_sam_name())) {
+	    !strequal(domain, get_global_sam_name()) &&
+	    !is_trusted_domain(domain))
+	{
 		if (lp_map_untrusted_to_domain())
 			domain = my_sam_name();
 		else
-- 
1.9.1


From 302e6ee7e040f96a7e2bd737c1db6d415096a5ce Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 22 Mar 2017 12:08:20 +0100
Subject: [PATCH 2/4] auth3: prepare the logic for "map untrusted to domain =
 auto"

This implements the same behavior as Windows,
we should pass the domain and account names given
by the client directly to the auth backends,
they can decide if they are able to process the
authentication pass it to the next backend.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=8630

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/auth/auth_util.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 43e073b..1655f22 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -109,6 +109,7 @@ NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
 	bool was_mapped;
 	char *internal_username = NULL;
 	bool upn_form = false;
+	int map_untrusted = lp_map_untrusted_to_domain();
 
 	if (client_domain[0] == '\0' && strchr(smb_name, '@')) {
 		upn_form = true;
@@ -132,15 +133,16 @@ NTSTATUS make_user_info_map(TALLOC_CTX *mem_ctx,
 	 * non-domain member box will also map to WORKSTATION\user.
 	 * This also deals with the client passing in a "" domain */
 
-	if (!upn_form &&
+	if (map_untrusted != Auto && !upn_form &&
 	    !strequal(domain, my_sam_name()) &&
 	    !strequal(domain, get_global_sam_name()) &&
 	    !is_trusted_domain(domain))
 	{
-		if (lp_map_untrusted_to_domain())
+		if (map_untrusted) {
 			domain = my_sam_name();
-		else
+		} else {
 			domain = get_global_sam_name();
+		}
 		DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from "
 			  "workstation [%s]\n",
 			  client_domain, domain, smb_name, workstation_name));
-- 
1.9.1


From b5b2d4f07e2af46e68b0c0468acbbfc656a53d09 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 22 Mar 2017 12:11:26 +0100
Subject: [PATCH 3/4] TODO docs-xml: document "map untrusted to domain = auto"

BUG: https://bugzilla.samba.org/show_bug.cgi?id=8630
---
 .../smbdotconf/security/mapuntrustedtodomain.xml   | 23 ++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/docs-xml/smbdotconf/security/mapuntrustedtodomain.xml b/docs-xml/smbdotconf/security/mapuntrustedtodomain.xml
index 496e7c2..7a2df9a 100644
--- a/docs-xml/smbdotconf/security/mapuntrustedtodomain.xml
+++ b/docs-xml/smbdotconf/security/mapuntrustedtodomain.xml
@@ -1,6 +1,7 @@
 <samba:parameter name="map untrusted to domain"
                  context="G"
-                 type="boolean"
+                 type="enum"
+                 enumlist="enum_bool_auto"
                  deprecated="1"
                  xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
 <description>
@@ -20,13 +21,31 @@
     </para>
 
     <para>
-    When this parameter is set to <constant>yes</constant> smbd provides the
+    The above describes the situation with <smbconfoption name="map untrusted to domain">no</smbconfoption>,
+    which was the default up to Samba 4.6.
+    </para>
+
+    <para>
+    With <smbconfoption name="map untrusted to domain">yes</smbconfoption> smbd provides the
     legacy behavior of mapping untrusted domain names to the primary domain.
     When smbd is not acting as a domain member server, this parameter has no
     effect.
     </para>
 
+    <para>
+    With <smbconfoption name="map untrusted to domain">auto</smbconfoption> smbd will
+    defer the mapping decision to the stack of auth method backends.
+    Each auth method is able to say I'm not authoritative and the
+    next backend will be used. This is basically the same as the behavior
+    implemented in Windows.
+    </para>
+
+    <para>
+    <smbconfoption name="map untrusted to domain">auto</smbconfoption> was added
+    with Samba 4.7.0.
+    </para>
 </description>
 
 <value type="default">no</value>
+<value type="example">auto</value>
 </samba:parameter>
-- 
1.9.1


From 4227cb36bb9fb3d270148f62cfc631c0316cc5be Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Wed, 22 Mar 2017 12:11:26 +0100
Subject: [PATCH 4/4] docs-xml: change the default for "map untrusted to
 domain" to "auto"

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 docs-xml/smbdotconf/security/mapuntrustedtodomain.xml | 7 ++++---
 lib/param/loadparm.c                                  | 2 ++
 source3/param/loadparm.c                              | 2 +-
 3 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/docs-xml/smbdotconf/security/mapuntrustedtodomain.xml b/docs-xml/smbdotconf/security/mapuntrustedtodomain.xml
index 7a2df9a..fc2233f 100644
--- a/docs-xml/smbdotconf/security/mapuntrustedtodomain.xml
+++ b/docs-xml/smbdotconf/security/mapuntrustedtodomain.xml
@@ -42,10 +42,11 @@
 
     <para>
     <smbconfoption name="map untrusted to domain">auto</smbconfoption> was added
-    with Samba 4.7.0.
+    and become the default with Samba 4.7.0. As the option is marked as
+    <constant>deprecated</constant> it will be removed in a future release, while the behavior of
+    <smbconfoption name="map untrusted to domain">auto</smbconfoption> will be kept.
     </para>
 </description>
 
-<value type="default">no</value>
-<value type="example">auto</value>
+<value type="default">auto</value>
 </samba:parameter>
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index 335c54a..b032dd0 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -2794,6 +2794,8 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
 
 	lpcfg_do_global_parameter(lp_ctx, "guest account", GUEST_ACCOUNT);
 
+	lpcfg_do_global_parameter(lp_ctx, "map untrusted to domain", "auto");
+
 	lpcfg_do_global_parameter(lp_ctx, "client schannel", "auto");
 
 	lpcfg_do_global_parameter(lp_ctx, "smb encrypt", "default");
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index c65e613..2b37e60 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -856,7 +856,7 @@ static void init_globals(struct loadparm_context *lp_ctx, bool reinit_globals)
 
 	Globals.min_receivefile_size = 0;
 
-	Globals.map_untrusted_to_domain = false;
+	Globals.map_untrusted_to_domain = Auto;
 	Globals.multicast_dns_register = true;
 
 	Globals.smb2_max_read = DEFAULT_SMB2_MAX_READ;
-- 
1.9.1

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: OpenPGP digital signature
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20170323/619aec69/signature.sig>


More information about the samba-technical mailing list