2005-11-11 04:46:48 +00: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
2007-07-10 02:07:03 +00:00
the Free Software Foundation ; either version 3 of the License , or
2005-11-11 04:46:48 +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/>.
2005-11-11 04:46:48 +00:00
*/
# include "includes.h"
# include "libcli/smb2/smb2.h"
2005-11-11 05:53:54 +00:00
# include "libcli/smb2/smb2_calls.h"
2006-03-25 16:01:28 +00:00
# include "torture/torture.h"
2006-02-04 14:08:24 +00:00
# include "torture/smb2/proto.h"
2005-11-11 12:37:16 +00:00
/*
2005-11-11 14:04:46 +00:00
send a close
2005-11-11 12:37:16 +00:00
*/
2005-11-11 14:04:46 +00:00
static NTSTATUS torture_smb2_close ( struct smb2_tree * tree , struct smb2_handle handle )
2005-11-11 12:37:16 +00:00
{
2005-11-11 14:04:46 +00:00
struct smb2_close io ;
2005-11-11 12:37:16 +00:00
NTSTATUS status ;
2005-11-11 13:08:31 +00:00
TALLOC_CTX * tmp_ctx = talloc_new ( tree ) ;
2005-11-11 12:37:16 +00:00
ZERO_STRUCT ( io ) ;
2006-05-20 10:46:38 +00:00
io . in . file . handle = handle ;
io . in . flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION ;
2005-11-11 14:04:46 +00:00
status = smb2_close ( tree , & io ) ;
2005-11-11 12:37:16 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2005-11-11 14:04:46 +00:00
printf ( " close failed - %s \n " , nt_errstr ( status ) ) ;
return status ;
2005-11-11 12:37:16 +00:00
}
2005-11-12 07:48:56 +00: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 02:08:15 +00:00
printf ( " alloc_size = %lld \n " , ( long long ) io . out . alloc_size ) ;
printf ( " size = %lld \n " , ( long long ) io . out . size ) ;
2005-11-12 07:48:56 +00:00
printf ( " file_attr = 0x%x \n " , io . out . file_attr ) ;
}
2005-11-11 13:08:31 +00:00
talloc_free ( tmp_ctx ) ;
2005-11-11 12:37:16 +00:00
2005-11-11 14:04:46 +00:00
return status ;
2005-11-11 12:37:16 +00:00
}
2005-11-11 14:04:46 +00:00
2005-11-14 05:10:09 +00:00
/*
test writing
*/
2007-12-02 21:32:08 +01:00
static NTSTATUS torture_smb2_write ( struct torture_context * tctx , struct smb2_tree * tree , struct smb2_handle handle )
2005-11-14 05:10:09 +00:00
{
struct smb2_write w ;
struct smb2_read r ;
2005-11-25 11:33:57 +00:00
struct smb2_flush f ;
2005-11-14 05:10:09 +00:00
NTSTATUS status ;
DATA_BLOB data ;
2005-11-16 06:39:57 +00:00
int i ;
2005-11-14 05:10:09 +00:00
2007-12-02 21:32:08 +01:00
if ( torture_setting_bool ( tctx , " dangerous " , false ) ) {
2006-10-16 13:06:41 +00:00
data = data_blob_talloc ( tree , NULL , 160000 ) ;
2007-12-02 21:32:08 +01:00
} else if ( torture_setting_bool ( tctx , " samba4 " , false ) ) {
2006-05-20 19:00:53 +00:00
data = data_blob_talloc ( tree , NULL , UINT16_MAX ) ;
2005-11-16 06:39:57 +00:00
} else {
2009-06-03 10:49:44 +02:00
data = data_blob_talloc ( tree , NULL , torture_setting_int ( tctx , " smb2maxwrite " , 120000 ) ) ;
2005-11-16 06:39:57 +00:00
}
for ( i = 0 ; i < data . length ; i + + ) {
data . data [ i ] = i ;
}
2005-11-14 05:10:09 +00:00
ZERO_STRUCT ( w ) ;
2006-05-20 10:46:38 +00:00
w . in . file . handle = handle ;
2005-11-14 05:10:09 +00:00
w . in . offset = 0 ;
w . in . data = data ;
2005-11-15 04:38:59 +00: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 05:10:09 +00: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 04:38:59 +00:00
torture_smb2_all_info ( tree , handle ) ;
2005-11-25 11:33:57 +00:00
ZERO_STRUCT ( f ) ;
2006-05-20 10:46:38 +00:00
f . in . file . handle = handle ;
2005-11-25 11:33:57 +00:00
status = smb2_flush ( tree , & f ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " flush failed - %s \n " , nt_errstr ( status ) ) ;
return status ;
}
2005-11-14 05:10:09 +00:00
ZERO_STRUCT ( r ) ;
2006-05-20 10:46:38 +00:00
r . in . file . handle = handle ;
2005-11-14 05:10:09 +00:00
r . in . length = data . length ;
r . in . offset = 0 ;
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 13:08:31 +00:00
/*
2005-11-11 14:04:46 +00:00
send a create
2005-11-11 13:08:31 +00:00
*/
2008-05-27 14:07:27 +10:00
static struct smb2_handle torture_smb2_createfile ( struct smb2_tree * tree ,
2006-10-16 13:06:41 +00:00
const char * fname )
2005-11-11 13:08:31 +00:00
{
2005-11-11 14:04:46 +00:00
struct smb2_create io ;
2005-11-11 13:08:31 +00:00
NTSTATUS status ;
TALLOC_CTX * tmp_ctx = talloc_new ( tree ) ;
ZERO_STRUCT ( io ) ;
2008-02-13 15:05:44 +11:00
io . in . oplock_level = 0 ;
io . in . desired_access = SEC_RIGHTS_FILE_ALL ;
io . in . file_attributes = FILE_ATTRIBUTE_NORMAL ;
io . in . create_disposition = NTCREATEX_DISP_OPEN_IF ;
2005-11-11 14:04:46 +00: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 11:01:15 +00:00
status = smb2_create ( tree , tmp_ctx , & io ) ;
2005-11-11 13:08:31 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2005-11-11 14:04:46 +00:00
printf ( " create1 failed - %s \n " , nt_errstr ( status ) ) ;
2006-05-20 10:46:38 +00:00
return io . out . file . handle ;
2005-11-11 13:08:31 +00:00
}
2005-11-12 07:48:56 +00:00
if ( DEBUGLVL ( 1 ) ) {
printf ( " Open gave: \n " ) ;
2008-02-13 15:05:44 +11:00
printf ( " oplock_flags = 0x%x \n " , io . out . oplock_level ) ;
2005-11-12 07:48:56 +00:00
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 02:08:15 +00:00
printf ( " alloc_size = %lld \n " , ( long long ) io . out . alloc_size ) ;
printf ( " size = %lld \n " , ( long long ) io . out . size ) ;
2005-11-12 07:48:56 +00:00
printf ( " file_attr = 0x%x \n " , io . out . file_attr ) ;
printf ( " handle = %016llx%016llx \n " ,
2006-05-20 10:46:38 +00:00
( long long ) io . out . file . handle . data [ 0 ] ,
( long long ) io . out . file . handle . data [ 1 ] ) ;
2005-11-12 07:48:56 +00:00
}
2005-11-11 13:08:31 +00:00
talloc_free ( tmp_ctx ) ;
2006-05-20 10:46:38 +00:00
return io . out . file . handle ;
2005-11-11 13:08:31 +00:00
}
2005-11-12 07:48:56 +00:00
2005-11-11 05:53:54 +00:00
/*
basic testing of SMB2 connection calls
*/
2007-10-06 22:28:14 +00:00
bool torture_smb2_connect ( struct torture_context * torture )
2005-11-11 05:53:54 +00:00
{
TALLOC_CTX * mem_ctx = talloc_new ( NULL ) ;
2005-11-11 09:11:51 +00:00
struct smb2_tree * tree ;
2008-06-09 21:41:55 +02:00
struct smb2_request * req ;
2005-11-11 13:08:31 +00:00
struct smb2_handle h1 , h2 ;
2005-11-25 11:05:21 +00:00
NTSTATUS status ;
2005-11-11 05:53:54 +00:00
2007-12-03 00:28:22 +01:00
if ( ! torture_smb2_connection ( torture , & tree ) ) {
2007-10-06 22:28:14 +00:00
return false ;
2005-11-12 02:12:51 +00:00
}
2005-11-12 01:08:43 +00:00
2009-07-08 10:09:54 +02:00
smb2_util_unlink ( tree , " test9.dat " ) ;
2008-05-27 14:07:27 +10:00
h1 = torture_smb2_createfile ( tree , " test9.dat " ) ;
h2 = torture_smb2_createfile ( tree , " test9.dat " ) ;
2007-12-02 21:32:08 +01:00
status = torture_smb2_write ( torture , tree , h1 ) ;
2006-07-01 07:49:02 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Write failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-06 22:28:14 +00:00
return false ;
2006-07-01 07:49:02 +00:00
}
status = torture_smb2_close ( tree , h1 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Close failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-06 22:28:14 +00:00
return false ;
2006-07-01 07:49:02 +00:00
}
status = torture_smb2_close ( tree , h2 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Close failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-06 22:28:14 +00:00
return false ;
2006-07-01 07:49:02 +00:00
}
2005-11-11 05:53:54 +00:00
2006-05-22 14:18:17 +00:00
status = smb2_util_close ( tree , h1 ) ;
2006-07-01 14:27:49 +00:00
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_FILE_CLOSED ) ) {
2006-05-22 14:18:17 +00:00
printf ( " close should have closed the handle - %s \n " , nt_errstr ( status ) ) ;
2007-10-06 22:28:14 +00:00
return false ;
2006-05-22 14:18:17 +00:00
}
2005-11-25 11:12:08 +00:00
status = smb2_tdis ( tree ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " tdis failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-06 22:28:14 +00:00
return false ;
2005-11-25 11:12:08 +00:00
}
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 ) ) ;
2007-10-06 22:28:14 +00:00
return false ;
2005-11-25 11:12:08 +00:00
}
2005-12-07 07:28:43 +00:00
status = smb2_logoff ( tree - > session ) ;
2005-11-25 11:05:21 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Logoff failed - %s \n " , nt_errstr ( status ) ) ;
2007-10-06 22:28:14 +00:00
return false ;
2005-11-25 11:05:21 +00:00
}
2008-06-09 21:41:55 +02:00
req = smb2_logoff_send ( tree - > session ) ;
if ( ! req ) {
printf ( " smb2_logoff_send() failed \n " ) ;
return false ;
}
req - > session = NULL ;
status = smb2_logoff_recv ( req ) ;
2005-11-25 11:05:21 +00:00
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_USER_SESSION_DELETED ) ) {
printf ( " Logoff should have disabled session - %s \n " , nt_errstr ( status ) ) ;
2007-10-06 22:28:14 +00:00
return false ;
2005-11-25 11:05:21 +00:00
}
2005-12-07 07:28:43 +00:00
status = smb2_keepalive ( tree - > session - > transport ) ;
2005-11-25 11:51:47 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " keepalive failed? - %s \n " , nt_errstr ( status ) ) ;
2007-10-06 22:28:14 +00:00
return false ;
2005-11-25 11:51:47 +00:00
}
2005-11-11 04:46:48 +00:00
talloc_free ( mem_ctx ) ;
2007-10-06 22:28:14 +00:00
return true ;
2005-11-11 04:46:48 +00:00
}