2005-11-11 07:46:48 +03:00
/*
Unix SMB / CIFS implementation .
test suite for SMB2 connection operations
Copyright ( C ) Andrew Tridgell 2005
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-01-03 18:40:05 +03:00
# include "smb.h"
2006-03-18 18:42:57 +03:00
# include "librpc/gen_ndr/security.h"
2005-11-11 07:46:48 +03:00
# include "libcli/smb2/smb2.h"
2005-11-11 08:53:54 +03:00
# include "libcli/smb2/smb2_calls.h"
2006-02-04 17:08:24 +03:00
# include "torture/smb2/proto.h"
2005-11-11 15:37:16 +03:00
/*
2005-11-11 17:04:46 +03:00
send a close
2005-11-11 15:37:16 +03:00
*/
2005-11-11 17:04:46 +03:00
static NTSTATUS torture_smb2_close ( struct smb2_tree * tree , struct smb2_handle handle )
2005-11-11 15:37:16 +03:00
{
2005-11-11 17:04:46 +03:00
struct smb2_close io ;
2005-11-11 15:37:16 +03:00
NTSTATUS status ;
2005-11-11 16:08:31 +03:00
TALLOC_CTX * tmp_ctx = talloc_new ( tree ) ;
2005-11-11 15:37:16 +03:00
ZERO_STRUCT ( io ) ;
2005-11-12 02:27:47 +03:00
io . in . flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION ;
2005-11-11 17:04:46 +03:00
io . in . handle = handle ;
status = smb2_close ( tree , & io ) ;
2005-11-11 15:37:16 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2005-11-11 17:04:46 +03:00
printf ( " close failed - %s \n " , nt_errstr ( status ) ) ;
return status ;
2005-11-11 15:37:16 +03:00
}
2005-11-12 10:48:56 +03:00
if ( DEBUGLVL ( 1 ) ) {
printf ( " Close gave: \n " ) ;
printf ( " create_time = %s \n " , nt_time_string ( tmp_ctx , io . out . create_time ) ) ;
printf ( " access_time = %s \n " , nt_time_string ( tmp_ctx , io . out . access_time ) ) ;
printf ( " write_time = %s \n " , nt_time_string ( tmp_ctx , io . out . write_time ) ) ;
printf ( " change_time = %s \n " , nt_time_string ( tmp_ctx , io . out . change_time ) ) ;
2005-11-30 05:08:15 +03:00
printf ( " alloc_size = %lld \n " , ( long long ) io . out . alloc_size ) ;
printf ( " size = %lld \n " , ( long long ) io . out . size ) ;
2005-11-12 10:48:56 +03:00
printf ( " file_attr = 0x%x \n " , io . out . file_attr ) ;
}
2005-11-11 16:08:31 +03:00
talloc_free ( tmp_ctx ) ;
2005-11-11 15:37:16 +03:00
2005-11-11 17:04:46 +03:00
return status ;
2005-11-11 15:37:16 +03:00
}
2005-11-11 17:04:46 +03:00
2005-11-14 08:10:09 +03:00
/*
test writing
*/
static NTSTATUS torture_smb2_write ( struct smb2_tree * tree , struct smb2_handle handle )
{
struct smb2_write w ;
struct smb2_read r ;
2005-11-25 14:33:57 +03:00
struct smb2_flush f ;
2005-11-14 08:10:09 +03:00
NTSTATUS status ;
DATA_BLOB data ;
2005-11-16 09:39:57 +03:00
int i ;
2005-11-14 08:10:09 +03:00
2005-11-16 09:39:57 +03:00
if ( lp_parm_bool ( - 1 , " torture " , " dangerous " , False ) ) {
data = data_blob_talloc ( tree , NULL , 160000 ) ;
} else {
data = data_blob_talloc ( tree , NULL , 120000 ) ;
}
for ( i = 0 ; i < data . length ; i + + ) {
data . data [ i ] = i ;
}
2005-11-14 08:10:09 +03:00
ZERO_STRUCT ( w ) ;
w . in . offset = 0 ;
w . in . handle = handle ;
w . in . data = data ;
2005-11-15 07:38:59 +03:00
status = smb2_write ( tree , & w ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " write failed - %s \n " , nt_errstr ( status ) ) ;
return status ;
}
torture_smb2_all_info ( tree , handle ) ;
2005-11-14 08:10:09 +03:00
status = smb2_write ( tree , & w ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " write failed - %s \n " , nt_errstr ( status ) ) ;
return status ;
}
2005-11-15 07:38:59 +03:00
torture_smb2_all_info ( tree , handle ) ;
2005-11-25 14:33:57 +03:00
ZERO_STRUCT ( f ) ;
f . in . handle = handle ;
status = smb2_flush ( tree , & f ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " flush failed - %s \n " , nt_errstr ( status ) ) ;
return status ;
}
2005-11-14 08:10:09 +03:00
ZERO_STRUCT ( r ) ;
r . in . length = data . length ;
r . in . offset = 0 ;
r . in . handle = handle ;
status = smb2_read ( tree , tree , & r ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " read failed - %s \n " , nt_errstr ( status ) ) ;
return status ;
}
if ( data . length ! = r . out . data . length | |
memcmp ( data . data , r . out . data . data , data . length ) ! = 0 ) {
printf ( " read data mismatch \n " ) ;
return NT_STATUS_NET_WRITE_FAULT ;
}
return status ;
}
2005-11-11 16:08:31 +03:00
/*
2005-11-11 17:04:46 +03:00
send a create
2005-11-11 16:08:31 +03:00
*/
2005-11-11 17:04:46 +03:00
static struct smb2_handle torture_smb2_create ( struct smb2_tree * tree ,
const char * fname )
2005-11-11 16:08:31 +03:00
{
2005-11-11 17:04:46 +03:00
struct smb2_create io ;
2005-11-11 16:08:31 +03:00
NTSTATUS status ;
TALLOC_CTX * tmp_ctx = talloc_new ( tree ) ;
ZERO_STRUCT ( io ) ;
2005-11-12 02:27:47 +03:00
io . in . oplock_flags = 0 ;
2005-11-11 17:04:46 +03:00
io . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
2005-11-12 02:27:47 +03:00
io . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
2005-11-11 17:04:46 +03:00
io . in . share_access =
NTCREATEX_SHARE_ACCESS_DELETE |
NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE ;
io . in . create_options = NTCREATEX_OPTIONS_WRITE_THROUGH ;
io . in . fname = fname ;
2005-11-16 14:01:15 +03:00
status = smb2_create ( tree , tmp_ctx , & io ) ;
2005-11-11 16:08:31 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2005-11-11 17:04:46 +03:00
printf ( " create1 failed - %s \n " , nt_errstr ( status ) ) ;
return io . out . handle ;
2005-11-11 16:08:31 +03:00
}
2005-11-12 10:48:56 +03:00
if ( DEBUGLVL ( 1 ) ) {
printf ( " Open gave: \n " ) ;
printf ( " oplock_flags = 0x%x \n " , io . out . oplock_flags ) ;
printf ( " create_action = 0x%x \n " , io . out . create_action ) ;
printf ( " create_time = %s \n " , nt_time_string ( tmp_ctx , io . out . create_time ) ) ;
printf ( " access_time = %s \n " , nt_time_string ( tmp_ctx , io . out . access_time ) ) ;
printf ( " write_time = %s \n " , nt_time_string ( tmp_ctx , io . out . write_time ) ) ;
printf ( " change_time = %s \n " , nt_time_string ( tmp_ctx , io . out . change_time ) ) ;
2005-11-30 05:08:15 +03:00
printf ( " alloc_size = %lld \n " , ( long long ) io . out . alloc_size ) ;
printf ( " size = %lld \n " , ( long long ) io . out . size ) ;
2005-11-12 10:48:56 +03:00
printf ( " file_attr = 0x%x \n " , io . out . file_attr ) ;
printf ( " handle = %016llx%016llx \n " ,
2005-11-30 05:08:15 +03:00
( long long ) io . out . handle . data [ 0 ] ,
( long long ) io . out . handle . data [ 1 ] ) ;
2005-11-12 10:48:56 +03:00
}
2005-11-11 16:08:31 +03:00
talloc_free ( tmp_ctx ) ;
2005-11-11 17:04:46 +03:00
return io . out . handle ;
2005-11-11 16:08:31 +03:00
}
2005-11-12 10:48:56 +03:00
2005-11-11 08:53:54 +03:00
/*
basic testing of SMB2 connection calls
*/
BOOL torture_smb2_connect ( void )
{
TALLOC_CTX * mem_ctx = talloc_new ( NULL ) ;
2005-11-11 12:11:51 +03:00
struct smb2_tree * tree ;
2005-11-11 16:08:31 +03:00
struct smb2_handle h1 , h2 ;
2005-11-25 14:05:21 +03:00
NTSTATUS status ;
2005-11-11 08:53:54 +03:00
2005-11-15 07:38:59 +03:00
if ( ! torture_smb2_connection ( mem_ctx , & tree ) ) {
2005-11-12 05:12:51 +03:00
return False ;
}
2005-11-12 04:08:43 +03:00
2005-11-12 05:37:51 +03:00
h1 = torture_smb2_create ( tree , " test9.dat " ) ;
h2 = torture_smb2_create ( tree , " test9.dat " ) ;
2005-11-14 08:10:09 +03:00
torture_smb2_write ( tree , h1 ) ;
2005-11-11 16:08:31 +03:00
torture_smb2_close ( tree , h1 ) ;
torture_smb2_close ( tree , h2 ) ;
2005-11-11 08:53:54 +03:00
2005-11-25 14:12:08 +03:00
status = smb2_tdis ( tree ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " tdis failed - %s \n " , nt_errstr ( status ) ) ;
return False ;
}
status = smb2_tdis ( tree ) ;
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_NETWORK_NAME_DELETED ) ) {
printf ( " tdis should have disabled session - %s \n " , nt_errstr ( status ) ) ;
return False ;
}
2005-12-07 10:28:43 +03:00
status = smb2_logoff ( tree - > session ) ;
2005-11-25 14:05:21 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Logoff failed - %s \n " , nt_errstr ( status ) ) ;
return False ;
}
2005-12-07 10:28:43 +03:00
status = smb2_logoff ( tree - > session ) ;
2005-11-25 14:05:21 +03:00
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_USER_SESSION_DELETED ) ) {
printf ( " Logoff should have disabled session - %s \n " , nt_errstr ( status ) ) ;
return False ;
}
2005-12-07 10:28:43 +03:00
status = smb2_keepalive ( tree - > session - > transport ) ;
2005-11-25 14:51:47 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " keepalive failed? - %s \n " , nt_errstr ( status ) ) ;
return False ;
}
2005-11-11 07:46:48 +03:00
talloc_free ( mem_ctx ) ;
2005-11-11 08:53:54 +03:00
return True ;
2005-11-11 07:46:48 +03:00
}