Faster winbind against passdb

Andrew Bartlett abartlet at samba.org
Fri Mar 23 02:13:13 UTC 2018


On Thu, 2018-03-22 at 07:55 +0100, Stefan Metzmacher wrote:
> 
> The winbindd patches should also discussed separately,
> maybe Ralph has some comments there, because he recently fixed
> some retry logic.

G'Day Ralph,

Attached is just the winbindd changes Metze mentions above. 

They make winbindd much faster on the AD DC as we do not constantly re-
open the pipe to LSA and SAMR over the internal ncacn_np transport. 

It is on top of my for-autobuild-2018-03-23 branch in catalyst's repo,
which I have submitted to autobuild with the rest of the un-pushed
changes.

Please review!

Thanks,

Andrew Bartlett

-- 
Andrew Bartlett
https://samba.org/~abartlet/
Authentication Developer, Samba Team         https://samba.org
Samba Development and Support, Catalyst IT   
https://catalyst.net.nz/services/samba



-------------- next part --------------
From b022111cd5add2974724657e1275dda0f89c6f9e Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Wed, 21 Mar 2018 20:43:10 +1300
Subject: [PATCH 1/4] winbindd: Add a cache of the samr and lsa handles for the
 passdb domain

This domain is very close, in AD DC configurations over a internal ncacn_np pipe
and otherwise in the same process via C linking.  It is however very expensive
to re-create the binding handle per SID->name lookup, so keep a cache.

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 source3/winbindd/winbindd_samr.c | 272 +++++++++++++++++++++++----------------
 1 file changed, 162 insertions(+), 110 deletions(-)

diff --git a/source3/winbindd/winbindd_samr.c b/source3/winbindd/winbindd_samr.c
index aedb77bdee9..68064d725a2 100644
--- a/source3/winbindd/winbindd_samr.c
+++ b/source3/winbindd/winbindd_samr.c
@@ -40,6 +40,21 @@
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_WINBIND
 
+/*
+ * The other end of this won't go away easily, so we can trust it
+ * 
+ * It is either a long-lived process with the same lifetime as
+ * winbindd or a part of this process
+ */
+struct winbind_internal_pipe_private
+{
+	struct rpc_pipe_client *samr_pipe;
+	struct policy_handle samr_domain_hnd;
+	struct rpc_pipe_client *lsa_pipe;
+	struct policy_handle lsa_hnd;
+};
+
+
 NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
 				 struct winbindd_domain *domain,
 				 struct rpc_pipe_client **samr_pipe,
@@ -101,6 +116,70 @@ NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
 	return status;
 }
 
+	
+static NTSTATUS open_cached_internal_pipe_conn(struct winbindd_domain *domain,
+					       struct rpc_pipe_client **samr_pipe,
+					       struct policy_handle *samr_domain_hnd,
+					       struct rpc_pipe_client **lsa_pipe,
+					       struct policy_handle *lsa_hnd)
+{
+	struct winbind_internal_pipe_private *private_data;
+	
+	if (domain->private_data == NULL) {
+		TALLOC_CTX *frame = talloc_stackframe();
+		NTSTATUS status;
+		
+		private_data = talloc(frame,
+				      struct winbind_internal_pipe_private);
+		
+		status = open_internal_samr_conn(private_data,
+						 domain,
+						 &private_data->samr_pipe,
+						 &private_data->samr_domain_hnd);
+		
+		if (!NT_STATUS_IS_OK(status)) {
+			TALLOC_FREE(frame);
+			return status;
+		}
+		
+		status = open_internal_lsa_conn(private_data,
+						&private_data->lsa_pipe,
+						&private_data->lsa_hnd);
+		
+		if (!NT_STATUS_IS_OK(status)) {
+			TALLOC_FREE(frame);
+			return status;
+		}
+		
+		domain->private_data = talloc_steal(domain, private_data);
+	
+		TALLOC_FREE(frame);
+	
+	} else {
+		private_data =
+			talloc_get_type_abort(domain->private_data,
+					      struct winbind_internal_pipe_private);
+	}
+		
+	if (samr_domain_hnd) {
+		*samr_domain_hnd = private_data->samr_domain_hnd;
+	}
+	
+	if (samr_pipe) {
+		*samr_pipe = private_data->samr_pipe;
+	}
+	
+	if (lsa_hnd) {
+		*lsa_hnd = private_data->lsa_hnd;
+	}
+	
+	if (lsa_pipe) {
+		*lsa_pipe = private_data->lsa_pipe;
+	}
+	
+	return NT_STATUS_OK;
+}
+
 /*********************************************************************
  SAM specific functions.
 *********************************************************************/
