From 52995a5f7d48d41b07ee9fab20903a685c0dd33b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 19 Oct 2001 01:46:43 +0000 Subject: [PATCH] Converted some more functions to create and dispose of a talloc context on a per-call basis rather than per-connection. Had a bit more of a reformatting fest. Still need to run it through insure and handle downed connections. (This used to be commit 46fe5a8fb96974e1323bc3e5d94fda74edbeb852) --- source3/nsswitch/winbindd.h | 1 + source3/nsswitch/winbindd_group.c | 45 ++++++++-------- source3/nsswitch/winbindd_proto.h | 2 + source3/nsswitch/winbindd_user.c | 56 ++++++++++--------- source3/nsswitch/winbindd_util.c | 89 +++++++++++++++++-------------- 5 files changed, 106 insertions(+), 87 deletions(-) diff --git a/source3/nsswitch/winbindd.h b/source3/nsswitch/winbindd.h index a9035ca2003..659789a9206 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 893302716f0..b526feb780f 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 46751553acb..f3ba2063ee9 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 845c787b2a2..08a8973e944 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 859b0850dca..0e0493e57f8 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 */ -- 2.34.1