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

Stefan Metzmacher metze at samba.org
Tue Mar 21 15:10:38 UTC 2017


Am 21.03.2017 um 08:59 schrieb Stefan Metzmacher via samba-technical:
> Am 21.03.2017 um 00:06 schrieb Stefan Metzmacher via samba-technical:
>> Hi Volker,
>>
>>> On Mon, Mar 20, 2017 at 10:54:59AM +0100, Stefan Metzmacher wrote:
>>>> I'm currently looking into this and I might have something that should
>>>> do the job without changing too much within the next days.
>>>
>>> Can you share your ideas?
>>
>> https://git.samba.org/?p=metze/samba/wip.git;a=shortlog;h=refs/heads/master3-auth
> 
> Ok,
> https://git.samba.org/?p=metze/samba/wip.git;a=shortlog;h=refs/heads/master3-auth-ok
> contains the first preparation step that should not really change the logic.

The following patchset also passed autobuild and should not change the
logic.

Please review:-)

I'll try to prepare the rest in the next days.

Andrew, I rebased you branch on top of this:
https://git.samba.org/?p=metze/samba/wip.git;a=shortlog;h=refs/heads/master3-auth-logging

metze
-------------- next part --------------
From 2fcd10fb9c21b6b35c04ac8a1cf61400003e59b0 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 01/37] 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.

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 58ff14bbb37db8cb988e9f6f3aae7b28105f458e Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 19:28:16 +0100
Subject: [PATCH 02/37] netlogon.idl: make netr_LogonInfoClass public

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 librpc/idl/netlogon.idl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/librpc/idl/netlogon.idl b/librpc/idl/netlogon.idl
index 621d537..e4b499f 100644
--- a/librpc/idl/netlogon.idl
+++ b/librpc/idl/netlogon.idl
@@ -168,7 +168,7 @@ interface netlogon
 		[size_is(length)] uint8 *data;
 	} netr_GenericInfo;
 
-	typedef enum {
+	typedef [public] enum {
 		NetlogonInteractiveInformation = 1,
 		NetlogonNetworkInformation = 2,
 		NetlogonServiceInformation = 3,
-- 
1.9.1


From 0795bd8f7217b35c94c7d9213cdcfc86d80959d8 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 11:41:04 +0100
Subject: [PATCH 03/37] auth4: make auth_check_password_wrapper() static

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/auth/auth.h      |  6 ------
 source4/auth/ntlm/auth.c | 10 +++++-----
 2 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/source4/auth/auth.h b/source4/auth/auth.h
index 7c62318..feddb46 100644
--- a/source4/auth/auth.h
+++ b/source4/auth/auth.h
@@ -145,12 +145,6 @@ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx,
 			     struct loadparm_context *lp_ctx,
 			     struct auth4_context **auth_ctx);
 
-NTSTATUS auth_check_password_wrapper(struct auth4_context *auth_ctx,
-			     TALLOC_CTX *mem_ctx,
-			     const struct auth_usersupplied_info *user_info, 
-			     void **server_returned_info,
-			     DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key);
-
 NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
 			     TALLOC_CTX *mem_ctx,
 			     const struct auth_usersupplied_info *user_info, 
diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
index 05d6c3c..2260244 100644
--- a/source4/auth/ntlm/auth.c
+++ b/source4/auth/ntlm/auth.c
@@ -184,11 +184,11 @@ _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
 	return status;
 }
 
-_PUBLIC_ NTSTATUS auth_check_password_wrapper(struct auth4_context *auth_ctx,
-					      TALLOC_CTX *mem_ctx,
-					      const struct auth_usersupplied_info *user_info, 
-					      void **server_returned_info,
-					      DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
+static NTSTATUS auth_check_password_wrapper(struct auth4_context *auth_ctx,
+					    TALLOC_CTX *mem_ctx,
+					    const struct auth_usersupplied_info *user_info,
+					    void **server_returned_info,
+					    DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
 {
 	struct auth_user_info_dc *user_info_dc;
 	NTSTATUS status;
-- 
1.9.1


From 3ed849478076315e20644bd91f9290cafc19cb95 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 6 Mar 2017 14:32:18 +0100
Subject: [PATCH 04/37] wbinfo: Add "authoritative" to wbinfo -a output

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 nsswitch/wbinfo.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/nsswitch/wbinfo.c b/nsswitch/wbinfo.c
index 80b245a..57f2b3b 100644
--- a/nsswitch/wbinfo.c
+++ b/nsswitch/wbinfo.c
@@ -1823,13 +1823,15 @@ static bool wbinfo_auth_crap(char *username, bool use_ntlmv2, bool use_lanman)
 
 	if (wbc_status == WBC_ERR_AUTH_ERROR) {
 		d_fprintf(stderr,
-			 "wbcAuthenticateUserEx(%s%c%s): error code was %s (0x%x)\n"
+			 "wbcAuthenticateUserEx(%s%c%s): error code was "
+			  "%s (0x%x, authoritative=%"PRIu8")\n"
 			 "error message was: %s\n",
 			 name_domain,
 			 winbind_separator(),
 			 name_user,
 			 err->nt_string,
 			 err->nt_status,
+			 err->authoritative,
 			 err->display_string);
 		wbcFreeMemory(err);
 	} else if (WBC_ERROR_IS_OK(wbc_status)) {
-- 
1.9.1


From 987e5ab63106f2d427fe11ad780962f2f1e317bf Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sat, 11 Feb 2017 15:05:52 +0100
Subject: [PATCH 05/37] auth3: Don't try other auth modules on any error

So far if any kind of error has happened, we just tried further auth
modules. An auth module should have the chance to definitely say "no,
this is a valid error, no further attempts anywhere else". The protocol
so far was for an auth module to return NT_STATUS_NOT_IMPLEMENTED if it
wanted to pass on to other modules, but any error led to the next auth
modules also being given a try.

This patch makes any auth module return code except NOT_IMPLEMENTED to
terminate the loop, such that every module has to explicitly request to
pass on to the next module via NOT_IMPLEMENTED.

All modules we reference in make_auth_context_subsystem() have code to
explicitly say "not for me please" with NOT_IMPLEMENTED.

This *might* break existing setups which fail in for example "guest" or
"winbind" due to other reasons. I prefer it this way though, because
adding another parameter like "This is a real authoritative failure,
don't go looking somewhere else" will only add to the mess.

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

diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 1cbe46e..61e8ce6 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -250,9 +250,7 @@ NTSTATUS auth_check_ntlm_password(TALLOC_CTX *mem_ctx,
 				  auth_method->name, user_info->client.account_name, nt_errstr(nt_status)));
 		}
 
-		if (NT_STATUS_IS_OK(nt_status)) {
-			break;
-		}
+		break;
 	}
 
 	/* successful authentication */
-- 
1.9.1


From c191e6666fc67849ea1f885218930b5405c1c265 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Sat, 11 Feb 2017 15:44:01 +0100
Subject: [PATCH 06/37] auth3: Simplify the logic in auth_check_ntlm_password

Move everything but the strict loop logic outside. This makes the
loop exit condition clearer to me: Anything but NOT_IMPLEMENTED breaks
the loop.

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

diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 61e8ce6..6d6ed71 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -166,6 +166,7 @@ NTSTATUS auth_check_ntlm_password(TALLOC_CTX *mem_ctx,
 				  struct auth_serversupplied_info **pserver_info)
 {
 	TALLOC_CTX *frame;
+	const char *auth_method_name = "";
 	/* if all the modules say 'not for me' this is reasonable */
 	NTSTATUS nt_status = NT_STATUS_NO_SUCH_USER;
 	const char *unix_username;
@@ -214,51 +215,50 @@ NTSTATUS auth_check_ntlm_password(TALLOC_CTX *mem_ctx,
 	}
 
 	for (auth_method = auth_context->auth_method_list;auth_method; auth_method = auth_method->next) {
-		NTSTATUS result;
+
+		auth_method_name = auth_method->name;
 
 		if (user_info->flags & USER_INFO_LOCAL_SAM_ONLY
 		    && !(auth_method->flags & AUTH_METHOD_LOCAL_SAM)) {
 			continue;
 		}
 
-		result = auth_method->auth(auth_context,
-					   auth_method->private_data,
-					   talloc_tos(),
-					   user_info,
-					   &server_info);
-
-		/* check if the module did anything */
-		if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) {
-			DEBUG(10,("check_ntlm_password: %s had nothing to say\n", auth_method->name));
-			if (user_info->flags & USER_INFO_LOCAL_SAM_ONLY) {
-				/* we don't expose the NT_STATUS_NOT_IMPLEMENTED
-				 * internals, except when the caller is only probing
-				 * one method, as they may do the fallback 
-				 */
-				nt_status = result;
-			}
-			continue;
-		}
-
-		nt_status = result;
+		nt_status = auth_method->auth(auth_context,
+					      auth_method->private_data,
+					      talloc_tos(),
+					      user_info,
+					      &server_info);
 
-		if (NT_STATUS_IS_OK(nt_status)) {
-			DEBUG(3, ("check_ntlm_password: %s authentication for user [%s] succeeded\n", 
-				  auth_method->name, user_info->client.account_name));
-		} else {
-			DEBUG(5, ("check_ntlm_password: %s authentication for user [%s] FAILED with error %s\n", 
-				  auth_method->name, user_info->client.account_name, nt_errstr(nt_status)));
+		if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) {
+			break;
 		}
 
-		break;
+		DBG_DEBUG("%s had nothing to say\n", auth_method->name);
 	}
 
-	/* successful authentication */
+	/* check if the module did anything */
+	if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED) &&
+	    ((user_info->flags & USER_INFO_LOCAL_SAM_ONLY) == 0)) {
+		/*
+		 * we don't expose the NT_STATUS_NOT_IMPLEMENTED
+		 * internals, except when the caller is only probing
+		 * one method, as they may do the fallback
+		 */
+		nt_status = NT_STATUS_NO_SUCH_USER;
+	}
 
 	if (!NT_STATUS_IS_OK(nt_status)) {
+		DBG_INFO("%s authentication for user [%s] FAILED with "
+			 "error %s\n",
+			 auth_method_name,
+			 user_info->client.account_name,
+			 nt_errstr(nt_status));
 		goto fail;
 	}
 
+	DBG_NOTICE("%s authentication for user [%s] succeeded\n",
+		   auth_method_name, user_info->client.account_name);
+
 	unix_username = server_info->unix_name;
 
 	/* We skip doing this step if the caller asked us not to */
-- 
1.9.1


From 787a8b3712e671150eaf1e6c5402388ccfe0ad71 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 13 Mar 2017 08:08:44 +0100
Subject: [PATCH 07/37] auth3: Introduce auth3_context_set_challenge

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/auth/auth.c  | 14 +++++++++++++-
 source3/auth/proto.h |  2 ++
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 6d6ed71..2c8c495 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -545,4 +545,16 @@ NTSTATUS make_auth_context_fixed(TALLOC_CTX *mem_ctx,
 	return nt_status;
 }
 
