2003-08-13 01:53:07 +00:00
/*
Unix SMB / CIFS implementation .
RAW_SFILEINFO_ * 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"
2004-11-02 00:24:21 +00:00
# include "system/time.h"
2005-12-28 15:38:36 +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 "\\testsfileinfo"
/* basic testing of all RAW_SFILEINFO_* calls
for each call we test that it succeeds , and where possible test
for consistency between the calls .
*/
2009-11-24 16:25:02 -08:00
static bool
torture_raw_sfileinfo_base ( struct torture_context * torture , struct smbcli_state * cli )
2003-08-13 01:53:07 +00:00
{
2007-09-08 15:09:59 +00:00
bool ret = true ;
int fnum = - 1 ;
2003-08-13 01:53:07 +00:00
char * fnum_fname ;
char * fnum_fname_new ;
char * path_fname ;
char * path_fname_new ;
union smb_fileinfo finfo1 , finfo2 ;
union smb_setfileinfo sfinfo ;
NTSTATUS status , status2 ;
const char * call_name ;
time_t basetime = ( time ( NULL ) - 86400 ) & ~ 1 ;
2007-10-06 22:28:14 +00:00
bool check_fnum ;
2003-08-13 01:53:07 +00:00
int n = time ( NULL ) % 100 ;
asprintf ( & path_fname , BASEDIR " \\ fname_test_%d.txt " , n ) ;
asprintf ( & path_fname_new , BASEDIR " \\ fname_test_new_%d.txt " , n ) ;
asprintf ( & fnum_fname , BASEDIR " \\ fnum_test_%d.txt " , n ) ;
asprintf ( & fnum_fname_new , BASEDIR " \\ fnum_test_new_%d.txt " , n ) ;
2004-11-12 09:37:59 +00:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2007-10-06 22:28:14 +00:00
return false ;
2004-11-12 09:37:59 +00:00
}
2003-08-13 01:53:07 +00:00
# define RECREATE_FILE(fname) do { \
2004-08-04 13:23:35 +00:00
if ( fnum ! = - 1 ) smbcli_close ( cli - > tree , fnum ) ; \
2007-08-28 12:54:27 +00:00
fnum = create_complex_file ( cli , torture , fname ) ; \
2003-08-13 01:53:07 +00:00
if ( fnum = = - 1 ) { \
2004-11-07 10:03:56 +00:00
printf ( " (%s) ERROR: open of %s failed (%s) \n " , \
__location__ , fname , smbcli_errstr ( cli - > tree ) ) ; \
2007-10-06 22:28:14 +00:00
ret = false ; \
2003-08-13 01:53:07 +00:00
goto done ; \
} } while ( 0 )
# define RECREATE_BOTH do { \
RECREATE_FILE ( path_fname ) ; \
2004-08-04 13:23:35 +00:00
smbcli_close ( cli - > tree , fnum ) ; \
2003-08-13 01:53:07 +00:00
RECREATE_FILE ( fnum_fname ) ; \
} while ( 0 )
RECREATE_BOTH ;
# define CHECK_CALL_FNUM(call, rightstatus) do { \
2007-10-06 22:28:14 +00:00
check_fnum = true ; \
2003-08-13 01:53:07 +00:00
call_name = # call ; \
sfinfo . generic . level = RAW_SFILEINFO_ # # call ; \
2006-03-12 22:48:25 +00:00
sfinfo . generic . in . file . fnum = fnum ; \
2003-08-13 01:53:07 +00:00
status = smb_raw_setfileinfo ( cli - > tree , & sfinfo ) ; \
if ( ! NT_STATUS_EQUAL ( status , rightstatus ) ) { \
2004-11-07 10:03:56 +00:00
printf ( " (%s) %s - %s (should be %s) \n " , __location__ , # call , \
2003-08-13 01:53:07 +00:00
nt_errstr ( status ) , nt_errstr ( rightstatus ) ) ; \
2007-10-06 22:28:14 +00:00
ret = false ; \
2003-08-13 01:53:07 +00:00
} \
finfo1 . generic . level = RAW_FILEINFO_ALL_INFO ; \
2006-03-12 22:48:25 +00:00
finfo1 . generic . in . file . fnum = fnum ; \
2007-08-28 12:54:27 +00:00
status2 = smb_raw_fileinfo ( cli - > tree , torture , & finfo1 ) ; \
2003-08-13 01:53:07 +00:00
if ( ! NT_STATUS_IS_OK ( status2 ) ) { \
2004-11-07 10:03:56 +00:00
printf ( " (%s) %s pathinfo - %s \n " , __location__ , # call , nt_errstr ( status ) ) ; \
2007-10-06 22:28:14 +00:00
ret = false ; \
2003-08-13 01:53:07 +00:00
} } while ( 0 )
# define CHECK_CALL_PATH(call, rightstatus) do { \
2007-10-06 22:28:14 +00:00
check_fnum = false ; \
2003-08-13 01:53:07 +00:00
call_name = # call ; \
sfinfo . generic . level = RAW_SFILEINFO_ # # call ; \
2006-03-12 22:48:25 +00:00
sfinfo . generic . in . file . path = path_fname ; \
2003-08-13 01:53:07 +00:00
status = smb_raw_setpathinfo ( cli - > tree , & sfinfo ) ; \
if ( NT_STATUS_EQUAL ( status , NT_STATUS_OBJECT_NAME_NOT_FOUND ) ) { \
2006-03-12 22:48:25 +00:00
sfinfo . generic . in . file . path = path_fname_new ; \
2003-08-13 01:53:07 +00:00
status = smb_raw_setpathinfo ( cli - > tree , & sfinfo ) ; \
} \
if ( ! NT_STATUS_EQUAL ( status , rightstatus ) ) { \
2004-11-07 10:03:56 +00:00
printf ( " (%s) %s - %s (should be %s) \n " , __location__ , # call , \
2003-08-13 01:53:07 +00:00
nt_errstr ( status ) , nt_errstr ( rightstatus ) ) ; \
2007-10-06 22:28:14 +00:00
ret = false ; \
2003-08-13 01:53:07 +00:00
} \
finfo1 . generic . level = RAW_FILEINFO_ALL_INFO ; \
2006-03-12 22:48:25 +00:00
finfo1 . generic . in . file . path = path_fname ; \
2007-08-28 12:54:27 +00:00
status2 = smb_raw_pathinfo ( cli - > tree , torture , & finfo1 ) ; \
2003-08-13 01:53:07 +00:00
if ( NT_STATUS_EQUAL ( status2 , NT_STATUS_OBJECT_NAME_NOT_FOUND ) ) { \
2006-03-12 22:48:25 +00:00
finfo1 . generic . in . file . path = path_fname_new ; \
2007-08-28 12:54:27 +00:00
status2 = smb_raw_pathinfo ( cli - > tree , torture , & finfo1 ) ; \
2003-08-13 01:53:07 +00:00
} \
if ( ! NT_STATUS_IS_OK ( status2 ) ) { \
2004-11-07 10:03:56 +00:00
printf ( " (%s) %s pathinfo - %s \n " , __location__ , # call , nt_errstr ( status2 ) ) ; \
2007-10-06 22:28:14 +00:00
ret = false ; \
2003-08-13 01:53:07 +00:00
} } while ( 0 )
# define CHECK1(call) \
do { if ( NT_STATUS_IS_OK ( status ) ) { \
finfo2 . generic . level = RAW_FILEINFO_ # # call ; \
if ( check_fnum ) { \
2006-03-12 22:48:25 +00:00
finfo2 . generic . in . file . fnum = fnum ; \
2007-08-28 12:54:27 +00:00
status2 = smb_raw_fileinfo ( cli - > tree , torture , & finfo2 ) ; \
2003-08-13 01:53:07 +00:00
} else { \
2006-03-12 22:48:25 +00:00
finfo2 . generic . in . file . path = path_fname ; \
2007-08-28 12:54:27 +00:00
status2 = smb_raw_pathinfo ( cli - > tree , torture , & finfo2 ) ; \
2003-08-13 01:53:07 +00:00
if ( NT_STATUS_EQUAL ( status2 , NT_STATUS_OBJECT_NAME_NOT_FOUND ) ) { \
2006-03-12 22:48:25 +00:00
finfo2 . generic . in . file . path = path_fname_new ; \
2007-08-28 12:54:27 +00:00
status2 = smb_raw_pathinfo ( cli - > tree , torture , & finfo2 ) ; \
2003-08-13 01:53:07 +00:00
} \
} \
if ( ! NT_STATUS_IS_OK ( status2 ) ) { \
printf ( " %s - %s \n " , # call , nt_errstr ( status2 ) ) ; \
2007-10-06 22:28:14 +00:00
ret = false ; \
2003-08-13 01:53:07 +00:00
} \
} } while ( 0 )
# define CHECK_VALUE(call, stype, field, value) do { \
CHECK1 ( call ) ; \
2003-10-10 05:40:32 +00:00
if ( NT_STATUS_IS_OK ( status ) & & NT_STATUS_IS_OK ( status2 ) & & finfo2 . stype . out . field ! = value ) { \
2004-11-07 10:03:56 +00:00
printf ( " (%s) %s - %s/%s should be 0x%x - 0x%x \n " , __location__ , \
2003-08-13 01:53:07 +00:00
call_name , # stype , # field , \
( uint_t ) value , ( uint_t ) finfo2 . stype . out . field ) ; \
2007-08-28 12:54:27 +00:00
dump_all_info ( torture , & finfo1 ) ; \
2007-10-06 22:28:14 +00:00
ret = false ; \
2003-08-13 01:53:07 +00:00
} } while ( 0 )
# define CHECK_TIME(call, stype, field, value) do { \
CHECK1 ( call ) ; \
2004-05-25 13:57:39 +00:00
if ( NT_STATUS_IS_OK ( status ) & & NT_STATUS_IS_OK ( status2 ) & & nt_time_to_unix ( finfo2 . stype . out . field ) ! = value ) { \
2004-11-07 10:03:56 +00:00
printf ( " (%s) %s - %s/%s should be 0x%x - 0x%x \n " , __location__ , \
2003-08-13 01:53:07 +00:00
call_name , # stype , # field , \
( uint_t ) value , \
2004-05-25 13:57:39 +00:00
( uint_t ) nt_time_to_unix ( finfo2 . stype . out . field ) ) ; \
2007-08-28 12:54:27 +00:00
printf ( " \t %s " , timestring ( torture , value ) ) ; \
printf ( " \t %s \n " , nt_time_string ( torture , finfo2 . stype . out . field ) ) ; \
dump_all_info ( torture , & finfo1 ) ; \
2007-10-06 22:28:14 +00:00
ret = false ; \
2003-08-13 01:53:07 +00:00
} } while ( 0 )
# define CHECK_STR(call, stype, field, value) do { \
CHECK1 ( call ) ; \
2003-10-10 05:40:32 +00:00
if ( NT_STATUS_IS_OK ( status ) & & NT_STATUS_IS_OK ( status2 ) & & strcmp ( finfo2 . stype . out . field , value ) ! = 0 ) { \
2004-11-07 10:03:56 +00:00
printf ( " (%s) %s - %s/%s should be '%s' - '%s' \n " , __location__ , \
2003-08-13 01:53:07 +00:00
call_name , # stype , # field , \
value , \
finfo2 . stype . out . field ) ; \
2007-08-28 12:54:27 +00:00
dump_all_info ( torture , & finfo1 ) ; \
2007-10-06 22:28:14 +00:00
ret = false ; \
2003-08-13 01:53:07 +00:00
} } while ( 0 )
2005-08-04 04:20:26 +00:00
# define CHECK_STATUS(status, correct) do { \
if ( ! NT_STATUS_EQUAL ( status , correct ) ) { \
printf ( " (%s) Incorrect status %s - should be %s \n " , \
__location__ , nt_errstr ( status ) , nt_errstr ( correct ) ) ; \
2007-10-06 22:28:14 +00:00
ret = false ; \
2005-08-04 04:20:26 +00:00
goto done ; \
} } while ( 0 )
2003-08-13 01:53:07 +00:00
printf ( " test setattr \n " ) ;
sfinfo . setattr . in . attrib = FILE_ATTRIBUTE_READONLY ;
sfinfo . setattr . in . write_time = basetime ;
CHECK_CALL_PATH ( SETATTR , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , attrib , FILE_ATTRIBUTE_READONLY ) ;
CHECK_TIME ( ALL_INFO , all_info , write_time , basetime ) ;
printf ( " setting to NORMAL doesn't do anything \n " ) ;
sfinfo . setattr . in . attrib = FILE_ATTRIBUTE_NORMAL ;
sfinfo . setattr . in . write_time = 0 ;
CHECK_CALL_PATH ( SETATTR , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , attrib , FILE_ATTRIBUTE_READONLY ) ;
CHECK_TIME ( ALL_INFO , all_info , write_time , basetime ) ;
printf ( " a zero write_time means don't change \n " ) ;
sfinfo . setattr . in . attrib = 0 ;
sfinfo . setattr . in . write_time = 0 ;
CHECK_CALL_PATH ( SETATTR , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , attrib , FILE_ATTRIBUTE_NORMAL ) ;
CHECK_TIME ( ALL_INFO , all_info , write_time , basetime ) ;
printf ( " test setattre \n " ) ;
sfinfo . setattre . in . create_time = basetime + 20 ;
sfinfo . setattre . in . access_time = basetime + 30 ;
sfinfo . setattre . in . write_time = basetime + 40 ;
CHECK_CALL_FNUM ( SETATTRE , NT_STATUS_OK ) ;
CHECK_TIME ( ALL_INFO , all_info , create_time , basetime + 20 ) ;
CHECK_TIME ( ALL_INFO , all_info , access_time , basetime + 30 ) ;
CHECK_TIME ( ALL_INFO , all_info , write_time , basetime + 40 ) ;
sfinfo . setattre . in . create_time = 0 ;
sfinfo . setattre . in . access_time = 0 ;
sfinfo . setattre . in . write_time = 0 ;
CHECK_CALL_FNUM ( SETATTRE , NT_STATUS_OK ) ;
CHECK_TIME ( ALL_INFO , all_info , create_time , basetime + 20 ) ;
CHECK_TIME ( ALL_INFO , all_info , access_time , basetime + 30 ) ;
CHECK_TIME ( ALL_INFO , all_info , write_time , basetime + 40 ) ;
printf ( " test standard level \n " ) ;
sfinfo . standard . in . create_time = basetime + 100 ;
sfinfo . standard . in . access_time = basetime + 200 ;
sfinfo . standard . in . write_time = basetime + 300 ;
CHECK_CALL_FNUM ( STANDARD , NT_STATUS_OK ) ;
CHECK_TIME ( ALL_INFO , all_info , create_time , basetime + 100 ) ;
CHECK_TIME ( ALL_INFO , all_info , access_time , basetime + 200 ) ;
CHECK_TIME ( ALL_INFO , all_info , write_time , basetime + 300 ) ;
printf ( " test basic_info level \n " ) ;
basetime + = 86400 ;
unix_to_nt_time ( & sfinfo . basic_info . in . create_time , basetime + 100 ) ;
unix_to_nt_time ( & sfinfo . basic_info . in . access_time , basetime + 200 ) ;
unix_to_nt_time ( & sfinfo . basic_info . in . write_time , basetime + 300 ) ;
unix_to_nt_time ( & sfinfo . basic_info . in . change_time , basetime + 400 ) ;
sfinfo . basic_info . in . attrib = FILE_ATTRIBUTE_READONLY ;
CHECK_CALL_FNUM ( BASIC_INFO , NT_STATUS_OK ) ;
CHECK_TIME ( ALL_INFO , all_info , create_time , basetime + 100 ) ;
CHECK_TIME ( ALL_INFO , all_info , access_time , basetime + 200 ) ;
CHECK_TIME ( ALL_INFO , all_info , write_time , basetime + 300 ) ;
CHECK_TIME ( ALL_INFO , all_info , change_time , basetime + 400 ) ;
CHECK_VALUE ( ALL_INFO , all_info , attrib , FILE_ATTRIBUTE_READONLY ) ;
printf ( " a zero time means don't change \n " ) ;
unix_to_nt_time ( & sfinfo . basic_info . in . create_time , 0 ) ;
unix_to_nt_time ( & sfinfo . basic_info . in . access_time , 0 ) ;
unix_to_nt_time ( & sfinfo . basic_info . in . write_time , 0 ) ;
unix_to_nt_time ( & sfinfo . basic_info . in . change_time , 0 ) ;
2006-06-30 08:19:44 +00:00
sfinfo . basic_info . in . attrib = 0 ;
2003-08-13 01:53:07 +00:00
CHECK_CALL_FNUM ( BASIC_INFO , NT_STATUS_OK ) ;
CHECK_TIME ( ALL_INFO , all_info , create_time , basetime + 100 ) ;
CHECK_TIME ( ALL_INFO , all_info , access_time , basetime + 200 ) ;
CHECK_TIME ( ALL_INFO , all_info , write_time , basetime + 300 ) ;
CHECK_TIME ( ALL_INFO , all_info , change_time , basetime + 400 ) ;
2006-06-30 08:19:44 +00:00
CHECK_VALUE ( ALL_INFO , all_info , attrib , FILE_ATTRIBUTE_READONLY ) ;
2003-08-13 01:53:07 +00:00
printf ( " test basic_information level \n " ) ;
basetime + = 86400 ;
unix_to_nt_time ( & sfinfo . basic_info . in . create_time , basetime + 100 ) ;
unix_to_nt_time ( & sfinfo . basic_info . in . access_time , basetime + 200 ) ;
unix_to_nt_time ( & sfinfo . basic_info . in . write_time , basetime + 300 ) ;
unix_to_nt_time ( & sfinfo . basic_info . in . change_time , basetime + 400 ) ;
2006-06-30 08:19:44 +00:00
sfinfo . basic_info . in . attrib = FILE_ATTRIBUTE_NORMAL ;
2003-08-13 01:53:07 +00:00
CHECK_CALL_FNUM ( BASIC_INFORMATION , NT_STATUS_OK ) ;
CHECK_TIME ( ALL_INFO , all_info , create_time , basetime + 100 ) ;
CHECK_TIME ( ALL_INFO , all_info , access_time , basetime + 200 ) ;
CHECK_TIME ( ALL_INFO , all_info , write_time , basetime + 300 ) ;
CHECK_TIME ( ALL_INFO , all_info , change_time , basetime + 400 ) ;
2006-06-30 08:19:44 +00:00
CHECK_VALUE ( ALL_INFO , all_info , attrib , FILE_ATTRIBUTE_NORMAL ) ;
2003-08-13 01:53:07 +00:00
CHECK_CALL_PATH ( BASIC_INFORMATION , NT_STATUS_OK ) ;
CHECK_TIME ( ALL_INFO , all_info , create_time , basetime + 100 ) ;
CHECK_TIME ( ALL_INFO , all_info , access_time , basetime + 200 ) ;
CHECK_TIME ( ALL_INFO , all_info , write_time , basetime + 300 ) ;
CHECK_TIME ( ALL_INFO , all_info , change_time , basetime + 400 ) ;
2006-06-30 08:19:44 +00:00
CHECK_VALUE ( ALL_INFO , all_info , attrib , FILE_ATTRIBUTE_NORMAL ) ;
2003-08-13 01:53:07 +00:00
printf ( " a zero time means don't change \n " ) ;
unix_to_nt_time ( & sfinfo . basic_info . in . create_time , 0 ) ;
unix_to_nt_time ( & sfinfo . basic_info . in . access_time , 0 ) ;
unix_to_nt_time ( & sfinfo . basic_info . in . write_time , 0 ) ;
unix_to_nt_time ( & sfinfo . basic_info . in . change_time , 0 ) ;
sfinfo . basic_info . in . attrib = FILE_ATTRIBUTE_NORMAL ;
CHECK_CALL_FNUM ( BASIC_INFORMATION , NT_STATUS_OK ) ;
CHECK_TIME ( ALL_INFO , all_info , create_time , basetime + 100 ) ;
CHECK_TIME ( ALL_INFO , all_info , access_time , basetime + 200 ) ;
CHECK_TIME ( ALL_INFO , all_info , write_time , basetime + 300 ) ;
CHECK_TIME ( ALL_INFO , all_info , change_time , basetime + 400 ) ;
CHECK_VALUE ( ALL_INFO , all_info , attrib , FILE_ATTRIBUTE_NORMAL ) ;
CHECK_CALL_PATH ( BASIC_INFORMATION , NT_STATUS_OK ) ;
CHECK_TIME ( ALL_INFO , all_info , create_time , basetime + 100 ) ;
CHECK_TIME ( ALL_INFO , all_info , access_time , basetime + 200 ) ;
CHECK_TIME ( ALL_INFO , all_info , write_time , basetime + 300 ) ;
/* interesting - w2k3 leaves change_time as current time for 0 change time
in setpathinfo
CHECK_TIME ( ALL_INFO , all_info , change_time , basetime + 400 ) ;
*/
CHECK_VALUE ( ALL_INFO , all_info , attrib , FILE_ATTRIBUTE_NORMAL ) ;
printf ( " test disposition_info level \n " ) ;
sfinfo . disposition_info . in . delete_on_close = 1 ;
CHECK_CALL_FNUM ( DISPOSITION_INFO , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , delete_pending , 1 ) ;
CHECK_VALUE ( ALL_INFO , all_info , nlink , 0 ) ;
sfinfo . disposition_info . in . delete_on_close = 0 ;
CHECK_CALL_FNUM ( DISPOSITION_INFO , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , delete_pending , 0 ) ;
CHECK_VALUE ( ALL_INFO , all_info , nlink , 1 ) ;
printf ( " test disposition_information level \n " ) ;
sfinfo . disposition_info . in . delete_on_close = 1 ;
CHECK_CALL_FNUM ( DISPOSITION_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , delete_pending , 1 ) ;
CHECK_VALUE ( ALL_INFO , all_info , nlink , 0 ) ;
/* this would delete the file! */
/*
CHECK_CALL_PATH ( DISPOSITION_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , delete_pending , 1 ) ;
CHECK_VALUE ( ALL_INFO , all_info , nlink , 0 ) ;
*/
sfinfo . disposition_info . in . delete_on_close = 0 ;
CHECK_CALL_FNUM ( DISPOSITION_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , delete_pending , 0 ) ;
CHECK_VALUE ( ALL_INFO , all_info , nlink , 1 ) ;
CHECK_CALL_PATH ( DISPOSITION_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , delete_pending , 0 ) ;
CHECK_VALUE ( ALL_INFO , all_info , nlink , 1 ) ;
printf ( " test allocation_info level \n " ) ;
sfinfo . allocation_info . in . alloc_size = 0 ;
CHECK_CALL_FNUM ( ALLOCATION_INFO , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , size , 0 ) ;
CHECK_VALUE ( ALL_INFO , all_info , alloc_size , 0 ) ;
sfinfo . allocation_info . in . alloc_size = 4096 ;
CHECK_CALL_FNUM ( ALLOCATION_INFO , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , alloc_size , 4096 ) ;
CHECK_VALUE ( ALL_INFO , all_info , size , 0 ) ;
RECREATE_BOTH ;
sfinfo . allocation_info . in . alloc_size = 0 ;
CHECK_CALL_FNUM ( ALLOCATION_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , size , 0 ) ;
CHECK_VALUE ( ALL_INFO , all_info , alloc_size , 0 ) ;
CHECK_CALL_PATH ( ALLOCATION_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , size , 0 ) ;
CHECK_VALUE ( ALL_INFO , all_info , alloc_size , 0 ) ;
sfinfo . allocation_info . in . alloc_size = 4096 ;
CHECK_CALL_FNUM ( ALLOCATION_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , alloc_size , 4096 ) ;
CHECK_VALUE ( ALL_INFO , all_info , size , 0 ) ;
/* setting the allocation size up via setpathinfo seems
to be broken in w2k3 */
CHECK_CALL_PATH ( ALLOCATION_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , alloc_size , 0 ) ;
CHECK_VALUE ( ALL_INFO , all_info , size , 0 ) ;
printf ( " test end_of_file_info level \n " ) ;
sfinfo . end_of_file_info . in . size = 37 ;
CHECK_CALL_FNUM ( END_OF_FILE_INFO , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , size , 37 ) ;
sfinfo . end_of_file_info . in . size = 7 ;
CHECK_CALL_FNUM ( END_OF_FILE_INFO , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , size , 7 ) ;
sfinfo . end_of_file_info . in . size = 37 ;
CHECK_CALL_FNUM ( END_OF_FILE_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , size , 37 ) ;
CHECK_CALL_PATH ( END_OF_FILE_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , size , 37 ) ;
sfinfo . end_of_file_info . in . size = 7 ;
CHECK_CALL_FNUM ( END_OF_FILE_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , size , 7 ) ;
CHECK_CALL_PATH ( END_OF_FILE_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( ALL_INFO , all_info , size , 7 ) ;
printf ( " test position_information level \n " ) ;
sfinfo . position_information . in . position = 123456 ;
CHECK_CALL_FNUM ( POSITION_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( POSITION_INFORMATION , position_information , position , 123456 ) ;
CHECK_CALL_PATH ( POSITION_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( POSITION_INFORMATION , position_information , position , 0 ) ;
printf ( " test mode_information level \n " ) ;
sfinfo . mode_information . in . mode = 2 ;
CHECK_CALL_FNUM ( MODE_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( MODE_INFORMATION , mode_information , mode , 2 ) ;
CHECK_CALL_PATH ( MODE_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( MODE_INFORMATION , mode_information , mode , 0 ) ;
sfinfo . mode_information . in . mode = 1 ;
CHECK_CALL_FNUM ( MODE_INFORMATION , NT_STATUS_INVALID_PARAMETER ) ;
CHECK_CALL_PATH ( MODE_INFORMATION , NT_STATUS_INVALID_PARAMETER ) ;
sfinfo . mode_information . in . mode = 0 ;
CHECK_CALL_FNUM ( MODE_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( MODE_INFORMATION , mode_information , mode , 0 ) ;
CHECK_CALL_PATH ( MODE_INFORMATION , NT_STATUS_OK ) ;
CHECK_VALUE ( MODE_INFORMATION , mode_information , mode , 0 ) ;
2007-06-14 13:01:58 +00:00
#if 0
printf ( " test unix_basic level \n " ) ;
CHECK_CALL_FNUM ( UNIX_BASIC , NT_STATUS_OK ) ;
CHECK_CALL_PATH ( UNIX_BASIC , NT_STATUS_OK ) ;
printf ( " test unix_link level \n " ) ;
CHECK_CALL_FNUM ( UNIX_LINK , NT_STATUS_OK ) ;
CHECK_CALL_PATH ( UNIX_LINK , NT_STATUS_OK ) ;
# endif
done :
smb_raw_exit ( cli - > session ) ;
smbcli_close ( cli - > tree , fnum ) ;
if ( NT_STATUS_IS_ERR ( smbcli_unlink ( cli - > tree , fnum_fname ) ) ) {
printf ( " Failed to delete %s - %s \n " , fnum_fname , smbcli_errstr ( cli - > tree ) ) ;
}
if ( NT_STATUS_IS_ERR ( smbcli_unlink ( cli - > tree , path_fname ) ) ) {
printf ( " Failed to delete %s - %s \n " , path_fname , smbcli_errstr ( cli - > tree ) ) ;
}
return ret ;
}
/*
* basic testing of all RAW_SFILEINFO_RENAME call
*/
2009-11-24 16:25:02 -08:00
static bool
torture_raw_sfileinfo_rename ( struct torture_context * torture ,
struct smbcli_state * cli )
2007-06-14 13:01:58 +00:00
{
2007-10-06 22:28:14 +00:00
bool ret = true ;
2007-06-14 13:01:58 +00:00
int fnum_saved , d_fnum , fnum2 , fnum = - 1 ;
char * fnum_fname ;
char * fnum_fname_new ;
char * path_fname ;
char * path_fname_new ;
2008-02-29 09:03:47 +01:00
char * path_dname ;
char * path_dname_new ;
char * saved_name ;
char * saved_name_new ;
2007-06-14 13:01:58 +00:00
union smb_fileinfo finfo1 , finfo2 ;
union smb_setfileinfo sfinfo ;
NTSTATUS status , status2 ;
const char * call_name ;
2007-10-06 22:28:14 +00:00
bool check_fnum ;
2007-06-14 13:01:58 +00:00
int n = time ( NULL ) % 100 ;
asprintf ( & path_fname , BASEDIR " \\ fname_test_%d.txt " , n ) ;
asprintf ( & path_fname_new , BASEDIR " \\ fname_test_new_%d.txt " , n ) ;
asprintf ( & fnum_fname , BASEDIR " \\ fnum_test_%d.txt " , n ) ;
asprintf ( & fnum_fname_new , BASEDIR " \\ fnum_test_new_%d.txt " , n ) ;
2008-02-29 09:03:47 +01:00
asprintf ( & path_dname , BASEDIR " \\ dname_test_%d " , n ) ;
asprintf ( & path_dname_new , BASEDIR " \\ dname_test_new_%d " , n ) ;
2007-06-14 13:01:58 +00:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2007-10-06 22:28:14 +00:00
return false ;
2007-06-14 13:01:58 +00:00
}
RECREATE_BOTH ;
ZERO_STRUCT ( sfinfo ) ;
2007-08-28 12:54:27 +00:00
smbcli_close ( cli - > tree , create_complex_file ( cli , torture , fnum_fname_new ) ) ;
smbcli_close ( cli - > tree , create_complex_file ( cli , torture , path_fname_new ) ) ;
2003-08-13 01:53:07 +00:00
sfinfo . rename_information . in . overwrite = 0 ;
sfinfo . rename_information . in . root_fid = 0 ;
sfinfo . rename_information . in . new_name = fnum_fname_new + strlen ( BASEDIR ) + 1 ;
CHECK_CALL_FNUM ( RENAME_INFORMATION , NT_STATUS_OBJECT_NAME_COLLISION ) ;
sfinfo . rename_information . in . new_name = path_fname_new + strlen ( BASEDIR ) + 1 ;
CHECK_CALL_PATH ( RENAME_INFORMATION , NT_STATUS_OBJECT_NAME_COLLISION ) ;
2003-08-15 03:54:45 +00:00
sfinfo . rename_information . in . new_name = fnum_fname_new ;
sfinfo . rename_information . in . overwrite = 1 ;
CHECK_CALL_FNUM ( RENAME_INFORMATION , NT_STATUS_NOT_SUPPORTED ) ;
2003-08-13 01:53:07 +00:00
sfinfo . rename_information . in . new_name = fnum_fname_new + strlen ( BASEDIR ) + 1 ;
sfinfo . rename_information . in . overwrite = 1 ;
CHECK_CALL_FNUM ( RENAME_INFORMATION , NT_STATUS_OK ) ;
CHECK_STR ( NAME_INFO , name_info , fname . s , fnum_fname_new ) ;
2003-08-13 02:04:44 +00:00
printf ( " Trying rename with dest file open \n " ) ;
2007-08-28 12:54:27 +00:00
fnum2 = create_complex_file ( cli , torture , fnum_fname ) ;
2003-08-13 02:04:44 +00:00
sfinfo . rename_information . in . new_name = fnum_fname + strlen ( BASEDIR ) + 1 ;
sfinfo . rename_information . in . overwrite = 1 ;
CHECK_CALL_FNUM ( RENAME_INFORMATION , NT_STATUS_ACCESS_DENIED ) ;
CHECK_STR ( NAME_INFO , name_info , fname . s , fnum_fname_new ) ;
fnum_saved = fnum ;
fnum = fnum2 ;
sfinfo . disposition_info . in . delete_on_close = 1 ;
CHECK_CALL_FNUM ( DISPOSITION_INFO , NT_STATUS_OK ) ;
fnum = fnum_saved ;
printf ( " Trying rename with dest file open and delete_on_close \n " ) ;
2005-07-15 12:16:39 +00:00
sfinfo . rename_information . in . new_name = fnum_fname + strlen ( BASEDIR ) + 1 ;
sfinfo . rename_information . in . overwrite = 1 ;
2003-08-13 02:04:44 +00:00
CHECK_CALL_FNUM ( RENAME_INFORMATION , NT_STATUS_ACCESS_DENIED ) ;
2004-08-04 13:23:35 +00:00
smbcli_close ( cli - > tree , fnum2 ) ;
2003-08-13 02:04:44 +00:00
CHECK_CALL_FNUM ( RENAME_INFORMATION , NT_STATUS_OK ) ;
CHECK_STR ( NAME_INFO , name_info , fname . s , fnum_fname ) ;
printf ( " Trying rename with source file open twice \n " ) ;
sfinfo . rename_information . in . new_name = fnum_fname + strlen ( BASEDIR ) + 1 ;
sfinfo . rename_information . in . overwrite = 1 ;
CHECK_CALL_FNUM ( RENAME_INFORMATION , NT_STATUS_OK ) ;
CHECK_STR ( NAME_INFO , name_info , fname . s , fnum_fname ) ;
2007-08-28 12:54:27 +00:00
fnum2 = create_complex_file ( cli , torture , fnum_fname ) ;
2003-08-13 02:04:44 +00:00
sfinfo . rename_information . in . new_name = fnum_fname_new + strlen ( BASEDIR ) + 1 ;
sfinfo . rename_information . in . overwrite = 0 ;
CHECK_CALL_FNUM ( RENAME_INFORMATION , NT_STATUS_OK ) ;
CHECK_STR ( NAME_INFO , name_info , fname . s , fnum_fname_new ) ;
2004-08-04 13:23:35 +00:00
smbcli_close ( cli - > tree , fnum2 ) ;
2003-08-13 02:04:44 +00:00
sfinfo . rename_information . in . new_name = fnum_fname + strlen ( BASEDIR ) + 1 ;
sfinfo . rename_information . in . overwrite = 0 ;
CHECK_CALL_FNUM ( RENAME_INFORMATION , NT_STATUS_OK ) ;
CHECK_STR ( NAME_INFO , name_info , fname . s , fnum_fname ) ;
2003-08-13 01:53:07 +00:00
sfinfo . rename_information . in . new_name = path_fname_new + strlen ( BASEDIR ) + 1 ;
2003-08-13 02:04:44 +00:00
sfinfo . rename_information . in . overwrite = 1 ;
2003-08-13 01:53:07 +00:00
CHECK_CALL_PATH ( RENAME_INFORMATION , NT_STATUS_OK ) ;
CHECK_STR ( NAME_INFO , name_info , fname . s , path_fname_new ) ;
sfinfo . rename_information . in . new_name = fnum_fname + strlen ( BASEDIR ) + 1 ;
CHECK_CALL_FNUM ( RENAME_INFORMATION , NT_STATUS_OK ) ;
CHECK_STR ( NAME_INFO , name_info , fname . s , fnum_fname ) ;
sfinfo . rename_information . in . new_name = path_fname + strlen ( BASEDIR ) + 1 ;
CHECK_CALL_PATH ( RENAME_INFORMATION , NT_STATUS_OK ) ;
CHECK_STR ( NAME_INFO , name_info , fname . s , path_fname ) ;
2003-09-02 04:37:33 +00:00
printf ( " Trying rename with a root fid \n " ) ;
2005-08-03 17:50:00 +00:00
status = create_directory_handle ( cli - > tree , BASEDIR , & d_fnum ) ;
2005-08-04 04:20:26 +00:00
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2003-09-02 04:37:33 +00:00
sfinfo . rename_information . in . new_name = fnum_fname_new + strlen ( BASEDIR ) + 1 ;
sfinfo . rename_information . in . root_fid = d_fnum ;
CHECK_CALL_FNUM ( RENAME_INFORMATION , NT_STATUS_INVALID_PARAMETER ) ;
CHECK_STR ( NAME_INFO , name_info , fname . s , fnum_fname ) ;
2008-02-29 09:03:47 +01:00
smbcli_close ( cli - > tree , d_fnum ) ;
printf ( " Trying rename directory \n " ) ;
if ( ! torture_setup_dir ( cli , path_dname ) ) {
ret = false ;
goto done ;
}
saved_name = path_fname ;
saved_name_new = path_fname_new ;
path_fname = path_dname ;
path_fname_new = path_dname_new ;
sfinfo . rename_information . in . new_name = path_dname_new + strlen ( BASEDIR ) + 1 ;
sfinfo . rename_information . in . overwrite = 0 ;
sfinfo . rename_information . in . root_fid = 0 ;
CHECK_CALL_PATH ( RENAME_INFORMATION , NT_STATUS_OK ) ;
CHECK_STR ( NAME_INFO , name_info , fname . s , path_dname_new ) ;
path_fname = saved_name ;
path_fname_new = saved_name_new ;
2003-08-13 01:53:07 +00:00
2008-02-28 12:10:27 +01:00
if ( torture_setting_bool ( torture , " samba3 " , false ) ) {
2008-02-29 09:03:47 +01:00
printf ( " SKIP: Trying rename directory with a handle \n " ) ;
2008-02-28 12:10:27 +01:00
printf ( " SKIP: Trying rename by path while a handle is open \n " ) ;
2008-02-29 09:03:47 +01:00
printf ( " SKIP: Trying rename directory by path while a handle is open \n " ) ;
2008-02-28 12:10:27 +01:00
goto done ;
}
2008-02-29 09:03:47 +01:00
printf ( " Trying rename directory with a handle \n " ) ;
status = create_directory_handle ( cli - > tree , path_dname_new , & d_fnum ) ;
fnum_saved = fnum ;
fnum = d_fnum ;
saved_name = fnum_fname ;
saved_name_new = fnum_fname_new ;
fnum_fname = path_dname ;
fnum_fname_new = path_dname_new ;
sfinfo . rename_information . in . new_name = path_dname + strlen ( BASEDIR ) + 1 ;
sfinfo . rename_information . in . overwrite = 0 ;
sfinfo . rename_information . in . root_fid = 0 ;
CHECK_CALL_FNUM ( RENAME_INFORMATION , NT_STATUS_OK ) ;
CHECK_STR ( NAME_INFO , name_info , fname . s , path_dname ) ;
smbcli_close ( cli - > tree , d_fnum ) ;
fnum = fnum_saved ;
fnum_fname = saved_name ;
fnum_fname_new = saved_name_new ;
2008-02-28 12:10:27 +01:00
printf ( " Trying rename by path while a handle is open \n " ) ;
fnum_saved = fnum ;
fnum = create_complex_file ( cli , torture , path_fname ) ;
sfinfo . rename_information . in . new_name = path_fname_new + strlen ( BASEDIR ) + 1 ;
sfinfo . rename_information . in . overwrite = 0 ;
sfinfo . rename_information . in . root_fid = 0 ;
CHECK_CALL_PATH ( RENAME_INFORMATION , NT_STATUS_OK ) ;
CHECK_STR ( NAME_INFO , name_info , fname . s , path_fname_new ) ;
/* check that the handle returns the same name */
check_fnum = true ;
CHECK_STR ( NAME_INFO , name_info , fname . s , path_fname_new ) ;
/* rename it back on the handle */
sfinfo . rename_information . in . new_name = path_fname + strlen ( BASEDIR ) + 1 ;
CHECK_CALL_FNUM ( RENAME_INFORMATION , NT_STATUS_OK ) ;
CHECK_STR ( NAME_INFO , name_info , fname . s , path_fname ) ;
check_fnum = false ;
CHECK_STR ( NAME_INFO , name_info , fname . s , path_fname ) ;
smbcli_close ( cli - > tree , fnum ) ;
fnum = fnum_saved ;
2008-02-29 09:03:47 +01:00
printf ( " Trying rename directory by path while a handle is open \n " ) ;
status = create_directory_handle ( cli - > tree , path_dname , & d_fnum ) ;
fnum_saved = fnum ;
fnum = d_fnum ;
saved_name = path_fname ;
saved_name_new = path_fname_new ;
path_fname = path_dname ;
path_fname_new = path_dname_new ;
sfinfo . rename_information . in . new_name = path_dname_new + strlen ( BASEDIR ) + 1 ;
sfinfo . rename_information . in . overwrite = 0 ;
sfinfo . rename_information . in . root_fid = 0 ;
CHECK_CALL_PATH ( RENAME_INFORMATION , NT_STATUS_OK ) ;
CHECK_STR ( NAME_INFO , name_info , fname . s , path_dname_new ) ;
path_fname = saved_name ;
path_fname_new = saved_name_new ;
saved_name = fnum_fname ;
saved_name_new = fnum_fname_new ;
fnum_fname = path_dname ;
fnum_fname_new = path_dname_new ;
/* check that the handle returns the same name */
check_fnum = true ;
CHECK_STR ( NAME_INFO , name_info , fname . s , path_dname_new ) ;
/* rename it back on the handle */
sfinfo . rename_information . in . new_name = path_dname + strlen ( BASEDIR ) + 1 ;
CHECK_CALL_FNUM ( RENAME_INFORMATION , NT_STATUS_OK ) ;
CHECK_STR ( NAME_INFO , name_info , fname . s , path_dname ) ;
fnum_fname = saved_name ;
fnum_fname_new = saved_name_new ;
saved_name = path_fname ;
saved_name_new = path_fname_new ;
path_fname = path_dname ;
path_fname_new = path_dname_new ;
check_fnum = false ;
CHECK_STR ( NAME_INFO , name_info , fname . s , path_dname ) ;
smbcli_close ( cli - > tree , d_fnum ) ;
fnum = fnum_saved ;
path_fname = saved_name ;
path_fname_new = saved_name_new ;
2003-08-13 01:53:07 +00:00
done :
2003-09-02 04:37:33 +00:00
smb_raw_exit ( cli - > session ) ;
2008-02-29 09:03:47 +01:00
smbcli_deltree ( cli - > tree , BASEDIR ) ;
2003-08-13 01:53:07 +00:00
return ret ;
}
/*
look for the w2k3 setpathinfo STANDARD bug
*/
2009-11-24 16:25:02 -08:00
static bool torture_raw_sfileinfo_bug ( struct torture_context * torture ,
struct smbcli_state * cli )
2003-08-13 01:53:07 +00:00
{
const char * fname = " \\ bug3.txt " ;
union smb_setfileinfo sfinfo ;
NTSTATUS status ;
int fnum ;
2007-08-28 12:54:27 +00:00
if ( ! torture_setting_bool ( torture , " dangerous " , false ) )
torture_skip ( torture ,
" torture_raw_sfileinfo_bug disabled - enable dangerous tests to use \n " ) ;
2003-08-13 01:53:07 +00:00
2007-08-28 12:54:27 +00:00
fnum = create_complex_file ( cli , torture , fname ) ;
2004-08-04 13:23:35 +00:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 01:53:07 +00:00
sfinfo . generic . level = RAW_SFILEINFO_STANDARD ;
2006-03-12 22:48:25 +00:00
sfinfo . generic . in . file . path = fname ;
2003-08-13 01:53:07 +00:00
sfinfo . standard . in . create_time = 0 ;
sfinfo . standard . in . access_time = 0 ;
sfinfo . standard . in . write_time = 0 ;
status = smb_raw_setpathinfo ( cli - > tree , & sfinfo ) ;
printf ( " %s - %s \n " , fname , nt_errstr ( status ) ) ;
printf ( " now try and delete %s \n " , fname ) ;
2007-10-06 22:28:14 +00:00
return true ;
2003-08-13 01:53:07 +00:00
}
2009-11-24 16:25:02 -08:00
2009-11-30 11:59:19 -08:00
/**
* Test both the snia cifs RAW_SFILEINFO_END_OF_FILE_INFO and the undocumented
* pass - through RAW_SFILEINFO_END_OF_FILE_INFORMATION in the context of
* trans2setpathinfo .
*/
2009-11-24 16:29:19 -08:00
static bool
2009-11-30 11:59:19 -08:00
torture_raw_sfileinfo_eof ( struct torture_context * tctx ,
struct smbcli_state * cli1 , struct smbcli_state * cli2 )
2009-11-24 16:29:19 -08:00
{
const char * fname = BASEDIR " \\ test_sfileinfo_end_of_file.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_setfileinfo sfi ;
union smb_fileinfo qfi ;
uint16_t fnum = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname ) ;
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid . fnum = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
io . ntcreatex . in . flags = 0 ;
/* Open the file sharing none. */
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK , ret ,
done , " Status should be OK " ) ;
fnum = io . ntcreatex . out . file . fnum ;
/* Try to sfileinfo to extend the file. */
ZERO_STRUCT ( sfi ) ;
sfi . generic . level = RAW_SFILEINFO_END_OF_FILE_INFO ;
sfi . generic . in . file . path = fname ;
sfi . end_of_file_info . in . size = 100 ;
status = smb_raw_setpathinfo ( cli2 - > tree , & sfi ) ;
/* There should be share mode contention in this case. */
torture_assert_ntstatus_equal_goto ( tctx , status ,
NT_STATUS_SHARING_VIOLATION , ret , done , " Status should be "
" SHARING_VIOLATION " ) ;
/* Make sure the size is still 0. */
ZERO_STRUCT ( qfi ) ;
qfi . generic . level = RAW_FILEINFO_STANDARD_INFO ;
qfi . generic . in . file . path = fname ;
status = smb_raw_pathinfo ( cli2 - > tree , tctx , & qfi ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK , ret ,
done , " Status should be OK " ) ;
torture_assert_u64_equal ( tctx , qfi . standard_info . out . size , 0 ,
" alloc_size should be 0 since the setpathinfo failed. " ) ;
/* Try again with the pass through instead of documented version. */
ZERO_STRUCT ( sfi ) ;
sfi . generic . level = RAW_SFILEINFO_END_OF_FILE_INFORMATION ;
sfi . generic . in . file . path = fname ;
sfi . end_of_file_info . in . size = 100 ;
status = smb_raw_setpathinfo ( cli2 - > tree , & sfi ) ;
/*
* Looks like a windows bug :
* http : //lists.samba.org/archive/cifs-protocol/2009-November/001130.html
*/
2009-11-25 14:40:54 -08:00
if ( TARGET_IS_W2K8 ( tctx ) | | TARGET_IS_WIN7 ( tctx ) ) {
/* It succeeds! This is just weird! */
2009-11-30 11:59:19 -08:00
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK ,
ret , done , " Status should be OK " ) ;
/* Verify that the file was actually extended to 100. */
ZERO_STRUCT ( qfi ) ;
qfi . generic . level = RAW_FILEINFO_STANDARD_INFO ;
qfi . generic . in . file . path = fname ;
status = smb_raw_pathinfo ( cli2 - > tree , tctx , & qfi ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK ,
ret , done , " Status should be OK " ) ;
torture_assert_u64_equal ( tctx , qfi . standard_info . out . size , 100 ,
" alloc_size should be 100 since the setpathinfo "
" succeeded. " ) ;
2009-11-25 14:40:54 -08:00
} else {
2009-11-24 16:29:19 -08:00
torture_assert_ntstatus_equal_goto ( tctx , status ,
NT_STATUS_SHARING_VIOLATION , ret , done , " Status should be "
" SHARING_VIOLATION " ) ;
}
2009-11-30 11:59:19 -08:00
/* close the first file. */
smbcli_close ( cli1 - > tree , fnum ) ;
fnum = 0 ;
/* Try to sfileinfo to extend the file again (non-pass-through). */
ZERO_STRUCT ( sfi ) ;
sfi . generic . level = RAW_SFILEINFO_END_OF_FILE_INFO ;
sfi . generic . in . file . path = fname ;
sfi . end_of_file_info . in . size = 200 ;
status = smb_raw_setpathinfo ( cli2 - > tree , & sfi ) ;
/* This should cause the client to retun invalid level. */
if ( TARGET_IS_W2K8 ( tctx ) | | TARGET_IS_WIN7 ( tctx ) ) {
/*
* Windows sends back an invalid packet that smbclient sees
* and returns INTERNAL_ERROR .
*/
torture_assert_ntstatus_equal_goto ( tctx , status ,
NT_STATUS_INTERNAL_ERROR , ret , done , " Status should be "
" INTERNAL_ERROR " ) ;
} else {
torture_assert_ntstatus_equal_goto ( tctx , status ,
NT_STATUS_INVALID_LEVEL , ret , done , " Status should be "
" INVALID_LEVEL " ) ;
}
/* Try to extend the file now with the passthrough level. */
sfi . generic . level = RAW_SFILEINFO_END_OF_FILE_INFORMATION ;
status = smb_raw_setpathinfo ( cli2 - > tree , & sfi ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK , ret ,
done , " Status should be OK " ) ;
/* Verify that the file was actually extended to 200. */
2009-11-24 16:29:19 -08:00
ZERO_STRUCT ( qfi ) ;
qfi . generic . level = RAW_FILEINFO_STANDARD_INFO ;
qfi . generic . in . file . path = fname ;
status = smb_raw_pathinfo ( cli2 - > tree , tctx , & qfi ) ;
2009-11-30 11:59:19 -08:00
2009-11-24 16:29:19 -08:00
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK , ret ,
done , " Status should be OK " ) ;
2009-11-30 11:59:19 -08:00
torture_assert_u64_equal ( tctx , qfi . standard_info . out . size , 200 ,
" alloc_size should be 200 since the setpathinfo succeeded. " ) ;
2009-11-24 16:29:19 -08:00
2009-11-30 11:59:19 -08:00
/* Open the file so end of file can be set by handle. */
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_WRITE ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK , ret ,
done , " Status should be OK " ) ;
fnum = io . ntcreatex . out . file . fnum ;
2009-11-24 16:29:19 -08:00
2009-11-30 11:59:19 -08:00
/* Try sfileinfo to extend the file by handle (non-pass-through). */
ZERO_STRUCT ( sfi ) ;
sfi . generic . level = RAW_SFILEINFO_END_OF_FILE_INFO ;
sfi . generic . in . file . fnum = fnum ;
sfi . end_of_file_info . in . size = 300 ;
status = smb_raw_setfileinfo ( cli1 - > tree , & sfi ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK , ret ,
done , " Status should be OK " ) ;
2009-11-24 16:29:19 -08:00
2009-11-30 11:59:19 -08:00
/* Verify that the file was actually extended to 300. */
ZERO_STRUCT ( qfi ) ;
qfi . generic . level = RAW_FILEINFO_STANDARD_INFO ;
qfi . generic . in . file . path = fname ;
status = smb_raw_pathinfo ( cli1 - > tree , tctx , & qfi ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK , ret ,
done , " Status should be OK " ) ;
torture_assert_u64_equal ( tctx , qfi . standard_info . out . size , 300 ,
" alloc_size should be 300 since the setpathinfo succeeded. " ) ;
/* Try sfileinfo to extend the file by handle (pass-through). */
ZERO_STRUCT ( sfi ) ;
sfi . generic . level = RAW_SFILEINFO_END_OF_FILE_INFORMATION ;
sfi . generic . in . file . fnum = fnum ;
sfi . end_of_file_info . in . size = 400 ;
status = smb_raw_setfileinfo ( cli1 - > tree , & sfi ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK , ret ,
done , " Status should be OK " ) ;
/* Verify that the file was actually extended to 300. */
ZERO_STRUCT ( qfi ) ;
qfi . generic . level = RAW_FILEINFO_STANDARD_INFO ;
qfi . generic . in . file . path = fname ;
status = smb_raw_pathinfo ( cli1 - > tree , tctx , & qfi ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK , ret ,
done , " Status should be OK " ) ;
torture_assert_u64_equal ( tctx , qfi . standard_info . out . size , 400 ,
" alloc_size should be 400 since the setpathinfo succeeded. " ) ;
done :
if ( fnum > 0 ) {
smbcli_close ( cli1 - > tree , fnum ) ;
fnum = 0 ;
}
2009-11-24 16:29:19 -08:00
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
static bool
torture_raw_sfileinfo_eof_access ( struct torture_context * tctx ,
struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_exclusive3.dat " ;
NTSTATUS status , expected_status ;
bool ret = true ;
union smb_open io ;
union smb_setfileinfo sfi ;
uint16_t fnum = 0 ;
uint32_t access_mask = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname ) ;
/*
* base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid . fnum = 0 ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OVERWRITE_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
io . ntcreatex . in . flags = 0 ;
for ( access_mask = 1 ; access_mask < = 0x00001FF ; access_mask + + ) {
io . ntcreatex . in . access_mask = access_mask ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
continue ;
}
fnum = io . ntcreatex . out . file . fnum ;
ZERO_STRUCT ( sfi ) ;
sfi . generic . level = RAW_SFILEINFO_END_OF_FILE_INFO ;
sfi . generic . in . file . fnum = fnum ;
sfi . end_of_file_info . in . size = 100 ;
status = smb_raw_setfileinfo ( cli1 - > tree , & sfi ) ;
expected_status = ( access_mask & SEC_FILE_WRITE_DATA ) ?
NT_STATUS_OK : NT_STATUS_ACCESS_DENIED ;
if ( ! NT_STATUS_EQUAL ( expected_status , status ) ) {
torture_comment ( tctx , " 0x%x wrong \n " , access_mask ) ;
}
torture_assert_ntstatus_equal_goto ( tctx , status ,
expected_status , ret , done , " Status Wrong " ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
}
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2009-12-17 22:32:58 +00:00
static bool
torture_raw_sfileinfo_archive ( struct torture_context * tctx ,
struct smbcli_state * cli )
{
const char * fname = BASEDIR " \\ test_archive.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_setfileinfo sfinfo ;
union smb_fileinfo finfo ;
uint16_t fnum = 0 ;
uint32_t access_mask = 0 ;
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli - > tree , fname ) ;
/*
* create a normal file , verify archive bit
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid . fnum = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_CREATE ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
io . ntcreatex . in . flags = 0 ;
status = smb_raw_open ( cli - > tree , tctx , & io ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK ,
ret , done , " open failed " ) ;
fnum = io . ntcreatex . out . file . fnum ;
torture_assert_int_equal ( tctx ,
io . ntcreatex . out . attrib & ~ FILE_ATTRIBUTE_NONINDEXED ,
FILE_ATTRIBUTE_ARCHIVE ,
" archive bit not set " ) ;
/*
* try to turn off archive bit
*/
ZERO_STRUCT ( sfinfo ) ;
sfinfo . generic . level = RAW_SFILEINFO_BASIC_INFO ;
sfinfo . generic . in . file . fnum = fnum ;
sfinfo . basic_info . in . attrib = FILE_ATTRIBUTE_NORMAL ;
status = smb_raw_setfileinfo ( cli - > tree , & sfinfo ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK ,
ret , done , " setfileinfo failed " ) ;
finfo . generic . level = RAW_FILEINFO_ALL_INFO ;
finfo . generic . in . file . fnum = fnum ;
status = smb_raw_fileinfo ( cli - > tree , tctx , & finfo ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK ,
ret , done , " fileinfo failed " ) ;
torture_assert_int_equal ( tctx ,
finfo . all_info . out . attrib & ~ FILE_ATTRIBUTE_NONINDEXED ,
FILE_ATTRIBUTE_NORMAL ,
" archive bit set " ) ;
status = smbcli_close ( cli - > tree , fnum ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK ,
ret , done , " close failed " ) ;
status = smbcli_unlink ( cli - > tree , fname ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK ,
ret , done , " unlink failed " ) ;
/*
* create a directory , verify no archive bit
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid . fnum = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_DIR_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_DIRECTORY ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_CREATE ;
io . ntcreatex . in . create_options = NTCREATEX_OPTIONS_DIRECTORY ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
io . ntcreatex . in . flags = 0 ;
status = smb_raw_open ( cli - > tree , tctx , & io ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK ,
ret , done , " directory open failed " ) ;
fnum = io . ntcreatex . out . file . fnum ;
torture_assert_int_equal ( tctx ,
io . ntcreatex . out . attrib & ~ FILE_ATTRIBUTE_NONINDEXED ,
FILE_ATTRIBUTE_DIRECTORY ,
" archive bit set " ) ;
/*
* verify you can turn on archive bit
*/
sfinfo . generic . level = RAW_SFILEINFO_BASIC_INFO ;
sfinfo . generic . in . file . fnum = fnum ;
sfinfo . basic_info . in . attrib = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_ARCHIVE ;
status = smb_raw_setfileinfo ( cli - > tree , & sfinfo ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK ,
ret , done , " setfileinfo failed " ) ;
finfo . generic . level = RAW_FILEINFO_ALL_INFO ;
finfo . generic . in . file . fnum = fnum ;
status = smb_raw_fileinfo ( cli - > tree , tctx , & finfo ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK ,
ret , done , " fileinfo failed " ) ;
torture_assert_int_equal ( tctx ,
finfo . all_info . out . attrib & ~ FILE_ATTRIBUTE_NONINDEXED ,
FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_ARCHIVE ,
" archive bit not set " ) ;
/*
* and try to turn it back off
*/
sfinfo . generic . level = RAW_SFILEINFO_BASIC_INFO ;
sfinfo . generic . in . file . fnum = fnum ;
sfinfo . basic_info . in . attrib = FILE_ATTRIBUTE_DIRECTORY ;
status = smb_raw_setfileinfo ( cli - > tree , & sfinfo ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK ,
ret , done , " setfileinfo failed " ) ;
finfo . generic . level = RAW_FILEINFO_ALL_INFO ;
finfo . generic . in . file . fnum = fnum ;
status = smb_raw_fileinfo ( cli - > tree , tctx , & finfo ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK ,
ret , done , " fileinfo failed " ) ;
torture_assert_int_equal ( tctx ,
finfo . all_info . out . attrib & ~ FILE_ATTRIBUTE_NONINDEXED ,
FILE_ATTRIBUTE_DIRECTORY ,
" archive bit set " ) ;
status = smbcli_close ( cli - > tree , fnum ) ;
torture_assert_ntstatus_equal_goto ( tctx , status , NT_STATUS_OK ,
ret , done , " close failed " ) ;
done :
smbcli_close ( cli - > tree , fnum ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
2009-11-24 16:25:02 -08:00
struct torture_suite * torture_raw_sfileinfo ( TALLOC_CTX * mem_ctx )
{
struct torture_suite * suite = torture_suite_create ( mem_ctx ,
" SFILEINFO " ) ;
torture_suite_add_1smb_test ( suite , " BASE " , torture_raw_sfileinfo_base ) ;
torture_suite_add_1smb_test ( suite , " RENAME " ,
torture_raw_sfileinfo_rename ) ;
torture_suite_add_1smb_test ( suite , " BUG " , torture_raw_sfileinfo_bug ) ;
2009-11-24 16:29:19 -08:00
torture_suite_add_2smb_test ( suite , " END-OF-FILE " ,
torture_raw_sfileinfo_eof ) ;
torture_suite_add_2smb_test ( suite , " END-OF-FILE-ACCESS " ,
torture_raw_sfileinfo_eof_access ) ;
2009-12-17 22:32:58 +00:00
torture_suite_add_1smb_test ( suite , " ARCHIVE " , torture_raw_sfileinfo_archive ) ;
2009-11-24 16:25:02 -08:00
return suite ;
}