@@ -116,8 +195,7 @@ static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
 	struct wb_acct_info *info = NULL;
 	uint32_t num_info = 0;
 	TALLOC_CTX *tmp_ctx;
-	NTSTATUS status, result;
-	struct dcerpc_binding_handle *b = NULL;
+	NTSTATUS status;
 
 	DEBUG(3,("sam_enum_dom_groups\n"));
 
@@ -130,20 +208,24 @@ static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+	status = open_cached_internal_pipe_conn(domain,
+						&samr_pipe,
+						&dom_pol,
+						NULL,
+						NULL);
 	if (!NT_STATUS_IS_OK(status)) {
-		goto error;
+		TALLOC_FREE(tmp_ctx);
+		return status;
 	}
 
-	b = samr_pipe->binding_handle;
-
 	status = rpc_enum_dom_groups(tmp_ctx,
 				     samr_pipe,
 				     &dom_pol,
 				     &num_info,
 				     &info);
 	if (!NT_STATUS_IS_OK(status)) {
-		goto error;
+		TALLOC_FREE(tmp_ctx);
+		return status;
 	}
 
 	if (pnum_info) {
@@ -154,10 +236,6 @@ static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
 		*pinfo = talloc_move(mem_ctx, &info);
 	}
 
-error:
-	if (b && is_valid_policy_hnd(&dom_pol)) {
-		dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
-	}
 	TALLOC_FREE(tmp_ctx);
 	return status;
 }
@@ -171,8 +249,7 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
 	struct policy_handle dom_pol = { 0 };
 	uint32_t *rids = NULL;
 	TALLOC_CTX *tmp_ctx;
-	NTSTATUS status, result;
-	struct dcerpc_binding_handle *b = NULL;
+	NTSTATUS status;
 
 	DEBUG(3,("samr_query_user_list\n"));
 
@@ -181,13 +258,15 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+	status = open_cached_internal_pipe_conn(domain,
+						&samr_pipe,
+						&dom_pol,
+						NULL,
+						NULL);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
 
-	b = samr_pipe->binding_handle;
-
 	status = rpc_query_user_list(tmp_ctx,
 				     samr_pipe,
 				     &dom_pol,
@@ -202,10 +281,6 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
 	}
 
 done:
-	if (b && is_valid_policy_hnd(&dom_pol)) {
-		dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
-	}
-
 	TALLOC_FREE(rids);
 	TALLOC_FREE(tmp_ctx);
 	return status;
@@ -221,8 +296,7 @@ static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
 	struct netr_DomainTrust *trusts = NULL;
 	uint32_t num_trusts = 0;
 	TALLOC_CTX *tmp_ctx;
-	NTSTATUS status, result;
-	struct dcerpc_binding_handle *b = NULL;
+	NTSTATUS status;
 
 	DEBUG(3,("samr: trusted domains\n"));
 
@@ -235,13 +309,15 @@ static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
+	status = open_cached_internal_pipe_conn(domain,
+						NULL,
+						NULL,
+						&lsa_pipe,
+						&lsa_policy);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
 
-	b = lsa_pipe->binding_handle;
-
 	status = rpc_trusted_domains(tmp_ctx,
 				     lsa_pipe,
 				     &lsa_policy,
@@ -257,10 +333,6 @@ static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
 	}
 
 done:
-	if (b && is_valid_policy_hnd(&lsa_policy)) {
-		dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
-	}
-
 	TALLOC_FREE(tmp_ctx);
 	return status;
 }
