summaryrefslogtreecommitdiffstats
path: root/source/nsswitch/winbindd_group.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/nsswitch/winbindd_group.c')
-rw-r--r--source/nsswitch/winbindd_group.c42
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) {