2003-08-13 05:53:07 +04:00
/*
Unix SMB / CIFS implementation .
basic raw test suite for oplocks
Copyright ( C ) Andrew Tridgell 2003
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
2003-08-13 05:53:07 +04: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/>.
2003-08-13 05:53:07 +04:00
*/
# include "includes.h"
2006-01-03 16:41:17 +03:00
# include "torture/torture.h"
2006-03-16 03:23:11 +03:00
# include "librpc/gen_ndr/security.h"
2005-12-28 18:38:36 +03:00
# include "libcli/raw/libcliraw.h"
2006-01-03 18:40:05 +03:00
# include "libcli/libcli.h"
2006-03-17 20:59:58 +03:00
# include "torture/util.h"
2006-04-10 08:51:52 +04:00
# include "lib/events/events.h"
2003-08-13 05:53:07 +04:00
# define CHECK_VAL(v, correct) do { \
if ( ( v ) ! = ( correct ) ) { \
2007-07-25 13:57:14 +04:00
torture_comment ( tctx , " (%s): wrong value for %s got 0x%x - should be 0x%x \n " , \
__location__ , # v , ( int ) v , ( int ) correct ) ; \
2003-08-13 05:53:07 +04:00
ret = False ; \
} } while ( 0 )
2007-03-06 00:28:55 +03:00
# define CHECK_STATUS(tctx, status, correct) do { \
2003-08-13 05:53:07 +04:00
if ( ! NT_STATUS_EQUAL ( status , correct ) ) { \
2007-03-06 00:28:55 +03:00
torture_result ( tctx , TORTURE_FAIL , __location__ " : Incorrect status %s - should be %s " , \
nt_errstr ( status ) , nt_errstr ( correct ) ) ; \
2003-08-13 05:53:07 +04:00
ret = False ; \
goto done ; \
} } while ( 0 )
static struct {
int fnum ;
2004-05-29 12:11:46 +04:00
uint8_t level ;
2003-08-13 05:53:07 +04:00
int count ;
2005-12-29 01:18:45 +03:00
int failures ;
2003-08-13 05:53:07 +04:00
} break_info ;
2007-05-25 17:03:33 +04:00
# define BASEDIR "\\test_oplock"
2006-04-10 08:51:52 +04:00
2003-08-13 05:53:07 +04:00
/*
2006-04-11 08:40:11 +04:00
a handler function for oplock break requests . Ack it as a break to level II if possible
2003-08-13 05:53:07 +04:00
*/
2006-04-11 08:40:11 +04:00
static BOOL oplock_handler_ack_to_levelII ( struct smbcli_transport * transport , uint16_t tid ,
uint16_t fnum , uint8_t level , void * private )
2003-08-13 05:53:07 +04:00
{
2004-08-04 17:23:35 +04:00
struct smbcli_tree * tree = private ;
2003-08-13 05:53:07 +04:00
break_info . fnum = fnum ;
break_info . level = level ;
break_info . count + + ;
2006-04-11 08:40:11 +04:00
printf ( " Acking to level II in oplock handler \n " ) ;
2003-08-13 05:53:07 +04:00
2004-08-04 17:23:35 +04:00
return smbcli_oplock_ack ( tree , fnum , level ) ;
2003-08-13 05:53:07 +04:00
}
2006-04-11 08:40:11 +04:00
/*
a handler function for oplock break requests . Ack it as a break to none
*/
static BOOL oplock_handler_ack_to_none ( struct smbcli_transport * transport , uint16_t tid ,
uint16_t fnum , uint8_t level ,
void * private )
{
struct smbcli_tree * tree = private ;
break_info . fnum = fnum ;
break_info . level = level ;
break_info . count + + ;
printf ( " Acking to none in oplock handler \n " ) ;
return smbcli_oplock_ack ( tree , fnum , OPLOCK_BREAK_TO_NONE ) ;
}
2005-12-29 01:18:45 +03:00
static void oplock_handler_close_recv ( struct smbcli_request * req )
{
NTSTATUS status ;
status = smbcli_request_simple_recv ( req ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " close failed in oplock_handler_close \n " ) ;
break_info . failures + + ;
}
}
2003-08-13 05:53:07 +04:00
/*
a handler function for oplock break requests - close the file
*/
2006-04-11 08:40:11 +04:00
static BOOL oplock_handler_close ( struct smbcli_transport * transport , uint16_t tid ,
uint16_t fnum , uint8_t level , void * private )
2003-08-13 05:53:07 +04:00
{
union smb_close io ;
2004-08-04 17:23:35 +04:00
struct smbcli_tree * tree = private ;
2005-12-29 01:18:45 +03:00
struct smbcli_request * req ;
2003-08-13 05:53:07 +04:00
break_info . fnum = fnum ;
break_info . level = level ;
break_info . count + + ;
io . close . level = RAW_CLOSE_CLOSE ;
2006-03-13 01:48:25 +03:00
io . close . in . file . fnum = fnum ;
2003-08-13 05:53:07 +04:00
io . close . in . write_time = 0 ;
2005-12-29 01:18:45 +03:00
req = smb_raw_close_send ( tree , & io ) ;
if ( req = = NULL ) {
printf ( " failed to send close in oplock_handler_close \n " ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
2005-12-29 01:18:45 +03:00
req - > async . fn = oplock_handler_close_recv ;
req - > async . private = NULL ;
2003-08-13 05:53:07 +04:00
return True ;
}
2007-05-25 17:03:33 +04:00
static bool test_raw_oplock_normal ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
2003-08-13 05:53:07 +04:00
{
2007-05-25 17:03:33 +04:00
const char * fname = BASEDIR " \\ test_normal.dat " ;
2003-08-13 05:53:07 +04:00
NTSTATUS status ;
2007-05-25 17:03:33 +04:00
bool ret = true ;
2003-08-13 05:53:07 +04:00
union smb_open io ;
2006-03-10 23:49:20 +03:00
union smb_unlink unl ;
2007-05-25 17:03:33 +04:00
uint16_t fnum = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
2003-08-13 05:53:07 +04:00
/* cleanup */
2006-07-19 20:44:50 +04:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
2006-07-19 20:44:50 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
2003-08-13 05:53:07 +04:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
2004-12-02 07:37:36 +03:00
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
2003-08-13 05:53:07 +04:00
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " open a file with a normal oplock \n " ) ;
2003-08-13 05:53:07 +04:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-13 01:48:25 +03:00
fnum = io . ntcreatex . out . file . fnum ;
2003-08-13 05:53:07 +04:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , EXCLUSIVE_OPLOCK_RETURN ) ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " a 2nd open should not cause a break \n " ) ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2006-04-10 10:06:26 +04:00
CHECK_VAL ( break_info . count , 0 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " unlink it - should also be no break \n " ) ;
2006-03-10 23:49:20 +03:00
unl . unlink . in . pattern = fname ;
unl . unlink . in . attrib = 0 ;
2006-07-19 20:44:50 +04:00
status = smb_raw_unlink ( cli2 - > tree , & unl ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2003-08-13 05:53:07 +04:00
CHECK_VAL ( break_info . count , 0 ) ;
2005-12-29 01:18:45 +03:00
CHECK_VAL ( break_info . failures , 0 ) ;
2003-08-13 05:53:07 +04:00
2006-07-19 20:44:50 +04:00
smbcli_close ( cli1 - > tree , fnum ) ;
2003-08-13 05:53:07 +04:00
2007-05-25 17:03:33 +04:00
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
static bool test_raw_oplock_batch1 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch1.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_unlink unl ;
uint16_t fnum = 0 ;
char c = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname ) ;
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
2003-08-13 05:53:07 +04:00
/*
with a batch oplock we get a break
*/
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " open with batch oplock \n " ) ;
2003-08-13 05:53:07 +04:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-13 01:48:25 +03:00
fnum = io . ntcreatex . out . file . fnum ;
2003-08-13 05:53:07 +04:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " unlink should generate a break \n " ) ;
2006-03-10 23:49:20 +03:00
unl . unlink . in . pattern = fname ;
unl . unlink . in . attrib = 0 ;
2006-07-19 20:44:50 +04:00
status = smb_raw_unlink ( cli2 - > tree , & unl ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2003-08-13 05:53:07 +04:00
2006-04-11 08:40:11 +04:00
CHECK_VAL ( break_info . count , 1 ) ;
2003-08-13 05:53:07 +04:00
CHECK_VAL ( break_info . fnum , fnum ) ;
2006-04-11 08:40:11 +04:00
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " 2nd unlink should not generate a break \n " ) ;
2006-04-11 08:40:11 +04:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 20:44:50 +04:00
status = smb_raw_unlink ( cli2 - > tree , & unl ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2006-04-11 08:40:11 +04:00
CHECK_VAL ( break_info . count , 0 ) ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " writing should generate a self break to none \n " ) ;
2006-07-19 20:44:50 +04:00
smbcli_write ( cli1 - > tree , fnum , 0 , & c , 0 , 1 ) ;
2006-04-11 08:40:11 +04:00
msleep ( 100 ) ;
2006-07-19 20:44:50 +04:00
smbcli_write ( cli1 - > tree , fnum , 0 , & c , 1 , 1 ) ;
2006-04-11 08:40:11 +04:00
2003-08-13 05:53:07 +04:00
CHECK_VAL ( break_info . count , 1 ) ;
2006-04-11 08:40:11 +04:00
CHECK_VAL ( break_info . fnum , fnum ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_NONE ) ;
2005-12-29 01:18:45 +03:00
CHECK_VAL ( break_info . failures , 0 ) ;
2003-08-13 05:53:07 +04:00
2006-07-19 20:44:50 +04:00
smbcli_close ( cli1 - > tree , fnum ) ;
2003-08-13 05:53:07 +04:00
2007-05-25 17:03:33 +04:00
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
static bool test_raw_oplock_batch2 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch2.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_unlink unl ;
uint16_t fnum = 0 ;
char c = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname ) ;
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
2006-04-11 08:40:11 +04:00
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " open with batch oplock \n " ) ;
2006-04-11 08:40:11 +04:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-04-11 08:40:11 +04:00
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " unlink should generate a break, which we ack as break to none \n " ) ;
2006-07-19 20:44:50 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_none , cli1 - > tree ) ;
2006-04-11 08:40:11 +04:00
unl . unlink . in . pattern = fname ;
unl . unlink . in . attrib = 0 ;
2006-07-19 20:44:50 +04:00
status = smb_raw_unlink ( cli2 - > tree , & unl ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2006-04-11 08:40:11 +04:00
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . fnum , fnum ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " 2nd unlink should not generate a break \n " ) ;
2006-04-11 08:40:11 +04:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 20:44:50 +04:00
status = smb_raw_unlink ( cli2 - > tree , & unl ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2006-04-11 08:40:11 +04:00
CHECK_VAL ( break_info . count , 0 ) ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " writing should not generate a break \n " ) ;
2006-07-19 20:44:50 +04:00
smbcli_write ( cli1 - > tree , fnum , 0 , & c , 0 , 1 ) ;
2006-04-11 08:40:11 +04:00
msleep ( 100 ) ;
2006-07-19 20:44:50 +04:00
smbcli_write ( cli1 - > tree , fnum , 0 , & c , 1 , 1 ) ;
2006-04-11 08:40:11 +04:00
CHECK_VAL ( break_info . count , 0 ) ;
2006-07-19 20:44:50 +04:00
smbcli_close ( cli1 - > tree , fnum ) ;
2006-04-11 08:40:11 +04:00
2007-05-25 17:03:33 +04:00
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
static bool test_raw_oplock_batch3 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch3.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_unlink unl ;
uint16_t fnum = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname ) ;
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " if we close on break then the unlink can succeed \n " ) ;
2003-08-13 05:53:07 +04:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 20:44:50 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_close , cli1 - > tree ) ;
2003-08-13 05:53:07 +04:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-13 01:48:25 +03:00
fnum = io . ntcreatex . out . file . fnum ;
2003-08-13 05:53:07 +04:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
2006-03-10 23:49:20 +03:00
unl . unlink . in . pattern = fname ;
unl . unlink . in . attrib = 0 ;
2003-08-13 05:53:07 +04:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 20:44:50 +04:00
status = smb_raw_unlink ( cli2 - > tree , & unl ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2003-08-13 05:53:07 +04:00
2006-04-11 08:40:11 +04:00
CHECK_VAL ( break_info . count , 1 ) ;
2003-08-13 05:53:07 +04:00
CHECK_VAL ( break_info . fnum , fnum ) ;
2004-05-30 12:12:17 +04:00
CHECK_VAL ( break_info . level , 1 ) ;
2005-12-29 01:18:45 +03:00
CHECK_VAL ( break_info . failures , 0 ) ;
2003-08-13 05:53:07 +04:00
2007-05-25 17:03:33 +04:00
smbcli_close ( cli1 - > tree , fnum ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
static bool test_raw_oplock_batch4 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch4.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_read rd ;
uint16_t fnum = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname ) ;
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " a self read should not cause a break \n " ) ;
2003-08-13 05:53:07 +04:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 20:44:50 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
2003-08-13 05:53:07 +04:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-13 01:48:25 +03:00
fnum = io . ntcreatex . out . file . fnum ;
2003-08-13 05:53:07 +04:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
rd . read . level = RAW_READ_READ ;
2006-03-13 01:48:25 +03:00
rd . read . in . file . fnum = fnum ;
2003-08-13 05:53:07 +04:00
rd . read . in . count = 1 ;
rd . read . in . offset = 0 ;
rd . read . in . remaining = 0 ;
2006-07-19 20:44:50 +04:00
status = smb_raw_read ( cli1 - > tree , & rd ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2003-08-13 05:53:07 +04:00
CHECK_VAL ( break_info . count , 0 ) ;
2005-12-29 01:18:45 +03:00
CHECK_VAL ( break_info . failures , 0 ) ;
2003-08-13 05:53:07 +04:00
2007-05-25 17:03:33 +04:00
smbcli_close ( cli1 - > tree , fnum ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
static bool test_raw_oplock_batch5 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch5.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
uint16_t fnum = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname ) ;
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " a 2nd open should give a break \n " ) ;
2003-08-13 05:53:07 +04:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 20:44:50 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
2003-08-13 05:53:07 +04:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-13 01:48:25 +03:00
fnum = io . ntcreatex . out . file . fnum ;
2003-08-13 05:53:07 +04:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2003-08-13 05:53:07 +04:00
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . fnum , fnum ) ;
2004-05-30 12:12:17 +04:00
CHECK_VAL ( break_info . level , 1 ) ;
2005-12-29 01:18:45 +03:00
CHECK_VAL ( break_info . failures , 0 ) ;
2003-08-13 05:53:07 +04:00
2007-05-25 17:03:33 +04:00
smbcli_close ( cli1 - > tree , fnum ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
static bool test_raw_oplock_batch6 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch6.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
uint16_t fnum = 0 , fnum2 = 0 ;
char c = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname ) ;
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
2006-04-11 08:40:11 +04:00
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " a 2nd open should give a break to level II if the first open allowed shared read \n " ) ;
2006-04-11 08:40:11 +04:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 20:44:50 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
smbcli_oplock_handler ( cli2 - > transport , oplock_handler_ack_to_levelII , cli2 - > tree ) ;
2006-04-11 08:40:11 +04:00
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_READ | SEC_RIGHTS_FILE_WRITE ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-04-11 08:40:11 +04:00
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
ZERO_STRUCT ( break_info ) ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-07-19 20:44:50 +04:00
fnum2 = io . ntcreatex . out . file . fnum ;
2006-04-11 08:40:11 +04:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . fnum , fnum ) ;
CHECK_VAL ( break_info . level , 1 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
ZERO_STRUCT ( break_info ) ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " write should trigger a break to none on both \n " ) ;
2006-07-19 20:44:50 +04:00
smbcli_write ( cli1 - > tree , fnum , 0 , & c , 0 , 1 ) ;
2006-04-11 08:40:11 +04:00
msleep ( 100 ) ;
2006-07-19 20:44:50 +04:00
smbcli_write ( cli1 - > tree , fnum , 0 , & c , 1 , 1 ) ;
2006-04-11 08:40:11 +04:00
CHECK_VAL ( break_info . count , 2 ) ;
CHECK_VAL ( break_info . level , 0 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
2006-07-19 20:44:50 +04:00
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
2006-04-11 08:40:11 +04:00
2007-05-25 17:03:33 +04:00
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
static bool test_raw_oplock_batch7 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch7.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
uint16_t fnum = 0 , fnum2 = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname ) ;
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " a 2nd open should get an oplock when we close instead of ack \n " ) ;
2003-08-13 05:53:07 +04:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 20:44:50 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_close , cli1 - > tree ) ;
2003-08-13 05:53:07 +04:00
2006-04-11 08:40:11 +04:00
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
2003-08-13 05:53:07 +04:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-13 01:48:25 +03:00
fnum2 = io . ntcreatex . out . file . fnum ;
2003-08-13 05:53:07 +04:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-13 01:48:25 +03:00
fnum = io . ntcreatex . out . file . fnum ;
2003-08-13 05:53:07 +04:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . fnum , fnum2 ) ;
2004-05-30 12:12:17 +04:00
CHECK_VAL ( break_info . level , 1 ) ;
2005-12-29 01:18:45 +03:00
CHECK_VAL ( break_info . failures , 0 ) ;
2003-08-13 05:53:07 +04:00
2006-07-19 20:44:50 +04:00
smbcli_close ( cli2 - > tree , fnum ) ;
2004-05-25 04:05:51 +04:00
2007-05-25 17:03:33 +04:00
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
static bool test_raw_oplock_batch8 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch8.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
uint16_t fnum = 0 , fnum2 = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname ) ;
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " open with batch oplock \n " ) ;
2004-05-25 04:05:51 +04:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 20:44:50 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
2004-05-25 04:05:51 +04:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-13 01:48:25 +03:00
fnum = io . ntcreatex . out . file . fnum ;
2004-05-25 04:05:51 +04:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
ZERO_STRUCT ( break_info ) ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " second open with attributes only shouldn't cause oplock break \n " ) ;
2004-05-25 04:05:51 +04:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2004-11-30 07:33:27 +03:00
io . ntcreatex . in . access_mask = SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_ATTRIBUTE | SEC_STD_SYNCHRONIZE ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-13 01:48:25 +03:00
fnum2 = io . ntcreatex . out . file . fnum ;
2004-05-25 04:05:51 +04:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , NO_OPLOCK_RETURN ) ;
CHECK_VAL ( break_info . count , 0 ) ;
2005-12-29 01:18:45 +03:00
CHECK_VAL ( break_info . failures , 0 ) ;
2003-08-13 05:53:07 +04:00
2006-07-19 20:44:50 +04:00
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
2007-05-25 17:03:33 +04:00
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
static bool test_raw_oplock_batch9 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch9.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
uint16_t fnum = 0 , fnum2 = 0 ;
char c = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
2006-07-19 20:44:50 +04:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2004-05-30 12:12:17 +04:00
2007-05-25 17:03:33 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " open with attributes only can create file \n " ) ;
2006-07-19 20:44:50 +04:00
2004-05-30 12:12:17 +04:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2004-11-30 07:33:27 +03:00
io . ntcreatex . in . access_mask = SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_ATTRIBUTE | SEC_STD_SYNCHRONIZE ;
2004-05-30 12:12:17 +04:00
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_CREATE ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-13 01:48:25 +03:00
fnum = io . ntcreatex . out . file . fnum ;
2004-05-30 12:12:17 +04:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " Subsequent normal open should break oplock on attribute only open to level II \n " ) ;
2004-05-30 12:12:17 +04:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 20:44:50 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
2004-05-30 12:12:17 +04:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2004-12-02 07:37:36 +03:00
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
2004-05-30 12:12:17 +04:00
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-13 01:48:25 +03:00
fnum2 = io . ntcreatex . out . file . fnum ;
2004-05-30 12:12:17 +04:00
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . fnum , fnum ) ;
2005-12-29 01:18:45 +03:00
CHECK_VAL ( break_info . failures , 0 ) ;
2006-04-11 08:40:11 +04:00
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
2004-05-30 12:12:17 +04:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
2006-07-19 20:44:50 +04:00
smbcli_close ( cli2 - > tree , fnum2 ) ;
2005-07-08 10:29:06 +04:00
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " third oplocked open should grant level2 without break \n " ) ;
2005-07-08 10:29:06 +04:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 20:44:50 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
smbcli_oplock_handler ( cli2 - > transport , oplock_handler_ack_to_levelII , cli2 - > tree ) ;
2005-07-08 10:29:06 +04:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-13 01:48:25 +03:00
fnum2 = io . ntcreatex . out . file . fnum ;
2005-07-08 10:29:06 +04:00
CHECK_VAL ( break_info . count , 0 ) ;
2005-12-29 01:18:45 +03:00
CHECK_VAL ( break_info . failures , 0 ) ;
2005-07-08 10:29:06 +04:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
ZERO_STRUCT ( break_info ) ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " write should trigger a break to none on both \n " ) ;
2006-07-19 20:44:50 +04:00
smbcli_write ( cli2 - > tree , fnum2 , 0 , & c , 0 , 1 ) ;
2005-07-08 10:29:06 +04:00
/* Now the oplock break request comes in. But right now we can't
* answer it . Do another write */
msleep ( 100 ) ;
2006-07-19 20:44:50 +04:00
smbcli_write ( cli2 - > tree , fnum2 , 0 , & c , 1 , 1 ) ;
2005-07-08 10:29:06 +04:00
CHECK_VAL ( break_info . count , 2 ) ;
CHECK_VAL ( break_info . level , 0 ) ;
2005-12-29 01:18:45 +03:00
CHECK_VAL ( break_info . failures , 0 ) ;
2005-07-08 10:29:06 +04:00
2006-07-19 20:44:50 +04:00
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
2005-07-08 10:29:06 +04:00
2007-05-25 17:03:33 +04:00
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
static bool test_raw_oplock_batch10 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch10.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
uint16_t fnum = 0 , fnum2 = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname ) ;
2006-07-19 20:44:50 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
2005-07-08 10:29:06 +04:00
2007-05-25 17:03:33 +04:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
torture_comment ( tctx , " Open with oplock after a non-oplock open should grant level2 \n " ) ;
ZERO_STRUCT ( break_info ) ;
2005-07-08 10:29:06 +04:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE |
NTCREATEX_SHARE_ACCESS_DELETE ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-13 01:48:25 +03:00
fnum = io . ntcreatex . out . file . fnum ;
2005-07-08 10:29:06 +04:00
CHECK_VAL ( break_info . count , 0 ) ;
2005-12-29 01:18:45 +03:00
CHECK_VAL ( break_info . failures , 0 ) ;
2005-07-08 10:29:06 +04:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , 0 ) ;
2007-05-25 17:03:33 +04:00
smbcli_oplock_handler ( cli2 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
2005-07-08 10:29:06 +04:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE |
NTCREATEX_SHARE_ACCESS_DELETE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-13 01:48:25 +03:00
fnum2 = io . ntcreatex . out . file . fnum ;
2005-07-08 10:29:06 +04:00
CHECK_VAL ( break_info . count , 0 ) ;
2005-12-29 01:18:45 +03:00
CHECK_VAL ( break_info . failures , 0 ) ;
2005-07-08 10:29:06 +04:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " write should trigger a break to none \n " ) ;
2005-07-08 10:29:06 +04:00
{
union smb_write wr ;
wr . write . level = RAW_WRITE_WRITE ;
2006-03-13 01:48:25 +03:00
wr . write . in . file . fnum = fnum ;
2005-07-08 10:29:06 +04:00
wr . write . in . count = 1 ;
wr . write . in . offset = 0 ;
wr . write . in . remaining = 0 ;
2006-01-18 19:20:33 +03:00
wr . write . in . data = ( const uint8_t * ) " x " ;
2006-07-19 20:44:50 +04:00
status = smb_raw_write ( cli1 - > tree , & wr ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2005-07-08 10:29:06 +04:00
}
/* Now the oplock break request comes in. But right now we can't
* answer it . Do another write */
msleep ( 100 ) ;
{
union smb_write wr ;
wr . write . level = RAW_WRITE_WRITE ;
2006-03-13 01:48:25 +03:00
wr . write . in . file . fnum = fnum ;
2005-07-08 10:29:06 +04:00
wr . write . in . count = 1 ;
wr . write . in . offset = 0 ;
wr . write . in . remaining = 0 ;
2006-01-18 19:20:33 +03:00
wr . write . in . data = ( const uint8_t * ) " x " ;
2006-07-19 20:44:50 +04:00
status = smb_raw_write ( cli1 - > tree , & wr ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2005-07-08 10:29:06 +04:00
}
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . fnum , fnum2 ) ;
CHECK_VAL ( break_info . level , 0 ) ;
2005-12-29 01:18:45 +03:00
CHECK_VAL ( break_info . failures , 0 ) ;
2004-05-30 12:12:17 +04:00
2006-07-19 20:44:50 +04:00
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
2007-05-25 17:03:33 +04:00
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
static bool test_raw_oplock_batch11 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch11.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_setfileinfo sfi ;
uint16_t fnum = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
2006-07-19 20:44:50 +04:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2006-05-30 07:36:51 +04:00
2007-05-25 17:03:33 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
2006-05-30 07:36:51 +04:00
/* Test if a set-eof on pathname breaks an exclusive oplock. */
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " Test if setpathinfo set EOF breaks oplocks. \n " ) ;
2006-05-30 07:36:51 +04:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 20:44:50 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
2006-05-30 07:36:51 +04:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE |
NTCREATEX_SHARE_ACCESS_DELETE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_CREATE ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-05-30 07:57:43 +04:00
fnum = io . ntcreatex . out . file . fnum ;
2006-05-30 07:36:51 +04:00
CHECK_VAL ( break_info . count , 0 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
ZERO_STRUCT ( sfi ) ;
sfi . generic . level = RAW_SFILEINFO_END_OF_FILE_INFORMATION ;
sfi . generic . in . file . path = fname ;
sfi . end_of_file_info . in . size = 100 ;
2006-07-19 20:44:50 +04:00
status = smb_raw_setpathinfo ( cli2 - > tree , & sfi ) ;
2006-05-30 07:36:51 +04:00
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-05-30 07:36:51 +04:00
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
2006-05-30 07:57:43 +04:00
CHECK_VAL ( break_info . level , 0 ) ;
2006-07-19 20:44:50 +04:00
smbcli_close ( cli1 - > tree , fnum ) ;
2007-05-25 17:03:33 +04:00
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
static bool test_raw_oplock_batch12 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch12.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_setfileinfo sfi ;
uint16_t fnum = 0 , fnum2 = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
2006-07-19 20:44:50 +04:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2006-05-30 07:57:43 +04:00
2007-05-25 17:03:33 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
2006-05-30 07:57:43 +04:00
/* Test if a set-allocation size on pathname breaks an exclusive oplock. */
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " Test if setpathinfo allocation size breaks oplocks. \n " ) ;
2006-05-30 07:57:43 +04:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 20:44:50 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
2006-05-30 07:57:43 +04:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE |
NTCREATEX_SHARE_ACCESS_DELETE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_CREATE ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-05-30 07:57:43 +04:00
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( break_info . count , 0 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
2006-05-30 07:36:51 +04:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
2006-05-30 07:57:43 +04:00
ZERO_STRUCT ( sfi ) ;
sfi . generic . level = SMB_SFILEINFO_ALLOCATION_INFORMATION ;
sfi . generic . in . file . path = fname ;
sfi . allocation_info . in . alloc_size = 65536 * 8 ;
2006-07-19 20:44:50 +04:00
status = smb_raw_setpathinfo ( cli2 - > tree , & sfi ) ;
2006-05-30 07:57:43 +04:00
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-05-30 07:57:43 +04:00
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
CHECK_VAL ( break_info . level , 0 ) ;
2006-05-30 07:36:51 +04:00
2006-07-19 22:35:07 +04:00
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
2007-05-25 17:03:33 +04:00
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
static bool test_raw_oplock_batch13 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch13.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
uint16_t fnum = 0 , fnum2 = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
2006-07-19 22:35:07 +04:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2007-05-25 17:03:33 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
smbcli_oplock_handler ( cli2 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " open with batch oplock \n " ) ;
2006-07-19 22:35:07 +04:00
ZERO_STRUCT ( break_info ) ;
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
2007-05-25 17:03:33 +04:00
2006-07-19 22:35:07 +04:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 17:03:33 +04:00
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE |
NTCREATEX_SHARE_ACCESS_DELETE ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-07-19 22:35:07 +04:00
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
ZERO_STRUCT ( break_info ) ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " second open with attributes only and NTCREATEX_DISP_OVERWRITE dispostion causes oplock break \n " ) ;
2006-07-19 22:35:07 +04:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
io . ntcreatex . in . access_mask = SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_ATTRIBUTE | SEC_STD_SYNCHRONIZE ;
2007-05-25 17:03:33 +04:00
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE |
NTCREATEX_SHARE_ACCESS_DELETE ;
2006-07-19 22:35:07 +04:00
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OVERWRITE ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-07-19 22:35:07 +04:00
fnum2 = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
2007-05-25 17:03:33 +04:00
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
static bool test_raw_oplock_batch14 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch14.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
uint16_t fnum = 0 , fnum2 = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
2006-07-19 22:35:07 +04:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2007-05-25 17:03:33 +04:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " open with batch oplock \n " ) ;
2006-07-19 22:35:07 +04:00
ZERO_STRUCT ( break_info ) ;
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_levelII , cli1 - > tree ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 17:03:33 +04:00
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE |
NTCREATEX_SHARE_ACCESS_DELETE ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-07-19 22:35:07 +04:00
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
ZERO_STRUCT ( break_info ) ;
2007-03-06 00:28:55 +03:00
torture_comment ( tctx , " second open with attributes only and NTCREATEX_DISP_SUPERSEDE dispostion causes oplock break \n " ) ;
2006-07-19 22:35:07 +04:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
io . ntcreatex . in . access_mask = SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_ATTRIBUTE | SEC_STD_SYNCHRONIZE ;
2007-05-25 17:03:33 +04:00
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE |
NTCREATEX_SHARE_ACCESS_DELETE ;
2006-07-19 22:35:07 +04:00
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OVERWRITE ;
2007-05-25 17:03:33 +04:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-07-19 22:35:07 +04:00
fnum2 = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
2003-08-13 05:53:07 +04:00
done :
2007-05-25 17:03:33 +04:00
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
2003-08-13 05:53:07 +04:00
return ret ;
}
/*
basic testing of oplocks
*/
2007-08-28 16:54:27 +04:00
struct torture_suite * torture_raw_oplock ( TALLOC_CTX * mem_ctx )
2003-08-13 05:53:07 +04:00
{
2007-08-28 16:54:27 +04:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " OPLOCK " ) ;
2007-05-25 17:03:33 +04:00
torture_suite_add_2smb_test ( suite , " NORMAL " , test_raw_oplock_normal ) ;
torture_suite_add_2smb_test ( suite , " BATCH1 " , test_raw_oplock_batch1 ) ;
torture_suite_add_2smb_test ( suite , " BATCH2 " , test_raw_oplock_batch2 ) ;
torture_suite_add_2smb_test ( suite , " BATCH3 " , test_raw_oplock_batch3 ) ;
torture_suite_add_2smb_test ( suite , " BATCH4 " , test_raw_oplock_batch4 ) ;
torture_suite_add_2smb_test ( suite , " BATCH5 " , test_raw_oplock_batch5 ) ;
torture_suite_add_2smb_test ( suite , " BATCH6 " , test_raw_oplock_batch6 ) ;
torture_suite_add_2smb_test ( suite , " BATCH7 " , test_raw_oplock_batch7 ) ;
torture_suite_add_2smb_test ( suite , " BATCH8 " , test_raw_oplock_batch8 ) ;
torture_suite_add_2smb_test ( suite , " BATCH9 " , test_raw_oplock_batch9 ) ;
torture_suite_add_2smb_test ( suite , " BATCH10 " , test_raw_oplock_batch10 ) ;
torture_suite_add_2smb_test ( suite , " BATCH11 " , test_raw_oplock_batch11 ) ;
torture_suite_add_2smb_test ( suite , " BATCH12 " , test_raw_oplock_batch12 ) ;
torture_suite_add_2smb_test ( suite , " BATCH13 " , test_raw_oplock_batch13 ) ;
torture_suite_add_2smb_test ( suite , " BATCH14 " , test_raw_oplock_batch14 ) ;
return suite ;
2006-04-10 08:51:52 +04:00
}
/*
stress testing of oplocks
*/
BOOL torture_bench_oplock ( struct torture_context * torture )
{
struct smbcli_state * * cli ;
BOOL ret = True ;
TALLOC_CTX * mem_ctx = talloc_new ( torture ) ;
2007-08-26 22:24:12 +04:00
int torture_nprocs = torture_setting_int ( torture , " nprocs " , 4 ) ;
2006-04-10 08:51:52 +04:00
int i , count = 0 ;
2006-10-18 18:23:19 +04:00
int timelimit = torture_setting_int ( torture , " timelimit " , 10 ) ;
2006-04-10 08:51:52 +04:00
union smb_open io ;
struct timeval tv ;
struct event_context * ev = event_context_find ( mem_ctx ) ;
cli = talloc_array ( mem_ctx , struct smbcli_state * , torture_nprocs ) ;
2007-03-06 00:28:55 +03:00
torture_comment ( torture , " Opening %d connections \n " , torture_nprocs ) ;
2006-04-10 08:51:52 +04:00
for ( i = 0 ; i < torture_nprocs ; i + + ) {
2006-07-19 20:44:50 +04:00
if ( ! torture_open_connection_ev ( & cli [ i ] , i , ev ) ) {
2006-04-10 08:51:52 +04:00
return False ;
}
talloc_steal ( mem_ctx , cli [ i ] ) ;
smbcli_oplock_handler ( cli [ i ] - > transport , oplock_handler_close ,
cli [ i ] - > tree ) ;
}
if ( ! torture_setup_dir ( cli [ 0 ] , BASEDIR ) ) {
2003-08-13 05:53:07 +04:00
ret = False ;
2006-04-10 08:51:52 +04:00
goto done ;
2003-08-13 05:53:07 +04:00
}
2006-04-10 08:51:52 +04:00
io . ntcreatex . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = BASEDIR " \\ test.dat " ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
tv = timeval_current ( ) ;
2006-04-10 09:12:49 +04:00
/*
we open the same file with SHARE_ACCESS_NONE from all the
connections in a round robin fashion . Each open causes an
oplock break on the previous connection , which is answered
by the oplock_handler_close ( ) to close the file .
This measures how fast we can pass on oplocks , and stresses
the oplock handling code
*/
2007-03-06 00:28:55 +03:00
torture_comment ( torture , " Running for %d seconds \n " , timelimit ) ;
2006-04-10 08:51:52 +04:00
while ( timeval_elapsed ( & tv ) < timelimit ) {
for ( i = 0 ; i < torture_nprocs ; i + + ) {
NTSTATUS status ;
status = smb_raw_open ( cli [ i ] - > tree , mem_ctx , & io ) ;
2007-03-06 00:28:55 +03:00
CHECK_STATUS ( torture , status , NT_STATUS_OK ) ;
2006-04-10 08:51:52 +04:00
count + + ;
}
2007-04-30 01:37:29 +04:00
if ( torture_setting_bool ( torture , " progress " , true ) ) {
torture_comment ( torture , " %.2f ops/second \r " , count / timeval_elapsed ( & tv ) ) ;
}
2006-04-10 08:51:52 +04:00
}
2007-03-06 00:28:55 +03:00
torture_comment ( torture , " %.2f ops/second \n " , count / timeval_elapsed ( & tv ) ) ;
2006-04-10 08:51:52 +04:00
smb_raw_exit ( cli [ torture_nprocs - 1 ] - > session ) ;
done :
smb_raw_exit ( cli [ 0 ] - > session ) ;
smbcli_deltree ( cli [ 0 ] - > tree , BASEDIR ) ;
2005-01-27 10:08:20 +03:00
talloc_free ( mem_ctx ) ;
2003-08-13 05:53:07 +04:00
return ret ;
}
2007-08-29 08:33:26 +04:00
static struct hold_oplock_info {
const char * fname ;
bool close_on_break ;
uint32_t share_access ;
uint16_t fnum ;
} hold_info [ ] = {
{ BASEDIR " \\ notshared_close " , True ,
NTCREATEX_SHARE_ACCESS_NONE , } ,
{ BASEDIR " \\ notshared_noclose " , False ,
NTCREATEX_SHARE_ACCESS_NONE , } ,
{ BASEDIR " \\ shared_close " , True ,
NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE , } ,
{ BASEDIR " \\ shared_noclose " , False ,
NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE , } ,
} ;
static BOOL oplock_handler_hold ( struct smbcli_transport * transport , uint16_t tid ,
uint16_t fnum , uint8_t level , void * private )
{
struct smbcli_tree * tree = private ;
struct hold_oplock_info * info ;
int i ;
for ( i = 0 ; i < ARRAY_SIZE ( hold_info ) ; i + + ) {
if ( hold_info [ i ] . fnum = = fnum ) break ;
}
if ( i = = ARRAY_SIZE ( hold_info ) ) {
printf ( " oplock break for unknown fnum %u \n " , fnum ) ;
return False ;
}
info = & hold_info [ i ] ;
if ( info - > close_on_break ) {
printf ( " oplock break on %s - closing \n " ,
info - > fname ) ;
oplock_handler_close ( transport , tid , fnum , level , private ) ;
return True ;
}
printf ( " oplock break on %s - acking break \n " , info - > fname ) ;
return smbcli_oplock_ack ( tree , fnum , OPLOCK_BREAK_TO_NONE ) ;
}
/*
used for manual testing of oplocks - especially interaction with
other filesystems ( such as NFS and local access )
*/
BOOL torture_hold_oplock ( struct torture_context * torture ,
struct smbcli_state * cli )
{
struct event_context * ev = cli - > transport - > socket - > event . ctx ;
int i ;
printf ( " Setting up open files with oplocks in %s \n " , BASEDIR ) ;
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
return False ;
}
smbcli_oplock_handler ( cli - > transport , oplock_handler_hold , cli - > tree ) ;
/* setup the files */
for ( i = 0 ; i < ARRAY_SIZE ( hold_info ) ; i + + ) {
union smb_open io ;
NTSTATUS status ;
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid = 0 ;
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = hold_info [ i ] . share_access ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN_IF ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = hold_info [ i ] . fname ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
printf ( " opening %s \n " , hold_info [ i ] . fname ) ;
status = smb_raw_open ( cli - > tree , cli , & io ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Failed to open %s - %s \n " ,
hold_info [ i ] . fname , nt_errstr ( status ) ) ;
return False ;
}
if ( io . ntcreatex . out . oplock_level ! = BATCH_OPLOCK_RETURN ) {
printf ( " Oplock not granted for %s - expected %d but got %d \n " ,
hold_info [ i ] . fname , BATCH_OPLOCK_RETURN ,
io . ntcreatex . out . oplock_level ) ;
return False ;
}
hold_info [ i ] . fnum = io . ntcreatex . out . file . fnum ;
}
printf ( " Waiting for oplock events \n " ) ;
event_loop_wait ( ev ) ;
return True ;
}