[PATCHES] refactor wb_grent and wb_pwent a bit

Michael Adam obnox at samba.org
Tue Mar 10 17:17:46 MDT 2015


Attached find a patchset that refactors the code for
nss user and group enumeration a bit to remove some
code duplication.

Thanks for review / comments.

Michael
-------------- next part --------------
From 44dae326f6efdeda7176be75a8ed42cc0c7873d4 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Mon, 19 Jan 2015 08:14:44 +0100
Subject: [PATCH 01/14] s3:util_sid: donate an empty line.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/lib/util_sid_passdb.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/source3/lib/util_sid_passdb.c b/source3/lib/util_sid_passdb.c
index b56837e..0ff64cc 100644
--- a/source3/lib/util_sid_passdb.c
+++ b/source3/lib/util_sid_passdb.c
@@ -62,6 +62,7 @@ bool sid_check_object_is_for_passdb(const struct dom_sid *sid)
 
 	return false;
 }
+
 /**
  * check whether this is an object- or domain-sid that should
  * be treated by the passdb, e.g. for id-mapping.
-- 
2.1.0


From d478884c1a42ceee634481434a635c290cc6d767 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 20 Jan 2015 08:39:58 +0100
Subject: [PATCH 02/14] s3:winbind:util: fix comment typo

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/winbindd_util.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index 8dab36e..b1b9326 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -34,7 +34,7 @@
 extern struct winbindd_methods cache_methods;
 
 /**
- * @file winbindd_util.cq
+ * @file winbindd_util.c
  *
  * Winbind daemon for NT domain authentication nss module.
  **/
-- 
2.1.0


