2005-11-12 05:37:51 +03:00
/*
Unix SMB / CIFS implementation .
SMB2 opcode scanner
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-12 05:37:51 +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-12 05:37:51 +03:00
*/
# include "includes.h"
# include "libcli/smb2/smb2.h"
# include "libcli/smb2/smb2_calls.h"
# include "lib/cmdline/popt_common.h"
2006-03-25 19:01:28 +03:00
# include "torture/torture.h"
2007-12-03 23:25:14 +03:00
# include "param/param.h"
2007-12-10 20:41:19 +03:00
# include "libcli/resolve/resolve.h"
2005-11-12 05:37:51 +03:00
2006-02-04 17:08:24 +03:00
# include "torture/smb2/proto.h"
2005-11-12 05:37:51 +03:00
2005-11-12 10:48:56 +03:00
/*
scan for valid SMB2 getinfo levels
*/
2016-02-22 18:06:51 +03:00
static bool torture_smb2_getinfo_scan ( struct torture_context * tctx )
2005-11-12 10:48:56 +03:00
{
struct smb2_tree * tree ;
NTSTATUS status ;
struct smb2_getinfo io ;
2005-11-17 03:50:42 +03:00
struct smb2_handle fhandle , dhandle ;
2005-11-12 10:48:56 +03:00
int c , i ;
2012-03-02 15:02:18 +04:00
static const char * FNAME = " scan-getinfo.dat " ;
static const char * FNAME2 = " scan-getinfo.dat:2ndstream " ;
static const char * DNAME = " scan-getinfo.dir " ;
static const char * DNAME2 = " scan-getinfo.dir:2ndstream " ;
2016-02-22 18:06:51 +03:00
if ( ! torture_smb2_connection ( tctx , & tree ) ) {
2007-10-07 02:28:14 +04:00
return false ;
2005-11-12 10:48:56 +03:00
}
2016-02-22 17:40:50 +03:00
status = torture_setup_complex_file ( tctx , tree , FNAME ) ;
2005-11-18 12:51:13 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2016-02-22 18:06:51 +03:00
torture_comment ( tctx , " Failed to setup complex file '%s': %s \n " ,
2012-03-02 15:05:59 +04:00
FNAME , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2005-11-12 11:19:39 +03:00
}
2016-02-22 17:40:50 +03:00
torture_setup_complex_file ( tctx , tree , FNAME2 ) ;
2005-11-12 11:19:39 +03:00
2016-02-22 17:40:50 +03:00
status = torture_setup_complex_dir ( tctx , tree , DNAME ) ;
2005-11-18 12:51:13 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2016-02-22 18:06:51 +03:00
torture_comment ( tctx , " Failed to setup complex dir '%s': %s \n " ,
2012-03-02 15:05:59 +04:00
DNAME , nt_errstr ( status ) ) ;
2012-03-02 14:19:48 +04:00
smb2_util_unlink ( tree , FNAME ) ;
2007-10-07 02:28:14 +04:00
return false ;
2005-11-12 10:48:56 +03:00
}
2016-02-22 17:40:50 +03:00
torture_setup_complex_file ( tctx , tree , DNAME2 ) ;
2005-11-12 10:48:56 +03:00
2005-11-17 03:50:42 +03:00
torture_smb2_testfile ( tree , FNAME , & fhandle ) ;
torture_smb2_testdir ( tree , DNAME , & dhandle ) ;
2005-11-12 10:48:56 +03:00
ZERO_STRUCT ( io ) ;
2008-02-14 09:11:36 +03:00
io . in . output_buffer_length = 0xFFFF ;
2005-11-15 07:38:59 +03:00
2005-11-17 03:50:42 +03:00
for ( c = 1 ; c < 5 ; c + + ) {
2005-11-12 10:48:56 +03:00
for ( i = 0 ; i < 0x100 ; i + + ) {
2008-02-14 09:11:36 +03:00
io . in . info_type = c ;
io . in . info_class = i ;
2005-11-17 03:50:42 +03:00
2006-06-20 11:03:53 +04:00
io . in . file . handle = fhandle ;
2016-02-22 18:06:51 +03:00
status = smb2_getinfo ( tree , tctx , & io ) ;
2008-05-31 07:39:34 +04:00
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_INVALID_INFO_CLASS ) ) {
2016-02-22 18:06:51 +03:00
torture_comment ( tctx , " file level 0x%02x:%02x %u is %ld bytes - %s \n " ,
2008-02-14 09:11:36 +03:00
io . in . info_type , io . in . info_class ,
2008-05-31 07:39:34 +04:00
( unsigned ) io . in . info_class ,
2008-02-14 09:11:36 +03:00
( long ) io . out . blob . length , nt_errstr ( status ) ) ;
2005-11-17 03:50:42 +03:00
dump_data ( 1 , io . out . blob . data , io . out . blob . length ) ;
}
2006-06-20 11:03:53 +04:00
io . in . file . handle = dhandle ;
2016-02-22 18:06:51 +03:00
status = smb2_getinfo ( tree , tctx , & io ) ;
2008-05-31 07:39:34 +04:00
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_INVALID_INFO_CLASS ) ) {
2016-02-22 18:06:51 +03:00
torture_comment ( tctx , " dir level 0x%02x:%02x %u is %ld bytes - %s \n " ,
2008-02-14 09:11:36 +03:00
io . in . info_type , io . in . info_class ,
2008-05-31 07:39:34 +04:00
( unsigned ) io . in . info_class ,
2008-02-14 09:11:36 +03:00
( long ) io . out . blob . length , nt_errstr ( status ) ) ;
2005-11-17 03:50:42 +03:00
dump_data ( 1 , io . out . blob . data , io . out . blob . length ) ;
2005-11-12 10:48:56 +03:00
}
}
}
2012-03-02 14:19:48 +04:00
smb2_util_unlink ( tree , FNAME ) ;
smb2_util_rmdir ( tree , DNAME ) ;
2007-10-07 02:28:14 +04:00
return true ;
2005-11-12 10:48:56 +03:00
}
2005-11-18 12:25:25 +03:00
/*
scan for valid SMB2 setinfo levels
*/
2016-02-22 18:06:51 +03:00
static bool torture_smb2_setinfo_scan ( struct torture_context * tctx )
2005-11-18 12:25:25 +03:00
{
2012-03-02 15:02:18 +04:00
static const char * FNAME = " scan-setinfo.dat " ;
static const char * FNAME2 = " scan-setinfo.dat:2ndstream " ;
2005-11-18 12:25:25 +03:00
struct smb2_tree * tree ;
NTSTATUS status ;
struct smb2_setinfo io ;
struct smb2_handle handle ;
int c , i ;
2016-02-22 18:06:51 +03:00
if ( ! torture_smb2_connection ( tctx , & tree ) ) {
2007-10-07 02:28:14 +04:00
return false ;
2005-11-18 12:25:25 +03:00
}
2016-02-22 17:40:50 +03:00
status = torture_setup_complex_file ( tctx , tree , FNAME ) ;
2005-11-18 12:51:13 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2016-02-22 18:06:51 +03:00
torture_comment ( tctx , " Failed to setup complex file '%s': %s \n " ,
2012-03-02 15:05:59 +04:00
FNAME , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2005-11-18 12:25:25 +03:00
}
2016-02-22 17:40:50 +03:00
torture_setup_complex_file ( tctx , tree , FNAME2 ) ;
2005-11-18 12:25:25 +03:00
torture_smb2_testfile ( tree , FNAME , & handle ) ;
ZERO_STRUCT ( io ) ;
2016-02-22 18:06:51 +03:00
io . in . blob = data_blob_talloc_zero ( tctx , 1024 ) ;
2005-11-18 12:25:25 +03:00
for ( c = 1 ; c < 5 ; c + + ) {
for ( i = 0 ; i < 0x100 ; i + + ) {
io . in . level = ( i < < 8 ) | c ;
2006-06-20 11:03:53 +04:00
io . in . file . handle = handle ;
2005-11-18 12:25:25 +03:00
status = smb2_setinfo ( tree , & io ) ;
2008-05-31 07:39:34 +04:00
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_INVALID_INFO_CLASS ) ) {
2016-02-22 18:06:51 +03:00
torture_comment ( tctx , " file level 0x%04x - %s \n " ,
2005-11-18 12:25:25 +03:00
io . in . level , nt_errstr ( status ) ) ;
}
}
}
2012-03-02 14:20:18 +04:00
smb2_util_unlink ( tree , FNAME ) ;
2007-10-07 02:28:14 +04:00
return true ;
2005-11-18 12:25:25 +03:00
}
2005-11-19 09:39:12 +03:00
/*
scan for valid SMB2 scan levels
*/
2016-02-22 18:06:51 +03:00
static bool torture_smb2_find_scan ( struct torture_context * tctx )
2005-11-19 09:39:12 +03:00
{
struct smb2_tree * tree ;
NTSTATUS status ;
struct smb2_find io ;
struct smb2_handle handle ;
int i ;
2016-02-22 18:06:51 +03:00
if ( ! torture_smb2_connection ( tctx , & tree ) ) {
2007-10-07 02:28:14 +04:00
return false ;
2005-11-19 09:39:12 +03:00
}
2016-02-22 18:06:51 +03:00
torture_assert_ntstatus_ok ( tctx ,
smb2_util_roothandle ( tree , & handle ) ,
" Failed to open roothandle " ) ;
2005-11-19 09:39:12 +03:00
ZERO_STRUCT ( io ) ;
2006-05-20 14:46:38 +04:00
io . in . file . handle = handle ;
io . in . pattern = " * " ;
io . in . continue_flags = SMB2_CONTINUE_FLAG_RESTART ;
io . in . max_response_size = 0x10000 ;
2005-11-19 09:39:12 +03:00
for ( i = 1 ; i < 0x100 ; i + + ) {
io . in . level = i ;
2006-05-20 14:46:38 +04:00
io . in . file . handle = handle ;
2016-02-22 18:06:51 +03:00
status = smb2_find ( tree , tctx , & io ) ;
2005-11-19 09:39:12 +03:00
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_INVALID_INFO_CLASS ) & &
! NT_STATUS_EQUAL ( status , NT_STATUS_INVALID_PARAMETER ) & &
! NT_STATUS_EQUAL ( status , NT_STATUS_NOT_SUPPORTED ) ) {
2016-02-22 18:06:51 +03:00
torture_comment ( tctx , " find level 0x%04x is %ld bytes - %s \n " ,
2005-11-30 05:08:15 +03:00
io . in . level , ( long ) io . out . blob . length , nt_errstr ( status ) ) ;
2005-11-19 09:39:12 +03:00
dump_data ( 1 , io . out . blob . data , io . out . blob . length ) ;
}
}
2007-10-07 02:28:14 +04:00
return true ;
2005-11-19 09:39:12 +03:00
}
2005-11-12 05:37:51 +03:00
/*
scan for valid SMB2 opcodes
*/
2016-02-22 18:06:51 +03:00
static bool torture_smb2_scan ( struct torture_context * tctx )
2005-11-12 05:37:51 +03:00
{
TALLOC_CTX * mem_ctx = talloc_new ( NULL ) ;
struct smb2_tree * tree ;
2016-02-22 18:06:51 +03:00
const char * host = torture_setting_string ( tctx , " host " , NULL ) ;
const char * share = torture_setting_string ( tctx , " share " , NULL ) ;
2005-11-12 05:37:51 +03:00
struct cli_credentials * credentials = cmdline_credentials ;
NTSTATUS status ;
int opcode ;
struct smb2_request * req ;
2008-05-30 11:03:54 +04:00
struct smbcli_options options ;
2016-02-22 18:06:51 +03:00
lpcfg_smbcli_options ( tctx - > lp_ctx , & options ) ;
2005-11-12 05:37:51 +03:00
2016-02-22 18:06:51 +03:00
status = smb2_connect ( mem_ctx , host ,
lpcfg_smb_ports ( tctx - > lp_ctx ) ,
share ,
lpcfg_resolve_context ( tctx - > lp_ctx ) ,
credentials , & tree , tctx - > ev , & options ,
lpcfg_socket_options ( tctx - > lp_ctx ) ,
lpcfg_gensec_settings ( tctx , tctx - > lp_ctx ) ) ;
torture_assert_ntstatus_ok ( tctx , status , " Connection failed " ) ;
2005-11-12 05:37:51 +03:00
2008-05-30 11:03:54 +04:00
tree - > session - > transport - > options . request_timeout = 3 ;
2005-11-12 05:37:51 +03:00
for ( opcode = 0 ; opcode < 1000 ; opcode + + ) {
2007-10-07 02:28:14 +04:00
req = smb2_request_init_tree ( tree , opcode , 2 , false , 0 ) ;
2005-11-12 05:37:51 +03:00
SSVAL ( req - > out . body , 0 , 0 ) ;
smb2_transport_send ( req ) ;
if ( ! smb2_request_receive ( req ) ) {
talloc_free ( tree ) ;
2016-02-22 18:06:51 +03:00
status = smb2_connect ( mem_ctx , host ,
lpcfg_smb_ports ( tctx - > lp_ctx ) ,
share ,
lpcfg_resolve_context ( tctx - > lp_ctx ) ,
credentials , & tree , tctx - > ev , & options ,
lpcfg_socket_options ( tctx - > lp_ctx ) ,
lpcfg_gensec_settings ( mem_ctx , tctx - > lp_ctx ) ) ;
torture_assert_ntstatus_ok ( tctx , status , " Connection failed " ) ;
2008-05-30 11:03:54 +04:00
tree - > session - > transport - > options . request_timeout = 3 ;
2005-11-12 05:37:51 +03:00
} else {
status = smb2_request_destroy ( req ) ;
2016-02-22 18:06:51 +03:00
torture_comment ( tctx , " active opcode %4d gave status %s \n " , opcode , nt_errstr ( status ) ) ;
2005-11-12 05:37:51 +03:00
}
}
talloc_free ( mem_ctx ) ;
2007-10-07 02:28:14 +04:00
return true ;
2005-11-12 05:37:51 +03:00
}
2012-03-01 18:59:41 +04:00
2017-04-25 01:42:20 +03:00
struct torture_suite * torture_smb2_scan_init ( TALLOC_CTX * ctx )
2012-03-01 18:59:41 +04:00
{
2017-04-25 01:42:20 +03:00
struct torture_suite * suite = torture_suite_create ( ctx , " scan " ) ;
2012-03-01 18:59:41 +04:00
torture_suite_add_simple_test ( suite , " scan " , torture_smb2_scan ) ;
torture_suite_add_simple_test ( suite , " getinfo " , torture_smb2_getinfo_scan ) ;
torture_suite_add_simple_test ( suite , " setinfo " , torture_smb2_setinfo_scan ) ;
torture_suite_add_simple_test ( suite , " find " , torture_smb2_find_scan ) ;
suite - > description = talloc_strdup ( suite , " scan target (not a test) " ) ;
return suite ;
}