2016-09-29 08:41:01 +02:00
/*
Unix SMB / CIFS implementation .
test suite for SMB2 leases
Copyright ( C ) Zachary Loafman 2009
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
the Free Software Foundation ; either version 3 of the License , or
( 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
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include <tevent.h>
# include "libcli/smb2/smb2.h"
# include "libcli/smb2/smb2_calls.h"
# include "torture/torture.h"
# include "torture/smb2/proto.h"
# include "torture/util.h"
# include "libcli/smb/smbXcli_base.h"
# include "lease_break_handler.h"
struct lease_break_info lease_break_info ;
void torture_lease_break_callback ( struct smb2_request * req )
{
NTSTATUS status ;
status = smb2_lease_break_ack_recv ( req , & lease_break_info . lease_break_ack ) ;
if ( ! NT_STATUS_IS_OK ( status ) )
lease_break_info . failures + + ;
return ;
}
/* a lease break request handler */
bool torture_lease_handler ( struct smb2_transport * transport ,
const struct smb2_lease_break * lb ,
void * private_data )
{
struct smb2_tree * tree = private_data ;
struct smb2_lease_break_ack io ;
struct smb2_request * req ;
2021-03-17 13:49:28 +01:00
const char * action = NULL ;
char * ls = smb2_util_lease_state_string ( lease_break_info . tctx ,
lb - > new_lease_state ) ;
if ( lb - > break_flags & SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED ) {
action = " acking " ;
} else {
action = " received " ;
}
2016-09-29 08:41:01 +02:00
lease_break_info . lease_transport = transport ;
lease_break_info . lease_break = * lb ;
lease_break_info . count + + ;
if ( lease_break_info . lease_skip_ack ) {
2021-03-17 13:49:28 +01:00
torture_comment ( lease_break_info . tctx ,
" transport[%p] Skip %s to %s in lease handler \n " ,
transport , action , ls ) ;
2016-09-29 08:41:01 +02:00
return true ;
}
2021-03-17 13:49:28 +01:00
torture_comment ( lease_break_info . tctx ,
" transport[%p] %s to %s in lease handler \n " ,
transport , action , ls ) ;
2016-09-29 08:41:01 +02:00
if ( lb - > break_flags & SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED ) {
ZERO_STRUCT ( io ) ;
io . in . lease . lease_key = lb - > current_lease . lease_key ;
io . in . lease . lease_state = lb - > new_lease_state ;
req = smb2_lease_break_ack_send ( tree , & io ) ;
req - > async . fn = torture_lease_break_callback ;
req - > async . private_data = NULL ;
}
return true ;
}
2019-03-16 12:25:07 +00:00
/*
* A lease break handler which ignores incoming lease break requests
* To be used in cases where the client is expected to ignore incoming
* lease break requests
*/
bool torture_lease_ignore_handler ( struct smb2_transport * transport ,
const struct smb2_lease_break * lb ,
void * private_data )
{
return true ;
}
2016-09-29 08:41:01 +02: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
*/
void torture_wait_for_lease_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 = lease_break_info . count ;
2018-05-28 17:24:54 +05:30
/* Wait 1 second for an lease break */
ne = tevent_timeval_current_ofs ( 0 , 1000000 ) ;
2016-09-29 08:41:01 +02:00
te = tevent_add_timer ( tctx - > ev , tmp_ctx , ne , timeout_cb , & timesup ) ;
if ( te = = NULL ) {
2021-03-17 13:49:28 +01:00
torture_comment ( tctx , " Failed to wait for an lease break. "
" test results may not be accurate. \n " ) ;
2016-09-29 08:41:01 +02:00
goto done ;
}
2021-03-17 13:49:28 +01:00
torture_comment ( tctx , " Waiting for a potential lease break... \n " ) ;
2016-09-29 08:41:01 +02:00
while ( ! timesup & & lease_break_info . count < old_count + 1 ) {
if ( tevent_loop_once ( tctx - > ev ) ! = 0 ) {
2021-03-17 13:49:28 +01:00
torture_comment ( tctx , " Failed to wait for a lease "
2016-09-29 08:41:01 +02:00
" break. test results may not be "
2021-03-17 13:49:28 +01:00
" accurate. \n " ) ;
2016-09-29 08:41:01 +02:00
goto done ;
}
}
2021-03-17 13:49:28 +01:00
if ( timesup ) {
torture_comment ( tctx , " ... waiting for a lease break timed out \n " ) ;
} else {
torture_comment ( tctx , " Got %u lease breaks \n " ,
lease_break_info . count - old_count ) ;
}
2016-09-29 08:41:01 +02:00
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 ;
}