fix for enumerate domain users (bug spotted by sean matthews).
authorLuke Leighton <lkcl@samba.org>
Fri, 29 Jan 1999 21:22:08 +0000 (21:22 +0000)
committerLuke Leighton <lkcl@samba.org>
Fri, 29 Jan 1999 21:22:08 +0000 (21:22 +0000)
also needed to use start index properly and generate next index.

both client and server code need to recognise error code 0x105
when there's not enough room to store all the users in one call.

sort this out another time.
(This used to be commit ad58cdfac6b85d9431216e32e532ad4d60f9c6dd)

source3/include/proto.h
source3/include/rpc_samr.h
source3/rpc_client/cli_samr.c
source3/rpc_parse/parse_samr.c
source3/rpc_server/srv_samr.c
source3/rpcclient/cmd_samr.c

index 15ed9a50af48d12a1a4116e6a6def6efb394e8bd..9dbf57d17e701e5d33f71f6574e419d9eaa710af 100644 (file)
@@ -1679,7 +1679,7 @@ BOOL samr_enum_dom_aliases(struct cli_state *cli, uint16 fnum,
                                struct acct_info **sam,
                                int *num_sam_aliases);
 BOOL samr_enum_dom_users(struct cli_state *cli, uint16 fnum, 
-                               POLICY_HND *pol, uint16 num_entries, uint16 unk_0,
+                               POLICY_HND *pol, uint32 start_idx, 
                                uint16 acb_mask, uint16 unk_1, uint32 size,
                                struct acct_info **sam,
                                int *num_sam_users);
@@ -2181,7 +2181,7 @@ void make_samr_r_unknown_3(SAMR_R_UNKNOWN_3 *r_u,
                                uint32 status);
 void samr_io_r_unknown_3(char *desc,  SAMR_R_UNKNOWN_3 *r_u, prs_struct *ps, int depth);
 void make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
-                               uint16 req_num_entries, uint16 unk_0,
+                               uint32 start_idx, 
                                uint16 acb_mask, uint16 unk_1, uint32 size);
 void samr_io_q_enum_dom_users(char *desc,  SAMR_Q_ENUM_DOM_USERS *q_e, prs_struct *ps, int depth);
 void make_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
@@ -2779,6 +2779,7 @@ void display_reg_value_info(FILE *out_hnd, enum action_type action,
                                char *val_name, uint32 val_type, BUFFER2 *value);
 void display_reg_key_info(FILE *out_hnd, enum action_type action,
                                char *key_name, time_t key_mod_time);
+char *get_svc_start_type_str(uint32 type);
 void display_query_svc_cfg(FILE *out_hnd, enum action_type action,
                                QUERY_SERVICE_CONFIG *cfg);
 void display_svc_info(FILE *out_hnd, enum action_type action, ENUM_SRVC_STATUS *svc);
