From 3a40f80a94cba569c1a1f19ba36165069ba7e83a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 5 Jul 2001 22:36:25 +0000 Subject: Fix for enumerating large numbers of users. Jeremy. (This used to be commit c8c138c1fbb49799a2dd4c6e781bd89f51c0c0c5) --- source3/include/rpc_samr.h | 2 +- source3/rpc_server/srv_samr_nt.c | 81 ++++++++++++++++++++++++---------------- source3/tdb/tdb.c | 2 +- 3 files changed, 50 insertions(+), 35 deletions(-) diff --git a/source3/include/rpc_samr.h b/source3/include/rpc_samr.h index 18b0a8c143..cdfb19580d 100644 --- a/source3/include/rpc_samr.h +++ b/source3/include/rpc_samr.h @@ -617,7 +617,7 @@ typedef struct r_samr_open_domain_info } SAMR_R_OPEN_DOMAIN; -#define MAX_SAM_ENTRIES 250 +#define MAX_SAM_ENTRIES 50 typedef struct samr_entry_info { diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index a73dcb30d2..fb2dcf03cc 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -88,28 +88,28 @@ static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass) dynamically returns the correct user info..... JRA. ********************************************************************/ -static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx, +static uint32 get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx, int *total_entries, int *num_entries, int max_num_entries, uint16 acb_mask) { SAM_ACCOUNT *pwd = NULL; - BOOL ret; + BOOL not_finished = True; (*num_entries) = 0; (*total_entries) = 0; if (pw_buf == NULL) - return False; + return NT_STATUS_NO_MEMORY; pdb_init_sam(&pwd); if (!pdb_setsampwent(False)) { DEBUG(0, ("get_sampwd_entries: Unable to open passdb.\n")); pdb_free_sam(pwd); - return False; + return NT_STATUS_ACCESS_DENIED; } - while (((ret = pdb_getsampwent(pwd)) != False) && (*num_entries) < max_num_entries) { + while (((not_finished = pdb_getsampwent(pwd)) != False) && (*num_entries) < max_num_entries) { int user_name_len; if (start_idx > 0) { @@ -148,32 +148,36 @@ static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx, pdb_endsampwent(); pdb_free_sam(pwd); - return (*num_entries) > 0; + if (not_finished) + return STATUS_MORE_ENTRIES; + else + return NT_STATUS_NO_PROBLEMO; } -static BOOL jf_get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx, +static uint32 jf_get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx, int *total_entries, uint32 *num_entries, int max_num_entries, uint16 acb_mask) { SAM_ACCOUNT *pwd = NULL; + BOOL not_finished = True; *num_entries = 0; *total_entries = 0; if (pw_buf == NULL) - return False; + return NT_STATUS_NO_MEMORY; DEBUG(10,("jf_get_sampwd_entries: start index:%d, max entries:%d, mask:%d\n", start_idx, max_num_entries, acb_mask)); if (!pdb_setsampwent(False)) { DEBUG(0, ("jf_get_sampwd_entries: Unable to open passdb.\n")); - return False; + return NT_STATUS_ACCESS_DENIED; } pdb_init_sam(&pwd); - while ((pdb_getsampwent(pwd) != False) && (*num_entries) < max_num_entries) { + while (((not_finished = pdb_getsampwent(pwd)) != False) && (*num_entries) < max_num_entries) { int user_name_len; int full_name_len; @@ -221,7 +225,10 @@ static BOOL jf_get_sampwd_entries(SAM_USER_INFO_21 *pw_buf, int start_idx, pdb_free_sam(pwd); - return True; + if (not_finished) + return STATUS_MORE_ENTRIES; + else + return NT_STATUS_NO_PROBLEMO; } /******************************************************************* @@ -684,7 +691,6 @@ uint32 _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES]; int num_entries = 0; int total_entries = 0; - BOOL ret; r_u->status = NT_STATUS_NOPROBLEMO; @@ -695,12 +701,12 @@ uint32 _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u, SAMR_R_ DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__)); become_root(); - ret = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, + r_u->status = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask); unbecome_root(); - if (!ret) - return NT_STATUS_ACCESS_DENIED; + if (r_u->status != NT_STATUS_NOPROBLEMO && r_u->status != STATUS_MORE_ENTRIES) + return r_u->status; samr_clear_passwd_fields(pass, num_entries); @@ -995,7 +1001,7 @@ uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_ int total_entries = 0; uint32 data_size = 0; DOM_SID sid; - BOOL ret; + uint32 disp_ret; SAM_DISPINFO_CTR *ctr; DEBUG(5, ("samr_reply_query_dispinfo: %d\n", __LINE__)); @@ -1020,30 +1026,30 @@ uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_ case 0x4: become_root(); #if 0 - ret = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, + r_u->status = get_passwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, acb_mask); #endif #if 0 /* * Which should we use here ? JRA. */ - ret = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, + r_u->status = get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, acb_mask); #endif #if 1 - ret = jf_get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, + r_u->status = jf_get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries, MAX_SAM_ENTRIES, acb_mask); #endif unbecome_root(); - if (!ret) { + if (r_u->status!=STATUS_MORE_ENTRIES && r_u->status!=NT_STATUS_NO_PROBLEMO) { DEBUG(5, ("get_sampwd_entries: failed\n")); - return NT_STATUS_ACCESS_DENIED; + return r_u->status; } break; case 0x3: case 0x5: - ret = get_group_domain_entries(p->mem_ctx, &grps, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES); - if (!ret) + r_u->status = get_group_domain_entries(p->mem_ctx, &grps, &sid, q_u->start_idx, &num_entries, MAX_SAM_ENTRIES); + if (r_u->status != NT_STATUS_NO_PROBLEMO) return NT_STATUS_ACCESS_DENIED; break; default: @@ -1051,6 +1057,7 @@ uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_ return NT_STATUS_INVALID_INFO_CLASS; } + orig_num_entries = num_entries; if (num_entries > q_u->max_entries) num_entries = q_u->max_entries; @@ -1064,7 +1071,6 @@ uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_ samr_clear_passwd_fields(pass, num_entries); data_size = q_u->max_size; - orig_num_entries = num_entries; if (!(ctr = (SAM_DISPINFO_CTR *)talloc(p->mem_ctx,sizeof(SAM_DISPINFO_CTR)))) return NT_STATUS_NO_MEMORY; @@ -1074,29 +1080,39 @@ uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_ case 0x1: if (!(ctr->sam.info1 = (SAM_DISPINFO_1 *)talloc(p->mem_ctx,sizeof(SAM_DISPINFO_1)))) return NT_STATUS_NO_MEMORY; - init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, &num_entries, &data_size, q_u->start_idx, pass); + disp_ret = init_sam_dispinfo_1(p->mem_ctx, ctr->sam.info1, &num_entries, &data_size, q_u->start_idx, pass); + if (disp_ret != NT_STATUS_NO_PROBLEMO) + return disp_ret; break; case 0x2: if (!(ctr->sam.info2 = (SAM_DISPINFO_2 *)talloc(p->mem_ctx,sizeof(SAM_DISPINFO_2)))) return NT_STATUS_NO_MEMORY; - init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, &num_entries, &data_size, q_u->start_idx, pass); + disp_ret = init_sam_dispinfo_2(p->mem_ctx, ctr->sam.info2, &num_entries, &data_size, q_u->start_idx, pass); + if (disp_ret != NT_STATUS_NO_PROBLEMO) + return disp_ret; break; case 0x3: if (!(ctr->sam.info3 = (SAM_DISPINFO_3 *)talloc(p->mem_ctx,sizeof(SAM_DISPINFO_3)))) return NT_STATUS_NO_MEMORY; - init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, &num_entries, &data_size, q_u->start_idx, grps); + disp_ret = init_sam_dispinfo_3(p->mem_ctx, ctr->sam.info3, &num_entries, &data_size, q_u->start_idx, grps); safe_free(grps); + if (disp_ret != NT_STATUS_NO_PROBLEMO) + return disp_ret; break; case 0x4: if (!(ctr->sam.info4 = (SAM_DISPINFO_4 *)talloc(p->mem_ctx,sizeof(SAM_DISPINFO_4)))) return NT_STATUS_NO_MEMORY; - init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, &num_entries, &data_size, q_u->start_idx, pass); + disp_ret = init_sam_dispinfo_4(p->mem_ctx, ctr->sam.info4, &num_entries, &data_size, q_u->start_idx, pass); + if (disp_ret != NT_STATUS_NO_PROBLEMO) + return disp_ret; break; case 0x5: if (!(ctr->sam.info5 = (SAM_DISPINFO_5 *)talloc(p->mem_ctx,sizeof(SAM_DISPINFO_5)))) return NT_STATUS_NO_MEMORY; - init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, &num_entries, &data_size, q_u->start_idx, grps); + disp_ret = init_sam_dispinfo_5(p->mem_ctx, ctr->sam.info5, &num_entries, &data_size, q_u->start_idx, grps); safe_free(grps); + if (disp_ret != NT_STATUS_NO_PROBLEMO) + return disp_ret; break; default: ctr->sam.info = NULL; @@ -1105,11 +1121,10 @@ uint32 _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u, SAMR_R_ DEBUG(5, ("_samr_query_dispinfo: %d\n", __LINE__)); - init_samr_r_query_dispinfo(r_u, num_entries, data_size, q_u->switch_level, ctr, r_u->status); - - if (num_entries < orig_num_entries) { + if (num_entries < orig_num_entries) return STATUS_MORE_ENTRIES; - } + + init_samr_r_query_dispinfo(r_u, num_entries, data_size, q_u->switch_level, ctr, r_u->status); return r_u->status; } diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c index 97c8e00ae6..c3ded6368b 100644 --- a/source3/tdb/tdb.c +++ b/source3/tdb/tdb.c @@ -1340,7 +1340,7 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, return ret; fail: - if (tdb.name) free(tdb.name); + if (tdb.name) free(tdb.name); if (tdb.fd != -1) close(tdb.fd); tdb_munmap(&tdb); return NULL; -- cgit