diff options
Diffstat (limited to 'source/nsswitch/winbindd_group.c')
-rw-r--r-- | source/nsswitch/winbindd_group.c | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c index 4ef57513bb0..126a99763bc 100644 --- a/source/nsswitch/winbindd_group.c +++ b/source/nsswitch/winbindd_group.c @@ -393,19 +393,16 @@ enum winbindd_result winbindd_endgrent(struct winbindd_cli_state *state) #define MAX_FETCH_SAM_ENTRIES 100 -static BOOL get_sam_group_entries(struct getent_state *ent) +static BOOL get_sam_group_entries(struct getent_state *ent, NTSTATUS *status) { - NTSTATUS status; uint32 num_entries; struct acct_info *name_list = NULL; TALLOC_CTX *mem_ctx; BOOL result = False; struct acct_info *sam_grp_entries = NULL; struct winbindd_domain *domain; + NTSTATUS nt_status; - if (ent->got_sam_entries) - return False; - if (!(mem_ctx = talloc_init_named("get_sam_group_entries(%s)", ent->domain_name))) return False; @@ -425,15 +422,11 @@ static BOOL get_sam_group_entries(struct getent_state *ent) goto done; } - status = domain->methods->enum_dom_groups(domain, - mem_ctx, - &num_entries, - &sam_grp_entries); + nt_status = domain->methods->enum_dom_groups( + domain, mem_ctx, &num_entries, &sam_grp_entries); - if (!NT_STATUS_IS_OK(status)) { - result = False; - goto done; - } + if (status && !NT_STATUS_IS_OK(nt_status)) + *status = nt_status; /* Copy entries into return buffer */ @@ -450,7 +443,12 @@ static BOOL get_sam_group_entries(struct getent_state *ent) ent->sam_entries = name_list; ent->sam_entry_index = 0; - result = (ent->num_sam_entries > 0); + /* Return false if we got an error or no sam entries, true otherwise */ + + if (!NT_STATUS_IS_OK(nt_status)) + result = False; + else + result = (ent->num_sam_entries > 0); done: talloc_destroy(mem_ctx); @@ -508,7 +506,7 @@ enum winbindd_result winbindd_getgrent(struct winbindd_cli_state *state) if (ent->num_sam_entries == ent->sam_entry_index) { - while(ent && !get_sam_group_entries(ent)) { + while(ent && !get_sam_group_entries(ent, NULL)) { struct getent_state *next_ent; DEBUG(10, ("freeing state info for domain %s\n", ent->domain_name)); @@ -685,21 +683,29 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state) for (domain = domain_list(); domain; domain = domain->next) { struct getent_state groups; + NTSTATUS status; ZERO_STRUCT(groups); /* Skip domains other than WINBINDD_DOMAIN environment variable */ + if ((strcmp(state->request.domain, "") != 0) && !check_domain_env(state->request.domain, domain->name)) continue; /* Get list of sam groups */ + ZERO_STRUCT(groups); fstrcpy(groups.domain_name, domain->name); - get_sam_group_entries(&groups); - + if (!get_sam_group_entries(&groups, &status)) { + if (!NT_STATUS_IS_OK(status)) + state->response.nt_status = NT_STATUS_V(status); + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) + continue; + } + if (groups.num_sam_entries == 0) { /* this domain is empty or in an error state */ continue; @@ -707,10 +713,12 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state) /* keep track the of the total number of groups seen so far over all domains */ + total_entries += groups.num_sam_entries; /* Allocate some memory for extra data. Note that we limit account names to sizeof(fstring) = 128 characters. */ + ted = Realloc(extra_data, sizeof(fstring) * total_entries); if (!ted) { |