@@ -284,9 +356,8 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
 	uint32_t *name_types = NULL;
 
 	TALLOC_CTX *tmp_ctx;
-	NTSTATUS status, result;
-	struct dcerpc_binding_handle *b = NULL;
-
+	NTSTATUS status;
+	
 	DEBUG(3,("sam_lookup_groupmem\n"));
 
 	/* Paranoia check */
@@ -304,13 +375,15 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+	status = open_cached_internal_pipe_conn(domain,
+						&samr_pipe,
+						&dom_pol,
+						NULL,
+						NULL);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
 
-	b = samr_pipe->binding_handle;
-
 	status = rpc_lookup_groupmem(tmp_ctx,
 				     samr_pipe,
 				     &dom_pol,
@@ -340,10 +413,6 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
 	}
 
 done:
-	if (b && is_valid_policy_hnd(&dom_pol)) {
-		dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
-	}
-
 	TALLOC_FREE(tmp_ctx);
 	return status;
 }
@@ -398,8 +467,7 @@ static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
 	struct wb_acct_info *info = NULL;
 	uint32_t num_info = 0;
 	TALLOC_CTX *tmp_ctx;
-	NTSTATUS status, result;
-	struct dcerpc_binding_handle *b = NULL;
+	NTSTATUS status;
 
 	DEBUG(3,("samr: enum local groups\n"));
 
@@ -412,13 +480,15 @@ static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+	status = open_cached_internal_pipe_conn(domain,
+						&samr_pipe,
+						&dom_pol,
+						NULL,
+						NULL);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
 
-	b = samr_pipe->binding_handle;
-
 	status = rpc_enum_local_groups(mem_ctx,
 				       samr_pipe,
 				       &dom_pol,
@@ -437,10 +507,6 @@ static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
 	}
 
 done:
-	if (b && is_valid_policy_hnd(&dom_pol)) {
-		dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
-	}
-
 	TALLOC_FREE(tmp_ctx);
 	return status;
 }
@@ -459,8 +525,7 @@ static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
 	struct dom_sid sid;
 	enum lsa_SidType type;
 	TALLOC_CTX *tmp_ctx;
-	NTSTATUS status, result;
-	struct dcerpc_binding_handle *b = NULL;
+	NTSTATUS status;
 
 	DEBUG(3,("sam_name_to_sid\n"));
 
@@ -469,13 +534,15 @@ static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
+	status = open_cached_internal_pipe_conn(domain,
+						NULL,
+						NULL,
+						&lsa_pipe,
+						&lsa_policy);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
 
-	b = lsa_pipe->binding_handle;
-
 	status = rpc_name_to_sid(tmp_ctx,
 				 lsa_pipe,
 				 &lsa_policy,
@@ -496,10 +563,6 @@ static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
 	}
 
 done:
-	if (b && is_valid_policy_hnd(&lsa_policy)) {
-		dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
-	}
-
 	TALLOC_FREE(tmp_ctx);
 	return status;
 }
@@ -518,8 +581,7 @@ static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
 	char *name = NULL;
 	enum lsa_SidType type;
 	TALLOC_CTX *tmp_ctx;
-	NTSTATUS status, result;
-	struct dcerpc_binding_handle *b = NULL;
+	NTSTATUS status;
 
 	DEBUG(3,("sam_sid_to_name\n"));
 
@@ -543,13 +605,15 @@ static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
+	status = open_cached_internal_pipe_conn(domain,
+						NULL,
+						NULL,
+						&lsa_pipe,
+						&lsa_policy);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
 
-	b = lsa_pipe->binding_handle;
-
 	status = rpc_sid_to_name(tmp_ctx,
 				 lsa_pipe,
 				 &lsa_policy,
@@ -572,9 +636,6 @@ static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
 	}
 
 done:
-	if (b && is_valid_policy_hnd(&lsa_policy)) {
-		dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
-	}
 
 	TALLOC_FREE(tmp_ctx);
 	return status;