-
+bool auth3_context_set_challenge(struct auth_context *ctx, uint8_t chal[8],
+				 const char *challenge_set_by)
+{
+	ctx->challenge = data_blob_talloc(ctx, chal, 8);
+	if (ctx->challenge.data == NULL) {
+		return false;
+	}
+	ctx->challenge_set_by = talloc_strdup(ctx, challenge_set_by);
+	if (ctx->challenge_set_by == NULL) {
+		return false;
+	}
+	return true;
+}
diff --git a/source3/auth/proto.h b/source3/auth/proto.h
index 5fd3158..83ea2a5 100644
--- a/source3/auth/proto.h
+++ b/source3/auth/proto.h
@@ -43,6 +43,8 @@ NTSTATUS make_auth_context_subsystem(TALLOC_CTX *mem_ctx,
 NTSTATUS make_auth_context_fixed(TALLOC_CTX *mem_ctx,
 				 struct auth_context **auth_context,
 				 uchar chal[8]) ;
+bool auth3_context_set_challenge(struct auth_context *ctx, uint8_t chal[8],
+				 const char *challenge_set_by);
 
 /****************************************************************************
  Try to get a challenge out of the various authentication modules.
-- 
1.9.1


From 41bbc79dc87937462a2c6588ef5837fe2b3c7bd4 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 13 Mar 2017 08:43:06 +0100
Subject: [PATCH 08/37] auth3: Slightly simplify make_auth_context_subsystem()
 step1

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

diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 2c8c495..23b0a0a 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -469,10 +469,12 @@ NTSTATUS make_auth_context_subsystem(TALLOC_CTX *mem_ctx,
 	char **auth_method_list = NULL; 
 	NTSTATUS nt_status;
 
-	if (lp_auth_methods()
-	    && !(auth_method_list = str_list_copy(talloc_tos(), 
-			      lp_auth_methods()))) {
-		return NT_STATUS_NO_MEMORY;
+	if (lp_auth_methods()) {
+		DEBUG(5,("Using specified auth order\n"));
+		nt_status = make_auth_context_text_list(
+			mem_ctx, auth_context,
+			discard_const_p(char *, lp_auth_methods()));
+		return nt_status;
 	}
 
 	if (auth_method_list == NULL) {
-- 
1.9.1


From bf8f9669a5dd80a7beeb190e3259beb903720d64 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 13 Mar 2017 08:43:06 +0100
Subject: [PATCH 09/37] auth3: Slightly simplify make_auth_context_subsystem()
 step2

Use "git show -b" to see the simple diff.

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

diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 23b0a0a..b589abd 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -477,48 +477,43 @@ NTSTATUS make_auth_context_subsystem(TALLOC_CTX *mem_ctx,
 		return nt_status;
 	}
 
-	if (auth_method_list == NULL) {
-		switch (lp_server_role()) 
-		{
-		case ROLE_DOMAIN_MEMBER:
-			DEBUG(5,("Making default auth method list for server role = 'domain member'\n"));
+	switch (lp_server_role()) {
+	case ROLE_DOMAIN_MEMBER:
+		DEBUG(5,("Making default auth method list for server role = 'domain member'\n"));
+		auth_method_list = str_list_make_v3(
+			talloc_tos(), "guest sam winbind:ntdomain",
+			NULL);
+		break;
+	case ROLE_DOMAIN_BDC:
+	case ROLE_DOMAIN_PDC:
+		DEBUG(5,("Making default auth method list for DC\n"));
+		auth_method_list = str_list_make_v3(
+			talloc_tos(),
+			"guest sam winbind:trustdomain",
+			NULL);
+		break;
+	case ROLE_STANDALONE:
+		DEBUG(5,("Making default auth method list for server role = 'standalone server', encrypt passwords = yes\n"));
+		if (lp_encrypt_passwords()) {
 			auth_method_list = str_list_make_v3(
-				talloc_tos(), "guest sam winbind:ntdomain",
-				NULL);
-			break;
-		case ROLE_DOMAIN_BDC:
-		case ROLE_DOMAIN_PDC:
-			DEBUG(5,("Making default auth method list for DC\n"));
-			auth_method_list = str_list_make_v3(
-				talloc_tos(),
-				"guest sam winbind:trustdomain",
-				NULL);
-			break;
-		case ROLE_STANDALONE:
-			DEBUG(5,("Making default auth method list for server role = 'standalone server', encrypt passwords = yes\n"));
-			if (lp_encrypt_passwords()) {
-				auth_method_list = str_list_make_v3(
-						talloc_tos(), "guest sam",
-						NULL);
-			} else {
-				DEBUG(5,("Making default auth method list for server role = 'standalone server', encrypt passwords = no\n"));
-				auth_method_list = str_list_make_v3(
-					talloc_tos(), "guest unix", NULL);
-			}
-			break;
-		case ROLE_ACTIVE_DIRECTORY_DC:
-			DEBUG(5,("Making default auth method list for server role = 'active directory domain controller'\n"));
+					talloc_tos(), "guest sam",
+					NULL);
+		} else {
+			DEBUG(5,("Making default auth method list for server role = 'standalone server', encrypt passwords = no\n"));
 			auth_method_list = str_list_make_v3(
-				talloc_tos(),
-				"samba4",
-				NULL);
-			break;
-		default:
-			DEBUG(5,("Unknown auth method!\n"));
-			return NT_STATUS_UNSUCCESSFUL;
+				talloc_tos(), "guest unix", NULL);
 		}
-	} else {
-		DEBUG(5,("Using specified auth order\n"));
+		break;
+	case ROLE_ACTIVE_DIRECTORY_DC:
+		DEBUG(5,("Making default auth method list for server role = 'active directory domain controller'\n"));
+		auth_method_list = str_list_make_v3(
+			talloc_tos(),
+			"samba4",
+			NULL);
+		break;
+	default:
+		DEBUG(5,("Unknown auth method!\n"));
+		return NT_STATUS_UNSUCCESSFUL;
 	}
 
 	nt_status = make_auth_context_text_list(mem_ctx, auth_context,
-- 
1.9.1


From b74e7ccb3d8529572d034dca9dd1a065903fb07b Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 13 Mar 2017 08:14:00 +0100
Subject: [PATCH 10/37] winbindd: Call make_auth_context_subsystem directly

Soon we'll call specific methods here

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/winbindd/winbindd_pam.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 782b28a..4ff6eaa 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1235,6 +1235,7 @@ static NTSTATUS winbindd_dual_auth_passdb(TALLOC_CTX *mem_ctx,
 	struct tsocket_address *local;
 	struct netr_SamInfo3 *info3;
 	NTSTATUS status;
+	bool ok;
 	int rc;
 	TALLOC_CTX *frame = talloc_stackframe();
 
@@ -1268,15 +1269,22 @@ static NTSTATUS winbindd_dual_auth_passdb(TALLOC_CTX *mem_ctx,
 		user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
 	}
 
-	status = make_auth_context_fixed(frame, &auth_context, challenge->data);
+	status = make_auth_context_subsystem(frame, &auth_context);
 
 	if (!NT_STATUS_IS_OK(status)) {
-		DBG_ERR("make_auth_context_fixed failed: %s\n",
+		DBG_ERR("make_auth_context_subsystem failed: %s\n",
 			nt_errstr(status));
 		TALLOC_FREE(frame);
 		return status;
 	}
 
+	ok = auth3_context_set_challenge(auth_context,
+					 challenge->data, "fixed");
+	if (!ok) {
+		TALLOC_FREE(frame);
+		return NT_STATUS_NO_MEMORY;
+	}
+
 	status = auth_check_ntlm_password(mem_ctx,
 					  auth_context,
 					  user_info,
-- 
1.9.1


From 4372c0ec931b90197ce026a2d0fe635b3fad2d12 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Thu, 9 Mar 2017 15:19:06 +0100
Subject: [PATCH 11/37] netlogond3: "authorititative" is a uint8

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/rpc_server/netlogon/srv_netlog_nt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
index ef2c827..005bd03 100644
--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
@@ -1510,7 +1510,7 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
 			return NT_STATUS_INTERNAL_ERROR;
 	}
 
-	*r->out.authoritative = true; /* authoritative response */
+	*r->out.authoritative = 1; /* authoritative response */
 
 	switch (r->in.validation_level) {
 	case 2:
-- 
1.9.1


From 851fddece32e60ee6159c42aea14dcf8993e356a Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 13 Mar 2017 08:14:00 +0100
Subject: [PATCH 12/37] netlogond3: Call make_auth_context_subsystem directly

Soon we'll call specific methods here

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/rpc_server/netlogon/srv_netlog_nt.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
index 005bd03..09feb13 100644
--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
@@ -1586,13 +1586,20 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
 	{
 		const char *wksname = nt_workstation;
 		const char *workgroup = lp_workgroup();
+		bool ok;
 
-		status = make_auth_context_fixed(talloc_tos(), &auth_context,
-						 logon->network->challenge);
+		status = make_auth_context_subsystem(talloc_tos(),
+						     &auth_context);
 		if (!NT_STATUS_IS_OK(status)) {
 			return status;
 		}
 
+		ok = auth3_context_set_challenge(
+			auth_context, logon->network->challenge, "fixed");
+		if (!ok) {
+			return NT_STATUS_NO_MEMORY;
+		}
+
 		/* For a network logon, the workstation name comes in with two
 		 * backslashes in the front. Strip them if they are there. */
 
-- 
1.9.1


From a2cbb2557e418d5393753f8cf29f6d421491207f Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 16 Mar 2017 15:54:18 +0100
Subject: [PATCH 13/37] netlogond3: only call make_auth_context_subsystem() in
 one place

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/rpc_server/netlogon/srv_netlog_nt.c | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
index 09feb13..088ffe1 100644
--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
@@ -1580,6 +1580,12 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
 					      r->in.logon_level,
 					      logon);
 
+	status = make_auth_context_subsystem(talloc_tos(),
+					     &auth_context);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
 	switch (r->in.logon_level) {
 	case NetlogonNetworkInformation:
 	case NetlogonNetworkTransitiveInformation:
@@ -1588,12 +1594,6 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
 		const char *workgroup = lp_workgroup();
 		bool ok;
 
-		status = make_auth_context_subsystem(talloc_tos(),
-						     &auth_context);
-		if (!NT_STATUS_IS_OK(status)) {
-			return status;
-		}
-
 		ok = auth3_context_set_challenge(
 			auth_context, logon->network->challenge, "fixed");
 		if (!ok) {
@@ -1658,11 +1658,6 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
 		DEBUG(100,("decrypt of nt owf password:"));
 		dump_data(100, logon->password->ntpassword.hash, 16);
 #endif
-		status = make_auth_context_subsystem(talloc_tos(),
-						     &auth_context);
-		if (!NT_STATUS_IS_OK(status)) {
-			return status;
-		}
 
 		auth_get_ntlm_challenge(auth_context, chal);
 
-- 
1.9.1


From 4f9e41948e2fb8726a5869a0b826bd02131e0b73 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 13 Mar 2017 08:19:41 +0100
Subject: [PATCH 14/37] pdbtest: Call make_auth_context_subsystem directly

Last caller of make_auth_context_fixed

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/torture/pdbtest.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/source3/torture/pdbtest.c b/source3/torture/pdbtest.c
index fe51a76..a9f49bb 100644
--- a/source3/torture/pdbtest.c
+++ b/source3/torture/pdbtest.c
@@ -268,6 +268,7 @@ static bool test_auth(TALLOC_CTX *mem_ctx, struct samu *pdb_entry)
 	struct netr_SamInfo3 *info3_sam, *info3_auth;
 	struct auth_serversupplied_info *server_info;
 	NTSTATUS status;
+	bool ok;
 	
 	SMBOWFencrypt(pdb_get_nt_passwd(pdb_entry), challenge_8,
 		      local_nt_response);
@@ -298,13 +299,20 @@ static bool test_auth(TALLOC_CTX *mem_ctx, struct samu *pdb_entry)
 		return False;
 	}
 
-	status = make_auth_context_fixed(NULL, &auth_context, challenge.data);
+	status = make_auth_context_subsystem(NULL, &auth_context);
 
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0, ("Failed to test authentication with check_sam_security_info3: %s\n", nt_errstr(status)));
 		return False;
 	}
-	
+
+	ok = auth3_context_set_challenge(
+		auth_context, challenge.data, "fixed");
+	if (!ok) {
+		DBG_ERR("auth3_context_set_challenge failed\n");
+		return false;
+	}
+
 	status = auth_check_ntlm_password(mem_ctx,
 					  auth_context,
 					  user_info,
-- 
1.9.1


From 2849c20b33ab770dae14481385fac8c496010570 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 13 Mar 2017 08:22:27 +0100
Subject: [PATCH 15/37] auth3: Remove unused make_auth_context_fixed

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/auth/auth.c  | 19 -------------------
 source3/auth/proto.h |  3 ---
 2 files changed, 22 deletions(-)

diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index b589abd..aa70534 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -523,25 +523,6 @@ NTSTATUS make_auth_context_subsystem(TALLOC_CTX *mem_ctx,
 	return nt_status;
 }
 
-/***************************************************************************
- Make a auth_info struct with a fixed challenge
-***************************************************************************/
-
-NTSTATUS make_auth_context_fixed(TALLOC_CTX *mem_ctx,
-				 struct auth_context **auth_context,
-				 uchar chal[8])
-{
-	NTSTATUS nt_status;
-	nt_status = make_auth_context_subsystem(mem_ctx, auth_context);
-	if (!NT_STATUS_IS_OK(nt_status)) {
-		return nt_status;
-	}
-
-	(*auth_context)->challenge = data_blob_talloc(*auth_context, chal, 8);
-	(*auth_context)->challenge_set_by = "fixed";
-	return nt_status;
-}
-
 bool auth3_context_set_challenge(struct auth_context *ctx, uint8_t chal[8],
 				 const char *challenge_set_by)
 {
diff --git a/source3/auth/proto.h b/source3/auth/proto.h
index 83ea2a5..5ffe757 100644
--- a/source3/auth/proto.h
+++ b/source3/auth/proto.h
@@ -40,9 +40,6 @@ bool load_auth_module(struct auth_context *auth_context,
 		      const char *module, auth_methods **ret) ;
 NTSTATUS make_auth_context_subsystem(TALLOC_CTX *mem_ctx,
 				     struct auth_context **auth_context);
-NTSTATUS make_auth_context_fixed(TALLOC_CTX *mem_ctx,
-				 struct auth_context **auth_context,
-				 uchar chal[8]) ;
 bool auth3_context_set_challenge(struct auth_context *ctx, uint8_t chal[8],
 				 const char *challenge_set_by);
 
-- 
1.9.1


From ab116ac31d806355d566a512ebd66521582f3c2d Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Mon, 13 Mar 2017 08:58:43 +0100
Subject: [PATCH 16/37] auth3: Introduce make_auth_context_specific

Take a string instead of a string list. Simplifies
make_auth_context_subsystem and later similar callers

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

diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index aa70534..7769c23 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -459,6 +459,26 @@ static NTSTATUS make_auth_context_text_list(TALLOC_CTX *mem_ctx,
 	return NT_STATUS_OK;
 }
 
+static NTSTATUS make_auth_context_specific(TALLOC_CTX *mem_ctx,
+					   struct auth_context **auth_context,
+					   const char *methods)
+{
+	char **method_list;
+	NTSTATUS status;
+
+	method_list = str_list_make_v3(talloc_tos(), methods, NULL);
+	if (method_list == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	status = make_auth_context_text_list(
+		mem_ctx, auth_context, method_list);
+
+	TALLOC_FREE(method_list);
+
+	return status;
+}
+
 /***************************************************************************
  Make a auth_context struct for the auth subsystem
 ***************************************************************************/
@@ -466,7 +486,7 @@ static NTSTATUS make_auth_context_text_list(TALLOC_CTX *mem_ctx,
 NTSTATUS make_auth_context_subsystem(TALLOC_CTX *mem_ctx,
 				     struct auth_context **auth_context)
 {
-	char **auth_method_list = NULL; 
+	const char *methods = NULL;
 	NTSTATUS nt_status;
 
 	if (lp_auth_methods()) {
@@ -480,47 +500,32 @@ NTSTATUS make_auth_context_subsystem(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"));
-		auth_method_list = str_list_make_v3(
-			talloc_tos(), "guest sam winbind:ntdomain",
-			NULL);
+		methods = "guest sam winbind:ntdomain";
 		break;
 	case ROLE_DOMAIN_BDC:
 	case ROLE_DOMAIN_PDC:
 		DEBUG(5,("Making default auth method list for DC\n"));
-		auth_method_list = str_list_make_v3(
-			talloc_tos(),
-			"guest sam winbind:trustdomain",
-			NULL);
+		methods = "guest sam winbind:trustdomain";
 		break;
 	case ROLE_STANDALONE:
 		DEBUG(5,("Making default auth method list for server role = 'standalone server', encrypt passwords = yes\n"));
 		if (lp_encrypt_passwords()) {
-			auth_method_list = str_list_make_v3(
-					talloc_tos(), "guest sam",
-					NULL);
+			methods = "guest sam";
 		} else {
 			DEBUG(5,("Making default auth method list for server role = 'standalone server', encrypt passwords = no\n"));
-			auth_method_list = str_list_make_v3(
-				talloc_tos(), "guest unix", NULL);
+			methods = "guest unix";
 		}
 		break;
 	case ROLE_ACTIVE_DIRECTORY_DC:
 		DEBUG(5,("Making default auth method list for server role = 'active directory domain controller'\n"));
-		auth_method_list = str_list_make_v3(
-			talloc_tos(),
-			"samba4",
-			NULL);
+		methods = "samba4";
 		break;
 	default:
 		DEBUG(5,("Unknown auth method!\n"));
 		return NT_STATUS_UNSUCCESSFUL;
 	}
 
-	nt_status = make_auth_context_text_list(mem_ctx, auth_context,
-						auth_method_list);
-
-	TALLOC_FREE(auth_method_list);
-	return nt_status;
+	return make_auth_context_specific(mem_ctx, auth_context, methods);
 }
 
 bool auth3_context_set_challenge(struct auth_context *ctx, uint8_t chal[8],
-- 
1.9.1


From 008a1ddae40ef8738ff7fd2f2d381e6e4d580e37 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 09:13:02 +0100
Subject: [PATCH 17/37] auth3: add
 make_auth3_context_for_{ntlm,netlogon,winbind}

For now they'll all do the same, but that will change in the following commits.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/auth/auth.c  | 18 ++++++++++++++++++
 source3/auth/proto.h |  6 ++++++
 2 files changed, 24 insertions(+)

diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 7769c23..ed42740 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -528,6 +528,24 @@ 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)
+{
+	return make_auth_context_subsystem(mem_ctx, auth_context);
+}
+
+NTSTATUS make_auth3_context_for_winbind(TALLOC_CTX *mem_ctx,
+				        struct auth_context **auth_context)
+{
+	return make_auth_context_subsystem(mem_ctx, auth_context);
+}
+
 bool auth3_context_set_challenge(struct auth_context *ctx, uint8_t chal[8],
 				 const char *challenge_set_by)
 {
diff --git a/source3/auth/proto.h b/source3/auth/proto.h
index 5ffe757..92b2a85 100644
--- a/source3/auth/proto.h
+++ b/source3/auth/proto.h
@@ -40,6 +40,12 @@ bool load_auth_module(struct auth_context *auth_context,
 		      const char *module, auth_methods **ret) ;
 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);
+NTSTATUS make_auth3_context_for_netlogon(TALLOC_CTX *mem_ctx,
+					 struct auth_context **auth_context);
+NTSTATUS make_auth3_context_for_winbind(TALLOC_CTX *mem_ctx,
+					struct auth_context **auth_context);
 bool auth3_context_set_challenge(struct auth_context *ctx, uint8_t chal[8],
 				 const char *challenge_set_by);
 
-- 
1.9.1


From 68bcd0f0f0d68bc2e172712cc7386856ba746f6f Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 09:17:45 +0100
Subject: [PATCH 18/37] auth3: make use of make_auth3_context_for_ntlm()

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

diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
index f9b9184..95c70e8 100644
--- a/source3/auth/auth_generic.c
+++ b/source3/auth/auth_generic.c
@@ -208,7 +208,7 @@ NTSTATUS make_auth4_context(TALLOC_CTX *mem_ctx, struct auth4_context **auth4_co
 	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
 	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
 
-	nt_status = make_auth_context_subsystem(tmp_ctx, &auth_context);
+	nt_status = make_auth3_context_for_ntlm(tmp_ctx, &auth_context);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		TALLOC_FREE(tmp_ctx);
 		return nt_status;
@@ -242,7 +242,7 @@ NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
 	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
 	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
 
-	nt_status = make_auth_context_subsystem(tmp_ctx, &auth_context);
+	nt_status = make_auth3_context_for_ntlm(tmp_ctx, &auth_context);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		TALLOC_FREE(tmp_ctx);
 		return nt_status;
-- 
1.9.1


From 4895b4efe90a0e319e38565b145780dea0fd2957 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 12:29:26 +0100
Subject: [PATCH 19/37] pdbtest: make use of make_auth3_context_for_ntlm()

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

diff --git a/source3/torture/pdbtest.c b/source3/torture/pdbtest.c
index a9f49bb..0003566 100644
--- a/source3/torture/pdbtest.c
+++ b/source3/torture/pdbtest.c
@@ -299,7 +299,7 @@ static bool test_auth(TALLOC_CTX *mem_ctx, struct samu *pdb_entry)
 		return False;
 	}
 
-	status = make_auth_context_subsystem(NULL, &auth_context);
+	status = make_auth3_context_for_ntlm(NULL, &auth_context);
 
 	if (!NT_STATUS_IS_OK(status)) {
 		DEBUG(0, ("Failed to test authentication with check_sam_security_info3: %s\n", nt_errstr(status)));
-- 
1.9.1


From ee67f095261f02457e6f5f18805d35c056113a41 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 09:18:25 +0100
Subject: [PATCH 20/37] netlogond3: make use of
 make_auth3_context_for_netlogon()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/rpc_server/netlogon/srv_netlog_nt.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
index 088ffe1..4c43802 100644
--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
@@ -1580,8 +1580,7 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
 					      r->in.logon_level,
 					      logon);
 
-	status = make_auth_context_subsystem(talloc_tos(),
-					     &auth_context);
+	status = make_auth3_context_for_netlogon(talloc_tos(), &auth_context);
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
-- 
1.9.1


From 3cca83ea7e567aa9728cf601b9e1e7baae9c252b Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 09:18:41 +0100
Subject: [PATCH 21/37] winbindd: make use of make_auth3_context_for_winbind()

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

diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 4ff6eaa..fb6b8af 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1269,10 +1269,9 @@ static NTSTATUS winbindd_dual_auth_passdb(TALLOC_CTX *mem_ctx,
 		user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
 	}
 
-	status = make_auth_context_subsystem(frame, &auth_context);
-
+	status = make_auth3_context_for_winbind(frame, &auth_context);
 	if (!NT_STATUS_IS_OK(status)) {
-		DBG_ERR("make_auth_context_subsystem failed: %s\n",
+		DBG_ERR("make_auth3_context_for_winbind failed: %s\n",
 			nt_errstr(status));
 		TALLOC_FREE(frame);
 		return status;
-- 
1.9.1


From 64431fce766e68f2a88e8da0844f63b13b10cdb2 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 12:31:01 +0100
Subject: [PATCH 22/37] auth3: make make_auth_context_subsystem() static

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

diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index ed42740..ef8fcef 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -483,8 +483,8 @@ static NTSTATUS make_auth_context_specific(TALLOC_CTX *mem_ctx,
  Make a auth_context struct for the auth subsystem
 ***************************************************************************/
 
-NTSTATUS make_auth_context_subsystem(TALLOC_CTX *mem_ctx,
-				     struct auth_context **auth_context)
+static NTSTATUS make_auth_context_subsystem(TALLOC_CTX *mem_ctx,
+					    struct auth_context **auth_context)
 {
 	const char *methods = NULL;
 	NTSTATUS nt_status;
diff --git a/source3/auth/proto.h b/source3/auth/proto.h
index 92b2a85..1101346 100644
--- a/source3/auth/proto.h
+++ b/source3/auth/proto.h
@@ -38,8 +38,6 @@
 NTSTATUS smb_register_auth(int version, const char *name, auth_init_function init);
 bool load_auth_module(struct auth_context *auth_context,
 		      const char *module, auth_methods **ret) ;
-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);
 NTSTATUS make_auth3_context_for_netlogon(TALLOC_CTX *mem_ctx,
-- 
1.9.1


From 39218e49dc9a745edd988fa0b89ec0629b066aaf Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 12:08:59 +0100
Subject: [PATCH 23/37] auth4: add auth_context_create_for_netlogon()

For now it's the same as auth_context_create(), but this will
change the in the next commits.

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/auth/auth.h      | 5 +++++
 source4/auth/ntlm/auth.c | 9 +++++++++
 2 files changed, 14 insertions(+)

diff --git a/source4/auth/auth.h b/source4/auth/auth.h
index feddb46..95aacfe 100644
--- a/source4/auth/auth.h
+++ b/source4/auth/auth.h
@@ -144,6 +144,11 @@ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx,
 			     struct imessaging_context *msg,
 			     struct loadparm_context *lp_ctx,
 			     struct auth4_context **auth_ctx);
+NTSTATUS auth_context_create_for_netlogon(TALLOC_CTX *mem_ctx,
+					  struct tevent_context *ev,
+					  struct imessaging_context *msg,
+					  struct loadparm_context *lp_ctx,
+					  struct auth4_context **auth_ctx);
 
 NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
 			     TALLOC_CTX *mem_ctx,
diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
index 2260244..926bf48 100644
--- a/source4/auth/ntlm/auth.c
+++ b/source4/auth/ntlm/auth.c
@@ -645,6 +645,15 @@ _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx,
 	return status;
 }
 
+_PUBLIC_ NTSTATUS auth_context_create_for_netlogon(TALLOC_CTX *mem_ctx,
+						   struct tevent_context *ev,
+						   struct imessaging_context *msg,
+						   struct loadparm_context *lp_ctx,
+						   struct auth4_context **auth_ctx)
+{
+	return auth_context_create(mem_ctx, ev, msg, lp_ctx, auth_ctx);
+}
+
 /* the list of currently registered AUTH backends */
 static struct auth_backend {
 	const struct auth_operations *ops;
-- 
1.9.1


From 09ad791f70a23a3c5e9c63ee77c4145978168504 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 12:15:13 +0100
Subject: [PATCH 24/37] netlogon4: make use of
 auth_context_create_for_netlogon()

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index afa9b1c..332afd3 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -868,11 +868,10 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal
 	case NetlogonInteractiveTransitiveInformation:
 	case NetlogonServiceTransitiveInformation:
 
-		/* TODO: we need to deny anonymous access here */
-		nt_status = auth_context_create(mem_ctx,
-						dce_call->event_ctx, dce_call->msg_ctx,
-						dce_call->conn->dce_ctx->lp_ctx,
-						&auth_context);
+		nt_status = auth_context_create_for_netlogon(mem_ctx,
+					dce_call->event_ctx, dce_call->msg_ctx,
+					dce_call->conn->dce_ctx->lp_ctx,
+					&auth_context);
 		NT_STATUS_NOT_OK_RETURN(nt_status);
 
 		user_info->logon_parameters = r->in.logon->password->identity_info.parameter_control;
@@ -895,11 +894,10 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal
 	case NetlogonNetworkInformation:
 	case NetlogonNetworkTransitiveInformation:
 
-		/* TODO: we need to deny anonymous access here */
-		nt_status = auth_context_create(mem_ctx,
-						dce_call->event_ctx, dce_call->msg_ctx,
-						dce_call->conn->dce_ctx->lp_ctx,
-						&auth_context);
+		nt_status = auth_context_create_for_netlogon(mem_ctx,
+					dce_call->event_ctx, dce_call->msg_ctx,
+					dce_call->conn->dce_ctx->lp_ctx,
+					&auth_context);
 		NT_STATUS_NOT_OK_RETURN(nt_status);
 
 		nt_status = auth_context_set_challenge(auth_context, r->in.logon->network->challenge, "netr_LogonSamLogonWithFlags");
-- 
1.9.1


From 31b0196e1d7d264d2f6860ba63b99e0e2955fff3 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Thu, 2 Mar 2017 11:28:18 +0100
Subject: [PATCH 25/37] winbindd: NT_STATUS_CANT_ACCESS_DOMAIN_INFO means
 "Dunno"

Signed-off-by: Volker Lendecke <vl at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
---
 source3/winbindd/winbindd_pam.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index fb6b8af..77f2bf7 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1344,6 +1344,16 @@ static NTSTATUS winbind_samlogon_retry_loop(struct winbindd_domain *domain,
 
 		result = cm_connect_netlogon(domain, &netlogon_pipe);
 
+		if (NT_STATUS_EQUAL(result,
+				    NT_STATUS_CANT_ACCESS_DOMAIN_INFO)) {
+			/*
+			 * This means we don't have a trust account.
+			 */
+			*authoritative = 0;
+			result = NT_STATUS_NO_SUCH_USER;
+			break;
+		}
+
 		if (!NT_STATUS_IS_OK(result)) {
 			DEBUG(3,("Could not open handle to NETLOGON pipe "
 				 "(error: %s, attempts: %d)\n",
-- 
1.9.1


From c623dc0cae4cbf6e8d25de33a9c8bf574dc333a6 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 09:42:38 +0100
Subject: [PATCH 26/37] winbindd: let winbindd_dual_auth_passdb() return
 pauthoritative

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/winbindd/winbindd_pam.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 77f2bf7..2bac9ec 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1227,6 +1227,7 @@ static NTSTATUS winbindd_dual_auth_passdb(TALLOC_CTX *mem_ctx,
 					  const DATA_BLOB *lm_resp,
 					  const DATA_BLOB *nt_resp,
 					  bool interactive,
+					  uint8_t *pauthoritative,
 					  struct netr_SamInfo3 **pinfo3)
 {
 	struct auth_context *auth_context;
@@ -1239,6 +1240,11 @@ static NTSTATUS winbindd_dual_auth_passdb(TALLOC_CTX *mem_ctx,
 	int rc;
 	TALLOC_CTX *frame = talloc_stackframe();
 
+	/*
+	 * We are authoritative by default
+	 */
+	*pauthoritative = 1;
+
 	rc = tsocket_address_inet_from_strings(frame,
 					       "ip",
 					       "127.0.0.1",
@@ -1290,6 +1296,9 @@ static NTSTATUS winbindd_dual_auth_passdb(TALLOC_CTX *mem_ctx,
 					  &server_info);
 
 	if (!NT_STATUS_IS_OK(status)) {
+		if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) {
+			*pauthoritative = 0;
+		}
 		TALLOC_FREE(frame);
 		return status;
 	}
@@ -1563,12 +1572,14 @@ static NTSTATUS winbindd_dual_pam_auth_samlogon(TALLOC_CTX *mem_ctx,
 			mem_ctx, 0, name_domain, name_user,
 			&chal_blob, &lm_resp, &nt_resp,
 			true, /* interactive */
+			&authoritative,
 			info3);
 
 		/* 
-		 * We need to try the remote NETLOGON server if this is NOT_IMPLEMENTED 
+		 * We need to try the remote NETLOGON server if this is
+		 * not authoritative.
 		 */
-		if (!NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) {
+		if (authoritative != 0) {
 			goto done;
 		}
 	}
@@ -1983,13 +1994,14 @@ NTSTATUS winbind_dual_SamLogon(struct winbindd_domain *domain,
 			name_domain, name_user,
 			&chal_blob, &lm_response, &nt_response,
 			false, /* interactive */
+			authoritative,
 			info3);
 
 		/* 
-		 * We need to try the remote NETLOGON server if this is NOT_IMPLEMENTED 
+		 * We need to try the remote NETLOGON server if this is
+		 * not authoritative.
 		 */
-		if (!NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) {
-			*authoritative = 1;
+		if (*authoritative != 0) {
 			*flags = 0;
 			goto process_result;
 		}
-- 
1.9.1


From 14ce86c2c511beb1fc177310be35e64501a12f41 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 09:43:59 +0100
Subject: [PATCH 27/37] auth3: let auth_check_ntlm_password() return
 pauthoritative

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/auth/auth.c                         | 35 +++++++++++++++--------------
 source3/auth/auth_ntlmssp.c                 | 10 ++++++---
 source3/auth/proto.h                        | 10 ++++++---
 source3/rpc_server/netlogon/srv_netlog_nt.c | 12 ++--------
 source3/torture/pdbtest.c                   | 10 ++++++---
 source3/winbindd/winbindd_pam.c             |  7 ++----
 6 files changed, 43 insertions(+), 41 deletions(-)

diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index ef8fcef..11a777a4 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -153,22 +153,25 @@ static bool check_domain_match(const char *user, const char *domain)
  *                  filled in, either at creation or by calling the challenge geneation 
  *                  function auth_get_challenge().  
  *
- * @param server_info If successful, contains information about the authentication, 
- *                    including a struct samu struct describing the user.
+ * @param pserver_info If successful, contains information about the authentication,
+ *                     including a struct samu struct describing the user.
+ *
+ * @param pauthoritative Indicates if the result should be treated as final
+ *                       result.
  *
  * @return An NTSTATUS with NT_STATUS_OK or an appropriate error.
  *
  **/
-
 NTSTATUS auth_check_ntlm_password(TALLOC_CTX *mem_ctx,
 				  const struct auth_context *auth_context,
 				  const struct auth_usersupplied_info *user_info,
-				  struct auth_serversupplied_info **pserver_info)
+				  struct auth_serversupplied_info **pserver_info,
+				  uint8_t *pauthoritative)
 {
 	TALLOC_CTX *frame;
 	const char *auth_method_name = "";
 	/* if all the modules say 'not for me' this is reasonable */
-	NTSTATUS nt_status = NT_STATUS_NO_SUCH_USER;
+	NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED;
 	const char *unix_username;
 	auth_methods *auth_method;
 	struct auth_serversupplied_info *server_info;
@@ -179,6 +182,8 @@ NTSTATUS auth_check_ntlm_password(TALLOC_CTX *mem_ctx,
 
 	frame = talloc_stackframe();
 
+	*pauthoritative = 1;
+
 	DEBUG(3, ("check_ntlm_password:  Checking password for unmapped user [%s]\\[%s]@[%s] with the new password interface\n", 
 		  user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name));
 
@@ -236,23 +241,18 @@ NTSTATUS auth_check_ntlm_password(TALLOC_CTX *mem_ctx,
 		DBG_DEBUG("%s had nothing to say\n", auth_method->name);
 	}
 
-	/* check if the module did anything */
-	if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED) &&
-	    ((user_info->flags & USER_INFO_LOCAL_SAM_ONLY) == 0)) {
-		/*
-		 * we don't expose the NT_STATUS_NOT_IMPLEMENTED
-		 * internals, except when the caller is only probing
-		 * one method, as they may do the fallback
-		 */
+	if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) {
+		*pauthoritative = 0;
 		nt_status = NT_STATUS_NO_SUCH_USER;
 	}
 
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DBG_INFO("%s authentication for user [%s] FAILED with "
-			 "error %s\n",
+			 "error %s, authoritative=%u\n",
 			 auth_method_name,
 			 user_info->client.account_name,
-			 nt_errstr(nt_status));
+			 nt_errstr(nt_status),
+			 *pauthoritative);
 		goto fail;
 	}
 
@@ -313,9 +313,10 @@ fail:
 
 	/* failed authentication; check for guest lapping */
 
-	DEBUG(2, ("check_ntlm_password:  Authentication for user [%s] -> [%s] FAILED with error %s\n",
+	DEBUG(2, ("check_ntlm_password:  Authentication for user "
+		  "[%s] -> [%s] FAILED with error %s, authoritative=%u\n",
 		  user_info->client.account_name, user_info->mapped.account_name,
-		  nt_errstr(nt_status)));
+		  nt_errstr(nt_status), *pauthoritative));
 	ZERO_STRUCTP(pserver_info);
 
 	TALLOC_FREE(frame);
diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c
index a0e4902..0ff3bdd 100644
--- a/source3/auth/auth_ntlmssp.c
+++ b/source3/auth/auth_ntlmssp.c
@@ -145,6 +145,7 @@ NTSTATUS auth3_check_password(struct auth4_context *auth4_context,
 	struct auth_serversupplied_info *server_info;
 	NTSTATUS nt_status;
 	bool username_was_mapped;
+	uint8_t authoritative = 0;
 
 	/* The client has given us its machine name (which we only get over NBT transport).
 	   We need to possibly reload smb.conf if smb.conf includes depend on the machine name. */
@@ -179,13 +180,16 @@ NTSTATUS auth3_check_password(struct auth4_context *auth4_context,
 	nt_status = auth_check_ntlm_password(mem_ctx,
 					     auth_context,
 					     mapped_user_info,
-					     &server_info);
+					     &server_info,
+					     &authoritative);
 
 	if (!NT_STATUS_IS_OK(nt_status)) {
-		DEBUG(5,("Checking NTLMSSP password for %s\\%s failed: %s\n",
+		DEBUG(5,("Checking NTLMSSP password for %s\\%s failed: "
+			 "%s, authoritative=%u\n",
 			 user_info->client.domain_name,
 			 user_info->client.account_name,
-			 nt_errstr(nt_status)));
+			 nt_errstr(nt_status),
+			 authoritative));
 	}
 
 	username_was_mapped = mapped_user_info->was_mapped;
diff --git a/source3/auth/proto.h b/source3/auth/proto.h
index 1101346..ccc284c 100644
--- a/source3/auth/proto.h
+++ b/source3/auth/proto.h
@@ -78,8 +78,11 @@ NTSTATUS auth_get_ntlm_challenge(struct auth_context *auth_context,
  *                  filled in, either at creation or by calling the challenge geneation 
  *                  function auth_get_challenge().  
  *
- * @param server_info If successful, contains information about the authentication, 
- *                    including a struct samu struct describing the user.
+ * @param pserver_info If successful, contains information about the authentication,
+ *                     including a struct samu struct describing the user.
+ *
+ * @param pauthoritative Indicates if the result should be treated as final
+ *                       result.
  *
  * @return An NTSTATUS with NT_STATUS_OK or an appropriate error.
  *
@@ -87,7 +90,8 @@ NTSTATUS auth_get_ntlm_challenge(struct auth_context *auth_context,
 NTSTATUS auth_check_ntlm_password(TALLOC_CTX *mem_ctx,
 				  const struct auth_context *auth_context,
 				  const struct auth_usersupplied_info *user_info,
-				  struct auth_serversupplied_info **server_info);
+				  struct auth_serversupplied_info **pserver_info,
+				  uint8_t *pauthoritative);
 
 /* The following definitions come from auth/auth_builtin.c  */
 
diff --git a/source3/rpc_server/netlogon/srv_netlog_nt.c b/source3/rpc_server/netlogon/srv_netlog_nt.c
index 4c43802..38d7bda 100644
--- a/source3/rpc_server/netlogon/srv_netlog_nt.c
+++ b/source3/rpc_server/netlogon/srv_netlog_nt.c
@@ -1682,7 +1682,8 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
 		status = auth_check_ntlm_password(p->mem_ctx,
 						  auth_context,
 						  user_info,
-						  &server_info);
+						  &server_info,
+						  r->out.authoritative);
 	}
 
 	TALLOC_FREE(auth_context);
@@ -1694,15 +1695,6 @@ static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
 	/* Check account and password */
 
 	if (!NT_STATUS_IS_OK(status)) {
-		/* If we don't know what this domain is, we need to
-		   indicate that we are not authoritative.  This
-		   allows the client to decide if it needs to try
-		   a local user.  Fix by jpjanosi at us.ibm.com, #2976 */
-                if ( NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER)
-		     && !strequal(nt_domain, get_global_sam_name())
-		     && !is_trusted_domain(nt_domain) )
-			*r->out.authoritative = false; /* We are not authoritative */
-
 		TALLOC_FREE(server_info);
 		return status;
 	}
diff --git a/source3/torture/pdbtest.c b/source3/torture/pdbtest.c
index 0003566..b442883 100644
--- a/source3/torture/pdbtest.c
+++ b/source3/torture/pdbtest.c
@@ -269,7 +269,8 @@ static bool test_auth(TALLOC_CTX *mem_ctx, struct samu *pdb_entry)
 	struct auth_serversupplied_info *server_info;
 	NTSTATUS status;
 	bool ok;
-	
+	uint8_t authoritative = 0;
+
 	SMBOWFencrypt(pdb_get_nt_passwd(pdb_entry), challenge_8,
 		      local_nt_response);
 	SMBsesskeygen_ntv1(pdb_get_nt_passwd(pdb_entry), local_nt_session_key);
@@ -316,10 +317,13 @@ static bool test_auth(TALLOC_CTX *mem_ctx, struct samu *pdb_entry)
 	status = auth_check_ntlm_password(mem_ctx,
 					  auth_context,
 					  user_info,
-					  &server_info);
+					  &server_info,
+					  &authoritative);
 
 	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("Failed to test authentication with auth module: %s\n", nt_errstr(status)));
+		DEBUG(0, ("Failed to test authentication with auth module: "
+			  "%s authoritative[%u].\n",
+			  nt_errstr(status), authoritative));
 		return False;
 	}
 	
diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 2bac9ec..74941c7 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1293,12 +1293,9 @@ static NTSTATUS winbindd_dual_auth_passdb(TALLOC_CTX *mem_ctx,
 	status = auth_check_ntlm_password(mem_ctx,
 					  auth_context,
 					  user_info,
-					  &server_info);
-
+					  &server_info,
+					  pauthoritative);
 	if (!NT_STATUS_IS_OK(status)) {
-		if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) {
-			*pauthoritative = 0;
-		}
 		TALLOC_FREE(frame);
 		return status;
 	}
-- 
1.9.1


From 51da4b53f396ba0f42bbcac6d3c20472fb727eea Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 11:16:36 +0100
Subject: [PATCH 28/37] auth4: let auth_check_password* return pauthoritative

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/auth/auth_samba4.c                    | 11 +++++++--
 source4/auth/auth.h                           |  6 +++--
 source4/auth/ntlm/auth.c                      | 32 ++++++++++++++++-----------
 source4/auth/ntlm/auth_simple.c               |  4 +++-
 source4/rpc_server/netlogon/dcerpc_netlogon.c |  4 ++--
 source4/smb_server/smb/sesssetup.c            |  9 +++++---
 6 files changed, 43 insertions(+), 23 deletions(-)

diff --git a/source3/auth/auth_samba4.c b/source3/auth/auth_samba4.c
index a0d6afd3..138c6cd 100644
--- a/source3/auth/auth_samba4.c
+++ b/source3/auth/auth_samba4.c
@@ -118,6 +118,7 @@ static NTSTATUS check_samba4_security(const struct auth_context *auth_context,
 	NTSTATUS nt_status;
 	struct auth_user_info_dc *user_info_dc;
 	struct auth4_context *auth4_context;
+	uint8_t authoritative = 0;
 
 	nt_status = make_auth4_context_s4(auth_context, mem_ctx, &auth4_context);
 	if (!NT_STATUS_IS_OK(nt_status)) {
@@ -132,13 +133,19 @@ static NTSTATUS check_samba4_security(const struct auth_context *auth_context,
 		return nt_status;
 	}
 
-	nt_status = auth_check_password(auth4_context, auth4_context, user_info, &user_info_dc);
+	nt_status = auth_check_password(auth4_context, auth4_context, user_info,
+					&user_info_dc, &authoritative);
 	if (!NT_STATUS_IS_OK(nt_status)) {
+		if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) &&
+				    authoritative == 0)
+		{
+			nt_status = NT_STATUS_NOT_IMPLEMENTED;
+		}
 		TALLOC_FREE(auth4_context);
 		TALLOC_FREE(frame);
 		return nt_status;
 	}
-	
+
 	nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx,
 						       user_info_dc,
 						       &info3);
diff --git a/source4/auth/auth.h b/source4/auth/auth.h
index 95aacfe..7358f40 100644
--- a/source4/auth/auth.h
+++ b/source4/auth/auth.h
@@ -153,7 +153,8 @@ NTSTATUS auth_context_create_for_netlogon(TALLOC_CTX *mem_ctx,
 NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
 			     TALLOC_CTX *mem_ctx,
 			     const struct auth_usersupplied_info *user_info, 
-			     struct auth_user_info_dc **user_info_dc);
+			     struct auth_user_info_dc **user_info_dc,
+			     uint8_t *pauthoritative);
 NTSTATUS auth4_init(void);
 NTSTATUS auth_register(const struct auth_operations *ops);
 NTSTATUS server_service_auth_init(void);
@@ -173,7 +174,8 @@ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx,
 					    const struct auth_usersupplied_info *user_info);
 NTSTATUS auth_check_password_recv(struct tevent_req *req,
 				  TALLOC_CTX *mem_ctx,
-				  struct auth_user_info_dc **user_info_dc);
+				  struct auth_user_info_dc **user_info_dc,
+				  uint8_t *pauthoritative);
 
 bool auth_challenge_may_be_modified(struct auth4_context *auth_ctx);
 NTSTATUS auth_context_set_challenge(struct auth4_context *auth_ctx, const uint8_t chal[8], const char *set_by);
diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
index 926bf48..12e26f4 100644
--- a/source4/auth/ntlm/auth.c
+++ b/source4/auth/ntlm/auth.c
@@ -155,7 +155,8 @@ static NTSTATUS auth_generate_session_info_principal(struct auth4_context *auth_
 _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
 			     TALLOC_CTX *mem_ctx,
 			     const struct auth_usersupplied_info *user_info, 
-			     struct auth_user_info_dc **user_info_dc)
+			     struct auth_user_info_dc **user_info_dc,
+			     uint8_t *pauthoritative)
 {
 	struct tevent_req *subreq;
 	struct tevent_context *ev;
@@ -178,7 +179,8 @@ _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
 		return NT_STATUS_INTERNAL_ERROR;
 	}
 
-	status = auth_check_password_recv(subreq, mem_ctx, user_info_dc);
+	status = auth_check_password_recv(subreq, mem_ctx,
+					  user_info_dc, pauthoritative);
 	TALLOC_FREE(subreq);
 
 	return status;
@@ -192,9 +194,10 @@ static NTSTATUS auth_check_password_wrapper(struct auth4_context *auth_ctx,
 {
 	struct auth_user_info_dc *user_info_dc;
 	NTSTATUS status;
+	uint8_t authoritative = 0;
 
 	status = auth_check_password(auth_ctx, mem_ctx, user_info,
-				     &user_info_dc);
+				     &user_info_dc, &authoritative);
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
@@ -225,6 +228,7 @@ struct auth_check_password_state {
 	const struct auth_usersupplied_info *user_info;
 	struct auth_user_info_dc *user_info_dc;
 	struct auth_method_context *method;
+	uint8_t authoritative;
 };
 
 static void auth_check_password_async_trigger(struct tevent_context *ev,
@@ -279,6 +283,10 @@ _PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx,
 		return NULL;
 	}
 
+	/*
+	 * We are authoritative by default.
+	 */
+	state->authoritative	= 1;
 	state->auth_ctx		= auth_ctx;
 	state->user_info	= user_info;
 
@@ -386,13 +394,8 @@ static void auth_check_password_async_trigger(struct tevent_context *ev,
 	}
 
 	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
-		if (!(state->user_info->flags & USER_INFO_LOCAL_SAM_ONLY)) {
-			/* don't expose the NT_STATUS_NOT_IMPLEMENTED
-			 * internals, except when the caller is only probing
-			 * one method, as they may do the fallback 
-			 */
-			status = NT_STATUS_NO_SUCH_USER;
-		}
+		state->authoritative = 0;
+		status = NT_STATUS_NO_SUCH_USER;
 	}
 
 	if (tevent_req_nterror(req, status)) {
@@ -424,20 +427,23 @@ static void auth_check_password_async_trigger(struct tevent_context *ev,
 
 _PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req,
 				  TALLOC_CTX *mem_ctx,
-				  struct auth_user_info_dc **user_info_dc)
+				  struct auth_user_info_dc **user_info_dc,
+				  uint8_t *pauthoritative)
 {
 	struct auth_check_password_state *state =
 		tevent_req_data(req, struct auth_check_password_state);
 	NTSTATUS status;
 
+	*pauthoritative = state->authoritative;
+
 	if (tevent_req_is_nterror(req, &status)) {
 		DEBUG(2,("auth_check_password_recv: "
 			 "%s authentication for user [%s\\%s] "
-			 "FAILED with error %s\n",
+			 "FAILED with error %s, authoritative=%u\n",
 			 (state->method ? state->method->ops->name : "NO_METHOD"),
 			 state->user_info->mapped.domain_name,
 			 state->user_info->mapped.account_name,
-			 nt_errstr(status)));
+			 nt_errstr(status), state->authoritative));
 		tevent_req_received(req);
 		return status;
 	}
diff --git a/source4/auth/ntlm/auth_simple.c b/source4/auth/ntlm/auth_simple.c
index f6dd9d0..be2ff5e 100644
--- a/source4/auth/ntlm/auth_simple.c
+++ b/source4/auth/ntlm/auth_simple.c
@@ -42,6 +42,7 @@ _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx,
 	struct auth_usersupplied_info *user_info;
 	struct auth_user_info_dc *user_info_dc;
 	NTSTATUS nt_status;
+	uint8_t authoritative = 0;
 	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
 
 	if (!tmp_ctx) {
@@ -83,7 +84,8 @@ _PUBLIC_ NTSTATUS authenticate_username_pw(TALLOC_CTX *mem_ctx,
 		MSV1_0_CLEARTEXT_PASSWORD_ALLOWED |
 		MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED;
 
-	nt_status = auth_check_password(auth_context, tmp_ctx, user_info, &user_info_dc);
+	nt_status = auth_check_password(auth_context, tmp_ctx, user_info,
+					&user_info_dc, &authoritative);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		talloc_free(tmp_ctx);
 		return nt_status;
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 332afd3..0f59a96 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -982,8 +982,8 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal
 		return NT_STATUS_INVALID_PARAMETER;
 	}
 
-	nt_status = auth_check_password(auth_context, mem_ctx, user_info, &user_info_dc);
-	/* TODO: set *r->out.authoritative = 0 on specific errors */
+	nt_status = auth_check_password(auth_context, mem_ctx, user_info,
+					&user_info_dc, r->out.authoritative);
 	NT_STATUS_NOT_OK_RETURN(nt_status);
 
 	switch (r->in.validation_level) {
diff --git a/source4/smb_server/smb/sesssetup.c b/source4/smb_server/smb/sesssetup.c
index e06853a..e3bfcb3 100644
--- a/source4/smb_server/smb/sesssetup.c
+++ b/source4/smb_server/smb/sesssetup.c
@@ -72,9 +72,11 @@ static void sesssetup_old_send(struct tevent_req *subreq)
 	struct auth_session_info *session_info;
 	struct smbsrv_session *smb_sess;
 	NTSTATUS status;
+	uint8_t authoritative = 0;
 	uint32_t flags;
 
-	status = auth_check_password_recv(subreq, req, &user_info_dc);
+	status = auth_check_password_recv(subreq, req, &user_info_dc,
+					  &authoritative);
 	TALLOC_FREE(subreq);
 	if (!NT_STATUS_IS_OK(status)) goto failed;
 
@@ -202,11 +204,12 @@ static void sesssetup_nt1_send(struct tevent_req *subreq)
 	struct auth_user_info_dc *user_info_dc = NULL;
 	struct auth_session_info *session_info;
 	struct smbsrv_session *smb_sess;
-
+	uint8_t authoritative = 0;
 	uint32_t flags;
 	NTSTATUS status;
 
-	status = auth_check_password_recv(subreq, req, &user_info_dc);
+	status = auth_check_password_recv(subreq, req, &user_info_dc,
+					  &authoritative);
 	TALLOC_FREE(subreq);
 	if (!NT_STATUS_IS_OK(status)) goto failed;
 
-- 
1.9.1


From 47d862b12c9fac981966f289ce34d4b154283801 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 11:49:40 +0100
Subject: [PATCH 29/37] ntlm_auth3: let contact_winbind_auth_crap() return
 pauthoritative

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source3/utils/ntlm_auth.c             | 11 +++++++++++
 source3/utils/ntlm_auth_diagnostics.c | 15 ++++++++++-----
 source3/utils/ntlm_auth_proto.h       |  1 +
 3 files changed, 22 insertions(+), 5 deletions(-)

diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
index 829eb8f..4bfab5b 100644
--- a/source3/utils/ntlm_auth.c
+++ b/source3/utils/ntlm_auth.c
@@ -528,6 +528,7 @@ NTSTATUS contact_winbind_auth_crap(const char *username,
 				   uint32_t extra_logon_parameters,
 				   uint8_t lm_key[8],
 				   uint8_t user_session_key[16],
+				   uint8_t *pauthoritative,
 				   char **error_string,
 				   char **unix_name)
 {
@@ -536,6 +537,8 @@ NTSTATUS contact_winbind_auth_crap(const char *username,
 	struct winbindd_request request;
 	struct winbindd_response response;
 
+	*pauthoritative = 1;
+
 	if (!get_require_membership_sid()) {
 		return NT_STATUS_INVALID_PARAMETER;
 	}
@@ -605,6 +608,7 @@ NTSTATUS contact_winbind_auth_crap(const char *username,
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		if (error_string) 
 			*error_string = smb_xstrdup(response.data.auth.error_string);
+		*pauthoritative = response.data.auth.authoritative;
 		winbindd_free_response(&response);
 		return nt_status;
 	}
@@ -951,6 +955,7 @@ static NTSTATUS winbind_pw_check(struct auth4_context *auth4_context,
 	uint8_t lm_key[8]; 
 	uint8_t user_sess_key[16]; 
 	char *unix_name = NULL;
+	uint8_t authoritative = 0;
 
 	nt_status = contact_winbind_auth_crap(user_info->client.account_name, user_info->client.domain_name, 
 					      user_info->workstation_name, 
@@ -960,6 +965,7 @@ static NTSTATUS winbind_pw_check(struct auth4_context *auth4_context,
 					      WBFLAG_PAM_LMKEY | WBFLAG_PAM_USER_SESSION_KEY | WBFLAG_PAM_UNIX_NAME,
 					      0,
 					      lm_key, user_sess_key, 
+					      &authoritative,
 					      &error_string, &unix_name);
 
 	if (NT_STATUS_IS_OK(nt_status)) {
@@ -1719,6 +1725,8 @@ static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mod
 				TALLOC_FREE(mem_ctx);
 
 			} else {
+				uint8_t authoritative = 0;
+
 				if (!domain) {
 					domain = smb_xstrdup(get_winbind_domain());
 				}
@@ -1738,6 +1746,7 @@ static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mod
 								      flags, 0,
 								      lm_key,
 								      user_session_key,
+								      &authoritative,
 								      &error_string,
 								      NULL);
 			}
@@ -2185,6 +2194,7 @@ static bool check_auth_crap(void)
 	char *hex_lm_key;
 	char *hex_user_session_key;
 	char *error_string;
+	uint8_t authoritative = 0;
 
 	setbuf(stdout, NULL);
 
@@ -2204,6 +2214,7 @@ static bool check_auth_crap(void)
 					      flags, 0,
 					      (unsigned char *)lm_key, 
 					      (unsigned char *)user_session_key, 
+					      &authoritative,
 					      &error_string, NULL);
 
 	if (!NT_STATUS_IS_OK(nt_status)) {
diff --git a/source3/utils/ntlm_auth_diagnostics.c b/source3/utils/ntlm_auth_diagnostics.c
index 5533fd2..41591a8 100644
--- a/source3/utils/ntlm_auth_diagnostics.c
+++ b/source3/utils/ntlm_auth_diagnostics.c
@@ -54,7 +54,7 @@ static bool test_lm_ntlm_broken(enum ntlm_break break_which)
 	DATA_BLOB lm_response = data_blob(NULL, 24);
 	DATA_BLOB nt_response = data_blob(NULL, 24);
 	DATA_BLOB session_key = data_blob(NULL, 16);
-
+	uint8_t authoritative = 0;
 	uchar lm_key[8];
 	uchar user_session_key[16];
 	uchar lm_hash[16];
@@ -101,6 +101,7 @@ static bool test_lm_ntlm_broken(enum ntlm_break break_which)
 					      flags, 0,
 					      lm_key, 
 					      user_session_key,
+					      &authoritative,
 					      &error_string, NULL);
 	
 	data_blob_free(&lm_response);
@@ -176,7 +177,7 @@ static bool test_ntlm_in_lm(void)
 	NTSTATUS nt_status;
 	uint32_t flags = 0;
 	DATA_BLOB nt_response = data_blob(NULL, 24);
-
+	uint8_t authoritative = 0;
 	uchar lm_key[8];
 	uchar lm_hash[16];
 	uchar user_session_key[16];
@@ -200,6 +201,7 @@ static bool test_ntlm_in_lm(void)
 					      flags, 0,
 					      lm_key,
 					      user_session_key,
+					      &authoritative,
 					      &error_string, NULL);
 	
 	data_blob_free(&nt_response);
@@ -243,7 +245,7 @@ static bool test_ntlm_in_both(void)
 	uint32_t flags = 0;
 	DATA_BLOB nt_response = data_blob(NULL, 24);
 	DATA_BLOB session_key = data_blob(NULL, 16);
-
+	uint8_t authoritative = 0;
 	uint8_t lm_key[8];
 	uint8_t lm_hash[16];
 	uint8_t user_session_key[16];
@@ -271,6 +273,7 @@ static bool test_ntlm_in_both(void)
 					      flags, 0,
 					      lm_key,
 					      user_session_key,
+					      &authoritative,
 					      &error_string, NULL);
 	
 	data_blob_free(&nt_response);
@@ -319,7 +322,7 @@ static bool test_lmv2_ntlmv2_broken(enum ntlm_break break_which)
 	DATA_BLOB lmv2_response = data_blob_null;
 	DATA_BLOB ntlmv2_session_key = data_blob_null;
 	DATA_BLOB names_blob = NTLMv2_generate_names_blob(NULL, get_winbind_netbios_name(), get_winbind_domain());
-
+	uint8_t authoritative = 0;
 	uchar user_session_key[16];
 	DATA_BLOB chall = get_challenge();
 	char *error_string;
@@ -362,6 +365,7 @@ static bool test_lmv2_ntlmv2_broken(enum ntlm_break break_which)
 					      flags, 0,
 					      NULL, 
 					      user_session_key,
+					      &authoritative,
 					      &error_string, NULL);
 	
 	data_blob_free(&lmv2_response);
@@ -448,7 +452,7 @@ static bool test_plaintext(enum ntlm_break break_which)
 	char *password;
 	smb_ucs2_t *nt_response_ucs2;
 	size_t converted_size;
-
+	uint8_t authoritative = 0;
 	uchar user_session_key[16];
 	uchar lm_key[16];
 	static const uchar zeros[8] = { 0, };
@@ -513,6 +517,7 @@ static bool test_plaintext(enum ntlm_break break_which)
 					      flags, MSV1_0_CLEARTEXT_PASSWORD_ALLOWED,
 					      lm_key,
 					      user_session_key,
+					      &authoritative,
 					      &error_string, NULL);
 	
 	TALLOC_FREE(nt_response.data);
diff --git a/source3/utils/ntlm_auth_proto.h b/source3/utils/ntlm_auth_proto.h
index 367fd79..63c4763 100644
--- a/source3/utils/ntlm_auth_proto.h
+++ b/source3/utils/ntlm_auth_proto.h
@@ -39,6 +39,7 @@ NTSTATUS contact_winbind_auth_crap(const char *username,
 				   uint32_t extra_logon_parameters,
 				   uint8_t lm_key[8],
 				   uint8_t user_session_key[16],
+				   uint8_t *pauthoritative,
 				   char **error_string,
 				   char **unix_name);
 
-- 
1.9.1


From 0e143a55abef30953e2e866501912b4e8ef691d0 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 11:52:51 +0100
Subject: [PATCH 30/37] auth: let auth4_context->check_ntlm_password() return
 pauthoritative

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 auth/common_auth.h            |  1 +
 auth/ntlmssp/ntlmssp_server.c |  3 +++
 source3/auth/auth_generic.c   |  2 ++
 source3/auth/auth_ntlmssp.c   | 12 +++++++++---
 source3/auth/proto.h          |  1 +
 source3/utils/ntlm_auth.c     |  9 ++++++---
 source4/auth/ntlm/auth.c      |  4 ++--
 7 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/auth/common_auth.h b/auth/common_auth.h
index d1a775d..5d232f4 100644
--- a/auth/common_auth.h
+++ b/auth/common_auth.h
@@ -110,6 +110,7 @@ struct auth4_context {
 	NTSTATUS (*check_ntlm_password)(struct auth4_context *auth_ctx,
 					TALLOC_CTX *mem_ctx,
 					const struct auth_usersupplied_info *user_info,
+					uint8_t *pauthoritative,
 					void **server_returned_info,
 					DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key);
 
diff --git a/auth/ntlmssp/ntlmssp_server.c b/auth/ntlmssp/ntlmssp_server.c
index ddee875..eab8121 100644
--- a/auth/ntlmssp/ntlmssp_server.c
+++ b/auth/ntlmssp/ntlmssp_server.c
@@ -726,9 +726,12 @@ static NTSTATUS ntlmssp_server_check_password(struct gensec_security *gensec_sec
 	user_info->password.response.nt.data = talloc_steal(user_info, ntlmssp_state->nt_resp.data);
 
 	if (auth_context->check_ntlm_password) {
+		uint8_t authoritative = 0;
+
 		nt_status = auth_context->check_ntlm_password(auth_context,
 							      gensec_ntlmssp,
 							      user_info,
+							      &authoritative,
 							      &gensec_ntlmssp->server_returned_info,
 							      user_session_key, lm_session_key);
 	}
diff --git a/source3/auth/auth_generic.c b/source3/auth/auth_generic.c
index 95c70e8..875b7ff 100644
--- a/source3/auth/auth_generic.c
+++ b/source3/auth/auth_generic.c
@@ -389,10 +389,12 @@ NTSTATUS auth_check_password_session_info(struct auth4_context *auth_context,
 {
 	NTSTATUS nt_status;
 	void *server_info;
+	uint8_t authoritative = 0;
 
 	nt_status = auth_context->check_ntlm_password(auth_context,
 						      talloc_tos(),
 						      user_info,
+						      &authoritative,
 						      &server_info, NULL, NULL);
 
 	if (NT_STATUS_IS_OK(nt_status)) {
diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c
index 0ff3bdd..a48c444 100644
--- a/source3/auth/auth_ntlmssp.c
+++ b/source3/auth/auth_ntlmssp.c
@@ -136,6 +136,7 @@ NTSTATUS auth3_set_challenge(struct auth4_context *auth4_context, const uint8_t
 NTSTATUS auth3_check_password(struct auth4_context *auth4_context,
 			      TALLOC_CTX *mem_ctx,
 			      const struct auth_usersupplied_info *user_info,
+			      uint8_t *pauthoritative,
 			      void **server_returned_info,
 			      DATA_BLOB *session_key, DATA_BLOB *lm_session_key)
 {
@@ -145,7 +146,11 @@ NTSTATUS auth3_check_password(struct auth4_context *auth4_context,
 	struct auth_serversupplied_info *server_info;
 	NTSTATUS nt_status;
 	bool username_was_mapped;
-	uint8_t authoritative = 0;
+
+	/*
+	 * Be authoritative by default.
+	 */
+	*pauthoritative = 1;
 
 	/* The client has given us its machine name (which we only get over NBT transport).
 	   We need to possibly reload smb.conf if smb.conf includes depend on the machine name. */
@@ -181,7 +186,7 @@ NTSTATUS auth3_check_password(struct auth4_context *auth4_context,
 					     auth_context,
 					     mapped_user_info,
 					     &server_info,
-					     &authoritative);
+					     pauthoritative);
 
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		DEBUG(5,("Checking NTLMSSP password for %s\\%s failed: "
@@ -189,7 +194,7 @@ NTSTATUS auth3_check_password(struct auth4_context *auth4_context,
 			 user_info->client.domain_name,
 			 user_info->client.account_name,
 			 nt_errstr(nt_status),
-			 authoritative));
+			 *pauthoritative));
 	}
 
 	username_was_mapped = mapped_user_info->was_mapped;
@@ -203,6 +208,7 @@ NTSTATUS auth3_check_password(struct auth4_context *auth4_context,
 							user_info->client.domain_name,
 							&server_info);
 		if (NT_STATUS_IS_OK(nt_status)) {
+			*pauthoritative = 1;
 			*server_returned_info = talloc_steal(mem_ctx, server_info);
 		}
 		return nt_status;
diff --git a/source3/auth/proto.h b/source3/auth/proto.h
index ccc284c..c5f6ade 100644
--- a/source3/auth/proto.h
+++ b/source3/auth/proto.h
@@ -132,6 +132,7 @@ NTSTATUS auth3_set_challenge(struct auth4_context *auth4_context, const uint8_t
 NTSTATUS auth3_check_password(struct auth4_context *auth4_context,
 			      TALLOC_CTX *mem_ctx,
 			      const struct auth_usersupplied_info *user_info,
+			      uint8_t *pauthoritative,
 			      void **server_returned_info,
 			      DATA_BLOB *session_key, DATA_BLOB *lm_session_key);
 
diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c
index 4bfab5b..3bd945f 100644
--- a/source3/utils/ntlm_auth.c
+++ b/source3/utils/ntlm_auth.c
@@ -947,6 +947,7 @@ static NTSTATUS ntlm_auth_set_challenge(struct auth4_context *auth_ctx, const ui
 static NTSTATUS winbind_pw_check(struct auth4_context *auth4_context, 
 				 TALLOC_CTX *mem_ctx,
 				 const struct auth_usersupplied_info *user_info, 
+				 uint8_t *pauthoritative,
 				 void **server_returned_info,
 				 DATA_BLOB *session_key, DATA_BLOB *lm_session_key)
 {
@@ -955,7 +956,6 @@ static NTSTATUS winbind_pw_check(struct auth4_context *auth4_context,
 	uint8_t lm_key[8]; 
 	uint8_t user_sess_key[16]; 
 	char *unix_name = NULL;
-	uint8_t authoritative = 0;
 
 	nt_status = contact_winbind_auth_crap(user_info->client.account_name, user_info->client.domain_name, 
 					      user_info->workstation_name, 
@@ -965,7 +965,7 @@ static NTSTATUS winbind_pw_check(struct auth4_context *auth4_context,
 					      WBFLAG_PAM_LMKEY | WBFLAG_PAM_USER_SESSION_KEY | WBFLAG_PAM_UNIX_NAME,
 					      0,
 					      lm_key, user_sess_key, 
-					      &authoritative,
+					      pauthoritative,
 					      &error_string, &unix_name);
 
 	if (NT_STATUS_IS_OK(nt_status)) {
@@ -995,7 +995,8 @@ static NTSTATUS winbind_pw_check(struct auth4_context *auth4_context,
 
 static NTSTATUS local_pw_check(struct auth4_context *auth4_context, 
 				TALLOC_CTX *mem_ctx,
-				const struct auth_usersupplied_info *user_info, 
+				const struct auth_usersupplied_info *user_info,
+				uint8_t *pauthoritative,
 				void **server_returned_info,
 				DATA_BLOB *session_key, DATA_BLOB *lm_session_key)
 {
@@ -1004,6 +1005,8 @@ static NTSTATUS local_pw_check(struct auth4_context *auth4_context,
 
 	nt_lm_owf_gen (opt_password, nt_pw.hash, lm_pw.hash);
 
+	*pauthoritative = 1;
+
 	nt_status = ntlm_password_check(mem_ctx,
 					true, true, 0,
 					&auth4_context->challenge.data,
diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
index 12e26f4..0eb2260 100644
--- a/source4/auth/ntlm/auth.c
+++ b/source4/auth/ntlm/auth.c
@@ -189,15 +189,15 @@ _PUBLIC_ NTSTATUS auth_check_password(struct auth4_context *auth_ctx,
 static NTSTATUS auth_check_password_wrapper(struct auth4_context *auth_ctx,
 					    TALLOC_CTX *mem_ctx,
 					    const struct auth_usersupplied_info *user_info,
+					    uint8_t *pauthoritative,
 					    void **server_returned_info,
 					    DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
 {
 	struct auth_user_info_dc *user_info_dc;
 	NTSTATUS status;
-	uint8_t authoritative = 0;
 
 	status = auth_check_password(auth_ctx, mem_ctx, user_info,
-				     &user_info_dc, &authoritative);
+				     &user_info_dc, pauthoritative);
 	if (!NT_STATUS_IS_OK(status)) {
 		return status;
 	}
-- 
1.9.1


From c30a388e57c27e2796ee438da3e77d53401723a5 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Thu, 16 Mar 2017 16:47:15 +0100
Subject: [PATCH 31/37] auth4: debug if method->ops->check_password() gives
 NOT_IMPLEMENTED

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

diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
index 0eb2260..5d3fbef 100644
--- a/source4/auth/ntlm/auth.c
+++ b/source4/auth/ntlm/auth.c
@@ -374,7 +374,7 @@ static void auth_check_password_async_trigger(struct tevent_context *ev,
 		status = method->ops->want_check(method, req, state->user_info);
 		if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
 			DEBUG(11,("auth_check_password_send: "
-				  "%s had nothing to say\n",
+				  "%s doesn't want to check\n",
 				  method->ops->name));
 			continue;
 		}
@@ -387,10 +387,15 @@ static void auth_check_password_async_trigger(struct tevent_context *ev,
 						     state,
 						     state->user_info,
 						     &state->user_info_dc);
-		if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
-			/* the backend has handled the request */
-			break;
+		if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
+			DEBUG(11,("auth_check_password_send: "
+				  "%s passes to the next method\n",
+				  method->ops->name));
+			continue;
 		}
+
+		/* the backend has handled the request */
+		break;
 	}
 
 	if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
-- 
1.9.1


From b66978c430da9e480a55b86d081d6987fc600ec8 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 16:46:38 +0100
Subject: [PATCH 32/37] auth3: only use "[samba4:]sam" in
 make_auth3_context_for_winbind()

This makes the USER_INFO_LOCAL_SAM_ONLY and AUTH_METHOD_LOCAL_SAM
interaction obsolete.

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

diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 11a777a4..31313c7 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -544,7 +544,24 @@ NTSTATUS make_auth3_context_for_netlogon(TALLOC_CTX *mem_ctx,
 NTSTATUS make_auth3_context_for_winbind(TALLOC_CTX *mem_ctx,
 				        struct auth_context **auth_context)
 {
-	return make_auth_context_subsystem(mem_ctx, auth_context);
+	const char *methods = NULL;
+
+	switch (lp_server_role()) {
+	case ROLE_STANDALONE:
+	case ROLE_DOMAIN_MEMBER:
+	case ROLE_DOMAIN_BDC:
+	case ROLE_DOMAIN_PDC:
+		methods = "sam";
+		break;
+	case ROLE_ACTIVE_DIRECTORY_DC:
+		methods = "samba4:sam";
+		break;
+	default:
+		DEBUG(5,("Unknown auth method!\n"));
+		return NT_STATUS_UNSUCCESSFUL;
+	}
+
+	return make_auth_context_specific(mem_ctx, auth_context, methods);
 }
 
 bool auth3_context_set_challenge(struct auth_context *ctx, uint8_t chal[8],
-- 
1.9.1


From 0a6cd2150577a43c7e169da25d7dc0626ba38c1a Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 21 Mar 2017 08:31:29 +0100
Subject: [PATCH 33/37] winbindd: no longer use USER_INFO_LOCAL_SAM_ONLY

make_auth3_context_for_winbind() restricts the used auth backends now.

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

diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c
index 74941c7..c04367e 100644
--- a/source3/winbindd/winbindd_pam.c
+++ b/source3/winbindd/winbindd_pam.c
@@ -1269,7 +1269,7 @@ static NTSTATUS winbindd_dual_auth_passdb(TALLOC_CTX *mem_ctx,
 	user_info->mapped_state = True;
 
 	/* We don't want to come back to winbindd or to do PAM account checks */
-	user_info->flags |= USER_INFO_LOCAL_SAM_ONLY | USER_INFO_INFO3_AND_NO_AUTHZ;
+	user_info->flags |= USER_INFO_INFO3_AND_NO_AUTHZ;
 
 	if (interactive) {
 		user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
-- 
1.9.1


From de1ff966aab1ec444813611c7d43b477386f7b3b Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 21 Mar 2017 08:32:27 +0100
Subject: [PATCH 34/37] auth3: remove unused
 USER_INFO_LOCAL_SAM_ONLY/AUTH_METHOD_LOCAL_SAM handling

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

diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 31313c7..3d82f2b 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -223,11 +223,6 @@ NTSTATUS auth_check_ntlm_password(TALLOC_CTX *mem_ctx,
 
 		auth_method_name = auth_method->name;
 
-		if (user_info->flags & USER_INFO_LOCAL_SAM_ONLY
-		    && !(auth_method->flags & AUTH_METHOD_LOCAL_SAM)) {
-			continue;
-		}
-
 		nt_status = auth_method->auth(auth_context,
 					      auth_method->private_data,
 					      talloc_tos(),
diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c
index c4100d5..5b53bca 100644
--- a/source3/auth/auth_sam.c
+++ b/source3/auth/auth_sam.c
@@ -121,8 +121,7 @@ static NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *par
 	}
 	result->auth = auth_samstrict_auth;
 	result->name = "sam";
-	result->flags = AUTH_METHOD_LOCAL_SAM;
-        *auth_method = result;
+	*auth_method = result;
 	return NT_STATUS_OK;
 }
 
diff --git a/source3/auth/auth_samba4.c b/source3/auth/auth_samba4.c
index 138c6cd..4c83c2a 100644
--- a/source3/auth/auth_samba4.c
+++ b/source3/auth/auth_samba4.c
@@ -379,7 +379,6 @@ static NTSTATUS auth_init_samba4(struct auth_context *auth_context,
 	result->auth = check_samba4_security;
 	result->prepare_gensec = prepare_gensec;
 	result->make_auth4_context = make_auth4_context_s4;
-	result->flags = AUTH_METHOD_LOCAL_SAM;
 
 	if (param && *param) {
 		auth_context->forced_samba4_methods = talloc_strdup(result, param);
-- 
1.9.1


From 2742f8be69cccbde599d90dee1be5ae0c37cd3c0 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 21 Mar 2017 08:32:27 +0100
Subject: [PATCH 35/37] auth4: remove unused
 USER_INFO_LOCAL_SAM_ONLY/AUTH_METHOD_LOCAL_SAM handling

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/auth/ntlm/auth.c     | 5 -----
 source4/auth/ntlm/auth_sam.c | 2 --
 2 files changed, 7 deletions(-)

diff --git a/source4/auth/ntlm/auth.c b/source4/auth/ntlm/auth.c
index 5d3fbef..1b7faee 100644
--- a/source4/auth/ntlm/auth.c
+++ b/source4/auth/ntlm/auth.c
@@ -361,11 +361,6 @@ static void auth_check_password_async_trigger(struct tevent_context *ev,
 
 	for (method=state->auth_ctx->methods; method; method = method->next) {
 
-		if (state->user_info->flags & USER_INFO_LOCAL_SAM_ONLY
-		    && !(method->ops->flags & AUTH_METHOD_LOCAL_SAM)) {
-			continue;
-		}
-
 		/* we fill in state->method here so debug messages in
 		   the callers know which method failed */
 		state->method = method;
diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c
index 90eabca..086f9af 100644
--- a/source4/auth/ntlm/auth_sam.c
+++ b/source4/auth/ntlm/auth_sam.c
@@ -700,7 +700,6 @@ static const struct auth_operations sam_ignoredomain_ops = {
 	.want_check	           = authsam_ignoredomain_want_check,
 	.check_password	           = authsam_check_password_internals,
 	.get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper,
-	.flags                     = AUTH_METHOD_LOCAL_SAM
 };
 
 static const struct auth_operations sam_ops = {
@@ -708,7 +707,6 @@ static const struct auth_operations sam_ops = {
 	.want_check	           = authsam_want_check,
 	.check_password	           = authsam_check_password_internals,
 	.get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper,
-	.flags                     = AUTH_METHOD_LOCAL_SAM
 };
 
 _PUBLIC_ NTSTATUS auth4_sam_init(void);
-- 
1.9.1


From c54e9eb7d9c31cc45846f4f3b0a31e52d74928ca Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Tue, 21 Mar 2017 08:32:27 +0100
Subject: [PATCH 36/37] auth: remove unused
 USER_INFO_LOCAL_SAM_ONLY/AUTH_METHOD_LOCAL_SAM defines

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 auth/common_auth.h | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/auth/common_auth.h b/auth/common_auth.h
index 5d232f4..8cbfc54 100644
--- a/auth/common_auth.h
+++ b/auth/common_auth.h
@@ -26,7 +26,7 @@
 #define USER_INFO_CASE_INSENSITIVE_PASSWORD 0x02 /* password may be in any case */
 #define USER_INFO_DONT_CHECK_UNIX_ACCOUNT   0x04 /* don't check unix account status */
 #define USER_INFO_INTERACTIVE_LOGON         0x08 /* Interactive logon */
-#define USER_INFO_LOCAL_SAM_ONLY            0x10 /* Only authenticate against the local SAM, do not map missing passwords to NO_SUCH_USER */
+/*unused #define USER_INFO_LOCAL_SAM_ONLY   0x10    Only authenticate against the local SAM, do not map missing passwords to NO_SUCH_USER */
 #define USER_INFO_INFO3_AND_NO_AUTHZ        0x20 /* Only fill in server_info->info3 and do not do any authorization steps */
 
 enum auth_password_state {
@@ -79,8 +79,6 @@ struct loadparm_context;
 struct ldb_context;
 struct smb_krb5_context;
 
-#define AUTH_METHOD_LOCAL_SAM 0x01
-
 struct auth4_context {
 	struct {
 		/* Who set this up in the first place? */
-- 
1.9.1


From c822b44f61d3db6d2bde082327316db71f46e555 Mon Sep 17 00:00:00 2001
From: Stefan Metzmacher <metze at samba.org>
Date: Fri, 17 Mar 2017 19:27:38 +0100
Subject: [PATCH 37/37] netlogond4: prepare dcesrv_netr_LogonSamLogon_base for
 async processing

Signed-off-by: Stefan Metzmacher <metze at samba.org>
---
 source4/rpc_server/netlogon/dcerpc_netlogon.c | 185 +++++++++++++++++++-------
 1 file changed, 138 insertions(+), 47 deletions(-)

diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index 0f59a96..334243d 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -832,6 +832,24 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_check(const struct netr_LogonSamLogonE
 	return NT_STATUS_OK;
 }
 
+struct dcesrv_netr_LogonSamLogon_base_state {
+	struct dcesrv_call_state *dce_call;
+
+	TALLOC_CTX *mem_ctx;
+
+	struct netlogon_creds_CredentialState *creds;
+
+	struct netr_LogonSamLogonEx r;
+
+	uint32_t _ignored_flags;
+
+	struct {
+		struct netr_LogonSamLogon *lsl;
+		struct netr_LogonSamLogonWithFlags *lslwf;
+		struct netr_LogonSamLogonEx *lslex;
+	} _r;
+};
+
 /*
   netr_LogonSamLogon_base
 
@@ -840,9 +858,12 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_check(const struct netr_LogonSamLogonE
   We can't do the traditional 'wrapping' format completely, as this
   function must only run under schannel
 */
-static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
-					struct netr_LogonSamLogonEx *r, struct netlogon_creds_CredentialState *creds)
+static NTSTATUS dcesrv_netr_LogonSamLogon_base_call(struct dcesrv_netr_LogonSamLogon_base_state *state)
 {
+	struct dcesrv_call_state *dce_call = state->dce_call;
+	TALLOC_CTX *mem_ctx = state->mem_ctx;
+	struct netr_LogonSamLogonEx *r = &state->r;
+	struct netlogon_creds_CredentialState *creds = state->creds;
 	struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
 	const char *workgroup = lpcfg_workgroup(lp_ctx);
 	struct auth4_context *auth_context = NULL;
@@ -1035,19 +1056,39 @@ static NTSTATUS dcesrv_netr_LogonSamLogon_base(struct dcesrv_call_state *dce_cal
 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
 				     struct netr_LogonSamLogonEx *r)
 {
+	struct dcesrv_netr_LogonSamLogon_base_state *state;
 	NTSTATUS nt_status;
-	struct netlogon_creds_CredentialState *creds;
 
 	*r->out.authoritative = 1;
 
-	nt_status = dcesrv_netr_LogonSamLogon_check(r);
+	state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonSamLogon_base_state);
+	if (state == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	state->dce_call = dce_call;
+	state->mem_ctx = mem_ctx;
+
+	state->r.in.server_name      = r->in.server_name;
+	state->r.in.computer_name    = r->in.computer_name;
+	state->r.in.logon_level      = r->in.logon_level;
+	state->r.in.logon            = r->in.logon;
+	state->r.in.validation_level = r->in.validation_level;
+	state->r.in.flags            = r->in.flags;
+	state->r.out.validation      = r->out.validation;
+	state->r.out.authoritative   = r->out.authoritative;
+	state->r.out.flags           = r->out.flags;
+
+	state->_r.lslex = r;
+
+	nt_status = dcesrv_netr_LogonSamLogon_check(&state->r);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		return nt_status;
 	}
 
 	nt_status = schannel_get_creds_state(mem_ctx,
 					     dce_call->conn->dce_ctx->lp_ctx,
-					     r->in.computer_name, &creds);
+					     r->in.computer_name, &state->creds);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		return nt_status;
 	}
@@ -1055,7 +1096,14 @@ static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call,
 	if (dce_call->conn->auth_state.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
 		return NT_STATUS_ACCESS_DENIED;
 	}
-	return dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, r, creds);
+
+	nt_status = dcesrv_netr_LogonSamLogon_base_call(state);
+
+	if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
+		return nt_status;
+	}
+
+	return nt_status;
 }
 
 /*
@@ -1065,44 +1113,57 @@ static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call,
 static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
 					    struct netr_LogonSamLogonWithFlags *r)
 {
+	struct dcesrv_netr_LogonSamLogon_base_state *state;
 	NTSTATUS nt_status;
-	struct netlogon_creds_CredentialState *creds;
-	struct netr_LogonSamLogonEx r2;
 
-	struct netr_Authenticator *return_authenticator;
+	*r->out.authoritative = 1;
 
-	ZERO_STRUCT(r2);
+	state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonSamLogon_base_state);
+	if (state == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	state->dce_call = dce_call;
+	state->mem_ctx = mem_ctx;
 
-	r2.in.server_name	= r->in.server_name;
-	r2.in.computer_name	= r->in.computer_name;
-	r2.in.logon_level	= r->in.logon_level;
-	r2.in.logon		= r->in.logon;
-	r2.in.validation_level	= r->in.validation_level;
-	r2.in.flags		= r->in.flags;
-	r2.out.validation	= r->out.validation;
-	r2.out.authoritative	= r->out.authoritative;
-	r2.out.flags		= r->out.flags;
+	state->r.in.server_name      = r->in.server_name;
+	state->r.in.computer_name    = r->in.computer_name;
+	state->r.in.logon_level      = r->in.logon_level;
+	state->r.in.logon            = r->in.logon;
+	state->r.in.validation_level = r->in.validation_level;
+	state->r.in.flags            = r->in.flags;
+	state->r.out.validation      = r->out.validation;
+	state->r.out.authoritative   = r->out.authoritative;
+	state->r.out.flags           = r->out.flags;
 
-	*r->out.authoritative = 1;
+	state->_r.lslwf = r;
 
-	nt_status = dcesrv_netr_LogonSamLogon_check(&r2);
+	nt_status = dcesrv_netr_LogonSamLogon_check(&state->r);
 	if (!NT_STATUS_IS_OK(nt_status)) {
 		return nt_status;
 	}
 
-	return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
-	NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
+	r->out.return_authenticator = talloc_zero(mem_ctx,
+						  struct netr_Authenticator);
+	if (r->out.return_authenticator == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
 
 	nt_status = dcesrv_netr_creds_server_step_check(dce_call,
 							mem_ctx,
 							r->in.computer_name,
-							r->in.credential, return_authenticator,
-							&creds);
-	NT_STATUS_NOT_OK_RETURN(nt_status);
+							r->in.credential,
+							r->out.return_authenticator,
+							&state->creds);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		return nt_status;
+	}
 
-	nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
+	nt_status = dcesrv_netr_LogonSamLogon_base_call(state);
 
-	r->out.return_authenticator	= return_authenticator;
+	if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
+		return nt_status;
+	}
 
 	return nt_status;
 }
@@ -1113,29 +1174,59 @@ static NTSTATUS dcesrv_netr_LogonSamLogonWithFlags(struct dcesrv_call_state *dce
 static NTSTATUS dcesrv_netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
 				   struct netr_LogonSamLogon *r)
 {
-	struct netr_LogonSamLogonWithFlags r2;
-	uint32_t flags = 0;
-	NTSTATUS status;
+	struct dcesrv_netr_LogonSamLogon_base_state *state;
+	NTSTATUS nt_status;
 
-	ZERO_STRUCT(r2);
+	*r->out.authoritative = 1;
 
-	r2.in.server_name = r->in.server_name;
-	r2.in.computer_name = r->in.computer_name;
-	r2.in.credential  = r->in.credential;
-	r2.in.return_authenticator = r->in.return_authenticator;
-	r2.in.logon_level = r->in.logon_level;
-	r2.in.logon = r->in.logon;
-	r2.in.validation_level = r->in.validation_level;
-	r2.in.flags = &flags;
-	r2.out.validation = r->out.validation;
-	r2.out.authoritative = r->out.authoritative;
-	r2.out.flags = &flags;
-
-	status = dcesrv_netr_LogonSamLogonWithFlags(dce_call, mem_ctx, &r2);
+	state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonSamLogon_base_state);
+	if (state == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
 
-	r->out.return_authenticator = r2.out.return_authenticator;
+	state->dce_call = dce_call;
+	state->mem_ctx = mem_ctx;
 
-	return status;
+	state->r.in.server_name      = r->in.server_name;
+	state->r.in.computer_name    = r->in.computer_name;
+	state->r.in.logon_level      = r->in.logon_level;
+	state->r.in.logon            = r->in.logon;
+	state->r.in.validation_level = r->in.validation_level;
+	state->r.in.flags            = &state->_ignored_flags;
+	state->r.out.validation      = r->out.validation;
+	state->r.out.authoritative   = r->out.authoritative;
+	state->r.out.flags           = &state->_ignored_flags;
+
+	state->_r.lsl = r;
+
+	nt_status = dcesrv_netr_LogonSamLogon_check(&state->r);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		return nt_status;
+	}
+
+	r->out.return_authenticator = talloc_zero(mem_ctx,
+						  struct netr_Authenticator);
+	if (r->out.return_authenticator == NULL) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	nt_status = dcesrv_netr_creds_server_step_check(dce_call,
+							mem_ctx,
+							r->in.computer_name,
+							r->in.credential,
+							r->out.return_authenticator,
+							&state->creds);
+	if (!NT_STATUS_IS_OK(nt_status)) {
+		return nt_status;
+	}
+
+	nt_status = dcesrv_netr_LogonSamLogon_base_call(state);
+
+	if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) {
+		return nt_status;
+	}
+
+	return nt_status;
 }
 
 
-- 
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/20170321/73950321/signature.sig>


More information about the samba-technical mailing list