/* 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,
/* 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"));
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;
}
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;
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;
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)
/* 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;
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; i<num_rids; i++) {
+ rids[i] = centry_uint32(centry);
}
do_cached:
return status;
do_query:
- *num_entries = 0;
- *info = NULL;
/* Return status value returned by seq number check */
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)));
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?
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;
}
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);
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) {
*/
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; 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++]);
- }
+ 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)
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;
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:
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,
/* 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;
}
/* 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;
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;
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;
}
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,
/* 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;
ZERO_STRUCT(dom_pol);
- if (pnum_info) {
- *pnum_info = 0;
- }
+ *prids = NULL;
tmp_ctx = talloc_stackframe();
if (tmp_ctx == NULL) {
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:
/* 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;
}