@@ -595,8 +656,7 @@ static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
 	char *domain_name = NULL;
 	char **names = NULL;
 	TALLOC_CTX *tmp_ctx;
-	NTSTATUS status, result;
-	struct dcerpc_binding_handle *b = NULL;
+	NTSTATUS status;
 
 	DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
 
@@ -616,13 +676,15 @@ static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = open_internal_lsa_conn(tmp_ctx, &lsa_pipe, &lsa_policy);
+	status = open_cached_internal_pipe_conn(domain,
+						NULL,
+						NULL,
+						&lsa_pipe,
+						&lsa_policy);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
 
-	b = lsa_pipe->binding_handle;
-
 	status = rpc_rids_to_names(tmp_ctx,
 				   lsa_pipe,
 				   &lsa_policy,
@@ -650,10 +712,6 @@ static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
 	}
 
 done:
-	if (b && is_valid_policy_hnd(&lsa_policy)) {
-		dcerpc_lsa_Close(b, mem_ctx, &lsa_policy, &result);
-	}
-
 	TALLOC_FREE(tmp_ctx);
 	return status;
 }
@@ -676,13 +734,17 @@ static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+	status = open_cached_internal_pipe_conn(domain,
+						&samr_pipe,
+						&dom_pol,
+						NULL,
+						NULL);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto error;
 	}
 
 	b = samr_pipe->binding_handle;
-
+	
 	status = dcerpc_samr_QueryDomainInfo(b,
 					     mem_ctx,
 					     &dom_pol,
@@ -700,10 +762,6 @@ static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
 	*lockout_policy = info->info12;
 
 error:
-	if (b && is_valid_policy_hnd(&dom_pol)) {
-		dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
-	}
-
 	TALLOC_FREE(tmp_ctx);
 	return status;
 }
@@ -726,7 +784,11 @@ static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+	status = open_cached_internal_pipe_conn(domain,
+						&samr_pipe,
+						&dom_pol,
+						NULL,
+						NULL);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto error;
 	}
@@ -750,10 +812,6 @@ static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
 	*passwd_policy = info->info1;
 
 error:
-	if (b && is_valid_policy_hnd(&dom_pol)) {
-		dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
-	}
-
 	TALLOC_FREE(tmp_ctx);
 	return status;
 }
@@ -770,8 +828,7 @@ static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
 	struct dom_sid *user_grpsids = NULL;
 	uint32_t num_groups = 0;
 	TALLOC_CTX *tmp_ctx;
-	NTSTATUS status, result;
-	struct dcerpc_binding_handle *b = NULL;
+	NTSTATUS status;
 
 	DEBUG(3,("sam_lookup_usergroups\n"));
 
@@ -786,13 +843,15 @@ static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+	status = open_cached_internal_pipe_conn(domain,
+						&samr_pipe,
+						&dom_pol,
+						NULL,
+						NULL);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
 
-	b = samr_pipe->binding_handle;
-
 	status = rpc_lookup_usergroups(tmp_ctx,
 				       samr_pipe,
 				       &dom_pol,
@@ -813,9 +872,6 @@ static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
 	}
 
 done:
-	if (b && is_valid_policy_hnd(&dom_pol)) {
-		dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
-	}
 
 	TALLOC_FREE(tmp_ctx);
 	return status;
@@ -833,8 +889,7 @@ static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
 	uint32_t num_aliases = 0;
 	uint32_t *alias_rids = NULL;
 	TALLOC_CTX *tmp_ctx;
-	NTSTATUS status, result;
-	struct dcerpc_binding_handle *b = NULL;
+	NTSTATUS status;
 
 	DEBUG(3,("sam_lookup_useraliases\n"));
 
@@ -847,13 +902,15 @@ static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+	status = open_cached_internal_pipe_conn(domain,
+						&samr_pipe,
+						&dom_pol,
+						NULL,
+						NULL);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
 
-	b = samr_pipe->binding_handle;
-
 	status = rpc_lookup_useraliases(tmp_ctx,
 					samr_pipe,
 					&dom_pol,
@@ -874,9 +931,6 @@ static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
 	}
 
 done:
