From: Volker Lendecke Date: Tue, 3 Jan 2017 12:11:30 +0000 (+0000) Subject: winbind: Simplify query_user_list to only return rids X-Git-Tag: samba-4.6.0rc1~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=480c9581a13afc08b20e80d2ff8a45ac8d7f18d3;p=thirdparty%2Fsamba.git winbind: Simplify query_user_list to only return rids Unfortunately this is a pretty large patch, because many functions implement this API. The alternative would have been to create a new backend function, add the new one piece by piece and then remove the original function. Signed-off-by: Volker Lendecke Reviewed-by: Uri Simchoni Reviewed-by: Andreas Schneider --- diff --git a/source3/winbindd/winbindd.h b/source3/winbindd/winbindd.h index 3f28fd07a3c..0f9570338d9 100644 --- a/source3/winbindd/winbindd.h +++ b/source3/winbindd/winbindd.h @@ -222,8 +222,7 @@ struct winbindd_methods { /* get a list of users, returning a wbint_userinfo for each one */ NTSTATUS (*query_user_list)(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32_t *num_entries, - struct wbint_userinfo **info); + uint32_t **rids); /* get a list of domain groups */ NTSTATUS (*enum_dom_groups)(struct winbindd_domain *domain, diff --git a/source3/winbindd/winbindd_ads.c b/source3/winbindd/winbindd_ads.c index 0f70334fe61..83579686ff4 100644 --- a/source3/winbindd/winbindd_ads.c +++ b/source3/winbindd/winbindd_ads.c @@ -288,18 +288,18 @@ static ADS_STRUCT *ads_cached_connection(struct winbindd_domain *domain) /* 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_t *num_entries, - struct wbint_userinfo **pinfo) + uint32_t **prids) { ADS_STRUCT *ads = NULL; - const char *attrs[] = { "*", NULL }; - int i, count; + const char *attrs[] = { "sAMAccountType", "objectSid", NULL }; + int count; + uint32_t *rids; ADS_STATUS rc; LDAPMessage *res = NULL; LDAPMessage *msg = NULL; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - *num_entries = 0; + *prids = NULL; DEBUG(3,("ads: query_user_list\n")); @@ -332,8 +332,8 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, goto done; } - (*pinfo) = talloc_zero_array(mem_ctx, struct wbint_userinfo, count); - if (!*pinfo) { + rids = talloc_zero_array(mem_ctx, uint32_t, count); + if (rids == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } @@ -341,8 +341,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, count = 0; for (msg = ads_first_entry(ads, res); msg; msg = ads_next_entry(ads, msg)) { - struct wbint_userinfo *info = &((*pinfo)[count]); - uint32_t group; + struct dom_sid user_sid; uint32_t atype; bool ok; @@ -356,59 +355,30 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain, continue; } - info->acct_name = ads_pull_username(ads, mem_ctx, msg); - info->full_name = ads_pull_string(ads, mem_ctx, msg, "displayName"); - if (info->full_name == NULL) { - info->full_name = ads_pull_string(ads, mem_ctx, msg, "name"); - } - info->homedir = NULL; - info->shell = NULL; - info->primary_gid = (gid_t)-1; - - if (!ads_pull_sid(ads, msg, "objectSid", - &info->user_sid)) { - DEBUG(1, ("No sid for %s !?\n", info->acct_name)); + if (!ads_pull_sid(ads, msg, "objectSid", &user_sid)) { + DBG_INFO("No sid for %s !?\n", + ads_get_dn(ads, talloc_tos(), msg)); continue; } - if (!ads_pull_uint32(ads, msg, "primaryGroupID", &group)) { - DEBUG(1, ("No primary group for %s !?\n", - info->acct_name)); + if (!dom_sid_in_domain(&domain->sid, &user_sid)) { + fstring sidstr, domstr; + DBG_WARNING("Got sid %s in domain %s\n", + sid_to_fstring(sidstr, &user_sid), + sid_to_fstring(domstr, &domain->sid)); continue; } - sid_compose(&info->group_sid, &domain->sid, group); + sid_split_rid(&user_sid, &rids[count]); count += 1; } - (*num_entries) = count; - ads_msgfree(ads, res); - - for (i=0; iuser_sid, mem_ctx, - &info->homedir, &info->shell, - &gecos, &primary_gid); - if (!NT_STATUS_IS_OK(status)) { - /* - * Deliberately ignore this error, there might be more - * users to fill - */ - continue; - } - - if (gecos != NULL) { - info->full_name = gecos; - } - info->primary_gid = primary_gid; - } + rids = talloc_realloc(mem_ctx, rids, uint32_t, count); + *prids = rids; status = NT_STATUS_OK; - DEBUG(3,("ads query_user_list gave %d entries\n", (*num_entries))); + DBG_NOTICE("ads query_user_list gave %d entries\n", count); done: return status; diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index d8a49c7015f..4a2b1aa9586 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -1006,36 +1006,6 @@ static void wcache_save_sid_to_name(struct winbindd_domain *domain, NTSTATUS sta centry_free(centry); } - -static void wcache_save_user(struct winbindd_domain *domain, NTSTATUS status, - struct wbint_userinfo *info) -{ - struct cache_entry *centry; - fstring sid_string; - - if (is_null_sid(&info->user_sid)) { - return; - } - - centry = centry_start(domain, status); - if (!centry) - return; - centry_put_string(centry, info->domain_name); - centry_put_string(centry, info->acct_name); - centry_put_string(centry, info->full_name); - centry_put_string(centry, info->homedir); - centry_put_string(centry, info->shell); - centry_put_uint32(centry, info->uid); - centry_put_uint32(centry, info->primary_gid); - centry_put_string(centry, info->primary_group_name); - centry_put_sid(centry, &info->user_sid); - centry_put_sid(centry, &info->group_sid); - centry_end(centry, "U/%s", sid_to_fstring(sid_string, - &info->user_sid)); - DEBUG(10,("wcache_save_user: %s (acct_name %s)\n", sid_string, info->acct_name)); - centry_free(centry); -} - static void wcache_save_lockout_policy(struct winbindd_domain *domain, NTSTATUS status, struct samr_DomInfo12 *lockout_policy) @@ -1459,15 +1429,18 @@ NTSTATUS wcache_save_creds(struct winbindd_domain *domain, /* Query display info. This is the basic user list fn */ NTSTATUS wb_cache_query_user_list(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32_t *num_entries, - struct wbint_userinfo **info) + uint32_t **prids) { struct winbind_cache *cache = get_cache(domain); struct cache_entry *centry = NULL; + uint32_t num_rids = 0; + uint32_t *rids = NULL; NTSTATUS status; unsigned int i, retry; bool old_status = domain->online; + *prids = NULL; + if (!cache->tdb) goto do_query; @@ -1476,26 +1449,19 @@ NTSTATUS wb_cache_query_user_list(struct winbindd_domain *domain, goto do_query; do_fetch_cache: - *num_entries = centry_uint32(centry); + num_rids = centry_uint32(centry); - if (*num_entries == 0) + if (num_rids == 0) { goto do_cached; + } - (*info) = talloc_array(mem_ctx, struct wbint_userinfo, *num_entries); - if (! (*info)) { - smb_panic_fn("query_user_list out of memory"); + rids = talloc_array(mem_ctx, uint32_t, num_rids); + if (rids == NULL) { + return NT_STATUS_NO_MEMORY; } - for (i=0; i<(*num_entries); i++) { - (*info)[i].domain_name = centry_string(centry, mem_ctx); - (*info)[i].acct_name = centry_string(centry, mem_ctx); - (*info)[i].full_name = centry_string(centry, mem_ctx); - (*info)[i].homedir = centry_string(centry, mem_ctx); - (*info)[i].shell = centry_string(centry, mem_ctx); - (*info)[i].uid = centry_uint32(centry); - (*info)[i].primary_gid = centry_uint32(centry); - (*info)[i].primary_group_name = centry_string(centry, mem_ctx); - centry_sid(centry, &(*info)[i].user_sid); - centry_sid(centry, &(*info)[i].group_sid); + + for (i=0; iname )); - status = domain->backend->query_user_list(domain, mem_ctx, num_entries, info); + rids = NULL; + status = domain->backend->query_user_list(domain, mem_ctx, + &rids); + num_rids = talloc_array_length(rids); + if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("query_user_list: returned 0x%08x, " "retrying\n", NT_STATUS_V(status))); @@ -1546,7 +1514,7 @@ do_query: set_domain_offline(domain); } /* store partial response. */ - if (*num_entries > 0) { + if (num_rids > 0) { /* * humm, what about the status used for cache? * Should it be NT_STATUS_OK? @@ -1581,36 +1549,15 @@ do_query: centry = centry_start(domain, status); if (!centry) goto skip_save; - centry_put_uint32(centry, *num_entries); - for (i=0; i<(*num_entries); i++) { - centry_put_string(centry, (*info)[i].domain_name); - centry_put_string(centry, (*info)[i].acct_name); - centry_put_string(centry, (*info)[i].full_name); - centry_put_string(centry, (*info)[i].homedir); - centry_put_string(centry, (*info)[i].shell); - centry_put_uint32(centry, (*info)[i].uid); - centry_put_uint32(centry, (*info)[i].primary_gid); - centry_put_string(centry, (*info)[i].primary_group_name); - centry_put_sid(centry, &(*info)[i].user_sid); - centry_put_sid(centry, &(*info)[i].group_sid); - if (domain->backend && domain->backend->consistent) { - /* when the backend is consistent we can pre-prime some mappings */ - wcache_save_name_to_sid(domain, NT_STATUS_OK, - domain->name, - (*info)[i].acct_name, - &(*info)[i].user_sid, - SID_NAME_USER); - wcache_save_sid_to_name(domain, NT_STATUS_OK, - &(*info)[i].user_sid, - domain->name, - (*info)[i].acct_name, - SID_NAME_USER); - wcache_save_user(domain, NT_STATUS_OK, &(*info)[i]); - } + centry_put_uint32(centry, num_rids); + for (i=0; iname); centry_free(centry); + *prids = rids; + skip_save: return status; } @@ -3692,17 +3639,7 @@ static int validate_ul(TALLOC_CTX *mem_ctx, const char *keystr, TDB_DATA dbuf, num_entries = (int32_t)centry_uint32(centry); for (i=0; i< num_entries; i++) { - struct dom_sid sid; - (void)centry_string(centry, mem_ctx); - (void)centry_string(centry, mem_ctx); - (void)centry_string(centry, mem_ctx); - (void)centry_string(centry, mem_ctx); - (void)centry_string(centry, mem_ctx); - (void)centry_uint32(centry); (void)centry_uint32(centry); - (void)centry_string(centry, mem_ctx); - (void)centry_sid(centry, &sid); - (void)centry_sid(centry, &sid); } centry_free(centry); diff --git a/source3/winbindd/winbindd_dual_srv.c b/source3/winbindd/winbindd_dual_srv.c index 06392ffa742..49236cdd95c 100644 --- a/source3/winbindd/winbindd_dual_srv.c +++ b/source3/winbindd/winbindd_dual_srv.c @@ -466,8 +466,6 @@ NTSTATUS _wbint_QueryUserRidList(struct pipes_struct *p, struct wbint_QueryUserRidList *r) { struct winbindd_domain *domain = wb_child_domain(); - uint32_t i, num_userinfos; - struct wbint_userinfo *userinfos; NTSTATUS status; if (domain == NULL) { @@ -480,33 +478,16 @@ NTSTATUS _wbint_QueryUserRidList(struct pipes_struct *p, */ status = wb_cache_query_user_list(domain, p->mem_ctx, - &num_userinfos, &userinfos); + &r->out.rids->rids); reset_cm_connection_on_error(domain, status); if (!NT_STATUS_IS_OK(status)) { return status; } - r->out.rids->rids = talloc_array(r->out.rids, uint32_t, num_userinfos); - if (r->out.rids->rids == NULL) { - return NT_STATUS_NO_MEMORY; - } - - for (i=0; isid, &info->user_sid)) { - fstring sidstr, domstr; - DBG_WARNING("Got sid %s in domain %s\n", - sid_to_fstring(sidstr, &info->user_sid), - sid_to_fstring(domstr, &domain->sid)); - continue; - } - sid_split_rid(&info->user_sid, - &r->out.rids->rids[r->out.rids->num_rids++]); - } + r->out.rids->num_rids = talloc_array_length(r->out.rids->rids); - return status; + return NT_STATUS_OK; } NTSTATUS _wbint_DsGetDcName(struct pipes_struct *p, struct wbint_DsGetDcName *r) diff --git a/source3/winbindd/winbindd_msrpc.c b/source3/winbindd/winbindd_msrpc.c index bc19973082d..4b742c4c58b 100644 --- a/source3/winbindd/winbindd_msrpc.c +++ b/source3/winbindd/winbindd_msrpc.c @@ -49,22 +49,16 @@ static NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx, application. */ static NTSTATUS msrpc_query_user_list(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32_t *pnum_info, - struct wbint_userinfo **pinfo) + uint32_t **prids) { struct rpc_pipe_client *samr_pipe = NULL; struct policy_handle dom_pol; - struct wbint_userinfo *info = NULL; - uint32_t num_info = 0; + uint32_t *rids; TALLOC_CTX *tmp_ctx; NTSTATUS status; DEBUG(3, ("msrpc_query_user_list\n")); - if (pnum_info) { - *pnum_info = 0; - } - tmp_ctx = talloc_stackframe(); if (tmp_ctx == NULL) { return NT_STATUS_NO_MEMORY; @@ -86,18 +80,13 @@ static NTSTATUS msrpc_query_user_list(struct winbindd_domain *domain, samr_pipe, &dom_pol, &domain->sid, - &num_info, - &info); + &rids); if (!NT_STATUS_IS_OK(status)) { goto done; } - if (pnum_info) { - *pnum_info = num_info; - } - - if (pinfo) { - *pinfo = talloc_move(mem_ctx, &info); + if (prids) { + *prids = talloc_move(mem_ctx, &rids); } done: diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 040e8ab5ede..42e731d81c1 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -59,8 +59,7 @@ NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx, NTSTATUS wb_cache_query_user_list(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32_t *num_entries, - struct wbint_userinfo **info); + uint32_t **prids); NTSTATUS wb_cache_enum_dom_groups(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, uint32_t *num_entries, diff --git a/source3/winbindd/winbindd_reconnect.c b/source3/winbindd/winbindd_reconnect.c index 5727a653e3e..d23ffcfb8de 100644 --- a/source3/winbindd/winbindd_reconnect.c +++ b/source3/winbindd/winbindd_reconnect.c @@ -83,17 +83,15 @@ bool reconnect_need_retry(NTSTATUS status, struct winbindd_domain *domain) /* List all users */ static NTSTATUS query_user_list(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32_t *num_entries, - struct wbint_userinfo **info) + uint32_t **rids) { NTSTATUS result; - result = msrpc_methods.query_user_list(domain, mem_ctx, - num_entries, info); + result = msrpc_methods.query_user_list(domain, mem_ctx, rids); if (reconnect_need_retry(result, domain)) - result = msrpc_methods.query_user_list(domain, mem_ctx, - num_entries, info); + result = msrpc_methods.query_user_list(domain, mem_ctx, rids); + return result; } diff --git a/source3/winbindd/winbindd_reconnect_ads.c b/source3/winbindd/winbindd_reconnect_ads.c index dbfa7ff16d3..17ea9d28c0c 100644 --- a/source3/winbindd/winbindd_reconnect_ads.c +++ b/source3/winbindd/winbindd_reconnect_ads.c @@ -34,17 +34,14 @@ extern struct winbindd_methods ads_methods; /* List all users */ static NTSTATUS query_user_list(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32_t *num_entries, - struct wbint_userinfo **info) + uint32_t **rids) { NTSTATUS result; - result = ads_methods.query_user_list(domain, mem_ctx, - num_entries, info); + result = ads_methods.query_user_list(domain, mem_ctx, rids); if (reconnect_need_retry(result, domain)) { - result = ads_methods.query_user_list(domain, mem_ctx, - num_entries, info); + result = ads_methods.query_user_list(domain, mem_ctx, rids); } return result; diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c index 1e234ba4181..bb8af45c896 100644 --- a/source3/winbindd/winbindd_rpc.c +++ b/source3/winbindd/winbindd_rpc.c @@ -38,18 +38,17 @@ NTSTATUS rpc_query_user_list(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *samr_pipe, struct policy_handle *samr_policy, const struct dom_sid *domain_sid, - uint32_t *pnum_info, - struct wbint_userinfo **pinfo) + uint32_t **prids) { - struct wbint_userinfo *info = NULL; - uint32_t num_info = 0; + uint32_t *rids = NULL; + uint32_t num_rids = 0; uint32_t loop_count = 0; uint32_t start_idx = 0; uint32_t i = 0; NTSTATUS status, result; struct dcerpc_binding_handle *b = samr_pipe->binding_handle; - *pnum_info = 0; + *prids = NULL; do { uint32_t j; @@ -87,62 +86,23 @@ NTSTATUS rpc_query_user_list(TALLOC_CTX *mem_ctx, loop_count++; num_dom_users = disp_info.info1.count; - num_info += num_dom_users; + num_rids += num_dom_users; /* If there are no user to enumerate we're done */ - if (num_info == 0) { + if (num_rids == 0) { return NT_STATUS_OK; } - info = talloc_realloc(mem_ctx, - info, - struct wbint_userinfo, - num_info); - if (info == NULL) { + rids = talloc_realloc(mem_ctx, rids, uint32_t, num_rids); + if (rids == NULL) { return NT_STATUS_NO_MEMORY; } - for (j = 0; j < num_dom_users; i++, j++) { - uint32_t rid = disp_info.info1.entries[j].rid; - struct samr_DispEntryGeneral *src; - struct wbint_userinfo *dst; - - src = &(disp_info.info1.entries[j]); - dst = &(info[i]); - - *dst = (struct wbint_userinfo) {0}; - - dst->acct_name = talloc_strdup(info, - src->account_name.string); - if (dst->acct_name == NULL) { - return NT_STATUS_NO_MEMORY; - } - - dst->full_name = talloc_strdup(info, src->full_name.string); - if ((src->full_name.string != NULL) && - (dst->full_name == NULL)) - { - return NT_STATUS_NO_MEMORY; - } - - dst->homedir = NULL; - dst->shell = NULL; - dst->primary_gid = (gid_t)-1; - sid_compose(&dst->user_sid, domain_sid, rid); - - /* 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. */ - sid_compose(&dst->group_sid, domain_sid, - DOMAIN_RID_USERS); + for (j = 0; j < num_dom_users; j++) { + rids[i++] = disp_info.info1.entries[j].rid; } } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); - *pnum_info = num_info; - *pinfo = info; + *prids = rids; return NT_STATUS_OK; } diff --git a/source3/winbindd/winbindd_rpc.h b/source3/winbindd/winbindd_rpc.h index beb605a0053..ee4b21073b5 100644 --- a/source3/winbindd/winbindd_rpc.h +++ b/source3/winbindd/winbindd_rpc.h @@ -31,8 +31,7 @@ NTSTATUS rpc_query_user_list(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *samr_pipe, struct policy_handle *samr_policy, const struct dom_sid *domain_sid, - uint32_t *pnum_info, - struct wbint_userinfo **pinfo); + uint32_t **prids); NTSTATUS rpc_enum_dom_groups(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *samr_pipe, diff --git a/source3/winbindd/winbindd_samr.c b/source3/winbindd/winbindd_samr.c index 419e328ba28..7f6c37ae7ee 100644 --- a/source3/winbindd/winbindd_samr.c +++ b/source3/winbindd/winbindd_samr.c @@ -167,13 +167,11 @@ error: /* Query display info for a domain */ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32_t *pnum_info, - struct wbint_userinfo **pinfo) + uint32_t **prids) { struct rpc_pipe_client *samr_pipe = NULL; struct policy_handle dom_pol; - struct wbint_userinfo *info = NULL; - uint32_t num_info = 0; + uint32_t *rids; TALLOC_CTX *tmp_ctx; NTSTATUS status, result; struct dcerpc_binding_handle *b = NULL; @@ -182,9 +180,7 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain, ZERO_STRUCT(dom_pol); - if (pnum_info) { - *pnum_info = 0; - } + *prids = NULL; tmp_ctx = talloc_stackframe(); if (tmp_ctx == NULL) { @@ -202,18 +198,13 @@ static NTSTATUS sam_query_user_list(struct winbindd_domain *domain, samr_pipe, &dom_pol, &domain->sid, - &num_info, - &info); + &rids); if (!NT_STATUS_IS_OK(status)) { goto done; } - if (pnum_info) { - *pnum_info = num_info; - } - - if (pinfo) { - *pinfo = talloc_move(mem_ctx, &info); + if (prids) { + *prids = talloc_move(mem_ctx, &rids); } done: @@ -385,12 +376,10 @@ static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain, /* Query display info for a domain */ static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, - uint32_t *num_entries, - struct wbint_userinfo **info) + uint32_t **rids) { /* We don't have users */ - *num_entries = 0; - *info = NULL; + *rids = NULL; return NT_STATUS_OK; }