diff options
author | Stefan Metzmacher <metze@samba.org> | 2006-07-06 08:00:24 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 14:09:49 -0500 |
commit | af0a9eb52955cfae570bfdc01821f56385c860cf (patch) | |
tree | 9a798fd727753c3d9ceb44512579dc5b3e7fbebf | |
parent | 51e0ae33acf3cd09ae0eb9ef5077cecab4780a3e (diff) | |
download | samba-af0a9eb52955cfae570bfdc01821f56385c860cf.tar.gz samba-af0a9eb52955cfae570bfdc01821f56385c860cf.tar.bz2 samba-af0a9eb52955cfae570bfdc01821f56385c860cf.zip |
r16834: split the level's of smb_search_first/smb_search_next and the levels
of smb_search_data
metze
(This used to be commit 78c201db8a47a71908698c4dda2add4cf85694d9)
-rw-r--r-- | source4/libcli/clilist.c | 57 | ||||
-rw-r--r-- | source4/libcli/raw/interfaces.h | 74 | ||||
-rw-r--r-- | source4/libcli/raw/rawsearch.c | 120 | ||||
-rw-r--r-- | source4/libcli/smb2/find.c | 14 | ||||
-rw-r--r-- | source4/ntvfs/nbench/vfs_nbench.c | 4 | ||||
-rw-r--r-- | source4/ntvfs/posix/pvfs_search.c | 116 | ||||
-rw-r--r-- | source4/ntvfs/simple/vfs_simple.c | 12 | ||||
-rw-r--r-- | source4/smb_server/blob.c | 14 | ||||
-rw-r--r-- | source4/smb_server/smb/search.c | 2 | ||||
-rw-r--r-- | source4/smb_server/smb/trans2.c | 52 | ||||
-rw-r--r-- | source4/torture/basic/delete.c | 4 | ||||
-rw-r--r-- | source4/torture/masktest.c | 4 | ||||
-rw-r--r-- | source4/torture/raw/chkpath.c | 15 | ||||
-rw-r--r-- | source4/torture/raw/search.c | 214 |
14 files changed, 435 insertions, 267 deletions
diff --git a/source4/libcli/clilist.c b/source4/libcli/clilist.c index f18ec84db9..16986e9428 100644 --- a/source4/libcli/clilist.c +++ b/source4/libcli/clilist.c @@ -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); } diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index c581978b81..f77d31a1c7 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -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; diff --git a/source4/libcli/raw/rawsearch.c b/source4/libcli/raw/rawsearch.c index 5e05d7c3c5..4836766a93 100644 --- a/source4/libcli/raw/rawsearch.c +++ b/source4/libcli/raw/rawsearch.c @@ -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); diff --git a/source4/libcli/smb2/find.c b/source4/libcli/smb2/find.c index 8f4d6c8301..794e31bed3 100644 --- a/source4/libcli/smb2/find.c +++ b/source4/libcli/smb2/find.c @@ -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; diff --git a/source4/ntvfs/nbench/vfs_nbench.c b/source4/ntvfs/nbench/vfs_nbench.c index f7834a9751..34cf8d9565 100644 --- a/source4/ntvfs/nbench/vfs_nbench.c +++ b/source4/ntvfs/nbench/vfs_nbench.c @@ -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)); diff --git a/source4/ntvfs/posix/pvfs_search.c b/source4/ntvfs/posix/pvfs_search.c index 4d218fbe9c..794d223060 100644 --- a/source4/ntvfs/posix/pvfs_search.c +++ b/source4/ntvfs/posix/pvfs_search.c @@ -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); diff --git a/source4/ntvfs/simple/vfs_simple.c b/source4/ntvfs/simple/vfs_simple.c index 9e5d4ae922..beffe2b546 100644 --- a/source4/ntvfs/simple/vfs_simple.c +++ b/source4/ntvfs/simple/vfs_simple.c @@ -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; } diff --git a/source4/smb_server/blob.c b/source4/smb_server/blob.c index 07d1e0480d..a456e04b34 100644 --- a/source4/smb_server/blob.c +++ b/source4/smb_server/blob.c @@ -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); diff --git a/source4/smb_server/smb/search.c b/source4/smb_server/smb/search.c index b86c0ddb7e..cc6d866ac7 100644 --- a/source4/smb_server/smb/search.c +++ b/source4/smb_server/smb/search.c @@ -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)); diff --git a/source4/smb_server/smb/trans2.c b/source4/smb_server/smb/trans2.c index a8fe9f165d..8a4abd8e60 100644 --- a/source4/smb_server/smb/trans2.c +++ b/source4/smb_server/smb/trans2.c @@ -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; diff --git a/source4/torture/basic/delete.c b/source4/torture/basic/delete.c index a220e52438..a71fed32b7 100644 --- a/source4/torture/basic/delete.c +++ b/source4/torture/basic/delete.c @@ -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)) { diff --git a/source4/torture/masktest.c b/source4/torture/masktest.c index 6e2678ed80..8facd6a3eb 100644 --- a/source4/torture/masktest.c +++ b/source4/torture/masktest.c @@ -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); diff --git a/source4/torture/raw/chkpath.c b/source4/torture/raw/chkpath.c index a7675f3e3e..c4344d5c73 100644 --- a/source4/torture/raw/chkpath.c +++ b/source4/torture/raw/chkpath.c @@ -38,10 +38,11 @@ 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) diff --git a/source4/torture/raw/search.c b/source4/torture/raw/search.c index e90cbdfbf9..d4e317d9fb 100644 --- a/source4/torture/raw/search.c +++ b/source4/torture/raw/search.c @@ -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; |