-	if (b && is_valid_policy_hnd(&dom_pol)) {
-		dcerpc_samr_Close(b, mem_ctx, &dom_pol, &result);
-	}
 
 	TALLOC_FREE(tmp_ctx);
 	return status;
@@ -890,8 +944,7 @@ static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
 	struct policy_handle dom_pol = { 0 };
 	uint32_t seq = DOM_SEQUENCE_NONE;
 	TALLOC_CTX *tmp_ctx;
-	NTSTATUS status, result;
-	struct dcerpc_binding_handle *b = NULL;
+	NTSTATUS status;
 
 	DEBUG(3,("samr: sequence number\n"));
 
@@ -904,13 +957,15 @@ static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
 		return NT_STATUS_NO_MEMORY;
 	}
 
-	status = open_internal_samr_conn(tmp_ctx, domain, &samr_pipe, &dom_pol);
+	status = open_cached_internal_pipe_conn(domain,
+						&samr_pipe,
+						&dom_pol,
+						NULL,
+						NULL);
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
 
-	b = samr_pipe->binding_handle;
-
 	status = rpc_sequence_number(tmp_ctx,
 				     samr_pipe,
 				     &dom_pol,
@@ -923,11 +978,8 @@ static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
 	if (pseq) {
 		*pseq = seq;
 	}
-done:
-	if (b && is_valid_policy_hnd(&dom_pol)) {
-		dcerpc_samr_Close(b, tmp_ctx, &dom_pol, &result);
-	}
 
+done:
 	TALLOC_FREE(tmp_ctx);
 	return status;
 }
-- 
2.11.0


From 9d2faba242192b49d1ef906b98ab40aec6591a3a Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Wed, 21 Mar 2018 20:44:31 +1300
Subject: [PATCH 2/4] winbindd: Do re-connect if the RPC call fails in the
 passdb case

This is very, very unlikely but possible as in the AD case the RPC server is in
another process that may eventually be able to restart.

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 source3/winbindd/winbindd_samr.c | 309 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 308 insertions(+), 1 deletion(-)

diff --git a/source3/winbindd/winbindd_samr.c b/source3/winbindd/winbindd_samr.c
index 68064d725a2..70e07fa30a6 100644
--- a/source3/winbindd/winbindd_samr.c
+++ b/source3/winbindd/winbindd_samr.c
@@ -28,6 +28,7 @@
 #include "winbindd_rpc.h"
 #include "lib/util_unixsids.h"
 #include "rpc_client/rpc_client.h"
+#include "rpc_client/cli_pipe.h"
 #include "../librpc/gen_ndr/ndr_samr_c.h"
 #include "rpc_client/cli_samr.h"
 #include "../librpc/gen_ndr/ndr_lsa_c.h"
@@ -223,6 +224,29 @@ static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
 				     &dom_pol,
 				     &num_info,
 				     &info);
+	/*
+	 * Very unlikely, but before checking the result, 
+	 * if we disconnected try again
+	 */
+	if (!rpccli_is_connected(samr_pipe)) {
+		TALLOC_FREE(domain->private_data);
+		status = open_cached_internal_pipe_conn(domain,
+							&samr_pipe,
+							&dom_pol,
+							NULL,
+							NULL);
+		if (!NT_STATUS_IS_OK(status)) {
+			TALLOC_FREE(tmp_ctx);
+			return status;
+		}
+		
+		status = rpc_enum_dom_groups(tmp_ctx,
+					     samr_pipe,
+					     &dom_pol,
+					     &num_info,
+					     &info);
+	}
+	
 	if (!NT_STATUS_IS_OK(status)) {
 		TALLOC_FREE(tmp_ctx);
 		return status;
@@ -272,6 +296,28 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
 				     &dom_pol,
 				     &domain->sid,
 				     &rids);
