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 | |
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)
-rw-r--r-- | source3/auth/auth_util.c | 117 | ||||
-rw-r--r-- | source3/groupdb/mapping.c | 2 | ||||
-rw-r--r-- | source3/groupdb/mapping_ldb.c | 6 | ||||
-rw-r--r-- | source3/groupdb/mapping_tdb.c | 10 | ||||
-rw-r--r-- | source3/lib/privileges.c | 4 | ||||
-rw-r--r-- | source3/lib/system_smbd.c | 15 | ||||
-rw-r--r-- | source3/lib/util.c | 36 | ||||
-rw-r--r-- | source3/lib/util_sid.c | 31 | ||||
-rw-r--r-- | source3/lib/util_str.c | 4 | ||||
-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 | ||||
-rw-r--r-- | source3/passdb/pdb_interface.c | 30 | ||||
-rw-r--r-- | source3/passdb/pdb_ldap.c | 51 | ||||
-rw-r--r-- | source3/rpcclient/cmd_samr.c | 4 | ||||
-rw-r--r-- | source3/smbd/conn.c | 2 | ||||
-rw-r--r-- | source3/smbd/service.c | 9 |
20 files changed, 290 insertions, 159 deletions
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index e066ba279c..7e65121b2d 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -605,8 +605,12 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, "for gid %d!\n", gids[i])); continue; } - add_sid_to_array_unique( result, &unix_group_sid, - &result->sids, &result->num_sids ); + if (!add_sid_to_array_unique( result, &unix_group_sid, + &result->sids, &result->num_sids )) { + result->sam_account = NULL; /* Don't free on error exit. */ + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } } /* For now we throw away the gids and convert via sid_to_gid @@ -657,10 +661,9 @@ static NTSTATUS add_aliases(const DOM_SID *domain_sid, for (i=0; i<num_aliases; i++) { DOM_SID alias_sid; sid_compose(&alias_sid, domain_sid, aliases[i]); - add_sid_to_array_unique(token, &alias_sid, + if (!add_sid_to_array_unique(token, &alias_sid, &token->user_sids, - &token->num_sids); - if (token->user_sids == NULL) { + &token->num_sids)) { DEBUG(0, ("add_sid_to_array failed\n")); TALLOC_FREE(tmp_ctx); return NT_STATUS_NO_MEMORY; @@ -733,8 +736,10 @@ static NTSTATUS add_builtin_administrators( struct nt_user_token *token ) /* Add Administrators if the user beloongs to Domain Admins */ if ( nt_token_check_sid( &domadm, token ) ) { - add_sid_to_array(token, &global_sid_Builtin_Administrators, - &token->user_sids, &token->num_sids); + if (!add_sid_to_array(token, &global_sid_Builtin_Administrators, + &token->user_sids, &token->num_sids)) { + return NT_STATUS_NO_MEMORY; + } } return NT_STATUS_OK; @@ -843,28 +848,40 @@ static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx, /* Add the user and primary group sid */ - add_sid_to_array(result, user_sid, - &result->user_sids, &result->num_sids); + if (!add_sid_to_array(result, user_sid, + &result->user_sids, &result->num_sids)) { + return NULL; + } /* For guest, num_groupsids may be zero. */ if (num_groupsids) { - add_sid_to_array(result, &groupsids[0], - &result->user_sids, &result->num_sids); + if (!add_sid_to_array(result, &groupsids[0], + &result->user_sids, &result->num_sids)) { + return NULL; + } } /* Add in BUILTIN sids */ - add_sid_to_array(result, &global_sid_World, - &result->user_sids, &result->num_sids); - add_sid_to_array(result, &global_sid_Network, - &result->user_sids, &result->num_sids); + if (!add_sid_to_array(result, &global_sid_World, + &result->user_sids, &result->num_sids)) { + return NULL; + } + if (!add_sid_to_array(result, &global_sid_Network, + &result->user_sids, &result->num_sids)) { + return NULL; + } if (is_guest) { - add_sid_to_array(result, &global_sid_Builtin_Guests, - &result->user_sids, &result->num_sids); + if (!add_sid_to_array(result, &global_sid_Builtin_Guests, + &result->user_sids, &result->num_sids)) { + return NULL; + } } else { - add_sid_to_array(result, &global_sid_Authenticated_Users, - &result->user_sids, &result->num_sids); + if (!add_sid_to_array(result, &global_sid_Authenticated_Users, + &result->user_sids, &result->num_sids)) { + return NULL; + } } /* Now the SIDs we got from authentication. These are the ones from @@ -874,8 +891,10 @@ static struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx, * first group sid as primary above. */ for (i=1; i<num_groupsids; i++) { - add_sid_to_array_unique(result, &groupsids[i], - &result->user_sids, &result->num_sids); + if (!add_sid_to_array_unique(result, &groupsids[i], + &result->user_sids, &result->num_sids)) { + return NULL; + } } /* Deal with the BUILTIN\Administrators group. If the SID can @@ -1018,8 +1037,11 @@ NTSTATUS create_local_token(auth_serversupplied_info *server_info) "ignoring it\n", sid_string_static(sid))); continue; } - add_gid_to_array_unique(server_info, gid, &server_info->groups, - &server_info->n_groups); + if (!add_gid_to_array_unique(server_info, gid, &server_info->groups, + &server_info->n_groups)) { + TALLOC_FREE(mem_ctx); + return NT_STATUS_NO_MEMORY; + } } debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok); @@ -1060,7 +1082,6 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username, DOM_SID user_sid; enum lsa_SidType type; gid_t *gids; - DOM_SID primary_group_sid; DOM_SID *group_sids; DOM_SID unix_group_sid; size_t num_group_sids; @@ -1109,7 +1130,7 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username, goto unix_user; } - result = pdb_enum_group_memberships(tmp_ctx, sam_acct, + result = pdb_enum_group_memberships(mem_ctx, sam_acct, &group_sids, &gids, &num_group_sids); if (!NT_STATUS_IS_OK(result)) { @@ -1157,7 +1178,8 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username, goto done; } - group_sids = talloc_array(tmp_ctx, DOM_SID, num_group_sids); + /* group_sids can be realloced - must be done on mem_ctx not tmp_ctx. */ + group_sids = talloc_array(mem_ctx, DOM_SID, num_group_sids); if (group_sids == NULL) { DEBUG(1, ("talloc_array failed\n")); result = NT_STATUS_NO_MEMORY; @@ -1185,18 +1207,24 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username, uint32 dummy; - sid_copy(&primary_group_sid, &user_sid); - sid_split_rid(&primary_group_sid, &dummy); - sid_append_rid(&primary_group_sid, DOMAIN_GROUP_RID_USERS); + num_group_sids = 1; + group_sids = talloc_array(mem_ctx, DOM_SID, num_group_sids); + if (group_sids == NULL) { + DEBUG(1, ("talloc_array failed\n")); + result = NT_STATUS_NO_MEMORY; + goto done; + } + + sid_copy(&group_sids[0], &user_sid); + sid_split_rid(&group_sids[0], &dummy); + sid_append_rid(&group_sids[0], DOMAIN_GROUP_RID_USERS); - if (!sid_to_gid(&primary_group_sid, gid)) { + if (!sid_to_gid(&group_sids[0], gid)) { DEBUG(1, ("sid_to_gid(%s) failed\n", - sid_string_static(&primary_group_sid))); + sid_string_static(&group_sids[0]))); goto done; } - num_group_sids = 1; - group_sids = &primary_group_sid; gids = gid; *found_username = talloc_strdup(mem_ctx, username); @@ -1223,8 +1251,11 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username, "for gid %d!\n", gids[i])); continue; } - add_sid_to_array_unique( mem_ctx, &unix_group_sid, - &group_sids, &num_group_sids ); + if (!add_sid_to_array_unique( mem_ctx, &unix_group_sid, + &group_sids, &num_group_sids )) { + result = NT_STATUS_NO_MEMORY; + goto done; + } } *token = create_local_nt_token(mem_ctx, &user_sid, @@ -1869,8 +1900,11 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, TALLOC_FREE(result); return NT_STATUS_INVALID_PARAMETER; } - add_sid_to_array(result, &sid, &result->sids, - &result->num_sids); + if (!add_sid_to_array(result, &sid, &result->sids, + &result->num_sids)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } } /* Copy 'other' sids. We need to do sid filtering here to @@ -1880,9 +1914,12 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, */ for (i = 0; i < info3->num_other_sids; i++) { - add_sid_to_array(result, &info3->other_sids[i].sid, - &result->sids, - &result->num_sids); + if (!add_sid_to_array(result, &info3->other_sids[i].sid, + &result->sids, + &result->num_sids)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } } result->login_server = unistr2_tdup(result, diff --git a/source3/groupdb/mapping.c b/source3/groupdb/mapping.c index ba1a7d1dee..54cffd1588 100644 --- a/source3/groupdb/mapping.c +++ b/source3/groupdb/mapping.c @@ -591,7 +591,7 @@ NTSTATUS pdb_default_alias_memberships(struct pdb_methods *methods, *p_num_alias_rids += 1; } - SAFE_FREE(alias_sids); + TALLOC_FREE(alias_sids); return NT_STATUS_OK; } diff --git a/source3/groupdb/mapping_ldb.c b/source3/groupdb/mapping_ldb.c index 29d5b49edf..a743c2456e 100644 --- a/source3/groupdb/mapping_ldb.c +++ b/source3/groupdb/mapping_ldb.c @@ -423,8 +423,7 @@ failed: goto failed; } string_to_sid(&alias, (char *)el->values[0].data); - add_sid_to_array_unique(NULL, &alias, sids, num); - if (sids == NULL) { + if (!add_sid_to_array_unique(NULL, &alias, sids, num)) { status = NT_STATUS_NO_MEMORY; goto failed; } @@ -558,8 +557,7 @@ static NTSTATUS modify_aliasmem(const DOM_SID *alias, const DOM_SID *member, for (i=0;i<el->num_values;i++) { DOM_SID sid; string_to_sid(&sid, (const char *)el->values[i].data); - add_sid_to_array_unique(NULL, &sid, sids, num); - if (sids == NULL) { + if (!add_sid_to_array_unique(NULL, &sid, sids, num)) { talloc_free(dn); return NT_STATUS_NO_MEMORY; } diff --git a/source3/groupdb/mapping_tdb.c b/source3/groupdb/mapping_tdb.c index 12b7c682fb..cff557ff13 100644 --- a/source3/groupdb/mapping_tdb.c +++ b/source3/groupdb/mapping_tdb.c @@ -429,10 +429,9 @@ BOOL enum_group_mapping(const DOM_SID *domsid, enum lsa_SidType sid_name_use, GR if (!string_to_sid(&alias, string_sid)) continue; - add_sid_to_array_unique(NULL, &alias, sids, num); - - if (sids == NULL) + if (!add_sid_to_array_unique(NULL, &alias, sids, num)) { return NT_STATUS_NO_MEMORY; + } } SAFE_FREE(dbuf.dptr); @@ -577,7 +576,10 @@ static int collect_aliasmem(TDB_CONTEXT *tdb_ctx, TDB_DATA key, TDB_DATA data, if (!string_to_sid(&member, member_string)) continue; - add_sid_to_array(NULL, &member, closure->sids, closure->num); + if (!add_sid_to_array(NULL, &member, closure->sids, closure->num)) { + /* talloc fail. */ + break; + } } return 0; diff --git a/source3/lib/privileges.c b/source3/lib/privileges.c index 32535394c7..c0f7857c95 100644 --- a/source3/lib/privileges.c +++ b/source3/lib/privileges.c @@ -517,7 +517,9 @@ static int priv_traverse_fn(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *s return 0; } - add_sid_to_array( NULL, &sid, &priv->sids.list, &priv->sids.count ); + if (!add_sid_to_array( NULL, &sid, &priv->sids.list, &priv->sids.count )) { + return 0; + } return 0; } diff --git a/source3/lib/system_smbd.c b/source3/lib/system_smbd.c index fc506c901d..509b2bbcb1 100644 --- a/source3/lib/system_smbd.c +++ b/source3/lib/system_smbd.c @@ -181,11 +181,18 @@ BOOL getgroups_unix_user(TALLOC_CTX *mem_ctx, const char *user, groups = NULL; /* Add in primary group first */ - add_gid_to_array_unique(mem_ctx, primary_gid, &groups, &ngrp); + if (!add_gid_to_array_unique(mem_ctx, primary_gid, &groups, &ngrp)) { + SAFE_FREE(temp_groups); + return False; + } - for (i=0; i<max_grp; i++) - add_gid_to_array_unique(mem_ctx, temp_groups[i], - &groups, &ngrp); + for (i=0; i<max_grp; i++) { + if (!add_gid_to_array_unique(mem_ctx, temp_groups[i], + &groups, &ngrp)) { + SAFE_FREE(temp_groups); + return False; + } + } *p_ngroups = ngrp; *ret_groups = groups; diff --git a/source3/lib/util.c b/source3/lib/util.c index 19c6cab5b2..d1801527e9 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -307,7 +307,7 @@ const char *tmpdir(void) Add a gid to an array of gids if it's not already there. ****************************************************************************/ -void add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid, +BOOL add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid, gid_t **gids, size_t *num_gids) { int i; @@ -316,26 +316,24 @@ void add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid, /* * A former call to this routine has failed to allocate memory */ - return; + return False; } for (i=0; i<*num_gids; i++) { - if ((*gids)[i] == gid) - return; - } - - if (mem_ctx != NULL) { - *gids = TALLOC_REALLOC_ARRAY(mem_ctx, *gids, gid_t, *num_gids+1); - } else { - *gids = SMB_REALLOC_ARRAY(*gids, gid_t, *num_gids+1); + if ((*gids)[i] == gid) { + return True; + } } + *gids = TALLOC_REALLOC_ARRAY(mem_ctx, *gids, gid_t, *num_gids+1); if (*gids == NULL) { - return; + *num_gids = 0; + return False; } (*gids)[*num_gids] = gid; *num_gids += 1; + return True; } /**************************************************************************** @@ -1077,12 +1075,7 @@ void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size, goto error; } - if (mem_ctx != NULL) { - *array = TALLOC(mem_ctx, element_size * (*array_size)); - } else { - *array = SMB_MALLOC(element_size * (*array_size)); - } - + *array = TALLOC(mem_ctx, element_size * (*array_size)); if (*array == NULL) { goto error; } @@ -1095,13 +1088,8 @@ void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size, goto error; } - if (mem_ctx != NULL) { - *array = TALLOC_REALLOC(mem_ctx, *array, - element_size * (*array_size)); - } else { - *array = SMB_REALLOC(*array, - element_size * (*array_size)); - } + *array = TALLOC_REALLOC(mem_ctx, *array, + element_size * (*array_size)); if (*array == NULL) { goto error; diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index b6952fca81..032be9aa93 100644 --- a/source3/lib/util_sid.c +++ b/source3/lib/util_sid.c @@ -580,24 +580,20 @@ DOM_SID *sid_dup_talloc(TALLOC_CTX *ctx, const DOM_SID *src) Add SID to an array SIDs ********************************************************************/ -void add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid, +BOOL add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid, DOM_SID **sids, size_t *num) { - if (mem_ctx != NULL) { - *sids = TALLOC_REALLOC_ARRAY(mem_ctx, *sids, DOM_SID, + *sids = TALLOC_REALLOC_ARRAY(mem_ctx, *sids, DOM_SID, (*num)+1); - } else { - *sids = SMB_REALLOC_ARRAY(*sids, DOM_SID, (*num)+1); - } - if (*sids == NULL) { - return; + *num = 0; + return False; } sid_copy(&((*sids)[*num]), sid); *num += 1; - return; + return True; } @@ -605,17 +601,17 @@ void add_sid_to_array(TALLOC_CTX *mem_ctx, const DOM_SID *sid, Add SID to an array SIDs ensuring that it is not already there ********************************************************************/ -void add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid, +BOOL add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const DOM_SID *sid, DOM_SID **sids, size_t *num_sids) { size_t i; for (i=0; i<(*num_sids); i++) { if (sid_compare(sid, &(*sids)[i]) == 0) - return; + return True; } - add_sid_to_array(mem_ctx, sid, sids, num_sids); + return add_sid_to_array(mem_ctx, sid, sids, num_sids); } /******************************************************************** @@ -647,23 +643,26 @@ void del_sid_from_array(const DOM_SID *sid, DOM_SID **sids, size_t *num) return; } -void add_rid_to_array_unique(TALLOC_CTX *mem_ctx, +BOOL add_rid_to_array_unique(TALLOC_CTX *mem_ctx, uint32 rid, uint32 **pp_rids, size_t *p_num) { size_t i; for (i=0; i<*p_num; i++) { if ((*pp_rids)[i] == rid) - return; + return True; } *pp_rids = TALLOC_REALLOC_ARRAY(mem_ctx, *pp_rids, uint32, *p_num+1); - if (*pp_rids == NULL) - return; + if (*pp_rids == NULL) { + *p_num = 0; + return False; + } (*pp_rids)[*p_num] = rid; *p_num += 1; + return True; } BOOL is_null_sid(const DOM_SID *sid) diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index fc13b75cc5..cd52faa52d 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -2428,8 +2428,10 @@ BOOL add_string_to_array(TALLOC_CTX *mem_ctx, *strings = TALLOC_REALLOC_ARRAY(mem_ctx, *strings, const char *, (*num)+1); - if ((*strings == NULL) || (dup_str == NULL)) + if ((*strings == NULL) || (dup_str == NULL)) { + *num = 0; return False; + } (*strings)[*num] = dup_str; *num += 1; 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); diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 607a8b91d3..b84b0bfaff 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -1271,23 +1271,24 @@ static BOOL pdb_default_sid_to_id(struct pdb_methods *methods, return ret; } -static void add_uid_to_array_unique(TALLOC_CTX *mem_ctx, +static BOOL add_uid_to_array_unique(TALLOC_CTX *mem_ctx, uid_t uid, uid_t **pp_uids, size_t *p_num) { size_t i; for (i=0; i<*p_num; i++) { if ((*pp_uids)[i] == uid) - return; + return True; } *pp_uids = TALLOC_REALLOC_ARRAY(mem_ctx, *pp_uids, uid_t, *p_num+1); if (*pp_uids == NULL) - return; + return False; (*pp_uids)[*p_num] = uid; *p_num += 1; + return True; } static BOOL get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size_t *p_num) @@ -1296,6 +1297,7 @@ static BOOL get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size char **gr; struct passwd *pwd; BOOL winbind_env; + BOOL ret = False; *pp_uids = NULL; *p_num = 0; @@ -1306,19 +1308,17 @@ static BOOL get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size if ((grp = getgrgid(gid)) == NULL) { /* allow winbindd lookups, but only if they weren't already disabled */ - if (!winbind_env) { - winbind_on(); - } - - return False; + goto done; } /* Primary group members */ setpwent(); while ((pwd = getpwent()) != NULL) { if (pwd->pw_gid == gid) { - add_uid_to_array_unique(mem_ctx, pwd->pw_uid, - pp_uids, p_num); + if (!add_uid_to_array_unique(mem_ctx, pwd->pw_uid, + pp_uids, p_num)) { + goto done; + } } } endpwent(); @@ -1329,15 +1329,21 @@ static BOOL get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size if (pw == NULL) continue; - add_uid_to_array_unique(mem_ctx, pw->pw_uid, pp_uids, p_num); + if (!add_uid_to_array_unique(mem_ctx, pw->pw_uid, pp_uids, p_num)) { + goto done; + } } + ret = True; + + done: + /* allow winbindd lookups, but only if they weren't already disabled */ if (!winbind_env) { winbind_on(); } - return True; + return ret; } NTSTATUS pdb_default_enum_group_members(struct pdb_methods *methods, diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index fbcb0e4616..8ea54ead30 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -2470,8 +2470,11 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods, sid_peek_rid(&sid, &rid); - add_rid_to_array_unique(mem_ctx, rid, pp_member_rids, - p_num_members); + if (!add_rid_to_array_unique(mem_ctx, rid, pp_member_rids, + p_num_members)) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } } } @@ -2506,8 +2509,11 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods, goto done; } - add_rid_to_array_unique(mem_ctx, rid, pp_member_rids, - p_num_members); + if (!add_rid_to_array_unique(mem_ctx, rid, pp_member_rids, + p_num_members)) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } } ret = NT_STATUS_OK; @@ -2618,11 +2624,17 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, /* We need to add the primary group as the first gid/sid */ - add_gid_to_array_unique(mem_ctx, primary_gid, pp_gids, &num_gids); + if (!add_gid_to_array_unique(mem_ctx, primary_gid, pp_gids, &num_gids)) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } /* This sid will be replaced later */ - add_sid_to_array_unique(mem_ctx, &global_sid_NULL, pp_sids, &num_sids); + if (!add_sid_to_array_unique(mem_ctx, &global_sid_NULL, pp_sids, &num_sids)) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } for (entry = ldap_first_entry(conn->ldap_struct, result); entry != NULL; @@ -2654,10 +2666,16 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, if (gid == primary_gid) { sid_copy(&(*pp_sids)[0], &sid); } else { - add_gid_to_array_unique(mem_ctx, gid, pp_gids, - &num_gids); - add_sid_to_array_unique(mem_ctx, &sid, pp_sids, - &num_sids); + if (!add_gid_to_array_unique(mem_ctx, gid, pp_gids, + &num_gids)) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } + if (!add_sid_to_array_unique(mem_ctx, &sid, pp_sids, + &num_sids)) { + ret = NT_STATUS_NO_MEMORY; + goto done; + } } } @@ -3354,7 +3372,11 @@ static NTSTATUS ldapsam_enum_aliasmem(struct pdb_methods *methods, if (!string_to_sid(&member, values[i])) continue; - add_sid_to_array(NULL, &member, pp_members, &num_members); + if (!add_sid_to_array(NULL, &member, pp_members, &num_members)) { + ldap_value_free(values); + ldap_msgfree(result); + return NT_STATUS_NO_MEMORY; + } } *p_num_members = num_members; @@ -3442,8 +3464,11 @@ static NTSTATUS ldapsam_alias_memberships(struct pdb_methods *methods, if (!sid_peek_check_rid(domain_sid, &sid, &rid)) continue; - add_rid_to_array_unique(mem_ctx, rid, pp_alias_rids, - p_num_alias_rids); + if (!add_rid_to_array_unique(mem_ctx, rid, pp_alias_rids, + p_num_alias_rids)) { + ldap_msgfree(result); + return NT_STATUS_NO_MEMORY; + } } ldap_msgfree(result); diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index c65e466fe5..238ee7db63 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -684,7 +684,9 @@ static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli, printf("%s is not a legal SID\n", argv[i]); return NT_STATUS_INVALID_PARAMETER; } - add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids); + if (!add_sid_to_array(mem_ctx, &tmp_sid, &sids, &num_sids)) { + return NT_STATUS_NO_MEMORY; + } } sid2 = TALLOC_ARRAY(mem_ctx, DOM_SID2, num_sids); diff --git a/source3/smbd/conn.c b/source3/smbd/conn.c index 0b0da589e4..f2c04662a1 100644 --- a/source3/smbd/conn.c +++ b/source3/smbd/conn.c @@ -269,7 +269,7 @@ void conn_free_internal(connection_struct *conn) } if (conn->ngroups && conn->groups) { - SAFE_FREE(conn->groups); + TALLOC_FREE(conn->groups); conn->ngroups = 0; } diff --git a/source3/smbd/service.c b/source3/smbd/service.c index c2dd062777..62d85cfdd9 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -853,8 +853,13 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, sid_string_static(sid))); continue; } - add_gid_to_array_unique(NULL, gid, &conn->groups, - &conn->ngroups); + if (!add_gid_to_array_unique(NULL, gid, &conn->groups, + &conn->ngroups)) { + DEBUG(0, ("add_gid_to_array_unique failed\n")); + conn_free(conn); + *status = NT_STATUS_NO_MEMORY; + return NULL; + } } } |