index 07ae0301d431d72a377aa3421396abe733b12d83..d70702f8a68cd239e7e9965f8ad734ea5c7a6cbc 100644 (file)
@@ -486,8 +486,7 @@ typedef struct q_samr_enum_dom_users_info
 {
        POLICY_HND pol;          /* policy handle */
 
-       uint16 req_num_entries;   /* number of values (0 indicates unlimited?) */
-       uint16 unknown_0;         /* enumeration context? */
+       uint32 start_idx;   /* number of values (0 indicates unlimited?) */
        uint16 acb_mask;          /* 0x0000 indicates all */
        uint16 unknown_1;         /* 0x0000 */
 
@@ -499,8 +498,8 @@ typedef struct q_samr_enum_dom_users_info
 /* SAMR_R_ENUM_DOM_USERS - SAM rids and names */
 typedef struct r_samr_enum_dom_users_info
 {
-       uint32 unknown_0;          /* unknown. */
-       uint32 ptr_entries1;       /* actual number of entries to follow, having masked some out */
+       uint32 next_idx;     /* next starting index required for enum */
+       uint32 ptr_entries1;  
 
        uint32 num_entries2;
        uint32 ptr_entries2;
index 7c89dfcc02dda74ab86b80f6a2f0121b4ac53198..f97a38b718db0f5535db0bc26882a9de73863938 100644 (file)
@@ -698,7 +698,7 @@ BOOL samr_enum_dom_aliases(struct cli_state *cli, uint16 fnum,
 do a SAMR enumerate users
 ****************************************************************************/
 BOOL samr_enum_dom_users(struct cli_state *cli, uint16 fnum, 
-                               POLICY_HND *pol, uint16 num_entries, uint16 unk_0,
+                               POLICY_HND *pol, uint32 start_idx, 
                                uint16 acb_mask, uint16 unk_1, uint32 size,
                                struct acct_info **sam,
                                int *num_sam_users)
@@ -719,9 +719,7 @@ BOOL samr_enum_dom_users(struct cli_state *cli, uint16 fnum,
        prs_init(&rdata, 0   , 4, SAFETY_MARGIN, True );
 
        /* store the parameters */
-       make_samr_q_enum_dom_users(&q_e, pol,
-                                  num_entries, unk_0,
-                                  acb_mask, unk_1, size);
+       make_samr_q_enum_dom_users(&q_e, pol, start_idx, acb_mask, unk_1, size);
 
        /* turn parameters into data stream */
        samr_io_q_enum_dom_users("", &q_e, &data, 0);
index f4c17902541c2be00f4df69c36c519a084e000e2..1fcb57c4359791840d80b5a2ac67bed40c72535d 100644 (file)
@@ -871,7 +871,7 @@ static void sam_io_sam_entry(char *desc,  SAM_ENTRY *sam, prs_struct *ps, int de
 makes a SAMR_Q_ENUM_DOM_USERS structure.
 ********************************************************************/
 void make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
-                               uint16 req_num_entries, uint16 unk_0,
+                               uint32 start_idx, 
                                uint16 acb_mask, uint16 unk_1, uint32 size)
 {
        if (q_e == NULL || pol == NULL) return;
@@ -880,8 +880,7 @@ void make_samr_q_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_e, POLICY_HND *pol,
 
        memcpy(&(q_e->pol), pol, sizeof(*pol));
 
-       q_e->req_num_entries = req_num_entries; /* zero indicates lots */
-       q_e->unknown_0 = unk_0; /* this gets returned in the response */
+       q_e->start_idx = start_idx; /* zero indicates lots */
        q_e->acb_mask  = acb_mask;
        q_e->unknown_1 = unk_1;
        q_e->max_size = size;
@@ -902,13 +901,11 @@ void samr_io_q_enum_dom_users(char *desc,  SAMR_Q_ENUM_DOM_USERS *q_e, prs_struc
        smb_io_pol_hnd("pol", &(q_e->pol), ps, depth); 
        prs_align(ps);
 
-       prs_uint16("req_num_entries", ps, depth, &(q_e->req_num_entries));
-       prs_uint16("unknown_0      ", ps, depth, &(q_e->unknown_0      ));
-
-       prs_uint16("acb_mask       ", ps, depth, &(q_e->acb_mask       ));
-       prs_uint16("unknown_1      ", ps, depth, &(q_e->unknown_1      ));
+       prs_uint32("start_idx", ps, depth, &(q_e->start_idx));
+       prs_uint16("acb_mask ", ps, depth, &(q_e->acb_mask ));
+       prs_uint16("unknown_1", ps, depth, &(q_e->unknown_1));
 
-       prs_uint32("max_size       ", ps, depth, &(q_e->max_size       ));
+       prs_uint32("max_size ", ps, depth, &(q_e->max_size ));
 
        prs_align(ps);
 }
@@ -918,7 +915,7 @@ void samr_io_q_enum_dom_users(char *desc,  SAMR_Q_ENUM_DOM_USERS *q_e, prs_struc
 makes a SAMR_R_ENUM_DOM_USERS structure.
 ********************************************************************/
 void make_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
-               uint32 unk_0,
+               uint32 next_idx,
                uint32 num_sam_entries, SAM_USER_INFO_21 pass[MAX_SAM_ENTRIES], uint32 status)
 {
        int i;
@@ -934,7 +931,7 @@ void make_samr_r_enum_dom_users(SAMR_R_ENUM_DOM_USERS *r_u,
                         num_sam_entries));
        }
 
-       r_u->unknown_0 = unk_0;
+       r_u->next_idx = next_idx;
 
        if (num_sam_entries != 0)
        {
@@ -981,7 +978,7 @@ void samr_io_r_enum_dom_users(char *desc,  SAMR_R_ENUM_DOM_USERS *r_u, prs_struc
 
        prs_align(ps);
 
-       prs_uint32("unknown_0   ", ps, depth, &(r_u->unknown_0   ));
+       prs_uint32("next_idx    ", ps, depth, &(r_u->next_idx    ));
        prs_uint32("ptr_entries1", ps, depth, &(r_u->ptr_entries1));
 
        if (r_u->ptr_entries1 != 0)
index 15cef476c4a370dac4ccd816bd134cf661f15b88..1fb64c10effec1fdeae92c23d2e22b687773b43f 100644 (file)
@@ -73,7 +73,10 @@ static BOOL get_sampwd_entries(SAM_USER_INFO_21 *pw_buf,
                        /* skip the requested number of entries.
                           not very efficient, but hey...
                         */
-                       start_idx--;
+                       if (acb_mask == 0 || IS_BITS_SET_SOME(pwd->acct_ctrl, acb_mask))
+                       {
+                               start_idx--;
+                       }
                        continue;
                }
 
@@ -344,11 +347,12 @@ static void samr_reply_enum_dom_users(SAMR_Q_ENUM_DOM_USERS *q_u,
        DEBUG(5,("samr_reply_enum_dom_users: %d\n", __LINE__));
 
        become_root(True);
-       get_sampwd_entries(pass, 0, &total_entries, &num_entries, MAX_SAM_ENTRIES, q_u->acb_mask);
+       get_sampwd_entries(pass, q_u->start_idx, &total_entries, &num_entries,
+                          MAX_SAM_ENTRIES, q_u->acb_mask);
        unbecome_root(True);
 
        make_samr_r_enum_dom_users(&r_e, 
-                                  0x00000000, num_entries,
+                                  q_u->start_idx + num_entries, num_entries,
                                   pass, r_e.status);
 
        /* store the response in the SMB stream */
index 8a43a69cb7dae3dda4cb6d5f2133beccfbff52c4..18018659b929fb7c5b2d98393ab39cdfcc2abaa7 100644 (file)
@@ -1034,7 +1034,7 @@ void cmd_sam_enum_users(struct client_info *info)
        BOOL request_user_info  = False;
        BOOL request_group_info = False;
        BOOL request_alias_info = False;
-       uint16 num_entries = 0;
+       uint16 start_idx = 0x0;
        uint16 unk_0 = 0x0;
        uint16 acb_mask = 0;
        uint16 unk_1 = 0x0;
@@ -1075,7 +1075,7 @@ void cmd_sam_enum_users(struct client_info *info)
 #ifdef DEBUG_TESTING
        if (next_token(NULL, tmp, NULL, sizeof(tmp)))
        {
-               num_entries = (uint16)strtol(tmp, (char**)NULL, 16);
+               start_idx = (uint32)strtol(tmp, (char**)NULL, 10);
        }
 
        if (next_token(NULL, tmp, NULL, sizeof(tmp)))
@@ -1102,7 +1102,7 @@ void cmd_sam_enum_users(struct client_info *info)
 
 #ifdef DEBUG_TESTING
        DEBUG(5,("Number of entries:%d unk_0:%04x acb_mask:%04x unk_1:%04x\n",
-                 num_entries, unk_0, acb_mask, unk_1));
+                 start_idx, unk_0, acb_mask, unk_1));
 #endif
 
        /* open SAMR session.  negotiate credentials */
@@ -1127,9 +1127,9 @@ void cmd_sam_enum_users(struct client_info *info)
 
        /* read some users */
        res = res ? samr_enum_dom_users(smb_cli, fnum, 
-                               &info->dom.samr_pol_open_domain,
-                   num_entries, unk_0, acb_mask, unk_1, 0xffff,
-                               &info->dom.sam, &info->dom.num_sam_entries) : False;
+                    &info->dom.samr_pol_open_domain,
+                    start_idx, acb_mask, unk_1, 0x80,
+                    &info->dom.sam, &info->dom.num_sam_entries) : False;
 
        if (res && info->dom.num_sam_entries == 0)
        {