summaryrefslogtreecommitdiff
path: root/source3/winbindd/winbindd_group.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2008-06-26 14:02:39 -0700
committerJeremy Allison <jra@samba.org>2008-06-26 14:02:39 -0700
commit120c09b125f656d6d03b979560f3ef6652217691 (patch)
treec7f5db8defa25852acacb3e1eebaaba4b2bc3e04 /source3/winbindd/winbindd_group.c
parent23cafd02d3222b910dbc30a7eab20ebdcc81ab33 (diff)
downloadsamba-120c09b125f656d6d03b979560f3ef6652217691.tar.gz
samba-120c09b125f656d6d03b979560f3ef6652217691.tar.bz2
samba-120c09b125f656d6d03b979560f3ef6652217691.zip
From Steve Danneman @ Isilon.
Attached is the companion patch to (037b9689d9042a398cb91e4628a82fcdfa913c21), which made handling of WINBINDD_LIST_GROUPS asynchronous. Because most all of the list_groups code was reusable, I abstracted it, and implemented both list_groups and list_users on top of it. On my large test domain a "wbinfo -u" call went from 70 seconds to 30 seconds with this patch. Plus, the parent process is no longer blocked from receiving new requests during that time. Steven Danneman | Software Development Engineer Isilon Systems P +1-206-315-7500 F +1-206-315-7501 www.isilon.com (This used to be commit 5188f2861137ff06d5399561d55d7d00c3a08644)
Diffstat (limited to 'source3/winbindd/winbindd_group.c')
-rw-r--r--source3/winbindd/winbindd_group.c104
1 files changed, 1 insertions, 103 deletions
diff --git a/source3/winbindd/winbindd_group.c b/source3/winbindd/winbindd_group.c
index d10609a83f..f9f946f3f3 100644
--- a/source3/winbindd/winbindd_group.c
+++ b/source3/winbindd/winbindd_group.c
@@ -1339,112 +1339,10 @@ void winbindd_getgrent(struct winbindd_cli_state *state)
request_error(state);
}
-struct listgroups_state {
- TALLOC_CTX *mem_ctx;
- struct winbindd_cli_state *cli_state;
- unsigned int domain_count;
- char *extra_data;
- unsigned int extra_data_len;
-};
-
-static void listgroups_recv(void *private_data, bool success, fstring dom_name,
- char *extra_data);
-
/* List domain groups without mapping to unix ids */
void winbindd_list_groups(struct winbindd_cli_state *state)
{
- struct winbindd_domain *domain;
- const char *which_domain;
- struct listgroups_state *groups_state;
-
- DEBUG(3, ("[%5lu]: list groups\n", (unsigned long)state->pid));
-
- /* Ensure null termination */
- state->request.domain_name[sizeof(state->request.domain_name)-1]='\0';
- which_domain = state->request.domain_name;
-
- /* Initialize listgroups_state */
- groups_state = TALLOC_P(state->mem_ctx, struct listgroups_state);
- if (groups_state == NULL) {
- DEBUG(0, ("talloc failed\n"));
- request_error(state);
- return;
- }
-
- groups_state->mem_ctx = state->mem_ctx;
- groups_state->cli_state = state;
- groups_state->domain_count = 0;
- groups_state->extra_data = NULL;
- groups_state->extra_data_len = 0;
-
- /* Must count the full list of expected domains before we request data
- * from any of them. Otherwise it's possible for a connection to the
- * first domain to fail, call listgroups_recv(), and return to the
- * client without checking any other domains. */
- for (domain = domain_list(); domain; domain = domain->next) {
- /* if we have a domain name restricting the request and this
- one in the list doesn't match, then just bypass the remainder
- of the loop */
- if ( *which_domain && !strequal(which_domain, domain->name) )
- continue;
-
- groups_state->domain_count++;
- }
-
- /* Make sure we're enumerating at least one domain */
- if (!groups_state->domain_count) {
- request_ok(state);
- return;
- }
-
- /* Enumerate list of trusted domains and request group list from each */
- for (domain = domain_list(); domain; domain = domain->next) {
- if ( *which_domain && !strequal(which_domain, domain->name) )
- continue;
-
- winbindd_listgroups_async(state->mem_ctx, domain,
- listgroups_recv, groups_state);
- }
-}
-
-static void listgroups_recv(void *private_data, bool success, fstring dom_name,
- char *extra_data)
-{
- /* extra_data comes to us as a '\0' terminated string of comma
- separated groups */
- struct listgroups_state *state = talloc_get_type_abort(
- private_data, struct listgroups_state);
-
- /* Append groups from one domain onto the whole list */
- if (extra_data) {
- DEBUG(5, ("listgroups_recv: %s returned groups.\n", dom_name));
- if (!state->extra_data)
- state->extra_data = talloc_asprintf(state->mem_ctx,
- "%s", extra_data);
- else
- state->extra_data = talloc_asprintf_append_buffer(
- state->extra_data,
- ",%s", extra_data);
- /* Add one for the '\0' and each additional ',' */
- state->extra_data_len += strlen(extra_data) + 1;
- }
- else {
- DEBUG(5, ("listgroups_recv: %s returned no groups.\n",
- dom_name));
- }
-
- if (--state->domain_count)
- /* Still waiting for some child domains to return */
- return;
-
- /* Return list of all groups to the client */
- if (state->extra_data) {
- state->cli_state->response.extra_data.data =
- SMB_STRDUP(state->extra_data);
- state->cli_state->response.length += state->extra_data_len;
- }
-
- request_ok(state->cli_state);
+ winbindd_list_ent(state, LIST_GROUPS);
}
/* Get user supplementary groups. This is much quicker than trying to