From 0c7dae9d8afc135305cdea8677bd70ce40a6e4e8 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Sat, 17 Jan 2015 23:34:37 +0100
Subject: [PATCH 03/14] s3:winbind:pwent: use wb_next_find_domain()

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/wb_next_pwent.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/source3/winbindd/wb_next_pwent.c b/source3/winbindd/wb_next_pwent.c
index ade74e3..77e4c96 100644
--- a/source3/winbindd/wb_next_pwent.c
+++ b/source3/winbindd/wb_next_pwent.c
@@ -111,13 +111,7 @@ static void wb_next_pwent_fetch_done(struct tevent_req *subreq)
 	}
 
 	if (state->gstate->num_users == 0) {
-		state->gstate->domain = state->gstate->domain->next;
-
-		if ((state->gstate->domain != NULL)
-		    && sid_check_is_our_sam(&state->gstate->domain->sid)) {
-			state->gstate->domain = state->gstate->domain->next;
-		}
-
+		state->gstate->domain = wb_next_find_domain(state->gstate->domain);
 		if (state->gstate->domain == NULL) {
 			tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
 			return;
-- 
2.1.0


From e04fab2cfd3ab1a894c79b29f2091ab064bd207c Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 20 Jan 2015 09:41:31 +0100
Subject: [PATCH 04/14] s3:winbind:pwent: rename wb_next_find_domain to
 wb_next_domain

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/wb_next_pwent.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/source3/winbindd/wb_next_pwent.c b/source3/winbindd/wb_next_pwent.c
index 77e4c96..0de7fd1 100644
--- a/source3/winbindd/wb_next_pwent.c
+++ b/source3/winbindd/wb_next_pwent.c
@@ -31,7 +31,7 @@ struct wb_next_pwent_state {
 static void wb_next_pwent_fetch_done(struct tevent_req *subreq);
 static void wb_next_pwent_fill_done(struct tevent_req *subreq);
 
-static struct winbindd_domain *wb_next_find_domain(struct winbindd_domain *domain)
+static struct winbindd_domain *wb_next_domain(struct winbindd_domain *domain)
 {
 	if (domain == NULL) {
 		domain = domain_list();
@@ -65,7 +65,7 @@ struct tevent_req *wb_next_pwent_send(TALLOC_CTX *mem_ctx,
 	if (state->gstate->next_user >= state->gstate->num_users) {
 		TALLOC_FREE(state->gstate->users);
 
-		state->gstate->domain = wb_next_find_domain(state->gstate->domain);
+		state->gstate->domain = wb_next_domain(state->gstate->domain);
 		if (state->gstate->domain == NULL) {
 			tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
 			return tevent_req_post(req, ev);
@@ -111,7 +111,7 @@ static void wb_next_pwent_fetch_done(struct tevent_req *subreq)
 	}
 
 	if (state->gstate->num_users == 0) {
-		state->gstate->domain = wb_next_find_domain(state->gstate->domain);
+		state->gstate->domain = wb_next_domain(state->gstate->domain);
 		if (state->gstate->domain == NULL) {
 			tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
 			return;
@@ -157,7 +157,7 @@ static void wb_next_pwent_fill_done(struct tevent_req *subreq)
 		if (state->gstate->next_user >= state->gstate->num_users) {
 			TALLOC_FREE(state->gstate->users);
 
-			state->gstate->domain = wb_next_find_domain(state->gstate->domain);
+			state->gstate->domain = wb_next_domain(state->gstate->domain);
 			if (state->gstate->domain == NULL) {
 				tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
 				return;
-- 
2.1.0


From b1f19a36b96f2bd05bb0e97533b4d11c358dc443 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 20 Jan 2015 10:07:59 +0100
Subject: [PATCH 05/14] s3:winbind:pwent: move wb_next_domain() to
 winbindd_util.c for re-use

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/wb_next_pwent.c  | 15 ---------------
 source3/winbindd/winbindd_proto.h |  1 +
 source3/winbindd/winbindd_util.c  | 19 +++++++++++++++++++
 3 files changed, 20 insertions(+), 15 deletions(-)

diff --git a/source3/winbindd/wb_next_pwent.c b/source3/winbindd/wb_next_pwent.c
index 0de7fd1..9bd2a09 100644
--- a/source3/winbindd/wb_next_pwent.c
+++ b/source3/winbindd/wb_next_pwent.c
@@ -31,21 +31,6 @@ struct wb_next_pwent_state {
 static void wb_next_pwent_fetch_done(struct tevent_req *subreq);
 static void wb_next_pwent_fill_done(struct tevent_req *subreq);
 
-static struct winbindd_domain *wb_next_domain(struct winbindd_domain *domain)
-{
-	if (domain == NULL) {
-		domain = domain_list();
-	} else {
-		domain = domain->next;
-	}
-
-	if ((domain != NULL)
-	    && sid_check_is_our_sam(&domain->sid)) {
-		domain = domain->next;
-	}
-	return domain;
-}
-
 struct tevent_req *wb_next_pwent_send(TALLOC_CTX *mem_ctx,
 				      struct tevent_context *ev,
 				      struct getpwent_state *gstate,
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index e0b7aad..ba4ef0a 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -404,6 +404,7 @@ NTSTATUS winbind_dual_SamLogon(struct winbindd_domain *domain,
 /* The following definitions come from winbindd/winbindd_util.c  */
 
 struct winbindd_domain *domain_list(void);
+struct winbindd_domain *wb_next_domain(struct winbindd_domain *domain);
 bool domain_is_forest_root(const struct winbindd_domain *domain);
 void rescan_trusted_domains(struct tevent_context *ev, struct tevent_timer *te,
 			    struct timeval now, void *private_data);
diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c
index b1b9326..a0d42a5 100644
--- a/source3/winbindd/winbindd_util.c
+++ b/source3/winbindd/winbindd_util.c
@@ -73,6 +73,25 @@ static void free_domain_list(void)
 	}
 }
 
+/**
+ * Iterator for winbindd's domain list.
+ * To be used (e.g.) in tevent based loops.
+ */
+struct winbindd_domain *wb_next_domain(struct winbindd_domain *domain)
+{
+	if (domain == NULL) {
+		domain = domain_list();
+	} else {
+		domain = domain->next;
+	}
+
+	if ((domain != NULL)
+	    && sid_check_is_our_sam(&domain->sid)) {
+		domain = domain->next;
+	}
+	return domain;
+}
+
 static bool is_internal_domain(const struct dom_sid *sid)
 {
 	if (sid == NULL)
-- 
2.1.0


From fadd1df255e043a3b72fb87facfbf42fc9a5808b Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 20 Jan 2015 11:06:51 +0100
Subject: [PATCH 06/14] s3:winbind:pwent: move resetting next_user up.

This does not change the behaviour and makes it more evident
that we have anothe code duplication here:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (state->gstate->num_users == 0) {
	...
}

subreq = wb_fill_pwent_send(...)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

is for the current setting of variables equivalent
to the block found elsewhere:

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if (state->gstate->next_user >= state->gstate->num_users) {
	...
}

subreq = wb_fill_pwent_send(...)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

because both num_users is set to a non-negative
value and num_users starts at 0 and is incremented up to
num_users.

The code duplication will be factored out next.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/wb_next_pwent.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/source3/winbindd/wb_next_pwent.c b/source3/winbindd/wb_next_pwent.c
index 9bd2a09..a6159de 100644
--- a/source3/winbindd/wb_next_pwent.c
+++ b/source3/winbindd/wb_next_pwent.c
@@ -95,6 +95,8 @@ static void wb_next_pwent_fetch_done(struct tevent_req *subreq)
 		state->gstate->num_users = 0;
 	}
 
+	state->gstate->next_user = 0;
+
 	if (state->gstate->num_users == 0) {
 		state->gstate->domain = wb_next_domain(state->gstate->domain);
 		if (state->gstate->domain == NULL) {
@@ -110,8 +112,6 @@ static void wb_next_pwent_fetch_done(struct tevent_req *subreq)
 		return;
 	}
 
-	state->gstate->next_user = 0;
-
 	subreq = wb_fill_pwent_send(
 		state, state->ev,
 		&state->gstate->users[state->gstate->next_user],
-- 
2.1.0


From 17f6062211ebbb92f426284bd0bf543aa9c3293b Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Mon, 19 Jan 2015 13:51:39 +0100
Subject: [PATCH 07/14] s3:winbind:pwent: refactor duplication into
 wb_next_pwent_send_do()

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/wb_next_pwent.c | 109 ++++++++++++++-------------------------
 1 file changed, 38 insertions(+), 71 deletions(-)

diff --git a/source3/winbindd/wb_next_pwent.c b/source3/winbindd/wb_next_pwent.c
index a6159de..af5e8d9 100644
--- a/source3/winbindd/wb_next_pwent.c
+++ b/source3/winbindd/wb_next_pwent.c
@@ -31,21 +31,10 @@ struct wb_next_pwent_state {
 static void wb_next_pwent_fetch_done(struct tevent_req *subreq);
 static void wb_next_pwent_fill_done(struct tevent_req *subreq);
 
-struct tevent_req *wb_next_pwent_send(TALLOC_CTX *mem_ctx,
-				      struct tevent_context *ev,
-				      struct getpwent_state *gstate,
-				      struct winbindd_pw *pw)
+static void wb_next_pwent_send_do(struct tevent_req *req,
+				  struct wb_next_pwent_state *state)
 {
-	struct tevent_req *req, *subreq;
-	struct wb_next_pwent_state *state;
-
-	req = tevent_req_create(mem_ctx, &state, struct wb_next_pwent_state);
-	if (req == NULL) {
-		return NULL;
-	}
-	state->ev = ev;
-	state->gstate = gstate;
-	state->pw = pw;
+	struct tevent_req *subreq;
 
 	if (state->gstate->next_user >= state->gstate->num_users) {
 		TALLOC_FREE(state->gstate->users);
@@ -53,25 +42,50 @@ struct tevent_req *wb_next_pwent_send(TALLOC_CTX *mem_ctx,
 		state->gstate->domain = wb_next_domain(state->gstate->domain);
 		if (state->gstate->domain == NULL) {
 			tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
-			return tevent_req_post(req, ev);
+			return;
 		}
+
 		subreq = wb_query_user_list_send(state, state->ev,
 						 state->gstate->domain);
 		if (tevent_req_nomem(subreq, req)) {
-			return tevent_req_post(req, ev);
+			return;
 		}
+
 		tevent_req_set_callback(subreq, wb_next_pwent_fetch_done, req);
-		return req;
+		return;
 	}
 
-	subreq = wb_fill_pwent_send(
-		state, state->ev,
-		&state->gstate->users[state->gstate->next_user],
-		state->pw);
+	subreq = wb_fill_pwent_send(state, state->ev,
+				&state->gstate->users[state->gstate->next_user],
+				state->pw);
 	if (tevent_req_nomem(subreq, req)) {
-		return tevent_req_post(req, ev);
+		return;
 	}
+
 	tevent_req_set_callback(subreq, wb_next_pwent_fill_done, req);
+}
+
+struct tevent_req *wb_next_pwent_send(TALLOC_CTX *mem_ctx,
+				      struct tevent_context *ev,
+				      struct getpwent_state *gstate,
+				      struct winbindd_pw *pw)
+{
+	struct tevent_req *req;
+	struct wb_next_pwent_state *state;
+
+	req = tevent_req_create(mem_ctx, &state, struct wb_next_pwent_state);
+	if (req == NULL) {
+		return NULL;
+	}
+	state->ev = ev;
+	state->gstate = gstate;
+	state->pw = pw;
+
+	wb_next_pwent_send_do(req, state);
+	if (!tevent_req_is_in_progress(req)) {
+		return tevent_req_post(req, ev);
+	}
+
 	return req;
 }
 
@@ -97,29 +111,7 @@ static void wb_next_pwent_fetch_done(struct tevent_req *subreq)
 
 	state->gstate->next_user = 0;
 
-	if (state->gstate->num_users == 0) {
-		state->gstate->domain = wb_next_domain(state->gstate->domain);
-		if (state->gstate->domain == NULL) {
-			tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
-			return;
-		}
-		subreq = wb_query_user_list_send(state, state->ev,
-						 state->gstate->domain);
-		if (tevent_req_nomem(subreq, req)) {
-			return;
-		}
-		tevent_req_set_callback(subreq, wb_next_pwent_fetch_done, req);
-		return;
-	}
-
-	subreq = wb_fill_pwent_send(
-		state, state->ev,
-		&state->gstate->users[state->gstate->next_user],
-		state->pw);
-	if (tevent_req_nomem(subreq, req)) {
-		return;
-	}
-	tevent_req_set_callback(subreq, wb_next_pwent_fill_done, req);
+	wb_next_pwent_send_do(req, state);
 }
 
 static void wb_next_pwent_fill_done(struct tevent_req *subreq)
@@ -139,32 +131,7 @@ static void wb_next_pwent_fill_done(struct tevent_req *subreq)
 	if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
 		state->gstate->next_user += 1;
 
-		if (state->gstate->next_user >= state->gstate->num_users) {
-			TALLOC_FREE(state->gstate->users);
-
-			state->gstate->domain = wb_next_domain(state->gstate->domain);
-			if (state->gstate->domain == NULL) {
-				tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
-				return;
-			}
-
-			subreq = wb_query_user_list_send(state, state->ev,
-					state->gstate->domain);
-			if (tevent_req_nomem(subreq, req)) {
-				return;
-			}
-			tevent_req_set_callback(subreq, wb_next_pwent_fetch_done, req);
-			return;
-		}
-
-		subreq = wb_fill_pwent_send(state,
-					    state->ev,
-					    &state->gstate->users[state->gstate->next_user],
-					    state->pw);
-		if (tevent_req_nomem(subreq, req)) {
-			return;
-		}
-		tevent_req_set_callback(subreq, wb_next_pwent_fill_done, req);
+		wb_next_pwent_send_do(req, state);
 
 		return;
 	} else if (tevent_req_nterror(req, status)) {
-- 
2.1.0


From a36086df165bd54b09c2c3aeb58e1946d4f085f4 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Sun, 25 Jan 2015 12:20:35 +0100
Subject: [PATCH 08/14] s3:winbind:grent: fix a debug message.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/wb_next_grent.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/source3/winbindd/wb_next_grent.c b/source3/winbindd/wb_next_grent.c
index 58e161d..02f929a 100644
--- a/source3/winbindd/wb_next_grent.c
+++ b/source3/winbindd/wb_next_grent.c
@@ -103,14 +103,14 @@ static void wb_next_grent_fetch_done(struct tevent_req *subreq)
 	TALLOC_FREE(subreq);
 	if (tevent_req_nterror(req, status)) {
 		/* Ignore errors here, just log it */
-		DEBUG(10, ("query_user_list for domain %s returned %s\n",
+		DEBUG(10, ("QueryGroupList for domain %s returned %s\n",
 			   state->gstate->domain->name,
 			   nt_errstr(status)));
 		return;
 	}
 	if (!NT_STATUS_IS_OK(result)) {
 		/* Ignore errors here, just log it */
-		DEBUG(10, ("query_user_list for domain %s returned %s/%s\n",
+		DEBUG(10, ("QueryGroupList for domain %s returned %s/%s\n",
 			   state->gstate->domain->name,
 			   nt_errstr(status), nt_errstr(result)));
 		tevent_req_nterror(req, result);
-- 
2.1.0


From cf902571df9c8e5e291e1f3ad1cf8e9b081c7420 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 20 Jan 2015 10:25:37 +0100
Subject: [PATCH 09/14] s3:winbind:grent: use wb_next_domain() in
 wb_next_grent.c

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/wb_next_grent.c | 32 +++-----------------------------
 1 file changed, 3 insertions(+), 29 deletions(-)

diff --git a/source3/winbindd/wb_next_grent.c b/source3/winbindd/wb_next_grent.c
index 02f929a..108be35 100644
--- a/source3/winbindd/wb_next_grent.c
+++ b/source3/winbindd/wb_next_grent.c
@@ -55,17 +55,7 @@ struct tevent_req *wb_next_grent_send(TALLOC_CTX *mem_ctx,
 	if (state->gstate->next_group >= state->gstate->num_groups) {
 		TALLOC_FREE(state->gstate->groups);
 
-		if (state->gstate->domain == NULL) {
-			state->gstate->domain = domain_list();
-		} else {
-			state->gstate->domain = state->gstate->domain->next;
-		}
-
-		if ((state->gstate->domain != NULL)
-		    && sid_check_is_our_sam(&state->gstate->domain->sid)) {
-			state->gstate->domain = state->gstate->domain->next;
-		}
-
+		state->gstate->domain = wb_next_domain(state->gstate->domain);
 		if (state->gstate->domain == NULL) {
 			tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
 			return tevent_req_post(req, ev);
@@ -122,13 +112,7 @@ static void wb_next_grent_fetch_done(struct tevent_req *subreq)
 		state->gstate, &state->next_groups.principals);
 
 	if (state->gstate->num_groups == 0) {
-		state->gstate->domain = state->gstate->domain->next;
-
-		if ((state->gstate->domain != NULL)
-		    && sid_check_is_our_sam(&state->gstate->domain->sid)) {
-			state->gstate->domain = state->gstate->domain->next;
-		}
-
+		state->gstate->domain = wb_next_domain(state->gstate->domain);
 		if (state->gstate->domain == NULL) {
 			tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
 			return;
@@ -175,18 +159,8 @@ static void wb_next_grent_getgrsid_done(struct tevent_req *subreq)
 		if (state->gstate->next_group >= state->gstate->num_groups) {
 			TALLOC_FREE(state->gstate->groups);
 
-			if (state->gstate->domain == NULL) {
-				state->gstate->domain = domain_list();
-			} else {
-				state->gstate->domain = state->gstate->domain->next;
-			}
-
-			if ((state->gstate->domain != NULL) &&
-			    sid_check_is_our_sam(&state->gstate->domain->sid))
-			{
-				state->gstate->domain = state->gstate->domain->next;
-			}
 
+			state->gstate->domain = wb_next_domain(state->gstate->domain);
 			if (state->gstate->domain == NULL) {
 				tevent_req_nterror(req,
 						   NT_STATUS_NO_MORE_ENTRIES);
-- 
2.1.0


From 52e9dcb896e3eb1ef4757a668f264ee0bc6dd350 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Tue, 20 Jan 2015 12:25:29 +0100
Subject: [PATCH 10/14] s3:winbind:grent: move resetting next_group up.

This is to make it more obvious that this is a case
of code duplication.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/wb_next_grent.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/source3/winbindd/wb_next_grent.c b/source3/winbindd/wb_next_grent.c
index 108be35..d5cff18 100644
--- a/source3/winbindd/wb_next_grent.c
+++ b/source3/winbindd/wb_next_grent.c
@@ -110,6 +110,7 @@ static void wb_next_grent_fetch_done(struct tevent_req *subreq)
 	state->gstate->num_groups = state->next_groups.num_principals;
 	state->gstate->groups = talloc_move(
 		state->gstate, &state->next_groups.principals);
+	state->gstate->next_group = 0;
 
 	if (state->gstate->num_groups == 0) {
 		state->gstate->domain = wb_next_domain(state->gstate->domain);
@@ -127,8 +128,6 @@ static void wb_next_grent_fetch_done(struct tevent_req *subreq)
 		return;
 	}
 
-	state->gstate->next_group = 0;
-
 	subreq = wb_getgrsid_send(
 		state, state->ev,
 		&state->gstate->groups[state->gstate->next_group].sid,
-- 
2.1.0


From 97c2809561e2970df7aa194e72f98271c3580389 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Wed, 21 Jan 2015 12:32:04 +0100
Subject: [PATCH 11/14] s3:winbind:grent: refactor duplication into
 wb_next_grent_send_do()

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/wb_next_grent.c | 115 +++++++++++++--------------------------
 1 file changed, 37 insertions(+), 78 deletions(-)

diff --git a/source3/winbindd/wb_next_grent.c b/source3/winbindd/wb_next_grent.c
index d5cff18..4161425 100644
--- a/source3/winbindd/wb_next_grent.c
+++ b/source3/winbindd/wb_next_grent.c
@@ -34,23 +34,10 @@ struct wb_next_grent_state {
 static void wb_next_grent_fetch_done(struct tevent_req *subreq);
 static void wb_next_grent_getgrsid_done(struct tevent_req *subreq);
 
-struct tevent_req *wb_next_grent_send(TALLOC_CTX *mem_ctx,
-				      struct tevent_context *ev,
-				      int max_nesting,
-				      struct getgrent_state *gstate,
-				      struct winbindd_gr *gr)
+static void wb_next_grent_send_do(struct tevent_req *req,
+				  struct wb_next_grent_state *state)
 {
-	struct tevent_req *req, *subreq;
-	struct wb_next_grent_state *state;
-
-	req = tevent_req_create(mem_ctx, &state, struct wb_next_grent_state);
-	if (req == NULL) {
-		return NULL;
-	}
-	state->ev = ev;
-	state->gstate = gstate;
-	state->gr = gr;
-	state->max_nesting = max_nesting;
+	struct tevent_req *subreq;
 
 	if (state->gstate->next_group >= state->gstate->num_groups) {
 		TALLOC_FREE(state->gstate->groups);
@@ -58,16 +45,18 @@ struct tevent_req *wb_next_grent_send(TALLOC_CTX *mem_ctx,
 		state->gstate->domain = wb_next_domain(state->gstate->domain);
 		if (state->gstate->domain == NULL) {
 			tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
-			return tevent_req_post(req, ev);
+			return;
 		}
+
 		subreq = dcerpc_wbint_QueryGroupList_send(
-			state, state->ev, dom_child_handle(state->gstate->domain),
+			state, state->ev,
+			dom_child_handle(state->gstate->domain),
 			&state->next_groups);
 		if (tevent_req_nomem(subreq, req)) {
-			return tevent_req_post(req, ev);
+			return;
 		}
 		tevent_req_set_callback(subreq, wb_next_grent_fetch_done, req);
-		return req;
+		return;
 	}
 
 	subreq = wb_getgrsid_send(
@@ -75,9 +64,34 @@ struct tevent_req *wb_next_grent_send(TALLOC_CTX *mem_ctx,
 		&state->gstate->groups[state->gstate->next_group].sid,
 		state->max_nesting);
 	if (tevent_req_nomem(subreq, req)) {
-		return tevent_req_post(req, ev);
+		return;
 	}
 	tevent_req_set_callback(subreq, wb_next_grent_getgrsid_done, req);
+}
+
+struct tevent_req *wb_next_grent_send(TALLOC_CTX *mem_ctx,
+				      struct tevent_context *ev,
+				      int max_nesting,
+				      struct getgrent_state *gstate,
+				      struct winbindd_gr *gr)
+{
+	struct tevent_req *req;
+	struct wb_next_grent_state *state;
+
+	req = tevent_req_create(mem_ctx, &state, struct wb_next_grent_state);
+	if (req == NULL) {
+		return NULL;
+	}
+	state->ev = ev;
+	state->gstate = gstate;
+	state->gr = gr;
+	state->max_nesting = max_nesting;
+
+	wb_next_grent_send_do(req, state);
+	if (!tevent_req_is_in_progress(req)) {
+		return tevent_req_post(req, ev);
+	}
+
 	return req;
 }
 
@@ -112,31 +126,7 @@ static void wb_next_grent_fetch_done(struct tevent_req *subreq)
 		state->gstate, &state->next_groups.principals);
 	state->gstate->next_group = 0;
 
-	if (state->gstate->num_groups == 0) {
-		state->gstate->domain = wb_next_domain(state->gstate->domain);
-		if (state->gstate->domain == NULL) {
-			tevent_req_nterror(req, NT_STATUS_NO_MORE_ENTRIES);
-			return;
-		}
-		subreq = dcerpc_wbint_QueryGroupList_send(
-			state, state->ev, dom_child_handle(state->gstate->domain),
-			&state->next_groups);
-		if (tevent_req_nomem(subreq, req)) {
-			return;
-		}
-		tevent_req_set_callback(subreq, wb_next_grent_fetch_done, req);
-		return;
-	}
-
-	subreq = wb_getgrsid_send(
-		state, state->ev,
-		&state->gstate->groups[state->gstate->next_group].sid,
-		state->max_nesting);
-	if (tevent_req_nomem(subreq, req)) {
-		return;
-	}
-	tevent_req_set_callback(subreq, wb_next_grent_getgrsid_done, req);
-	return;
+	wb_next_grent_send_do(req, state);
 }
 
 static void wb_next_grent_getgrsid_done(struct tevent_req *subreq)
@@ -155,39 +145,8 @@ static void wb_next_grent_getgrsid_done(struct tevent_req *subreq)
 	if (NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
 		state->gstate->next_group += 1;
 
-		if (state->gstate->next_group >= state->gstate->num_groups) {
-			TALLOC_FREE(state->gstate->groups);
-
+		wb_next_grent_send_do(req, state);
 
-			state->gstate->domain = wb_next_domain(state->gstate->domain);
-			if (state->gstate->domain == NULL) {
-				tevent_req_nterror(req,
-						   NT_STATUS_NO_MORE_ENTRIES);
-				return;
-			}
-
-			subreq = dcerpc_wbint_QueryGroupList_send(
-				state, state->ev,
-				dom_child_handle(state->gstate->domain),
-				&state->next_groups);
-			if (tevent_req_nomem(subreq, req)) {
-				return;
-			}
-
-			tevent_req_set_callback(subreq,
-						wb_next_grent_fetch_done, req);
-			return;
-		}
-
-		subreq = wb_getgrsid_send(
-			state, state->ev,
-			&state->gstate->groups[state->gstate->next_group].sid,
-			state->max_nesting);
-		if (tevent_req_nomem(subreq, req)) {
-			return;
-		}
-		tevent_req_set_callback(subreq, wb_next_grent_getgrsid_done,
-					req);
 		return;
 	} else if (tevent_req_nterror(req, status)) {
 		return;
-- 
2.1.0


From d3f9aa1794bc8004fd7adc19a6f68c08d63602ee Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Fri, 23 Jan 2015 14:06:40 +0100
Subject: [PATCH 12/14] s3:winbind: add wb_query_group_list module - async
 query group list

Modeled after wb_query_user_list.c

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/wb_query_group_list.c | 93 ++++++++++++++++++++++++++++++++++
 source3/winbindd/winbindd_proto.h      |  8 +++
 source3/wscript_build                  |  1 +
 3 files changed, 102 insertions(+)
 create mode 100644 source3/winbindd/wb_query_group_list.c

diff --git a/source3/winbindd/wb_query_group_list.c b/source3/winbindd/wb_query_group_list.c
new file mode 100644
index 0000000..703d331
--- /dev/null
+++ b/source3/winbindd/wb_query_group_list.c
@@ -0,0 +1,93 @@
+/*
+   Unix SMB/CIFS implementation.
+   async query_group_list
+   Copyright (C) Volker Lendecke 2009
+   Copyright (C) Michael Adam 2015
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "winbindd.h"
+#include "librpc/gen_ndr/ndr_winbind_c.h"
+
+
+struct wb_query_group_list_state {
+	struct wbint_Principals groups;
+};
+
+static void wb_query_group_list_done(struct tevent_req *subreq);
+
+struct tevent_req *wb_query_group_list_send(TALLOC_CTX *mem_ctx,
+					    struct tevent_context *ev,
+					    struct winbindd_domain *domain)
+{
+	struct tevent_req *req, *subreq;
+	struct wb_query_group_list_state *state;
+
+	req = tevent_req_create(mem_ctx, &state,
+				struct wb_query_group_list_state);
+	if (req == NULL) {
+		return NULL;
+	}
+
+	subreq = dcerpc_wbint_QueryGroupList_send(state, ev,
+						  dom_child_handle(domain),
+						  &state->groups);
+	if (tevent_req_nomem(subreq, req)) {
+		return tevent_req_post(req, ev);
+	}
+
+	tevent_req_set_callback(subreq, wb_query_group_list_done, req);
+	return req;
+}
+
+static void wb_query_group_list_done(struct tevent_req *subreq)
+{
+	struct tevent_req *req = tevent_req_callback_data(
+		subreq, struct tevent_req);
+	struct wb_query_group_list_state *state = tevent_req_data(
+		req, struct wb_query_group_list_state);
+	NTSTATUS status, result;
+
+	status = dcerpc_wbint_QueryGroupList_recv(subreq, state, &result);
+	TALLOC_FREE(subreq);
+	if (any_nt_status_not_ok(status, result, &status)) {
+		tevent_req_nterror(req, status);
+		return;
+	}
+
+	DEBUG(10, ("dcerpc_wbint_QueryGroupList returned %d groups\n",
+		   state->groups.num_principals));
+
+	tevent_req_done(req);
+}
+
+NTSTATUS wb_query_group_list_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+				  int *num_groups,
+				  struct wbint_Principal **groups)
+{
+	struct wb_query_group_list_state *state = tevent_req_data(
+		req, struct wb_query_group_list_state);
+	NTSTATUS status;
+
+	if (tevent_req_is_nterror(req, &status)) {
+		return status;
+	}
+
+	*num_groups = state->groups.num_principals;
+	*groups = talloc_move(mem_ctx, &state->groups.principals);
+
+	return NT_STATUS_OK;
+}
diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h
index ba4ef0a..10650af 100644
--- a/source3/winbindd/winbindd_proto.h
+++ b/source3/winbindd/winbindd_proto.h
@@ -715,6 +715,14 @@ NTSTATUS wb_query_user_list_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
 				 int *num_users,
 				 struct wbint_userinfo **users);
 
+struct tevent_req *wb_query_group_list_send(TALLOC_CTX *mem_ctx,
+					    struct tevent_context *ev,
+					    struct winbindd_domain *domain);
+NTSTATUS wb_query_group_list_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
+				  int *num_users,
+				  struct wbint_Principal **groups);
+
+
 struct tevent_req *wb_fill_pwent_send(TALLOC_CTX *mem_ctx,
 				      struct tevent_context *ev,
 				      struct wbint_userinfo *info,
diff --git a/source3/wscript_build b/source3/wscript_build
index 24cf06c..654e0dd 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -931,6 +931,7 @@ bld.SAMBA3_BINARY('winbindd/winbindd',
                  winbindd/wb_group_members.c
                  winbindd/wb_getgrsid.c
                  winbindd/wb_query_user_list.c
+                 winbindd/wb_query_group_list.c
                  winbindd/wb_fill_pwent.c
                  winbindd/wb_next_pwent.c
                  winbindd/wb_next_grent.c
-- 
2.1.0


From 725b37b330c4757eaef35d1575afac73cd7e2d6e Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Fri, 23 Jan 2015 14:23:16 +0100
Subject: [PATCH 13/14] s3:winbind:grent: convert wb_next_grent to use
 wb_query_group_list.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/wb_next_grent.c | 32 ++++++++++----------------------
 1 file changed, 10 insertions(+), 22 deletions(-)

diff --git a/source3/winbindd/wb_next_grent.c b/source3/winbindd/wb_next_grent.c
index 4161425..db6f924 100644
--- a/source3/winbindd/wb_next_grent.c
+++ b/source3/winbindd/wb_next_grent.c
@@ -26,7 +26,6 @@ struct wb_next_grent_state {
 	struct tevent_context *ev;
 	int max_nesting;
 	struct getgrent_state *gstate;
-	struct wbint_Principals next_groups;
 	struct winbindd_gr *gr;
 	struct talloc_dict *members;
 };
@@ -48,10 +47,8 @@ static void wb_next_grent_send_do(struct tevent_req *req,
 			return;
 		}
 
-		subreq = dcerpc_wbint_QueryGroupList_send(
-			state, state->ev,
-			dom_child_handle(state->gstate->domain),
-			&state->next_groups);
+		subreq = wb_query_group_list_send(state, state->ev,
+						  state->gstate->domain);
 		if (tevent_req_nomem(subreq, req)) {
 			return;
 		}
@@ -101,29 +98,20 @@ static void wb_next_grent_fetch_done(struct tevent_req *subreq)
 		subreq, struct tevent_req);
 	struct wb_next_grent_state *state = tevent_req_data(
 		req, struct wb_next_grent_state);
-	NTSTATUS status, result;
+	NTSTATUS status;
 
-	status = dcerpc_wbint_QueryGroupList_recv(subreq, state, &result);
+	status = wb_query_group_list_recv(subreq, state->gstate,
+					  &state->gstate->num_groups,
+					  &state->gstate->groups);
 	TALLOC_FREE(subreq);
-	if (tevent_req_nterror(req, status)) {
-		/* Ignore errors here, just log it */
-		DEBUG(10, ("QueryGroupList for domain %s returned %s\n",
-			   state->gstate->domain->name,
-			   nt_errstr(status)));
-		return;
-	}
-	if (!NT_STATUS_IS_OK(result)) {
+	if (!NT_STATUS_IS_OK(status)) {
 		/* Ignore errors here, just log it */
-		DEBUG(10, ("QueryGroupList for domain %s returned %s/%s\n",
-			   state->gstate->domain->name,
-			   nt_errstr(status), nt_errstr(result)));
-		tevent_req_nterror(req, result);
+		DEBUG(10, ("query_group_list for domain %s returned %s\n",
+			   state->gstate->domain->name, nt_errstr(status)));
+		tevent_req_nterror(req, status);
 		return;
 	}
 
-	state->gstate->num_groups = state->next_groups.num_principals;
-	state->gstate->groups = talloc_move(
-		state->gstate, &state->next_groups.principals);
 	state->gstate->next_group = 0;
 
 	wb_next_grent_send_do(req, state);
-- 
2.1.0


From 962c2b38b7c4f2da8dd49bb15a257ce5228def37 Mon Sep 17 00:00:00 2001
From: Michael Adam <obnox at samba.org>
Date: Sun, 25 Jan 2015 12:16:50 +0100
Subject: [PATCH 14/14] s3:winbind:grent: don't stop when querying one domain
 fails.

Just continue with the next domain.

Signed-off-by: Michael Adam <obnox at samba.org>
---
 source3/winbindd/wb_next_grent.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/source3/winbindd/wb_next_grent.c b/source3/winbindd/wb_next_grent.c
index db6f924..fd925b6 100644
--- a/source3/winbindd/wb_next_grent.c
+++ b/source3/winbindd/wb_next_grent.c
@@ -108,8 +108,7 @@ static void wb_next_grent_fetch_done(struct tevent_req *subreq)
 		/* Ignore errors here, just log it */
 		DEBUG(10, ("query_group_list for domain %s returned %s\n",
 			   state->gstate->domain->name, nt_errstr(status)));
-		tevent_req_nterror(req, status);
-		return;
+		state->gstate->num_groups = 0;
 	}
 
 	state->gstate->next_group = 0;
-- 
2.1.0

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20150311/646f15bc/attachment.pgp>


More information about the samba-technical mailing list