1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-23 09:57:40 +03:00

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 <vl@samba.org>
Reviewed-by: Uri Simchoni <uri@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
This commit is contained in:
Volker Lendecke 2017-01-03 12:11:30 +00:00
parent 67c0696761
commit 480c9581a1
11 changed files with 83 additions and 265 deletions

View File

@ -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,

View File

@ -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; i<count; i++) {
struct wbint_userinfo *info = &((*pinfo)[i]);
const char *gecos = NULL;
gid_t primary_gid = (gid_t)-1;
status = nss_get_info_cached(domain, &info->user_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;

View File

@ -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");
}
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);
rids = talloc_array(mem_ctx, uint32_t, num_rids);
if (rids == NULL) {
return NT_STATUS_NO_MEMORY;
}
for (i=0; i<num_rids; i++) {
rids[i] = centry_uint32(centry);
}
do_cached:
@ -1508,8 +1474,6 @@ do_cached:
return status;
do_query:
*num_entries = 0;
*info = NULL;
/* Return status value returned by seq number check */
@ -1530,7 +1494,11 @@ do_query:
DEBUG(10,("query_user_list: [Cached] - doing backend query for list for domain %s\n",
domain->name ));
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; i<num_rids; i++) {
centry_put_uint32(centry, rids[i]);
}
centry_end(centry, "UL/%s", domain->name);
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);

View File

@ -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;
}
r->out.rids->num_rids = talloc_array_length(r->out.rids->rids);
for (i=0; i<num_userinfos; i++) {
struct wbint_userinfo *info = &userinfos[i];
if (!dom_sid_in_domain(&domain->sid, &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++]);
}
return status;
return NT_STATUS_OK;
}
NTSTATUS _wbint_DsGetDcName(struct pipes_struct *p, struct wbint_DsGetDcName *r)

View File

@ -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:

View File

@ -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,

View File

@ -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;
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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,

View File

@ -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;
}