r16834: split the level's of smb_search_first/smb_search_next and the levels
authorStefan Metzmacher <metze@samba.org>
Thu, 6 Jul 2006 08:00:24 +0000 (08:00 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:09:49 +0000 (14:09 -0500)
of smb_search_data

metze
(This used to be commit 78c201db8a47a71908698c4dda2add4cf85694d9)

14 files changed:
source4/libcli/clilist.c
source4/libcli/raw/interfaces.h
source4/libcli/raw/rawsearch.c
source4/libcli/smb2/find.c
source4/ntvfs/nbench/vfs_nbench.c
source4/ntvfs/posix/pvfs_search.c
source4/ntvfs/simple/vfs_simple.c
source4/smb_server/blob.c
source4/smb_server/smb/search.c
source4/smb_server/smb/trans2.c
source4/torture/basic/delete.c
source4/torture/masktest.c
source4/torture/raw/chkpath.c
source4/torture/raw/search.c

index f18ec84db93c903e32e74d8d90befbbd870b5eae..16986e9428d974d68dc88a5a25dd78f66990012e 100644 (file)
@@ -29,7 +29,7 @@ struct search_private {
        int dirlist_len;
        int ff_searchcount;  /* total received in 1 server trip */
        int total_received;  /* total received all together */
-       enum smb_search_level info_level;
+       enum smb_search_data_level data_level;
        const char *last_name;     /* used to continue trans2 search */
        struct smb_search_id id;   /* used for old-style search */
 };
@@ -38,7 +38,7 @@ struct search_private {
 /****************************************************************************
  Interpret a long filename structure.
 ****************************************************************************/
-static BOOL interpret_long_filename(enum smb_search_level level,
+static BOOL interpret_long_filename(enum smb_search_data_level level,
                                    union smb_search_data *info,
                                    struct clilist_file_info *finfo)
 {
@@ -48,7 +48,7 @@ static BOOL interpret_long_filename(enum smb_search_level level,
        ZERO_STRUCTP(finfo);
 
        switch (level) {
-       case RAW_SEARCH_STANDARD:
+       case RAW_SEARCH_DATA_STANDARD:
                finfo->size = info->standard.size;
                finfo->mtime = info->standard.write_time;
                finfo->attrib = info->standard.attrib;
@@ -56,7 +56,7 @@ static BOOL interpret_long_filename(enum smb_search_level level,
                finfo->short_name = info->standard.name.s;
                break;
 
-       case RAW_SEARCH_BOTH_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO:
                finfo->size = info->both_directory_info.size;
                finfo->mtime = nt_time_to_unix(info->both_directory_info.write_time);
                finfo->attrib = info->both_directory_info.attrib;
@@ -89,7 +89,7 @@ static BOOL smbcli_list_new_callback(void *private, union smb_search_data *file)
        state->dirlist = tdl;
        state->dirlist_len++;
 
-       interpret_long_filename(state->info_level, file, &state->dirlist[state->total_received]);
+       interpret_long_filename(state->data_level, file, &state->dirlist[state->total_received]);
 
        state->last_name = state->dirlist[state->total_received].name;
        state->total_received++;
@@ -99,7 +99,7 @@ static BOOL smbcli_list_new_callback(void *private, union smb_search_data *file)
 }
 
 int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribute, 
-                   enum smb_search_level level,
+                   enum smb_search_data_level level,
                    void (*fn)(struct clilist_file_info *, const char *, void *), 
                    void *caller_state)
 {
@@ -122,21 +122,22 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu
        state.dirlist = talloc_new(state.mem_ctx);
        mask = talloc_strdup(state.mem_ctx, Mask);
 
-       if (level == RAW_SEARCH_GENERIC) {
+       if (level == RAW_SEARCH_DATA_GENERIC) {
                if (tree->session->transport->negotiate.capabilities & CAP_NT_SMBS) {
-                       level = RAW_SEARCH_BOTH_DIRECTORY_INFO;
+                       level = RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO;
                } else {
-                       level = RAW_SEARCH_STANDARD;
+                       level = RAW_SEARCH_DATA_STANDARD;
                }
        }
-       state.info_level = level;
+       state.data_level = level;
 
        while (1) {
                state.ff_searchcount = 0;
                if (first) {
                        NTSTATUS status;
 
-                       first_parms.t2ffirst.level = state.info_level;
+                       first_parms.t2ffirst.level = RAW_SEARCH_TRANS2;
+                       first_parms.t2ffirst.data_level = state.data_level;
                        first_parms.t2ffirst.in.max_count = max_matches;
                        first_parms.t2ffirst.in.search_attrib = attribute;
                        first_parms.t2ffirst.in.pattern = mask;
@@ -162,7 +163,8 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu
                } else {
                        NTSTATUS status;
 
-                       next_parms.t2fnext.level = state.info_level;
+                       next_parms.t2fnext.level = RAW_SEARCH_TRANS2;
+                       next_parms.t2fnext.data_level = state.data_level;
                        next_parms.t2fnext.in.max_count = max_matches;
                        next_parms.t2fnext.in.last_name = state.last_name;
                        next_parms.t2fnext.in.handle = ff_dir_handle;
@@ -201,20 +203,29 @@ int smbcli_list_new(struct smbcli_tree *tree, const char *Mask, uint16_t attribu
  Interpret a short filename structure.
  The length of the structure is returned.
 ****************************************************************************/
-static BOOL interpret_short_filename(int level,
-                               union smb_search_data *info,
-                               struct clilist_file_info *finfo)
+static BOOL interpret_short_filename(enum smb_search_data_level level,
+                                    union smb_search_data *info,
+                                    struct clilist_file_info *finfo)
 {
        struct clilist_file_info finfo2;
 
        if (!finfo) finfo = &finfo2;
        ZERO_STRUCTP(finfo);
+
+       switch (level) {
+       case RAW_SEARCH_DATA_SEARCH:
+               finfo->mtime = info->search.write_time;
+               finfo->size = info->search.size;
+               finfo->attrib = info->search.attrib;
+               finfo->name = info->search.name;
+               finfo->short_name = info->search.name;
+               break;
+
+       default:
+               DEBUG(0,("Unhandled level %d in interpret_short_filename\n", (int)level));
+               return False;
+       }
        
-       finfo->mtime = info->search.write_time;
-       finfo->size = info->search.size;
-       finfo->attrib = info->search.attrib;
-       finfo->name = info->search.name;
-       finfo->short_name = info->search.name;
        return True;
 }
 
@@ -236,7 +247,7 @@ static BOOL smbcli_list_old_callback(void *private, union smb_search_data *file)
        state->dirlist = tdl;
        state->dirlist_len++;
 
-       interpret_short_filename(state->info_level, file, &state->dirlist[state->total_received]);
+       interpret_short_filename(state->data_level, file, &state->dirlist[state->total_received]);
 
        state->total_received++;
        state->ff_searchcount++;
@@ -273,6 +284,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu
                        NTSTATUS status;
 
                        first_parms.search_first.level = RAW_SEARCH_SEARCH;
+                       first_parms.search_first.data_level = RAW_SEARCH_DATA_SEARCH;
                        first_parms.search_first.in.max_count = num_asked;
                        first_parms.search_first.in.search_attrib = attribute;
                        first_parms.search_first.in.pattern = mask;
@@ -294,6 +306,7 @@ int smbcli_list_old(struct smbcli_tree *tree, const char *Mask, uint16_t attribu
                        NTSTATUS status;
 
                        next_parms.search_next.level = RAW_SEARCH_SEARCH;
+                       next_parms.search_next.data_level = RAW_SEARCH_DATA_SEARCH;
                        next_parms.search_next.in.max_count = num_asked;
                        next_parms.search_next.in.search_attrib = attribute;
                        next_parms.search_next.in.id = state.id;
@@ -336,5 +349,5 @@ int smbcli_list(struct smbcli_tree *tree, const char *Mask,uint16_t attribute,
 {
        if (tree->session->transport->negotiate.protocol <= PROTOCOL_LANMAN1)
                return smbcli_list_old(tree, Mask, attribute, fn, state);
-       return smbcli_list_new(tree, Mask, attribute, RAW_SEARCH_GENERIC, fn, state);
+       return smbcli_list_new(tree, Mask, attribute, RAW_SEARCH_DATA_GENERIC, fn, state);
 }
index c581978b81b067bee2afd09f688dbd70c944ece6..f77d31a1c776d92c1750a4554ffd768f53537ee5 100644 (file)
@@ -2146,33 +2146,41 @@ struct smb_notify {
        } out;
 };
 
-enum smb_search_level {RAW_SEARCH_GENERIC                 = 0xF000, 
-                      RAW_SEARCH_SEARCH,                 /* SMBsearch */ 
-                      RAW_SEARCH_FFIRST,                 /* SMBffirst */ 
-                      RAW_SEARCH_FUNIQUE,                /* SMBfunique */
-                      RAW_SEARCH_SMB2,                   /* SMB2 Find */
-                      RAW_SEARCH_STANDARD                = SMB_FIND_STANDARD,
-                      RAW_SEARCH_EA_SIZE                 = SMB_FIND_EA_SIZE,
-                      RAW_SEARCH_EA_LIST                 = SMB_FIND_EA_LIST,
-                      RAW_SEARCH_DIRECTORY_INFO          = SMB_FIND_DIRECTORY_INFO,
-                      RAW_SEARCH_FULL_DIRECTORY_INFO     = SMB_FIND_FULL_DIRECTORY_INFO,
-                      RAW_SEARCH_NAME_INFO               = SMB_FIND_NAME_INFO,
-                      RAW_SEARCH_BOTH_DIRECTORY_INFO     = SMB_FIND_BOTH_DIRECTORY_INFO,
-                      RAW_SEARCH_ID_FULL_DIRECTORY_INFO  = SMB_FIND_ID_FULL_DIRECTORY_INFO,
-                      RAW_SEARCH_ID_BOTH_DIRECTORY_INFO  = SMB_FIND_ID_BOTH_DIRECTORY_INFO,
-                      RAW_SEARCH_UNIX_INFO               = SMB_FIND_UNIX_INFO};
+enum smb_search_level {
+       RAW_SEARCH_SEARCH,      /* SMBsearch */ 
+       RAW_SEARCH_FFIRST,      /* SMBffirst */ 
+       RAW_SEARCH_FUNIQUE,     /* SMBfunique */
+       RAW_SEARCH_TRANS2,      /* SMBtrans2 */
+       RAW_SEARCH_SMB2         /* SMB2 Find */
+};
 
+enum smb_search_data_level {
+       RAW_SEARCH_DATA_GENERIC                 = 0x10000, /* only used in the smbcli_ code */
+       RAW_SEARCH_DATA_SEARCH,
+       RAW_SEARCH_DATA_STANDARD                = SMB_FIND_STANDARD,
+       RAW_SEARCH_DATA_EA_SIZE                 = SMB_FIND_EA_SIZE,
+       RAW_SEARCH_DATA_EA_LIST                 = SMB_FIND_EA_LIST,
+       RAW_SEARCH_DATA_DIRECTORY_INFO          = SMB_FIND_DIRECTORY_INFO,
+       RAW_SEARCH_DATA_FULL_DIRECTORY_INFO     = SMB_FIND_FULL_DIRECTORY_INFO,
+       RAW_SEARCH_DATA_NAME_INFO               = SMB_FIND_NAME_INFO,
+       RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO     = SMB_FIND_BOTH_DIRECTORY_INFO,
+       RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO  = SMB_FIND_ID_FULL_DIRECTORY_INFO,
+       RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO  = SMB_FIND_ID_BOTH_DIRECTORY_INFO,
+       RAW_SEARCH_DATA_UNIX_INFO               = SMB_FIND_UNIX_INFO
+};
        
 /* union for file search */
 union smb_search_first {
        struct {
                enum smb_search_level level;
+               enum smb_search_data_level data_level;
        } generic;
        
        /* search (old) findfirst interface. 
           Also used for ffirst and funique. */
        struct {
                enum smb_search_level level;
+               enum smb_search_data_level data_level;
        
                struct {
                        uint16_t max_count;
@@ -2187,6 +2195,7 @@ union smb_search_first {
        /* trans2 findfirst interface */
        struct {
                enum smb_search_level level;
+               enum smb_search_data_level data_level;
                
                struct {
                        uint16_t search_attrib;
@@ -2207,7 +2216,7 @@ union smb_search_first {
        } t2ffirst;
 
 /*
-  SMB2 uses different level numbers for the same old SMB search levels
+  SMB2 uses different level numbers for the same old SMB trans2 search levels
 */
 #define SMB2_FIND_DIRECTORY_INFO         0x01
 #define SMB2_FIND_FULL_DIRECTORY_INFO    0x02
@@ -2218,6 +2227,7 @@ union smb_search_first {
        /* SMB2 Find */
        struct smb2_find {
                enum smb_search_level level;
+               enum smb_search_data_level data_level;
                struct {
                        union smb_handle file;
 
@@ -2228,7 +2238,7 @@ union smb_search_first {
                        uint32_t unknown; /* perhaps a continue token? */
                        /* struct smb2_handle handle; */
                        /* uint16_t pattern_ofs; */
-                       /* uint32_t pattern_size; */
+                       /* uint16_t pattern_size; */
                        uint32_t max_response_size;
        
                        /* dynamic body */
@@ -2250,12 +2260,14 @@ union smb_search_first {
 union smb_search_next {
        struct {
                enum smb_search_level level;
+               enum smb_search_data_level data_level;
        } generic;
 
        /* search (old) findnext interface. Also used
           for ffirst when continuing */
        struct {
                enum smb_search_level level;
+               enum smb_search_data_level data_level;
        
                struct {
                        uint16_t max_count;
@@ -2276,6 +2288,7 @@ union smb_search_next {
        /* trans2 findnext interface */
        struct {
                enum smb_search_level level;
+               enum smb_search_data_level data_level;
                
                struct {
                        uint16_t handle;
@@ -2297,7 +2310,10 @@ union smb_search_next {
 
 /* union for search reply file data */
 union smb_search_data {
-       /* search (old) findfirst */
+       /*
+        * search (old) findfirst 
+        * RAW_SEARCH_DATA_SEARCH
+        */
        struct {
                uint16_t attrib;
                time_t write_time;
@@ -2305,8 +2321,8 @@ union smb_search_data {
                struct smb_search_id id;
                const char *name;
        } search;
-       
-       /* trans2 findfirst RAW_SEARCH_STANDARD level */
+
+       /* trans2 findfirst RAW_SEARCH_DATA_STANDARD level */
        struct {
                uint32_t resume_key;
                time_t create_time;
@@ -2318,7 +2334,7 @@ union smb_search_data {
                struct smb_wire_string name;
        } standard;
 
-       /* trans2 findfirst RAW_SEARCH_EA_SIZE level */
+       /* trans2 findfirst RAW_SEARCH_DATA_EA_SIZE level */
        struct {
                uint32_t resume_key;
                time_t create_time;
@@ -2331,7 +2347,7 @@ union smb_search_data {
                struct smb_wire_string name;
        } ea_size;
 
-       /* trans2 findfirst RAW_SEARCH_EA_LIST level */
+       /* trans2 findfirst RAW_SEARCH_DATA_EA_LIST level */
        struct {
                uint32_t resume_key;
                time_t create_time;
@@ -2344,7 +2360,7 @@ union smb_search_data {
                struct smb_wire_string name;
        } ea_list;
 
-       /* RAW_SEARCH_DIRECTORY_INFO interface */
+       /* RAW_SEARCH_DATA_DIRECTORY_INFO interface */
        struct {
                uint32_t file_index;
                NTTIME create_time;
@@ -2357,7 +2373,7 @@ union smb_search_data {
                struct smb_wire_string name;
        } directory_info;
 
-       /* RAW_SEARCH_FULL_DIRECTORY_INFO interface */
+       /* RAW_SEARCH_DATA_FULL_DIRECTORY_INFO interface */
        struct {
                uint32_t file_index;
                NTTIME create_time;
@@ -2371,13 +2387,13 @@ union smb_search_data {
                struct smb_wire_string name;
        } full_directory_info;
 
-       /* RAW_SEARCH_NAME_INFO interface */
+       /* RAW_SEARCH_DATA_NAME_INFO interface */
        struct {
                uint32_t file_index;
                struct smb_wire_string name;
        } name_info;
 
-       /* RAW_SEARCH_BOTH_DIRECTORY_INFO interface */
+       /* RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO interface */
        struct {
                uint32_t file_index;
                NTTIME create_time;
@@ -2392,7 +2408,7 @@ union smb_search_data {
                struct smb_wire_string name;
        } both_directory_info;
 
-       /* RAW_SEARCH_ID_FULL_DIRECTORY_INFO interface */
+       /* RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO interface */
        struct {
                uint32_t file_index;
                NTTIME create_time;
@@ -2407,7 +2423,7 @@ union smb_search_data {
                struct smb_wire_string name;
        } id_full_directory_info;
 
-       /* RAW_SEARCH_ID_BOTH_DIRECTORY_INFO interface */
+       /* RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO interface */
        struct {
                uint32_t file_index;
                NTTIME create_time;
@@ -2423,7 +2439,7 @@ union smb_search_data {
                struct smb_wire_string name;
        } id_both_directory_info;
 
-       /* RAW_SEARCH_UNIX_INFO interface */
+       /* RAW_SEARCH_DATA_UNIX_INFO interface */
        struct {
                uint32_t file_index;
                uint64_t size;
index 5e05d7c3c5f202980ac2e03c134289fe16fb8b87..4836766a930760e0fa3f50dd21bd8c0beac1eae2 100644 (file)
@@ -194,7 +194,6 @@ static NTSTATUS smb_raw_search_close_old(struct smbcli_tree *tree,
 static NTSTATUS smb_raw_search_first_blob(struct smbcli_tree *tree,
                                          TALLOC_CTX *mem_ctx,  /* used to allocate output blobs */
                                          union smb_search_first *io,
-                                         uint16_t info_level,
                                          DATA_BLOB *out_param_blob,
                                          DATA_BLOB *out_data_blob)
 {
@@ -211,7 +210,15 @@ static NTSTATUS smb_raw_search_first_blob(struct smbcli_tree *tree,
        tp.in.max_data = 0xFFFF;
        tp.in.setup = &setup;
 
-       if (info_level == RAW_SEARCH_EA_LIST) {
+       if (io->t2ffirst.level != RAW_SEARCH_TRANS2) {
+               return NT_STATUS_INVALID_LEVEL;
+       }
+
+       if (io->t2ffirst.data_level >= RAW_SEARCH_DATA_GENERIC) {
+               return NT_STATUS_INVALID_LEVEL;
+       }
+
+       if (io->t2ffirst.data_level == RAW_SEARCH_DATA_EA_LIST) {
                if (!ea_push_name_list(mem_ctx, 
                                       &tp.in.data,
                                       io->t2ffirst.in.num_names,
@@ -219,7 +226,7 @@ static NTSTATUS smb_raw_search_first_blob(struct smbcli_tree *tree,
                        return NT_STATUS_NO_MEMORY;
                }               
        }
-       
+
        tp.in.params = data_blob_talloc(mem_ctx, NULL, 12);
        if (!tp.in.params.data) {
                return NT_STATUS_NO_MEMORY;
@@ -228,7 +235,7 @@ static NTSTATUS smb_raw_search_first_blob(struct smbcli_tree *tree,
        SSVAL(tp.in.params.data, 0, io->t2ffirst.in.search_attrib);
        SSVAL(tp.in.params.data, 2, io->t2ffirst.in.max_count); 
        SSVAL(tp.in.params.data, 4, io->t2ffirst.in.flags);
-       SSVAL(tp.in.params.data, 6, info_level);
+       SSVAL(tp.in.params.data, 6, io->t2ffirst.data_level);
        SIVAL(tp.in.params.data, 8, io->t2ffirst.in.storage_type);
 
        smbcli_blob_append_string(tree->session, mem_ctx, &tp.in.params,
@@ -255,7 +262,6 @@ static NTSTATUS smb_raw_search_first_blob(struct smbcli_tree *tree,
 static NTSTATUS smb_raw_search_next_blob(struct smbcli_tree *tree,
                                         TALLOC_CTX *mem_ctx,
                                         union smb_search_next *io,
-                                        uint16_t info_level,
                                         DATA_BLOB *out_param_blob,
                                         DATA_BLOB *out_data_blob)
 {
@@ -272,7 +278,15 @@ static NTSTATUS smb_raw_search_next_blob(struct smbcli_tree *tree,
        tp.in.max_data = 0xFFFF;
        tp.in.setup = &setup;
 
-       if (info_level == RAW_SEARCH_EA_LIST) {
+       if (io->t2fnext.level != RAW_SEARCH_TRANS2) {
+               return NT_STATUS_INVALID_LEVEL;
+       }
+
+       if (io->t2fnext.data_level >= RAW_SEARCH_DATA_GENERIC) {
+               return NT_STATUS_INVALID_LEVEL;
+       }
+
+       if (io->t2fnext.data_level == RAW_SEARCH_DATA_EA_LIST) {
                if (!ea_push_name_list(mem_ctx, 
                                       &tp.in.data,
                                       io->t2fnext.in.num_names,
@@ -287,8 +301,8 @@ static NTSTATUS smb_raw_search_next_blob(struct smbcli_tree *tree,
        }
        
        SSVAL(tp.in.params.data, 0, io->t2fnext.in.handle);
-       SSVAL(tp.in.params.data, 2, io->t2fnext.in.max_count);  
-       SSVAL(tp.in.params.data, 4, info_level);
+       SSVAL(tp.in.params.data, 2, io->t2fnext.in.max_count);
+       SSVAL(tp.in.params.data, 4, io->t2fnext.data_level);
        SIVAL(tp.in.params.data, 6, io->t2fnext.in.resume_key);
        SSVAL(tp.in.params.data, 10, io->t2fnext.in.flags);
 
@@ -315,7 +329,7 @@ static NTSTATUS smb_raw_search_next_blob(struct smbcli_tree *tree,
   SMB2
 */
 NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx, 
-                              enum smb_search_level level,
+                              enum smb_search_data_level level,
                               const DATA_BLOB *blob,
                               union smb_search_data *data,
                               uint_t *next_ofs,
@@ -335,7 +349,7 @@ NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx,
        }
 
        switch (level) {
-       case RAW_SEARCH_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_DIRECTORY_INFO:
                if (blen < 65) return NT_STATUS_INFO_LENGTH_MISMATCH;
                data->directory_info.file_index  = IVAL(blob->data,             4);
                data->directory_info.create_time = smbcli_pull_nttime(blob->data,  8);
@@ -353,7 +367,7 @@ NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx,
                }
                return NT_STATUS_OK;
 
-       case RAW_SEARCH_FULL_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO:
                if (blen < 69) return NT_STATUS_INFO_LENGTH_MISMATCH;
                data->full_directory_info.file_index  = IVAL(blob->data,                4);
                data->full_directory_info.create_time = smbcli_pull_nttime(blob->data,  8);
@@ -372,7 +386,7 @@ NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx,
                }
                return NT_STATUS_OK;
 
-       case RAW_SEARCH_NAME_INFO:
+       case RAW_SEARCH_DATA_NAME_INFO:
                if (blen < 13) return NT_STATUS_INFO_LENGTH_MISMATCH;
                data->name_info.file_index  = IVAL(blob->data, 4);
                len = smbcli_blob_pull_string(NULL, mem_ctx, blob,
@@ -384,7 +398,7 @@ NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx,
                return NT_STATUS_OK;
 
 
-       case RAW_SEARCH_BOTH_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO:
                if (blen < 95) return NT_STATUS_INFO_LENGTH_MISMATCH;
                data->both_directory_info.file_index  = IVAL(blob->data,                4);
                data->both_directory_info.create_time = smbcli_pull_nttime(blob->data,  8);
@@ -407,7 +421,7 @@ NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx,
                return NT_STATUS_OK;
 
 
-       case RAW_SEARCH_ID_FULL_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO:
                if (blen < 81) return NT_STATUS_INFO_LENGTH_MISMATCH;
                data->id_full_directory_info.file_index  = IVAL(blob->data,             4);
                data->id_full_directory_info.create_time = smbcli_pull_nttime(blob->data,  8);
@@ -427,7 +441,7 @@ NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx,
                }
                return NT_STATUS_OK;
 
-       case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO:
                if (blen < 105) return NT_STATUS_INFO_LENGTH_MISMATCH;
                data->id_both_directory_info.file_index  = IVAL(blob->data,             4);
                data->id_both_directory_info.create_time = smbcli_pull_nttime(blob->data,  8);
@@ -467,7 +481,7 @@ NTSTATUS smb_raw_search_common(TALLOC_CTX *mem_ctx,
 */
 static int parse_trans2_search(struct smbcli_tree *tree,
                               TALLOC_CTX *mem_ctx, 
-                              enum smb_search_level level,
+                              enum smb_search_data_level level,
                               uint16_t flags,
                               DATA_BLOB *blob,
                               union smb_search_data *data)
@@ -478,15 +492,12 @@ static int parse_trans2_search(struct smbcli_tree *tree,
        NTSTATUS status;
 
        switch (level) {
-       case RAW_SEARCH_GENERIC:
-       case RAW_SEARCH_SEARCH:
-       case RAW_SEARCH_FFIRST:
-       case RAW_SEARCH_FUNIQUE:
-       case RAW_SEARCH_SMB2:
+       case RAW_SEARCH_DATA_GENERIC:
+       case RAW_SEARCH_DATA_SEARCH:
                /* handled elsewhere */
                return -1;
 
-       case RAW_SEARCH_STANDARD:
+       case RAW_SEARCH_DATA_STANDARD:
                if (flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {
                        if (blob->length < 4) return -1;
                        data->standard.resume_key = IVAL(blob->data, 0);
@@ -508,7 +519,7 @@ static int parse_trans2_search(struct smbcli_tree *tree,
                                           22, 23, STR_LEN8BIT | STR_TERMINATE | STR_LEN_NOTERM);
                return len + 23;
 
-       case RAW_SEARCH_EA_SIZE:
+       case RAW_SEARCH_DATA_EA_SIZE:
                if (flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {
                        if (blob->length < 4) return -1;
                        data->ea_size.resume_key = IVAL(blob->data, 0);
@@ -531,7 +542,7 @@ static int parse_trans2_search(struct smbcli_tree *tree,
                                           26, 27, STR_LEN8BIT | STR_TERMINATE | STR_NOALIGN);
                return len + 27 + 1;
 
-       case RAW_SEARCH_EA_LIST:
+       case RAW_SEARCH_DATA_EA_LIST:
                if (flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {
                        if (blob->length < 4) return -1;
                        data->ea_list.resume_key = IVAL(blob->data, 0);
@@ -569,7 +580,7 @@ static int parse_trans2_search(struct smbcli_tree *tree,
                                              STR_LEN8BIT | STR_NOALIGN);
                return len + ea_size + 23 + 1;
 
-       case RAW_SEARCH_UNIX_INFO:
+       case RAW_SEARCH_DATA_UNIX_INFO:
                if (blob->length < 109) return -1;
                ofs                                  = IVAL(blob->data,             0);
                data->unix_info.file_index           = IVAL(blob->data,             4);
@@ -594,12 +605,12 @@ static int parse_trans2_search(struct smbcli_tree *tree,
                }
                return ofs;
 
-       case RAW_SEARCH_DIRECTORY_INFO:
-       case RAW_SEARCH_FULL_DIRECTORY_INFO:
-       case RAW_SEARCH_NAME_INFO:
-       case RAW_SEARCH_BOTH_DIRECTORY_INFO:
-       case RAW_SEARCH_ID_FULL_DIRECTORY_INFO:
-       case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO: {
+       case RAW_SEARCH_DATA_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_NAME_INFO:
+       case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO: {
                uint_t str_flags = STR_UNICODE;
                if (!(tree->session->transport->negotiate.capabilities & CAP_UNICODE)) {
                        str_flags = STR_ASCII;
@@ -622,7 +633,7 @@ static int parse_trans2_search(struct smbcli_tree *tree,
 ****************************************************************************/
 static NTSTATUS smb_raw_t2search_backend(struct smbcli_tree *tree,
                                         TALLOC_CTX *mem_ctx,
-                                        enum smb_search_level level,
+                                        enum smb_search_data_level level,
                                         uint16_t flags,
                                         int16_t count,
                                         DATA_BLOB *blob,
@@ -668,22 +679,24 @@ NTSTATUS smb_raw_search_first(struct smbcli_tree *tree,
                              union smb_search_first *io, void *private,
                              BOOL (*callback)(void *private, union smb_search_data *file))
 {
-       uint16_t info_level = 0;
        DATA_BLOB p_blob, d_blob;
        NTSTATUS status;
-                       
-       if (io->generic.level == RAW_SEARCH_SEARCH ||
-           io->generic.level == RAW_SEARCH_FFIRST ||
-           io->generic.level == RAW_SEARCH_FUNIQUE) {
+
+       switch (io->generic.level) {
+       case RAW_SEARCH_SEARCH:
+       case RAW_SEARCH_FFIRST:
+       case RAW_SEARCH_FUNIQUE:
                return smb_raw_search_first_old(tree, mem_ctx, io, private, callback);
-       }
-       if (io->generic.level >= RAW_SEARCH_GENERIC) {
+
+       case RAW_SEARCH_TRANS2:
+               break;
+
+       case RAW_SEARCH_SMB2:
                return NT_STATUS_INVALID_LEVEL;
        }
-       info_level = (uint16_t)io->generic.level;
 
        status = smb_raw_search_first_blob(tree, mem_ctx,
-                                          io, info_level, &p_blob, &d_blob);
+                                          io, &p_blob, &d_blob);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -698,9 +711,9 @@ NTSTATUS smb_raw_search_first(struct smbcli_tree *tree,
        io->t2ffirst.out.handle = SVAL(p_blob.data, 0);
        io->t2ffirst.out.count = SVAL(p_blob.data, 2);
        io->t2ffirst.out.end_of_search = SVAL(p_blob.data, 4);
-               
+
        status = smb_raw_t2search_backend(tree, mem_ctx,
-                                         io->generic.level, 
+                                         io->generic.data_level, 
                                          io->t2ffirst.in.flags, io->t2ffirst.out.count,
                                          &d_blob, private, callback);
        
@@ -714,21 +727,26 @@ NTSTATUS smb_raw_search_next(struct smbcli_tree *tree,
                             union smb_search_next *io, void *private,
                             BOOL (*callback)(void *private, union smb_search_data *file))
 {
-       uint16_t info_level = 0;
        DATA_BLOB p_blob, d_blob;
        NTSTATUS status;
 
-       if (io->generic.level == RAW_SEARCH_SEARCH ||
-           io->generic.level == RAW_SEARCH_FFIRST) {
+       switch (io->generic.level) {
+       case RAW_SEARCH_SEARCH:
+       case RAW_SEARCH_FFIRST:
                return smb_raw_search_next_old(tree, mem_ctx, io, private, callback);
-       }
-       if (io->generic.level >= RAW_SEARCH_GENERIC) {
+
+       case RAW_SEARCH_FUNIQUE:
+               return NT_STATUS_INVALID_LEVEL;
+
+       case RAW_SEARCH_TRANS2:
+               break;
+
+       case RAW_SEARCH_SMB2:
                return NT_STATUS_INVALID_LEVEL;
        }
-       info_level = (uint16_t)io->generic.level;
 
        status = smb_raw_search_next_blob(tree, mem_ctx,
-                                         io, info_level, &p_blob, &d_blob);
+                                         io, &p_blob, &d_blob);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -744,7 +762,7 @@ NTSTATUS smb_raw_search_next(struct smbcli_tree *tree,
        io->t2fnext.out.end_of_search = SVAL(p_blob.data, 2);
                
        status = smb_raw_t2search_backend(tree, mem_ctx,
-                                         io->generic.level, 
+                                         io->generic.data_level, 
                                          io->t2fnext.in.flags, io->t2fnext.out.count,
                                          &d_blob, private, callback);
        
index 8f4d6c830110d03716cf52107101f1184605cc68..794e31bed3ec66381aaabe94976d3c23194aeaa4 100644 (file)
@@ -101,27 +101,27 @@ NTSTATUS smb2_find_level_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
        struct smb2_find f;
        NTSTATUS status;
        DATA_BLOB b;
-       enum smb_search_level smb_level;
+       enum smb_search_data_level smb_level;
        uint_t next_ofs=0;
 
        switch (level) {
        case SMB2_FIND_DIRECTORY_INFO:
-               smb_level = RAW_SEARCH_DIRECTORY_INFO;
+               smb_level = RAW_SEARCH_DATA_DIRECTORY_INFO;
                break;
        case SMB2_FIND_FULL_DIRECTORY_INFO:
-               smb_level = RAW_SEARCH_FULL_DIRECTORY_INFO;
+               smb_level = RAW_SEARCH_DATA_FULL_DIRECTORY_INFO;
                break;
        case SMB2_FIND_BOTH_DIRECTORY_INFO:
-               smb_level = RAW_SEARCH_BOTH_DIRECTORY_INFO;
+               smb_level = RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO;
                break;
        case SMB2_FIND_NAME_INFO:
-               smb_level = RAW_SEARCH_NAME_INFO;
+               smb_level = RAW_SEARCH_DATA_NAME_INFO;
                break;
        case SMB2_FIND_ID_FULL_DIRECTORY_INFO:
-               smb_level = RAW_SEARCH_ID_FULL_DIRECTORY_INFO;
+               smb_level = RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO;
                break;
        case SMB2_FIND_ID_BOTH_DIRECTORY_INFO:
-               smb_level = RAW_SEARCH_ID_BOTH_DIRECTORY_INFO;
+               smb_level = RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO;
                break;
        default:
                return NT_STATUS_INVALID_INFO_CLASS;
index f7834a9751f25633266f289442276a610336a50b..34cf8d9565ff0ffe1abe1be1a4672276ce1076fc 100644 (file)
@@ -819,13 +819,13 @@ static void nbench_search_first_send(struct ntvfs_request *req)
        union smb_search_first *io = req->async_states->private_data;
        
        switch (io->generic.level) {
-       case RAW_SEARCH_BOTH_DIRECTORY_INFO:
+       case RAW_SEARCH_TRANS2:
                if (NT_STATUS_IS_ERR(req->async_states->status)) {
                        ZERO_STRUCT(io->t2ffirst.out);
                }
                nbench_log(req, "FIND_FIRST \"%s\" %d %d %d %s\n", 
                           io->t2ffirst.in.pattern,
-                          io->generic.level,
+                          io->t2ffirst.data_level,
                           io->t2ffirst.in.max_count,
                           io->t2ffirst.out.count,
                           get_nt_error_c_code(req->async_states->status));
index 4d218fbe9c36db135febec358d3fc22d4ba82c9f..794d2230608f8b2137f43c0159ac39ebe06689fb 100644 (file)
@@ -68,7 +68,7 @@ static void pvfs_search_setup_timer(struct pvfs_search_state *search)
   fill in a single search result for a given info level
 */
 static NTSTATUS fill_search_info(struct pvfs_state *pvfs,
-                                enum smb_search_level level,
+                                enum smb_search_data_level level,
                                 const char *unix_path,
                                 const char *fname, 
                                 struct pvfs_search_state *search,
@@ -90,9 +90,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs,
        }
 
        switch (level) {
-       case RAW_SEARCH_SEARCH:
-       case RAW_SEARCH_FFIRST:
-       case RAW_SEARCH_FUNIQUE:
+       case RAW_SEARCH_DATA_SEARCH:
                shortname = pvfs_short_name(pvfs, name, name);
                file->search.attrib           = name->dos.attrib;
                file->search.write_time       = nt_time_to_unix(name->dos.write_time);
@@ -107,7 +105,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs,
                file->search.id.client_cookie = 0;
                return NT_STATUS_OK;
 
-       case RAW_SEARCH_STANDARD:
+       case RAW_SEARCH_DATA_STANDARD:
                file->standard.resume_key   = dir_index;
                file->standard.create_time  = nt_time_to_unix(name->dos.create_time);
                file->standard.access_time  = nt_time_to_unix(name->dos.access_time);
@@ -118,7 +116,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs,
                file->standard.name.s       = fname;
                return NT_STATUS_OK;
 
-       case RAW_SEARCH_EA_SIZE:
+       case RAW_SEARCH_DATA_EA_SIZE:
                file->ea_size.resume_key   = dir_index;
                file->ea_size.create_time  = nt_time_to_unix(name->dos.create_time);
                file->ea_size.access_time  = nt_time_to_unix(name->dos.access_time);
@@ -130,7 +128,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs,
                file->ea_size.name.s       = fname;
                return NT_STATUS_OK;
 
-       case RAW_SEARCH_EA_LIST:
+       case RAW_SEARCH_DATA_EA_LIST:
                file->ea_list.resume_key   = dir_index;
                file->ea_list.create_time  = nt_time_to_unix(name->dos.create_time);
                file->ea_list.access_time  = nt_time_to_unix(name->dos.access_time);
@@ -144,7 +142,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs,
                                          search->ea_names,
                                          &file->ea_list.eas);
 
-       case RAW_SEARCH_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_DIRECTORY_INFO:
                file->directory_info.file_index   = dir_index;
                file->directory_info.create_time  = name->dos.create_time;
                file->directory_info.access_time  = name->dos.access_time;
@@ -156,7 +154,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs,
                file->directory_info.name.s       = fname;
                return NT_STATUS_OK;
 
-       case RAW_SEARCH_FULL_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO:
                file->full_directory_info.file_index   = dir_index;
                file->full_directory_info.create_time  = name->dos.create_time;
                file->full_directory_info.access_time  = name->dos.access_time;
@@ -169,12 +167,12 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs,
                file->full_directory_info.name.s       = fname;
                return NT_STATUS_OK;
 
-       case RAW_SEARCH_NAME_INFO:
+       case RAW_SEARCH_DATA_NAME_INFO:
                file->name_info.file_index   = dir_index;
                file->name_info.name.s       = fname;
                return NT_STATUS_OK;
 
-       case RAW_SEARCH_BOTH_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO:
                file->both_directory_info.file_index   = dir_index;
                file->both_directory_info.create_time  = name->dos.create_time;
                file->both_directory_info.access_time  = name->dos.access_time;
@@ -188,7 +186,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs,
                file->both_directory_info.name.s       = fname;
                return NT_STATUS_OK;
 
-       case RAW_SEARCH_ID_FULL_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO:
                file->id_full_directory_info.file_index   = dir_index;
                file->id_full_directory_info.create_time  = name->dos.create_time;
                file->id_full_directory_info.access_time  = name->dos.access_time;
@@ -202,7 +200,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs,
                file->id_full_directory_info.name.s       = fname;
                return NT_STATUS_OK;
 
-       case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO:
                file->id_both_directory_info.file_index   = dir_index;
                file->id_both_directory_info.create_time  = name->dos.create_time;
                file->id_both_directory_info.access_time  = name->dos.access_time;
@@ -217,7 +215,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs,
                file->id_both_directory_info.name.s       = fname;
                return NT_STATUS_OK;
 
-       case RAW_SEARCH_GENERIC:
+       case RAW_SEARCH_DATA_GENERIC:
                break;
        }
 
@@ -231,7 +229,7 @@ static NTSTATUS fill_search_info(struct pvfs_state *pvfs,
 static NTSTATUS pvfs_search_fill(struct pvfs_state *pvfs, TALLOC_CTX *mem_ctx, 
                                 uint_t max_count, 
                                 struct pvfs_search_state *search,
-                                enum smb_search_level level,
+                                enum smb_search_data_level level,
                                 uint_t *reply_count,
                                 void *search_private, 
                                 BOOL (*callback)(void *, union smb_search_data *))
@@ -378,7 +376,7 @@ static NTSTATUS pvfs_search_first_old(struct ntvfs_module_context *ntvfs,
 
        talloc_set_destructor(search, pvfs_search_destructor);
 
-       status = pvfs_search_fill(pvfs, req, io->search_first.in.max_count, search, io->generic.level,
+       status = pvfs_search_fill(pvfs, req, io->search_first.in.max_count, search, io->generic.data_level,
                                  &reply_count, search_private, callback);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -422,7 +420,7 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs,
        search->last_used = time(NULL);
        dir = search->dir;
 
-       status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.level,
+       status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.data_level,
                                  &reply_count, search_private, callback);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -441,10 +439,10 @@ static NTSTATUS pvfs_search_next_old(struct ntvfs_module_context *ntvfs,
 /* 
    list files in a directory matching a wildcard pattern
 */
-NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs,
-                          struct ntvfs_request *req, union smb_search_first *io, 
-                          void *search_private, 
-                          BOOL (*callback)(void *, union smb_search_data *))
+static NTSTATUS pvfs_search_first_trans2(struct ntvfs_module_context *ntvfs,
+                                        struct ntvfs_request *req, union smb_search_first *io, 
+                                        void *search_private, 
+                                        BOOL (*callback)(void *, union smb_search_data *))
 {
        struct pvfs_dir *dir;
        struct pvfs_state *pvfs = ntvfs->private_data;
@@ -456,10 +454,6 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs,
        struct pvfs_filename *name;
        int id;
 
-       if (io->generic.level >= RAW_SEARCH_SEARCH) {
-               return pvfs_search_first_old(ntvfs, req, io, search_private, callback);
-       }
-
        search_attrib = io->t2ffirst.in.search_attrib;
        pattern       = io->t2ffirst.in.pattern;
        max_count     = io->t2ffirst.in.max_count;
@@ -512,7 +506,7 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs,
        DLIST_ADD(pvfs->search.list, search);
        talloc_set_destructor(search, pvfs_search_destructor);
 
-       status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.level,
+       status = pvfs_search_fill(pvfs, req, max_count, search, io->generic.data_level,
                                  &reply_count, search_private, callback);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -541,10 +535,10 @@ NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs,
 }
 
 /* continue a search */
-NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs,
-                         struct ntvfs_request *req, union smb_search_next *io, 
-                         void *search_private, 
-                         BOOL (*callback)(void *, union smb_search_data *))
+static NTSTATUS pvfs_search_next_trans2(struct ntvfs_module_context *ntvfs,
+                                       struct ntvfs_request *req, union smb_search_next *io, 
+                                       void *search_private, 
+                                       BOOL (*callback)(void *, union smb_search_data *))
 {
        struct pvfs_state *pvfs = ntvfs->private_data;
        struct pvfs_search_state *search;
@@ -553,10 +547,6 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs,
        uint16_t handle;
        NTSTATUS status;
 
-       if (io->generic.level >= RAW_SEARCH_SEARCH) {
-               return pvfs_search_next_old(ntvfs, req, io, search_private, callback);
-       }
-
        handle = io->t2fnext.in.handle;
 
        search = idr_find(pvfs->search.idtree, handle);
@@ -586,7 +576,7 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs,
        search->num_ea_names = io->t2fnext.in.num_names;
        search->ea_names = io->t2fnext.in.ea_names;
 
-       status = pvfs_search_fill(pvfs, req, io->t2fnext.in.max_count, search, io->generic.level,
+       status = pvfs_search_fill(pvfs, req, io->t2fnext.in.max_count, search, io->generic.data_level,
                                  &reply_count, search_private, callback);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
@@ -605,18 +595,68 @@ NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs,
        return NT_STATUS_OK;
 }
 
+/* 
+   list files in a directory matching a wildcard pattern
+*/
+NTSTATUS pvfs_search_first(struct ntvfs_module_context *ntvfs,
+                          struct ntvfs_request *req, union smb_search_first *io, 
+                          void *search_private, 
+                          BOOL (*callback)(void *, union smb_search_data *))
+{
+       switch (io->generic.level) {
+       case RAW_SEARCH_SEARCH:
+       case RAW_SEARCH_FFIRST:
+       case RAW_SEARCH_FUNIQUE:
+               return pvfs_search_first_old(ntvfs, req, io, search_private, callback);
+
+       case RAW_SEARCH_TRANS2:
+               return pvfs_search_first_trans2(ntvfs, req, io, search_private, callback);
+       }
+
+       return NT_STATUS_INVALID_LEVEL;
+}
+
+/* continue a search */
+NTSTATUS pvfs_search_next(struct ntvfs_module_context *ntvfs,
+                         struct ntvfs_request *req, union smb_search_next *io, 
+                         void *search_private, 
+                         BOOL (*callback)(void *, union smb_search_data *))
+{
+       switch (io->generic.level) {
+       case RAW_SEARCH_SEARCH:
+       case RAW_SEARCH_FFIRST:
+               return pvfs_search_next_old(ntvfs, req, io, search_private, callback);
+
+       case RAW_SEARCH_FUNIQUE:
+               return NT_STATUS_INVALID_LEVEL;
+
+       case RAW_SEARCH_TRANS2:
+               return pvfs_search_next_trans2(ntvfs, req, io, search_private, callback);
+       }
+
+       return NT_STATUS_INVALID_LEVEL;
+}
+
+
 /* close a search */
 NTSTATUS pvfs_search_close(struct ntvfs_module_context *ntvfs,
                           struct ntvfs_request *req, union smb_search_close *io)
 {
        struct pvfs_state *pvfs = ntvfs->private_data;
        struct pvfs_search_state *search;
-       uint16_t handle;
+       uint16_t handle = 0;
 
-       if (io->generic.level == RAW_FINDCLOSE_FCLOSE) {
+       switch (io->generic.level) {
+       case RAW_FINDCLOSE_GENERIC:
+               return NT_STATUS_INVALID_LEVEL;
+
+       case RAW_FINDCLOSE_FCLOSE:
                handle = io->fclose.in.id.handle;
-       } else {
+               break;
+
+       case RAW_FINDCLOSE_FINDCLOSE:
                handle = io->findclose.in.handle;
+               break;
        }
 
        search = idr_find(pvfs->search.idtree, handle);
index 9e5d4ae922d8eb528847bf949fbfd74880a0d277..beffe2b546b826999d90ba2f241b242ee96df23f 100644 (file)
@@ -838,7 +838,11 @@ static NTSTATUS svfs_search_first(struct ntvfs_module_context *ntvfs,
        union smb_search_data file;
        uint_t max_count;
 
-       if (io->generic.level != RAW_SEARCH_BOTH_DIRECTORY_INFO) {
+       if (io->generic.level != RAW_SEARCH_TRANS2) {
+               return NT_STATUS_NOT_SUPPORTED;
+       }
+
+       if (io->generic.data_level != RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO) {
                return NT_STATUS_NOT_SUPPORTED;
        }
 
@@ -908,7 +912,11 @@ static NTSTATUS svfs_search_next(struct ntvfs_module_context *ntvfs,
        union smb_search_data file;
        uint_t max_count;
 
-       if (io->generic.level != RAW_SEARCH_BOTH_DIRECTORY_INFO) {
+       if (io->generic.level != RAW_SEARCH_TRANS2) {
+               return NT_STATUS_NOT_SUPPORTED;
+       }
+
+       if (io->generic.data_level != RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO) {
                return NT_STATUS_NOT_SUPPORTED;
        }
 
index 07d1e0480d726afa4f1b3893fbbfc460ff5eb0ff..a456e04b345c17bc0ce9234fc7a049a43357f21a 100644 (file)
@@ -593,7 +593,7 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx,
 */
 NTSTATUS smbsrv_push_passthru_search(TALLOC_CTX *mem_ctx,
                                     DATA_BLOB *blob,
-                                    enum smb_search_level level,
+                                    enum smb_search_data_level level,
                                     union smb_search_data *file,
                                     int default_str_flags)
 {
@@ -601,7 +601,7 @@ NTSTATUS smbsrv_push_passthru_search(TALLOC_CTX *mem_ctx,
        uint_t ofs = blob->length;
 
        switch (level) {
-       case RAW_SEARCH_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_DIRECTORY_INFO:
                BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 64));
                data = blob->data + ofs;
                SIVAL(data,          4, file->directory_info.file_index);
@@ -619,7 +619,7 @@ NTSTATUS smbsrv_push_passthru_search(TALLOC_CTX *mem_ctx,
                SIVAL(data,          0, blob->length - ofs);
                return NT_STATUS_OK;
 
-       case RAW_SEARCH_FULL_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO:
                BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 68));
                data = blob->data + ofs;
                SIVAL(data,          4, file->full_directory_info.file_index);
@@ -638,7 +638,7 @@ NTSTATUS smbsrv_push_passthru_search(TALLOC_CTX *mem_ctx,
                SIVAL(data,          0, blob->length - ofs);
                return NT_STATUS_OK;
 
-       case RAW_SEARCH_NAME_INFO:
+       case RAW_SEARCH_DATA_NAME_INFO:
                BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 12));
                data = blob->data + ofs;
                SIVAL(data,          4, file->name_info.file_index);
@@ -649,7 +649,7 @@ NTSTATUS smbsrv_push_passthru_search(TALLOC_CTX *mem_ctx,
                SIVAL(data,          0, blob->length - ofs);
                return NT_STATUS_OK;
 
-       case RAW_SEARCH_BOTH_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO:
                BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 94));
                data = blob->data + ofs;
                SIVAL(data,          4, file->both_directory_info.file_index);
@@ -679,7 +679,7 @@ NTSTATUS smbsrv_push_passthru_search(TALLOC_CTX *mem_ctx,
                SIVAL(data,          0, blob->length - ofs);
                return NT_STATUS_OK;
 
-       case RAW_SEARCH_ID_FULL_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO:
                BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 80));
                data = blob->data + ofs;
                SIVAL(data,          4, file->id_full_directory_info.file_index);
@@ -700,7 +700,7 @@ NTSTATUS smbsrv_push_passthru_search(TALLOC_CTX *mem_ctx,
                SIVAL(data,          0, blob->length - ofs);
                return NT_STATUS_OK;
 
-       case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO:
                BLOB_CHECK(smbsrv_blob_grow_data(mem_ctx, blob, ofs + 104));
                data = blob->data + ofs;
                SIVAL(data,          4, file->id_both_directory_info.file_index);
index b86c0ddb7e4dbd7c7e548e49ff050b68b34b06bd..cc6d866ac72ec387d99bdd3965b3de8a2763c62d 100644 (file)
@@ -185,6 +185,7 @@ void smbsrv_reply_search(struct smbsrv_request *req)
                sn->search_next.in.id.client_cookie = IVAL(p, 17);
 
                sn->search_next.level = level;
+               sn->search_next.data_level = RAW_SEARCH_DATA_SEARCH;
                sn->search_next.in.max_count     = SVAL(req->in.vwv, VWV(0));
                sn->search_next.in.search_attrib = SVAL(req->in.vwv, VWV(1));
 
@@ -195,6 +196,7 @@ void smbsrv_reply_search(struct smbsrv_request *req)
 
                /* do a search first operation */
                sf->search_first.level = level;
+               sf->search_first.data_level = RAW_SEARCH_DATA_SEARCH;
                sf->search_first.in.search_attrib = SVAL(req->in.vwv, VWV(1));
                sf->search_first.in.max_count     = SVAL(req->in.vwv, VWV(0));
 
index a8fe9f165d29dc2a6c1306f1f84f4a53c87af379..8a4abd8e60f94e24f953d40c45da6f53f717ba20 100644 (file)
@@ -682,7 +682,7 @@ static NTSTATUS trans2_setpathinfo(struct smbsrv_request *req, struct trans_op *
 struct find_state {
        struct trans_op *op;
        void *search;
-       enum smb_search_level level;
+       enum smb_search_data_level data_level;
        uint16_t last_entry_offset;
        uint16_t flags;
 };
@@ -699,16 +699,13 @@ static NTSTATUS find_fill_info(struct find_state *state,
        uint_t ofs = trans->out.data.length;
        uint32_t ea_size;
 
-       switch (state->level) {
-       case RAW_SEARCH_SEARCH:
-       case RAW_SEARCH_FFIRST:
-       case RAW_SEARCH_FUNIQUE:
-       case RAW_SEARCH_GENERIC:
-       case RAW_SEARCH_SMB2:
+       switch (state->data_level) {
+       case RAW_SEARCH_DATA_GENERIC:
+       case RAW_SEARCH_DATA_SEARCH:
                /* handled elsewhere */
                return NT_STATUS_INVALID_LEVEL;
 
-       case RAW_SEARCH_STANDARD:
+       case RAW_SEARCH_DATA_STANDARD:
                if (state->flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {
                        TRANS2_CHECK(smbsrv_blob_grow_data(trans, &trans->out.data, ofs + 27));
                        SIVAL(trans->out.data.data, ofs, file->standard.resume_key);
@@ -728,7 +725,7 @@ static NTSTATUS find_fill_info(struct find_state *state,
                                                       STR_LEN8BIT | STR_TERMINATE | STR_LEN_NOTERM));
                break;
 
-       case RAW_SEARCH_EA_SIZE:
+       case RAW_SEARCH_DATA_EA_SIZE:
                if (state->flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {
                        TRANS2_CHECK(smbsrv_blob_grow_data(trans, &trans->out.data, ofs + 31));
                        SIVAL(trans->out.data.data, ofs, file->ea_size.resume_key);
@@ -750,7 +747,7 @@ static NTSTATUS find_fill_info(struct find_state *state,
                TRANS2_CHECK(smbsrv_blob_fill_data(trans, &trans->out.data, trans->out.data.length + 1));
                break;
 
-       case RAW_SEARCH_EA_LIST:
+       case RAW_SEARCH_DATA_EA_LIST:
                ea_size = ea_list_size(file->ea_list.eas.num_eas, file->ea_list.eas.eas);
                if (state->flags & FLAG_TRANS2_FIND_REQUIRE_RESUME) {
                        TRANS2_CHECK(smbsrv_blob_grow_data(trans, &trans->out.data, ofs + 27 + ea_size));
@@ -773,14 +770,17 @@ static NTSTATUS find_fill_info(struct find_state *state,
                TRANS2_CHECK(smbsrv_blob_fill_data(trans, &trans->out.data, trans->out.data.length + 1));
                break;
 
-       case RAW_SEARCH_DIRECTORY_INFO:
-       case RAW_SEARCH_FULL_DIRECTORY_INFO:
-       case RAW_SEARCH_NAME_INFO:
-       case RAW_SEARCH_BOTH_DIRECTORY_INFO:
-       case RAW_SEARCH_ID_FULL_DIRECTORY_INFO:
-       case RAW_SEARCH_ID_BOTH_DIRECTORY_INFO:
-               return smbsrv_push_passthru_search(trans, &trans->out.data, state->level, file,
+       case RAW_SEARCH_DATA_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_FULL_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_NAME_INFO:
+       case RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO:
+       case RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO:
+               return smbsrv_push_passthru_search(trans, &trans->out.data, state->data_level, file,
                                                   SMBSRV_REQ_DEFAULT_STR_FLAGS(req));
+
+       case RAW_SEARCH_DATA_UNIX_INFO:
+               return NT_STATUS_INVALID_LEVEL;
        }
 
        return NT_STATUS_OK;
@@ -861,12 +861,13 @@ static NTSTATUS trans2_findfirst(struct smbsrv_request *req, struct trans_op *op
                return NT_STATUS_FOOBAR;
        }
 
-       search->t2ffirst.level = (enum smb_search_level)level;
-       if (search->t2ffirst.level >= RAW_SEARCH_GENERIC) {
+       search->t2ffirst.level = RAW_SEARCH_TRANS2;
+       search->t2ffirst.data_level = (enum smb_search_data_level)level;
+       if (search->t2ffirst.data_level >= RAW_SEARCH_DATA_GENERIC) {
                return NT_STATUS_INVALID_LEVEL;
        }
 
-       if (search->t2ffirst.level == RAW_SEARCH_EA_LIST) {
+       if (search->t2ffirst.data_level == RAW_SEARCH_DATA_EA_LIST) {
                TRANS2_CHECK(ea_pull_name_list(&trans->in.data, req,
                                               &search->t2ffirst.in.num_names, 
                                               &search->t2ffirst.in.ea_names));
@@ -878,7 +879,7 @@ static NTSTATUS trans2_findfirst(struct smbsrv_request *req, struct trans_op *op
        NT_STATUS_HAVE_NO_MEMORY(state);
        state->op               = op;
        state->search           = search;
-       state->level            = search->t2ffirst.level;
+       state->data_level       = search->t2ffirst.data_level;
        state->last_entry_offset= 0;
        state->flags            = search->t2ffirst.in.flags;
 
@@ -946,12 +947,13 @@ static NTSTATUS trans2_findnext(struct smbsrv_request *req, struct trans_op *op)
                return NT_STATUS_FOOBAR;
        }
 
-       search->t2fnext.level = (enum smb_search_level)level;
-       if (search->t2fnext.level >= RAW_SEARCH_GENERIC) {
+       search->t2fnext.level = RAW_SEARCH_TRANS2;
+       search->t2fnext.data_level = (enum smb_search_data_level)level;
+       if (search->t2fnext.data_level >= RAW_SEARCH_DATA_GENERIC) {
                return NT_STATUS_INVALID_LEVEL;
        }
 
-       if (search->t2fnext.level == RAW_SEARCH_EA_LIST) {
+       if (search->t2fnext.data_level == RAW_SEARCH_DATA_EA_LIST) {
                TRANS2_CHECK(ea_pull_name_list(&trans->in.data, req,
                                               &search->t2fnext.in.num_names, 
                                               &search->t2fnext.in.ea_names));
@@ -962,7 +964,7 @@ static NTSTATUS trans2_findnext(struct smbsrv_request *req, struct trans_op *op)
        NT_STATUS_HAVE_NO_MEMORY(state);
        state->op               = op;
        state->search           = search;
-       state->level            = search->t2fnext.level;
+       state->data_level       = search->t2fnext.data_level;
        state->last_entry_offset= 0;
        state->flags            = search->t2fnext.in.flags;
 
index a220e524388f329336af9ebada0acd38e9d33784..a71fed32b74652e1a8e95137ead3bb57ce461b57 100644 (file)
@@ -44,7 +44,9 @@ static BOOL check_delete_on_close(struct smbcli_state *cli, int fnum,
        BOOL res = True;
 
        status = torture_single_search(cli, mem_ctx,
-                                      fname, RAW_SEARCH_FULL_DIRECTORY_INFO,
+                                      fname,
+                                      RAW_SEARCH_TRANS2,
+                                      RAW_SEARCH_DATA_FULL_DIRECTORY_INFO,
                                       FILE_ATTRIBUTE_DIRECTORY,
                                       &data);
        if (!NT_STATUS_IS_OK(status)) {
index 6e2678ed80f2784445ddf91625fc55f5162313b8..8facd6a3ebaee923193d8514a1afbe2c864d503e 100644 (file)
@@ -128,7 +128,7 @@ static void get_real_name(struct smbcli_state *cli,
 
        smbcli_list_new(cli->tree, mask, 
                        FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY, 
-                       RAW_SEARCH_BOTH_DIRECTORY_INFO,
+                       RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO,
                        listfn, NULL);
 
        if (f_info_hit) {
@@ -169,7 +169,7 @@ static void testpair(struct smbcli_state *cli, char *mask, char *file)
        fstrcpy(res1, "---");
        smbcli_list_new(cli->tree, mask, 
                        FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_DIRECTORY, 
-                       RAW_SEARCH_BOTH_DIRECTORY_INFO,
+                       RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO,
                        listfn, NULL);
 
        res2 = reg_test(cli, mask, long_name, short_name);
index a7675f3e3e9b86971133ffa72831c86055793e9c..c4344d5c7320db8610e1557eabfc2868cfd63d94 100644 (file)
 static NTSTATUS single_search(struct smbcli_state *cli,
                               TALLOC_CTX *mem_ctx, const char *pattern)
 {
-        union smb_search_first io;
-        NTSTATUS status;
-                                                                                                                                   
-        io.generic.level = RAW_SEARCH_STANDARD;
+       union smb_search_first io;
+       NTSTATUS status;
+
+       io.t2ffirst.level = RAW_SEARCH_TRANS2;
+       io.t2ffirst.data_level = RAW_SEARCH_DATA_STANDARD;
        io.t2ffirst.in.search_attrib = 0;
        io.t2ffirst.in.max_count = 1;
        io.t2ffirst.in.flags = FLAG_TRANS2_FIND_CLOSE;
@@ -49,9 +50,9 @@ static NTSTATUS single_search(struct smbcli_state *cli,
        io.t2ffirst.in.pattern = pattern;
 
        status = smb_raw_search_first(cli->tree, mem_ctx,
-                       &io, NULL, NULL);
-                                                                                                                                   
-        return status;
+                                     &io, NULL, NULL);
+
+       return status;
 }
 
 static BOOL test_path(struct smbcli_state *cli, const char *path, NTSTATUS expected, NTSTATUS dos_expected)
index e90cbdfbf9543e41709eb87bf8ae19bf6e1e80be..d4e317d9fbd1d118f6202ffe1cd5a216c855b4ca 100644 (file)
@@ -47,6 +47,7 @@ NTSTATUS torture_single_search(struct smbcli_state *cli,
                               TALLOC_CTX *mem_ctx,
                               const char *pattern,
                               enum smb_search_level level,
+                              enum smb_search_data_level data_level,
                               uint16_t attrib,
                               union smb_search_data *data)
 {
@@ -54,19 +55,29 @@ NTSTATUS torture_single_search(struct smbcli_state *cli,
        union smb_search_close c;
        NTSTATUS status;
 
-       io.generic.level = level;
-       if (level == RAW_SEARCH_SEARCH ||
-           level == RAW_SEARCH_FFIRST ||
-           level == RAW_SEARCH_FUNIQUE) {
+       switch (level) {
+       case RAW_SEARCH_SEARCH:
+       case RAW_SEARCH_FFIRST:
+       case RAW_SEARCH_FUNIQUE:
+               io.search_first.level = level;
+               io.search_first.data_level = RAW_SEARCH_DATA_SEARCH;
                io.search_first.in.max_count = 1;
                io.search_first.in.search_attrib = attrib;
                io.search_first.in.pattern = pattern;
-       } else {
+               break;
+
+       case RAW_SEARCH_TRANS2:
+               io.t2ffirst.level = RAW_SEARCH_TRANS2;
+               io.t2ffirst.data_level = data_level;
                io.t2ffirst.in.search_attrib = attrib;
                io.t2ffirst.in.max_count = 1;
                io.t2ffirst.in.flags = FLAG_TRANS2_FIND_CLOSE;
                io.t2ffirst.in.storage_type = 0;
                io.t2ffirst.in.pattern = pattern;
+               break;
+
+       case RAW_SEARCH_SMB2:
+               return NT_STATUS_INVALID_LEVEL;
        }
 
        status = smb_raw_search_first(cli->tree, mem_ctx,
@@ -87,57 +98,70 @@ NTSTATUS torture_single_search(struct smbcli_state *cli,
 static struct {
        const char *name;
        enum smb_search_level level;
+       enum smb_search_data_level data_level;
        int name_offset;
        int resume_key_offset;
        uint32_t capability_mask;
        NTSTATUS status;
        union smb_search_data data;
 } levels[] = {
-       {"FFIRST",                 RAW_SEARCH_FFIRST, 
+       {"FFIRST",
+        RAW_SEARCH_FFIRST, RAW_SEARCH_DATA_SEARCH,
         offsetof(union smb_search_data, search.name),
         -1,
        },
-       {"FUNIQUE",                RAW_SEARCH_FUNIQUE, 
+       {"FUNIQUE",
+        RAW_SEARCH_FUNIQUE, RAW_SEARCH_DATA_SEARCH,
         offsetof(union smb_search_data, search.name),
         -1,
        },
-       {"SEARCH",                 RAW_SEARCH_SEARCH, 
+       {"SEARCH",
+        RAW_SEARCH_SEARCH, RAW_SEARCH_DATA_SEARCH,
         offsetof(union smb_search_data, search.name),
         -1,
        },
-       {"STANDARD",               RAW_SEARCH_STANDARD, 
+       {"STANDARD",
+        RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_STANDARD, 
         offsetof(union smb_search_data, standard.name.s),
         offsetof(union smb_search_data, standard.resume_key),
        },
-       {"EA_SIZE",                RAW_SEARCH_EA_SIZE, 
+       {"EA_SIZE",
+        RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_EA_SIZE, 
         offsetof(union smb_search_data, ea_size.name.s),
         offsetof(union smb_search_data, ea_size.resume_key),
        },
-       {"DIRECTORY_INFO",         RAW_SEARCH_DIRECTORY_INFO, 
+       {"DIRECTORY_INFO",
+        RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_DIRECTORY_INFO, 
         offsetof(union smb_search_data, directory_info.name.s),
         offsetof(union smb_search_data, directory_info.file_index),
        },
-       {"FULL_DIRECTORY_INFO",    RAW_SEARCH_FULL_DIRECTORY_INFO, 
+       {"FULL_DIRECTORY_INFO",
+        RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, 
         offsetof(union smb_search_data, full_directory_info.name.s),
         offsetof(union smb_search_data, full_directory_info.file_index),
        },
-       {"NAME_INFO",              RAW_SEARCH_NAME_INFO, 
+       {"NAME_INFO",
+        RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_NAME_INFO, 
         offsetof(union smb_search_data, name_info.name.s),
         offsetof(union smb_search_data, name_info.file_index),
        },
-       {"BOTH_DIRECTORY_INFO",    RAW_SEARCH_BOTH_DIRECTORY_INFO, 
+       {"BOTH_DIRECTORY_INFO",
+        RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, 
         offsetof(union smb_search_data, both_directory_info.name.s),
         offsetof(union smb_search_data, both_directory_info.file_index),
        },
-       {"ID_FULL_DIRECTORY_INFO", RAW_SEARCH_ID_FULL_DIRECTORY_INFO, 
+       {"ID_FULL_DIRECTORY_INFO",
+        RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, 
         offsetof(union smb_search_data, id_full_directory_info.name.s),
         offsetof(union smb_search_data, id_full_directory_info.file_index),
        },
-       {"ID_BOTH_DIRECTORY_INFO", RAW_SEARCH_ID_BOTH_DIRECTORY_INFO, 
+       {"ID_BOTH_DIRECTORY_INFO",
+        RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, 
         offsetof(union smb_search_data, id_both_directory_info.name.s),
         offsetof(union smb_search_data, id_both_directory_info.file_index),
        },
-       {"UNIX_INFO",              RAW_SEARCH_UNIX_INFO, 
+       {"UNIX_INFO",
+        RAW_SEARCH_TRANS2, RAW_SEARCH_DATA_UNIX_INFO, 
         offsetof(union smb_search_data, unix_info.name),
         offsetof(union smb_search_data, unix_info.file_index),
         CAP_UNIX}
@@ -147,11 +171,13 @@ static struct {
 /*
   return level name
 */
-static const char *level_name(enum smb_search_level level)
+static const char *level_name(enum smb_search_level level,
+                             enum smb_search_data_level data_level)
 {
        int i;
        for (i=0;i<ARRAY_SIZE(levels);i++) {
-               if (level == levels[i].level) {
+               if (level == levels[i].level &&
+                   data_level == levels[i].data_level) {
                        return levels[i].name;
                }
        }
@@ -161,11 +187,13 @@ static const char *level_name(enum smb_search_level level)
 /*
   extract the name from a smb_data structure and level
 */
-static const char *extract_name(void *data, enum smb_search_level level)
+static const char *extract_name(void *data, enum smb_search_level level,
+                               enum smb_search_data_level data_level)
 {
        int i;
        for (i=0;i<ARRAY_SIZE(levels);i++) {
-               if (level == levels[i].level) {
+               if (level == levels[i].level &&
+                   data_level == levels[i].data_level) {
                        return *(const char **)(levels[i].name_offset + (char *)data);
                }
        }
@@ -175,11 +203,13 @@ static const char *extract_name(void *data, enum smb_search_level level)
 /*
   extract the name from a smb_data structure and level
 */
-static int extract_resume_key(void *data, enum smb_search_level level)
+static int extract_resume_key(void *data, enum smb_search_level level,
+                             enum smb_search_data_level data_level)
 {
        int i;
        for (i=0;i<ARRAY_SIZE(levels);i++) {
-               if (level == levels[i].level) {
+               if (level == levels[i].level &&
+                   data_level == levels[i].data_level) {
                        return (int)*(uint32_t *)(levels[i].resume_key_offset + (char *)data);
                }
        }
@@ -230,7 +260,9 @@ static BOOL test_one_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
                printf("testing %s\n", levels[i].name);
 
                levels[i].status = torture_single_search(cli, mem_ctx, fname, 
-                                                        levels[i].level, 0,
+                                                        levels[i].level,
+                                                        levels[i].data_level,
+                                                        0,
                                                         &levels[i].data);
 
                /* see if this server claims to support this level */
@@ -249,7 +281,9 @@ static BOOL test_one_file(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
                }
 
                status = torture_single_search(cli, mem_ctx, fname2, 
-                                              levels[i].level, 0,
+                                              levels[i].level,
+                                              levels[i].data_level,
+                                              0,
                                               &levels[i].data);
                
                expected_status = NT_STATUS_NO_SUCH_FILE;
@@ -517,7 +551,7 @@ enum continue_type {CONT_FLAGS, CONT_NAME, CONT_RESUME_KEY};
 static NTSTATUS multiple_search(struct smbcli_state *cli, 
                                TALLOC_CTX *mem_ctx,
                                const char *pattern,
-                               enum smb_search_level level,
+                               enum smb_search_data_level data_level,
                                enum continue_type cont_type,
                                void *data)
 {
@@ -527,12 +561,15 @@ static NTSTATUS multiple_search(struct smbcli_state *cli,
        const int per_search = 100;
        struct multiple_result *result = data;
 
-       io.generic.level = level;
-       if (level == RAW_SEARCH_SEARCH) {
+       if (data_level == RAW_SEARCH_DATA_SEARCH) {
+               io.search_first.level = RAW_SEARCH_SEARCH;
+               io.search_first.data_level = RAW_SEARCH_DATA_SEARCH;
                io.search_first.in.max_count = per_search;
                io.search_first.in.search_attrib = 0;
                io.search_first.in.pattern = pattern;
        } else {
+               io.t2ffirst.level = RAW_SEARCH_TRANS2;
+               io.t2ffirst.data_level = data_level;
                io.t2ffirst.in.search_attrib = 0;
                io.t2ffirst.in.max_count = per_search;
                io.t2ffirst.in.flags = FLAG_TRANS2_FIND_CLOSE_IF_END;
@@ -549,12 +586,15 @@ static NTSTATUS multiple_search(struct smbcli_state *cli,
        
 
        while (NT_STATUS_IS_OK(status)) {
-               io2.generic.level = level;
-               if (level == RAW_SEARCH_SEARCH) {
+               if (data_level == RAW_SEARCH_DATA_SEARCH) {
+                       io2.search_next.level = RAW_SEARCH_SEARCH;
+                       io2.search_next.data_level = RAW_SEARCH_DATA_SEARCH;
                        io2.search_next.in.max_count = per_search;
                        io2.search_next.in.search_attrib = 0;
                        io2.search_next.in.id = result->list[result->count-1].search.id;
                } else {
+                       io2.t2fnext.level = RAW_SEARCH_TRANS2;
+                       io2.t2fnext.data_level = data_level;
                        io2.t2fnext.in.handle = io.t2ffirst.out.handle;
                        io2.t2fnext.in.max_count = per_search;
                        io2.t2fnext.in.resume_key = 0;
@@ -562,17 +602,19 @@ static NTSTATUS multiple_search(struct smbcli_state *cli,
                        io2.t2fnext.in.last_name = "";
                        switch (cont_type) {
                        case CONT_RESUME_KEY:
-                               io2.t2fnext.in.resume_key = extract_resume_key(&result->list[result->count-1], level);
+                               io2.t2fnext.in.resume_key = extract_resume_key(&result->list[result->count-1],
+                                                                              io2.t2fnext.level, io2.t2fnext.data_level);
                                if (io2.t2fnext.in.resume_key <= 0) {
                                        printf("Server does not support resume by key for level %s\n",
-                                              level_name(level));
+                                              level_name(io2.t2fnext.level, io2.t2fnext.data_level));
                                        return NT_STATUS_NOT_SUPPORTED;
                                }
                                io2.t2fnext.in.flags |= FLAG_TRANS2_FIND_REQUIRE_RESUME |
                                        FLAG_TRANS2_FIND_BACKUP_INTENT;
                                break;
                        case CONT_NAME:
-                               io2.t2fnext.in.last_name = extract_name(&result->list[result->count-1], level);
+                               io2.t2fnext.in.last_name = extract_name(&result->list[result->count-1],
+                                                                       io2.t2fnext.level, io2.t2fnext.data_level);
                                break;
                        case CONT_FLAGS:
                                io2.t2fnext.in.flags |= FLAG_TRANS2_FIND_CONTINUE;
@@ -585,7 +627,7 @@ static NTSTATUS multiple_search(struct smbcli_state *cli,
                if (!NT_STATUS_IS_OK(status)) {
                        break;
                }
-               if (level == RAW_SEARCH_SEARCH) {
+               if (data_level == RAW_SEARCH_DATA_SEARCH) {
                        if (io2.search_next.out.count == 0) {
                                break;
                        }
@@ -622,13 +664,21 @@ static NTSTATUS multiple_search(struct smbcli_state *cli,
        }} while (0)
 
 
-static enum smb_search_level compare_level;
+static enum smb_search_data_level compare_data_level;
 
 static int search_compare(union smb_search_data *d1, union smb_search_data *d2)
 {
        const char *s1, *s2;
-       s1 = extract_name(d1, compare_level);
-       s2 = extract_name(d2, compare_level);
+       enum smb_search_level level;
+
+       if (compare_data_level == RAW_SEARCH_DATA_SEARCH) {
+               level = RAW_SEARCH_SEARCH;
+       } else {
+               level = RAW_SEARCH_TRANS2;
+       }
+
+       s1 = extract_name(d1, level, compare_data_level);
+       s2 = extract_name(d2, level, compare_data_level);
        return strcmp_safe(s1, s2);
 }
 
@@ -648,31 +698,31 @@ static BOOL test_many_files(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        struct {
                const char *name;
                const char *cont_name;
-               enum smb_search_level level;
+               enum smb_search_data_level data_level;
                enum continue_type cont_type;
        } search_types[] = {
-               {"SEARCH",              "ID",    RAW_SEARCH_SEARCH,              CONT_RESUME_KEY},
-               {"BOTH_DIRECTORY_INFO", "NAME",  RAW_SEARCH_BOTH_DIRECTORY_INFO, CONT_NAME},
-               {"BOTH_DIRECTORY_INFO", "FLAGS", RAW_SEARCH_BOTH_DIRECTORY_INFO, CONT_FLAGS},
-               {"BOTH_DIRECTORY_INFO", "KEY",   RAW_SEARCH_BOTH_DIRECTORY_INFO, CONT_RESUME_KEY},
-               {"STANDARD",            "FLAGS", RAW_SEARCH_STANDARD,            CONT_FLAGS},
-               {"STANDARD",            "KEY",   RAW_SEARCH_STANDARD,            CONT_RESUME_KEY},
-               {"STANDARD",            "NAME",  RAW_SEARCH_STANDARD,            CONT_NAME},
-               {"EA_SIZE",             "FLAGS", RAW_SEARCH_EA_SIZE,             CONT_FLAGS},
-               {"EA_SIZE",             "KEY",   RAW_SEARCH_EA_SIZE,             CONT_RESUME_KEY},
-               {"EA_SIZE",             "NAME",  RAW_SEARCH_EA_SIZE,             CONT_NAME},
-               {"DIRECTORY_INFO",      "FLAGS", RAW_SEARCH_DIRECTORY_INFO,      CONT_FLAGS},
-               {"DIRECTORY_INFO",      "KEY",   RAW_SEARCH_DIRECTORY_INFO,      CONT_RESUME_KEY},
-               {"DIRECTORY_INFO",      "NAME",  RAW_SEARCH_DIRECTORY_INFO,      CONT_NAME},
-               {"FULL_DIRECTORY_INFO",    "FLAGS", RAW_SEARCH_FULL_DIRECTORY_INFO,    CONT_FLAGS},
-               {"FULL_DIRECTORY_INFO",    "KEY",   RAW_SEARCH_FULL_DIRECTORY_INFO,    CONT_RESUME_KEY},
-               {"FULL_DIRECTORY_INFO",    "NAME",  RAW_SEARCH_FULL_DIRECTORY_INFO,    CONT_NAME},
-               {"ID_FULL_DIRECTORY_INFO", "FLAGS", RAW_SEARCH_ID_FULL_DIRECTORY_INFO, CONT_FLAGS},
-               {"ID_FULL_DIRECTORY_INFO", "KEY",   RAW_SEARCH_ID_FULL_DIRECTORY_INFO, CONT_RESUME_KEY},
-               {"ID_FULL_DIRECTORY_INFO", "NAME",  RAW_SEARCH_ID_FULL_DIRECTORY_INFO, CONT_NAME},
-               {"ID_BOTH_DIRECTORY_INFO", "NAME",  RAW_SEARCH_ID_BOTH_DIRECTORY_INFO, CONT_NAME},
-               {"ID_BOTH_DIRECTORY_INFO", "FLAGS", RAW_SEARCH_ID_BOTH_DIRECTORY_INFO, CONT_FLAGS},
-               {"ID_BOTH_DIRECTORY_INFO", "KEY",   RAW_SEARCH_ID_BOTH_DIRECTORY_INFO, CONT_RESUME_KEY}
+               {"SEARCH",              "ID",    RAW_SEARCH_DATA_SEARCH,              CONT_RESUME_KEY},
+               {"BOTH_DIRECTORY_INFO", "NAME",  RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_NAME},
+               {"BOTH_DIRECTORY_INFO", "FLAGS", RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_FLAGS},
+               {"BOTH_DIRECTORY_INFO", "KEY",   RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_RESUME_KEY},
+               {"STANDARD",            "FLAGS", RAW_SEARCH_DATA_STANDARD,            CONT_FLAGS},
+               {"STANDARD",            "KEY",   RAW_SEARCH_DATA_STANDARD,            CONT_RESUME_KEY},
+               {"STANDARD",            "NAME",  RAW_SEARCH_DATA_STANDARD,            CONT_NAME},
+               {"EA_SIZE",             "FLAGS", RAW_SEARCH_DATA_EA_SIZE,             CONT_FLAGS},
+               {"EA_SIZE",             "KEY",   RAW_SEARCH_DATA_EA_SIZE,             CONT_RESUME_KEY},
+               {"EA_SIZE",             "NAME",  RAW_SEARCH_DATA_EA_SIZE,             CONT_NAME},
+               {"DIRECTORY_INFO",      "FLAGS", RAW_SEARCH_DATA_DIRECTORY_INFO,      CONT_FLAGS},
+               {"DIRECTORY_INFO",      "KEY",   RAW_SEARCH_DATA_DIRECTORY_INFO,      CONT_RESUME_KEY},
+               {"DIRECTORY_INFO",      "NAME",  RAW_SEARCH_DATA_DIRECTORY_INFO,      CONT_NAME},
+               {"FULL_DIRECTORY_INFO",    "FLAGS", RAW_SEARCH_DATA_FULL_DIRECTORY_INFO,    CONT_FLAGS},
+               {"FULL_DIRECTORY_INFO",    "KEY",   RAW_SEARCH_DATA_FULL_DIRECTORY_INFO,    CONT_RESUME_KEY},
+               {"FULL_DIRECTORY_INFO",    "NAME",  RAW_SEARCH_DATA_FULL_DIRECTORY_INFO,    CONT_NAME},
+               {"ID_FULL_DIRECTORY_INFO", "FLAGS", RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_FLAGS},
+               {"ID_FULL_DIRECTORY_INFO", "KEY",   RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_RESUME_KEY},
+               {"ID_FULL_DIRECTORY_INFO", "NAME",  RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_NAME},
+               {"ID_BOTH_DIRECTORY_INFO", "NAME",  RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_NAME},
+               {"ID_BOTH_DIRECTORY_INFO", "FLAGS", RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_FLAGS},
+               {"ID_BOTH_DIRECTORY_INFO", "KEY",   RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_RESUME_KEY}
        };
 
        if (!torture_setup_dir(cli, BASEDIR)) {
@@ -701,7 +751,7 @@ static BOOL test_many_files(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
                printf("Continue %s via %s\n", search_types[t].name, search_types[t].cont_name);
 
                status = multiple_search(cli, mem_ctx, BASEDIR "\\*.*", 
-                                        search_types[t].level,
+                                        search_types[t].data_level,
                                         search_types[t].cont_type,
                                         &result);
        
@@ -714,14 +764,20 @@ static BOOL test_many_files(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
                }
                CHECK_VALUE(result.count, num_files);
 
-               compare_level = search_types[t].level;
+               compare_data_level = search_types[t].data_level;
 
                qsort(result.list, result.count, sizeof(result.list[0]), 
                      QSORT_CAST  search_compare);
 
                for (i=0;i<result.count;i++) {
                        const char *s;
-                       s = extract_name(&result.list[i], compare_level);
+                       enum smb_search_level level;
+                       if (compare_data_level == RAW_SEARCH_DATA_SEARCH) {
+                               level = RAW_SEARCH_SEARCH;
+                       } else {
+                               level = RAW_SEARCH_TRANS2;
+                       }
+                       s = extract_name(&result.list[i], level, compare_data_level);
                        fname = talloc_asprintf(cli, "t%03d-%d.txt", i, i);
                        if (strcmp(fname, s)) {
                                printf("Incorrect name %s at entry %d\n", s, i);
@@ -810,7 +866,8 @@ static BOOL test_modify_search(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        ZERO_STRUCT(result);
        result.mem_ctx = talloc_new(mem_ctx);
 
-       io.generic.level = RAW_SEARCH_BOTH_DIRECTORY_INFO;
+       io.t2ffirst.level = RAW_SEARCH_TRANS2;
+       io.t2ffirst.data_level = RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO;
        io.t2ffirst.in.search_attrib = 0;
        io.t2ffirst.in.max_count = 0;
        io.t2ffirst.in.flags = 0;
@@ -823,7 +880,8 @@ static BOOL test_modify_search(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_VALUE(result.count, 1);
        
        printf("pulling the second file\n");
-       io2.generic.level = RAW_SEARCH_BOTH_DIRECTORY_INFO;
+       io2.t2fnext.level = RAW_SEARCH_TRANS2;
+       io2.t2fnext.data_level = RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO;
        io2.t2fnext.in.handle = io.t2ffirst.out.handle;
        io2.t2fnext.in.max_count = 1;
        io2.t2fnext.in.resume_key = 0;
@@ -852,7 +910,8 @@ static BOOL test_modify_search(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        status = smb_raw_setfileinfo(cli->tree, &sfinfo);
        CHECK_STATUS(status, NT_STATUS_OK);
 
-       io2.generic.level = RAW_SEARCH_BOTH_DIRECTORY_INFO;
+       io2.t2fnext.level = RAW_SEARCH_TRANS2;
+       io2.t2fnext.data_level = RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO;
        io2.t2fnext.in.handle = io.t2ffirst.out.handle;
        io2.t2fnext.in.max_count = num_files + 3;
        io2.t2fnext.in.resume_key = 0;
@@ -927,7 +986,7 @@ static BOOL test_sorted(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        result.mem_ctx = mem_ctx;
        
        status = multiple_search(cli, mem_ctx, BASEDIR "\\*.*", 
-                                RAW_SEARCH_BOTH_DIRECTORY_INFO,
+                                RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO,
                                 CONT_NAME, &result);   
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_VALUE(result.count, num_files);
@@ -1007,7 +1066,8 @@ static BOOL test_many_dirs(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
        for (i=0;i<num_dirs;i++) {
                union smb_search_first io;
-               io.generic.level = RAW_SEARCH_SEARCH;
+               io.search_first.level = RAW_SEARCH_SEARCH;
+               io.search_first.data_level = RAW_SEARCH_DATA_SEARCH;
                io.search_first.in.max_count = 1;
                io.search_first.in.search_attrib = 0;
                io.search_first.in.pattern = talloc_asprintf(mem_ctx, BASEDIR "\\d%d\\*.txt", i);
@@ -1039,7 +1099,8 @@ static BOOL test_many_dirs(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        for (i=0;i<num_dirs;i++) {
                union smb_search_next io2;
 
-               io2.generic.level = RAW_SEARCH_SEARCH;
+               io2.search_next.level = RAW_SEARCH_SEARCH;
+               io2.search_next.data_level = RAW_SEARCH_DATA_SEARCH;
                io2.search_next.in.max_count = 1;
                io2.search_next.in.search_attrib = 0;
                io2.search_next.in.id = file[i].search.id;
@@ -1072,7 +1133,8 @@ static BOOL test_many_dirs(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        for (i=0;i<num_dirs;i++) {
                union smb_search_next io2;
 
-               io2.generic.level = RAW_SEARCH_SEARCH;
+               io2.search_next.level = RAW_SEARCH_SEARCH;
+               io2.search_next.data_level = RAW_SEARCH_DATA_SEARCH;
                io2.search_next.in.max_count = 1;
                io2.search_next.in.search_attrib = 0;
                io2.search_next.in.id = file[i].search.id;
@@ -1153,7 +1215,8 @@ static BOOL test_os2_delete(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        ZERO_STRUCT(result);
        result.mem_ctx = mem_ctx;
 
-       io.t2ffirst.level = RAW_SEARCH_EA_SIZE;
+       io.t2ffirst.level = RAW_SEARCH_TRANS2;
+       io.t2ffirst.data_level = RAW_SEARCH_DATA_EA_SIZE;
        io.t2ffirst.in.search_attrib = 0;
        io.t2ffirst.in.max_count = 100;
        io.t2ffirst.in.flags = FLAG_TRANS2_FIND_REQUIRE_RESUME;
@@ -1172,7 +1235,8 @@ static BOOL test_os2_delete(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
                talloc_free(fname);
        }
 
-       io2.t2fnext.level = RAW_SEARCH_EA_SIZE;
+       io2.t2fnext.level = RAW_SEARCH_TRANS2;
+       io2.t2fnext.data_level = RAW_SEARCH_DATA_EA_SIZE;
        io2.t2fnext.in.handle = io.t2ffirst.out.handle;
        io2.t2fnext.in.max_count = 100;
        io2.t2fnext.in.resume_key = result.list[i-1].ea_size.resume_key;
@@ -1273,7 +1337,8 @@ static BOOL test_ea_list(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        ZERO_STRUCT(result);
        result.mem_ctx = mem_ctx;
 
-       io.t2ffirst.level = RAW_SEARCH_EA_LIST;
+       io.t2ffirst.level = RAW_SEARCH_TRANS2;
+       io.t2ffirst.data_level = RAW_SEARCH_DATA_EA_LIST;
        io.t2ffirst.in.search_attrib = 0;
        io.t2ffirst.in.max_count = 2;
        io.t2ffirst.in.flags = FLAG_TRANS2_FIND_REQUIRE_RESUME;
@@ -1289,7 +1354,8 @@ static BOOL test_ea_list(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_VALUE(result.count, 2);
 
-       nxt.t2fnext.level = RAW_SEARCH_EA_LIST;
+       nxt.t2fnext.level = RAW_SEARCH_TRANS2;
+       nxt.t2fnext.data_level = RAW_SEARCH_DATA_EA_LIST;
        nxt.t2fnext.in.handle = io.t2ffirst.out.handle;
        nxt.t2fnext.in.max_count = 2;
        nxt.t2fnext.in.resume_key = result.list[1].ea_list.resume_key;