Fix for enumerating large numbers of users.
authorJeremy Allison <jra@samba.org>
Thu, 5 Jul 2001 22:36:25 +0000 (22:36 +0000)
committerJeremy Allison <jra@samba.org>
Thu, 5 Jul 2001 22:36:25 +0000 (22:36 +0000)
Jeremy.

source/include/rpc_samr.h
source/rpc_server/srv_samr_nt.c
source/tdb/tdb.c

index 18b0a8c14323b24d52a8ca8ebc6b08d8562c11a4..cdfb19580ded932e38e4c58bb08976d12f2eadbf 100644 (file)
@@ -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
 {
index a73dcb30d2c63f64ee9ae8f9afe450ba20721bad..fb2dcf03cc1d448518d8218d22fa6c27365e5833 100644 (file)
@@ -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;
 }
index 97c8e00ae685961014a0fe26b0910fc9dddf6002..c3ded6368b714b4b6cf2e509b7bdd23d9272ab1a 100644 (file)
@@ -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;