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
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2005-11-11 07:46:48 +03: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 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2005-11-11 07:46:48 +03:00
*/
# include "includes.h"
# include "libcli/smb2/smb2.h"
2005-11-11 08:53:54 +03:00
# include "libcli/smb2/smb2_calls.h"
2006-03-25 19:01:28 +03:00
# include "torture/torture.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
*/
2016-02-22 17:30:26 +03:00
static NTSTATUS torture_smb2_close ( struct torture_context * tctx ,
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 ) ;
2006-05-20 14:46:38 +04:00
io . in . file . handle = handle ;
io . in . flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION ;
2005-11-11 17:04:46 +03:00
status = smb2_close ( tree , & io ) ;
2005-11-11 15:37:16 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2016-02-22 17:30:26 +03:00
torture_comment ( tctx , " close failed - %s \n " , nt_errstr ( status ) ) ;
2005-11-11 17:04:46 +03:00
return status ;
2005-11-11 15:37:16 +03:00
}
2005-11-12 10:48:56 +03:00
if ( DEBUGLVL ( 1 ) ) {
2016-02-22 17:30:26 +03:00
torture_comment ( tctx , " Close gave: \n " ) ;
torture_comment ( tctx , " create_time = %s \n " , nt_time_string ( tmp_ctx , io . out . create_time ) ) ;
torture_comment ( tctx , " access_time = %s \n " , nt_time_string ( tmp_ctx , io . out . access_time ) ) ;
torture_comment ( tctx , " write_time = %s \n " , nt_time_string ( tmp_ctx , io . out . write_time ) ) ;
torture_comment ( tctx , " change_time = %s \n " , nt_time_string ( tmp_ctx , io . out . change_time ) ) ;
torture_comment ( tctx , " alloc_size = %lld \n " , ( long long ) io . out . alloc_size ) ;
torture_comment ( tctx , " size = %lld \n " , ( long long ) io . out . size ) ;
torture_comment ( tctx , " file_attr = 0x%x \n " , io . out . file_attr ) ;
2005-11-12 10:48:56 +03:00
}
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
*/
2007-12-02 23:32:08 +03:00
static NTSTATUS torture_smb2_write ( struct torture_context * tctx , struct smb2_tree * tree , struct smb2_handle handle )
2005-11-14 08:10:09 +03:00
{
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 ;
2011-10-12 20:34:26 +04:00
uint32_t size = torture_setting_int ( tctx , " smb2maxwrite " , 64 * 1024 ) ;
2005-11-14 08:10:09 +03:00
2011-10-12 20:34:26 +04:00
data = data_blob_talloc ( tree , NULL , size ) ;
if ( size ! = data . length ) {
2016-02-22 17:30:26 +03:00
torture_comment ( tctx , " data_blob_talloc(%u) failed \n " , ( unsigned int ) size ) ;
2011-10-12 20:34:26 +04:00
return NT_STATUS_NO_MEMORY ;
2005-11-16 09:39:57 +03:00
}
2011-10-12 20:34:26 +04:00
2005-11-16 09:39:57 +03:00
for ( i = 0 ; i < data . length ; i + + ) {
data . data [ i ] = i ;
}
2005-11-14 08:10:09 +03:00
ZERO_STRUCT ( w ) ;
2006-05-20 14:46:38 +04:00
w . in . file . handle = handle ;
2005-11-14 08:10:09 +03:00
w . in . offset = 0 ;
w . in . data = data ;
2005-11-15 07:38:59 +03:00
status = smb2_write ( tree , & w ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2016-02-22 17:30:26 +03:00
torture_comment ( tctx , " write 1 failed - %s \n " , nt_errstr ( status ) ) ;
2005-11-15 07:38:59 +03:00
return status ;
}
2016-02-22 17:40:50 +03:00
torture_smb2_all_info ( tctx , tree , handle ) ;
2005-11-15 07:38:59 +03:00
2005-11-14 08:10:09 +03:00
status = smb2_write ( tree , & w ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2016-02-22 17:30:26 +03:00
torture_comment ( tctx , " write 2 failed - %s \n " , nt_errstr ( status ) ) ;
2005-11-14 08:10:09 +03:00
return status ;
}
2016-02-22 17:40:50 +03:00
torture_smb2_all_info ( tctx , tree , handle ) ;
2005-11-15 07:38:59 +03:00
2005-11-25 14:33:57 +03:00
ZERO_STRUCT ( f ) ;
2006-05-20 14:46:38 +04:00
f . in . file . handle = handle ;
2005-11-25 14:33:57 +03:00
status = smb2_flush ( tree , & f ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2016-02-22 17:30:26 +03:00
torture_comment ( tctx , " flush failed - %s \n " , nt_errstr ( status ) ) ;
2005-11-25 14:33:57 +03:00
return status ;
}
2005-11-14 08:10:09 +03:00
ZERO_STRUCT ( r ) ;
2006-05-20 14:46:38 +04:00
r . in . file . handle = handle ;
2005-11-14 08:10:09 +03:00
r . in . length = data . length ;
r . in . offset = 0 ;
status = smb2_read ( tree , tree , & r ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2016-02-22 17:30:26 +03:00
torture_comment ( tctx , " read failed - %s \n " , nt_errstr ( status ) ) ;
2005-11-14 08:10:09 +03:00
return status ;
}
if ( data . length ! = r . out . data . length | |
memcmp ( data . data , r . out . data . data , data . length ) ! = 0 ) {
2016-02-22 17:30:26 +03:00
torture_comment ( tctx , " read data mismatch \n " ) ;
2005-11-14 08:10:09 +03:00
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
*/
2016-02-26 19:25:58 +03:00
NTSTATUS torture_smb2_createfile ( struct torture_context * tctx ,
struct smb2_tree * tree ,
const char * fname ,
struct smb2_handle * handle )
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 ) ;
2008-02-13 07:05:44 +03: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 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 ) ) {
2016-02-23 01:23:13 +03:00
TALLOC_FREE ( tmp_ctx ) ;
2016-02-22 17:30:26 +03:00
torture_comment ( tctx , " create1 failed - %s \n " , nt_errstr ( status ) ) ;
2016-02-22 18:22:14 +03:00
return status ;
2005-11-11 16:08:31 +03:00
}
2005-11-12 10:48:56 +03:00
if ( DEBUGLVL ( 1 ) ) {
2016-02-22 17:30:26 +03:00
torture_comment ( tctx , " Open gave: \n " ) ;
torture_comment ( tctx , " oplock_flags = 0x%x \n " , io . out . oplock_level ) ;
torture_comment ( tctx , " create_action = 0x%x \n " , io . out . create_action ) ;
torture_comment ( tctx , " create_time = %s \n " , nt_time_string ( tmp_ctx , io . out . create_time ) ) ;
torture_comment ( tctx , " access_time = %s \n " , nt_time_string ( tmp_ctx , io . out . access_time ) ) ;
torture_comment ( tctx , " write_time = %s \n " , nt_time_string ( tmp_ctx , io . out . write_time ) ) ;
torture_comment ( tctx , " change_time = %s \n " , nt_time_string ( tmp_ctx , io . out . change_time ) ) ;
torture_comment ( tctx , " alloc_size = %lld \n " , ( long long ) io . out . alloc_size ) ;
torture_comment ( tctx , " size = %lld \n " , ( long long ) io . out . size ) ;
torture_comment ( tctx , " file_attr = 0x%x \n " , io . out . file_attr ) ;
torture_comment ( tctx , " handle = %016llx%016llx \n " ,
2006-05-20 14:46:38 +04:00
( long long ) io . out . file . handle . data [ 0 ] ,
( long long ) io . out . file . handle . data [ 1 ] ) ;
2005-11-12 10:48:56 +03:00
}
2005-11-11 16:08:31 +03:00
talloc_free ( tmp_ctx ) ;
2016-02-22 18:22:14 +03:00
* handle = io . out . file . handle ;
return NT_STATUS_OK ;
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
*/
2016-02-22 17:30:26 +03:00
bool torture_smb2_connect ( struct torture_context * tctx )
2005-11-11 08:53:54 +03:00
{
TALLOC_CTX * mem_ctx = talloc_new ( NULL ) ;
2005-11-11 12:11:51 +03:00
struct smb2_tree * tree ;
2008-06-09 23:41:55 +04:00
struct smb2_request * req ;
2005-11-11 16:08:31 +03:00
struct smb2_handle h1 , h2 ;
2005-11-25 14:05:21 +03:00
NTSTATUS status ;
2016-02-22 16:32:44 +03:00
bool ok ;
2005-11-11 08:53:54 +03:00
2016-02-22 17:30:26 +03:00
ok = torture_smb2_connection ( tctx , & tree ) ;
torture_assert ( tctx , ok , " torture_smb2_connection failed " ) ;
2005-11-12 04:08:43 +03:00
2009-07-08 12:09:54 +04:00
smb2_util_unlink ( tree , " test9.dat " ) ;
2016-02-22 17:30:26 +03:00
status = torture_smb2_createfile ( tctx , tree , " test9.dat " , & h1 ) ;
torture_assert_ntstatus_ok ( tctx , status , " create failed " ) ;
2016-02-22 18:22:14 +03:00
2016-02-22 17:30:26 +03:00
status = torture_smb2_createfile ( tctx , tree , " test9.dat " , & h2 ) ;
torture_assert_ntstatus_ok ( tctx , status , " create failed " ) ;
2016-02-22 16:32:44 +03:00
2016-02-22 17:30:26 +03:00
status = torture_smb2_write ( tctx , tree , h1 ) ;
torture_assert_ntstatus_ok ( tctx , status , " write failed " ) ;
2016-02-22 16:32:44 +03:00
2016-02-22 17:30:26 +03:00
status = torture_smb2_close ( tctx , tree , h1 ) ;
torture_assert_ntstatus_ok ( tctx , status , " close failed " ) ;
2016-02-22 16:32:44 +03:00
2016-02-22 17:30:26 +03:00
status = torture_smb2_close ( tctx , tree , h2 ) ;
torture_assert_ntstatus_ok ( tctx , status , " close failed " ) ;
2005-11-11 08:53:54 +03:00
2006-05-22 18:18:17 +04:00
status = smb2_util_close ( tree , h1 ) ;
2016-02-22 17:30:26 +03:00
torture_assert_ntstatus_equal ( tctx , status , NT_STATUS_FILE_CLOSED ,
2016-02-22 16:32:44 +03:00
" close should have closed the handle " ) ;
2006-05-22 18:18:17 +04:00
2005-11-25 14:12:08 +03:00
status = smb2_tdis ( tree ) ;
2016-02-22 17:30:26 +03:00
torture_assert_ntstatus_ok ( tctx , status , " tdis failed " ) ;
2005-11-25 14:12:08 +03:00
status = smb2_tdis ( tree ) ;
2016-02-22 17:30:26 +03:00
torture_assert_ntstatus_equal ( tctx , status ,
2016-02-22 16:32:44 +03:00
NT_STATUS_NETWORK_NAME_DELETED ,
" tdis should have closed the tcon " ) ;
2005-11-25 14:12:08 +03:00
2005-12-07 10:28:43 +03:00
status = smb2_logoff ( tree - > session ) ;
2016-02-22 17:30:26 +03:00
torture_assert_ntstatus_ok ( tctx , status , " logoff failed " ) ;
2005-11-25 14:05:21 +03:00
2008-06-09 23:41:55 +04:00
req = smb2_logoff_send ( tree - > session ) ;
2016-02-22 17:30:26 +03:00
torture_assert_not_null ( tctx , req , " smb2_logoff_send failed " ) ;
2008-06-09 23:41:55 +04:00
req - > session = NULL ;
status = smb2_logoff_recv ( req ) ;
2016-02-22 17:30:26 +03:00
torture_assert_ntstatus_equal ( tctx , status , NT_STATUS_USER_SESSION_DELETED ,
2016-02-22 16:32:44 +03:00
" logoff should have disabled session " ) ;
2005-11-25 14:05:21 +03:00
2005-12-07 10:28:43 +03:00
status = smb2_keepalive ( tree - > session - > transport ) ;
2016-02-22 17:30:26 +03:00
torture_assert_ntstatus_ok ( tctx , status , " keepalive failed " ) ;
2005-11-25 14:51:47 +03:00
2005-11-11 07:46:48 +03:00
talloc_free ( mem_ctx ) ;
2007-10-07 02:28:14 +04:00
return true ;
2005-11-11 07:46:48 +03:00
}