From d033e533001ba255293e5fac639390d507ce3f3a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 11 Dec 2001 01:04:13 +0000 Subject: removed the start_ndx parameter from group enumeration I tried testing this by lowering the buffer size in cli_samr_enum_dom_groups() but that didn't work - I think this needs more looking into (This used to be commit 34328e30315e4b42087d0ee11ed0c3fb715bc250) --- source3/nsswitch/winbindd.h | 5 +- source3/nsswitch/winbindd_ads.c | 8 +-- source3/nsswitch/winbindd_cache.c | 8 +-- source3/nsswitch/winbindd_group.c | 110 +++++++++++++++----------------------- source3/nsswitch/winbindd_rpc.c | 36 +++++++++++-- 5 files changed, 80 insertions(+), 87 deletions(-) diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index e3bc15bd9d..40514cc83a 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -51,8 +51,7 @@ struct getent_state { struct getent_state *prev, *next; void *sam_entries; uint32 sam_entry_index, num_sam_entries; - uint32 grp_query_start_ndx; - BOOL got_all_grp_entries, got_sam_entries; + BOOL got_sam_entries; struct winbindd_domain *domain; }; @@ -99,7 +98,7 @@ struct winbindd_methods { /* get a list of groups */ NTSTATUS (*enum_dom_groups)(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *start_ndx, uint32 *num_entries, + uint32 *num_entries, struct acct_info **info); /* convert one user or group name to a sid */ diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index 13a0934ab4..afdf6d1ff0 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -236,7 +236,7 @@ done: /* list all domain groups */ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *start_ndx, uint32 *num_entries, + uint32 *num_entries, struct acct_info **info) { ADS_STRUCT *ads = NULL; @@ -251,12 +251,6 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, DEBUG(3,("ads: enum_dom_groups\n")); - if ((*start_ndx) != 0) { - DEBUG(1,("ads backend start_ndx not implemented\n")); - status = NT_STATUS_NOT_IMPLEMENTED; - goto done; - } - ads = ads_cached_connection(domain); if (!ads) goto done; diff --git a/source3/nsswitch/winbindd_cache.c b/source3/nsswitch/winbindd_cache.c index 304c686b97..32f9f0d69f 100644 --- a/source3/nsswitch/winbindd_cache.c +++ b/source3/nsswitch/winbindd_cache.c @@ -502,7 +502,7 @@ skip_save: /* list all domain groups */ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *start_ndx, uint32 *num_entries, + uint32 *num_entries, struct acct_info **info) { struct winbind_cache *cache = get_cache(domain); @@ -512,7 +512,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, if (!cache->tdb) goto do_query; - centry = wcache_fetch(cache, domain, "GL/%s/%d", domain->name, *start_ndx); + centry = wcache_fetch(cache, domain, "GL/%s", domain->name); if (!centry) goto do_query; *num_entries = centry_uint32(centry); @@ -538,7 +538,7 @@ do_query: return NT_STATUS_SERVER_DISABLED; } - status = cache->backend->enum_dom_groups(domain, mem_ctx, start_ndx, num_entries, info); + status = cache->backend->enum_dom_groups(domain, mem_ctx, num_entries, info); /* and save it */ refresh_sequence_number(domain, True); @@ -550,7 +550,7 @@ do_query: centry_put_string(centry, (*info)[i].acct_desc); centry_put_uint32(centry, (*info)[i].rid); } - centry_end(centry, "GL/%s/%d", domain->name, *start_ndx); + centry_end(centry, "GL/%s", domain->name); centry_free(centry); skip_save: diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index 1939fed275..2e932b1a55 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -413,11 +413,12 @@ static BOOL get_sam_group_entries(struct getent_state *ent) { NTSTATUS status; uint32 num_entries; - struct acct_info *name_list = NULL, *tnl; + struct acct_info *name_list = NULL; TALLOC_CTX *mem_ctx; BOOL result = False; + struct acct_info *sam_grp_entries = NULL; - if (ent->got_all_grp_entries) + if (ent->got_sam_entries) return False; if (!(mem_ctx = talloc_init())) @@ -427,63 +428,37 @@ static BOOL get_sam_group_entries(struct getent_state *ent) SAFE_FREE(ent->sam_entries); ent->num_sam_entries = 0; - - /* Enumerate domain groups */ - - do { - struct acct_info *sam_grp_entries = NULL; - - num_entries = 0; - - status = ent->domain->methods->enum_dom_groups(ent->domain, - mem_ctx, - &ent->grp_query_start_ndx, - &num_entries, - &sam_grp_entries); - - if (!NT_STATUS_IS_OK(status)) break; - - /* Copy entries into return buffer */ - - if (num_entries) { + ent->got_sam_entries = True; - tnl = Realloc(name_list, - sizeof(struct acct_info) * - (ent->num_sam_entries + - num_entries)); - - if (tnl == NULL) { - DEBUG(0,("get_sam_group_entries: unable to " - "realloc a structure!\n")); - SAFE_FREE(name_list); - - goto done; - } else - name_list = tnl; - - memcpy(&name_list[ent->num_sam_entries], - sam_grp_entries, - num_entries * sizeof(struct acct_info)); - } + /* Enumerate domain groups */ + num_entries = 0; - ent->num_sam_entries += num_entries; - - if (NT_STATUS_V(status) != NT_STATUS_V(STATUS_MORE_ENTRIES)) - break; + status = ent->domain->methods->enum_dom_groups(ent->domain, + mem_ctx, + &num_entries, + &sam_grp_entries); + + if (!NT_STATUS_IS_OK(status)) { + result = False; + goto done; + } - } while (ent->num_sam_entries < MAX_FETCH_SAM_ENTRIES); + /* Copy entries into return buffer */ + if (num_entries) { + name_list = malloc(sizeof(struct acct_info) * num_entries); + memcpy(name_list, sam_grp_entries, + num_entries * sizeof(struct acct_info)); + } + + ent->num_sam_entries = num_entries; /* Fill in remaining fields */ - ent->sam_entries = name_list; ent->sam_entry_index = 0; - ent->got_all_grp_entries = (NT_STATUS_V(status) != - NT_STATUS_V(STATUS_MORE_ENTRIES)); result = (ent->num_sam_entries > 0); done: - talloc_destroy(mem_ctx); return result; @@ -714,6 +689,8 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state) get_domain_info(); for (domain = domain_list; domain; domain = domain->next) { + int new_size; + int offset; /* Skip domains other than WINBINDD_DOMAIN environment variable */ @@ -735,29 +712,26 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state) num_domain_entries = 0; - while (get_sam_group_entries(&groups)) { - int new_size; - int offset; + get_sam_group_entries(&groups); - offset = sizeof(struct acct_info) * num_domain_entries; - new_size = sizeof(struct acct_info) - * (groups.num_sam_entries + num_domain_entries); - sam_entries = Realloc(sam_entries, new_size); + offset = sizeof(struct acct_info) * num_domain_entries; + new_size = sizeof(struct acct_info) + * (groups.num_sam_entries + num_domain_entries); + sam_entries = Realloc(sam_entries, new_size); - if (!sam_entries) - return WINBINDD_ERROR; - - num_domain_entries += groups.num_sam_entries; - memcpy (((char *)sam_entries)+offset, - groups.sam_entries, - sizeof(struct acct_info) * - groups.num_sam_entries); + if (!sam_entries) + return WINBINDD_ERROR; - free(groups.sam_entries); - - groups.sam_entries = NULL; - groups.num_sam_entries = 0; - } + num_domain_entries += groups.num_sam_entries; + memcpy (((char *)sam_entries)+offset, + groups.sam_entries, + sizeof(struct acct_info) * + groups.num_sam_entries); + + free(groups.sam_entries); + + groups.sam_entries = NULL; + groups.num_sam_entries = 0; /* skip remainder of loop if we idn;t retrieve any groups */ diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index eb14a30f39..87656d7ae2 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -109,7 +109,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, /* list all domain groups */ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *start_ndx, uint32 *num_entries, + uint32 *num_entries, struct acct_info **info) { uint32 des_access = SEC_RIGHTS_MAXIMUM_ALLOWED; @@ -118,6 +118,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, NTSTATUS status; *num_entries = 0; + *info = NULL; if (!(hnd = cm_get_sam_handle(domain->name))) { return NT_STATUS_UNSUCCESSFUL; @@ -129,10 +130,35 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain, return status; } - status = cli_samr_enum_dom_groups(hnd->cli, mem_ctx, &dom_pol, - start_ndx, - 0x8000, /* buffer size? */ - info, num_entries); + do { + struct acct_info *info2 = NULL; + uint32 count = 0, start = *num_entries; + TALLOC_CTX *mem_ctx2; + + mem_ctx2 = talloc_init(); + + status = cli_samr_enum_dom_groups(hnd->cli, mem_ctx2, &dom_pol, + &start, + 0xFFFF, /* buffer size? */ + &info2, &count); + + if (!NT_STATUS_IS_OK(status) && + !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { + talloc_destroy(mem_ctx2); + break; + } + + (*info) = talloc_realloc(mem_ctx, *info, + sizeof(**info) * ((*num_entries) + count)); + if (! *info) { + talloc_destroy(mem_ctx2); + return NT_STATUS_NO_MEMORY; + } + + memcpy(&(*info)[*num_entries], info2, count*sizeof(*info2)); + (*num_entries) += count; + talloc_destroy(mem_ctx2); + } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)); cli_samr_close(hnd->cli, mem_ctx, &dom_pol); -- cgit