2003-08-13 01:53:07 +00:00
/*
Unix SMB / CIFS implementation .
RAW_SEARCH_ * individual test suite
Copyright ( C ) Andrew Tridgell 2003
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-10 02:07:03 +00:00
the Free Software Foundation ; either version 3 of the License , or
2003-08-13 01:53:07 +00:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 02:07:03 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2003-08-13 01:53:07 +00:00
*/
# include "includes.h"
2006-01-03 13:41:17 +00:00
# include "torture/torture.h"
2005-02-10 05:09:35 +00:00
# include "system/filesys.h"
2004-11-01 01:03:22 +00:00
# include "libcli/raw/libcliraw.h"
2006-01-03 15:40:05 +00:00
# include "libcli/libcli.h"
2006-03-17 17:59:58 +00:00
# include "torture/util.h"
2003-08-13 01:53:07 +00:00
# define BASEDIR "\\testsearch"
/*
callback function for single_search
*/
2007-03-05 22:26:38 +00:00
static BOOL single_search_callback ( void * private , const union smb_search_data * file )
2003-08-13 01:53:07 +00:00
{
2007-09-07 15:08:14 +00:00
union smb_search_data * data = ( union smb_search_data * ) private ;
2003-08-13 01:53:07 +00:00
* data = * file ;
2007-09-02 02:35:11 +00:00
return true ;
2003-08-13 01:53:07 +00:00
}
/*
do a single file ( non - wildcard ) search
*/
2006-10-29 17:40:19 +00:00
_PUBLIC_ NTSTATUS torture_single_search ( struct smbcli_state * cli ,
2007-08-28 12:54:27 +00:00
TALLOC_CTX * tctx ,
2005-07-06 07:45:22 +00:00
const char * pattern ,
enum smb_search_level level ,
2006-07-06 08:00:24 +00:00
enum smb_search_data_level data_level ,
2005-07-06 14:56:45 +00:00
uint16_t attrib ,
2005-07-06 07:45:22 +00:00
union smb_search_data * data )
2003-08-13 01:53:07 +00:00
{
union smb_search_first io ;
2004-09-21 08:46:47 +00:00
union smb_search_close c ;
2003-08-13 01:53:07 +00:00
NTSTATUS status ;
2006-07-06 08:00:24 +00:00
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 ;
2003-08-13 01:53:07 +00:00
io . search_first . in . max_count = 1 ;
2005-07-06 14:56:45 +00:00
io . search_first . in . search_attrib = attrib ;
2003-08-13 01:53:07 +00:00
io . search_first . in . pattern = pattern ;
2006-07-06 08:00:24 +00:00
break ;
case RAW_SEARCH_TRANS2 :
io . t2ffirst . level = RAW_SEARCH_TRANS2 ;
io . t2ffirst . data_level = data_level ;
2005-07-06 14:56:45 +00:00
io . t2ffirst . in . search_attrib = attrib ;
2003-08-13 01:53:07 +00:00
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 ;
2006-07-06 08:00:24 +00:00
break ;
case RAW_SEARCH_SMB2 :
return NT_STATUS_INVALID_LEVEL ;
2003-08-13 01:53:07 +00:00
}
2007-08-28 12:54:27 +00:00
status = smb_raw_search_first ( cli - > tree , tctx ,
2003-08-13 01:53:07 +00:00
& io , ( void * ) data , single_search_callback ) ;
2004-09-21 08:46:47 +00:00
if ( NT_STATUS_IS_OK ( status ) & & level = = RAW_SEARCH_FFIRST ) {
c . fclose . level = RAW_FINDCLOSE_FCLOSE ;
c . fclose . in . max_count = 1 ;
c . fclose . in . search_attrib = 0 ;
c . fclose . in . id = data - > search . id ;
status = smb_raw_search_close ( cli - > tree , & c ) ;
}
2003-08-13 01:53:07 +00:00
return status ;
}
static struct {
const char * name ;
2004-07-19 10:35:05 +00:00
enum smb_search_level level ;
2006-07-06 08:00:24 +00:00
enum smb_search_data_level data_level ;
2006-04-01 03:46:46 +00:00
int name_offset ;
int resume_key_offset ;
2004-05-25 16:24:13 +00:00
uint32_t capability_mask ;
2003-08-13 01:53:07 +00:00
NTSTATUS status ;
union smb_search_data data ;
} levels [ ] = {
2006-07-06 08:00:24 +00:00
{ " FFIRST " ,
RAW_SEARCH_FFIRST , RAW_SEARCH_DATA_SEARCH ,
2006-04-01 03:46:46 +00:00
offsetof ( union smb_search_data , search . name ) ,
- 1 ,
} ,
2006-07-06 08:00:24 +00:00
{ " FUNIQUE " ,
RAW_SEARCH_FUNIQUE , RAW_SEARCH_DATA_SEARCH ,
2006-04-01 03:46:46 +00:00
offsetof ( union smb_search_data , search . name ) ,
- 1 ,
} ,
2006-07-06 08:00:24 +00:00
{ " SEARCH " ,
RAW_SEARCH_SEARCH , RAW_SEARCH_DATA_SEARCH ,
2006-04-01 03:46:46 +00:00
offsetof ( union smb_search_data , search . name ) ,
- 1 ,
} ,
2006-07-06 08:00:24 +00:00
{ " STANDARD " ,
RAW_SEARCH_TRANS2 , RAW_SEARCH_DATA_STANDARD ,
2006-04-01 03:46:46 +00:00
offsetof ( union smb_search_data , standard . name . s ) ,
offsetof ( union smb_search_data , standard . resume_key ) ,
} ,
2006-07-06 08:00:24 +00:00
{ " EA_SIZE " ,
RAW_SEARCH_TRANS2 , RAW_SEARCH_DATA_EA_SIZE ,
2006-04-01 03:46:46 +00:00
offsetof ( union smb_search_data , ea_size . name . s ) ,
offsetof ( union smb_search_data , ea_size . resume_key ) ,
} ,
2006-07-06 08:00:24 +00:00
{ " DIRECTORY_INFO " ,
RAW_SEARCH_TRANS2 , RAW_SEARCH_DATA_DIRECTORY_INFO ,
2006-04-01 03:46:46 +00:00
offsetof ( union smb_search_data , directory_info . name . s ) ,
offsetof ( union smb_search_data , directory_info . file_index ) ,
} ,
2006-07-06 08:00:24 +00:00
{ " FULL_DIRECTORY_INFO " ,
RAW_SEARCH_TRANS2 , RAW_SEARCH_DATA_FULL_DIRECTORY_INFO ,
2006-04-01 03:46:46 +00:00
offsetof ( union smb_search_data , full_directory_info . name . s ) ,
offsetof ( union smb_search_data , full_directory_info . file_index ) ,
} ,
2006-07-06 08:00:24 +00:00
{ " NAME_INFO " ,
RAW_SEARCH_TRANS2 , RAW_SEARCH_DATA_NAME_INFO ,
2006-04-01 03:46:46 +00:00
offsetof ( union smb_search_data , name_info . name . s ) ,
offsetof ( union smb_search_data , name_info . file_index ) ,
} ,
2006-07-06 08:00:24 +00:00
{ " BOTH_DIRECTORY_INFO " ,
RAW_SEARCH_TRANS2 , RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO ,
2006-04-01 03:46:46 +00:00
offsetof ( union smb_search_data , both_directory_info . name . s ) ,
offsetof ( union smb_search_data , both_directory_info . file_index ) ,
} ,
2006-07-06 08:00:24 +00:00
{ " ID_FULL_DIRECTORY_INFO " ,
RAW_SEARCH_TRANS2 , RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO ,
2006-04-01 03:46:46 +00:00
offsetof ( union smb_search_data , id_full_directory_info . name . s ) ,
offsetof ( union smb_search_data , id_full_directory_info . file_index ) ,
} ,
2006-07-06 08:00:24 +00:00
{ " ID_BOTH_DIRECTORY_INFO " ,
RAW_SEARCH_TRANS2 , RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO ,
2006-04-01 03:46:46 +00:00
offsetof ( union smb_search_data , id_both_directory_info . name . s ) ,
offsetof ( union smb_search_data , id_both_directory_info . file_index ) ,
} ,
2006-07-06 08:00:24 +00:00
{ " UNIX_INFO " ,
RAW_SEARCH_TRANS2 , RAW_SEARCH_DATA_UNIX_INFO ,
2006-04-01 03:46:46 +00:00
offsetof ( union smb_search_data , unix_info . name ) ,
offsetof ( union smb_search_data , unix_info . file_index ) ,
CAP_UNIX }
2003-08-13 01:53:07 +00:00
} ;
2006-04-01 03:46:46 +00:00
/*
return level name
*/
2006-07-06 08:00:24 +00:00
static const char * level_name ( enum smb_search_level level ,
enum smb_search_data_level data_level )
2006-04-01 03:46:46 +00:00
{
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
2006-07-06 08:00:24 +00:00
if ( level = = levels [ i ] . level & &
data_level = = levels [ i ] . data_level ) {
2006-04-01 03:46:46 +00:00
return levels [ i ] . name ;
}
}
return NULL ;
}
/*
extract the name from a smb_data structure and level
*/
2006-07-06 08:00:24 +00:00
static const char * extract_name ( void * data , enum smb_search_level level ,
enum smb_search_data_level data_level )
2006-04-01 03:46:46 +00:00
{
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
2006-07-06 08:00:24 +00:00
if ( level = = levels [ i ] . level & &
data_level = = levels [ i ] . data_level ) {
2006-04-01 03:46:46 +00:00
return * ( const char * * ) ( levels [ i ] . name_offset + ( char * ) data ) ;
}
}
return NULL ;
}
/*
extract the name from a smb_data structure and level
*/
2006-09-10 07:24:41 +00:00
static uint32_t extract_resume_key ( void * data , enum smb_search_level level ,
enum smb_search_data_level data_level )
2006-04-01 03:46:46 +00:00
{
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
2006-07-06 08:00:24 +00:00
if ( level = = levels [ i ] . level & &
data_level = = levels [ i ] . data_level ) {
2006-09-10 07:24:41 +00:00
return * ( uint32_t * ) ( levels [ i ] . resume_key_offset + ( char * ) data ) ;
2006-04-01 03:46:46 +00:00
}
}
2006-09-10 07:24:41 +00:00
return 0 ;
2006-04-01 03:46:46 +00:00
}
2003-08-13 01:53:07 +00:00
/* find a level in the table by name */
static union smb_search_data * find ( const char * name )
{
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
if ( NT_STATUS_IS_OK ( levels [ i ] . status ) & &
strcmp ( levels [ i ] . name , name ) = = 0 ) {
return & levels [ i ] . data ;
}
}
return NULL ;
}
/*
basic testing of all RAW_SEARCH_ * calls using a single file
*/
2007-09-02 02:35:11 +00:00
static bool test_one_file ( struct torture_context * tctx ,
struct smbcli_state * cli )
2003-08-13 01:53:07 +00:00
{
BOOL ret = True ;
int fnum ;
const char * fname = " \\ torture_search.txt " ;
2004-09-21 04:11:48 +00:00
const char * fname2 = " \\ torture_search-NOTEXIST.txt " ;
2003-08-13 01:53:07 +00:00
NTSTATUS status ;
int i ;
2003-09-02 04:37:33 +00:00
union smb_fileinfo all_info , alt_info , name_info , internal_info ;
2003-08-13 01:53:07 +00:00
union smb_search_data * s ;
2007-08-28 12:54:27 +00:00
fnum = create_complex_file ( cli , tctx , fname ) ;
2003-08-13 01:53:07 +00:00
if ( fnum = = - 1 ) {
2004-08-04 13:23:35 +00:00
printf ( " ERROR: open of %s failed (%s) \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 01:53:07 +00:00
ret = False ;
goto done ;
}
/* call all the levels */
for ( i = 0 ; i < ARRAY_SIZE ( levels ) ; i + + ) {
2004-09-21 04:11:48 +00:00
NTSTATUS expected_status ;
2004-05-25 16:24:13 +00:00
uint32_t cap = cli - > transport - > negotiate . capabilities ;
2003-08-13 01:53:07 +00:00
2007-09-02 02:35:11 +00:00
torture_comment ( tctx , " testing %s \n " , levels [ i ] . name ) ;
2004-04-12 18:53:41 +00:00
2007-08-28 12:54:27 +00:00
levels [ i ] . status = torture_single_search ( cli , tctx , fname ,
2006-07-06 08:00:24 +00:00
levels [ i ] . level ,
levels [ i ] . data_level ,
0 ,
2005-07-06 07:45:22 +00:00
& levels [ i ] . data ) ;
2003-08-13 01:53:07 +00:00
/* see if this server claims to support this level */
if ( ( cap & levels [ i ] . capability_mask ) ! = levels [ i ] . capability_mask ) {
2004-04-12 18:53:41 +00:00
printf ( " search level %s(%d) not supported by server \n " ,
levels [ i ] . name , ( int ) levels [ i ] . level ) ;
2003-08-13 01:53:07 +00:00
continue ;
}
if ( ! NT_STATUS_IS_OK ( levels [ i ] . status ) ) {
printf ( " search level %s(%d) failed - %s \n " ,
levels [ i ] . name , ( int ) levels [ i ] . level ,
nt_errstr ( levels [ i ] . status ) ) ;
ret = False ;
2004-09-21 04:11:48 +00:00
continue ;
}
2007-08-28 12:54:27 +00:00
status = torture_single_search ( cli , tctx , fname2 ,
2006-07-06 08:00:24 +00:00
levels [ i ] . level ,
levels [ i ] . data_level ,
0 ,
2005-07-06 07:45:22 +00:00
& levels [ i ] . data ) ;
2004-09-21 04:11:48 +00:00
expected_status = NT_STATUS_NO_SUCH_FILE ;
2004-09-21 08:46:47 +00:00
if ( levels [ i ] . level = = RAW_SEARCH_SEARCH | |
levels [ i ] . level = = RAW_SEARCH_FFIRST | |
levels [ i ] . level = = RAW_SEARCH_FUNIQUE ) {
2004-09-21 04:11:48 +00:00
expected_status = STATUS_NO_MORE_FILES ;
}
if ( ! NT_STATUS_EQUAL ( status , expected_status ) ) {
printf ( " search level %s(%d) should fail with %s - %s \n " ,
levels [ i ] . name , ( int ) levels [ i ] . level ,
nt_errstr ( expected_status ) ,
nt_errstr ( status ) ) ;
ret = False ;
2003-08-13 01:53:07 +00:00
}
}
/* get the all_info file into to check against */
all_info . generic . level = RAW_FILEINFO_ALL_INFO ;
2006-03-12 22:48:25 +00:00
all_info . generic . in . file . path = fname ;
2007-08-28 12:54:27 +00:00
status = smb_raw_pathinfo ( cli - > tree , tctx , & all_info ) ;
2007-09-02 02:35:11 +00:00
torture_assert_ntstatus_ok ( tctx , status , " RAW_FILEINFO_ALL_INFO failed " ) ;
2003-08-13 01:53:07 +00:00
alt_info . generic . level = RAW_FILEINFO_ALT_NAME_INFO ;
2006-03-12 22:48:25 +00:00
alt_info . generic . in . file . path = fname ;
2007-08-28 12:54:27 +00:00
status = smb_raw_pathinfo ( cli - > tree , tctx , & alt_info ) ;
2007-09-02 02:35:11 +00:00
torture_assert_ntstatus_ok ( tctx , status , " RAW_FILEINFO_ALT_NAME_INFO failed " ) ;
2003-08-13 01:53:07 +00:00
2003-09-02 04:37:33 +00:00
internal_info . generic . level = RAW_FILEINFO_INTERNAL_INFORMATION ;
2006-03-12 22:48:25 +00:00
internal_info . generic . in . file . path = fname ;
2007-08-28 12:54:27 +00:00
status = smb_raw_pathinfo ( cli - > tree , tctx , & internal_info ) ;
2007-09-02 02:35:11 +00:00
torture_assert_ntstatus_ok ( tctx , status , " RAW_FILEINFO_INTERNAL_INFORMATION failed " ) ;
2003-09-02 04:37:33 +00:00
2003-08-13 01:53:07 +00:00
name_info . generic . level = RAW_FILEINFO_NAME_INFO ;
2006-03-12 22:48:25 +00:00
name_info . generic . in . file . path = fname ;
2007-08-28 12:54:27 +00:00
status = smb_raw_pathinfo ( cli - > tree , tctx , & name_info ) ;
2007-09-02 02:35:11 +00:00
torture_assert_ntstatus_ok ( tctx , status , " RAW_FILEINFO_NAME_INFO failed " ) ;
2003-08-13 01:53:07 +00:00
# define CHECK_VAL(name, sname1, field1, v, sname2, field2) do { \
s = find ( name ) ; \
if ( s ) { \
2004-09-21 02:41:32 +00:00
if ( ( s - > sname1 . field1 ) ! = ( v . sname2 . out . field2 ) ) { \
2004-10-26 07:02:30 +00:00
printf ( " (%s) %s/%s [0x%x] != %s/%s [0x%x] \n " , \
__location__ , \
2003-08-13 01:53:07 +00:00
# sname1, #field1, (int)s->sname1.field1, \
# sname2, #field2, (int)v.sname2.out.field2); \
ret = False ; \
} \
} } while ( 0 )
# define CHECK_TIME(name, sname1, field1, v, sname2, field2) do { \
s = find ( name ) ; \
if ( s ) { \
2004-05-25 13:57:39 +00:00
if ( s - > sname1 . field1 ! = ( ~ 1 & nt_time_to_unix ( v . sname2 . out . field2 ) ) ) { \
2004-10-26 07:02:30 +00:00
printf ( " (%s) %s/%s [%s] != %s/%s [%s] \n " , \
__location__ , \
2007-08-28 12:54:27 +00:00
# sname1, #field1, timestring(tctx, s->sname1.field1), \
# sname2, #field2, nt_time_string(tctx, v.sname2.out.field2)); \
2003-08-13 01:53:07 +00:00
ret = False ; \
} \
} } while ( 0 )
# define CHECK_NTTIME(name, sname1, field1, v, sname2, field2) do { \
s = find ( name ) ; \
if ( s ) { \
2004-05-25 13:57:39 +00:00
if ( s - > sname1 . field1 ! = v . sname2 . out . field2 ) { \
2004-10-26 07:02:30 +00:00
printf ( " (%s) %s/%s [%s] != %s/%s [%s] \n " , \
__location__ , \
2007-08-28 12:54:27 +00:00
# sname1, #field1, nt_time_string(tctx, s->sname1.field1), \
# sname2, #field2, nt_time_string(tctx, v.sname2.out.field2)); \
2003-08-13 01:53:07 +00:00
ret = False ; \
} \
} } while ( 0 )
# define CHECK_STR(name, sname1, field1, v, sname2, field2) do { \
s = find ( name ) ; \
if ( s ) { \
if ( ! s - > sname1 . field1 | | strcmp ( s - > sname1 . field1 , v . sname2 . out . field2 . s ) ) { \
2004-10-26 07:02:30 +00:00
printf ( " (%s) %s/%s [%s] != %s/%s [%s] \n " , \
__location__ , \
2003-08-13 01:53:07 +00:00
# sname1, #field1, s->sname1.field1, \
# sname2, #field2, v.sname2.out.field2.s); \
ret = False ; \
} \
} } while ( 0 )
# define CHECK_WSTR(name, sname1, field1, v, sname2, field2, flags) do { \
s = find ( name ) ; \
if ( s ) { \
if ( ! s - > sname1 . field1 . s | | \
strcmp ( s - > sname1 . field1 . s , v . sname2 . out . field2 . s ) | | \
2007-05-14 05:53:26 +00:00
wire_bad_flags ( & s - > sname1 . field1 , flags , cli - > transport ) ) { \
2004-10-26 07:02:30 +00:00
printf ( " (%s) %s/%s [%s] != %s/%s [%s] \n " , \
__location__ , \
2003-08-13 01:53:07 +00:00
# sname1, #field1, s->sname1.field1.s, \
# sname2, #field2, v.sname2.out.field2.s); \
ret = False ; \
} \
} } while ( 0 )
# define CHECK_NAME(name, sname1, field1, fname, flags) do { \
s = find ( name ) ; \
if ( s ) { \
if ( ! s - > sname1 . field1 . s | | \
strcmp ( s - > sname1 . field1 . s , fname ) | | \
2007-05-14 05:53:26 +00:00
wire_bad_flags ( & s - > sname1 . field1 , flags , cli - > transport ) ) { \
2004-10-26 07:02:30 +00:00
printf ( " (%s) %s/%s [%s] != %s \n " , \
__location__ , \
2003-08-13 01:53:07 +00:00
# sname1, #field1, s->sname1.field1.s, \
fname ) ; \
ret = False ; \
} \
} } while ( 0 )
2004-04-14 01:09:41 +00:00
# define CHECK_UNIX_NAME(name, sname1, field1, fname, flags) do { \
s = find ( name ) ; \
if ( s ) { \
if ( ! s - > sname1 . field1 | | \
strcmp ( s - > sname1 . field1 , fname ) ) { \
2004-10-26 07:02:30 +00:00
printf ( " (%s) %s/%s [%s] != %s \n " , \
__location__ , \
2004-04-14 01:09:41 +00:00
# sname1, #field1, s->sname1.field1, \
fname ) ; \
ret = False ; \
} \
} } while ( 0 )
2003-08-13 01:53:07 +00:00
/* check that all the results are as expected */
2004-09-21 02:41:32 +00:00
CHECK_VAL ( " SEARCH " , search , attrib , all_info , all_info , attrib & 0xFFF ) ;
CHECK_VAL ( " STANDARD " , standard , attrib , all_info , all_info , attrib & 0xFFF ) ;
CHECK_VAL ( " EA_SIZE " , ea_size , attrib , all_info , all_info , attrib & 0xFFF ) ;
2003-08-13 01:53:07 +00:00
CHECK_VAL ( " DIRECTORY_INFO " , directory_info , attrib , all_info , all_info , attrib ) ;
CHECK_VAL ( " FULL_DIRECTORY_INFO " , full_directory_info , attrib , all_info , all_info , attrib ) ;
CHECK_VAL ( " BOTH_DIRECTORY_INFO " , both_directory_info , attrib , all_info , all_info , attrib ) ;
2003-09-02 04:37:33 +00:00
CHECK_VAL ( " ID_FULL_DIRECTORY_INFO " , id_full_directory_info , attrib , all_info , all_info , attrib ) ;
CHECK_VAL ( " ID_BOTH_DIRECTORY_INFO " , id_both_directory_info , attrib , all_info , all_info , attrib ) ;
2003-08-13 01:53:07 +00:00
CHECK_TIME ( " SEARCH " , search , write_time , all_info , all_info , write_time ) ;
CHECK_TIME ( " STANDARD " , standard , write_time , all_info , all_info , write_time ) ;
CHECK_TIME ( " EA_SIZE " , ea_size , write_time , all_info , all_info , write_time ) ;
CHECK_TIME ( " STANDARD " , standard , create_time , all_info , all_info , create_time ) ;
CHECK_TIME ( " EA_SIZE " , ea_size , create_time , all_info , all_info , create_time ) ;
CHECK_TIME ( " STANDARD " , standard , access_time , all_info , all_info , access_time ) ;
CHECK_TIME ( " EA_SIZE " , ea_size , access_time , all_info , all_info , access_time ) ;
CHECK_NTTIME ( " DIRECTORY_INFO " , directory_info , write_time , all_info , all_info , write_time ) ;
CHECK_NTTIME ( " FULL_DIRECTORY_INFO " , full_directory_info , write_time , all_info , all_info , write_time ) ;
CHECK_NTTIME ( " BOTH_DIRECTORY_INFO " , both_directory_info , write_time , all_info , all_info , write_time ) ;
2003-09-02 04:37:33 +00:00
CHECK_NTTIME ( " ID_FULL_DIRECTORY_INFO " , id_full_directory_info , write_time , all_info , all_info , write_time ) ;
CHECK_NTTIME ( " ID_BOTH_DIRECTORY_INFO " , id_both_directory_info , write_time , all_info , all_info , write_time ) ;
2003-08-13 01:53:07 +00:00
CHECK_NTTIME ( " DIRECTORY_INFO " , directory_info , create_time , all_info , all_info , create_time ) ;
CHECK_NTTIME ( " FULL_DIRECTORY_INFO " , full_directory_info , create_time , all_info , all_info , create_time ) ;
CHECK_NTTIME ( " BOTH_DIRECTORY_INFO " , both_directory_info , create_time , all_info , all_info , create_time ) ;
2003-09-02 04:37:33 +00:00
CHECK_NTTIME ( " ID_FULL_DIRECTORY_INFO " , id_full_directory_info , create_time , all_info , all_info , create_time ) ;
CHECK_NTTIME ( " ID_BOTH_DIRECTORY_INFO " , id_both_directory_info , create_time , all_info , all_info , create_time ) ;
2003-08-13 01:53:07 +00:00
CHECK_NTTIME ( " DIRECTORY_INFO " , directory_info , access_time , all_info , all_info , access_time ) ;
CHECK_NTTIME ( " FULL_DIRECTORY_INFO " , full_directory_info , access_time , all_info , all_info , access_time ) ;
CHECK_NTTIME ( " BOTH_DIRECTORY_INFO " , both_directory_info , access_time , all_info , all_info , access_time ) ;
2003-09-02 04:37:33 +00:00
CHECK_NTTIME ( " ID_FULL_DIRECTORY_INFO " , id_full_directory_info , access_time , all_info , all_info , access_time ) ;
CHECK_NTTIME ( " ID_BOTH_DIRECTORY_INFO " , id_both_directory_info , access_time , all_info , all_info , access_time ) ;
2003-08-13 01:53:07 +00:00
2005-11-10 12:35:12 +00:00
CHECK_NTTIME ( " DIRECTORY_INFO " , directory_info , change_time , all_info , all_info , change_time ) ;
CHECK_NTTIME ( " FULL_DIRECTORY_INFO " , full_directory_info , change_time , all_info , all_info , change_time ) ;
CHECK_NTTIME ( " BOTH_DIRECTORY_INFO " , both_directory_info , change_time , all_info , all_info , change_time ) ;
CHECK_NTTIME ( " ID_FULL_DIRECTORY_INFO " , id_full_directory_info , change_time , all_info , all_info , change_time ) ;
CHECK_NTTIME ( " ID_BOTH_DIRECTORY_INFO " , id_both_directory_info , change_time , all_info , all_info , change_time ) ;
2003-08-13 01:53:07 +00:00
CHECK_VAL ( " SEARCH " , search , size , all_info , all_info , size ) ;
CHECK_VAL ( " STANDARD " , standard , size , all_info , all_info , size ) ;
CHECK_VAL ( " EA_SIZE " , ea_size , size , all_info , all_info , size ) ;
CHECK_VAL ( " DIRECTORY_INFO " , directory_info , size , all_info , all_info , size ) ;
CHECK_VAL ( " FULL_DIRECTORY_INFO " , full_directory_info , size , all_info , all_info , size ) ;
CHECK_VAL ( " BOTH_DIRECTORY_INFO " , both_directory_info , size , all_info , all_info , size ) ;
2003-09-02 04:37:33 +00:00
CHECK_VAL ( " ID_FULL_DIRECTORY_INFO " , id_full_directory_info , size , all_info , all_info , size ) ;
CHECK_VAL ( " ID_BOTH_DIRECTORY_INFO " , id_both_directory_info , size , all_info , all_info , size ) ;
2004-04-13 23:59:13 +00:00
CHECK_VAL ( " UNIX_INFO " , unix_info , size , all_info , all_info , size ) ;
2003-08-13 01:53:07 +00:00
CHECK_VAL ( " STANDARD " , standard , alloc_size , all_info , all_info , alloc_size ) ;
CHECK_VAL ( " EA_SIZE " , ea_size , alloc_size , all_info , all_info , alloc_size ) ;
CHECK_VAL ( " DIRECTORY_INFO " , directory_info , alloc_size , all_info , all_info , alloc_size ) ;
CHECK_VAL ( " FULL_DIRECTORY_INFO " , full_directory_info , alloc_size , all_info , all_info , alloc_size ) ;
CHECK_VAL ( " BOTH_DIRECTORY_INFO " , both_directory_info , alloc_size , all_info , all_info , alloc_size ) ;
2003-09-02 04:37:33 +00:00
CHECK_VAL ( " ID_FULL_DIRECTORY_INFO " , id_full_directory_info , alloc_size , all_info , all_info , alloc_size ) ;
CHECK_VAL ( " ID_BOTH_DIRECTORY_INFO " , id_both_directory_info , alloc_size , all_info , all_info , alloc_size ) ;
2004-04-13 23:59:13 +00:00
CHECK_VAL ( " UNIX_INFO " , unix_info , alloc_size , all_info , all_info , alloc_size ) ;
2003-08-13 01:53:07 +00:00
CHECK_VAL ( " EA_SIZE " , ea_size , ea_size , all_info , all_info , ea_size ) ;
CHECK_VAL ( " FULL_DIRECTORY_INFO " , full_directory_info , ea_size , all_info , all_info , ea_size ) ;
CHECK_VAL ( " BOTH_DIRECTORY_INFO " , both_directory_info , ea_size , all_info , all_info , ea_size ) ;
2003-09-02 04:37:33 +00:00
CHECK_VAL ( " ID_FULL_DIRECTORY_INFO " , id_full_directory_info , ea_size , all_info , all_info , ea_size ) ;
CHECK_VAL ( " ID_BOTH_DIRECTORY_INFO " , id_both_directory_info , ea_size , all_info , all_info , ea_size ) ;
2003-08-13 01:53:07 +00:00
CHECK_STR ( " SEARCH " , search , name , alt_info , alt_name_info , fname ) ;
CHECK_WSTR ( " BOTH_DIRECTORY_INFO " , both_directory_info , short_name , alt_info , alt_name_info , fname , STR_UNICODE ) ;
CHECK_NAME ( " STANDARD " , standard , name , fname + 1 , 0 ) ;
CHECK_NAME ( " EA_SIZE " , ea_size , name , fname + 1 , 0 ) ;
CHECK_NAME ( " DIRECTORY_INFO " , directory_info , name , fname + 1 , STR_TERMINATE_ASCII ) ;
CHECK_NAME ( " FULL_DIRECTORY_INFO " , full_directory_info , name , fname + 1 , STR_TERMINATE_ASCII ) ;
CHECK_NAME ( " NAME_INFO " , name_info , name , fname + 1 , STR_TERMINATE_ASCII ) ;
CHECK_NAME ( " BOTH_DIRECTORY_INFO " , both_directory_info , name , fname + 1 , STR_TERMINATE_ASCII ) ;
2003-09-02 04:37:33 +00:00
CHECK_NAME ( " ID_FULL_DIRECTORY_INFO " , id_full_directory_info , name , fname + 1 , STR_TERMINATE_ASCII ) ;
CHECK_NAME ( " ID_BOTH_DIRECTORY_INFO " , id_both_directory_info , name , fname + 1 , STR_TERMINATE_ASCII ) ;
2004-04-14 01:09:41 +00:00
CHECK_UNIX_NAME ( " UNIX_INFO " , unix_info , name , fname + 1 , STR_TERMINATE_ASCII ) ;
2003-09-02 04:37:33 +00:00
CHECK_VAL ( " ID_FULL_DIRECTORY_INFO " , id_full_directory_info , file_id , internal_info , internal_information , file_id ) ;
CHECK_VAL ( " ID_BOTH_DIRECTORY_INFO " , id_both_directory_info , file_id , internal_info , internal_information , file_id ) ;
2003-08-13 01:53:07 +00:00
done :
smb_raw_exit ( cli - > session ) ;
2004-08-04 13:23:35 +00:00
smbcli_unlink ( cli - > tree , fname ) ;
2003-08-13 01:53:07 +00:00
return ret ;
}
struct multiple_result {
2007-08-28 12:54:27 +00:00
TALLOC_CTX * tctx ;
2003-08-13 01:53:07 +00:00
int count ;
union smb_search_data * list ;
} ;
/*
callback function for multiple_search
*/
2007-04-12 10:48:30 +00:00
static BOOL multiple_search_callback ( void * private , const union smb_search_data * file )
2003-08-13 01:53:07 +00:00
{
2007-09-07 15:08:14 +00:00
struct multiple_result * data = ( struct multiple_result * ) private ;
2003-08-13 01:53:07 +00:00
data - > count + + ;
2007-08-28 12:54:27 +00:00
data - > list = talloc_realloc ( data - > tctx ,
2004-09-27 01:36:19 +00:00
data - > list ,
union smb_search_data ,
data - > count ) ;
2003-08-13 01:53:07 +00:00
data - > list [ data - > count - 1 ] = * file ;
2007-09-02 02:35:11 +00:00
return true ;
2003-08-13 01:53:07 +00:00
}
enum continue_type { CONT_FLAGS , CONT_NAME , CONT_RESUME_KEY } ;
/*
do a single file ( non - wildcard ) search
*/
2004-08-04 13:23:35 +00:00
static NTSTATUS multiple_search ( struct smbcli_state * cli ,
2007-08-28 12:54:27 +00:00
TALLOC_CTX * tctx ,
2003-08-13 01:53:07 +00:00
const char * pattern ,
2006-07-06 08:00:24 +00:00
enum smb_search_data_level data_level ,
2003-08-13 01:53:07 +00:00
enum continue_type cont_type ,
void * data )
{
union smb_search_first io ;
union smb_search_next io2 ;
NTSTATUS status ;
2005-07-18 06:26:03 +00:00
const int per_search = 100 ;
2007-09-07 15:08:14 +00:00
struct multiple_result * result = ( struct multiple_result * ) data ;
2003-08-13 01:53:07 +00:00
2006-07-06 08:00:24 +00:00
if ( data_level = = RAW_SEARCH_DATA_SEARCH ) {
io . search_first . level = RAW_SEARCH_SEARCH ;
io . search_first . data_level = RAW_SEARCH_DATA_SEARCH ;
2003-08-13 01:53:07 +00:00
io . search_first . in . max_count = per_search ;
io . search_first . in . search_attrib = 0 ;
io . search_first . in . pattern = pattern ;
} else {
2006-07-06 08:00:24 +00:00
io . t2ffirst . level = RAW_SEARCH_TRANS2 ;
io . t2ffirst . data_level = data_level ;
2003-08-13 01:53:07 +00:00
io . t2ffirst . in . search_attrib = 0 ;
io . t2ffirst . in . max_count = per_search ;
2004-09-22 12:38:19 +00:00
io . t2ffirst . in . flags = FLAG_TRANS2_FIND_CLOSE_IF_END ;
2003-08-13 01:53:07 +00:00
io . t2ffirst . in . storage_type = 0 ;
io . t2ffirst . in . pattern = pattern ;
if ( cont_type = = CONT_RESUME_KEY ) {
2004-09-22 12:38:19 +00:00
io . t2ffirst . in . flags | = FLAG_TRANS2_FIND_REQUIRE_RESUME |
2003-08-13 01:53:07 +00:00
FLAG_TRANS2_FIND_BACKUP_INTENT ;
}
}
2007-08-28 12:54:27 +00:00
status = smb_raw_search_first ( cli - > tree , tctx ,
2003-08-13 01:53:07 +00:00
& io , data , multiple_search_callback ) ;
while ( NT_STATUS_IS_OK ( status ) ) {
2006-07-06 08:00:24 +00:00
if ( data_level = = RAW_SEARCH_DATA_SEARCH ) {
io2 . search_next . level = RAW_SEARCH_SEARCH ;
io2 . search_next . data_level = RAW_SEARCH_DATA_SEARCH ;
2003-08-13 01:53:07 +00:00
io2 . search_next . in . max_count = per_search ;
io2 . search_next . in . search_attrib = 0 ;
2004-09-21 08:46:47 +00:00
io2 . search_next . in . id = result - > list [ result - > count - 1 ] . search . id ;
2003-08-13 01:53:07 +00:00
} else {
2006-07-06 08:00:24 +00:00
io2 . t2fnext . level = RAW_SEARCH_TRANS2 ;
io2 . t2fnext . data_level = data_level ;
2003-08-13 01:53:07 +00:00
io2 . t2fnext . in . handle = io . t2ffirst . out . handle ;
io2 . t2fnext . in . max_count = per_search ;
io2 . t2fnext . in . resume_key = 0 ;
2004-09-22 12:38:19 +00:00
io2 . t2fnext . in . flags = FLAG_TRANS2_FIND_CLOSE_IF_END ;
2003-08-13 01:53:07 +00:00
io2 . t2fnext . in . last_name = " " ;
switch ( cont_type ) {
case CONT_RESUME_KEY :
2006-07-06 08:00:24 +00:00
io2 . t2fnext . in . resume_key = extract_resume_key ( & result - > list [ result - > count - 1 ] ,
io2 . t2fnext . level , io2 . t2fnext . data_level ) ;
2006-09-10 07:24:41 +00:00
if ( io2 . t2fnext . in . resume_key = = 0 ) {
2006-04-01 03:46:46 +00:00
printf ( " Server does not support resume by key for level %s \n " ,
2006-07-06 08:00:24 +00:00
level_name ( io2 . t2fnext . level , io2 . t2fnext . data_level ) ) ;
2004-09-21 02:41:32 +00:00
return NT_STATUS_NOT_SUPPORTED ;
}
2004-09-22 12:38:19 +00:00
io2 . t2fnext . in . flags | = FLAG_TRANS2_FIND_REQUIRE_RESUME |
2003-08-13 01:53:07 +00:00
FLAG_TRANS2_FIND_BACKUP_INTENT ;
break ;
case CONT_NAME :
2006-07-06 08:00:24 +00:00
io2 . t2fnext . in . last_name = extract_name ( & result - > list [ result - > count - 1 ] ,
io2 . t2fnext . level , io2 . t2fnext . data_level ) ;
2003-08-13 01:53:07 +00:00
break ;
case CONT_FLAGS :
2004-09-22 12:38:19 +00:00
io2 . t2fnext . in . flags | = FLAG_TRANS2_FIND_CONTINUE ;
2003-08-13 01:53:07 +00:00
break ;
}
}
2007-08-28 12:54:27 +00:00
status = smb_raw_search_next ( cli - > tree , tctx ,
2003-08-13 01:53:07 +00:00
& io2 , data , multiple_search_callback ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
break ;
}
2006-07-06 08:00:24 +00:00
if ( data_level = = RAW_SEARCH_DATA_SEARCH ) {
2003-08-13 01:53:07 +00:00
if ( io2 . search_next . out . count = = 0 ) {
break ;
}
} else if ( io2 . t2fnext . out . count = = 0 | |
io2 . t2fnext . out . end_of_search ) {
break ;
}
}
return status ;
}
2007-09-02 02:35:11 +00:00
# define CHECK_STATUS(status, correct) torture_assert_ntstatus_equal(tctx, status, correct, "incorrect status")
2003-08-13 01:53:07 +00:00
2007-09-02 02:35:11 +00:00
# define CHECK_VALUE(v, correct) torture_assert_int_equal(tctx, (v), (correct), "incorrect value");
2003-08-13 01:53:07 +00:00
2007-09-02 02:35:11 +00:00
# define CHECK_STRING(v, correct) torture_assert_casestr_equal(tctx, v, correct, "incorrect value");
2004-12-18 04:38:43 +00:00
2003-08-13 01:53:07 +00:00
2006-07-06 08:00:24 +00:00
static enum smb_search_data_level compare_data_level ;
2003-08-13 01:53:07 +00:00
2006-04-01 03:46:46 +00:00
static int search_compare ( union smb_search_data * d1 , union smb_search_data * d2 )
2003-08-13 01:53:07 +00:00
{
2006-04-01 03:46:46 +00:00
const char * s1 , * s2 ;
2006-07-06 08:00:24 +00:00
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 ) ;
2006-04-01 03:46:46 +00:00
return strcmp_safe ( s1 , s2 ) ;
2003-08-13 01:53:07 +00:00
}
/*
basic testing of search calls using many files
*/
2007-08-28 12:54:27 +00:00
static bool test_many_files ( struct torture_context * tctx ,
2007-09-02 02:35:11 +00:00
struct smbcli_state * cli )
2003-08-13 01:53:07 +00:00
{
const int num_files = 700 ;
int i , fnum , t ;
char * fname ;
BOOL ret = True ;
NTSTATUS status ;
struct multiple_result result ;
struct {
const char * name ;
const char * cont_name ;
2006-07-06 08:00:24 +00:00
enum smb_search_data_level data_level ;
2003-08-13 01:53:07 +00:00
enum continue_type cont_type ;
} search_types [ ] = {
2006-07-06 08:00:24 +00:00
{ " 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 }
2003-08-13 01:53:07 +00:00
} ;
2004-11-12 09:37:59 +00:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2007-09-02 02:35:11 +00:00
return false ;
2003-08-13 01:53:07 +00:00
}
2007-09-02 02:35:11 +00:00
torture_comment ( tctx , " Testing with %d files \n " , num_files ) ;
2003-08-13 01:53:07 +00:00
for ( i = 0 ; i < num_files ; i + + ) {
2005-07-22 10:58:49 +00:00
fname = talloc_asprintf ( cli , BASEDIR " \\ t%03d-%d.txt " , i , i ) ;
2004-08-04 13:23:35 +00:00
fnum = smbcli_open ( cli - > tree , fname , O_CREAT | O_RDWR , DENY_NONE ) ;
2007-09-02 02:35:11 +00:00
torture_assert ( tctx , fnum ! = - 1 , " Failed to create " ) ;
2005-07-22 10:58:49 +00:00
talloc_free ( fname ) ;
2004-08-04 13:23:35 +00:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 01:53:07 +00:00
}
for ( t = 0 ; t < ARRAY_SIZE ( search_types ) ; t + + ) {
ZERO_STRUCT ( result ) ;
2007-08-28 12:54:27 +00:00
result . tctx = talloc_new ( tctx ) ;
2003-08-13 01:53:07 +00:00
2007-09-02 02:35:11 +00:00
torture_comment ( tctx ,
" Continue %s via %s \n " , search_types [ t ] . name , search_types [ t ] . cont_name ) ;
2003-08-13 01:53:07 +00:00
2007-08-28 12:54:27 +00:00
status = multiple_search ( cli , tctx , BASEDIR " \\ *.* " ,
2006-07-06 08:00:24 +00:00
search_types [ t ] . data_level ,
2003-08-13 01:53:07 +00:00
search_types [ t ] . cont_type ,
& result ) ;
2007-09-02 02:35:11 +00:00
torture_assert_ntstatus_ok ( tctx , status , " search failed " ) ;
2003-08-13 01:53:07 +00:00
CHECK_VALUE ( result . count , num_files ) ;
2006-07-06 08:00:24 +00:00
compare_data_level = search_types [ t ] . data_level ;
2006-04-01 03:46:46 +00:00
qsort ( result . list , result . count , sizeof ( result . list [ 0 ] ) ,
QSORT_CAST search_compare ) ;
2003-08-13 01:53:07 +00:00
2004-10-26 11:10:02 +00:00
for ( i = 0 ; i < result . count ; i + + ) {
2003-08-13 01:53:07 +00:00
const char * s ;
2006-07-06 08:00:24 +00:00
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 ) ;
2005-07-22 10:58:49 +00:00
fname = talloc_asprintf ( cli , " t%03d-%d.txt " , i , i ) ;
2007-09-02 02:35:11 +00:00
torture_assert_str_equal ( tctx , fname , s , " Incorrect name " ) ;
2005-07-22 10:58:49 +00:00
talloc_free ( fname ) ;
2003-08-13 01:53:07 +00:00
}
2007-08-28 12:54:27 +00:00
talloc_free ( result . tctx ) ;
2003-08-13 01:53:07 +00:00
}
smb_raw_exit ( cli - > session ) ;
2004-08-04 13:23:35 +00:00
smbcli_deltree ( cli - > tree , BASEDIR ) ;
2003-08-13 01:53:07 +00:00
return ret ;
}
2004-09-21 02:41:32 +00:00
/*
check a individual file result
*/
2007-09-02 02:35:11 +00:00
static bool check_result ( struct multiple_result * result , const char * name , BOOL exist , uint32_t attrib )
2004-09-21 02:41:32 +00:00
{
int i ;
for ( i = 0 ; i < result - > count ; i + + ) {
if ( strcmp ( name , result - > list [ i ] . both_directory_info . name . s ) = = 0 ) break ;
}
if ( i = = result - > count ) {
if ( exist ) {
printf ( " failed: '%s' should exist with attribute %s \n " ,
2004-10-11 09:23:19 +00:00
name , attrib_string ( result - > list , attrib ) ) ;
2004-09-21 02:41:32 +00:00
return False ;
}
2007-09-02 02:35:11 +00:00
return true ;
2004-09-21 02:41:32 +00:00
}
if ( ! exist ) {
printf ( " failed: '%s' should NOT exist (has attribute %s) \n " ,
2004-10-11 09:23:19 +00:00
name , attrib_string ( result - > list , result - > list [ i ] . both_directory_info . attrib ) ) ;
2004-09-21 02:41:32 +00:00
return False ;
}
if ( ( result - > list [ i ] . both_directory_info . attrib & 0xFFF ) ! = attrib ) {
printf ( " failed: '%s' should have attribute 0x%x (has 0x%x) \n " ,
name ,
attrib , result - > list [ i ] . both_directory_info . attrib ) ;
return False ;
}
2007-09-02 02:35:11 +00:00
return true ;
2004-09-21 02:41:32 +00:00
}
/*
test what happens when the directory is modified during a search
*/
2007-08-28 12:54:27 +00:00
static bool test_modify_search ( struct torture_context * tctx ,
struct smbcli_state * cli )
2004-09-21 02:41:32 +00:00
{
const int num_files = 20 ;
int i , fnum ;
char * fname ;
BOOL ret = True ;
NTSTATUS status ;
struct multiple_result result ;
union smb_search_first io ;
union smb_search_next io2 ;
union smb_setfileinfo sfinfo ;
2004-11-12 09:37:59 +00:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2004-09-21 02:41:32 +00:00
return False ;
}
printf ( " Creating %d files \n " , num_files ) ;
2004-10-26 09:50:13 +00:00
for ( i = num_files - 1 ; i > = 0 ; i - - ) {
2005-07-22 10:58:49 +00:00
fname = talloc_asprintf ( cli , BASEDIR " \\ t%03d-%d.txt " , i , i ) ;
2004-09-21 02:41:32 +00:00
fnum = smbcli_open ( cli - > tree , fname , O_CREAT | O_RDWR , DENY_NONE ) ;
if ( fnum = = - 1 ) {
printf ( " Failed to create %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
ret = False ;
goto done ;
}
2005-07-22 10:58:49 +00:00
talloc_free ( fname ) ;
2004-09-21 02:41:32 +00:00
smbcli_close ( cli - > tree , fnum ) ;
}
2004-10-26 11:10:02 +00:00
printf ( " pulling the first file \n " ) ;
2004-09-21 02:41:32 +00:00
ZERO_STRUCT ( result ) ;
2007-08-28 12:54:27 +00:00
result . tctx = talloc_new ( tctx ) ;
2004-09-21 02:41:32 +00:00
2006-07-06 08:00:24 +00:00
io . t2ffirst . level = RAW_SEARCH_TRANS2 ;
io . t2ffirst . data_level = RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO ;
2004-09-21 02:41:32 +00:00
io . t2ffirst . in . search_attrib = 0 ;
io . t2ffirst . in . max_count = 0 ;
io . t2ffirst . in . flags = 0 ;
io . t2ffirst . in . storage_type = 0 ;
io . t2ffirst . in . pattern = BASEDIR " \\ *.* " ;
2007-08-28 12:54:27 +00:00
status = smb_raw_search_first ( cli - > tree , tctx ,
2004-09-21 02:41:32 +00:00
& io , & result , multiple_search_callback ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( result . count , 1 ) ;
2004-09-24 07:32:52 +00:00
2004-10-26 11:10:02 +00:00
printf ( " pulling the second file \n " ) ;
2006-07-06 08:00:24 +00:00
io2 . t2fnext . level = RAW_SEARCH_TRANS2 ;
io2 . t2fnext . data_level = RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO ;
2004-09-21 02:41:32 +00:00
io2 . t2fnext . in . handle = io . t2ffirst . out . handle ;
2004-10-26 09:50:13 +00:00
io2 . t2fnext . in . max_count = 1 ;
2004-09-21 02:41:32 +00:00
io2 . t2fnext . in . resume_key = 0 ;
io2 . t2fnext . in . flags = 0 ;
2005-07-24 01:01:00 +00:00
io2 . t2fnext . in . last_name = result . list [ result . count - 1 ] . both_directory_info . name . s ;
2004-09-21 02:41:32 +00:00
2007-08-28 12:54:27 +00:00
status = smb_raw_search_next ( cli - > tree , tctx ,
2004-09-21 02:41:32 +00:00
& io2 , & result , multiple_search_callback ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2004-10-26 09:50:13 +00:00
CHECK_VALUE ( result . count , 2 ) ;
2004-09-21 02:41:32 +00:00
2005-07-26 04:47:16 +00:00
result . count = 0 ;
2004-09-21 02:41:32 +00:00
printf ( " Changing attributes and deleting \n " ) ;
smbcli_open ( cli - > tree , BASEDIR " \\ T003-03.txt.2 " , O_CREAT | O_RDWR , DENY_NONE ) ;
smbcli_open ( cli - > tree , BASEDIR " \\ T013-13.txt.2 " , O_CREAT | O_RDWR , DENY_NONE ) ;
2007-08-28 12:54:27 +00:00
fnum = create_complex_file ( cli , tctx , BASEDIR " \\ T013-13.txt.3 " ) ;
2004-09-21 02:41:32 +00:00
smbcli_unlink ( cli - > tree , BASEDIR " \\ T014-14.txt " ) ;
torture_set_file_attribute ( cli - > tree , BASEDIR " \\ T015-15.txt " , FILE_ATTRIBUTE_HIDDEN ) ;
torture_set_file_attribute ( cli - > tree , BASEDIR " \\ T016-16.txt " , FILE_ATTRIBUTE_NORMAL ) ;
torture_set_file_attribute ( cli - > tree , BASEDIR " \\ T017-17.txt " , FILE_ATTRIBUTE_SYSTEM ) ;
2004-10-26 11:10:02 +00:00
torture_set_file_attribute ( cli - > tree , BASEDIR " \\ T018-18.txt " , 0 ) ;
2004-09-21 02:41:32 +00:00
sfinfo . generic . level = RAW_SFILEINFO_DISPOSITION_INFORMATION ;
2006-03-12 22:48:25 +00:00
sfinfo . generic . in . file . fnum = fnum ;
2004-09-21 02:41:32 +00:00
sfinfo . disposition_info . in . delete_on_close = 1 ;
status = smb_raw_setfileinfo ( cli - > tree , & sfinfo ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2006-07-06 08:00:24 +00:00
io2 . t2fnext . level = RAW_SEARCH_TRANS2 ;
io2 . t2fnext . data_level = RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO ;
2004-09-21 02:41:32 +00:00
io2 . t2fnext . in . handle = io . t2ffirst . out . handle ;
2005-07-24 01:01:00 +00:00
io2 . t2fnext . in . max_count = num_files + 3 ;
2004-09-21 02:41:32 +00:00
io2 . t2fnext . in . resume_key = 0 ;
io2 . t2fnext . in . flags = 0 ;
2005-07-24 01:01:00 +00:00
io2 . t2fnext . in . last_name = " . " ;
2004-09-21 02:41:32 +00:00
2007-08-28 12:54:27 +00:00
status = smb_raw_search_next ( cli - > tree , tctx ,
2004-09-21 02:41:32 +00:00
& io2 , & result , multiple_search_callback ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2005-07-26 04:47:16 +00:00
CHECK_VALUE ( result . count , 20 ) ;
2004-09-21 02:41:32 +00:00
ret & = check_result ( & result , " t009-9.txt " , True , FILE_ATTRIBUTE_ARCHIVE ) ;
ret & = check_result ( & result , " t014-14.txt " , False , 0 ) ;
ret & = check_result ( & result , " t015-15.txt " , False , 0 ) ;
ret & = check_result ( & result , " t016-16.txt " , True , FILE_ATTRIBUTE_NORMAL ) ;
ret & = check_result ( & result , " t017-17.txt " , False , 0 ) ;
ret & = check_result ( & result , " t018-18.txt " , True , FILE_ATTRIBUTE_ARCHIVE ) ;
ret & = check_result ( & result , " t019-19.txt " , True , FILE_ATTRIBUTE_ARCHIVE ) ;
ret & = check_result ( & result , " T013-13.txt.2 " , True , FILE_ATTRIBUTE_ARCHIVE ) ;
ret & = check_result ( & result , " T003-3.txt.2 " , False , 0 ) ;
ret & = check_result ( & result , " T013-13.txt.3 " , True , FILE_ATTRIBUTE_ARCHIVE ) ;
if ( ! ret ) {
for ( i = 0 ; i < result . count ; i + + ) {
printf ( " %s %s (0x%x) \n " ,
result . list [ i ] . both_directory_info . name . s ,
2007-08-28 12:54:27 +00:00
attrib_string ( tctx , result . list [ i ] . both_directory_info . attrib ) ,
2004-09-21 02:41:32 +00:00
result . list [ i ] . both_directory_info . attrib ) ;
}
}
done :
smb_raw_exit ( cli - > session ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
/*
testing if directories always come back sorted
*/
2007-08-28 12:54:27 +00:00
static bool test_sorted ( struct torture_context * tctx , struct smbcli_state * cli )
2004-09-21 02:41:32 +00:00
{
const int num_files = 700 ;
int i , fnum ;
char * fname ;
BOOL ret = True ;
NTSTATUS status ;
struct multiple_result result ;
2004-11-12 09:37:59 +00:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2004-09-21 02:41:32 +00:00
return False ;
}
printf ( " Creating %d files \n " , num_files ) ;
for ( i = 0 ; i < num_files ; i + + ) {
2007-08-28 12:54:27 +00:00
fname = talloc_asprintf ( cli , BASEDIR " \\ %s.txt " , generate_random_str_list ( tctx , 10 , " abcdefgh " ) ) ;
2004-09-21 02:41:32 +00:00
fnum = smbcli_open ( cli - > tree , fname , O_CREAT | O_RDWR , DENY_NONE ) ;
if ( fnum = = - 1 ) {
printf ( " Failed to create %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
ret = False ;
goto done ;
}
2005-07-22 10:58:49 +00:00
talloc_free ( fname ) ;
2004-09-21 02:41:32 +00:00
smbcli_close ( cli - > tree , fnum ) ;
}
ZERO_STRUCT ( result ) ;
2007-08-28 12:54:27 +00:00
result . tctx = tctx ;
2004-09-21 02:41:32 +00:00
2007-08-28 12:54:27 +00:00
status = multiple_search ( cli , tctx , BASEDIR " \\ *.* " ,
2006-07-06 08:00:24 +00:00
RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO ,
2004-09-21 02:41:32 +00:00
CONT_NAME , & result ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
CHECK_VALUE ( result . count , num_files ) ;
for ( i = 0 ; i < num_files - 1 ; i + + ) {
const char * name1 , * name2 ;
name1 = result . list [ i ] . both_directory_info . name . s ;
name2 = result . list [ i + 1 ] . both_directory_info . name . s ;
2005-08-30 11:55:05 +00:00
if ( strcasecmp_m ( name1 , name2 ) > 0 ) {
2004-09-21 02:41:32 +00:00
printf ( " non-alphabetical order at entry %d '%s' '%s' \n " ,
i , name1 , name2 ) ;
2004-10-12 05:36:37 +00:00
printf ( " Server does not produce sorted directory listings (not an error) \n " ) ;
2004-09-21 02:41:32 +00:00
goto done ;
}
}
2004-09-26 04:59:03 +00:00
talloc_free ( result . list ) ;
2004-09-21 02:41:32 +00:00
done :
smb_raw_exit ( cli - > session ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
2003-08-13 01:53:07 +00:00
2004-10-27 01:11:44 +00:00
2003-08-13 01:53:07 +00:00
/*
2004-10-27 01:11:44 +00:00
basic testing of many old style search calls using separate dirs
2003-08-13 01:53:07 +00:00
*/
2007-08-28 12:54:27 +00:00
static bool test_many_dirs ( struct torture_context * tctx ,
struct smbcli_state * cli )
2003-08-13 01:53:07 +00:00
{
2006-09-16 17:26:55 +00:00
const int num_dirs = 20 ;
2004-10-27 01:11:44 +00:00
int i , fnum , n ;
char * fname , * dname ;
2003-08-13 01:53:07 +00:00
BOOL ret = True ;
2004-10-27 01:11:44 +00:00
NTSTATUS status ;
union smb_search_data * file , * file2 , * file3 ;
2003-08-13 01:53:07 +00:00
2004-11-12 09:37:59 +00:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2003-08-13 01:53:07 +00:00
return False ;
}
2004-10-27 01:11:44 +00:00
printf ( " Creating %d dirs \n " , num_dirs ) ;
2003-08-13 01:53:07 +00:00
2004-10-27 01:11:44 +00:00
for ( i = 0 ; i < num_dirs ; i + + ) {
2005-07-22 10:58:49 +00:00
dname = talloc_asprintf ( cli , BASEDIR " \\ d%d " , i ) ;
2004-10-27 01:11:44 +00:00
status = smbcli_mkdir ( cli - > tree , dname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " (%s) Failed to create %s - %s \n " ,
__location__ , dname , nt_errstr ( status ) ) ;
ret = False ;
goto done ;
}
for ( n = 0 ; n < 3 ; n + + ) {
2005-07-22 10:58:49 +00:00
fname = talloc_asprintf ( cli , BASEDIR " \\ d%d \\ f%d-%d.txt " , i , i , n ) ;
2004-10-27 01:11:44 +00:00
fnum = smbcli_open ( cli - > tree , fname , O_CREAT | O_RDWR , DENY_NONE ) ;
if ( fnum = = - 1 ) {
printf ( " (%s) Failed to create %s - %s \n " ,
__location__ , fname , smbcli_errstr ( cli - > tree ) ) ;
ret = False ;
goto done ;
}
2005-07-22 10:58:49 +00:00
talloc_free ( fname ) ;
2005-07-15 12:58:09 +00:00
smbcli_close ( cli - > tree , fnum ) ;
2004-10-27 01:11:44 +00:00
}
2005-07-22 10:58:49 +00:00
talloc_free ( dname ) ;
2003-08-13 01:53:07 +00:00
}
2007-08-28 12:54:27 +00:00
file = talloc_zero_array ( tctx , union smb_search_data , num_dirs ) ;
file2 = talloc_zero_array ( tctx , union smb_search_data , num_dirs ) ;
file3 = talloc_zero_array ( tctx , union smb_search_data , num_dirs ) ;
2004-10-27 01:11:44 +00:00
printf ( " Search first on %d dirs \n " , num_dirs ) ;
for ( i = 0 ; i < num_dirs ; i + + ) {
union smb_search_first io ;
2006-07-06 08:00:24 +00:00
io . search_first . level = RAW_SEARCH_SEARCH ;
io . search_first . data_level = RAW_SEARCH_DATA_SEARCH ;
2004-10-27 01:11:44 +00:00
io . search_first . in . max_count = 1 ;
io . search_first . in . search_attrib = 0 ;
2007-08-28 12:54:27 +00:00
io . search_first . in . pattern = talloc_asprintf ( tctx , BASEDIR " \\ d%d \\ *.txt " , i ) ;
fname = talloc_asprintf ( tctx , " f%d- " , i ) ;
2004-10-27 01:11:44 +00:00
io . search_first . out . count = 0 ;
2007-08-28 12:54:27 +00:00
status = smb_raw_search_first ( cli - > tree , tctx ,
2004-10-27 01:11:44 +00:00
& io , ( void * ) & file [ i ] , single_search_callback ) ;
if ( io . search_first . out . count ! = 1 ) {
printf ( " (%s) search first gave %d entries for dir %d - %s \n " ,
__location__ , io . search_first . out . count , i , nt_errstr ( status ) ) ;
ret = False ;
goto done ;
}
CHECK_STATUS ( status , NT_STATUS_OK ) ;
if ( strncasecmp ( file [ i ] . search . name , fname , strlen ( fname ) ) ! = 0 ) {
printf ( " (%s) incorrect name '%s' expected '%s'[12].txt \n " ,
__location__ , file [ i ] . search . name , fname ) ;
ret = False ;
goto done ;
}
talloc_free ( fname ) ;
2003-08-13 01:53:07 +00:00
}
2004-10-27 01:11:44 +00:00
printf ( " Search next on %d dirs \n " , num_dirs ) ;
for ( i = 0 ; i < num_dirs ; i + + ) {
union smb_search_next io2 ;
2006-07-06 08:00:24 +00:00
io2 . search_next . level = RAW_SEARCH_SEARCH ;
io2 . search_next . data_level = RAW_SEARCH_DATA_SEARCH ;
2004-10-27 01:11:44 +00:00
io2 . search_next . in . max_count = 1 ;
io2 . search_next . in . search_attrib = 0 ;
io2 . search_next . in . id = file [ i ] . search . id ;
2007-08-28 12:54:27 +00:00
fname = talloc_asprintf ( tctx , " f%d- " , i ) ;
2004-10-27 01:11:44 +00:00
io2 . search_next . out . count = 0 ;
2007-08-28 12:54:27 +00:00
status = smb_raw_search_next ( cli - > tree , tctx ,
2004-10-27 01:11:44 +00:00
& io2 , ( void * ) & file2 [ i ] , single_search_callback ) ;
if ( io2 . search_next . out . count ! = 1 ) {
printf ( " (%s) search next gave %d entries for dir %d - %s \n " ,
__location__ , io2 . search_next . out . count , i , nt_errstr ( status ) ) ;
ret = False ;
goto done ;
}
CHECK_STATUS ( status , NT_STATUS_OK ) ;
if ( strncasecmp ( file2 [ i ] . search . name , fname , strlen ( fname ) ) ! = 0 ) {
printf ( " (%s) incorrect name '%s' expected '%s'[12].txt \n " ,
__location__ , file2 [ i ] . search . name , fname ) ;
ret = False ;
goto done ;
}
talloc_free ( fname ) ;
2004-09-21 02:41:32 +00:00
}
2004-10-27 01:11:44 +00:00
printf ( " Search next (rewind) on %d dirs \n " , num_dirs ) ;
for ( i = 0 ; i < num_dirs ; i + + ) {
union smb_search_next io2 ;
2006-07-06 08:00:24 +00:00
io2 . search_next . level = RAW_SEARCH_SEARCH ;
io2 . search_next . data_level = RAW_SEARCH_DATA_SEARCH ;
2004-10-27 01:11:44 +00:00
io2 . search_next . in . max_count = 1 ;
io2 . search_next . in . search_attrib = 0 ;
io2 . search_next . in . id = file [ i ] . search . id ;
2007-08-28 12:54:27 +00:00
fname = talloc_asprintf ( tctx , " f%d- " , i ) ;
2004-10-27 01:11:44 +00:00
io2 . search_next . out . count = 0 ;
2007-08-28 12:54:27 +00:00
status = smb_raw_search_next ( cli - > tree , tctx ,
2004-10-27 01:11:44 +00:00
& io2 , ( void * ) & file3 [ i ] , single_search_callback ) ;
if ( io2 . search_next . out . count ! = 1 ) {
printf ( " (%s) search next gave %d entries for dir %d - %s \n " ,
__location__ , io2 . search_next . out . count , i , nt_errstr ( status ) ) ;
ret = False ;
goto done ;
}
CHECK_STATUS ( status , NT_STATUS_OK ) ;
if ( strncasecmp ( file3 [ i ] . search . name , file2 [ i ] . search . name , 3 ) ! = 0 ) {
printf ( " (%s) incorrect name '%s' on rewind at dir %d \n " ,
__location__ , file2 [ i ] . search . name , i ) ;
ret = False ;
goto done ;
}
if ( strcmp ( file3 [ i ] . search . name , file2 [ i ] . search . name ) ! = 0 ) {
printf ( " (%s) server did not rewind - got '%s' expected '%s' \n " ,
__location__ , file3 [ i ] . search . name , file2 [ i ] . search . name ) ;
ret = False ;
goto done ;
}
talloc_free ( fname ) ;
}
done :
smb_raw_exit ( cli - > session ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
2004-12-12 11:29:35 +00:00
/*
testing of OS / 2 style delete
*/
2007-08-28 12:54:27 +00:00
static bool test_os2_delete ( struct torture_context * tctx ,
struct smbcli_state * cli )
2004-12-12 11:29:35 +00:00
{
const int num_files = 700 ;
const int delete_count = 4 ;
int total_deleted = 0 ;
int i , fnum ;
char * fname ;
BOOL ret = True ;
NTSTATUS status ;
union smb_search_first io ;
union smb_search_next io2 ;
struct multiple_result result ;
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
return False ;
}
printf ( " Testing OS/2 style delete on %d files \n " , num_files ) ;
for ( i = 0 ; i < num_files ; i + + ) {
2005-07-22 10:58:49 +00:00
fname = talloc_asprintf ( cli , BASEDIR " \\ file%u.txt " , i ) ;
2004-12-12 11:29:35 +00:00
fnum = smbcli_open ( cli - > tree , fname , O_CREAT | O_RDWR , DENY_NONE ) ;
if ( fnum = = - 1 ) {
printf ( " Failed to create %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
ret = False ;
goto done ;
}
2005-07-22 10:58:49 +00:00
talloc_free ( fname ) ;
2004-12-12 11:29:35 +00:00
smbcli_close ( cli - > tree , fnum ) ;
}
ZERO_STRUCT ( result ) ;
2007-08-28 12:54:27 +00:00
result . tctx = tctx ;
2004-12-12 11:29:35 +00:00
2006-07-06 08:00:24 +00:00
io . t2ffirst . level = RAW_SEARCH_TRANS2 ;
io . t2ffirst . data_level = RAW_SEARCH_DATA_EA_SIZE ;
2004-12-12 11:29:35 +00:00
io . t2ffirst . in . search_attrib = 0 ;
io . t2ffirst . in . max_count = 100 ;
io . t2ffirst . in . flags = FLAG_TRANS2_FIND_REQUIRE_RESUME ;
io . t2ffirst . in . storage_type = 0 ;
io . t2ffirst . in . pattern = BASEDIR " \\ * " ;
2007-08-28 12:54:27 +00:00
status = smb_raw_search_first ( cli - > tree , tctx ,
2004-12-12 11:29:35 +00:00
& io , & result , multiple_search_callback ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
for ( i = 0 ; i < MIN ( result . count , delete_count ) ; i + + ) {
2005-07-22 10:58:49 +00:00
fname = talloc_asprintf ( cli , BASEDIR " \\ %s " , result . list [ i ] . ea_size . name . s ) ;
2004-12-12 11:29:35 +00:00
status = smbcli_unlink ( cli - > tree , fname ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
total_deleted + + ;
2005-07-22 10:58:49 +00:00
talloc_free ( fname ) ;
2004-12-12 11:29:35 +00:00
}
2006-07-06 08:00:24 +00:00
io2 . t2fnext . level = RAW_SEARCH_TRANS2 ;
io2 . t2fnext . data_level = RAW_SEARCH_DATA_EA_SIZE ;
2004-12-12 11:29:35 +00:00
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 ;
io2 . t2fnext . in . flags = FLAG_TRANS2_FIND_REQUIRE_RESUME ;
io2 . t2fnext . in . last_name = result . list [ i - 1 ] . ea_size . name . s ;
do {
ZERO_STRUCT ( result ) ;
2007-08-28 12:54:27 +00:00
result . tctx = tctx ;
2004-12-12 11:29:35 +00:00
2007-08-28 12:54:27 +00:00
status = smb_raw_search_next ( cli - > tree , tctx ,
2004-12-12 11:29:35 +00:00
& io2 , & result , multiple_search_callback ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
break ;
}
for ( i = 0 ; i < MIN ( result . count , delete_count ) ; i + + ) {
2005-07-22 10:58:49 +00:00
fname = talloc_asprintf ( cli , BASEDIR " \\ %s " , result . list [ i ] . ea_size . name . s ) ;
2004-12-12 11:29:35 +00:00
status = smbcli_unlink ( cli - > tree , fname ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
total_deleted + + ;
2005-07-22 10:58:49 +00:00
talloc_free ( fname ) ;
2004-12-12 11:29:35 +00:00
}
if ( i > 0 ) {
2004-12-13 10:48:21 +00:00
io2 . t2fnext . in . resume_key = result . list [ i - 1 ] . ea_size . resume_key ;
2004-12-12 11:29:35 +00:00
io2 . t2fnext . in . last_name = result . list [ i - 1 ] . ea_size . name . s ;
}
} while ( NT_STATUS_IS_OK ( status ) & & result . count ! = 0 ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
if ( total_deleted ! = num_files ) {
printf ( " error: deleted %d - expected to delete %d \n " ,
total_deleted , num_files ) ;
ret = False ;
}
done :
smb_raw_exit ( cli - > session ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
2005-07-22 09:49:32 +00:00
static int ealist_cmp ( union smb_search_data * r1 , union smb_search_data * r2 )
{
return strcmp ( r1 - > ea_list . name . s , r2 - > ea_list . name . s ) ;
}
2004-12-18 04:38:43 +00:00
/*
testing of the rather strange ea_list level
*/
2007-08-28 12:54:27 +00:00
static bool test_ea_list ( struct torture_context * tctx ,
struct smbcli_state * cli )
2004-12-18 04:38:43 +00:00
{
int fnum ;
BOOL ret = True ;
NTSTATUS status ;
union smb_search_first io ;
union smb_search_next nxt ;
struct multiple_result result ;
union smb_setfileinfo setfile ;
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
return False ;
}
printf ( " Testing RAW_SEARCH_EA_LIST level \n " ) ;
fnum = smbcli_open ( cli - > tree , BASEDIR " \\ file1.txt " , O_CREAT | O_RDWR , DENY_NONE ) ;
smbcli_close ( cli - > tree , fnum ) ;
fnum = smbcli_open ( cli - > tree , BASEDIR " \\ file2.txt " , O_CREAT | O_RDWR , DENY_NONE ) ;
smbcli_close ( cli - > tree , fnum ) ;
fnum = smbcli_open ( cli - > tree , BASEDIR " \\ file3.txt " , O_CREAT | O_RDWR , DENY_NONE ) ;
smbcli_close ( cli - > tree , fnum ) ;
setfile . generic . level = RAW_SFILEINFO_EA_SET ;
2006-03-12 22:48:25 +00:00
setfile . generic . in . file . path = BASEDIR " \\ file2.txt " ;
2004-12-18 04:38:43 +00:00
setfile . ea_set . in . num_eas = 2 ;
2007-08-28 12:54:27 +00:00
setfile . ea_set . in . eas = talloc_array ( tctx , struct ea_struct , 2 ) ;
2004-12-18 04:38:43 +00:00
setfile . ea_set . in . eas [ 0 ] . flags = 0 ;
setfile . ea_set . in . eas [ 0 ] . name . s = " EA ONE " ;
setfile . ea_set . in . eas [ 0 ] . value = data_blob_string_const ( " VALUE 1 " ) ;
setfile . ea_set . in . eas [ 1 ] . flags = 0 ;
setfile . ea_set . in . eas [ 1 ] . name . s = " SECOND EA " ;
setfile . ea_set . in . eas [ 1 ] . value = data_blob_string_const ( " Value Two " ) ;
status = smb_raw_setpathinfo ( cli - > tree , & setfile ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2006-03-12 22:48:25 +00:00
setfile . generic . in . file . path = BASEDIR " \\ file3.txt " ;
2004-12-18 04:38:43 +00:00
status = smb_raw_setpathinfo ( cli - > tree , & setfile ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
ZERO_STRUCT ( result ) ;
2007-08-28 12:54:27 +00:00
result . tctx = tctx ;
2004-12-18 04:38:43 +00:00
2006-07-06 08:00:24 +00:00
io . t2ffirst . level = RAW_SEARCH_TRANS2 ;
io . t2ffirst . data_level = RAW_SEARCH_DATA_EA_LIST ;
2004-12-18 04:38:43 +00:00
io . t2ffirst . in . search_attrib = 0 ;
io . t2ffirst . in . max_count = 2 ;
io . t2ffirst . in . flags = FLAG_TRANS2_FIND_REQUIRE_RESUME ;
io . t2ffirst . in . storage_type = 0 ;
io . t2ffirst . in . pattern = BASEDIR " \\ * " ;
io . t2ffirst . in . num_names = 2 ;
2007-08-28 12:54:27 +00:00
io . t2ffirst . in . ea_names = talloc_array ( tctx , struct ea_name , 2 ) ;
2004-12-18 04:38:43 +00:00
io . t2ffirst . in . ea_names [ 0 ] . name . s = " SECOND EA " ;
io . t2ffirst . in . ea_names [ 1 ] . name . s = " THIRD EA " ;
2007-08-28 12:54:27 +00:00
status = smb_raw_search_first ( cli - > tree , tctx ,
2004-12-18 04:38:43 +00:00
& io , & result , multiple_search_callback ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2004-12-21 11:48:13 +00:00
CHECK_VALUE ( result . count , 2 ) ;
2004-12-18 04:38:43 +00:00
2006-07-06 08:00:24 +00:00
nxt . t2fnext . level = RAW_SEARCH_TRANS2 ;
nxt . t2fnext . data_level = RAW_SEARCH_DATA_EA_LIST ;
2004-12-18 04:38:43 +00:00
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 ;
nxt . t2fnext . in . flags = FLAG_TRANS2_FIND_REQUIRE_RESUME | FLAG_TRANS2_FIND_CONTINUE ;
2005-07-22 09:49:32 +00:00
nxt . t2fnext . in . last_name = result . list [ 1 ] . ea_list . name . s ;
2004-12-18 04:38:43 +00:00
nxt . t2fnext . in . num_names = 2 ;
2007-08-28 12:54:27 +00:00
nxt . t2fnext . in . ea_names = talloc_array ( tctx , struct ea_name , 2 ) ;
2004-12-18 04:38:43 +00:00
nxt . t2fnext . in . ea_names [ 0 ] . name . s = " SECOND EA " ;
nxt . t2fnext . in . ea_names [ 1 ] . name . s = " THIRD EA " ;
2007-08-28 12:54:27 +00:00
status = smb_raw_search_next ( cli - > tree , tctx ,
2004-12-18 04:38:43 +00:00
& nxt , & result , multiple_search_callback ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2005-07-22 09:49:32 +00:00
/* we have to sort the result as different servers can return directories
in different orders */
qsort ( result . list , result . count , sizeof ( result . list [ 0 ] ) ,
( comparison_fn_t ) ealist_cmp ) ;
2004-12-18 04:38:43 +00:00
CHECK_VALUE ( result . count , 3 ) ;
CHECK_VALUE ( result . list [ 0 ] . ea_list . eas . num_eas , 2 ) ;
CHECK_STRING ( result . list [ 0 ] . ea_list . name . s , " file1.txt " ) ;
CHECK_STRING ( result . list [ 0 ] . ea_list . eas . eas [ 0 ] . name . s , " SECOND EA " ) ;
CHECK_VALUE ( result . list [ 0 ] . ea_list . eas . eas [ 0 ] . value . length , 0 ) ;
CHECK_STRING ( result . list [ 0 ] . ea_list . eas . eas [ 1 ] . name . s , " THIRD EA " ) ;
CHECK_VALUE ( result . list [ 0 ] . ea_list . eas . eas [ 1 ] . value . length , 0 ) ;
CHECK_STRING ( result . list [ 1 ] . ea_list . name . s , " file2.txt " ) ;
CHECK_STRING ( result . list [ 1 ] . ea_list . eas . eas [ 0 ] . name . s , " SECOND EA " ) ;
CHECK_VALUE ( result . list [ 1 ] . ea_list . eas . eas [ 0 ] . value . length , 9 ) ;
2006-01-18 16:20:33 +00:00
CHECK_STRING ( ( const char * ) result . list [ 1 ] . ea_list . eas . eas [ 0 ] . value . data , " Value Two " ) ;
2004-12-18 04:38:43 +00:00
CHECK_STRING ( result . list [ 1 ] . ea_list . eas . eas [ 1 ] . name . s , " THIRD EA " ) ;
CHECK_VALUE ( result . list [ 1 ] . ea_list . eas . eas [ 1 ] . value . length , 0 ) ;
CHECK_STRING ( result . list [ 2 ] . ea_list . name . s , " file3.txt " ) ;
CHECK_STRING ( result . list [ 2 ] . ea_list . eas . eas [ 0 ] . name . s , " SECOND EA " ) ;
CHECK_VALUE ( result . list [ 2 ] . ea_list . eas . eas [ 0 ] . value . length , 9 ) ;
2006-01-18 16:20:33 +00:00
CHECK_STRING ( ( const char * ) result . list [ 2 ] . ea_list . eas . eas [ 0 ] . value . data , " Value Two " ) ;
2004-12-18 04:38:43 +00:00
CHECK_STRING ( result . list [ 2 ] . ea_list . eas . eas [ 1 ] . name . s , " THIRD EA " ) ;
CHECK_VALUE ( result . list [ 2 ] . ea_list . eas . eas [ 1 ] . value . length , 0 ) ;
smb_raw_exit ( cli - > session ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
2004-12-12 11:29:35 +00:00
2004-10-27 01:11:44 +00:00
/*
basic testing of all RAW_SEARCH_ * calls using a single file
*/
2007-08-28 12:54:27 +00:00
struct torture_suite * torture_raw_search ( TALLOC_CTX * mem_ctx )
2004-10-27 01:11:44 +00:00
{
2007-08-28 12:54:27 +00:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " SEARCH " ) ;
2004-09-21 02:41:32 +00:00
2007-09-02 02:35:11 +00:00
torture_suite_add_1smb_test ( suite , " one file search " , test_one_file ) ;
2007-08-28 12:54:27 +00:00
torture_suite_add_1smb_test ( suite , " many files " , test_many_files ) ;
torture_suite_add_1smb_test ( suite , " sorted " , test_sorted ) ;
torture_suite_add_1smb_test ( suite , " modify search " , test_modify_search ) ;
torture_suite_add_1smb_test ( suite , " many dirs " , test_many_dirs ) ;
torture_suite_add_1smb_test ( suite , " os2 delete " , test_os2_delete ) ;
torture_suite_add_1smb_test ( suite , " ea list " , test_ea_list ) ;
2004-10-27 01:11:44 +00:00
2007-08-28 12:54:27 +00:00
return suite ;
2003-08-13 01:53:07 +00:00
}