2003-08-13 01:53:07 +00: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 02:07:03 +00:00
the Free Software Foundation ; either version 3 of the License , or
2003-08-13 01:53:07 +00:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 02:07:03 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2003-08-13 01:53:07 +00:00
*/
# include "includes.h"
2005-12-28 15:38:36 +00:00
# include "libcli/raw/libcliraw.h"
2008-04-02 04:53:27 +02:00
# include "libcli/raw/raw_proto.h"
2006-01-03 15:40:05 +00:00
# include "libcli/libcli.h"
2006-03-17 17:59:58 +00:00
# include "torture/util.h"
2006-04-10 04:51:52 +00:00
# include "lib/events/events.h"
2008-03-06 15:54:07 +01:00
# include "param/param.h"
# include "lib/cmdline/popt_common.h"
# include "libcli/resolve/resolve.h"
2003-08-13 01:53:07 +00:00
# define CHECK_VAL(v, correct) do { \
if ( ( v ) ! = ( correct ) ) { \
2008-02-27 16:22:04 +01:00
torture_result ( tctx , TORTURE_FAIL , " (%s): wrong value for %s got 0x%x - should be 0x%x \n " , \
2007-07-25 09:57:14 +00:00
__location__ , # v , ( int ) v , ( int ) correct ) ; \
2007-10-06 22:28:14 +00:00
ret = false ; \
2003-08-13 01:53:07 +00:00
} } while ( 0 )
2009-12-02 18:39:05 -08:00
# define CHECK_RANGE(v, min, max) do { \
if ( ( v ) < ( min ) | | ( v ) > ( max ) ) { \
torture_warning ( tctx , " (%s): wrong value for %s got " \
" %d - should be between %d and %d \n " , \
__location__ , # v , ( int ) v , ( int ) min , ( int ) max ) ; \
2008-03-04 14:08:32 +01:00
} } while ( 0 )
2008-02-27 15:43:04 +01:00
# define CHECK_STRMATCH(v, correct) do { \
if ( ! v | | strstr ( ( v ) , ( correct ) ) = = NULL ) { \
2008-02-27 16:22:04 +01:00
torture_result ( tctx , TORTURE_FAIL , " (%s): wrong value for %s got '%s' - should be '%s' \n " , \
2008-02-27 15:43:04 +01:00
__location__ , # v , v ? v : " NULL " , correct ) ; \
ret = false ; \
} \
} while ( 0 )
2007-03-05 21:28:55 +00:00
# define CHECK_STATUS(tctx, status, correct) do { \
2003-08-13 01:53:07 +00:00
if ( ! NT_STATUS_EQUAL ( status , correct ) ) { \
2007-03-05 21:28:55 +00:00
torture_result ( tctx , TORTURE_FAIL , __location__ " : Incorrect status %s - should be %s " , \
nt_errstr ( status ) , nt_errstr ( correct ) ) ; \
2007-10-06 22:28:14 +00:00
ret = false ; \
2003-08-13 01:53:07 +00:00
goto done ; \
} } while ( 0 )
static struct {
int fnum ;
2004-05-29 08:11:46 +00:00
uint8_t level ;
2003-08-13 01:53:07 +00:00
int count ;
2005-12-28 22:18:45 +00:00
int failures ;
2003-08-13 01:53:07 +00:00
} break_info ;
2007-05-25 13:03:33 +00:00
# define BASEDIR "\\test_oplock"
2006-04-10 04:51:52 +00:00
2003-08-13 01:53:07 +00:00
/*
2006-04-11 04:40:11 +00:00
a handler function for oplock break requests . Ack it as a break to level II if possible
2003-08-13 01:53:07 +00:00
*/
2008-03-06 16:27:13 +01:00
static bool oplock_handler_ack_to_given ( struct smbcli_transport * transport ,
uint16_t tid , uint16_t fnum ,
2009-02-02 08:44:44 +01:00
uint8_t level , void * private_data )
2003-08-13 01:53:07 +00:00
{
2009-02-02 08:44:44 +01:00
struct smbcli_tree * tree = ( struct smbcli_tree * ) private_data ;
2008-03-06 16:27:13 +01:00
const char * name ;
2003-08-13 01:53:07 +00:00
break_info . fnum = fnum ;
break_info . level = level ;
break_info . count + + ;
2008-03-06 16:27:13 +01:00
switch ( level ) {
case OPLOCK_BREAK_TO_LEVEL_II :
name = " level II " ;
break ;
case OPLOCK_BREAK_TO_NONE :
name = " none " ;
break ;
default :
name = " unknown " ;
break_info . failures + + ;
}
printf ( " Acking to %s [0x%02X] in oplock handler \n " ,
name , level ) ;
2003-08-13 01:53:07 +00:00
2004-08-04 13:23:35 +00:00
return smbcli_oplock_ack ( tree , fnum , level ) ;
2003-08-13 01:53:07 +00:00
}
2006-04-11 04:40:11 +00:00
/*
a handler function for oplock break requests . Ack it as a break to none
*/
2007-09-07 15:08:14 +00:00
static bool oplock_handler_ack_to_none ( struct smbcli_transport * transport ,
uint16_t tid , uint16_t fnum ,
2009-02-02 08:44:44 +01:00
uint8_t level , void * private_data )
2006-04-11 04:40:11 +00:00
{
2009-02-02 08:44:44 +01:00
struct smbcli_tree * tree = ( struct smbcli_tree * ) private_data ;
2006-04-11 04:40:11 +00:00
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 ) ;
}
2008-03-04 14:08:32 +01:00
/*
a handler function for oplock break requests . Let it timeout
*/
static bool oplock_handler_timeout ( struct smbcli_transport * transport ,
uint16_t tid , uint16_t fnum ,
2009-02-02 08:44:44 +01:00
uint8_t level , void * private_data )
2008-03-04 14:08:32 +01:00
{
break_info . fnum = fnum ;
break_info . level = level ;
break_info . count + + ;
printf ( " Let oplock break timeout \n " ) ;
return true ;
}
2005-12-28 22:18:45 +00: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 01:53:07 +00:00
/*
a handler function for oplock break requests - close the file
*/
2007-10-06 22:28:14 +00:00
static bool oplock_handler_close ( struct smbcli_transport * transport , uint16_t tid ,
2009-02-02 08:44:44 +01:00
uint16_t fnum , uint8_t level , void * private_data )
2003-08-13 01:53:07 +00:00
{
union smb_close io ;
2009-02-02 08:44:44 +01:00
struct smbcli_tree * tree = ( struct smbcli_tree * ) private_data ;
2005-12-28 22:18:45 +00:00
struct smbcli_request * req ;
2003-08-13 01:53:07 +00:00
break_info . fnum = fnum ;
break_info . level = level ;
break_info . count + + ;
io . close . level = RAW_CLOSE_CLOSE ;
2006-03-12 22:48:25 +00:00
io . close . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00:00
io . close . in . write_time = 0 ;
2005-12-28 22:18:45 +00:00
req = smb_raw_close_send ( tree , & io ) ;
if ( req = = NULL ) {
printf ( " failed to send close in oplock_handler_close \n " ) ;
2007-10-06 22:28:14 +00:00
return false ;
2003-08-13 01:53:07 +00:00
}
2005-12-28 22:18:45 +00:00
req - > async . fn = oplock_handler_close_recv ;
2009-02-02 10:17:00 +01:00
req - > async . private_data = NULL ;
2005-12-28 22:18:45 +00:00
2007-10-06 22:28:14 +00:00
return true ;
2003-08-13 01:53:07 +00:00
}
2008-03-06 15:54:07 +01:00
static bool open_connection_no_level2_oplocks ( struct torture_context * tctx ,
struct smbcli_state * * c )
{
NTSTATUS status ;
struct smbcli_options options ;
2008-09-30 03:07:08 +02:00
struct smbcli_session_options session_options ;
2008-03-06 15:54:07 +01:00
lp_smbcli_options ( tctx - > lp_ctx , & options ) ;
2008-09-30 03:07:08 +02:00
lp_smbcli_session_options ( tctx - > lp_ctx , & session_options ) ;
2008-03-06 15:54:07 +01:00
options . use_level2_oplocks = false ;
status = smbcli_full_connection ( tctx , c ,
torture_setting_string ( tctx , " host " , NULL ) ,
lp_smb_ports ( tctx - > lp_ctx ) ,
torture_setting_string ( tctx , " share " , NULL ) ,
2008-11-02 02:30:21 +01:00
NULL , lp_socket_options ( tctx - > lp_ctx ) , cmdline_credentials ,
2008-03-06 15:54:07 +01:00
lp_resolve_context ( tctx - > lp_ctx ) ,
2008-10-24 13:13:27 +02:00
tctx - > ev , & options , & session_options ,
2008-11-02 16:07:28 +01:00
lp_gensec_settings ( tctx , tctx - > lp_ctx ) ) ;
2008-03-06 15:54:07 +01:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-09-08 13:12:26 -07:00
torture_comment ( tctx , " Failed to open connection - %s \n " ,
nt_errstr ( status ) ) ;
2008-03-06 15:54:07 +01:00
return false ;
}
return true ;
}
2009-09-25 16:44:51 -07:00
/*
Timer handler function notifies the registering function that time is up
*/
static void timeout_cb ( struct tevent_context * ev ,
struct tevent_timer * te ,
struct timeval current_time ,
void * private_data )
{
bool * timesup = ( bool * ) private_data ;
* timesup = true ;
return ;
}
/*
Wait a short period of time to receive a single oplock break request
*/
static void torture_wait_for_oplock_break ( struct torture_context * tctx )
{
TALLOC_CTX * tmp_ctx = talloc_new ( NULL ) ;
struct tevent_timer * te = NULL ;
struct timeval ne ;
bool timesup = false ;
int old_count = break_info . count ;
/* Wait .1 seconds for an oplock break */
ne = tevent_timeval_current_ofs ( 0 , 100000 ) ;
if ( ( te = event_add_timed ( tctx - > ev , tmp_ctx , ne , timeout_cb , & timesup ) )
= = NULL )
{
torture_comment ( tctx , " Failed to wait for an oplock break. "
" test results may not be accurate. " ) ;
goto done ;
}
while ( ! timesup & & break_info . count < old_count + 1 ) {
if ( event_loop_once ( tctx - > ev ) ! = 0 ) {
torture_comment ( tctx , " Failed to wait for an oplock "
" break. test results may not be "
" accurate. " ) ;
goto done ;
}
}
done :
/* We don't know if the timed event fired and was freed, we received
* our oplock break , or some other event triggered the loop . Thus ,
* we create a tmp_ctx to be able to safely free / remove the timed
* event in all 3 cases . */
talloc_free ( tmp_ctx ) ;
return ;
}
2009-12-01 15:29:00 -08:00
static uint8_t get_break_level1_to_none_count ( struct torture_context * tctx )
{
return torture_setting_bool ( tctx , " 2_step_break_to_none " , false ) ?
2 : 1 ;
}
2008-02-26 14:58:00 +01:00
static bool test_raw_oplock_exclusive1 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
2003-08-13 01:53:07 +00:00
{
2008-02-26 14:58:00 +01:00
const char * fname = BASEDIR " \\ test_exclusive1.dat " ;
2003-08-13 01:53:07 +00:00
NTSTATUS status ;
2007-05-25 13:03:33 +00:00
bool ret = true ;
2003-08-13 01:53:07 +00:00
union smb_open io ;
2006-03-10 20:49:20 +00:00
union smb_unlink unl ;
2007-05-25 13:03:33 +00:00
uint16_t fnum = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
2003-08-13 01:53:07 +00:00
/* cleanup */
2006-07-19 16:44:50 +00:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2003-08-13 01:53:07 +00:00
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2003-08-13 01:53:07 +00:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2004-12-02 04:37:36 +00:00
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
2003-08-13 01:53:07 +00: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 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " EXCLUSIVE1: open a file with an exclusive oplock (share mode: none) \n " ) ;
2003-08-13 01:53:07 +00:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK ;
2007-05-25 13:03:33 +00:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-12 22:48:25 +00:00
fnum = io . ntcreatex . out . file . fnum ;
2003-08-13 01:53:07 +00:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , EXCLUSIVE_OPLOCK_RETURN ) ;
2007-03-05 21:28:55 +00:00
torture_comment ( tctx , " a 2nd open should not cause a break \n " ) ;
2007-05-25 13:03:33 +00:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2006-04-10 06:06:26 +00:00
CHECK_VAL ( break_info . count , 0 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
2007-03-05 21:28:55 +00:00
torture_comment ( tctx , " unlink it - should also be no break \n " ) ;
2006-03-10 20:49:20 +00:00
unl . unlink . in . pattern = fname ;
unl . unlink . in . attrib = 0 ;
2006-07-19 16:44:50 +00:00
status = smb_raw_unlink ( cli2 - > tree , & unl ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2003-08-13 01:53:07 +00:00
CHECK_VAL ( break_info . count , 0 ) ;
2005-12-28 22:18:45 +00:00
CHECK_VAL ( break_info . failures , 0 ) ;
2003-08-13 01:53:07 +00:00
2006-07-19 16:44:50 +00:00
smbcli_close ( cli1 - > tree , fnum ) ;
2003-08-13 01:53:07 +00:00
2007-05-25 13:03:33 +00:00
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2008-02-26 15:51:17 +01:00
static bool test_raw_oplock_exclusive2 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_exclusive2.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_unlink unl ;
uint16_t fnum = 0 , fnum2 = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2008-02-26 15:51:17 +01:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2008-02-26 15:51:17 +01:00
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 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " EXCLUSIVE2: open a file with an exclusive oplock (share mode: all) \n " ) ;
2008-02-26 15:51:17 +01:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK ;
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 ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , EXCLUSIVE_OPLOCK_RETURN ) ;
torture_comment ( tctx , " a 2nd open should cause a break to level 2 \n " ) ;
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum2 = io . ntcreatex . out . file . fnum ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-02-26 15:51:17 +01: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 , OPLOCK_BREAK_TO_LEVEL_II ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
ZERO_STRUCT ( break_info ) ;
/* now we have 2 level II oplocks... */
torture_comment ( tctx , " try to unlink it - should not cause a break, but a sharing violation \n " ) ;
unl . unlink . in . pattern = fname ;
unl . unlink . in . attrib = 0 ;
status = smb_raw_unlink ( cli2 - > tree , & unl ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-02-26 15:51:17 +01:00
CHECK_VAL ( break_info . count , 0 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
torture_comment ( tctx , " close 1st handle \n " ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
torture_comment ( tctx , " try to unlink it - should not cause a break, but a sharing violation \n " ) ;
unl . unlink . in . pattern = fname ;
unl . unlink . in . attrib = 0 ;
status = smb_raw_unlink ( cli2 - > tree , & unl ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-02-26 15:51:17 +01:00
CHECK_VAL ( break_info . count , 0 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
2009-09-25 16:44:51 -07:00
torture_comment ( tctx , " close 2nd handle \n " ) ;
2008-02-26 15:51:17 +01:00
smbcli_close ( cli2 - > tree , fnum2 ) ;
torture_comment ( tctx , " unlink it \n " ) ;
unl . unlink . in . pattern = fname ;
unl . unlink . in . attrib = 0 ;
status = smb_raw_unlink ( cli2 - > tree , & unl ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-02-26 15:51:17 +01:00
CHECK_VAL ( break_info . count , 0 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2008-02-26 16:16:31 +01:00
static bool test_raw_oplock_exclusive3 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_exclusive3.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 */
smbcli_unlink ( cli1 - > tree , fname ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2008-02-26 16:16:31 +01:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2008-02-26 16:16:31 +01:00
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
2009-11-25 08:03:36 -08:00
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_WRITE ;
2008-02-26 16:16:31 +01:00
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 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " EXCLUSIVE3: open a file with an exclusive oplock (share mode: none) \n " ) ;
2008-03-11 12:37:20 -07:00
2008-02-26 16:16:31 +01:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , EXCLUSIVE_OPLOCK_RETURN ) ;
torture_comment ( tctx , " setpathinfo EOF should trigger a break to none \n " ) ;
ZERO_STRUCT ( sfi ) ;
2009-11-30 16:43:00 -08:00
sfi . generic . level = RAW_SFILEINFO_END_OF_FILE_INFORMATION ;
2008-02-26 16:16:31 +01:00
sfi . generic . in . file . path = fname ;
sfi . end_of_file_info . in . size = 100 ;
status = smb_raw_setpathinfo ( cli2 - > tree , & sfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2009-12-01 15:29:00 -08:00
CHECK_VAL ( break_info . count , get_break_level1_to_none_count ( tctx ) ) ;
2008-02-26 16:16:31 +01:00
CHECK_VAL ( break_info . failures , 0 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_NONE ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2008-02-27 08:51:25 +01:00
static bool test_raw_oplock_exclusive4 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_exclusive4.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 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2008-02-27 08:51:25 +01:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2008-02-27 08:51:25 +01:00
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 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " EXCLUSIVE4: open with exclusive oplock \n " ) ;
2008-02-27 08:51:25 +01:00
ZERO_STRUCT ( break_info ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2008-02-27 08:51:25 +01:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , EXCLUSIVE_OPLOCK_RETURN ) ;
ZERO_STRUCT ( break_info ) ;
torture_comment ( tctx , " second open with attributes only shouldn't cause oplock break \n " ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK ;
io . ntcreatex . in . access_mask = SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_ATTRIBUTE | SEC_STD_SYNCHRONIZE ;
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum2 = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , NO_OPLOCK_RETURN ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-02-27 08:51:25 +01:00
CHECK_VAL ( break_info . count , 0 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2008-02-27 10:02:52 +01:00
static bool test_raw_oplock_exclusive5 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_exclusive5.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 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
smbcli_oplock_handler ( cli2 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2008-02-27 10:02:52 +01:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2008-02-27 10:02:52 +01:00
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 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " EXCLUSIVE5: open with exclusive oplock \n " ) ;
2008-02-27 10:02:52 +01:00
ZERO_STRUCT ( break_info ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2008-02-27 10:02:52 +01:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK ;
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 ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , EXCLUSIVE_OPLOCK_RETURN ) ;
ZERO_STRUCT ( break_info ) ;
torture_comment ( tctx , " second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break \n " ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK ;
io . ntcreatex . in . access_mask = SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_ATTRIBUTE | SEC_STD_SYNCHRONIZE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OVERWRITE_IF ;
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum2 = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2009-12-01 15:29:00 -08:00
CHECK_VAL ( break_info . count , get_break_level1_to_none_count ( tctx ) ) ;
2008-02-27 10:02:52 +01:00
CHECK_VAL ( break_info . failures , 0 ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2008-02-27 10:40:19 +01:00
static bool test_raw_oplock_exclusive6 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname1 = BASEDIR " \\ test_exclusive6_1.dat " ;
const char * fname2 = BASEDIR " \\ test_exclusive6_2.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_rename rn ;
uint16_t fnum = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname1 ) ;
smbcli_unlink ( cli1 - > tree , fname2 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2008-02-27 10:40:19 +01:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2008-02-27 10:40:19 +01:00
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 = fname1 ;
2009-09-08 13:12:26 -07:00
torture_comment ( tctx , " EXCLUSIVE6: open a file with an exclusive "
" oplock (share mode: none) \n " ) ;
2008-02-27 10:40:19 +01:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED | NTCREATEX_FLAGS_REQUEST_OPLOCK ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , EXCLUSIVE_OPLOCK_RETURN ) ;
2009-09-08 13:12:26 -07:00
torture_comment ( tctx , " rename should not generate a break but get a "
" sharing violation \n " ) ;
2008-02-27 10:40:19 +01:00
ZERO_STRUCT ( rn ) ;
rn . generic . level = RAW_RENAME_RENAME ;
rn . rename . in . pattern1 = fname1 ;
rn . rename . in . pattern2 = fname2 ;
rn . rename . in . attrib = 0 ;
2009-09-08 13:12:26 -07:00
torture_comment ( tctx , " trying rename while first file open \n " ) ;
2008-02-27 10:40:19 +01:00
status = smb_raw_rename ( cli2 - > tree , & rn ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-02-27 10:40:19 +01:00
CHECK_VAL ( break_info . count , 0 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2009-12-02 11:39:50 -08:00
/**
* Exclusive version of batch19
*/
static bool test_raw_oplock_exclusive7 ( struct torture_context * tctx ,
struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname1 = BASEDIR " \\ test_exclusiv6_1.dat " ;
const char * fname2 = BASEDIR " \\ test_exclusiv6_2.dat " ;
const char * fname3 = BASEDIR " \\ test_exclusiv6_3.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_fileinfo qfi ;
union smb_setfileinfo sfi ;
uint16_t fnum = 0 ;
uint16_t fnum2 = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname1 ) ;
smbcli_unlink ( cli1 - > tree , fname2 ) ;
smbcli_unlink ( cli1 - > tree , fname3 ) ;
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given ,
cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid . fnum = 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_READ |
NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE ;
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 = fname1 ;
torture_comment ( tctx , " open a file with an exclusive oplock (share "
" mode: none) \n " ) ;
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , EXCLUSIVE_OPLOCK_RETURN ) ;
torture_comment ( tctx , " setpathinfo rename info should trigger a break "
" to none \n " ) ;
ZERO_STRUCT ( sfi ) ;
sfi . generic . level = RAW_SFILEINFO_RENAME_INFORMATION ;
sfi . generic . in . file . path = fname1 ;
sfi . rename_information . in . overwrite = 0 ;
sfi . rename_information . in . root_fid = 0 ;
sfi . rename_information . in . new_name = fname2 + strlen ( BASEDIR ) + 1 ;
status = smb_raw_setpathinfo ( cli2 - > tree , & sfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
torture_wait_for_oplock_break ( tctx ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
if ( TARGET_IS_WINXP ( tctx ) ) {
/* XP incorrectly breaks to level2. */
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
} else {
/* Exclusive oplocks should not be broken on rename. */
CHECK_VAL ( break_info . failures , 0 ) ;
CHECK_VAL ( break_info . count , 0 ) ;
}
ZERO_STRUCT ( qfi ) ;
qfi . generic . level = RAW_FILEINFO_ALL_INFORMATION ;
qfi . generic . in . file . fnum = fnum ;
status = smb_raw_fileinfo ( cli1 - > tree , tctx , & qfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_STRMATCH ( qfi . all_info . out . fname . s , fname2 ) ;
/* Try breaking to level2 and then see if rename breaks the level2.*/
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . fname = fname2 ;
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum2 = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
torture_wait_for_oplock_break ( tctx ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
if ( TARGET_IS_WINXP ( tctx ) ) {
/* XP already broke to level2. */
CHECK_VAL ( break_info . failures , 0 ) ;
CHECK_VAL ( break_info . count , 0 ) ;
} else {
/* Break to level 2 expected. */
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
}
ZERO_STRUCT ( break_info ) ;
sfi . generic . in . file . path = fname2 ;
sfi . rename_information . in . overwrite = 0 ;
sfi . rename_information . in . root_fid = 0 ;
sfi . rename_information . in . new_name = fname1 + strlen ( BASEDIR ) + 1 ;
status = smb_raw_setpathinfo ( cli2 - > tree , & sfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
/* Level2 oplocks are not broken on rename. */
torture_wait_for_oplock_break ( tctx ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
CHECK_VAL ( break_info . count , 0 ) ;
/* Close and re-open file with oplock. */
smbcli_close ( cli1 - > tree , fnum ) ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , EXCLUSIVE_OPLOCK_RETURN ) ;
torture_comment ( tctx , " setfileinfo rename info on a client's own fid "
" should not trigger a break nor a violation \n " ) ;
ZERO_STRUCT ( break_info ) ;
ZERO_STRUCT ( sfi ) ;
sfi . generic . level = RAW_SFILEINFO_RENAME_INFORMATION ;
sfi . generic . in . file . fnum = fnum ;
sfi . rename_information . in . overwrite = 0 ;
sfi . rename_information . in . root_fid = 0 ;
sfi . rename_information . in . new_name = fname3 + strlen ( BASEDIR ) + 1 ;
status = smb_raw_setfileinfo ( cli1 - > tree , & sfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
torture_wait_for_oplock_break ( tctx ) ;
if ( TARGET_IS_WINXP ( tctx ) ) {
/* XP incorrectly breaks to level2. */
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
} else {
CHECK_VAL ( break_info . count , 0 ) ;
}
ZERO_STRUCT ( qfi ) ;
qfi . generic . level = RAW_FILEINFO_ALL_INFORMATION ;
qfi . generic . in . file . fnum = fnum ;
status = smb_raw_fileinfo ( cli1 - > tree , tctx , & qfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_STRMATCH ( qfi . all_info . out . fname . s , fname3 ) ;
done :
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2007-05-25 13:03:33 +00:00
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 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2007-05-25 13:03:33 +00:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2007-05-25 13:03:33 +00:00
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 01:53:07 +00:00
/*
with a batch oplock we get a break
*/
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH1: open with batch oplock \n " ) ;
2003-08-13 01:53:07 +00:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 13:03:33 +00:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-12 22:48:25 +00:00
fnum = io . ntcreatex . out . file . fnum ;
2003-08-13 01:53:07 +00:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
2007-03-05 21:28:55 +00:00
torture_comment ( tctx , " unlink should generate a break \n " ) ;
2006-03-10 20:49:20 +00:00
unl . unlink . in . pattern = fname ;
unl . unlink . in . attrib = 0 ;
2006-07-19 16:44:50 +00:00
status = smb_raw_unlink ( cli2 - > tree , & unl ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2003-08-13 01:53:07 +00:00
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2006-04-11 04:40:11 +00:00
CHECK_VAL ( break_info . count , 1 ) ;
2003-08-13 01:53:07 +00:00
CHECK_VAL ( break_info . fnum , fnum ) ;
2006-04-11 04:40:11 +00:00
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
2007-03-05 21:28:55 +00:00
torture_comment ( tctx , " 2nd unlink should not generate a break \n " ) ;
2006-04-11 04:40:11 +00:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 16:44:50 +00:00
status = smb_raw_unlink ( cli2 - > tree , & unl ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2006-04-11 04:40:11 +00:00
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2006-04-11 04:40:11 +00:00
CHECK_VAL ( break_info . count , 0 ) ;
2007-03-05 21:28:55 +00:00
torture_comment ( tctx , " writing should generate a self break to none \n " ) ;
2006-07-19 16:44:50 +00:00
smbcli_write ( cli1 - > tree , fnum , 0 , & c , 0 , 1 ) ;
2006-04-11 04:40:11 +00:00
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
torture_wait_for_oplock_break ( tctx ) ;
2003-08-13 01:53:07 +00:00
CHECK_VAL ( break_info . count , 1 ) ;
2006-04-11 04:40:11 +00:00
CHECK_VAL ( break_info . fnum , fnum ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_NONE ) ;
2005-12-28 22:18:45 +00:00
CHECK_VAL ( break_info . failures , 0 ) ;
2003-08-13 01:53:07 +00:00
2006-07-19 16:44:50 +00:00
smbcli_close ( cli1 - > tree , fnum ) ;
2003-08-13 01:53:07 +00:00
2007-05-25 13:03:33 +00: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 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2007-05-25 13:03:33 +00:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2007-05-25 13:03:33 +00:00
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 04:40:11 +00:00
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH2: open with batch oplock \n " ) ;
2006-04-11 04:40:11 +00:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 13:03:33 +00:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-04-11 04:40:11 +00:00
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
2007-03-05 21:28:55 +00:00
torture_comment ( tctx , " unlink should generate a break, which we ack as break to none \n " ) ;
2006-07-19 16:44:50 +00:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_none , cli1 - > tree ) ;
2006-04-11 04:40:11 +00:00
unl . unlink . in . pattern = fname ;
unl . unlink . in . attrib = 0 ;
2006-07-19 16:44:50 +00:00
status = smb_raw_unlink ( cli2 - > tree , & unl ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2006-04-11 04:40:11 +00:00
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2006-04-11 04:40:11 +00: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-05 21:28:55 +00:00
torture_comment ( tctx , " 2nd unlink should not generate a break \n " ) ;
2006-04-11 04:40:11 +00:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 16:44:50 +00:00
status = smb_raw_unlink ( cli2 - > tree , & unl ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2006-04-11 04:40:11 +00:00
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2006-04-11 04:40:11 +00:00
CHECK_VAL ( break_info . count , 0 ) ;
2007-03-05 21:28:55 +00:00
torture_comment ( tctx , " writing should not generate a break \n " ) ;
2006-07-19 16:44:50 +00:00
smbcli_write ( cli1 - > tree , fnum , 0 , & c , 0 , 1 ) ;
2006-04-11 04:40:11 +00:00
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2006-04-11 04:40:11 +00:00
CHECK_VAL ( break_info . count , 0 ) ;
2006-07-19 16:44:50 +00:00
smbcli_close ( cli1 - > tree , fnum ) ;
2006-04-11 04:40:11 +00:00
2007-05-25 13:03:33 +00: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 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2007-05-25 13:03:33 +00:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2007-05-25 13:03:33 +00:00
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 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH3: if we close on break then the unlink can succeed \n " ) ;
2003-08-13 01:53:07 +00:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 16:44:50 +00:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_close , cli1 - > tree ) ;
2003-08-13 01:53:07 +00:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 13:03:33 +00:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-12 22:48:25 +00:00
fnum = io . ntcreatex . out . file . fnum ;
2003-08-13 01:53:07 +00:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
2006-03-10 20:49:20 +00:00
unl . unlink . in . pattern = fname ;
unl . unlink . in . attrib = 0 ;
2003-08-13 01:53:07 +00:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 16:44:50 +00:00
status = smb_raw_unlink ( cli2 - > tree , & unl ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2003-08-13 01:53:07 +00:00
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2006-04-11 04:40:11 +00:00
CHECK_VAL ( break_info . count , 1 ) ;
2003-08-13 01:53:07 +00:00
CHECK_VAL ( break_info . fnum , fnum ) ;
2004-05-30 08:12:17 +00:00
CHECK_VAL ( break_info . level , 1 ) ;
2005-12-28 22:18:45 +00:00
CHECK_VAL ( break_info . failures , 0 ) ;
2003-08-13 01:53:07 +00:00
2007-05-25 13:03:33 +00: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 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2007-05-25 13:03:33 +00:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2007-05-25 13:03:33 +00:00
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 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH4: a self read should not cause a break \n " ) ;
2003-08-13 01:53:07 +00:00
ZERO_STRUCT ( break_info ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2003-08-13 01:53:07 +00:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 13:03:33 +00:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-12 22:48:25 +00:00
fnum = io . ntcreatex . out . file . fnum ;
2003-08-13 01:53:07 +00:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
2009-11-20 11:25:43 -08:00
rd . readx . level = RAW_READ_READX ;
rd . readx . in . file . fnum = fnum ;
rd . readx . in . mincnt = 1 ;
rd . readx . in . maxcnt = 1 ;
rd . readx . in . offset = 0 ;
rd . readx . in . remaining = 0 ;
rd . readx . in . read_for_execute = false ;
2006-07-19 16:44:50 +00:00
status = smb_raw_read ( cli1 - > tree , & rd ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2003-08-13 01:53:07 +00:00
CHECK_VAL ( break_info . count , 0 ) ;
2005-12-28 22:18:45 +00:00
CHECK_VAL ( break_info . failures , 0 ) ;
2003-08-13 01:53:07 +00:00
2007-05-25 13:03:33 +00: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 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2007-05-25 13:03:33 +00:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2007-05-25 13:03:33 +00:00
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 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH5: a 2nd open should give a break \n " ) ;
2003-08-13 01:53:07 +00:00
ZERO_STRUCT ( break_info ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2003-08-13 01:53:07 +00:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 13:03:33 +00:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-12 22:48:25 +00:00
fnum = io . ntcreatex . out . file . fnum ;
2003-08-13 01:53:07 +00: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 13:03:33 +00:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2003-08-13 01:53:07 +00:00
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2003-08-13 01:53:07 +00:00
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . fnum , fnum ) ;
2004-05-30 08:12:17 +00:00
CHECK_VAL ( break_info . level , 1 ) ;
2005-12-28 22:18:45 +00:00
CHECK_VAL ( break_info . failures , 0 ) ;
2003-08-13 01:53:07 +00:00
2007-05-25 13:03:33 +00: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 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2009-09-25 16:44:51 -07:00
smbcli_oplock_handler ( cli2 - > transport , oplock_handler_ack_to_given , cli2 - > tree ) ;
2007-05-25 13:03:33 +00:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2007-05-25 13:03:33 +00:00
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 04:40:11 +00:00
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH6: a 2nd open should give a break to level II if the first open allowed shared read \n " ) ;
2006-04-11 04:40:11 +00:00
ZERO_STRUCT ( break_info ) ;
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 13:03:33 +00:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-04-11 04:40:11 +00:00
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
ZERO_STRUCT ( break_info ) ;
2007-05-25 13:03:33 +00:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-07-19 16:44:50 +00:00
fnum2 = io . ntcreatex . out . file . fnum ;
2006-04-11 04:40:11 +00:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
2009-09-25 16:44:51 -07:00
//torture_wait_for_oplock_break(tctx);
2006-04-11 04:40:11 +00:00
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-05 21:28:55 +00:00
torture_comment ( tctx , " write should trigger a break to none on both \n " ) ;
2006-07-19 16:44:50 +00:00
smbcli_write ( cli1 - > tree , fnum , 0 , & c , 0 , 1 ) ;
2009-09-25 16:44:51 -07:00
/* We expect two breaks */
torture_wait_for_oplock_break ( tctx ) ;
torture_wait_for_oplock_break ( tctx ) ;
2006-04-11 04:40:11 +00:00
CHECK_VAL ( break_info . count , 2 ) ;
CHECK_VAL ( break_info . level , 0 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
2006-07-19 16:44:50 +00:00
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
2006-04-11 04:40:11 +00:00
2007-05-25 13:03:33 +00: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 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2007-05-25 13:03:33 +00:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2007-05-25 13:03:33 +00:00
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 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH7: a 2nd open should get an oplock when we close instead of ack \n " ) ;
2003-08-13 01:53:07 +00:00
ZERO_STRUCT ( break_info ) ;
2006-07-19 16:44:50 +00:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_close , cli1 - > tree ) ;
2003-08-13 01:53:07 +00:00
2006-04-11 04:40:11 +00:00
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
2003-08-13 01:53:07 +00:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 13:03:33 +00:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-12 22:48:25 +00:00
fnum2 = io . ntcreatex . out . file . fnum ;
2003-08-13 01:53:07 +00: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 13:03:33 +00:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-12 22:48:25 +00:00
fnum = io . ntcreatex . out . file . fnum ;
2003-08-13 01:53:07 +00:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2003-08-13 01:53:07 +00:00
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . fnum , fnum2 ) ;
2004-05-30 08:12:17 +00:00
CHECK_VAL ( break_info . level , 1 ) ;
2005-12-28 22:18:45 +00:00
CHECK_VAL ( break_info . failures , 0 ) ;
2009-09-25 16:44:51 -07:00
2006-07-19 16:44:50 +00:00
smbcli_close ( cli2 - > tree , fnum ) ;
2004-05-25 00:05:51 +00:00
2007-05-25 13:03:33 +00: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 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2007-05-25 13:03:33 +00:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2007-05-25 13:03:33 +00:00
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 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH8: open with batch oplock \n " ) ;
2004-05-25 00:05:51 +00:00
ZERO_STRUCT ( break_info ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2004-05-25 00:05:51 +00:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 13:03:33 +00:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-12 22:48:25 +00:00
fnum = io . ntcreatex . out . file . fnum ;
2004-05-25 00:05:51 +00:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
ZERO_STRUCT ( break_info ) ;
2007-03-05 21:28:55 +00:00
torture_comment ( tctx , " second open with attributes only shouldn't cause oplock break \n " ) ;
2004-05-25 00:05:51 +00:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2004-11-30 04:33:27 +00:00
io . ntcreatex . in . access_mask = SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_ATTRIBUTE | SEC_STD_SYNCHRONIZE ;
2007-05-25 13:03:33 +00:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-12 22:48:25 +00:00
fnum2 = io . ntcreatex . out . file . fnum ;
2004-05-25 00:05:51 +00:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , NO_OPLOCK_RETURN ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2004-05-25 00:05:51 +00:00
CHECK_VAL ( break_info . count , 0 ) ;
2005-12-28 22:18:45 +00:00
CHECK_VAL ( break_info . failures , 0 ) ;
2003-08-13 01:53:07 +00:00
2006-07-19 16:44:50 +00:00
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
2007-05-25 13:03:33 +00: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 16:44:50 +00:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2004-05-30 08:12:17 +00:00
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2007-05-25 13:03:33 +00:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2007-05-25 13:03:33 +00:00
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 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH9: open with attributes only can create file \n " ) ;
2006-07-19 16:44:50 +00:00
2004-05-30 08:12:17 +00:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2004-11-30 04:33:27 +00:00
io . ntcreatex . in . access_mask = SEC_FILE_READ_ATTRIBUTE | SEC_FILE_WRITE_ATTRIBUTE | SEC_STD_SYNCHRONIZE ;
2004-05-30 08:12:17 +00:00
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_CREATE ;
2007-05-25 13:03:33 +00:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-12 22:48:25 +00:00
fnum = io . ntcreatex . out . file . fnum ;
2004-05-30 08:12:17 +00:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
2007-03-05 21:28:55 +00:00
torture_comment ( tctx , " Subsequent normal open should break oplock on attribute only open to level II \n " ) ;
2004-05-30 08:12:17 +00:00
ZERO_STRUCT ( break_info ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2004-05-30 08:12:17 +00:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2004-12-02 04:37:36 +00:00
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
2004-05-30 08:12:17 +00:00
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN ;
2007-05-25 13:03:33 +00:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-12 22:48:25 +00:00
fnum2 = io . ntcreatex . out . file . fnum ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2004-05-30 08:12:17 +00:00
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . fnum , fnum ) ;
2005-12-28 22:18:45 +00:00
CHECK_VAL ( break_info . failures , 0 ) ;
2006-04-11 04:40:11 +00:00
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
2004-05-30 08:12:17 +00:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
2006-07-19 16:44:50 +00:00
smbcli_close ( cli2 - > tree , fnum2 ) ;
2005-07-08 06:29:06 +00:00
2007-03-05 21:28:55 +00:00
torture_comment ( tctx , " third oplocked open should grant level2 without break \n " ) ;
2005-07-08 06:29:06 +00:00
ZERO_STRUCT ( break_info ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
smbcli_oplock_handler ( cli2 - > transport , oplock_handler_ack_to_given , cli2 - > tree ) ;
2005-07-08 06:29:06 +00: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 13:03:33 +00:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-12 22:48:25 +00:00
fnum2 = io . ntcreatex . out . file . fnum ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2005-07-08 06:29:06 +00:00
CHECK_VAL ( break_info . count , 0 ) ;
2005-12-28 22:18:45 +00:00
CHECK_VAL ( break_info . failures , 0 ) ;
2005-07-08 06:29:06 +00:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
ZERO_STRUCT ( break_info ) ;
2007-03-05 21:28:55 +00:00
torture_comment ( tctx , " write should trigger a break to none on both \n " ) ;
2006-07-19 16:44:50 +00:00
smbcli_write ( cli2 - > tree , fnum2 , 0 , & c , 0 , 1 ) ;
2005-07-08 06:29:06 +00:00
2009-09-25 16:44:51 -07:00
/* We expect two breaks */
torture_wait_for_oplock_break ( tctx ) ;
torture_wait_for_oplock_break ( tctx ) ;
2005-07-08 06:29:06 +00:00
CHECK_VAL ( break_info . count , 2 ) ;
CHECK_VAL ( break_info . level , 0 ) ;
2005-12-28 22:18:45 +00:00
CHECK_VAL ( break_info . failures , 0 ) ;
2005-07-08 06:29:06 +00:00
2006-07-19 16:44:50 +00:00
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
2005-07-08 06:29:06 +00:00
2007-05-25 13:03:33 +00: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 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2005-07-08 06:29:06 +00:00
2007-05-25 13:03:33 +00:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2007-05-25 13:03:33 +00:00
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 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH10: Open with oplock after a non-oplock open should grant level2 \n " ) ;
2007-05-25 13:03:33 +00:00
ZERO_STRUCT ( break_info ) ;
2005-07-08 06:29:06 +00: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 13:03:33 +00:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-12 22:48:25 +00:00
fnum = io . ntcreatex . out . file . fnum ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2005-07-08 06:29:06 +00:00
CHECK_VAL ( break_info . count , 0 ) ;
2005-12-28 22:18:45 +00:00
CHECK_VAL ( break_info . failures , 0 ) ;
2005-07-08 06:29:06 +00:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , 0 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli2 - > transport , oplock_handler_ack_to_given , cli2 - > tree ) ;
2007-05-25 13:03:33 +00:00
2005-07-08 06:29:06 +00: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 13:03:33 +00:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-03-12 22:48:25 +00:00
fnum2 = io . ntcreatex . out . file . fnum ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2005-07-08 06:29:06 +00:00
CHECK_VAL ( break_info . count , 0 ) ;
2005-12-28 22:18:45 +00:00
CHECK_VAL ( break_info . failures , 0 ) ;
2005-07-08 06:29:06 +00:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
2007-03-05 21:28:55 +00:00
torture_comment ( tctx , " write should trigger a break to none \n " ) ;
2005-07-08 06:29:06 +00:00
{
union smb_write wr ;
wr . write . level = RAW_WRITE_WRITE ;
2006-03-12 22:48:25 +00:00
wr . write . in . file . fnum = fnum ;
2005-07-08 06:29:06 +00:00
wr . write . in . count = 1 ;
wr . write . in . offset = 0 ;
wr . write . in . remaining = 0 ;
2006-01-18 16:20:33 +00:00
wr . write . in . data = ( const uint8_t * ) " x " ;
2006-07-19 16:44:50 +00:00
status = smb_raw_write ( cli1 - > tree , & wr ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2005-07-08 06:29:06 +00:00
}
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2005-07-08 06:29:06 +00:00
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . fnum , fnum2 ) ;
CHECK_VAL ( break_info . level , 0 ) ;
2005-12-28 22:18:45 +00:00
CHECK_VAL ( break_info . failures , 0 ) ;
2004-05-30 08:12:17 +00:00
2006-07-19 16:44:50 +00:00
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
2007-05-25 13:03:33 +00: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 16:44:50 +00:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2006-05-30 03:36:51 +00:00
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2007-05-25 13:03:33 +00:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2007-05-25 13:03:33 +00:00
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
2009-11-25 08:03:36 -08:00
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_WRITE ;
2007-05-25 13:03:33 +00:00
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 03:36:51 +00:00
/* Test if a set-eof on pathname breaks an exclusive oplock. */
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH11: Test if setpathinfo set EOF breaks oplocks. \n " ) ;
2006-05-30 03:36:51 +00:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
2009-09-25 16:44:51 -07:00
NTCREATEX_FLAGS_REQUEST_OPLOCK |
2006-05-30 03:36:51 +00:00
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 13:03:33 +00:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-05-30 03:57:43 +00:00
fnum = io . ntcreatex . out . file . fnum ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2006-05-30 03:36:51 +00:00
CHECK_VAL ( break_info . count , 0 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
2009-09-25 16:44:51 -07:00
2006-05-30 03:36:51 +00:00
ZERO_STRUCT ( sfi ) ;
2009-11-30 16:43:00 -08:00
sfi . generic . level = RAW_SFILEINFO_END_OF_FILE_INFORMATION ;
2006-05-30 03:36:51 +00:00
sfi . generic . in . file . path = fname ;
sfi . end_of_file_info . in . size = 100 ;
2006-07-19 16:44:50 +00:00
status = smb_raw_setpathinfo ( cli2 - > tree , & sfi ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2009-12-01 15:29:00 -08:00
CHECK_VAL ( break_info . count , get_break_level1_to_none_count ( tctx ) ) ;
2006-05-30 03:36:51 +00:00
CHECK_VAL ( break_info . failures , 0 ) ;
2006-05-30 03:57:43 +00:00
CHECK_VAL ( break_info . level , 0 ) ;
2006-07-19 16:44:50 +00:00
smbcli_close ( cli1 - > tree , fnum ) ;
2007-05-25 13:03:33 +00: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 ;
2008-02-23 11:51:43 +01:00
uint16_t fnum = 0 ;
2007-05-25 13:03:33 +00:00
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
2006-07-19 16:44:50 +00:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2006-05-30 03:57:43 +00:00
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2007-05-25 13:03:33 +00:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2007-05-25 13:03:33 +00:00
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 03:57:43 +00:00
/* Test if a set-allocation size on pathname breaks an exclusive oplock. */
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH12: Test if setpathinfo allocation size breaks oplocks. \n " ) ;
2006-05-30 03:57:43 +00:00
ZERO_STRUCT ( break_info ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2006-05-30 03:57:43 +00:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
2009-09-25 16:44:51 -07:00
NTCREATEX_FLAGS_REQUEST_OPLOCK |
2006-05-30 03:57:43 +00:00
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 13:03:33 +00:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-05-30 03:57:43 +00:00
fnum = io . ntcreatex . out . file . fnum ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2006-05-30 03:57:43 +00:00
CHECK_VAL ( break_info . count , 0 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
2006-05-30 03:36:51 +00:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
2009-09-25 16:44:51 -07:00
2006-05-30 03:57:43 +00: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 16:44:50 +00:00
status = smb_raw_setpathinfo ( cli2 - > tree , & sfi ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2009-12-01 15:29:00 -08:00
CHECK_VAL ( break_info . count , get_break_level1_to_none_count ( tctx ) ) ;
2006-05-30 03:57:43 +00:00
CHECK_VAL ( break_info . failures , 0 ) ;
CHECK_VAL ( break_info . level , 0 ) ;
2006-05-30 03:36:51 +00:00
2006-07-19 18:35:07 +00:00
smbcli_close ( cli1 - > tree , fnum ) ;
2007-05-25 13:03:33 +00: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 18:35:07 +00:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
smbcli_oplock_handler ( cli2 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2007-05-25 13:03:33 +00:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2007-05-25 13:03:33 +00:00
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 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH13: open with batch oplock \n " ) ;
2006-07-19 18:35:07 +00:00
ZERO_STRUCT ( break_info ) ;
2007-05-25 13:03:33 +00:00
2006-07-19 18:35:07 +00:00
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 13:03:33 +00: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-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-07-19 18:35:07 +00:00
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
ZERO_STRUCT ( break_info ) ;
2007-03-05 21:28:55 +00:00
torture_comment ( tctx , " second open with attributes only and NTCREATEX_DISP_OVERWRITE dispostion causes oplock break \n " ) ;
2006-07-19 18:35:07 +00: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 13:03:33 +00:00
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE |
NTCREATEX_SHARE_ACCESS_DELETE ;
2006-07-19 18:35:07 +00:00
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OVERWRITE ;
2007-05-25 13:03:33 +00:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-07-19 18:35:07 +00:00
fnum2 = io . ntcreatex . out . file . fnum ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2006-07-19 18:35:07 +00:00
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
2009-12-01 15:29:00 -08:00
CHECK_VAL ( break_info . count , get_break_level1_to_none_count ( tctx ) ) ;
2006-07-19 18:35:07 +00:00
CHECK_VAL ( break_info . failures , 0 ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
2007-05-25 13:03:33 +00: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 18:35:07 +00:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2007-05-25 13:03:33 +00:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2007-05-25 13:03:33 +00:00
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 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH14: open with batch oplock \n " ) ;
2006-07-19 18:35:07 +00:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
2007-05-25 13:03:33 +00: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-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-07-19 18:35:07 +00:00
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
ZERO_STRUCT ( break_info ) ;
2007-03-05 21:28:55 +00:00
torture_comment ( tctx , " second open with attributes only and NTCREATEX_DISP_SUPERSEDE dispostion causes oplock break \n " ) ;
2006-07-19 18:35:07 +00: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 13:03:33 +00:00
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE |
NTCREATEX_SHARE_ACCESS_DELETE ;
2006-07-19 18:35:07 +00:00
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OVERWRITE ;
2007-05-25 13:03:33 +00:00
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
2007-03-05 21:28:55 +00:00
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2006-07-19 18:35:07 +00:00
fnum2 = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2009-12-01 15:29:00 -08:00
CHECK_VAL ( break_info . count , get_break_level1_to_none_count ( tctx ) ) ;
2006-07-19 18:35:07 +00:00
CHECK_VAL ( break_info . failures , 0 ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
2003-08-13 01:53:07 +00:00
done :
2007-05-25 13:03:33 +00:00
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
2003-08-13 01:53:07 +00:00
return ret ;
}
2008-02-26 14:52:50 +01:00
static bool test_raw_oplock_batch15 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch15.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_fileinfo qfi ;
uint16_t fnum = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2008-02-26 14:52:50 +01:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2008-02-26 14:52:50 +01:00
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 ;
/* Test if a qpathinfo all info on pathname breaks a batch oplock. */
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH15: Test if qpathinfo all info breaks a batch oplock (should not). \n " ) ;
2008-02-26 14:52:50 +01:00
ZERO_STRUCT ( break_info ) ;
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 . share_access = NTCREATEX_SHARE_ACCESS_NONE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_CREATE ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-02-26 14:52:50 +01: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 ( qfi ) ;
qfi . generic . level = RAW_FILEINFO_ALL_INFORMATION ;
qfi . generic . in . file . path = fname ;
status = smb_raw_pathinfo ( cli2 - > tree , tctx , & qfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-02-26 14:52:50 +01:00
CHECK_VAL ( break_info . count , 0 ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2008-02-27 09:41:44 +01:00
static bool test_raw_oplock_batch16 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch16.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 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
smbcli_oplock_handler ( cli2 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2008-02-27 09:41:44 +01:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2008-02-27 09:41:44 +01:00
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 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH16: open with batch oplock \n " ) ;
2008-02-27 09:41:44 +01:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
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 ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
ZERO_STRUCT ( break_info ) ;
torture_comment ( tctx , " second open with attributes only and NTCREATEX_DISP_OVERWRITE_IF dispostion causes oplock break \n " ) ;
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 ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE |
NTCREATEX_SHARE_ACCESS_DELETE ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OVERWRITE_IF ;
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum2 = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2009-12-01 15:29:00 -08:00
CHECK_VAL ( break_info . count , get_break_level1_to_none_count ( tctx ) ) ;
2008-02-27 09:41:44 +01:00
CHECK_VAL ( break_info . failures , 0 ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2008-02-27 10:41:47 +01:00
static bool test_raw_oplock_batch17 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname1 = BASEDIR " \\ test_batch17_1.dat " ;
const char * fname2 = BASEDIR " \\ test_batch17_2.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_rename rn ;
uint16_t fnum = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname1 ) ;
smbcli_unlink ( cli1 - > tree , fname2 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2008-02-27 10:41:47 +01:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2008-02-27 10:41:47 +01:00
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 = fname1 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH17: open a file with an batch oplock (share mode: none) \n " ) ;
2008-02-27 10:41:47 +01:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
torture_comment ( tctx , " rename should trigger a break \n " ) ;
ZERO_STRUCT ( rn ) ;
rn . generic . level = RAW_RENAME_RENAME ;
rn . rename . in . pattern1 = fname1 ;
rn . rename . in . pattern2 = fname2 ;
rn . rename . in . attrib = 0 ;
2009-09-08 13:12:26 -07:00
torture_comment ( tctx , " trying rename while first file open \n " ) ;
2008-02-27 10:41:47 +01:00
status = smb_raw_rename ( cli2 - > tree , & rn ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-02-27 10:41:47 +01:00
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2008-02-27 11:07:53 +01:00
static bool test_raw_oplock_batch18 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname1 = BASEDIR " \\ test_batch18_1.dat " ;
const char * fname2 = BASEDIR " \\ test_batch18_2.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_rename rn ;
uint16_t fnum = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname1 ) ;
smbcli_unlink ( cli1 - > tree , fname2 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2008-02-27 11:07:53 +01:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2008-02-27 11:07:53 +01:00
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 = fname1 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH18: open a file with an batch oplock (share mode: none) \n " ) ;
2008-02-27 11:07:53 +01:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
torture_comment ( tctx , " ntrename should trigger a break \n " ) ;
ZERO_STRUCT ( rn ) ;
rn . generic . level = RAW_RENAME_NTRENAME ;
rn . ntrename . in . attrib = 0 ;
rn . ntrename . in . flags = RENAME_FLAG_RENAME ;
rn . ntrename . in . old_name = fname1 ;
rn . ntrename . in . new_name = fname2 ;
2009-09-08 13:12:26 -07:00
torture_comment ( tctx , " trying rename while first file open \n " ) ;
2008-02-27 11:07:53 +01:00
status = smb_raw_rename ( cli2 - > tree , & rn ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-02-27 11:07:53 +01:00
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2008-02-27 15:43:04 +01:00
static bool test_raw_oplock_batch19 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname1 = BASEDIR " \\ test_batch19_1.dat " ;
const char * fname2 = BASEDIR " \\ test_batch19_2.dat " ;
const char * fname3 = BASEDIR " \\ test_batch19_3.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_fileinfo qfi ;
union smb_setfileinfo sfi ;
uint16_t fnum = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname1 ) ;
smbcli_unlink ( cli1 - > tree , fname2 ) ;
smbcli_unlink ( cli1 - > tree , fname3 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2008-02-27 15:43:04 +01:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2008-02-27 15:43:04 +01:00
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
2009-12-21 14:48:43 -08:00
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE ;
2008-02-27 15:43:04 +01:00
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 = fname1 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH19: open a file with an batch oplock (share mode: none) \n " ) ;
2008-02-27 15:43:04 +01:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
2009-12-01 17:40:30 -08:00
torture_comment ( tctx , " setpathinfo rename info should trigger a break "
" to none \n " ) ;
2008-02-27 15:43:04 +01:00
ZERO_STRUCT ( sfi ) ;
sfi . generic . level = RAW_SFILEINFO_RENAME_INFORMATION ;
sfi . generic . in . file . path = fname1 ;
sfi . rename_information . in . overwrite = 0 ;
sfi . rename_information . in . root_fid = 0 ;
sfi . rename_information . in . new_name = fname2 + strlen ( BASEDIR ) + 1 ;
status = smb_raw_setpathinfo ( cli2 - > tree , & sfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2009-12-01 17:40:30 -08:00
CHECK_VAL ( break_info . failures , 0 ) ;
if ( TARGET_IS_WINXP ( tctx ) ) {
/* Win XP breaks to level2. */
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
} else if ( TARGET_IS_W2K3 ( tctx ) | | TARGET_IS_W2K8 ( tctx ) | |
TARGET_IS_SAMBA3 ( tctx ) | | TARGET_IS_SAMBA4 ( tctx ) ) {
/* Win2K3/2k8 incorrectly doesn't break at all. */
CHECK_VAL ( break_info . count , 0 ) ;
} else {
/* win7/2k8r2 break to none. */
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_NONE ) ;
}
2008-02-27 15:43:04 +01:00
ZERO_STRUCT ( qfi ) ;
qfi . generic . level = RAW_FILEINFO_ALL_INFORMATION ;
qfi . generic . in . file . fnum = fnum ;
status = smb_raw_fileinfo ( cli1 - > tree , tctx , & qfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_STRMATCH ( qfi . all_info . out . fname . s , fname2 ) ;
2009-12-01 17:40:30 -08:00
/* Close and re-open file with oplock. */
smbcli_close ( cli1 - > tree , fnum ) ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
torture_comment ( tctx , " setfileinfo rename info on a client's own fid "
" should not trigger a break nor a violation \n " ) ;
ZERO_STRUCT ( break_info ) ;
2008-02-27 15:43:04 +01:00
ZERO_STRUCT ( sfi ) ;
sfi . generic . level = RAW_SFILEINFO_RENAME_INFORMATION ;
2008-03-11 10:21:09 -07:00
sfi . generic . in . file . fnum = fnum ;
sfi . rename_information . in . overwrite = 0 ;
sfi . rename_information . in . root_fid = 0 ;
sfi . rename_information . in . new_name = fname3 + strlen ( BASEDIR ) + 1 ;
status = smb_raw_setfileinfo ( cli1 - > tree , & sfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2009-12-01 17:40:30 -08:00
if ( TARGET_IS_WINXP ( tctx ) ) {
/* XP incorrectly breaks to level2. */
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
} else {
CHECK_VAL ( break_info . count , 0 ) ;
}
2008-03-11 10:21:09 -07:00
ZERO_STRUCT ( qfi ) ;
qfi . generic . level = RAW_FILEINFO_ALL_INFORMATION ;
qfi . generic . in . file . fnum = fnum ;
status = smb_raw_fileinfo ( cli1 - > tree , tctx , & qfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_STRMATCH ( qfi . all_info . out . fname . s , fname3 ) ;
done :
2009-12-21 14:38:45 -08:00
smbcli_close ( cli1 - > tree , fnum ) ;
2008-03-11 10:21:09 -07:00
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
/****************************************************
Called from raw - rename - we need oplock handling for
this test so this is why it ' s in oplock . c , not rename . c
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool test_trans2rename ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname1 = BASEDIR " \\ test_trans2rename_1.dat " ;
const char * fname2 = BASEDIR " \\ test_trans2rename_2.dat " ;
const char * fname3 = BASEDIR " \\ test_trans2rename_3.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_fileinfo qfi ;
union smb_setfileinfo sfi ;
uint16_t fnum = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname1 ) ;
smbcli_unlink ( cli1 - > tree , fname2 ) ;
smbcli_unlink ( cli1 - > tree , fname3 ) ;
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2008-03-11 10:21:09 -07:00
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
2009-12-21 14:48:43 -08:00
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE ;
2008-03-11 10:21:09 -07:00
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 = fname1 ;
torture_comment ( tctx , " open a file with an exclusive oplock (share mode: none) \n " ) ;
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , EXCLUSIVE_OPLOCK_RETURN ) ;
torture_comment ( tctx , " setpathinfo rename info should not trigger a break nor a violation \n " ) ;
ZERO_STRUCT ( sfi ) ;
sfi . generic . level = RAW_SFILEINFO_RENAME_INFORMATION ;
sfi . generic . in . file . path = fname1 ;
sfi . rename_information . in . overwrite = 0 ;
sfi . rename_information . in . root_fid = 0 ;
sfi . rename_information . in . new_name = fname2 + strlen ( BASEDIR ) + 1 ;
status = smb_raw_setpathinfo ( cli2 - > tree , & sfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-03-11 10:21:09 -07:00
CHECK_VAL ( break_info . count , 0 ) ;
ZERO_STRUCT ( qfi ) ;
qfi . generic . level = RAW_FILEINFO_ALL_INFORMATION ;
qfi . generic . in . file . fnum = fnum ;
status = smb_raw_fileinfo ( cli1 - > tree , tctx , & qfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_STRMATCH ( qfi . all_info . out . fname . s , fname2 ) ;
torture_comment ( tctx , " setfileinfo rename info should not trigger a break nor a violation \n " ) ;
ZERO_STRUCT ( sfi ) ;
sfi . generic . level = RAW_SFILEINFO_RENAME_INFORMATION ;
2008-02-27 15:43:04 +01:00
sfi . generic . in . file . fnum = fnum ;
sfi . rename_information . in . overwrite = 0 ;
sfi . rename_information . in . root_fid = 0 ;
sfi . rename_information . in . new_name = fname3 + strlen ( BASEDIR ) + 1 ;
status = smb_raw_setfileinfo ( cli1 - > tree , & sfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-02-27 15:43:04 +01:00
CHECK_VAL ( break_info . count , 0 ) ;
ZERO_STRUCT ( qfi ) ;
qfi . generic . level = RAW_FILEINFO_ALL_INFORMATION ;
qfi . generic . in . file . fnum = fnum ;
status = smb_raw_fileinfo ( cli1 - > tree , tctx , & qfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_STRMATCH ( qfi . all_info . out . fname . s , fname3 ) ;
done :
2009-12-21 14:38:45 -08:00
smbcli_close ( cli1 - > tree , fnum ) ;
2008-02-27 15:43:04 +01:00
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2008-03-11 15:27:08 -07:00
/****************************************************
Called from raw - rename - we need oplock handling for
this test so this is why it ' s in oplock . c , not rename . c
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool test_nttransrename ( struct torture_context * tctx , struct smbcli_state * cli1 )
{
const char * fname1 = BASEDIR " \\ test_nttransrename_1.dat " ;
const char * fname2 = BASEDIR " \\ test_nttransrename_2.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
2008-03-12 15:10:57 +01:00
union smb_fileinfo qfi , qpi ;
2008-03-11 15:27:08 -07:00
union smb_rename rn ;
uint16_t fnum = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname1 ) ;
smbcli_unlink ( cli1 - > tree , fname2 ) ;
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2009-02-10 16:51:47 -08:00
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_ALL ;
2008-03-11 15:27:08 -07: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 = fname1 ;
torture_comment ( tctx , " nttrans_rename: open a file with an exclusive oplock (share mode: none) \n " ) ;
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , EXCLUSIVE_OPLOCK_RETURN ) ;
2008-03-12 15:10:57 +01:00
torture_comment ( tctx , " nttrans_rename: should not trigger a break nor a share mode violation \n " ) ;
2008-03-11 15:27:08 -07:00
ZERO_STRUCT ( rn ) ;
rn . generic . level = RAW_RENAME_NTTRANS ;
rn . nttrans . in . file . fnum = fnum ;
rn . nttrans . in . flags = 0 ;
rn . nttrans . in . new_name = fname2 + strlen ( BASEDIR ) + 1 ;
status = smb_raw_rename ( cli1 - > tree , & rn ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-03-11 15:27:08 -07:00
CHECK_VAL ( break_info . count , 0 ) ;
2008-03-12 15:10:57 +01:00
/* w2k3 does nothing, it doesn't rename the file */
torture_comment ( tctx , " nttrans_rename: the server should have done nothing \n " ) ;
2008-03-11 15:27:08 -07:00
ZERO_STRUCT ( qfi ) ;
qfi . generic . level = RAW_FILEINFO_ALL_INFORMATION ;
qfi . generic . in . file . fnum = fnum ;
status = smb_raw_fileinfo ( cli1 - > tree , tctx , & qfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2008-03-12 15:10:57 +01:00
CHECK_STRMATCH ( qfi . all_info . out . fname . s , fname1 ) ;
2008-03-11 15:27:08 -07:00
2008-03-12 15:10:57 +01:00
ZERO_STRUCT ( qpi ) ;
qpi . generic . level = RAW_FILEINFO_ALL_INFORMATION ;
qpi . generic . in . file . path = fname1 ;
status = smb_raw_pathinfo ( cli1 - > tree , tctx , & qpi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_STRMATCH ( qpi . all_info . out . fname . s , fname1 ) ;
ZERO_STRUCT ( qpi ) ;
qpi . generic . level = RAW_FILEINFO_ALL_INFORMATION ;
qpi . generic . in . file . path = fname2 ;
status = smb_raw_pathinfo ( cli1 - > tree , tctx , & qpi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OBJECT_NAME_NOT_FOUND ) ;
torture_comment ( tctx , " nttrans_rename: after closing the file the file is still not renamed \n " ) ;
status = smbcli_close ( cli1 - > tree , fnum ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
ZERO_STRUCT ( qpi ) ;
qpi . generic . level = RAW_FILEINFO_ALL_INFORMATION ;
qpi . generic . in . file . path = fname1 ;
status = smb_raw_pathinfo ( cli1 - > tree , tctx , & qpi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_STRMATCH ( qpi . all_info . out . fname . s , fname1 ) ;
ZERO_STRUCT ( qpi ) ;
qpi . generic . level = RAW_FILEINFO_ALL_INFORMATION ;
qpi . generic . in . file . path = fname2 ;
status = smb_raw_pathinfo ( cli1 - > tree , tctx , & qpi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OBJECT_NAME_NOT_FOUND ) ;
torture_comment ( tctx , " nttrans_rename: rename with an invalid handle gives NT_STATUS_INVALID_HANDLE \n " ) ;
ZERO_STRUCT ( rn ) ;
rn . generic . level = RAW_RENAME_NTTRANS ;
rn . nttrans . in . file . fnum = fnum + 1 ;
rn . nttrans . in . flags = 0 ;
rn . nttrans . in . new_name = fname2 + strlen ( BASEDIR ) + 1 ;
status = smb_raw_rename ( cli1 - > tree , & rn ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_INVALID_HANDLE ) ;
2008-03-11 15:27:08 -07:00
done :
smb_raw_exit ( cli1 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2008-02-27 15:45:08 +01:00
static bool test_raw_oplock_batch20 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname1 = BASEDIR " \\ test_batch20_1.dat " ;
const char * fname2 = BASEDIR " \\ test_batch20_2.dat " ;
const char * fname3 = BASEDIR " \\ test_batch20_3.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_fileinfo qfi ;
union smb_setfileinfo sfi ;
uint16_t fnum = 0 , fnum2 = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname1 ) ;
smbcli_unlink ( cli1 - > tree , fname2 ) ;
smbcli_unlink ( cli1 - > tree , fname3 ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2008-02-27 15:45:08 +01:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2008-02-27 15:45:08 +01:00
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 = fname1 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH20: open a file with an batch oplock (share mode: all) \n " ) ;
2008-02-27 15:45:08 +01:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
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 ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
ZERO_STRUCT ( sfi ) ;
sfi . generic . level = RAW_SFILEINFO_RENAME_INFORMATION ;
sfi . generic . in . file . path = fname1 ;
sfi . rename_information . in . overwrite = 0 ;
sfi . rename_information . in . root_fid = 0 ;
sfi . rename_information . in . new_name = fname2 + strlen ( BASEDIR ) + 1 ;
status = smb_raw_setpathinfo ( cli2 - > tree , & sfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2009-12-01 17:40:30 -08:00
CHECK_VAL ( break_info . failures , 0 ) ;
if ( TARGET_IS_WINXP ( tctx ) ) {
/* Win XP breaks to level2. */
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
} else if ( TARGET_IS_W2K3 ( tctx ) | | TARGET_IS_W2K8 ( tctx ) | |
TARGET_IS_SAMBA3 ( tctx ) | | TARGET_IS_SAMBA4 ( tctx ) ) {
/* Win2K3/2k8 incorrectly doesn't break at all. */
CHECK_VAL ( break_info . count , 0 ) ;
} else {
/* win7/2k8r2 break to none. */
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_NONE ) ;
}
2008-02-27 15:45:08 +01:00
ZERO_STRUCT ( qfi ) ;
qfi . generic . level = RAW_FILEINFO_ALL_INFORMATION ;
qfi . generic . in . file . fnum = fnum ;
status = smb_raw_fileinfo ( cli1 - > tree , tctx , & qfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_STRMATCH ( qfi . all_info . out . fname . s , fname2 ) ;
torture_comment ( tctx , " open a file with the new name an batch oplock (share mode: all) \n " ) ;
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE |
NTCREATEX_SHARE_ACCESS_DELETE ;
io . ntcreatex . in . fname = fname2 ;
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum2 = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-02-27 15:45:08 +01:00
2009-12-01 17:40:30 -08:00
if ( TARGET_IS_WINXP ( tctx ) ) {
/* XP broke to level2, and doesn't break again. */
CHECK_VAL ( break_info . count , 0 ) ;
} else if ( TARGET_IS_W2K3 ( tctx ) | | TARGET_IS_W2K8 ( tctx ) | |
TARGET_IS_SAMBA3 ( tctx ) | | TARGET_IS_SAMBA4 ( tctx ) ) {
/* Win2K3 incorrectly didn't break before so break now. */
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
} else {
/* win7/2k8r2 broke to none, and doesn't break again. */
CHECK_VAL ( break_info . count , 0 ) ;
}
ZERO_STRUCT ( break_info ) ;
2008-02-27 15:45:08 +01:00
ZERO_STRUCT ( sfi ) ;
sfi . generic . level = RAW_SFILEINFO_RENAME_INFORMATION ;
sfi . generic . in . file . fnum = fnum ;
sfi . rename_information . in . overwrite = 0 ;
sfi . rename_information . in . root_fid = 0 ;
sfi . rename_information . in . new_name = fname3 + strlen ( BASEDIR ) + 1 ;
status = smb_raw_setfileinfo ( cli1 - > tree , & sfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2009-12-01 17:40:30 -08:00
CHECK_VAL ( break_info . count , 0 ) ;
2008-02-27 15:45:08 +01:00
ZERO_STRUCT ( qfi ) ;
qfi . generic . level = RAW_FILEINFO_ALL_INFORMATION ;
qfi . generic . in . file . fnum = fnum ;
status = smb_raw_fileinfo ( cli1 - > tree , tctx , & qfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_STRMATCH ( qfi . all_info . out . fname . s , fname3 ) ;
ZERO_STRUCT ( qfi ) ;
qfi . generic . level = RAW_FILEINFO_ALL_INFORMATION ;
qfi . generic . in . file . fnum = fnum2 ;
status = smb_raw_fileinfo ( cli2 - > tree , tctx , & qfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_STRMATCH ( qfi . all_info . out . fname . s , fname3 ) ;
done :
2009-12-21 14:38:45 -08:00
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
2008-02-27 15:45:08 +01:00
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2008-03-04 12:15:32 +01:00
static bool test_raw_oplock_batch21 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch21.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
struct smb_echo e ;
uint16_t fnum = 0 ;
char c = 0 ;
ssize_t wr ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2008-03-04 12:15:32 +01:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2008-03-04 12:15:32 +01:00
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 ;
/*
with a batch oplock we get a break
*/
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH21: open with batch oplock \n " ) ;
2008-03-04 12:15:32 +01:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
torture_comment ( tctx , " writing should not generate a break \n " ) ;
wr = smbcli_write ( cli1 - > tree , fnum , 0 , & c , 0 , 1 ) ;
CHECK_VAL ( wr , 1 ) ;
CHECK_STATUS ( tctx , smbcli_nt_error ( cli1 - > tree ) , NT_STATUS_OK ) ;
ZERO_STRUCT ( e ) ;
e . in . repeat_count = 1 ;
status = smb_raw_echo ( cli1 - > transport , & e ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-03-04 12:15:32 +01:00
CHECK_VAL ( break_info . count , 0 ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2008-03-04 14:08:32 +01:00
static bool test_raw_oplock_batch22 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch22.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
2009-12-03 13:16:18 -08:00
uint16_t fnum = 0 , fnum2 = 0 , fnum3 = 0 ;
2008-03-04 14:08:32 +01:00
struct timeval tv ;
int timeout = torture_setting_int ( tctx , " oplocktimeout " , 30 ) ;
int te ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2008-03-04 14:08:32 +01:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2008-03-04 14:08:32 +01:00
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 ;
/*
with a batch oplock we get a break
*/
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH22: open with batch oplock \n " ) ;
2008-03-04 14:08:32 +01:00
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
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 ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
2009-09-08 13:12:26 -07:00
torture_comment ( tctx , " a 2nd open should not succeed after the oplock "
" break timeout \n " ) ;
2008-03-04 14:08:32 +01:00
tv = timeval_current ( ) ;
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_timeout , cli1 - > tree ) ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
2009-12-02 18:39:05 -08:00
if ( TARGET_IS_W2K3 ( tctx ) ) {
/* 2k3 has an issue here. xp/win7 are ok. */
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
} else {
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
}
2009-12-03 13:16:18 -08:00
fnum2 = io . ntcreatex . out . file . fnum ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-03-04 14:08:32 +01:00
te = ( int ) timeval_elapsed ( & tv ) ;
2009-12-02 18:39:05 -08:00
/*
* Some servers detect clients that let oplocks timeout , so this check
* only shows a warning message instead failing the test to eliminate
* failures from repeated runs of the test . This isn ' t ideal , but
* it ' s better than not running the test at all .
*/
2008-03-04 14:08:32 +01:00
CHECK_RANGE ( te , timeout - 1 , timeout + 15 ) ;
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 ) ;
ZERO_STRUCT ( break_info ) ;
2009-09-08 13:12:26 -07:00
torture_comment ( tctx , " a 2nd open should succeed after the oplock "
" release without break \n " ) ;
2008-03-04 14:08:32 +01:00
tv = timeval_current ( ) ;
2008-03-06 16:27:13 +01:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2008-03-04 14:08:32 +01:00
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2010-05-13 21:27:24 -07:00
#if 0
/* Samba 3.6.0 and above behave as Windows. */
2009-12-02 18:39:05 -08:00
if ( TARGET_IS_SAMBA3 ( tctx ) ) {
/* samba3 doesn't grant additional oplocks to bad clients. */
CHECK_VAL ( io . ntcreatex . out . oplock_level , NO_OPLOCK_RETURN ) ;
} else {
CHECK_VAL ( io . ntcreatex . out . oplock_level ,
2010-05-13 21:27:24 -07:00
LEVEL_II_OPLOCK_RETURN ) ;
2009-12-02 18:39:05 -08:00
}
2010-05-13 21:27:24 -07:00
# else
CHECK_VAL ( io . ntcreatex . out . oplock_level ,
LEVEL_II_OPLOCK_RETURN ) ;
# endif
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-03-04 14:08:32 +01:00
te = ( int ) timeval_elapsed ( & tv ) ;
/* it should come in without delay */
CHECK_RANGE ( te + 1 , 0 , timeout ) ;
2009-12-03 13:16:18 -08:00
fnum3 = io . ntcreatex . out . file . fnum ;
2008-03-04 14:08:32 +01:00
CHECK_VAL ( break_info . count , 0 ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli1 - > tree , fnum2 ) ;
2009-12-03 13:16:18 -08:00
smbcli_close ( cli1 - > tree , fnum3 ) ;
2008-03-04 14:08:32 +01:00
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2008-03-06 15:54:07 +01:00
static bool test_raw_oplock_batch23 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch23.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
uint16_t fnum = 0 , fnum2 = 0 , fnum3 = 0 ;
struct smbcli_state * cli3 = NULL ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname ) ;
ret = open_connection_no_level2_oplocks ( tctx , & cli3 ) ;
CHECK_VAL ( ret , true ) ;
2009-09-25 16:44:51 -07:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
smbcli_oplock_handler ( cli2 - > transport , oplock_handler_ack_to_given , cli2 - > tree ) ;
smbcli_oplock_handler ( cli3 - > transport , oplock_handler_ack_to_given , cli3 - > tree ) ;
2008-03-06 15:54:07 +01:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2008-03-06 15:54:07 +01:00
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 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH23: a open and ask for a batch oplock \n " ) ;
2008-03-06 15:54:07 +01:00
ZERO_STRUCT ( break_info ) ;
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 ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
ZERO_STRUCT ( break_info ) ;
torture_comment ( tctx , " a 2nd open without level2 oplock support should generate a break to level2 \n " ) ;
status = smb_raw_open ( cli3 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum3 = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , NO_OPLOCK_RETURN ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-03-06 15:54:07 +01: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 ) ;
ZERO_STRUCT ( break_info ) ;
torture_comment ( tctx , " a 3rd open with level2 oplock support should not generate a break \n " ) ;
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum2 = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-03-06 15:54:07 +01:00
CHECK_VAL ( break_info . count , 0 ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
smbcli_close ( cli3 - > tree , fnum3 ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smb_raw_exit ( cli3 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2008-03-06 15:56:03 +01:00
static bool test_raw_oplock_batch24 ( struct torture_context * tctx , struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch24.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
uint16_t fnum2 = 0 , fnum3 = 0 ;
struct smbcli_state * cli3 = NULL ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname ) ;
ret = open_connection_no_level2_oplocks ( tctx , & cli3 ) ;
CHECK_VAL ( ret , true ) ;
2009-09-25 16:44:51 -07:00
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
smbcli_oplock_handler ( cli2 - > transport , oplock_handler_ack_to_given , cli2 - > tree ) ;
smbcli_oplock_handler ( cli3 - > transport , oplock_handler_ack_to_given , cli3 - > tree ) ;
2008-03-06 15:56:03 +01:00
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2008-03-06 15:56:03 +01:00
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 ;
2008-03-11 13:39:04 -07:00
torture_comment ( tctx , " BATCH24: a open without level support and ask for a batch oplock \n " ) ;
2008-03-06 15:56:03 +01:00
ZERO_STRUCT ( break_info ) ;
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 ;
status = smb_raw_open ( cli3 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum3 = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
ZERO_STRUCT ( break_info ) ;
torture_comment ( tctx , " a 2nd open with level2 oplock support should generate a break to none \n " ) ;
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum2 = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , LEVEL_II_OPLOCK_RETURN ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-03-06 15:56:03 +01:00
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . fnum , fnum3 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_NONE ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
smbcli_close ( cli3 - > tree , fnum3 ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smb_raw_exit ( cli3 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2008-10-14 13:29:03 +02:00
static bool test_raw_oplock_batch25 ( struct torture_context * tctx ,
struct smbcli_state * cli1 ,
struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch25.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 */
smbcli_unlink ( cli1 - > tree , fname ) ;
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2008-10-14 13:29:03 +02:00
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 , " BATCH25: open a file with an batch oplock "
" (share mode: none) \n " ) ;
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
torture_comment ( tctx , " setpathinfo attribute info should not trigger "
" a break nor a violation \n " ) ;
ZERO_STRUCT ( sfi ) ;
sfi . generic . level = RAW_SFILEINFO_SETATTR ;
sfi . generic . in . file . path = fname ;
sfi . setattr . in . attrib = FILE_ATTRIBUTE_HIDDEN ;
sfi . setattr . in . write_time = 0 ;
status = smb_raw_setpathinfo ( cli2 - > tree , & sfi ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2008-10-14 13:29:03 +02:00
CHECK_VAL ( break_info . count , 0 ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2009-12-03 13:46:11 -08:00
/**
* Similar to batch17 / 18 , but test with open share mode rather than
* share_none .
*/
static bool test_raw_oplock_batch26 ( struct torture_context * tctx ,
struct smbcli_state * cli1 , struct smbcli_state * cli2 )
{
const char * fname1 = BASEDIR " \\ test_batch26_1.dat " ;
const char * fname2 = BASEDIR " \\ test_batch26_2.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
union smb_rename rn ;
uint16_t fnum = 0 ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli1 - > tree , fname1 ) ;
smbcli_unlink ( cli1 - > tree , fname2 ) ;
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given ,
cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
io . ntcreatex . in . root_fid . fnum = 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_READ |
NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE ;
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 = fname1 ;
torture_comment ( tctx , " BATCH26: open a file with an batch oplock "
" (share mode: none) \n " ) ;
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
torture_comment ( tctx , " rename should trigger a break \n " ) ;
ZERO_STRUCT ( rn ) ;
rn . generic . level = RAW_RENAME_RENAME ;
rn . rename . in . pattern1 = fname1 ;
rn . rename . in . pattern2 = fname2 ;
rn . rename . in . attrib = 0 ;
torture_comment ( tctx , " trying rename while first file open \n " ) ;
status = smb_raw_rename ( cli2 - > tree , & rn ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
torture_wait_for_oplock_break ( tctx ) ;
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
/* Close and reopen with batch again. */
smbcli_close ( cli1 - > tree , fnum ) ;
ZERO_STRUCT ( break_info ) ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
/* Now try ntrename. */
torture_comment ( tctx , " ntrename should trigger a break \n " ) ;
ZERO_STRUCT ( rn ) ;
rn . generic . level = RAW_RENAME_NTRENAME ;
rn . ntrename . in . attrib = 0 ;
rn . ntrename . in . flags = RENAME_FLAG_RENAME ;
rn . ntrename . in . old_name = fname1 ;
rn . ntrename . in . new_name = fname2 ;
torture_comment ( tctx , " trying rename while first file open \n " ) ;
status = smb_raw_rename ( cli2 - > tree , & rn ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_SHARING_VIOLATION ) ;
torture_wait_for_oplock_break ( tctx ) ;
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2009-04-01 18:44:15 -07:00
/* Test how oplocks work on streams. */
static bool test_raw_oplock_stream1 ( struct torture_context * tctx ,
struct smbcli_state * cli1 ,
struct smbcli_state * cli2 )
{
NTSTATUS status ;
union smb_open io ;
const char * fname_base = BASEDIR " \\ test_stream1.txt " ;
const char * stream = " Stream One:$DATA " ;
const char * fname_stream , * fname_default_stream ;
const char * default_stream = " ::$DATA " ;
bool ret = true ;
int fnum = - 1 ;
int i ;
int stream_fnum = - 1 ;
uint32_t batch_req = NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK | NTCREATEX_FLAGS_EXTENDED ;
uint32_t exclusive_req = NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_EXTENDED ;
2009-09-29 19:03:20 -07:00
2009-09-10 12:14:53 +10:00
# define NSTREAM_OPLOCK_RESULTS 8
struct {
2009-09-29 19:03:20 -07:00
const char * * fname ;
2009-09-10 12:14:53 +10:00
bool open_base_file ;
uint32_t oplock_req ;
uint32_t oplock_granted ;
} stream_oplock_results [ NSTREAM_OPLOCK_RESULTS ] = {
/* Request oplock on stream without the base file open. */
2009-09-29 19:03:20 -07:00
{ & fname_stream , false , batch_req , NO_OPLOCK_RETURN } ,
{ & fname_default_stream , false , batch_req , NO_OPLOCK_RETURN } ,
{ & fname_stream , false , exclusive_req , EXCLUSIVE_OPLOCK_RETURN } ,
{ & fname_default_stream , false , exclusive_req , EXCLUSIVE_OPLOCK_RETURN } ,
2009-09-10 12:14:53 +10:00
/* Request oplock on stream with the base file open. */
2009-09-29 19:03:20 -07:00
{ & fname_stream , true , batch_req , NO_OPLOCK_RETURN } ,
{ & fname_default_stream , true , batch_req , NO_OPLOCK_RETURN } ,
{ & fname_stream , true , exclusive_req , EXCLUSIVE_OPLOCK_RETURN } ,
{ & fname_default_stream , true , exclusive_req , LEVEL_II_OPLOCK_RETURN } ,
2009-09-10 12:14:53 +10:00
} ;
2009-04-01 18:44:15 -07:00
/* Only passes against windows at the moment. */
if ( torture_setting_bool ( tctx , " samba3 " , false ) | |
torture_setting_bool ( tctx , " samba4 " , false ) ) {
torture_skip ( tctx , " STREAM1 disabled against samba3+4 \n " ) ;
}
fname_stream = talloc_asprintf ( tctx , " %s:%s " , fname_base , stream ) ;
fname_default_stream = talloc_asprintf ( tctx , " %s%s " , fname_base ,
default_stream ) ;
if ( ! torture_setup_dir ( cli1 , BASEDIR ) ) {
return false ;
}
smbcli_unlink ( cli1 - > tree , fname_base ) ;
smbcli_oplock_handler ( cli1 - > transport , oplock_handler_ack_to_given , cli1 - > tree ) ;
2009-09-25 16:44:51 -07:00
smbcli_oplock_handler ( cli2 - > transport , oplock_handler_ack_to_given , cli2 - > tree ) ;
2009-04-01 18:44:15 -07:00
/* Setup generic open parameters. */
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2009-04-01 18:44:15 -07:00
io . ntcreatex . in . access_mask = ( SEC_FILE_READ_DATA | SEC_FILE_WRITE_DATA |
SEC_FILE_APPEND_DATA | SEC_STD_READ_CONTROL ) ;
io . ntcreatex . in . create_options = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
/* Create the file with a stream */
io . ntcreatex . in . fname = fname_stream ;
io . ntcreatex . in . flags = 0 ;
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_CREATE ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
smbcli_close ( cli1 - > tree , io . ntcreatex . out . file . fnum ) ;
/* Change the disposition to open now that the file has been created. */
io . ntcreatex . in . open_disposition = NTCREATEX_DISP_OPEN ;
2009-09-29 19:03:20 -07:00
/* Try some permutations of taking oplocks on streams. */
2009-04-01 18:44:15 -07:00
for ( i = 0 ; i < NSTREAM_OPLOCK_RESULTS ; i + + ) {
2009-09-29 19:03:20 -07:00
const char * fname = * stream_oplock_results [ i ] . fname ;
2009-04-01 18:44:15 -07:00
bool open_base_file = stream_oplock_results [ i ] . open_base_file ;
uint32_t oplock_req = stream_oplock_results [ i ] . oplock_req ;
uint32_t oplock_granted =
stream_oplock_results [ i ] . oplock_granted ;
int base_fnum = - 1 ;
if ( open_base_file ) {
torture_comment ( tctx , " Opening base file: %s with "
2009-10-01 11:35:17 -07:00
" %d \n " , fname_base , batch_req ) ;
2009-04-01 18:44:15 -07:00
io . ntcreatex . in . fname = fname_base ;
io . ntcreatex . in . flags = batch_req ;
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_VAL ( io . ntcreatex . out . oplock_level ,
BATCH_OPLOCK_RETURN ) ;
base_fnum = io . ntcreatex . out . file . fnum ;
}
torture_comment ( tctx , " %d: Opening stream: %s with %d \n " , i ,
fname , oplock_req ) ;
io . ntcreatex . in . fname = fname ;
io . ntcreatex . in . flags = oplock_req ;
/* Do the open with the desired oplock on the stream. */
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , oplock_granted ) ;
smbcli_close ( cli1 - > tree , io . ntcreatex . out . file . fnum ) ;
/* Cleanup the base file if it was opened. */
if ( base_fnum ! = - 1 ) {
smbcli_close ( cli2 - > tree , base_fnum ) ;
}
}
/* Open the stream with an exclusive oplock. */
torture_comment ( tctx , " Opening stream: %s with %d \n " ,
fname_stream , exclusive_req ) ;
io . ntcreatex . in . fname = fname_stream ;
io . ntcreatex . in . flags = exclusive_req ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , EXCLUSIVE_OPLOCK_RETURN ) ;
stream_fnum = io . ntcreatex . out . file . fnum ;
/* Open the base file and see if it contends. */
ZERO_STRUCT ( break_info ) ;
torture_comment ( tctx , " Opening base file: %s with "
" %d \n " , fname_base , batch_req ) ;
io . ntcreatex . in . fname = fname_base ;
io . ntcreatex . in . flags = batch_req ;
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_VAL ( io . ntcreatex . out . oplock_level ,
BATCH_OPLOCK_RETURN ) ;
smbcli_close ( cli2 - > tree , io . ntcreatex . out . file . fnum ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2009-04-01 18:44:15 -07:00
CHECK_VAL ( break_info . count , 0 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
/* Open the stream again to see if it contends. */
ZERO_STRUCT ( break_info ) ;
torture_comment ( tctx , " Opening stream again: %s with "
" %d \n " , fname_base , batch_req ) ;
io . ntcreatex . in . fname = fname_stream ;
io . ntcreatex . in . flags = exclusive_req ;
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_VAL ( io . ntcreatex . out . oplock_level ,
LEVEL_II_OPLOCK_RETURN ) ;
smbcli_close ( cli2 - > tree , io . ntcreatex . out . file . fnum ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2009-04-01 18:44:15 -07:00
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
/* Close the stream. */
if ( stream_fnum ! = - 1 ) {
smbcli_close ( cli1 - > tree , stream_fnum ) ;
}
done :
smbcli_close ( cli1 - > tree , fnum ) ;
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
2009-09-08 13:19:44 -07:00
static bool test_raw_oplock_doc ( struct torture_context * tctx ,
struct smbcli_state * cli )
{
const char * fname = BASEDIR " \\ test_oplock_doc.dat " ;
NTSTATUS status ;
bool ret = true ;
union smb_open io ;
uint16_t fnum = 0 ;
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
return false ;
}
/* cleanup */
smbcli_unlink ( cli - > tree , fname ) ;
smbcli_oplock_handler ( cli - > transport , oplock_handler_ack_to_given ,
cli - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2009-09-08 13:19:44 -07:00
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 = NTCREATEX_OPTIONS_DELETE_ON_CLOSE ;
io . ntcreatex . in . impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS ;
io . ntcreatex . in . security_flags = 0 ;
io . ntcreatex . in . fname = fname ;
torture_comment ( tctx , " open a delete-on-close file with a batch "
" oplock \n " ) ;
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
status = smb_raw_open ( cli - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
smbcli_close ( cli - > tree , fnum ) ;
done :
smb_raw_exit ( cli - > session ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
/* Open a file with a batch oplock, then open it again from a second client
* requesting no oplock . Having two open file handles should break our own
* oplock during BRL acquisition .
*/
static bool test_raw_oplock_brl1 ( struct torture_context * tctx ,
struct smbcli_state * cli1 ,
struct smbcli_state * cli2 )
{
const char * fname = BASEDIR " \\ test_batch_brl.dat " ;
/*int fname, f;*/
bool ret = true ;
uint8_t buf [ 1000 ] ;
bool correct = true ;
union smb_open io ;
NTSTATUS status ;
uint16_t fnum = 0 ;
uint16_t 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_given ,
cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2009-09-08 13:19:44 -07:00
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_READ |
SEC_RIGHTS_FILE_WRITE ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE ;
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 ;
/*
with a batch oplock we get a break
*/
torture_comment ( tctx , " open with batch oplock \n " ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
/* create a file with bogus data */
memset ( buf , 0 , sizeof ( buf ) ) ;
if ( smbcli_write ( cli1 - > tree , fnum , 0 , buf , 0 , sizeof ( buf ) ) ! =
sizeof ( buf ) )
{
torture_comment ( tctx , " Failed to create file \n " ) ;
correct = false ;
goto done ;
}
torture_comment ( tctx , " a 2nd open should give a break \n " ) ;
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED ;
status = smb_raw_open ( cli2 - > tree , tctx , & io ) ;
fnum2 = io . ntcreatex . out . file . fnum ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
CHECK_VAL ( break_info . fnum , fnum ) ;
ZERO_STRUCT ( break_info ) ;
2009-09-25 16:44:51 -07:00
torture_comment ( tctx , " a self BRL acquisition should break to none \n " ) ;
2009-09-08 13:19:44 -07:00
status = smbcli_lock ( cli1 - > tree , fnum , 0 , 4 , 0 , WRITE_LOCK ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2009-09-08 13:19:44 -07:00
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_NONE ) ;
CHECK_VAL ( break_info . fnum , fnum ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
/* expect no oplock break */
ZERO_STRUCT ( break_info ) ;
status = smbcli_lock ( cli1 - > tree , fnum , 2 , 4 , 0 , WRITE_LOCK ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_LOCK_NOT_GRANTED ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2009-09-08 13:19:44 -07:00
CHECK_VAL ( break_info . count , 0 ) ;
CHECK_VAL ( break_info . level , 0 ) ;
CHECK_VAL ( break_info . fnum , 0 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli2 - > tree , fnum2 ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smb_raw_exit ( cli2 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
/* Open a file with a batch oplock on one client and then acquire a brl.
* We should not contend our own oplock .
*/
static bool test_raw_oplock_brl2 ( struct torture_context * tctx , struct smbcli_state * cli1 )
{
const char * fname = BASEDIR " \\ test_batch_brl.dat " ;
/*int fname, f;*/
bool ret = true ;
uint8_t buf [ 1000 ] ;
bool correct = true ;
union smb_open io ;
NTSTATUS status ;
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_given ,
cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2009-09-08 13:19:44 -07:00
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_READ |
SEC_RIGHTS_FILE_WRITE ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE ;
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 ;
/*
with a batch oplock we get a break
*/
torture_comment ( tctx , " open with batch oplock \n " ) ;
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
/* create a file with bogus data */
memset ( buf , 0 , sizeof ( buf ) ) ;
if ( smbcli_write ( cli1 - > tree , fnum , 0 , buf , 0 , sizeof ( buf ) ) ! =
sizeof ( buf ) )
{
torture_comment ( tctx , " Failed to create file \n " ) ;
correct = false ;
goto done ;
}
2009-09-25 16:44:51 -07:00
torture_comment ( tctx , " a self BRL acquisition should not break to "
" none \n " ) ;
2009-09-08 13:19:44 -07:00
status = smbcli_lock ( cli1 - > tree , fnum , 0 , 4 , 0 , WRITE_LOCK ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
status = smbcli_lock ( cli1 - > tree , fnum , 2 , 4 , 0 , WRITE_LOCK ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_LOCK_NOT_GRANTED ) ;
/* With one file handle open a BRL should not contend our oplock.
* Thus , no oplock break will be received and the entire break_info
* struct will be 0 */
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2009-09-08 13:19:44 -07:00
CHECK_VAL ( break_info . fnum , 0 ) ;
CHECK_VAL ( break_info . count , 0 ) ;
CHECK_VAL ( break_info . level , 0 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
/* Open a file with a batch oplock twice from one client and then acquire a
* brl . BRL acquisition should break our own oplock .
*/
static bool test_raw_oplock_brl3 ( struct torture_context * tctx ,
struct smbcli_state * cli1 )
{
const char * fname = BASEDIR " \\ test_batch_brl.dat " ;
bool ret = true ;
uint8_t buf [ 1000 ] ;
bool correct = true ;
union smb_open io ;
NTSTATUS status ;
uint16_t fnum = 0 ;
uint16_t 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_given ,
cli1 - > tree ) ;
/*
base ntcreatex parms
*/
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2009-09-08 13:19:44 -07:00
io . ntcreatex . in . access_mask = SEC_RIGHTS_FILE_READ |
SEC_RIGHTS_FILE_WRITE ;
io . ntcreatex . in . alloc_size = 0 ;
io . ntcreatex . in . file_attr = FILE_ATTRIBUTE_NORMAL ;
io . ntcreatex . in . share_access = NTCREATEX_SHARE_ACCESS_READ |
NTCREATEX_SHARE_ACCESS_WRITE ;
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 ;
/*
with a batch oplock we get a break
*/
torture_comment ( tctx , " open with batch oplock \n " ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED |
NTCREATEX_FLAGS_REQUEST_OPLOCK |
NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
fnum = io . ntcreatex . out . file . fnum ;
CHECK_VAL ( io . ntcreatex . out . oplock_level , BATCH_OPLOCK_RETURN ) ;
/* create a file with bogus data */
memset ( buf , 0 , sizeof ( buf ) ) ;
if ( smbcli_write ( cli1 - > tree , fnum , 0 , buf , 0 , sizeof ( buf ) ) ! =
sizeof ( buf ) )
{
torture_comment ( tctx , " Failed to create file \n " ) ;
correct = false ;
goto done ;
}
torture_comment ( tctx , " a 2nd open should give a break \n " ) ;
ZERO_STRUCT ( break_info ) ;
io . ntcreatex . in . flags = NTCREATEX_FLAGS_EXTENDED ;
status = smb_raw_open ( cli1 - > tree , tctx , & io ) ;
fnum2 = io . ntcreatex . out . file . fnum ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_LEVEL_II ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
CHECK_VAL ( break_info . fnum , fnum ) ;
ZERO_STRUCT ( break_info ) ;
2009-09-25 16:44:51 -07:00
torture_comment ( tctx , " a self BRL acquisition should break to none \n " ) ;
2009-09-08 13:19:44 -07:00
status = smbcli_lock ( cli1 - > tree , fnum , 0 , 4 , 0 , WRITE_LOCK ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_OK ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2009-09-08 13:19:44 -07:00
CHECK_VAL ( break_info . count , 1 ) ;
CHECK_VAL ( break_info . level , OPLOCK_BREAK_TO_NONE ) ;
CHECK_VAL ( break_info . fnum , fnum ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
/* expect no oplock break */
ZERO_STRUCT ( break_info ) ;
status = smbcli_lock ( cli1 - > tree , fnum , 2 , 4 , 0 , WRITE_LOCK ) ;
CHECK_STATUS ( tctx , status , NT_STATUS_LOCK_NOT_GRANTED ) ;
2009-09-25 16:44:51 -07:00
torture_wait_for_oplock_break ( tctx ) ;
2009-09-08 13:19:44 -07:00
CHECK_VAL ( break_info . count , 0 ) ;
CHECK_VAL ( break_info . level , 0 ) ;
CHECK_VAL ( break_info . fnum , 0 ) ;
CHECK_VAL ( break_info . failures , 0 ) ;
smbcli_close ( cli1 - > tree , fnum ) ;
smbcli_close ( cli1 - > tree , fnum2 ) ;
done :
smb_raw_exit ( cli1 - > session ) ;
smbcli_deltree ( cli1 - > tree , BASEDIR ) ;
return ret ;
}
/*
2003-08-13 01:53:07 +00:00
basic testing of oplocks
*/
2007-08-28 12:54:27 +00:00
struct torture_suite * torture_raw_oplock ( TALLOC_CTX * mem_ctx )
2003-08-13 01:53:07 +00:00
{
2007-08-28 12:54:27 +00:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " OPLOCK " ) ;
2007-05-25 13:03:33 +00:00
2008-02-26 14:58:00 +01:00
torture_suite_add_2smb_test ( suite , " EXCLUSIVE1 " , test_raw_oplock_exclusive1 ) ;
2008-02-26 15:51:17 +01:00
torture_suite_add_2smb_test ( suite , " EXCLUSIVE2 " , test_raw_oplock_exclusive2 ) ;
2008-02-26 16:16:31 +01:00
torture_suite_add_2smb_test ( suite , " EXCLUSIVE3 " , test_raw_oplock_exclusive3 ) ;
2008-02-27 08:51:25 +01:00
torture_suite_add_2smb_test ( suite , " EXCLUSIVE4 " , test_raw_oplock_exclusive4 ) ;
2008-02-27 10:02:52 +01:00
torture_suite_add_2smb_test ( suite , " EXCLUSIVE5 " , test_raw_oplock_exclusive5 ) ;
2008-02-27 10:40:19 +01:00
torture_suite_add_2smb_test ( suite , " EXCLUSIVE6 " , test_raw_oplock_exclusive6 ) ;
2009-12-02 11:39:50 -08:00
torture_suite_add_2smb_test ( suite , " EXCLUSIVE7 " , test_raw_oplock_exclusive7 ) ;
2007-05-25 13:03:33 +00:00
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 ) ;
2008-02-26 14:52:50 +01:00
torture_suite_add_2smb_test ( suite , " BATCH15 " , test_raw_oplock_batch15 ) ;
2008-02-27 09:41:44 +01:00
torture_suite_add_2smb_test ( suite , " BATCH16 " , test_raw_oplock_batch16 ) ;
2008-02-27 10:41:47 +01:00
torture_suite_add_2smb_test ( suite , " BATCH17 " , test_raw_oplock_batch17 ) ;
2008-02-27 11:07:53 +01:00
torture_suite_add_2smb_test ( suite , " BATCH18 " , test_raw_oplock_batch18 ) ;
2008-02-27 15:43:04 +01:00
torture_suite_add_2smb_test ( suite , " BATCH19 " , test_raw_oplock_batch19 ) ;
2008-02-27 15:45:08 +01:00
torture_suite_add_2smb_test ( suite , " BATCH20 " , test_raw_oplock_batch20 ) ;
2008-03-04 12:15:32 +01:00
torture_suite_add_2smb_test ( suite , " BATCH21 " , test_raw_oplock_batch21 ) ;
2008-03-04 14:08:32 +01:00
torture_suite_add_2smb_test ( suite , " BATCH22 " , test_raw_oplock_batch22 ) ;
2008-03-06 15:54:07 +01:00
torture_suite_add_2smb_test ( suite , " BATCH23 " , test_raw_oplock_batch23 ) ;
2008-03-06 15:56:03 +01:00
torture_suite_add_2smb_test ( suite , " BATCH24 " , test_raw_oplock_batch24 ) ;
2008-10-14 13:29:03 +02:00
torture_suite_add_2smb_test ( suite , " BATCH25 " , test_raw_oplock_batch25 ) ;
2009-12-03 13:46:11 -08:00
torture_suite_add_2smb_test ( suite , " BATCH26 " , test_raw_oplock_batch26 ) ;
2009-04-01 18:44:15 -07:00
torture_suite_add_2smb_test ( suite , " STREAM1 " , test_raw_oplock_stream1 ) ;
2009-09-08 13:19:44 -07:00
torture_suite_add_1smb_test ( suite , " DOC1 " , test_raw_oplock_doc ) ;
torture_suite_add_2smb_test ( suite , " BRL1 " , test_raw_oplock_brl1 ) ;
torture_suite_add_1smb_test ( suite , " BRL2 " , test_raw_oplock_brl2 ) ;
torture_suite_add_1smb_test ( suite , " BRL3 " , test_raw_oplock_brl3 ) ;
2007-05-25 13:03:33 +00:00
return suite ;
2006-04-10 04:51:52 +00:00
}
2009-09-08 13:19:44 -07:00
/*
2006-04-10 04:51:52 +00:00
stress testing of oplocks
*/
2007-10-06 22:28:14 +00:00
bool torture_bench_oplock ( struct torture_context * torture )
2006-04-10 04:51:52 +00:00
{
struct smbcli_state * * cli ;
2007-10-06 22:28:14 +00:00
bool ret = true ;
2006-04-10 04:51:52 +00:00
TALLOC_CTX * mem_ctx = talloc_new ( torture ) ;
2007-08-26 18:24:12 +00:00
int torture_nprocs = torture_setting_int ( torture , " nprocs " , 4 ) ;
2006-04-10 04:51:52 +00:00
int i , count = 0 ;
2006-10-18 14:23:19 +00:00
int timelimit = torture_setting_int ( torture , " timelimit " , 10 ) ;
2006-04-10 04:51:52 +00:00
union smb_open io ;
struct timeval tv ;
cli = talloc_array ( mem_ctx , struct smbcli_state * , torture_nprocs ) ;
2007-03-05 21:28:55 +00:00
torture_comment ( torture , " Opening %d connections \n " , torture_nprocs ) ;
2006-04-10 04:51:52 +00:00
for ( i = 0 ; i < torture_nprocs ; i + + ) {
2008-04-16 23:06:27 +02:00
if ( ! torture_open_connection_ev ( & cli [ i ] , i , torture , torture - > ev ) ) {
2007-10-06 22:28:14 +00:00
return false ;
2006-04-10 04:51:52 +00:00
}
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 ) ) {
2007-10-06 22:28:14 +00:00
ret = false ;
2006-04-10 04:51:52 +00:00
goto done ;
2003-08-13 01:53:07 +00:00
}
2006-04-10 04:51:52 +00:00
io . ntcreatex . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2006-04-10 04:51:52 +00:00
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 05:12:49 +00: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-05 21:28:55 +00:00
torture_comment ( torture , " Running for %d seconds \n " , timelimit ) ;
2006-04-10 04:51:52 +00: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-05 21:28:55 +00:00
CHECK_STATUS ( torture , status , NT_STATUS_OK ) ;
2006-04-10 04:51:52 +00:00
count + + ;
}
2007-04-29 21:37:29 +00:00
if ( torture_setting_bool ( torture , " progress " , true ) ) {
torture_comment ( torture , " %.2f ops/second \r " , count / timeval_elapsed ( & tv ) ) ;
}
2006-04-10 04:51:52 +00:00
}
2007-03-05 21:28:55 +00:00
torture_comment ( torture , " %.2f ops/second \n " , count / timeval_elapsed ( & tv ) ) ;
2006-04-10 04:51:52 +00: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 07:08:20 +00:00
talloc_free ( mem_ctx ) ;
2003-08-13 01:53:07 +00:00
return ret ;
}
2007-08-29 04:33:26 +00:00
static struct hold_oplock_info {
const char * fname ;
bool close_on_break ;
uint32_t share_access ;
uint16_t fnum ;
} hold_info [ ] = {
2007-10-06 22:28:14 +00:00
{ BASEDIR " \\ notshared_close " , true ,
2007-08-29 04:33:26 +00:00
NTCREATEX_SHARE_ACCESS_NONE , } ,
2007-10-06 22:28:14 +00:00
{ BASEDIR " \\ notshared_noclose " , false ,
2007-08-29 04:33:26 +00:00
NTCREATEX_SHARE_ACCESS_NONE , } ,
2007-10-06 22:28:14 +00:00
{ BASEDIR " \\ shared_close " , true ,
2007-08-29 04:33:26 +00:00
NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE , } ,
2007-10-06 22:28:14 +00:00
{ BASEDIR " \\ shared_noclose " , false ,
2007-08-29 04:33:26 +00:00
NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE , } ,
} ;
2007-09-07 15:08:14 +00:00
static bool oplock_handler_hold ( struct smbcli_transport * transport ,
uint16_t tid , uint16_t fnum , uint8_t level ,
2009-02-02 08:44:44 +01:00
void * private_data )
2007-08-29 04:33:26 +00:00
{
2009-02-02 08:44:44 +01:00
struct smbcli_tree * tree = ( struct smbcli_tree * ) private_data ;
2007-08-29 04:33:26 +00:00
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 ) ;
2007-10-06 22:28:14 +00:00
return false ;
2007-08-29 04:33:26 +00:00
}
info = & hold_info [ i ] ;
if ( info - > close_on_break ) {
printf ( " oplock break on %s - closing \n " ,
info - > fname ) ;
2009-02-02 08:44:44 +01:00
oplock_handler_close ( transport , tid , fnum , level , private_data ) ;
2007-10-06 22:28:14 +00:00
return true ;
2007-08-29 04:33:26 +00:00
}
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 )
*/
2007-10-06 22:28:14 +00:00
bool torture_hold_oplock ( struct torture_context * torture ,
2007-08-29 04:33:26 +00:00
struct smbcli_state * cli )
{
2008-12-29 20:24:57 +01:00
struct tevent_context * ev =
( struct tevent_context * ) cli - > transport - > socket - > event . ctx ;
2007-08-29 04:33:26 +00:00
int i ;
printf ( " Setting up open files with oplocks in %s \n " , BASEDIR ) ;
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2007-10-06 22:28:14 +00:00
return false ;
2007-08-29 04:33:26 +00:00
}
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 ;
2007-10-18 01:37:46 +02:00
char c = 1 ;
2007-08-29 04:33:26 +00:00
io . generic . level = RAW_OPEN_NTCREATEX ;
2009-10-15 18:26:19 +11:00
io . ntcreatex . in . root_fid . fnum = 0 ;
2007-08-29 04:33:26 +00:00
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 ) ) ;
2007-10-06 22:28:14 +00:00
return false ;
2007-08-29 04:33:26 +00:00
}
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 ) ;
2007-10-06 22:28:14 +00:00
return false ;
2007-08-29 04:33:26 +00:00
}
hold_info [ i ] . fnum = io . ntcreatex . out . file . fnum ;
2007-10-18 01:37:46 +02:00
/* make the file non-zero size */
if ( smbcli_write ( cli - > tree , hold_info [ i ] . fnum , 0 , & c , 0 , 1 ) ! = 1 ) {
printf ( " Failed to write to file \n " ) ;
return false ;
}
2007-08-29 04:33:26 +00:00
}
printf ( " Waiting for oplock events \n " ) ;
event_loop_wait ( ev ) ;
2007-10-06 22:28:14 +00:00
return true ;
2007-08-29 04:33:26 +00:00
}