summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/nsswitch/winbindd.h1
-rw-r--r--source3/nsswitch/winbindd_group.c45
-rw-r--r--source3/nsswitch/winbindd_proto.h2
-rw-r--r--source3/nsswitch/winbindd_user.c56
-rw-r--r--source3/nsswitch/winbindd_util.c89
5 files changed, 106 insertions, 87 deletions
diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h
index a9035ca200..659789a920 100644
--- a/source3/nsswitch/winbindd.h
+++ b/source3/nsswitch/winbindd.h
@@ -55,6 +55,7 @@ struct getent_state {
uint32 grp_query_start_ndx;
BOOL got_all_sam_entries, got_sam_entries;
struct winbindd_domain *domain;
+ TALLOC_CTX *mem_ctx;
};
/* Storage for cached getpwent() user entries */
diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c
index 893302716f..b526feb780 100644
--- a/source3/nsswitch/winbindd_group.c
+++ b/source3/nsswitch/winbindd_group.c
@@ -52,9 +52,11 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
int buf_len, buf_ndx, i;
char **names = NULL, *buf;
BOOL result = False;
-
- if (!num_gr_mem || !gr_mem || !gr_mem_len) return False;
-
+ TALLOC_CTX *mem_ctx;
+
+ if (!(mem_ctx = talloc_init()))
+ return False;
+
/* Initialise group membership information */
DEBUG(10, ("fill_grent_mem(): group %s rid 0x%x\n",
@@ -65,28 +67,27 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
if (group_name_type != SID_NAME_DOM_GRP) {
DEBUG(1, ("fill_grent_mem(): rid %d in domain %s isn't a "
"domain group\n", group_rid, domain->name));
- return False;
+ goto done;
}
/* Lookup group members */
- if (!winbindd_lookup_groupmem(domain, group_rid, &num_names,
+ if (!winbindd_lookup_groupmem(domain, mem_ctx, group_rid, &num_names,
&rid_mem, &names, &name_types)) {
DEBUG(1, ("fill_grent_mem(): could not lookup membership "
"for group rid %d in domain %s\n",
group_rid, domain->name));
- return False;
+ goto done;
}
DEBUG(10, ("fill_grent_mem(): looked up %d names\n", num_names));
if (DEBUGLEVEL >= 10) {
- for (i = 0; i < num_names; i++) {
+ for (i = 0; i < num_names; i++)
DEBUG(10, ("\t%20s %x %d\n", names[i], rid_mem[i],
name_types[i]));
- }
}
/* Add members to list */
@@ -103,7 +104,8 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
the_name = names[i];
- DEBUG(10, ("fill_grent_mem(): processing name %s\n", the_name));
+ DEBUG(10, ("fill_grent_mem(): processing name %s\n",
+ the_name));
/* Only add domain users */
@@ -151,7 +153,7 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
if (!(buf = malloc(buf_len))) {
DEBUG(1, ("fill_grent_mem(): out of memory\n"));
result = False;
- goto cleanup;
+ goto done;
}
memset(buf, 0, buf_len);
goto again;
@@ -169,14 +171,8 @@ static BOOL fill_grent_mem(struct winbindd_domain *domain,
result = True;
- cleanup:
-
- /* Free memory allocated in winbindd_lookup_groupmem() */
-
- SAFE_FREE(name_types);
- SAFE_FREE(rid_mem);
-
- free_char_array(num_names, names);
+done:
+ talloc_destroy(mem_ctx);
DEBUG(10, ("fill_grent_mem(): returning %d\n", result));
@@ -413,9 +409,11 @@ enum winbindd_result winbindd_setgrent(struct winbindd_cli_state *state)
ZERO_STRUCTP(domain_state);
+ domain_state->domain = tmp;
+ domain_state->mem_ctx = talloc_init();
+
/* Add to list of open domains */
- domain_state->domain = tmp;
DLIST_ADD(state->getgrent_state, domain_state);
}
@@ -475,7 +473,7 @@ static BOOL get_sam_group_entries(struct getent_state *ent)
break;
status = cli_samr_enum_dom_groups(
- hnd->cli, hnd->cli->mem_ctx, &hnd->pol,
+ hnd->cli, ent->mem_ctx, &hnd->pol,
&ent->grp_query_start_ndx,
0x8000, /* buffer size? */
(struct acct_info **) &sam_grp_entries, &num_entries);
@@ -764,6 +762,7 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
ZERO_STRUCT(groups);
groups.domain = domain;
+ groups.mem_ctx = talloc_init();
/*
* iterate through all groups
@@ -798,7 +797,7 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
/* skip remainder of loop if we idn;t retrieve any groups */
if (num_domain_entries == 0)
- continue;
+ goto next_group;
/* setup the groups struct to contain all the groups
retrieved for this domain */
@@ -820,6 +819,7 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
DEBUG(0,("winbindd_list_groups: failed to enlarge "
"buffer!\n"));
SAFE_FREE(extra_data);
+ talloc_destroy(groups.mem_ctx);
return WINBINDD_ERROR;
} else
extra_data = ted;
@@ -845,6 +845,9 @@ enum winbindd_result winbindd_list_groups(struct winbindd_cli_state *state)
extra_data[extra_data_len++] = ',';
}
+
+ next_group:
+ talloc_destroy(groups.mem_ctx);
}
/* Assign extra_data fields in response structure */
diff --git a/source3/nsswitch/winbindd_proto.h b/source3/nsswitch/winbindd_proto.h
index 46751553ac..f3ba2063ee 100644
--- a/source3/nsswitch/winbindd_proto.h
+++ b/source3/nsswitch/winbindd_proto.h
@@ -129,6 +129,7 @@ BOOL winbindd_lookup_usergroups(struct winbindd_domain *domain,
uint32 user_rid, uint32 *num_groups,
DOM_GID **user_groups);
BOOL winbindd_lookup_groupmem(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
uint32 group_rid, uint32 *num_names,
uint32 **rid_mem, char ***names,
uint32 **name_types);
@@ -137,6 +138,7 @@ struct winbindd_domain *find_domain_from_sid(DOM_SID *sid);
void free_getent_state(struct getent_state *state);
BOOL winbindd_param_init(void);
NTSTATUS winbindd_query_dispinfo(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
uint32 *start_ndx, uint16 info_level,
uint32 *num_entries, SAM_DISPINFO_CTR *ctr);
BOOL check_domain_env(char *domain_env, char *domain);
diff --git a/source3/nsswitch/winbindd_user.c b/source3/nsswitch/winbindd_user.c
index 845c787b2a..08a8973e94 100644
--- a/source3/nsswitch/winbindd_user.c
+++ b/source3/nsswitch/winbindd_user.c
@@ -33,9 +33,8 @@ static BOOL winbindd_fill_pwent(char *domain_name, char *name,
fstring name_domain, name_user;
pstring homedir;
- if (!pw || !name) {
+ if (!pw || !name)
return False;
- }
/* Resolve the uid number */
@@ -112,9 +111,8 @@ enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state
/* Reject names that don't have a domain - i.e name_domain contains
the entire name. */
- if (strequal(name_domain, "")) {
+ if (strequal(name_domain, ""))
return WINBINDD_ERROR;
- }
if ((domain = find_domain_from_name(name_domain)) == NULL) {
DEBUG(5, ("No such domain: %s\n", name_domain));
@@ -124,9 +122,8 @@ enum winbindd_result winbindd_getpwnam_from_user(struct winbindd_cli_state
/* Check for cached user entry */
if (winbindd_fetch_user_cache_entry(domain, name_user,
- &state->response.data.pw)) {
+ &state->response.data.pw))
return WINBINDD_OK;
- }
slprintf(name, sizeof(name) - 1, "%s\\%s", name_domain, name_user);
@@ -189,9 +186,8 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
/* Bug out if the uid isn't in the winbind range */
if ((state->request.data.uid < server_state.uid_low ) ||
- (state->request.data.uid > server_state.uid_high)) {
+ (state->request.data.uid > server_state.uid_high))
return WINBINDD_ERROR;
- }
DEBUG(3, ("[%5d]: getpwuid %d\n", state->pid,
state->request.data.uid));
@@ -209,9 +205,8 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
if (winbindd_fetch_uid_cache_entry(domain,
state->request.data.uid,
- &state->response.data.pw)) {
+ &state->response.data.pw))
return WINBINDD_OK;
- }
/* Get name and name type from rid */
@@ -223,13 +218,13 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
sid_to_string(temp, &user_sid);
DEBUG(1, ("Could not lookup sid %s\n", temp));
+
return WINBINDD_ERROR;
}
- if (strcmp("\\", lp_winbind_separator())) {
+ if (strcmp("\\", lp_winbind_separator()))
string_sub(user_name, "\\", lp_winbind_separator(),
sizeof(fstring));
- }
/* Get some user info */
@@ -253,9 +248,8 @@ enum winbindd_result winbindd_getpwnam_from_uid(struct winbindd_cli_state
/* Fill in password structure */
if (!winbindd_fill_pwent(domain->name, user_name, user_rid, group_rid,
- gecos_name, &state->response.data.pw)) {
+ gecos_name, &state->response.data.pw))
return WINBINDD_ERROR;
- }
winbindd_store_uid_cache_entry(domain, state->request.data.uid,
&state->response.data.pw);
@@ -306,7 +300,9 @@ enum winbindd_result winbindd_setpwent(struct winbindd_cli_state *state)
return WINBINDD_ERROR;
ZERO_STRUCTP(domain_state);
+
domain_state->domain = tmp;
+ domain_state->mem_ctx = talloc_init();
/* Add to list of open domains */
@@ -383,7 +379,7 @@ static BOOL get_sam_user_entries(struct getent_state *ent)
num_entries = 0;
- status = winbindd_query_dispinfo(ent->domain,
+ status = winbindd_query_dispinfo(ent->domain, ent->mem_ctx,
&ent->dispinfo_ndx, 1,
&num_entries, &ctr);
@@ -572,9 +568,14 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
uint32 num_entries = 0, total_entries = 0;
char *ted, *extra_data = NULL;
int extra_data_len = 0;
+ TALLOC_CTX *mem_ctx;
+ enum winbindd_result rv = WINBINDD_ERROR;
DEBUG(3, ("[%5d]: list users\n", state->pid));
+ if (!(mem_ctx = talloc_init()))
+ return WINBINDD_ERROR;
+
/* Enumerate over trusted domains */
ctr.sam.info1 = &info1;
@@ -587,22 +588,20 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
variable */
if ((strcmp(state->request.domain, "") != 0) &&
- !check_domain_env(state->request.domain, domain->name)) {
+ !check_domain_env(state->request.domain, domain->name))
continue;
- }
/* Query display info */
do {
int i;
- status = winbindd_query_dispinfo(domain, &start_ndx,
- 1, &num_entries,
- &ctr);
+ status = winbindd_query_dispinfo(
+ domain, mem_ctx, &start_ndx,
+ 1, &num_entries, &ctr);
- if (num_entries == 0) {
+ if (num_entries == 0)
continue;
- }
/* Allocate some memory for extra data */
@@ -614,9 +613,9 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
if (!ted) {
DEBUG(0,("winbindd_list_users: failed to enlarge buffer!\n"));
SAFE_FREE(extra_data);
- return WINBINDD_ERROR;
- }
- else extra_data = ted;
+ goto done;
+ } else
+ extra_data = ted;
/* Pack user list into extra data fields */
@@ -657,5 +656,10 @@ enum winbindd_result winbindd_list_users(struct winbindd_cli_state *state)
/* No domains responded but that's still OK so don't return an
error. */
- return WINBINDD_OK;
+ rv = WINBINDD_OK;
+
+ done:
+ talloc_destroy(mem_ctx);
+
+ return rv;
}
diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c
index 859b0850dc..0e0493e57f 100644
--- a/source3/nsswitch/winbindd_util.c
+++ b/source3/nsswitch/winbindd_util.c
@@ -72,12 +72,12 @@ BOOL get_domain_info(void)
int i;
fstring level5_dom;
BOOL rv = False;
- TALLOC_CTX *mem_ctx = NULL;
+ TALLOC_CTX *mem_ctx;
DEBUG(1, ("getting trusted domain list\n"));
if (!(mem_ctx = talloc_init()))
- goto done;
+ return False;
/* Add our workgroup - keep handle to look up trusted domains */
@@ -113,8 +113,7 @@ BOOL get_domain_info(void)
rv = True;
done:
- if (mem_ctx)
- talloc_destroy(mem_ctx);
+ talloc_destroy(mem_ctx);
return rv;
}
@@ -131,7 +130,7 @@ BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain)
CLI_POLICY_HND *hnd;
NTSTATUS result;
BOOL rv = False;
- TALLOC_CTX *mem_ctx = NULL;
+ TALLOC_CTX *mem_ctx;
DEBUG(1, ("looking up sid for domain %s\n", domain_name));
@@ -180,8 +179,7 @@ BOOL lookup_domain_sid(char *domain_name, struct winbindd_domain *domain)
rv = False; /* An error occured with a trusted domain */
done:
- if (mem_ctx)
- talloc_destroy(mem_ctx);
+ talloc_destroy(mem_ctx);
return rv;
}
@@ -196,7 +194,7 @@ BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid,
uint32 *types = NULL;
CLI_POLICY_HND *hnd;
NTSTATUS result;
- TALLOC_CTX *mem_ctx = NULL;
+ TALLOC_CTX *mem_ctx;
BOOL rv = False;
/* Don't bother with machine accounts */
@@ -234,8 +232,7 @@ BOOL winbindd_lookup_sid_by_name(char *name, DOM_SID *sid,
rv = NT_STATUS_IS_OK(result);
done:
- if (mem_ctx)
- talloc_destroy(mem_ctx);
+ talloc_destroy(mem_ctx);
return rv;
}
@@ -256,7 +253,7 @@ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, fstring name,
/* Lookup name */
if (!(mem_ctx = talloc_init()))
- goto done;
+ return False;
if (!(hnd = cm_get_lsa_handle(lp_workgroup())))
goto done;
@@ -283,8 +280,7 @@ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, fstring name,
rv = NT_STATUS_IS_OK(result);
done:
- if (mem_ctx)
- talloc_destroy(mem_ctx);
+ talloc_destroy(mem_ctx);
return rv;
}
@@ -294,16 +290,23 @@ BOOL winbindd_lookup_name_by_sid(DOM_SID *sid, fstring name,
BOOL winbindd_lookup_userinfo(struct winbindd_domain *domain, uint32 user_rid,
SAM_USERINFO_CTR **user_info)
{
+ TALLOC_CTX *mem_ctx;
CLI_POLICY_HND *hnd;
uint16 info_level = 0x15;
- NTSTATUS result;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ if (!(mem_ctx = talloc_init()))
+ return False;
if (!(hnd = cm_get_sam_user_handle(domain->name, &domain->sid,
user_rid)))
- return False;
+ goto done;
- result = cli_samr_query_userinfo(hnd->cli, hnd->cli->mem_ctx,
- &hnd->pol, info_level, user_info);
+ result = cli_samr_query_userinfo(hnd->cli, mem_ctx, &hnd->pol,
+ info_level, user_info);
+
+ done:
+ talloc_destroy(mem_ctx);
return NT_STATUS_IS_OK(result);
}
@@ -314,16 +317,22 @@ BOOL winbindd_lookup_usergroups(struct winbindd_domain *domain,
uint32 user_rid, uint32 *num_groups,
DOM_GID **user_groups)
{
+ TALLOC_CTX *mem_ctx;
CLI_POLICY_HND *hnd;
- NTSTATUS result;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+
+ if (!(mem_ctx = talloc_init()))
+ return False;
if (!(hnd = cm_get_sam_user_handle(domain->name, &domain->sid,
user_rid)))
- return False;
+ goto done;
+
+ result = cli_samr_query_usergroups(hnd->cli, mem_ctx, &hnd->pol,
+ num_groups, user_groups);
- result = cli_samr_query_usergroups(hnd->cli, hnd->cli->mem_ctx,
- &hnd->pol, num_groups,
- user_groups);
+ done:
+ talloc_destroy(mem_ctx);
return NT_STATUS_IS_OK(result);
}
@@ -331,40 +340,39 @@ BOOL winbindd_lookup_usergroups(struct winbindd_domain *domain,
/* Lookup group membership given a rid. */
BOOL winbindd_lookup_groupmem(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
uint32 group_rid, uint32 *num_names,
uint32 **rid_mem, char ***names,
uint32 **name_types)
{
CLI_POLICY_HND *group_hnd, *dom_hnd;
- NTSTATUS result;
+ NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
uint32 i, total_names = 0;
if (!(group_hnd = cm_get_sam_group_handle(domain->name, &domain->sid,
group_rid)))
- return False;
+ goto done;
/* Get group membership. This is a list of rids. */
- result = cli_samr_query_groupmem(group_hnd->cli,
- group_hnd->cli->mem_ctx,
+ result = cli_samr_query_groupmem(group_hnd->cli, mem_ctx,
&group_hnd->pol, num_names, rid_mem,
name_types);
if (!NT_STATUS_IS_OK(result))
- return NT_STATUS_IS_OK(result);
+ goto done;
/* Convert list of rids into list of names. Do this in bunches of
~1000 to avoid crashing NT4. It looks like there is a buffer
overflow or something like that lurking around somewhere. */
if (!(dom_hnd = cm_get_sam_dom_handle(domain->name, &domain->sid)))
- return False;
+ goto done;
#define MAX_LOOKUP_RIDS 900
- *names = talloc(dom_hnd->cli->mem_ctx, *num_names * sizeof(char *));
- *name_types = talloc(dom_hnd->cli->mem_ctx, *num_names *
- sizeof(uint32));
+ *names = talloc(mem_ctx, *num_names * sizeof(char *));
+ *name_types = talloc(mem_ctx, *num_names * sizeof(uint32));
for (i = 0; i < *num_names; i += MAX_LOOKUP_RIDS) {
int num_lookup_rids = MIN(*num_names - i, MAX_LOOKUP_RIDS);
@@ -374,8 +382,7 @@ BOOL winbindd_lookup_groupmem(struct winbindd_domain *domain,
/* Lookup a chunk of rids */
- result = cli_samr_lookup_rids(dom_hnd->cli,
- dom_hnd->cli->mem_ctx,
+ result = cli_samr_lookup_rids(dom_hnd->cli, mem_ctx,
&dom_hnd->pol, 1000, /* flags */
num_lookup_rids,
&(*rid_mem)[i],
@@ -383,7 +390,7 @@ BOOL winbindd_lookup_groupmem(struct winbindd_domain *domain,
&tmp_names, &tmp_types);
if (!NT_STATUS_IS_OK(result))
- return False;
+ goto done;
/* Copy result into array. The talloc system will take
care of freeing the temporary arrays later on. */
@@ -399,6 +406,7 @@ BOOL winbindd_lookup_groupmem(struct winbindd_domain *domain,
*num_names = total_names;
+ done:
return NT_STATUS_IS_OK(result);
}
@@ -462,6 +470,8 @@ void free_getent_state(struct getent_state *state)
DLIST_REMOVE(state, state);
next = temp->next;
+ talloc_destroy(temp->mem_ctx);
+
SAFE_FREE(temp);
temp = next;
}
@@ -531,6 +541,7 @@ BOOL winbindd_param_init(void)
application. */
NTSTATUS winbindd_query_dispinfo(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
uint32 *start_ndx, uint16 info_level,
uint32 *num_entries, SAM_DISPINFO_CTR *ctr)
{
@@ -538,16 +549,14 @@ NTSTATUS winbindd_query_dispinfo(struct winbindd_domain *domain,
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
if (!(hnd = cm_get_sam_dom_handle(domain->name, &domain->sid)))
- return result;
+ goto done;
- result = cli_samr_query_dispinfo(hnd->cli, hnd->cli->mem_ctx,
+ result = cli_samr_query_dispinfo(hnd->cli, mem_ctx,
&hnd->pol, start_ndx, info_level,
num_entries, 0xffff, ctr);
- if (!NT_STATUS_IS_OK(result))
- return result;
-
- return NT_STATUS_OK;
+ done:
+ return result;
}
/* Check if a domain is present in a comma-separated list of domains */