diff options
Diffstat (limited to 'source3/nsswitch')
-rw-r--r-- | source3/nsswitch/winbindd.h | 5 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_ads.c | 8 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_cache.c | 8 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_group.c | 4 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_rpc.c | 62 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_user.c | 161 |
6 files changed, 120 insertions, 128 deletions
diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index e22824f33c..e3bc15bd9d 100644 --- a/source3/nsswitch/winbindd.h +++ b/source3/nsswitch/winbindd.h @@ -51,9 +51,8 @@ struct getent_state { struct getent_state *prev, *next; void *sam_entries; uint32 sam_entry_index, num_sam_entries; - uint32 dispinfo_ndx; uint32 grp_query_start_ndx; - BOOL got_all_sam_entries, got_sam_entries; + BOOL got_all_grp_entries, got_sam_entries; struct winbindd_domain *domain; }; @@ -94,7 +93,7 @@ struct winbindd_methods { /* get a list of users, returning a WINBIND_USERINFO for each one */ NTSTATUS (*query_user_list)(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *start_ndx, uint32 *num_entries, + uint32 *num_entries, WINBIND_USERINFO **info); /* get a list of groups */ diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index 84e8ab3fc3..13a0934ab4 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -149,7 +149,7 @@ static enum SID_NAME_USE ads_atype_map(uint32 atype) /* Query display info for a realm. This is the basic user list fn */ static NTSTATUS query_user_list(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *start_ndx, uint32 *num_entries, + uint32 *num_entries, WINBIND_USERINFO **info) { ADS_STRUCT *ads = NULL; @@ -164,12 +164,6 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, DEBUG(3,("ads: query_user_list\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 d10c4c1fc1..304c686b97 100644 --- a/source3/nsswitch/winbindd_cache.c +++ b/source3/nsswitch/winbindd_cache.c @@ -430,7 +430,7 @@ static void wcache_save_user(struct winbindd_domain *domain, NTSTATUS status, WI /* Query display info. This is the basic user list fn */ static NTSTATUS query_user_list(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *start_ndx, uint32 *num_entries, + uint32 *num_entries, WINBIND_USERINFO **info) { struct winbind_cache *cache = get_cache(domain); @@ -440,7 +440,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, if (!cache->tdb) goto do_query; - centry = wcache_fetch(cache, domain, "UL/%s/%d", domain->name, *start_ndx); + centry = wcache_fetch(cache, domain, "UL/%s", domain->name); if (!centry) goto do_query; *num_entries = centry_uint32(centry); @@ -467,7 +467,7 @@ do_query: return NT_STATUS_SERVER_DISABLED; } - status = cache->backend->query_user_list(domain, mem_ctx, start_ndx, num_entries, info); + status = cache->backend->query_user_list(domain, mem_ctx, num_entries, info); /* and save it */ refresh_sequence_number(domain, True); @@ -492,7 +492,7 @@ do_query: wcache_save_user(domain, NT_STATUS_OK, &(*info)[i]); } } - centry_end(centry, "UL/%s/%d", domain->name, *start_ndx); + centry_end(centry, "UL/%s", domain->name); centry_free(centry); skip_save: diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index abbd960e9d..1939fed275 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -417,7 +417,7 @@ static BOOL get_sam_group_entries(struct getent_state *ent) TALLOC_CTX *mem_ctx; BOOL result = False; - if (ent->got_all_sam_entries) + if (ent->got_all_grp_entries) return False; if (!(mem_ctx = talloc_init())) @@ -477,7 +477,7 @@ static BOOL get_sam_group_entries(struct getent_state *ent) ent->sam_entries = name_list; ent->sam_entry_index = 0; - ent->got_all_sam_entries = (NT_STATUS_V(status) != + ent->got_all_grp_entries = (NT_STATUS_V(status) != NT_STATUS_V(STATUS_MORE_ENTRIES)); result = (ent->num_sam_entries > 0); diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index 5417e8c4d0..eb14a30f39 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -28,7 +28,7 @@ application. */ static NTSTATUS query_user_list(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32 *start_ndx, uint32 *num_entries, + uint32 *num_entries, WINBIND_USERINFO **info) { CLI_POLICY_HND *hnd; @@ -41,6 +41,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, int i; *num_entries = 0; + *info = NULL; /* Get sam handle */ @@ -59,28 +60,43 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, ctr.sam.info1 = &info1; - /* Query display info level 1 */ - result = cli_samr_query_dispinfo(hnd->cli, mem_ctx, - &dom_pol, start_ndx, 1, - num_entries, 0xffff, &ctr); - - /* now map the result into the WINBIND_USERINFO structure */ - (*info) = (WINBIND_USERINFO *)talloc(mem_ctx, (*num_entries)*sizeof(WINBIND_USERINFO)); - if (!(*info)) { - return NT_STATUS_NO_MEMORY; - } - - for (i=0;i<*num_entries;i++) { - (*info)[i].acct_name = unistr2_tdup(mem_ctx, &info1.str[i].uni_acct_name); - (*info)[i].full_name = unistr2_tdup(mem_ctx, &info1.str[i].uni_full_name); - (*info)[i].user_rid = info1.sam[i].rid_user; - /* For the moment we set the primary group for every user to be the - Domain Users group. There are serious problems with determining - the actual primary group for large domains. This should really - be made into a 'winbind force group' smb.conf parameter or - something like that. */ - (*info)[i].group_rid = DOMAIN_GROUP_RID_USERS; - } + i = 0; + do { + uint32 count = 0, start=i; + int j; + + + /* Query display info level 1 */ + result = cli_samr_query_dispinfo(hnd->cli, mem_ctx, + &dom_pol, &start, 1, + &count, 0xFFFF, &ctr); + + if (!NT_STATUS_IS_OK(result) && + !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) break; + + (*num_entries) += count; + + /* now map the result into the WINBIND_USERINFO structure */ + (*info) = talloc_realloc(mem_ctx, *info, + (*num_entries)*sizeof(WINBIND_USERINFO)); + if (!(*info)) { + return NT_STATUS_NO_MEMORY; + } + + for (j=0;j<count;i++, j++) { + (*info)[i].acct_name = unistr2_tdup(mem_ctx, &info1.str[j].uni_acct_name); + (*info)[i].full_name = unistr2_tdup(mem_ctx, &info1.str[j].uni_full_name); + (*info)[i].user_rid = info1.sam[j].rid_user; + /* For the moment we set the primary group for + every user to be the Domain Users group. + There are serious problems with determining + the actual primary group for large domains. + This should really be made into a 'winbind + force group' smb.conf parameter or + something like that. */ + (*info)[i].group_rid = DOMAIN_GROUP_RID_USERS; + } + } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); done: diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c index ff4d89c1bb..6f38b13548 100644 --- a/source3/nsswitch/winbindd_user.c +++ b/source3/nsswitch/winbindd_user.c @@ -333,8 +333,9 @@ static BOOL get_sam_user_entries(struct getent_state *ent) BOOL result = False; TALLOC_CTX *mem_ctx; struct winbindd_methods *methods; + int i; - if (ent->got_all_sam_entries) + if (ent->num_sam_entries) return False; if (!(mem_ctx = talloc_init())) @@ -348,65 +349,53 @@ static BOOL get_sam_user_entries(struct getent_state *ent) ent->num_sam_entries = 0; /* Call query_user_list to get a list of usernames and user rids */ + num_entries = 0; - do { - int i; - - num_entries = 0; - - status = methods->query_user_list(ent->domain, mem_ctx, - &ent->dispinfo_ndx, - &num_entries, &info); + status = methods->query_user_list(ent->domain, mem_ctx, + &num_entries, &info); - if (num_entries) { - struct getpwent_user *tnl; - - tnl = (struct getpwent_user *)Realloc(name_list, - sizeof(struct getpwent_user) * - (ent->num_sam_entries + - num_entries)); - - if (!tnl) { - DEBUG(0,("get_sam_user_entries: Realloc failed.\n")); - SAFE_FREE(name_list); - goto done; - } else - name_list = tnl; - } - - for (i = 0; i < num_entries; i++) { - /* Store account name and gecos */ - if (!info[i].acct_name) { - fstrcpy(name_list[ent->num_sam_entries + i].name, ""); - } else { - fstrcpy(name_list[ent->num_sam_entries + i].name, - info[i].acct_name); - } - if (!info[i].full_name) { - fstrcpy(name_list[ent->num_sam_entries + i].gecos, ""); - } else { - fstrcpy(name_list[ent->num_sam_entries + i].gecos, - info[i].full_name); - } + if (num_entries) { + struct getpwent_user *tnl; + + tnl = (struct getpwent_user *)Realloc(name_list, + sizeof(struct getpwent_user) * + (ent->num_sam_entries + + num_entries)); + + if (!tnl) { + DEBUG(0,("get_sam_user_entries: Realloc failed.\n")); + SAFE_FREE(name_list); + goto done; + } else + name_list = tnl; + } - /* User and group ids */ - name_list[ent->num_sam_entries+i].user_rid = info[i].user_rid; - name_list[ent->num_sam_entries+i].group_rid = info[i].group_rid; + for (i = 0; i < num_entries; i++) { + /* Store account name and gecos */ + if (!info[i].acct_name) { + fstrcpy(name_list[ent->num_sam_entries + i].name, ""); + } else { + fstrcpy(name_list[ent->num_sam_entries + i].name, + info[i].acct_name); + } + if (!info[i].full_name) { + fstrcpy(name_list[ent->num_sam_entries + i].gecos, ""); + } else { + fstrcpy(name_list[ent->num_sam_entries + i].gecos, + info[i].full_name); } - ent->num_sam_entries += num_entries; - - if (NT_STATUS_V(status) != NT_STATUS_V(STATUS_MORE_ENTRIES)) - break; - - } while (ent->num_sam_entries < MAX_FETCH_SAM_ENTRIES); + /* User and group ids */ + name_list[ent->num_sam_entries+i].user_rid = info[i].user_rid; + name_list[ent->num_sam_entries+i].group_rid = info[i].group_rid; + } + + ent->num_sam_entries += num_entries; /* Fill in remaining fields */ ent->sam_entries = name_list; ent->sam_entry_index = 0; - ent->got_all_sam_entries = (NT_STATUS_V(status) != NT_STATUS_V(STATUS_MORE_ENTRIES)); - result = ent->num_sam_entries > 0; done: @@ -552,8 +541,8 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state) for (domain = domain_list; domain; domain = domain->next) { NTSTATUS status; - uint32 start_ndx = 0; struct winbindd_methods *methods; + int i; /* Skip domains other than WINBINDD_DOMAIN environment variable */ @@ -565,51 +554,45 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state) methods = domain->methods; /* Query display info */ + status = methods->query_user_list(domain, mem_ctx, + &num_entries, &info); - do { - int i; - - status = methods->query_user_list(domain, mem_ctx, &start_ndx, - &num_entries, &info); - - if (num_entries == 0) - continue; + if (num_entries == 0) + continue; - /* Allocate some memory for extra data */ - total_entries += num_entries; + /* Allocate some memory for extra data */ + total_entries += num_entries; - ted = Realloc(extra_data, sizeof(fstring) * - total_entries); + ted = Realloc(extra_data, sizeof(fstring) * total_entries); - if (!ted) { - DEBUG(0,("winbindd_list_users: failed to enlarge buffer!\n")); - SAFE_FREE(extra_data); - goto done; - } else - extra_data = ted; + if (!ted) { + DEBUG(0,("winbindd_list_users: failed to enlarge buffer!\n")); + SAFE_FREE(extra_data); + goto done; + } else + extra_data = ted; - /* Pack user list into extra data fields */ + /* Pack user list into extra data fields */ + + for (i = 0; i < num_entries; i++) { + fstring acct_name, name; + + if (!info[i].acct_name) { + fstrcpy(acct_name, ""); + } else { + fstrcpy(acct_name, info[i].acct_name); + } + + slprintf(name, sizeof(name) - 1, "%s%s%s", + domain->name, lp_winbind_separator(), + acct_name); - for (i = 0; i < num_entries; i++) { - fstring acct_name, name; - - if (!info[i].acct_name) { - fstrcpy(acct_name, ""); - } else { - fstrcpy(acct_name, info[i].acct_name); - } - - slprintf(name, sizeof(name) - 1, "%s%s%s", - domain->name, lp_winbind_separator(), - acct_name); - /* Append to extra data */ - memcpy(&extra_data[extra_data_len], name, - strlen(name)); - extra_data_len += strlen(name); - extra_data[extra_data_len++] = ','; - } - } while (NT_STATUS_V(status) == NT_STATUS_V(STATUS_MORE_ENTRIES)); + memcpy(&extra_data[extra_data_len], name, + strlen(name)); + extra_data_len += strlen(name); + extra_data[extra_data_len++] = ','; + } } /* Assign extra_data fields in response structure */ |