2003-08-13 05:53:07 +04:00
/*
Unix SMB / CIFS implementation .
SMB torture tester utility functions
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
the Free Software Foundation ; either version 2 of the License , or
( 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
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
2006-03-11 13:25:59 +03:00
# include "smb.h"
2006-05-14 02:17:58 +04:00
# include "lib/cmdline/popt_common.h"
2004-11-01 04:03:22 +03:00
# include "libcli/raw/libcliraw.h"
2006-05-19 18:10:14 +04:00
# include "libcli/raw/ioctl.h"
2006-01-03 18:40:05 +03:00
# include "libcli/libcli.h"
2004-11-02 02:45:40 +03:00
# include "system/shmem.h"
2004-11-02 03:24:21 +03:00
# include "system/time.h"
2006-03-17 19:45:24 +03:00
# include "torture/torture.h"
2003-08-13 05:53:07 +04:00
2006-03-17 19:11:02 +03:00
/**
2004-11-12 12:37:59 +03:00
setup a directory ready for a test
*/
2006-03-17 19:11:02 +03:00
_PUBLIC_ BOOL torture_setup_dir ( struct smbcli_state * cli , const char * dname )
2004-11-12 12:37:59 +03:00
{
smb_raw_exit ( cli - > session ) ;
if ( smbcli_deltree ( cli - > tree , dname ) = = - 1 | |
NT_STATUS_IS_ERR ( smbcli_mkdir ( cli - > tree , dname ) ) ) {
printf ( " Unable to setup %s - %s \n " , dname , smbcli_errstr ( cli - > tree ) ) ;
return False ;
}
return True ;
}
2003-08-14 02:23:18 +04:00
/*
create a directory , returning a handle to it
*/
2005-08-03 22:02:45 +04:00
NTSTATUS create_directory_handle ( struct smbcli_tree * tree , const char * dname , int * fnum )
2003-08-14 02:23:18 +04:00
{
NTSTATUS status ;
union smb_open io ;
TALLOC_CTX * mem_ctx ;
mem_ctx = talloc_init ( " create_directory_handle " ) ;
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
io . ntcreatex . in . flags = 0 ;
2005-07-01 16:47:10 +04:00
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
2003-08-14 02:23:18 +04:00
io . ntcreatex . in . create_options = NTCREATEX_OPTIONS_DIRECTORY ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE ;
io . ntcreatex . in . alloc_size = 0 ;
2005-08-04 08:20:26 +04:00
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
2003-08-14 02:23:18 +04:00
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = dname ;
2003-09-02 08:37:33 +04:00
status = smb_raw_open ( tree , mem_ctx , & io ) ;
2005-08-03 22:02:45 +04:00
talloc_free ( mem_ctx ) ;
if ( NT_STATUS_IS_OK ( status ) ) {
2006-03-13 01:48:25 +03:00
* fnum = io . ntcreatex . out . file . fnum ;
2003-08-14 02:23:18 +04:00
}
2005-08-03 22:02:45 +04:00
return status ;
2003-08-14 02:23:18 +04:00
}
2005-08-04 08:20:26 +04:00
2006-03-17 19:11:02 +03:00
/**
2003-08-13 05:53:07 +04:00
sometimes we need a fairly complex file to work with , so we can test
all possible attributes .
*/
2006-03-17 19:11:02 +03:00
_PUBLIC_ int create_complex_file ( struct smbcli_state * cli , TALLOC_CTX * mem_ctx , const char * fname )
2003-08-13 05:53:07 +04:00
{
int fnum ;
char buf [ 7 ] = " abc " ;
union smb_setfileinfo setfile ;
union smb_fileinfo fileinfo ;
time_t t = ( time ( NULL ) & ~ 1 ) ;
NTSTATUS status ;
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli - > tree , fname ) ;
2004-11-30 07:33:27 +03:00
fnum = smbcli_nt_create_full ( cli - > tree , fname , 0 ,
2004-12-02 07:37:36 +03:00
SEC_RIGHTS_FILE_ALL ,
2004-11-30 07:33:27 +03:00
FILE_ATTRIBUTE_NORMAL ,
NTCREATEX_SHARE_ACCESS_DELETE |
NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE ,
NTCREATEX_DISP_OVERWRITE_IF ,
0 , 0 ) ;
2003-08-13 05:53:07 +04:00
if ( fnum = = - 1 ) return - 1 ;
2004-08-04 17:23:35 +04:00
smbcli_write ( cli - > tree , fnum , 0 , buf , 0 , sizeof ( buf ) ) ;
2003-08-13 05:53:07 +04:00
2005-11-15 07:38:59 +03:00
if ( strchr ( fname , ' : ' ) = = NULL ) {
/* setup some EAs */
setfile . generic . level = RAW_SFILEINFO_EA_SET ;
2006-03-13 01:48:25 +03:00
setfile . generic . in . file . fnum = fnum ;
2005-11-15 07:38:59 +03:00
setfile . ea_set . in . num_eas = 2 ;
setfile . ea_set . in . eas = talloc_array ( mem_ctx , struct ea_struct , 2 ) ;
setfile . ea_set . in . eas [ 0 ] . flags = 0 ;
setfile . ea_set . in . eas [ 0 ] . name . s = " EAONE " ;
setfile . ea_set . in . eas [ 0 ] . value = data_blob_talloc ( mem_ctx , " VALUE1 " , 6 ) ;
setfile . ea_set . in . eas [ 1 ] . flags = 0 ;
setfile . ea_set . in . eas [ 1 ] . name . s = " SECONDEA " ;
setfile . ea_set . in . eas [ 1 ] . value = data_blob_talloc ( mem_ctx , " ValueTwo " , 8 ) ;
status = smb_raw_setfileinfo ( cli - > tree , & setfile ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Failed to setup EAs \n " ) ;
}
}
/* make sure all the timestamps aren't the same, and are also
in different DST zones */
setfile . generic . level = RAW_SFILEINFO_SETATTRE ;
2006-03-13 01:48:25 +03:00
setfile . generic . in . file . fnum = fnum ;
2005-11-15 07:38:59 +03:00
setfile . setattre . in . create_time = t + 9 * 30 * 24 * 60 * 60 ;
setfile . setattre . in . access_time = t + 6 * 30 * 24 * 60 * 60 ;
setfile . setattre . in . write_time = t + 3 * 30 * 24 * 60 * 60 ;
2003-08-13 05:53:07 +04:00
status = smb_raw_setfileinfo ( cli - > tree , & setfile ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2005-11-15 07:38:59 +03:00
printf ( " Failed to setup file times - %s \n " , nt_errstr ( status ) ) ;
}
/* make sure all the timestamps aren't the same */
fileinfo . generic . level = RAW_FILEINFO_GETATTRE ;
2006-03-13 01:48:25 +03:00
fileinfo . generic . in . file . fnum = fnum ;
2005-11-15 07:38:59 +03:00
status = smb_raw_fileinfo ( cli - > tree , mem_ctx , & fileinfo ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Failed to query file times - %s \n " , nt_errstr ( status ) ) ;
}
if ( setfile . setattre . in . create_time ! = fileinfo . getattre . out . create_time ) {
printf ( " create_time not setup correctly \n " ) ;
}
if ( setfile . setattre . in . access_time ! = fileinfo . getattre . out . access_time ) {
printf ( " access_time not setup correctly \n " ) ;
}
if ( setfile . setattre . in . write_time ! = fileinfo . getattre . out . write_time ) {
printf ( " write_time not setup correctly \n " ) ;
}
return fnum ;
}
/*
sometimes we need a fairly complex directory to work with , so we can test
all possible attributes .
*/
int create_complex_dir ( struct smbcli_state * cli , TALLOC_CTX * mem_ctx , const char * dname )
{
int fnum ;
union smb_setfileinfo setfile ;
union smb_fileinfo fileinfo ;
time_t t = ( time ( NULL ) & ~ 1 ) ;
NTSTATUS status ;
smbcli_deltree ( cli - > tree , dname ) ;
fnum = smbcli_nt_create_full ( cli - > tree , dname , 0 ,
SEC_RIGHTS_DIR_ALL ,
FILE_ATTRIBUTE_DIRECTORY ,
NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE ,
NTCREATEX_DISP_OPEN_IF ,
NTCREATEX_OPTIONS_DIRECTORY , 0 ) ;
if ( fnum = = - 1 ) return - 1 ;
if ( strchr ( dname , ' : ' ) = = NULL ) {
/* setup some EAs */
setfile . generic . level = RAW_SFILEINFO_EA_SET ;
2006-03-13 01:48:25 +03:00
setfile . generic . in . file . fnum = fnum ;
2005-11-15 07:38:59 +03:00
setfile . ea_set . in . num_eas = 2 ;
setfile . ea_set . in . eas = talloc_array ( mem_ctx , struct ea_struct , 2 ) ;
setfile . ea_set . in . eas [ 0 ] . flags = 0 ;
setfile . ea_set . in . eas [ 0 ] . name . s = " EAONE " ;
setfile . ea_set . in . eas [ 0 ] . value = data_blob_talloc ( mem_ctx , " VALUE1 " , 6 ) ;
setfile . ea_set . in . eas [ 1 ] . flags = 0 ;
setfile . ea_set . in . eas [ 1 ] . name . s = " SECONDEA " ;
setfile . ea_set . in . eas [ 1 ] . value = data_blob_talloc ( mem_ctx , " ValueTwo " , 8 ) ;
status = smb_raw_setfileinfo ( cli - > tree , & setfile ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Failed to setup EAs \n " ) ;
}
2003-08-13 05:53:07 +04:00
}
2004-04-11 00:18:22 +04:00
/* make sure all the timestamps aren't the same, and are also
in different DST zones */
2003-08-13 05:53:07 +04:00
setfile . generic . level = RAW_SFILEINFO_SETATTRE ;
2006-03-13 01:48:25 +03:00
setfile . generic . in . file . fnum = fnum ;
2003-08-13 05:53:07 +04:00
2004-04-11 00:18:22 +04:00
setfile . setattre . in . create_time = t + 9 * 30 * 24 * 60 * 60 ;
setfile . setattre . in . access_time = t + 6 * 30 * 24 * 60 * 60 ;
setfile . setattre . in . write_time = t + 3 * 30 * 24 * 60 * 60 ;
2003-08-13 05:53:07 +04:00
status = smb_raw_setfileinfo ( cli - > tree , & setfile ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Failed to setup file times - %s \n " , nt_errstr ( status ) ) ;
}
/* make sure all the timestamps aren't the same */
fileinfo . generic . level = RAW_FILEINFO_GETATTRE ;
2006-03-13 01:48:25 +03:00
fileinfo . generic . in . file . fnum = fnum ;
2003-08-13 05:53:07 +04:00
status = smb_raw_fileinfo ( cli - > tree , mem_ctx , & fileinfo ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Failed to query file times - %s \n " , nt_errstr ( status ) ) ;
}
if ( setfile . setattre . in . create_time ! = fileinfo . getattre . out . create_time ) {
printf ( " create_time not setup correctly \n " ) ;
}
if ( setfile . setattre . in . access_time ! = fileinfo . getattre . out . access_time ) {
printf ( " access_time not setup correctly \n " ) ;
}
if ( setfile . setattre . in . write_time ! = fileinfo . getattre . out . write_time ) {
printf ( " write_time not setup correctly \n " ) ;
}
return fnum ;
}
/* return a pointer to a anonymous shared memory segment of size "size"
which will persist across fork ( ) but will disappear when all processes
exit
The memory is not zeroed
This function uses system5 shared memory . It takes advantage of a property
that the memory is not destroyed if it is attached when the id is removed
*/
void * shm_setup ( int size )
{
int shmid ;
void * ret ;
shmid = shmget ( IPC_PRIVATE , size , SHM_R | SHM_W ) ;
if ( shmid = = - 1 ) {
printf ( " can't get shared memory \n " ) ;
exit ( 1 ) ;
}
ret = ( void * ) shmat ( shmid , 0 , 0 ) ;
if ( ! ret | | ret = = ( void * ) - 1 ) {
printf ( " can't attach to shared memory \n " ) ;
return NULL ;
}
/* the following releases the ipc, but note that this process
and all its children will still have access to the memory , its
just that the shmid is no longer valid for other shm calls . This
means we don ' t leave behind lots of shm segments after we exit
See Stevens " advanced programming in unix env " for details
*/
shmctl ( shmid , IPC_RMID , 0 ) ;
return ret ;
}
/*
check that a wire string matches the flags specified
not 100 % accurate , but close enough for testing
*/
2006-03-11 13:25:59 +03:00
BOOL wire_bad_flags ( struct smb_wire_string * str , int flags , struct smbcli_state * cli )
2003-08-13 05:53:07 +04:00
{
2004-08-12 01:11:37 +04:00
BOOL server_unicode ;
2003-08-13 05:53:07 +04:00
int len ;
2003-08-15 20:19:48 +04:00
if ( ! str | | ! str - > s ) return True ;
2003-08-13 05:53:07 +04:00
len = strlen ( str - > s ) ;
if ( flags & STR_TERMINATE ) len + + ;
2004-08-12 01:11:37 +04:00
server_unicode = ( cli - > transport - > negotiate . capabilities & CAP_UNICODE ) ? True : False ;
if ( getenv ( " CLI_FORCE_ASCII " ) | | ! lp_unicode ( ) ) {
server_unicode = False ;
}
if ( ( flags & STR_UNICODE ) | | server_unicode ) {
2003-08-13 05:53:07 +04:00
len * = 2 ;
} else if ( flags & STR_TERMINATE_ASCII ) {
len + + ;
}
if ( str - > private_length ! = len ) {
printf ( " Expected wire_length %d but got %d for '%s' \n " ,
len , str - > private_length , str - > s ) ;
return True ;
}
return False ;
}
/*
check if 2 NTTIMEs are equal
*/
BOOL nt_time_equal ( NTTIME * t1 , NTTIME * t2 )
{
2004-05-25 17:57:39 +04:00
return * t1 = = * t2 ;
2003-08-13 05:53:07 +04:00
}
/*
dump a all_info QFILEINFO structure
*/
void dump_all_info ( TALLOC_CTX * mem_ctx , union smb_fileinfo * finfo )
{
2004-05-25 17:57:39 +04:00
d_printf ( " \t create_time: %s \n " , nt_time_string ( mem_ctx , finfo - > all_info . out . create_time ) ) ;
d_printf ( " \t access_time: %s \n " , nt_time_string ( mem_ctx , finfo - > all_info . out . access_time ) ) ;
d_printf ( " \t write_time: %s \n " , nt_time_string ( mem_ctx , finfo - > all_info . out . write_time ) ) ;
d_printf ( " \t change_time: %s \n " , nt_time_string ( mem_ctx , finfo - > all_info . out . change_time ) ) ;
2003-08-13 05:53:07 +04:00
d_printf ( " \t attrib: 0x%x \n " , finfo - > all_info . out . attrib ) ;
2005-11-30 05:08:15 +03:00
d_printf ( " \t alloc_size: %llu \n " , ( long long ) finfo - > all_info . out . alloc_size ) ;
d_printf ( " \t size: %llu \n " , ( long long ) finfo - > all_info . out . size ) ;
2003-08-13 05:53:07 +04:00
d_printf ( " \t nlink: %u \n " , finfo - > all_info . out . nlink ) ;
d_printf ( " \t delete_pending: %u \n " , finfo - > all_info . out . delete_pending ) ;
d_printf ( " \t directory: %u \n " , finfo - > all_info . out . directory ) ;
d_printf ( " \t ea_size: %u \n " , finfo - > all_info . out . ea_size ) ;
d_printf ( " \t fname: '%s' \n " , finfo - > all_info . out . fname . s ) ;
}
/*
dump file infor by name
*/
2004-08-04 17:23:35 +04:00
void torture_all_info ( struct smbcli_tree * tree , const char * fname )
2003-08-13 05:53:07 +04:00
{
2004-08-25 14:21:14 +04:00
TALLOC_CTX * mem_ctx = talloc_init ( " %s " , fname ) ;
2003-08-13 05:53:07 +04:00
union smb_fileinfo finfo ;
NTSTATUS status ;
finfo . generic . level = RAW_FILEINFO_ALL_INFO ;
2006-03-13 01:48:25 +03:00
finfo . generic . in . file . path = fname ;
2003-08-13 05:53:07 +04:00
status = smb_raw_pathinfo ( tree , mem_ctx , & finfo ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s - %s \n " , fname , nt_errstr ( status ) ) ;
return ;
}
d_printf ( " %s: \n " , fname ) ;
dump_all_info ( mem_ctx , & finfo ) ;
2005-01-27 10:08:20 +03:00
talloc_free ( mem_ctx ) ;
2003-08-13 05:53:07 +04:00
}
/*
set a attribute on a file
*/
2004-08-04 17:23:35 +04:00
BOOL torture_set_file_attribute ( struct smbcli_tree * tree , const char * fname , uint16_t attrib )
2003-08-13 05:53:07 +04:00
{
union smb_setfileinfo sfinfo ;
NTSTATUS status ;
ZERO_STRUCT ( sfinfo . basic_info . in ) ;
2006-03-13 15:43:59 +03:00
sfinfo . basic_info . level = RAW_SFILEINFO_BASIC_INFORMATION ;
sfinfo . basic_info . in . file . path = fname ;
2003-08-13 05:53:07 +04:00
sfinfo . basic_info . in . attrib = attrib ;
status = smb_raw_setpathinfo ( tree , & sfinfo ) ;
return NT_STATUS_IS_OK ( status ) ;
}
/*
set a file descriptor as sparse
*/
2004-08-04 17:23:35 +04:00
NTSTATUS torture_set_sparse ( struct smbcli_tree * tree , int fnum )
2003-08-13 05:53:07 +04:00
{
2003-12-04 05:03:06 +03:00
union smb_ioctl nt ;
NTSTATUS status ;
TALLOC_CTX * mem_ctx ;
mem_ctx = talloc_init ( " torture_set_sparse " ) ;
if ( ! mem_ctx ) {
return NT_STATUS_NO_MEMORY ;
}
2003-08-13 05:53:07 +04:00
2003-12-04 05:03:06 +03:00
nt . ntioctl . level = RAW_IOCTL_NTIOCTL ;
2006-05-19 18:10:14 +04:00
nt . ntioctl . in . function = FSCTL_SET_SPARSE ;
2006-03-13 01:48:25 +03:00
nt . ntioctl . in . file . fnum = fnum ;
2003-12-04 05:03:06 +03:00
nt . ntioctl . in . fsctl = True ;
nt . ntioctl . in . filter = 0 ;
2006-05-19 18:10:14 +04:00
nt . ntioctl . in . max_data = 0 ;
nt . ntioctl . in . blob = data_blob ( NULL , 0 ) ;
2003-12-04 05:03:06 +03:00
status = smb_raw_ioctl ( tree , mem_ctx , & nt ) ;
2005-01-27 10:08:20 +03:00
talloc_free ( mem_ctx ) ;
2003-08-13 05:53:07 +04:00
2003-12-04 05:03:06 +03:00
return status ;
2003-08-13 05:53:07 +04:00
}
2004-12-13 13:48:21 +03:00
/*
check that an EA has the right value
*/
NTSTATUS torture_check_ea ( struct smbcli_state * cli ,
const char * fname , const char * eaname , const char * value )
{
union smb_fileinfo info ;
NTSTATUS status ;
2004-12-18 01:47:49 +03:00
struct ea_name ea ;
2005-01-06 05:32:43 +03:00
TALLOC_CTX * mem_ctx = talloc_new ( cli ) ;
2004-12-13 13:48:21 +03:00
2004-12-18 01:47:49 +03:00
info . ea_list . level = RAW_FILEINFO_EA_LIST ;
2006-03-13 01:48:25 +03:00
info . ea_list . in . file . path = fname ;
2004-12-18 01:47:49 +03:00
info . ea_list . in . num_names = 1 ;
info . ea_list . in . ea_names = & ea ;
ea . name . s = eaname ;
2004-12-13 13:48:21 +03:00
status = smb_raw_pathinfo ( cli - > tree , mem_ctx , & info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
talloc_free ( mem_ctx ) ;
return status ;
}
2004-12-18 01:47:49 +03:00
if ( info . ea_list . out . num_eas ! = 1 ) {
printf ( " Expected 1 ea in ea_list \n " ) ;
talloc_free ( mem_ctx ) ;
return NT_STATUS_EA_CORRUPT_ERROR ;
2004-12-13 13:48:21 +03:00
}
2005-08-30 15:55:05 +04:00
if ( strcasecmp_m ( eaname , info . ea_list . out . eas [ 0 ] . name . s ) ! = 0 ) {
2004-12-18 01:47:49 +03:00
printf ( " Expected ea '%s' not '%s' in ea_list \n " ,
eaname , info . ea_list . out . eas [ 0 ] . name . s ) ;
talloc_free ( mem_ctx ) ;
return NT_STATUS_EA_CORRUPT_ERROR ;
}
if ( value = = NULL ) {
if ( info . ea_list . out . eas [ 0 ] . value . length ! = 0 ) {
printf ( " Expected zero length ea for %s \n " , eaname ) ;
talloc_free ( mem_ctx ) ;
return NT_STATUS_EA_CORRUPT_ERROR ;
}
talloc_free ( mem_ctx ) ;
return NT_STATUS_OK ;
}
2004-12-13 13:48:21 +03:00
2004-12-18 01:47:49 +03:00
if ( strlen ( value ) = = info . ea_list . out . eas [ 0 ] . value . length & &
memcmp ( value , info . ea_list . out . eas [ 0 ] . value . data ,
info . ea_list . out . eas [ 0 ] . value . length ) = = 0 ) {
talloc_free ( mem_ctx ) ;
return NT_STATUS_OK ;
2004-12-13 13:48:21 +03:00
}
2004-12-18 01:47:49 +03:00
printf ( " Expected value '%s' not '%*.*s' for ea %s \n " ,
value ,
2005-07-17 13:20:52 +04:00
( int ) info . ea_list . out . eas [ 0 ] . value . length ,
( int ) info . ea_list . out . eas [ 0 ] . value . length ,
2004-12-18 01:47:49 +03:00
info . ea_list . out . eas [ 0 ] . value . data ,
eaname ) ;
talloc_free ( mem_ctx ) ;
return NT_STATUS_EA_CORRUPT_ERROR ;
2004-12-13 13:48:21 +03:00
}
2006-03-17 20:59:58 +03:00
BOOL torture_open_connection_share ( TALLOC_CTX * mem_ctx ,
struct smbcli_state * * c ,
const char * hostname ,
const char * sharename ,
struct event_context * ev )
{
NTSTATUS status ;
status = smbcli_full_connection ( mem_ctx , c , hostname ,
sharename , NULL ,
cmdline_credentials , ev ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Failed to open connection - %s \n " , nt_errstr ( status ) ) ;
return False ;
}
( * c ) - > transport - > options . use_oplocks = use_oplocks ;
( * c ) - > transport - > options . use_level2_oplocks = use_level_II_oplocks ;
return True ;
}
_PUBLIC_ BOOL torture_open_connection ( struct smbcli_state * * c )
{
const char * host = lp_parm_string ( - 1 , " torture " , " host " ) ;
const char * share = lp_parm_string ( - 1 , " torture " , " share " ) ;
return torture_open_connection_share ( NULL , c , host , share , NULL ) ;
}
2006-04-10 08:51:52 +04:00
_PUBLIC_ BOOL torture_open_connection_ev ( struct smbcli_state * * c ,
struct event_context * ev )
{
const char * host = lp_parm_string ( - 1 , " torture " , " host " ) ;
const char * share = lp_parm_string ( - 1 , " torture " , " share " ) ;
return torture_open_connection_share ( NULL , c , host , share , ev ) ;
}
2006-03-17 20:59:58 +03:00
_PUBLIC_ BOOL torture_close_connection ( struct smbcli_state * c )
{
BOOL ret = True ;
if ( ! c ) return True ;
if ( NT_STATUS_IS_ERR ( smbcli_tdis ( c ) ) ) {
printf ( " tdis failed (%s) \n " , smbcli_errstr ( c - > tree ) ) ;
ret = False ;
}
talloc_free ( c ) ;
return ret ;
}
/* check if the server produced the expected error code */
_PUBLIC_ BOOL check_error ( const char * location , struct smbcli_state * c ,
uint8_t eclass , uint32_t ecode , NTSTATUS nterr )
{
NTSTATUS status ;
status = smbcli_nt_error ( c - > tree ) ;
if ( NT_STATUS_IS_DOS ( status ) ) {
int class , num ;
class = NT_STATUS_DOS_CLASS ( status ) ;
num = NT_STATUS_DOS_CODE ( status ) ;
if ( eclass ! = class | | ecode ! = num ) {
printf ( " unexpected error code %s \n " , nt_errstr ( status ) ) ;
printf ( " expected %s or %s (at %s) \n " ,
nt_errstr ( NT_STATUS_DOS ( eclass , ecode ) ) ,
nt_errstr ( nterr ) , location ) ;
return False ;
}
} else {
if ( ! NT_STATUS_EQUAL ( nterr , status ) ) {
printf ( " unexpected error code %s \n " , nt_errstr ( status ) ) ;
printf ( " expected %s (at %s) \n " , nt_errstr ( nterr ) , location ) ;
return False ;
}
}
return True ;
}