2005-11-15 07:38:59 +03:00
/*
Unix SMB / CIFS implementation .
SMB2 getinfo test suite
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-15 07:38:59 +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-15 07:38:59 +03:00
*/
# include "includes.h"
# include "libcli/smb2/smb2.h"
# 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-15 07:38:59 +03:00
static struct {
const char * name ;
uint16_t level ;
NTSTATUS fstatus ;
NTSTATUS dstatus ;
2005-11-17 14:06:13 +03:00
union smb_fileinfo finfo ;
union smb_fileinfo dinfo ;
} file_levels [ ] = {
2005-11-15 07:38:59 +03:00
# define LEVEL(x) #x, x
2005-11-17 14:06:13 +03:00
{ LEVEL ( RAW_FILEINFO_BASIC_INFORMATION ) } ,
{ LEVEL ( RAW_FILEINFO_STANDARD_INFORMATION ) } ,
{ LEVEL ( RAW_FILEINFO_INTERNAL_INFORMATION ) } ,
{ LEVEL ( RAW_FILEINFO_EA_INFORMATION ) } ,
{ LEVEL ( RAW_FILEINFO_ACCESS_INFORMATION ) } ,
{ LEVEL ( RAW_FILEINFO_POSITION_INFORMATION ) } ,
{ LEVEL ( RAW_FILEINFO_MODE_INFORMATION ) } ,
{ LEVEL ( RAW_FILEINFO_ALIGNMENT_INFORMATION ) } ,
{ LEVEL ( RAW_FILEINFO_ALL_INFORMATION ) } ,
{ LEVEL ( RAW_FILEINFO_ALT_NAME_INFORMATION ) } ,
{ LEVEL ( RAW_FILEINFO_STREAM_INFORMATION ) } ,
{ LEVEL ( RAW_FILEINFO_COMPRESSION_INFORMATION ) } ,
{ LEVEL ( RAW_FILEINFO_NETWORK_OPEN_INFORMATION ) } ,
{ LEVEL ( RAW_FILEINFO_ATTRIBUTE_TAG_INFORMATION ) } ,
2008-05-22 08:50:36 +04:00
/*
{ LEVEL ( RAW_FILEINFO_SMB2_ALL_EAS ) } ,
*/
2005-11-17 14:06:13 +03:00
{ LEVEL ( RAW_FILEINFO_SMB2_ALL_INFORMATION ) } ,
{ LEVEL ( RAW_FILEINFO_SEC_DESC ) }
} ;
static struct {
const char * name ;
uint16_t level ;
NTSTATUS status ;
union smb_fsinfo info ;
} fs_levels [ ] = {
{ LEVEL ( RAW_QFS_VOLUME_INFORMATION ) } ,
{ LEVEL ( RAW_QFS_SIZE_INFORMATION ) } ,
{ LEVEL ( RAW_QFS_DEVICE_INFORMATION ) } ,
{ LEVEL ( RAW_QFS_ATTRIBUTE_INFORMATION ) } ,
{ LEVEL ( RAW_QFS_QUOTA_INFORMATION ) } ,
{ LEVEL ( RAW_QFS_FULL_SIZE_INFORMATION ) } ,
{ LEVEL ( RAW_QFS_OBJECTID_INFORMATION ) }
2005-11-15 07:38:59 +03:00
} ;
# define FNAME "testsmb2_file.dat"
# define DNAME "testsmb2_dir"
2005-11-17 14:06:13 +03:00
/*
test fileinfo levels
2005-11-15 07:38:59 +03:00
*/
2007-12-03 17:53:17 +03:00
static bool torture_smb2_fileinfo ( struct torture_context * tctx , struct smb2_tree * tree )
2005-11-15 07:38:59 +03:00
{
struct smb2_handle hfile , hdir ;
NTSTATUS status ;
int i ;
status = torture_smb2_testfile ( tree , FNAME , & hfile ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-02-18 06:55:30 +03:00
printf ( __location__ " Unable to create test file '%s' - %s \n " , FNAME , nt_errstr ( status ) ) ;
2005-11-15 07:38:59 +03:00
goto failed ;
}
status = torture_smb2_testdir ( tree , DNAME , & hdir ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-02-18 06:55:30 +03:00
printf ( __location__ " Unable to create test directory '%s' - %s \n " , DNAME , nt_errstr ( status ) ) ;
2005-11-15 07:38:59 +03:00
goto failed ;
}
2005-11-19 08:55:08 +03:00
printf ( " Testing file info levels \n " ) ;
2005-11-15 07:38:59 +03:00
torture_smb2_all_info ( tree , hfile ) ;
torture_smb2_all_info ( tree , hdir ) ;
2005-11-17 14:06:13 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( file_levels ) ; i + + ) {
if ( file_levels [ i ] . level = = RAW_FILEINFO_SEC_DESC ) {
2006-03-10 23:49:20 +03:00
file_levels [ i ] . finfo . query_secdesc . in . secinfo_flags = 0x7 ;
file_levels [ i ] . dinfo . query_secdesc . in . secinfo_flags = 0x7 ;
2005-11-15 07:38:59 +03:00
}
2005-11-19 08:55:08 +03:00
if ( file_levels [ i ] . level = = RAW_FILEINFO_SMB2_ALL_EAS ) {
2006-03-10 23:49:20 +03:00
file_levels [ i ] . finfo . all_eas . in . continue_flags =
2005-11-19 09:39:12 +03:00
SMB2_CONTINUE_FLAG_RESTART ;
2006-03-10 23:49:20 +03:00
file_levels [ i ] . dinfo . all_eas . in . continue_flags =
2005-11-19 09:39:12 +03:00
SMB2_CONTINUE_FLAG_RESTART ;
2005-11-19 08:55:08 +03:00
}
2005-11-17 14:06:13 +03:00
file_levels [ i ] . finfo . generic . level = file_levels [ i ] . level ;
2006-03-13 01:48:25 +03:00
file_levels [ i ] . finfo . generic . in . file . handle = hfile ;
2005-11-17 14:06:13 +03:00
file_levels [ i ] . fstatus = smb2_getinfo_file ( tree , tree , & file_levels [ i ] . finfo ) ;
if ( ! NT_STATUS_IS_OK ( file_levels [ i ] . fstatus ) ) {
2006-07-01 18:21:21 +04:00
printf ( " (%s) %s failed on file - %s \n " , __location__ ,
file_levels [ i ] . name , nt_errstr ( file_levels [ i ] . fstatus ) ) ;
goto failed ;
2005-11-17 14:06:13 +03:00
}
file_levels [ i ] . dinfo . generic . level = file_levels [ i ] . level ;
2006-03-13 01:48:25 +03:00
file_levels [ i ] . dinfo . generic . in . file . handle = hdir ;
2005-11-17 14:06:13 +03:00
file_levels [ i ] . dstatus = smb2_getinfo_file ( tree , tree , & file_levels [ i ] . dinfo ) ;
if ( ! NT_STATUS_IS_OK ( file_levels [ i ] . dstatus ) ) {
2006-07-01 18:21:21 +04:00
printf ( " (%s) %s failed on dir - %s \n " , __location__ ,
file_levels [ i ] . name , nt_errstr ( file_levels [ i ] . dstatus ) ) ;
goto failed ;
2005-11-15 07:38:59 +03:00
}
}
2007-10-07 02:28:14 +04:00
return true ;
2005-11-15 07:38:59 +03:00
failed :
2007-10-07 02:28:14 +04:00
return false ;
2005-11-15 07:38:59 +03:00
}
2005-11-17 14:06:13 +03:00
/*
test fsinfo levels
*/
2007-10-07 02:28:14 +04:00
static bool torture_smb2_fsinfo ( struct smb2_tree * tree )
2005-11-17 14:06:13 +03:00
{
int i ;
NTSTATUS status ;
struct smb2_handle handle ;
2005-11-19 08:55:08 +03:00
printf ( " Testing fsinfo levels \n " ) ;
status = smb2_util_roothandle ( tree , & handle ) ;
2005-11-17 14:06:13 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-02-18 06:55:30 +03:00
printf ( __location__ " Unable to create root handle - %s \n " , nt_errstr ( status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2005-11-17 14:06:13 +03:00
}
for ( i = 0 ; i < ARRAY_SIZE ( fs_levels ) ; i + + ) {
fs_levels [ i ] . info . generic . level = fs_levels [ i ] . level ;
fs_levels [ i ] . info . generic . handle = handle ;
fs_levels [ i ] . status = smb2_getinfo_fs ( tree , tree , & fs_levels [ i ] . info ) ;
if ( ! NT_STATUS_IS_OK ( fs_levels [ i ] . status ) ) {
printf ( " %s failed - %s \n " , fs_levels [ i ] . name , nt_errstr ( fs_levels [ i ] . status ) ) ;
2007-10-07 02:28:14 +04:00
return false ;
2005-11-17 14:06:13 +03:00
}
}
2007-10-07 02:28:14 +04:00
return true ;
2005-11-17 14:06:13 +03:00
}
2008-05-31 07:39:51 +04:00
/*
test for buffer size handling
*/
static bool torture_smb2_buffercheck ( struct smb2_tree * tree )
{
NTSTATUS status ;
struct smb2_handle handle ;
struct smb2_getinfo b ;
printf ( " Testing buffer size handling \n " ) ;
status = smb2_util_roothandle ( tree , & handle ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( __location__ " Unable to create root handle - %s \n " , nt_errstr ( status ) ) ;
return false ;
}
ZERO_STRUCT ( b ) ;
b . in . info_type = SMB2_GETINFO_FS ;
b . in . info_class = 1 ;
b . in . output_buffer_length = 0x1 ;
b . in . input_buffer_length = 0 ;
b . in . file . handle = handle ;
status = smb2_getinfo ( tree , tree , & b ) ;
if ( ! NT_STATUS_EQUAL ( status , NT_STATUS_INFO_LENGTH_MISMATCH ) ) {
printf ( __location__ " Wrong error code for small buffer %s \n " ,
nt_errstr ( status ) ) ;
return false ;
}
return true ;
}
2005-11-17 14:06:13 +03:00
/* basic testing of all SMB2 getinfo levels
*/
2007-10-07 02:28:14 +04:00
bool torture_smb2_getinfo ( struct torture_context * torture )
2005-11-17 14:06:13 +03:00
{
TALLOC_CTX * mem_ctx = talloc_new ( NULL ) ;
struct smb2_tree * tree ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2005-11-18 12:51:13 +03:00
NTSTATUS status ;
2005-11-17 14:06:13 +03:00
2007-12-03 02:28:22 +03:00
if ( ! torture_smb2_connection ( torture , & tree ) ) {
2007-10-07 02:28:14 +04:00
return false ;
2005-11-17 14:06:13 +03:00
}
2008-05-22 08:50:36 +04:00
smb2_deltree ( tree , FNAME ) ;
smb2_deltree ( tree , DNAME ) ;
2005-11-18 12:51:13 +03:00
status = torture_setup_complex_file ( tree , FNAME ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-10-07 02:28:14 +04:00
return false ;
2005-11-18 12:51:13 +03:00
}
torture_setup_complex_file ( tree , FNAME " :streamtwo " ) ;
status = torture_setup_complex_dir ( tree , DNAME ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-10-07 02:28:14 +04:00
return false ;
2005-11-18 12:51:13 +03:00
}
torture_setup_complex_file ( tree , DNAME " :streamtwo " ) ;
2005-11-17 14:06:13 +03:00
2007-12-03 17:53:17 +03:00
ret & = torture_smb2_fileinfo ( torture , tree ) ;
2005-11-17 14:06:13 +03:00
ret & = torture_smb2_fsinfo ( tree ) ;
2008-05-31 07:39:51 +04:00
ret & = torture_smb2_buffercheck ( tree ) ;
2005-11-17 14:06:13 +03:00
talloc_free ( mem_ctx ) ;
return ret ;
}