+	/*
+	 * Very unlikely, but before checking the result, 
+	 * if we disconnected try again
+	 */
+	if (!rpccli_is_connected(samr_pipe)) {
+		TALLOC_FREE(domain->private_data);
+		status = open_cached_internal_pipe_conn(domain,
+							&samr_pipe,
+							&dom_pol,
+							NULL,
+							NULL);
+		if (!NT_STATUS_IS_OK(status)) {
+			goto done;
+		}
+		
+		status = rpc_query_user_list(tmp_ctx,
+					     samr_pipe,
+					     &dom_pol,
+					     &domain->sid,
+					     &rids);
+	}
+	
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
@@ -323,6 +369,27 @@ static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
 				     &lsa_policy,
 				     &num_trusts,
 				     &trusts);
+	/*
+	 * Very unlikely, but before checking the result, 
+	 * if we disconnected try again
+	 */
+	if (!rpccli_is_connected(lsa_pipe)) {
+		TALLOC_FREE(domain->private_data);
+		status = open_cached_internal_pipe_conn(domain,
+							NULL,
+							NULL,
+							&lsa_pipe,
+							&lsa_policy);
+		if (!NT_STATUS_IS_OK(status)) {
+			goto done;
+		}
+		
+		status = rpc_trusted_domains(tmp_ctx,
+				     lsa_pipe,
+				     &lsa_policy,
+				     &num_trusts,
+				     &trusts);
+	}
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
@@ -396,6 +463,34 @@ static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
 				     &names,
 				     &name_types);
 
+	/*
+	 * Very unlikely, but before checking the result, 
+	 * if we disconnected try again
+	 */
+	if (!rpccli_is_connected(samr_pipe)) {
+		TALLOC_FREE(domain->private_data);
+		status = open_cached_internal_pipe_conn(domain,
+							&samr_pipe,
+							&dom_pol,
+							NULL,
+							NULL);
+		if (!NT_STATUS_IS_OK(status)) {
+			goto done;
+		}
+		
+		status = rpc_lookup_groupmem(tmp_ctx,
+					     samr_pipe,
+					     &dom_pol,
+					     domain->name,
+					     &domain->sid,
+					     group_sid,
+					     type,
+					     &num_names,
+					     &sid_mem,
+					     &names,
+					     &name_types);
+	}
+
 	if (pnum_names) {
 		*pnum_names = num_names;
 	}
@@ -494,6 +589,28 @@ static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
 				       &dom_pol,
 				       &num_info,
 				       &info);
+	/*
+	 * Very unlikely, but before checking the result, 
+	 * if we disconnected try again
+	 */
+	if (!rpccli_is_connected(samr_pipe)) {
+		TALLOC_FREE(domain->private_data);
+		status = open_cached_internal_pipe_conn(domain,
+							&samr_pipe,
+							&dom_pol,
+							NULL,
+							NULL);
+		if (!NT_STATUS_IS_OK(status)) {
+			goto done;
+		}
+		
+		status = rpc_enum_local_groups(mem_ctx,
+					       samr_pipe,
+					       &dom_pol,
+					       &num_info,
+					       &info);
+	}
+	
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
@@ -551,6 +668,30 @@ static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
 				 flags,
 				 &sid,
 				 &type);
+	/*
+	 * Very unlikely, but before checking the result, 
+	 * if we disconnected try again
+	 */
+	if (!rpccli_is_connected(lsa_pipe)) {
+		TALLOC_FREE(domain->private_data);
+		status = open_cached_internal_pipe_conn(domain,
+							NULL,
+							NULL,
+							&lsa_pipe,
+							&lsa_policy);
+		if (!NT_STATUS_IS_OK(status)) {
+			goto done;
+		}
+		
+		status = rpc_name_to_sid(tmp_ctx,
+					 lsa_pipe,
+					 &lsa_policy,
+					 domain_name,
+					 name,
+					 flags,
+					 &sid,
+					 &type);
+	}
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
@@ -622,7 +763,32 @@ static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
 				 &domain_name,
 				 &name,
 				 &type);
