r20090: Fix a class of bugs found by James Peach. Ensure
authorJeremy Allison <jra@samba.org>
Sat, 9 Dec 2006 02:58:18 +0000 (02:58 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:16:24 +0000 (12:16 -0500)
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.

20 files changed:
source/auth/auth_util.c
source/groupdb/mapping.c
source/groupdb/mapping_ldb.c
source/groupdb/mapping_tdb.c
source/lib/privileges.c
source/lib/system_smbd.c
source/lib/util.c
source/lib/util_sid.c
source/lib/util_str.c
source/nsswitch/winbindd_ads.c
source/nsswitch/winbindd_async.c
source/nsswitch/winbindd_cm.c
source/nsswitch/winbindd_group.c
source/nsswitch/winbindd_rpc.c
source/nsswitch/winbindd_util.c
source/passdb/pdb_interface.c
source/passdb/pdb_ldap.c
source/rpcclient/cmd_samr.c
source/smbd/conn.c
source/smbd/service.c

index e066ba279c3c78994a703be522b86cbb9b3d4ed1..7e65121b2d944fe7e45a37bf7420e52ae10aaca1 100644 (file)
@@ -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, 
index ba1a7d1dee51254ddda2b4ad58f7711254ce8285..54cffd15882c7291c81701505fb7a58bcde69cb2 100644 (file)
@@ -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;
 }
index 29d5b49edf89de00a8ab0d7094c47cbb5ef1886b..a743c2456e382eb8b35bf2304d19ee542244d02a 100644 (file)
@@ -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;
                }
index 12b7c682fb7230aeaa8bb8b57c2c9a2ee7a0e500..cff557ff1335a2c9550a9efa3d3a6d60a5a0c17e 100644 (file)
@@ -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;
index 32535394c7dc1f6ac6e4a8c6d84439aa5d360805..c0f7857c95b8c231504a7b39035da86fb1b1dfc2 100644 (file)
@@ -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;
 }
index fc506c901db624dc41f50ea787e9b271d4c301fc..509b2bbcb1e9e960cc9f3f6ab097b61921d2dc94 100644 (file)
@@ -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;
index 19c6cab5b28a5550f2889d9b4f3b99a1980bcc92..d1801527e972a92bde5792a885df3ce70b608cc8 100644 (file)
@@ -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;
index b6952fca81c45e38c693d35765a5d1a760976b43..032be9aa93b9d01791c9aa1612520e50dcbca0a9 100644 (file)
@@ -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)
index fc13b75cc572a536b4c399b8fd2d2709e12c361f..cd52faa52d9302b72b375ea2c413fe95404388a5 100644 (file)
@@ -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;
index 113f14a3b763522c171f31d74a46d7c4b035c161..ad24b87a900cfbbc0d543ee76e498ebb9d22d062 100644 (file)
@@ -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;
index 40211065163dff3cd5f791a1246b017ccecab527..607a9947ea22fb5b5ac0d97b42328b8dc24932aa 100644 (file)
@@ -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;
index 330ba4ca9becc0aade1b16602ddf41e93f886148..2c341d5efa8d057d2507179d77216c41b3baf8da 100644 (file)
@@ -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)) {
index 7feaadbf979e74a24b8455fc734b3ac878d021a0..aac8a9aac314891a321e1fc1428df91c4e74f26a 100644 (file)
@@ -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];
index 2e2b89535224d7e039680c3f19deb40b11182f44..08fe129db0e3f8b05e0ee38f9f5445ec7caa8894 100644 (file)
@@ -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;
                }
 
index 98990664e377f0b678794f31fa213f36ad7681e3..c9f3a396411f54cc50ed20850091e80273b2e89e 100644 (file)
@@ -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);
index 607a8b91d38132e1c0eedf0d94efc5ce2f86b21e..b84b0bfaff3f5ba57445a5f048ca126b1dca10f3 100644 (file)
@@ -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,
index fbcb0e461638befb063f423474c4d4245fac1518..8ea54ead30d9bbbfd3ee84f574a381c94fd1614f 100644 (file)
@@ -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);
index c65e466fe5df953c57af013f94c16919f311de68..238ee7db6309744f73edcecf1f098579ec9e189a 100644 (file)
@@ -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);
index 0b0da589e4d0a0df510c40f22605a188b87fc138..f2c04662a1b739c60e3f7a15ef4e7a5f72821e4d 100644 (file)
@@ -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;
        }
 
index c2dd062777b7d1b2e64869a00f2f05b19015f088..62d85cfdd97795f375db83691533cd26b5c03f64 100644 (file)
@@ -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;
+                       }
                }
        }