diff options
author | Jeremy Allison <jra@samba.org> | 2006-12-09 02:58:18 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:16:24 -0500 |
commit | 63609fbb04d2ce620338b4b79e7c1abf39f08ef8 (patch) | |
tree | c036fe84a97efbee490c470051cf1de360d502d3 /source3/nsswitch | |
parent | 19ddef3dd9065b04896c626e7b4c691c7bbbec53 (diff) | |
download | samba-63609fbb04d2ce620338b4b79e7c1abf39f08ef8.tar.gz samba-63609fbb04d2ce620338b4b79e7c1abf39f08ef8.tar.bz2 samba-63609fbb04d2ce620338b4b79e7c1abf39f08ef8.zip |
r20090: Fix a class of bugs found by James Peach. Ensure
we never mix malloc and talloc'ed contexts in the
add_XX_to_array() and add_XX_to_array_unique()
calls. Ensure that these calls always return
False on out of memory, True otherwise and always
check them. Ensure that the relevent parts of
the conn struct and the nt_user_tokens are
TALLOC_DESTROYED not SAFE_FREE'd.
James - this should fix your crash bug in both
branches.
Jeremy.
(This used to be commit 0ffca7559e07500bd09a64b775e230d448ce5c24)
Diffstat (limited to 'source3/nsswitch')
-rw-r--r-- | source3/nsswitch/winbindd_ads.c | 36 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_async.c | 27 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_cm.c | 38 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_group.c | 9 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_rpc.c | 6 | ||||
-rw-r--r-- | source3/nsswitch/winbindd_util.c | 12 |
6 files changed, 93 insertions, 35 deletions
diff --git a/source3/nsswitch/winbindd_ads.c b/source3/nsswitch/winbindd_ads.c index 113f14a3b7..ad24b87a90 100644 --- a/source3/nsswitch/winbindd_ads.c +++ b/source3/nsswitch/winbindd_ads.c @@ -592,7 +592,10 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain, num_groups = 0; /* always add the primary group to the sid array */ - add_sid_to_array(mem_ctx, primary_group, user_sids, &num_groups); + if (!add_sid_to_array(mem_ctx, primary_group, user_sids, &num_groups)) { + status = NT_STATUS_NO_MEMORY; + goto done; + } if (count > 0) { for (msg = ads_first_entry(ads, res); msg; @@ -609,8 +612,11 @@ static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain, continue; } - add_sid_to_array(mem_ctx, &group_sid, user_sids, - &num_groups); + if (!add_sid_to_array(mem_ctx, &group_sid, user_sids, + &num_groups)) { + status = NT_STATUS_NO_MEMORY; + goto done; + } } } @@ -673,7 +679,10 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain, num_groups = 0; /* always add the primary group to the sid array */ - add_sid_to_array(mem_ctx, primary_group, user_sids, &num_groups); + if (!add_sid_to_array(mem_ctx, primary_group, user_sids, &num_groups)) { + status = NT_STATUS_NO_MEMORY; + goto done; + } count = ads_pull_sids_from_extendeddn(ads, mem_ctx, res, "memberOf", ADS_EXTENDED_DN_HEX_STRING, @@ -691,8 +700,11 @@ static NTSTATUS lookup_usergroups_memberof(struct winbindd_domain *domain, continue; } - add_sid_to_array(mem_ctx, &group_sids[i], user_sids, - &num_groups); + if (!add_sid_to_array(mem_ctx, &group_sids[i], user_sids, + &num_groups)) { + status = NT_STATUS_NO_MEMORY; + goto done; + } } @@ -822,7 +834,10 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, *user_sids = NULL; num_groups = 0; - add_sid_to_array(mem_ctx, &primary_group, user_sids, &num_groups); + if (!add_sid_to_array(mem_ctx, &primary_group, user_sids, &num_groups)) { + status = NT_STATUS_NO_MEMORY; + goto done; + } for (i=0;i<count;i++) { @@ -831,8 +846,11 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, continue; } - add_sid_to_array_unique(mem_ctx, &sids[i], - user_sids, &num_groups); + if (!add_sid_to_array_unique(mem_ctx, &sids[i], + user_sids, &num_groups)) { + status = NT_STATUS_NO_MEMORY; + goto done; + } } *p_num_groups = (uint32)num_groups; diff --git a/source3/nsswitch/winbindd_async.c b/source3/nsswitch/winbindd_async.c index 4021106516..607a9947ea 100644 --- a/source3/nsswitch/winbindd_async.c +++ b/source3/nsswitch/winbindd_async.c @@ -774,7 +774,9 @@ static BOOL parse_sidlist(TALLOC_CTX *mem_ctx, char *sidstr, DEBUG(0, ("Could not parse sid %s\n", p)); return False; } - add_sid_to_array(mem_ctx, &sid, sids, num_sids); + if (!add_sid_to_array(mem_ctx, &sid, sids, num_sids)) { + return False; + } p = q; } return True; @@ -985,7 +987,9 @@ enum winbindd_result winbindd_dual_getsidaliases(struct winbindd_domain *domain, DEBUGADD(10, (" rid %d\n", alias_rids[i])); sid_copy(&sid, &domain->sid); sid_append_rid(&sid, alias_rids[i]); - add_sid_to_array(state->mem_ctx, &sid, &sids, &num_sids); + if (!add_sid_to_array(state->mem_ctx, &sid, &sids, &num_sids)) { + return WINBINDD_ERROR; + } } @@ -1096,8 +1100,12 @@ static void gettoken_recvdomgroups(TALLOC_CTX *mem_ctx, BOOL success, state->sids = NULL; state->num_sids = 0; - add_sid_to_array(mem_ctx, &state->user_sid, &state->sids, - &state->num_sids); + if (!add_sid_to_array(mem_ctx, &state->user_sid, &state->sids, + &state->num_sids)) { + DEBUG(0, ("Out of memory\n")); + state->cont(state->private_data, False, NULL, 0); + return; + } if (sids_str && !parse_sidlist(mem_ctx, sids_str, &state->sids, &state->num_sids)) { @@ -1133,9 +1141,14 @@ static void gettoken_recvaliases(void *private_data, BOOL success, return; } - for (i=0; i<num_aliases; i++) - add_sid_to_array(state->mem_ctx, &aliases[i], - &state->sids, &state->num_sids); + for (i=0; i<num_aliases; i++) { + if (!add_sid_to_array(state->mem_ctx, &aliases[i], + &state->sids, &state->num_sids)) { + DEBUG(0, ("Out of memory\n")); + state->cont(state->private_data, False, NULL, 0); + return; + } + } if (state->local_alias_domain != NULL) { struct winbindd_domain *local_domain = state->local_alias_domain; diff --git a/source3/nsswitch/winbindd_cm.c b/source3/nsswitch/winbindd_cm.c index 330ba4ca9b..2c341d5efa 100644 --- a/source3/nsswitch/winbindd_cm.c +++ b/source3/nsswitch/winbindd_cm.c @@ -692,8 +692,10 @@ static BOOL add_sockaddr_to_array(TALLOC_CTX *mem_ctx, { *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_in, (*num)+1); - if (*addrs == NULL) + if (*addrs == NULL) { + *num = 0; return False; + } (*addrs)[*num].sin_family = PF_INET; putip((char *)&((*addrs)[*num].sin_addr), (char *)&ip); @@ -987,15 +989,23 @@ static BOOL find_new_dc(TALLOC_CTX *mem_ctx, for (i=0; i<num_dcs; i++) { - add_string_to_array(mem_ctx, dcs[i].name, - &dcnames, &num_dcnames); - add_sockaddr_to_array(mem_ctx, dcs[i].ip, 445, - &addrs, &num_addrs); + if (!add_string_to_array(mem_ctx, dcs[i].name, + &dcnames, &num_dcnames)) { + return False; + } + if (!add_sockaddr_to_array(mem_ctx, dcs[i].ip, 445, + &addrs, &num_addrs)) { + return False; + } - add_string_to_array(mem_ctx, dcs[i].name, - &dcnames, &num_dcnames); - add_sockaddr_to_array(mem_ctx, dcs[i].ip, 139, - &addrs, &num_addrs); + if (!add_string_to_array(mem_ctx, dcs[i].name, + &dcnames, &num_dcnames)) { + return False; + } + if (!add_sockaddr_to_array(mem_ctx, dcs[i].ip, 139, + &addrs, &num_addrs)) { + return False; + } } if ((num_dcnames == 0) || (num_dcnames != num_addrs)) @@ -1102,8 +1112,14 @@ static NTSTATUS cm_open_connection(struct winbindd_domain *domain, int num_addrs = 0; int dummy = 0; - add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 445, &addrs, &num_addrs); - add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 139, &addrs, &num_addrs); + if (!add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 445, &addrs, &num_addrs)) { + set_domain_offline(domain); + return NT_STATUS_NO_MEMORY; + } + if (!add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 139, &addrs, &num_addrs)) { + set_domain_offline(domain); + return NT_STATUS_NO_MEMORY; + } /* 5 second timeout. */ if (!open_any_socket_out(addrs, num_addrs, 5000, &dummy, &fd)) { diff --git a/source3/nsswitch/winbindd_group.c b/source3/nsswitch/winbindd_group.c index 7feaadbf97..aac8a9aac3 100644 --- a/source3/nsswitch/winbindd_group.c +++ b/source3/nsswitch/winbindd_group.c @@ -1230,10 +1230,13 @@ static void getgroups_sid2gid_recv(void *private_data, BOOL success, gid_t gid) struct getgroups_state *s = (struct getgroups_state *)private_data; - if (success) - add_gid_to_array_unique(NULL, gid, + if (success) { + if (!add_gid_to_array_unique(NULL, gid, &s->token_gids, - &s->num_token_gids); + &s->num_token_gids)) { + return; + } + } if (s->i < s->num_token_sids) { const DOM_SID *sid = &s->token_sids[s->i]; diff --git a/source3/nsswitch/winbindd_rpc.c b/source3/nsswitch/winbindd_rpc.c index 2e2b895352..08fe129db0 100644 --- a/source3/nsswitch/winbindd_rpc.c +++ b/source3/nsswitch/winbindd_rpc.c @@ -580,8 +580,10 @@ NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain, for (i=0; i<num_aliases_query; i++) { size_t na = *num_aliases; - add_rid_to_array_unique(mem_ctx, alias_rids_query[i], - alias_rids, &na); + if (!add_rid_to_array_unique(mem_ctx, alias_rids_query[i], + alias_rids, &na)) { + return NT_STATUS_NO_MEMORY; + } *num_aliases = na; } diff --git a/source3/nsswitch/winbindd_util.c b/source3/nsswitch/winbindd_util.c index 98990664e3..c9f3a39641 100644 --- a/source3/nsswitch/winbindd_util.c +++ b/source3/nsswitch/winbindd_util.c @@ -1261,14 +1261,20 @@ NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain, /* always add the primary group to the sid array */ sid_compose(&primary_group, &info3->dom_sid.sid, info3->user_rid); - add_sid_to_array(mem_ctx, &primary_group, user_sids, &num_groups); + if (!add_sid_to_array(mem_ctx, &primary_group, user_sids, &num_groups)) { + SAFE_FREE(info3); + return NT_STATUS_NO_MEMORY; + } for (i=0; i<info3->num_groups; i++) { sid_copy(&group_sid, &info3->dom_sid.sid); sid_append_rid(&group_sid, info3->gids[i].g_rid); - add_sid_to_array(mem_ctx, &group_sid, user_sids, - &num_groups); + if (!add_sid_to_array(mem_ctx, &group_sid, user_sids, + &num_groups)) { + SAFE_FREE(info3); + return NT_STATUS_NO_MEMORY; + } } SAFE_FREE(info3); |