-
+	
+	/*
+	 * Very unlikely, but before checking the result, 
+	 * if we disconnected try again
+	 */
+	if (!rpccli_is_connected(lsa_pipe)) {
+		TALLOC_FREE(domain->private_data);
+		status = open_cached_internal_pipe_conn(domain,
+							NULL,
+							NULL,
+							&lsa_pipe,
+							&lsa_policy);
+		if (!NT_STATUS_IS_OK(status)) {
+			goto done;
+		}
+		
+		status = rpc_sid_to_name(tmp_ctx,
+					 lsa_pipe,
+					 &lsa_policy,
+					 domain,
+					 sid,
+					 &domain_name,
+					 &name,
+					 &type);
+	}
+	
 	if (ptype) {
 		*ptype = type;
 	}
@@ -695,6 +861,32 @@ static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
 				   &domain_name,
 				   &names,
 				   &types);
+	/*
+	 * Very unlikely, but before checking the result, 
+	 * if we disconnected try again
+	 */
+	if (!rpccli_is_connected(lsa_pipe)) {
+		TALLOC_FREE(domain->private_data);
+		status = open_cached_internal_pipe_conn(domain,
+							NULL,
+							NULL,
+							&lsa_pipe,
+							&lsa_policy);
+		if (!NT_STATUS_IS_OK(status)) {
+			goto done;
+		}
+		
+		status = rpc_rids_to_names(tmp_ctx,
+					   lsa_pipe,
+					   &lsa_policy,
+					   domain,
+					   domain_sid,
+					   rids,
+					   num_rids,
+					   &domain_name,
+					   &names,
+					   &types);
+	}
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
@@ -751,6 +943,28 @@ static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
 					     DomainLockoutInformation,
 					     &info,
 					     &result);
+	/*
+	 * Very unlikely, but before checking the result, 
+	 * if we disconnected try again
+	 */
+	if (!rpccli_is_connected(samr_pipe)) {
+		TALLOC_FREE(domain->private_data);
+		status = open_cached_internal_pipe_conn(domain,
+							&samr_pipe,
+							&dom_pol,
+							NULL,
+							NULL);
+		if (!NT_STATUS_IS_OK(status)) {
+			goto error;
+		}
+		
+		status = dcerpc_samr_QueryDomainInfo(b,
+						     mem_ctx,
+						     &dom_pol,
+						     DomainLockoutInformation,
+						     &info,
+						     &result);
+	}
 	if (!NT_STATUS_IS_OK(status)) {
 		goto error;
 	}
@@ -801,6 +1015,29 @@ static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
 					     DomainPasswordInformation,
 					     &info,
 					     &result);
+	/*
+	 * Very unlikely, but before checking the result, 
+	 * if we disconnected try again
+	 */
+	if (!rpccli_is_connected(samr_pipe)) {
+		TALLOC_FREE(domain->private_data);
+		status = open_cached_internal_pipe_conn(domain,
+							&samr_pipe,
+							&dom_pol,
+							NULL,
+							NULL);
+		if (!NT_STATUS_IS_OK(status)) {
+			goto error;
+		}
+		
+		status = dcerpc_samr_QueryDomainInfo(b,
+						     mem_ctx,
+						     &dom_pol,
+						     DomainPasswordInformation,
+						     &info,
+						     &result);
+	}
+	
 	if (!NT_STATUS_IS_OK(status)) {
 		goto error;
 	}
@@ -859,6 +1096,30 @@ static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
 				       user_sid,
 				       &num_groups,
 				       &user_grpsids);
+	/*
+	 * Very unlikely, but before checking the result, 
+	 * if we disconnected try again
+	 */
+	if (!rpccli_is_connected(samr_pipe)) {
+		TALLOC_FREE(domain->private_data);
+		status = open_cached_internal_pipe_conn(domain,
+							&samr_pipe,
+							&dom_pol,
+							NULL,
+							NULL);
+		if (!NT_STATUS_IS_OK(status)) {
+			goto done;
+		}
+		
+		status = rpc_lookup_usergroups(tmp_ctx,
+					       samr_pipe,
+					       &dom_pol,
+					       &domain->sid,
+					       user_sid,
+					       &num_groups,
+					       &user_grpsids);
+	}
+	
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
@@ -918,6 +1179,30 @@ static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
 					sids,
 					&num_aliases,
 					&alias_rids);
+	/*
+	 * Very unlikely, but before checking the result, 
+	 * if we disconnected try again
+	 */
+	if (!rpccli_is_connected(samr_pipe)) {
+		TALLOC_FREE(domain->private_data);
+		status = open_cached_internal_pipe_conn(domain,
+							&samr_pipe,
+							&dom_pol,
+							NULL,
+							NULL);
+		if (!NT_STATUS_IS_OK(status)) {
+			goto done;
+		}
+		
+		status = rpc_lookup_useraliases(tmp_ctx,
+						samr_pipe,
+						&dom_pol,
+						num_sids,
+						sids,
+						&num_aliases,
+						&alias_rids);
+	}
+	
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
@@ -971,6 +1256,28 @@ static NTSTATUS sam_sequence_number(struct winbindd_domain *domain,
 				     &dom_pol,
 				     domain->name,
 				     &seq);
+	/*
+	 * Very unlikely, but before checking the result, 
+	 * if we disconnected try again
+	 */
+	if (!rpccli_is_connected(samr_pipe)) {
+		TALLOC_FREE(domain->private_data);
+		status = open_cached_internal_pipe_conn(domain,
+							&samr_pipe,
+							&dom_pol,
+							NULL,
+							NULL);
+		if (!NT_STATUS_IS_OK(status)) {
+			goto done;
+		}
+		
+		status = rpc_sequence_number(tmp_ctx,
+					     samr_pipe,
+					     &dom_pol,
+					     domain->name,
+					     &seq);
+	}
+	
 	if (!NT_STATUS_IS_OK(status)) {
 		goto done;
 	}
-- 
2.11.0


From 557c1e8bed080a9b58b8aee11407130b13b45150 Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Wed, 21 Mar 2018 21:23:13 +1300
Subject: [PATCH 3/4] winbindd: Use talloc_zero_array for consistency with
 other winbindd_domain allocators

The other allocator for this structure uses talloc_zero()

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 source3/winbindd/wb_seqnums.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/source3/winbindd/wb_seqnums.c b/source3/winbindd/wb_seqnums.c
index 2a4cdc930e8..3c9af01e40f 100644
--- a/source3/winbindd/wb_seqnums.c
+++ b/source3/winbindd/wb_seqnums.c
@@ -56,8 +56,8 @@ struct tevent_req *wb_seqnums_send(TALLOC_CTX *mem_ctx,
 
 	state->subreqs = talloc_array(state, struct tevent_req *,
 				      state->num_domains);
-	state->domains = talloc_array(state, struct winbindd_domain *,
-				      state->num_domains);
+	state->domains = talloc_zero_array(state, struct winbindd_domain *,
+					   state->num_domains);
 	state->stati = talloc_array(state, NTSTATUS, state->num_domains);
 	state->seqnums = talloc_array(state, uint32_t, state->num_domains);
 
-- 
2.11.0


From c7a54cf121700c1aef9b34de5cf339970131d52a Mon Sep 17 00:00:00 2001
From: Andrew Bartlett <abartlet at samba.org>
Date: Fri, 23 Mar 2018 14:39:35 +1300
Subject: [PATCH 4/4] travis-ci: Run ad-dc tests in travis-ci now they run in
 less than 50mins

Key to making this possible was the fix to winbindd to not re-open sam.ldb over
and over again.

Signed-off-by: Andrew Bartlett <abartlet at samba.org>
---
 .travis.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.travis.yml b/.travis.yml
index f5e4dfc322e..e9b6a6b2938 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -17,6 +17,7 @@ env:
   - TASK=samba-systemkrb5
   - TASK=samba-nt4
   - TASK=samba-fileserver
+  - TASK=samba-ad-dc
   - TASK=samba-ad-dc-2
   - TASK=ldb
   - TASK=tdb
-- 
2.11.0

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 862 bytes
Desc: This is a digitally signed message part
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20180323/ba0ec29b/signature.sig>


More information about the samba-technical mailing list