2003-08-13 05:53:07 +04:00
/*
Unix SMB / CIFS implementation .
test suite for various lock operations
Copyright ( C ) Andrew Tridgell 2003
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2003-08-13 05:53:07 +04:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2003-08-13 05:53:07 +04:00
*/
# include "includes.h"
2006-01-03 16:41:17 +03:00
# include "torture/torture.h"
2004-11-01 04:03:22 +03:00
# include "libcli/raw/libcliraw.h"
2008-04-02 06:53:27 +04:00
# include "libcli/raw/raw_proto.h"
2004-11-02 03:24:21 +03:00
# include "system/time.h"
2005-02-10 08:09:35 +03:00
# include "system/filesys.h"
2006-01-03 18:40:05 +03:00
# include "libcli/libcli.h"
2006-03-17 20:59:58 +03:00
# include "torture/util.h"
2006-05-15 16:25:03 +04:00
# include "libcli/composite/composite.h"
# include "libcli/smb_composite/smb_composite.h"
# include "lib/cmdline/popt_common.h"
2007-09-08 16:42:09 +04:00
# include "param/param.h"
2011-03-19 02:42:42 +03:00
# include "torture/raw/proto.h"
2003-08-13 05:53:07 +04:00
# define CHECK_STATUS(status, correct) do { \
if ( ! NT_STATUS_EQUAL ( status , correct ) ) { \
2009-04-24 14:28:59 +04:00
torture_result ( tctx , TORTURE_FAIL , \
" (%s) Incorrect status %s - should be %s \n " , \
__location__ , nt_errstr ( status ) , nt_errstr ( correct ) ) ; \
2007-10-07 02:28:14 +04:00
ret = false ; \
2003-08-13 05:53:07 +04:00
goto done ; \
} } while ( 0 )
2009-02-10 08:58:50 +03:00
# define CHECK_STATUS_CONT(status, correct) do { \
if ( ! NT_STATUS_EQUAL ( status , correct ) ) { \
2009-04-24 14:28:59 +04:00
torture_result ( tctx , TORTURE_FAIL , \
" (%s) Incorrect status %s - should be %s \n " , \
__location__ , nt_errstr ( status ) , nt_errstr ( correct ) ) ; \
2009-02-10 08:58:50 +03:00
ret = false ; \
} } while ( 0 )
# define CHECK_STATUS_OR(status, correct1, correct2) do { \
if ( ( ! NT_STATUS_EQUAL ( status , correct1 ) ) & & \
( ! NT_STATUS_EQUAL ( status , correct2 ) ) ) { \
2009-04-24 14:28:59 +04:00
torture_result ( tctx , TORTURE_FAIL , \
" (%s) Incorrect status %s - should be %s or %s \n " , \
__location__ , nt_errstr ( status ) , nt_errstr ( correct1 ) , \
nt_errstr ( correct2 ) ) ; \
2009-02-10 08:58:50 +03:00
ret = false ; \
goto done ; \
} } while ( 0 )
# define CHECK_STATUS_OR_CONT(status, correct1, correct2) do { \
if ( ( ! NT_STATUS_EQUAL ( status , correct1 ) ) & & \
( ! NT_STATUS_EQUAL ( status , correct2 ) ) ) { \
2009-04-24 14:28:59 +04:00
torture_result ( tctx , TORTURE_FAIL , \
" (%s) Incorrect status %s - should be %s or %s \n " , \
__location__ , nt_errstr ( status ) , nt_errstr ( correct1 ) , \
nt_errstr ( correct2 ) ) ; \
2009-02-10 08:58:50 +03:00
ret = false ; \
} } while ( 0 )
2003-08-13 05:53:07 +04:00
# define BASEDIR "\\testlock"
2009-11-25 03:58:25 +03:00
# define TARGET_IS_W2K8(_tctx) (torture_setting_bool(_tctx, "w2k8", false))
# define TARGET_IS_WIN7(_tctx) (torture_setting_bool(_tctx, "win7", false))
2009-12-04 06:32:53 +03:00
# define TARGET_IS_WINDOWS(_tctx) \
( ( torture_setting_bool ( _tctx , " w2k3 " , false ) ) | | \
( torture_setting_bool ( _tctx , " w2k8 " , false ) ) | | \
( torture_setting_bool ( _tctx , " win7 " , false ) ) )
2009-11-25 03:58:25 +03:00
# define TARGET_IS_SAMBA3(_tctx) (torture_setting_bool(_tctx, "samba3", false))
# define TARGET_IS_SAMBA4(_tctx) (torture_setting_bool(_tctx, "samba4", false))
2009-12-05 01:02:52 +03:00
# define TARGET_SUPPORTS_INVALID_LOCK_RANGE(_tctx) \
( torture_setting_bool ( _tctx , " invalid_lock_range_support " , true ) )
2010-01-11 03:06:57 +03:00
# define TARGET_SUPPORTS_SMBEXIT(_tctx) \
( torture_setting_bool ( _tctx , " smbexit_pdu_support " , true ) )
2009-12-05 01:02:52 +03:00
# define TARGET_SUPPORTS_SMBLOCK(_tctx) \
( torture_setting_bool ( _tctx , " smblock_pdu_support " , true ) )
# define TARGET_SUPPORTS_OPENX_DENY_DOS(_tctx) \
( torture_setting_bool ( _tctx , " openx_deny_dos_support " , true ) )
2010-01-11 03:06:57 +03:00
# define TARGET_RETURNS_RANGE_NOT_LOCKED(_tctx) \
( torture_setting_bool ( _tctx , " range_not_locked_on_file_close " , true ) )
2003-08-13 05:53:07 +04:00
/*
test SMBlock and SMBunlock ops
*/
2007-08-28 16:54:27 +04:00
static bool test_lock ( struct torture_context * tctx , struct smbcli_state * cli )
2003-08-13 05:53:07 +04:00
{
union smb_lock io ;
NTSTATUS status ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2003-08-13 05:53:07 +04:00
int fnum ;
const char * fname = BASEDIR " \\ test.txt " ;
2009-11-25 03:58:25 +03:00
if ( ! TARGET_SUPPORTS_SMBLOCK ( tctx ) )
torture_skip ( tctx , " Target does not support the SMBlock PDU " ) ;
2012-05-18 09:43:31 +04:00
torture_assert ( tctx , torture_setup_dir ( cli , BASEDIR ) , " Failed to setup up test directory: " BASEDIR ) ;
2003-08-13 05:53:07 +04:00
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Testing RAW_LOCK_LOCK \n " ) ;
2003-08-13 05:53:07 +04:00
io . generic . level = RAW_LOCK_LOCK ;
2004-08-04 17:23:35 +04:00
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( fnum ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to create %s - %s \n " ,
fname , smbcli_errstr ( cli - > tree ) ) ) ;
2003-08-13 05:53:07 +04:00
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Trying 0/0 lock \n " ) ;
2003-08-13 05:53:07 +04:00
io . lock . level = RAW_LOCK_LOCK ;
2006-03-13 01:48:25 +03:00
io . lock . in . file . fnum = fnum ;
2003-08-13 05:53:07 +04:00
io . lock . in . count = 0 ;
io . lock . in . offset = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
cli - > session - > pid + + ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
cli - > session - > pid - - ;
io . lock . level = RAW_LOCK_UNLOCK ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Trying 0/1 lock \n " ) ;
2003-08-13 05:53:07 +04:00
io . lock . level = RAW_LOCK_LOCK ;
2006-03-13 01:48:25 +03:00
io . lock . in . file . fnum = fnum ;
2003-08-13 05:53:07 +04:00
io . lock . in . count = 1 ;
io . lock . in . offset = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
cli - > session - > pid + + ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_LOCK_NOT_GRANTED ) ;
cli - > session - > pid - - ;
io . lock . level = RAW_LOCK_UNLOCK ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
io . lock . level = RAW_LOCK_UNLOCK ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Trying 0xEEFFFFFF lock \n " ) ;
2004-10-18 11:40:17 +04:00
io . lock . level = RAW_LOCK_LOCK ;
2006-03-13 01:48:25 +03:00
io . lock . in . file . fnum = fnum ;
2004-10-18 11:40:17 +04:00
io . lock . in . count = 4000 ;
io . lock . in . offset = 0xEEFFFFFF ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
cli - > session - > pid + + ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_LOCK_NOT_GRANTED ) ;
cli - > session - > pid - - ;
io . lock . level = RAW_LOCK_UNLOCK ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
io . lock . level = RAW_LOCK_UNLOCK ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Trying 0xEF000000 lock \n " ) ;
2004-10-18 11:40:17 +04:00
io . lock . level = RAW_LOCK_LOCK ;
2006-03-13 01:48:25 +03:00
io . lock . in . file . fnum = fnum ;
2004-10-18 11:40:17 +04:00
io . lock . in . count = 4000 ;
io . lock . in . offset = 0xEEFFFFFF ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
cli - > session - > pid + + ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
cli - > session - > pid - - ;
io . lock . level = RAW_LOCK_UNLOCK ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
io . lock . level = RAW_LOCK_UNLOCK ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Trying max lock \n " ) ;
2003-08-13 05:53:07 +04:00
io . lock . level = RAW_LOCK_LOCK ;
2006-03-13 01:48:25 +03:00
io . lock . in . file . fnum = fnum ;
2003-08-13 05:53:07 +04:00
io . lock . in . count = 4000 ;
2004-10-18 11:40:17 +04:00
io . lock . in . offset = 0xEF000000 ;
2003-08-13 05:53:07 +04:00
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
cli - > session - > pid + + ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
cli - > session - > pid - - ;
io . lock . level = RAW_LOCK_UNLOCK ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
io . lock . level = RAW_LOCK_UNLOCK ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Trying wrong pid unlock \n " ) ;
2003-08-13 05:53:07 +04:00
io . lock . level = RAW_LOCK_LOCK ;
2006-03-13 01:48:25 +03:00
io . lock . in . file . fnum = fnum ;
2003-08-13 05:53:07 +04:00
io . lock . in . count = 4002 ;
io . lock . in . offset = 10001 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
cli - > session - > pid + + ;
io . lock . level = RAW_LOCK_UNLOCK ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
cli - > session - > pid - - ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
done :
2004-08-04 17:23:35 +04:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 05:53:07 +04:00
smb_raw_exit ( cli - > session ) ;
2004-08-04 17:23:35 +04:00
smbcli_deltree ( cli - > tree , BASEDIR ) ;
2003-08-13 05:53:07 +04:00
return ret ;
}
/*
test locking & X ops
*/
2007-08-28 16:54:27 +04:00
static bool test_lockx ( struct torture_context * tctx , struct smbcli_state * cli )
2003-08-13 05:53:07 +04:00
{
union smb_lock io ;
struct smb_lock_entry lock [ 1 ] ;
NTSTATUS status ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2003-08-13 05:53:07 +04:00
int fnum ;
const char * fname = BASEDIR " \\ test.txt " ;
2012-05-18 09:43:31 +04:00
torture_assert ( tctx , torture_setup_dir ( cli , BASEDIR ) , " Failed to setup up test directory: " BASEDIR ) ;
2003-08-13 05:53:07 +04:00
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Testing RAW_LOCK_LOCKX \n " ) ;
2003-08-13 05:53:07 +04:00
io . generic . level = RAW_LOCK_LOCKX ;
2004-08-04 17:23:35 +04:00
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( fnum ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to create %s - %s \n " ,
fname , smbcli_errstr ( cli - > tree ) ) ) ;
2003-08-13 05:53:07 +04:00
io . lockx . level = RAW_LOCK_LOCKX ;
2006-03-13 01:48:25 +03:00
io . lockx . in . file . fnum = fnum ;
2003-08-13 05:53:07 +04:00
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . timeout = 0 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . pid = cli - > session - > pid ;
2004-10-18 12:41:44 +04:00
lock [ 0 ] . offset = 10 ;
lock [ 0 ] . count = 1 ;
2003-08-13 05:53:07 +04:00
io . lockx . in . locks = & lock [ 0 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2004-10-18 12:41:44 +04:00
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Trying 0xEEFFFFFF lock \n " ) ;
2004-10-18 12:41:44 +04:00
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . count = 4000 ;
lock [ 0 ] . offset = 0xEEFFFFFF ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
lock [ 0 ] . pid + + ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_LOCK_NOT_GRANTED ) ;
lock [ 0 ] . pid - - ;
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Trying 0xEF000000 lock \n " ) ;
2004-10-18 12:41:44 +04:00
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . count = 4000 ;
lock [ 0 ] . offset = 0xEF000000 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
lock [ 0 ] . pid + + ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
lock [ 0 ] . pid - - ;
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Trying zero lock \n " ) ;
2004-10-18 12:41:44 +04:00
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . count = 0 ;
lock [ 0 ] . offset = ~ 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
lock [ 0 ] . pid + + ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
lock [ 0 ] . pid - - ;
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Trying max lock \n " ) ;
2004-10-18 12:41:44 +04:00
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . count = 0 ;
lock [ 0 ] . offset = ~ 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
lock [ 0 ] . pid + + ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
lock [ 0 ] . pid - - ;
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Trying 2^63 \n " ) ;
2004-10-18 12:41:44 +04:00
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . count = 1 ;
lock [ 0 ] . offset = 1 ;
lock [ 0 ] . offset < < = 63 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
lock [ 0 ] . pid + + ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_LOCK_NOT_GRANTED ) ;
lock [ 0 ] . pid - - ;
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Trying 2^63 - 1 \n " ) ;
2004-10-18 12:41:44 +04:00
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . count = 1 ;
lock [ 0 ] . offset = 1 ;
lock [ 0 ] . offset < < = 63 ;
lock [ 0 ] . offset - - ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
lock [ 0 ] . pid + + ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
lock [ 0 ] . pid - - ;
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Trying max lock 2 \n " ) ;
2004-10-18 12:41:44 +04:00
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . count = 1 ;
lock [ 0 ] . offset = ~ 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
lock [ 0 ] . pid + + ;
lock [ 0 ] . count = 2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
2009-11-25 03:58:25 +03:00
if ( TARGET_SUPPORTS_INVALID_LOCK_RANGE ( tctx ) )
2009-04-01 22:06:51 +04:00
CHECK_STATUS ( status , NT_STATUS_INVALID_LOCK_RANGE ) ;
2009-02-10 08:58:50 +03:00
else
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2004-10-18 12:41:44 +04:00
lock [ 0 ] . pid - - ;
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
lock [ 0 ] . count = 1 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
2009-02-10 08:58:50 +03:00
2009-07-06 17:36:03 +04:00
CHECK_STATUS ( status , NT_STATUS_OK ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
2004-10-18 12:41:44 +04:00
2003-08-13 05:53:07 +04:00
done :
2004-08-04 17:23:35 +04:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 06:04:44 +04:00
smb_raw_exit ( cli - > session ) ;
2004-08-04 17:23:35 +04:00
smbcli_deltree ( cli - > tree , BASEDIR ) ;
2003-08-13 06:04:44 +04:00
return ret ;
}
/*
test high pid
*/
2007-08-28 16:54:27 +04:00
static bool test_pidhigh ( struct torture_context * tctx ,
struct smbcli_state * cli )
2003-08-13 06:04:44 +04:00
{
union smb_lock io ;
struct smb_lock_entry lock [ 1 ] ;
NTSTATUS status ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2003-08-13 06:04:44 +04:00
int fnum ;
const char * fname = BASEDIR " \\ test.txt " ;
2004-12-04 16:56:25 +03:00
uint8_t c = 1 ;
2003-08-13 06:04:44 +04:00
2012-05-18 09:43:31 +04:00
torture_assert ( tctx , torture_setup_dir ( cli , BASEDIR ) , " Failed to setup up test directory: " BASEDIR ) ;
2003-08-13 06:04:44 +04:00
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Testing high pid \n " ) ;
2003-08-13 06:04:44 +04:00
io . generic . level = RAW_LOCK_LOCKX ;
cli - > session - > pid = 1 ;
2004-08-04 17:23:35 +04:00
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( fnum ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to create %s - %s \n " ,
fname , smbcli_errstr ( cli - > tree ) ) ) ;
2003-08-13 06:04:44 +04:00
2004-08-04 17:23:35 +04:00
if ( smbcli_write ( cli - > tree , fnum , 0 , & c , 0 , 1 ) ! = 1 ) {
2009-04-24 14:28:59 +04:00
torture_result ( tctx , TORTURE_FAIL ,
" Failed to write 1 byte - %s \n " ,
smbcli_errstr ( cli - > tree ) ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2003-08-13 06:04:44 +04:00
goto done ;
}
io . lockx . level = RAW_LOCK_LOCKX ;
2006-03-13 01:48:25 +03:00
io . lockx . in . file . fnum = fnum ;
2003-08-13 06:04:44 +04:00
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . timeout = 0 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . pid = cli - > session - > pid ;
lock [ 0 ] . offset = 0 ;
lock [ 0 ] . count = 0xFFFFFFFF ;
io . lockx . in . locks = & lock [ 0 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2004-08-04 17:23:35 +04:00
if ( smbcli_read ( cli - > tree , fnum , & c , 0 , 1 ) ! = 1 ) {
2009-04-24 14:28:59 +04:00
torture_result ( tctx , TORTURE_FAIL ,
" Failed to read 1 byte - %s \n " ,
smbcli_errstr ( cli - > tree ) ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2003-08-13 06:04:44 +04:00
goto done ;
}
cli - > session - > pid = 2 ;
2004-08-04 17:23:35 +04:00
if ( smbcli_read ( cli - > tree , fnum , & c , 0 , 1 ) = = 1 ) {
2009-04-24 14:28:59 +04:00
torture_result ( tctx , TORTURE_FAIL ,
" pid is incorrect handled for read with lock! \n " ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2003-08-13 06:04:44 +04:00
goto done ;
}
cli - > session - > pid = 0x10001 ;
2004-08-04 17:23:35 +04:00
if ( smbcli_read ( cli - > tree , fnum , & c , 0 , 1 ) ! = 1 ) {
2009-04-24 14:28:59 +04:00
torture_result ( tctx , TORTURE_FAIL ,
" High pid is used on this server! \n " ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2003-08-13 06:04:44 +04:00
} else {
2009-04-24 14:28:59 +04:00
torture_warning ( tctx , " High pid is not used on this server (correct) \n " ) ;
2003-08-13 06:04:44 +04:00
}
done :
2004-08-04 17:23:35 +04:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 05:53:07 +04:00
smb_raw_exit ( cli - > session ) ;
2004-08-04 17:23:35 +04:00
smbcli_deltree ( cli - > tree , BASEDIR ) ;
2003-08-13 05:53:07 +04:00
return ret ;
}
2004-10-18 12:41:44 +04:00
/*
test locking & X async operation
2003-08-13 05:53:07 +04:00
*/
2007-08-28 16:54:27 +04:00
static bool test_async ( struct torture_context * tctx ,
struct smbcli_state * cli )
2003-08-13 05:53:07 +04:00
{
2006-05-15 16:25:03 +04:00
struct smbcli_session * session ;
struct smb_composite_sesssetup setup ;
struct smbcli_tree * tree ;
union smb_tcon tcon ;
const char * host , * share ;
2004-10-18 12:41:44 +04:00
union smb_lock io ;
struct smb_lock_entry lock [ 2 ] ;
NTSTATUS status ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2004-10-18 12:41:44 +04:00
int fnum ;
const char * fname = BASEDIR " \\ test.txt " ;
time_t t ;
2009-11-26 04:39:42 +03:00
struct smbcli_request * req , * req2 ;
2008-09-30 03:29:53 +04:00
struct smbcli_session_options options ;
2003-08-13 05:53:07 +04:00
2012-05-18 09:43:31 +04:00
torture_assert ( tctx , torture_setup_dir ( cli , BASEDIR ) , " Failed to setup up test directory: " BASEDIR ) ;
2003-08-13 05:53:07 +04:00
2010-07-16 08:32:42 +04:00
lpcfg_smbcli_session_options ( tctx - > lp_ctx , & options ) ;
2008-09-30 03:29:53 +04:00
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Testing LOCKING_ANDX_CANCEL_LOCK \n " ) ;
2004-10-18 12:41:44 +04:00
io . generic . level = RAW_LOCK_LOCKX ;
2006-05-15 16:25:03 +04:00
2004-10-18 12:41:44 +04:00
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( fnum ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to create %s - %s \n " ,
fname , smbcli_errstr ( cli - > tree ) ) ) ;
2003-08-13 05:53:07 +04:00
2004-10-18 12:41:44 +04:00
io . lockx . level = RAW_LOCK_LOCKX ;
2006-03-13 01:48:25 +03:00
io . lockx . in . file . fnum = fnum ;
2004-10-18 12:41:44 +04:00
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . timeout = 0 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . pid = cli - > session - > pid ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
2009-11-26 04:39:42 +03:00
lock [ 1 ] . pid = cli - > session - > pid ;
lock [ 1 ] . offset = 110 ;
lock [ 1 ] . count = 10 ;
2004-10-18 12:41:44 +04:00
io . lockx . in . locks = & lock [ 0 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2010-09-10 13:51:15 +04:00
t = time_mono ( NULL ) ;
2004-10-18 12:41:44 +04:00
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing cancel by CANCEL_LOCK \n " ) ;
2004-10-18 15:47:13 +04:00
2004-10-18 12:41:44 +04:00
/* setup a timed lock */
io . lockx . in . timeout = 10000 ;
req = smb_raw_lock_send ( cli - > tree , & io ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( req ! = NULL ) , talloc_asprintf ( tctx ,
" Failed to setup timed lock (%s) \n " , __location__ ) ) ;
2003-08-13 05:53:07 +04:00
2004-10-18 12:41:44 +04:00
/* cancel the wrong range */
lock [ 0 ] . offset = 0 ;
io . lockx . in . timeout = 0 ;
io . lockx . in . mode = LOCKING_ANDX_CANCEL_LOCK ;
status = smb_raw_lock ( cli - > tree , & io ) ;
2005-07-04 09:05:28 +04:00
CHECK_STATUS ( status , NT_STATUS_DOS ( ERRDOS , ERRcancelviolation ) ) ;
2004-10-18 12:41:44 +04:00
/* cancel with the wrong bits set */
lock [ 0 ] . offset = 100 ;
io . lockx . in . timeout = 0 ;
io . lockx . in . mode = LOCKING_ANDX_CANCEL_LOCK ;
status = smb_raw_lock ( cli - > tree , & io ) ;
2005-07-04 09:05:28 +04:00
CHECK_STATUS ( status , NT_STATUS_DOS ( ERRDOS , ERRcancelviolation ) ) ;
2004-10-18 12:41:44 +04:00
/* cancel the right range */
lock [ 0 ] . offset = 100 ;
io . lockx . in . timeout = 0 ;
io . lockx . in . mode = LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_LARGE_FILES ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* receive the failed lock request */
status = smbcli_request_simple_recv ( req ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
2010-09-10 13:51:15 +04:00
torture_assert ( tctx , ! ( time_mono ( NULL ) > t + 2 ) , talloc_asprintf ( tctx ,
2009-04-24 14:28:59 +04:00
" lock cancel was not immediate (%s) \n " , __location__ ) ) ;
2003-08-13 06:04:44 +04:00
2009-11-26 04:39:42 +03:00
/* MS-CIFS (2.2.4.32.1) states that a cancel is honored if and only
* if the lock vector contains one entry . When given mutliple cancel
* requests in a single PDU we expect the server to return an
* error . Samba4 handles this correctly . Windows servers seem to
* accept the request but only cancel the first lock . Samba3
2009-12-05 01:02:52 +03:00
* now does what Windows does ( JRA ) .
*/
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing multiple cancel \n " ) ;
2009-11-26 04:39:42 +03:00
/* acquire second lock */
io . lockx . in . timeout = 0 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . locks = & lock [ 1 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* setup 2 timed locks */
2010-09-10 13:51:15 +04:00
t = time_mono ( NULL ) ;
2009-11-26 04:39:42 +03:00
io . lockx . in . timeout = 10000 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . locks = & lock [ 0 ] ;
req = smb_raw_lock_send ( cli - > tree , & io ) ;
torture_assert ( tctx , ( req ! = NULL ) , talloc_asprintf ( tctx ,
" Failed to setup timed lock (%s) \n " , __location__ ) ) ;
io . lockx . in . locks = & lock [ 1 ] ;
req2 = smb_raw_lock_send ( cli - > tree , & io ) ;
torture_assert ( tctx , ( req2 ! = NULL ) , talloc_asprintf ( tctx ,
" Failed to setup timed lock (%s) \n " , __location__ ) ) ;
/* try to cancel both locks in the same packet */
io . lockx . in . timeout = 0 ;
io . lockx . in . lock_cnt = 2 ;
io . lockx . in . mode = LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . locks = lock ;
status = smb_raw_lock ( cli - > tree , & io ) ;
2009-12-05 01:02:52 +03:00
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2009-11-26 04:39:42 +03:00
2009-12-05 01:02:52 +03:00
torture_warning ( tctx , " Target server accepted a lock cancel "
" request with multiple locks. This violates "
" MS-CIFS 2.2.4.32.1. \n " ) ;
/* receive the failed lock requests */
status = smbcli_request_simple_recv ( req ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
2010-09-10 13:51:15 +04:00
torture_assert ( tctx , ! ( time_mono ( NULL ) > t + 2 ) , talloc_asprintf ( tctx ,
2009-12-05 01:02:52 +03:00
" first lock was not cancelled immediately (%s) \n " ,
__location__ ) ) ;
/* send cancel to second lock */
io . lockx . in . timeout = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = LOCKING_ANDX_CANCEL_LOCK |
LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . locks = & lock [ 1 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
status = smbcli_request_simple_recv ( req2 ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
2010-09-10 13:51:15 +04:00
torture_assert ( tctx , ! ( time_mono ( NULL ) > t + 2 ) , talloc_asprintf ( tctx ,
2009-12-05 01:02:52 +03:00
" second lock was not cancelled immediately (%s) \n " ,
__location__ ) ) ;
2009-11-26 04:39:42 +03:00
/* cleanup the second lock */
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
2009-12-19 02:35:35 +03:00
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
2009-11-26 04:39:42 +03:00
io . lockx . in . locks = & lock [ 1 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2009-12-17 01:38:56 +03:00
/* If a lock request contained multiple ranges and we are cancelling
* one while it ' s still pending , what happens ? */
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing cancel 1/2 lock request \n " ) ;
2009-12-17 01:38:56 +03:00
/* Send request with two ranges */
io . lockx . in . timeout = - 1 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 2 ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . locks = lock ;
req = smb_raw_lock_send ( cli - > tree , & io ) ;
torture_assert ( tctx , ( req ! = NULL ) , talloc_asprintf ( tctx ,
" Failed to setup pending lock (%s) \n " , __location__ ) ) ;
/* Try to cancel the first lock range */
io . lockx . in . timeout = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . locks = & lock [ 0 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* Locking request should've failed and second range should be
* unlocked */
status = smbcli_request_simple_recv ( req ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . timeout = 0 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . locks = & lock [ 1 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* Cleanup both locks */
io . lockx . in . ulock_cnt = 2 ;
io . lockx . in . lock_cnt = 0 ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . locks = lock ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing cancel 2/2 lock request \n " ) ;
2009-12-17 01:38:56 +03:00
/* Lock second range so it contends */
io . lockx . in . timeout = 0 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . locks = & lock [ 1 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* Send request with two ranges */
io . lockx . in . timeout = - 1 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 2 ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . locks = lock ;
req = smb_raw_lock_send ( cli - > tree , & io ) ;
torture_assert ( tctx , ( req ! = NULL ) , talloc_asprintf ( tctx ,
" Failed to setup pending lock (%s) \n " , __location__ ) ) ;
/* Try to cancel the second lock range */
io . lockx . in . timeout = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . locks = & lock [ 1 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* Locking request should've failed and first range should be
* unlocked */
status = smbcli_request_simple_recv ( req ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . timeout = 0 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . locks = & lock [ 0 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* Cleanup both locks */
io . lockx . in . ulock_cnt = 2 ;
io . lockx . in . lock_cnt = 0 ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . locks = lock ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing cancel by unlock \n " ) ;
2004-10-18 15:47:13 +04:00
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . timeout = 0 ;
2009-11-26 04:39:42 +03:00
io . lockx . in . locks = & lock [ 0 ] ;
2004-10-18 15:47:13 +04:00
status = smb_raw_lock ( cli - > tree , & io ) ;
2009-12-17 01:38:56 +03:00
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2004-10-18 15:47:13 +04:00
io . lockx . in . timeout = 5000 ;
req = smb_raw_lock_send ( cli - > tree , & io ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( req ! = NULL ) , talloc_asprintf ( tctx ,
" Failed to setup timed lock (%s) \n " , __location__ ) ) ;
2004-10-18 15:47:13 +04:00
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2010-09-10 13:51:15 +04:00
t = time_mono ( NULL ) ;
2004-10-18 15:47:13 +04:00
status = smbcli_request_simple_recv ( req ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2010-09-10 13:51:15 +04:00
torture_assert ( tctx , ! ( time_mono ( NULL ) > t + 2 ) , talloc_asprintf ( tctx ,
2009-04-24 14:28:59 +04:00
" lock cancel by unlock was not immediate (%s) - took %d secs \n " ,
2010-09-10 13:51:15 +04:00
__location__ , ( int ) ( time_mono ( NULL ) - t ) ) ) ;
2004-10-18 15:47:13 +04:00
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing cancel by close \n " ) ;
2004-10-18 15:47:13 +04:00
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . timeout = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
2009-12-17 01:38:56 +03:00
CHECK_STATUS ( status , NT_STATUS_LOCK_NOT_GRANTED ) ;
2004-10-18 15:47:13 +04:00
2012-08-07 19:12:19 +04:00
{
/*
* Make the test block on the second lock
* request . This is to regression - test 64 c0367 .
*/
uint64_t tmp = lock [ 1 ] . offset ;
lock [ 1 ] . offset = lock [ 0 ] . offset ;
lock [ 0 ] . offset = tmp ;
}
2010-09-10 13:51:15 +04:00
t = time_mono ( NULL ) ;
2004-10-18 15:47:13 +04:00
io . lockx . in . timeout = 10000 ;
2012-08-07 19:12:19 +04:00
io . lockx . in . lock_cnt = 2 ;
2004-10-18 15:47:13 +04:00
req = smb_raw_lock_send ( cli - > tree , & io ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( req ! = NULL ) , talloc_asprintf ( tctx ,
" Failed to setup timed lock (%s) \n " , __location__ ) ) ;
2004-10-18 15:47:13 +04:00
2006-05-15 16:25:03 +04:00
status = smbcli_close ( cli - > tree , fnum ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2004-10-18 15:47:13 +04:00
status = smbcli_request_simple_recv ( req ) ;
2010-01-11 03:06:57 +03:00
if ( TARGET_RETURNS_RANGE_NOT_LOCKED ( tctx ) )
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
else
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
2004-10-18 15:47:13 +04:00
2010-09-10 13:51:15 +04:00
torture_assert ( tctx , ! ( time_mono ( NULL ) > t + 2 ) , talloc_asprintf ( tctx ,
2009-04-24 14:28:59 +04:00
" lock cancel by close was not immediate (%s) \n " , __location__ ) ) ;
2006-05-15 16:25:03 +04:00
2012-08-07 19:12:19 +04:00
{
/*
* Undo the change for 64 c0367
*/
uint64_t tmp = lock [ 1 ] . offset ;
lock [ 1 ] . offset = lock [ 0 ] . offset ;
lock [ 0 ] . offset = tmp ;
}
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " create a new sessions \n " ) ;
2008-09-30 03:29:53 +04:00
session = smbcli_session_init ( cli - > transport , tctx , false , options ) ;
2006-05-15 16:25:03 +04:00
setup . in . sesskey = cli - > transport - > negotiate . sesskey ;
setup . in . capabilities = cli - > transport - > negotiate . capabilities ;
2010-07-16 08:32:42 +04:00
setup . in . workgroup = lpcfg_workgroup ( tctx - > lp_ctx ) ;
2006-05-15 16:25:03 +04:00
setup . in . credentials = cmdline_credentials ;
2010-07-16 08:32:42 +04:00
setup . in . gensec_settings = lpcfg_gensec_settings ( tctx , tctx - > lp_ctx ) ;
2006-05-15 16:25:03 +04:00
status = smb_composite_sesssetup ( session , & setup ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
session - > vuid = setup . out . vuid ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " create new tree context \n " ) ;
2007-12-03 02:28:22 +03:00
share = torture_setting_string ( tctx , " share " , NULL ) ;
host = torture_setting_string ( tctx , " host " , NULL ) ;
2007-10-07 02:28:14 +04:00
tree = smbcli_tree_init ( session , tctx , false ) ;
2006-05-15 16:25:03 +04:00
tcon . generic . level = RAW_TCON_TCONX ;
2012-08-02 10:48:11 +04:00
tcon . tconx . in . flags = TCONX_FLAG_EXTENDED_RESPONSE ;
2006-05-15 16:25:03 +04:00
tcon . tconx . in . password = data_blob ( NULL , 0 ) ;
2007-08-28 16:54:27 +04:00
tcon . tconx . in . path = talloc_asprintf ( tctx , " \\ \\ %s \\ %s " , host , share ) ;
2006-05-15 16:25:03 +04:00
tcon . tconx . in . device = " A: " ;
2007-08-28 16:54:27 +04:00
status = smb_raw_tcon ( tree , tctx , & tcon ) ;
2006-05-15 16:25:03 +04:00
CHECK_STATUS ( status , NT_STATUS_OK ) ;
tree - > tid = tcon . tconx . out . tid ;
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing cancel by exit \n " ) ;
2010-01-11 03:06:57 +03:00
if ( TARGET_SUPPORTS_SMBEXIT ( tctx ) ) {
fname = BASEDIR " \\ test_exit.txt " ;
fnum = smbcli_open ( tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
torture_assert ( tctx , ( fnum ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to reopen %s - %s \n " ,
fname , smbcli_errstr ( tree ) ) ) ;
io . lockx . level = RAW_LOCK_LOCKX ;
io . lockx . in . file . fnum = fnum ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . timeout = 0 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . pid = session - > pid ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
io . lockx . in . locks = & lock [ 0 ] ;
status = smb_raw_lock ( tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2006-05-15 16:25:03 +04:00
2010-01-11 03:06:57 +03:00
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . timeout = 0 ;
status = smb_raw_lock ( tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_LOCK_NOT_GRANTED ) ;
io . lockx . in . timeout = 10000 ;
2010-09-10 13:51:15 +04:00
t = time_mono ( NULL ) ;
2010-01-11 03:06:57 +03:00
req = smb_raw_lock_send ( tree , & io ) ;
torture_assert ( tctx , ( req ! = NULL ) , talloc_asprintf ( tctx ,
" Failed to setup timed lock (%s) \n " ,
__location__ ) ) ;
status = smb_raw_exit ( session ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2006-05-15 16:25:03 +04:00
2010-01-11 03:06:57 +03:00
status = smbcli_request_simple_recv ( req ) ;
if ( TARGET_RETURNS_RANGE_NOT_LOCKED ( tctx ) )
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
else
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
2006-05-15 16:25:03 +04:00
2010-09-10 13:51:15 +04:00
torture_assert ( tctx , ! ( time_mono ( NULL ) > t + 2 ) , talloc_asprintf ( tctx ,
2010-01-11 03:06:57 +03:00
" lock cancel by exit was not immediate (%s) \n " ,
__location__ ) ) ;
}
else {
torture_comment ( tctx ,
" skipping test, SMBExit not supported \n " ) ;
}
2006-05-15 16:25:03 +04:00
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing cancel by ulogoff \n " ) ;
2006-05-15 16:25:03 +04:00
fname = BASEDIR " \\ test_ulogoff.txt " ;
fnum = smbcli_open ( tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( fnum ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to reopen %s - %s \n " ,
fname , smbcli_errstr ( tree ) ) ) ;
2006-05-15 16:25:03 +04:00
io . lockx . level = RAW_LOCK_LOCKX ;
io . lockx . in . file . fnum = fnum ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . timeout = 0 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . pid = session - > pid ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
io . lockx . in . locks = & lock [ 0 ] ;
status = smb_raw_lock ( tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . timeout = 0 ;
status = smb_raw_lock ( tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_LOCK_NOT_GRANTED ) ;
io . lockx . in . timeout = 10000 ;
2010-09-10 13:51:15 +04:00
t = time_mono ( NULL ) ;
2006-05-15 16:25:03 +04:00
req = smb_raw_lock_send ( tree , & io ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( req ! = NULL ) , talloc_asprintf ( tctx ,
" Failed to setup timed lock (%s) \n " , __location__ ) ) ;
2006-05-15 16:25:03 +04:00
status = smb_raw_ulogoff ( session ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
status = smbcli_request_simple_recv ( req ) ;
2010-01-11 03:06:57 +03:00
if ( TARGET_RETURNS_RANGE_NOT_LOCKED ( tctx ) ) {
if ( NT_STATUS_EQUAL ( NT_STATUS_FILE_LOCK_CONFLICT , status ) ) {
torture_result ( tctx , TORTURE_FAIL ,
" lock not canceled by ulogoff - %s "
" (ignored because of vfs_vifs fails it) \n " ,
nt_errstr ( status ) ) ;
smb_tree_disconnect ( tree ) ;
smb_raw_exit ( session ) ;
goto done ;
}
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
} else {
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
2006-05-15 16:25:03 +04:00
}
2010-09-10 13:51:15 +04:00
torture_assert ( tctx , ! ( time_mono ( NULL ) > t + 2 ) , talloc_asprintf ( tctx ,
2009-04-24 14:28:59 +04:00
" lock cancel by ulogoff was not immediate (%s) \n " , __location__ ) ) ;
2006-05-15 16:25:03 +04:00
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing cancel by tdis \n " ) ;
2006-05-15 16:25:03 +04:00
tree - > session = cli - > session ;
fname = BASEDIR " \\ test_tdis.txt " ;
fnum = smbcli_open ( tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( fnum ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to reopen %s - %s \n " ,
fname , smbcli_errstr ( tree ) ) ) ;
2006-05-15 16:25:03 +04:00
io . lockx . level = RAW_LOCK_LOCKX ;
io . lockx . in . file . fnum = fnum ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . timeout = 0 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . pid = cli - > session - > pid ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
io . lockx . in . locks = & lock [ 0 ] ;
status = smb_raw_lock ( tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
status = smb_raw_lock ( tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_LOCK_NOT_GRANTED ) ;
io . lockx . in . timeout = 10000 ;
2010-09-10 13:51:15 +04:00
t = time_mono ( NULL ) ;
2006-05-15 16:25:03 +04:00
req = smb_raw_lock_send ( tree , & io ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( req ! = NULL ) , talloc_asprintf ( tctx ,
" Failed to setup timed lock (%s) \n " , __location__ ) ) ;
2006-05-15 16:25:03 +04:00
status = smb_tree_disconnect ( tree ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
status = smbcli_request_simple_recv ( req ) ;
2010-01-11 03:06:57 +03:00
if ( TARGET_RETURNS_RANGE_NOT_LOCKED ( tctx ) )
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
else
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
2006-05-15 16:25:03 +04:00
2010-09-10 13:51:15 +04:00
torture_assert ( tctx , ! ( time_mono ( NULL ) > t + 2 ) , talloc_asprintf ( tctx ,
2009-04-24 14:28:59 +04:00
" lock cancel by tdis was not immediate (%s) \n " , __location__ ) ) ;
2004-10-18 15:47:13 +04:00
done :
2006-05-15 16:25:03 +04:00
smb_raw_exit ( cli - > session ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
/*
test NT_STATUS_LOCK_NOT_GRANTED vs . NT_STATUS_FILE_LOCK_CONFLICT
*/
2007-08-28 16:54:27 +04:00
static bool test_errorcode ( struct torture_context * tctx ,
struct smbcli_state * cli )
2006-05-15 16:25:03 +04:00
{
union smb_lock io ;
union smb_open op ;
struct smb_lock_entry lock [ 2 ] ;
NTSTATUS status ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2006-05-15 16:25:03 +04:00
int fnum , fnum2 ;
const char * fname ;
struct smbcli_request * req ;
time_t start ;
int t ;
2009-07-06 17:36:03 +04:00
int delay ;
2009-11-25 03:58:25 +03:00
uint16_t deny_mode = 0 ;
2006-05-15 16:25:03 +04:00
2012-05-18 09:43:31 +04:00
torture_assert ( tctx , torture_setup_dir ( cli , BASEDIR ) , " Failed to setup up test directory: " BASEDIR ) ;
2006-05-15 16:25:03 +04:00
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Testing LOCK_NOT_GRANTED vs. FILE_LOCK_CONFLICT \n " ) ;
2006-05-15 16:25:03 +04:00
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing with timeout = 0 \n " ) ;
2006-05-15 16:25:03 +04:00
fname = BASEDIR " \\ test0.txt " ;
t = 0 ;
/*
* the first run is with t = 0 ,
* the second with t > 0 ( = 1 )
*/
next_run :
2009-11-25 03:58:25 +03:00
/*
* use the DENY_DOS mode , that creates two fnum ' s of one low - level
* file handle , this demonstrates that the cache is per fnum , not
* per file handle
2006-05-15 16:25:03 +04:00
*/
2009-11-25 03:58:25 +03:00
if ( TARGET_SUPPORTS_OPENX_DENY_DOS ( tctx ) )
deny_mode = OPENX_MODE_DENY_DOS ;
else
deny_mode = OPENX_MODE_DENY_NONE ;
2006-05-15 16:25:03 +04:00
op . openx . level = RAW_OPEN_OPENX ;
op . openx . in . fname = fname ;
op . openx . in . flags = OPENX_FLAGS_ADDITIONAL_INFO ;
2009-11-25 03:58:25 +03:00
op . openx . in . open_mode = OPENX_MODE_ACCESS_RDWR | deny_mode ;
2006-05-15 16:25:03 +04:00
op . openx . in . open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE ;
op . openx . in . search_attrs = 0 ;
op . openx . in . file_attrs = 0 ;
op . openx . in . write_time = 0 ;
op . openx . in . size = 0 ;
op . openx . in . timeout = 0 ;
2007-08-28 16:54:27 +04:00
status = smb_raw_open ( cli - > tree , tctx , & op ) ;
2006-05-15 16:25:03 +04:00
CHECK_STATUS ( status , NT_STATUS_OK ) ;
fnum = op . openx . out . file . fnum ;
2007-08-28 16:54:27 +04:00
status = smb_raw_open ( cli - > tree , tctx , & op ) ;
2006-05-15 16:25:03 +04:00
CHECK_STATUS ( status , NT_STATUS_OK ) ;
fnum2 = op . openx . out . file . fnum ;
io . lockx . level = RAW_LOCK_LOCKX ;
io . lockx . in . file . fnum = fnum ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . timeout = t ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . pid = cli - > session - > pid ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
io . lockx . in . locks = & lock [ 0 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/*
* demonstrate that the first conflicting lock on each handle give LOCK_NOT_GRANTED
* this also demonstrates that the error code cache is per file handle
* ( LOCK_NOT_GRANTED is only be used when timeout is 0 ! )
*/
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , ( t ? NT_STATUS_FILE_LOCK_CONFLICT : NT_STATUS_LOCK_NOT_GRANTED ) ) ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , ( t ? NT_STATUS_FILE_LOCK_CONFLICT : NT_STATUS_LOCK_NOT_GRANTED ) ) ;
/* demonstrate that each following conflict gives FILE_LOCK_CONFLICT */
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
/* demonstrate that the smbpid doesn't matter */
lock [ 0 ] . pid + + ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
lock [ 0 ] . pid - - ;
/*
* demonstrate the a successful lock with count = 0 and the same offset ,
* doesn ' t reset the error cache
*/
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 0 ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
/*
* demonstrate the a successful lock with count = 0 and outside the locked range ,
* doesn ' t reset the error cache
*/
lock [ 0 ] . offset = 110 ;
lock [ 0 ] . count = 0 ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
lock [ 0 ] . offset = 99 ;
lock [ 0 ] . count = 0 ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
/* demonstrate that a changing count doesn't reset the error cache */
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 5 ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 15 ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
/*
* demonstrate the a lock with count = 0 and inside the locked range ,
* fails and resets the error cache
*/
lock [ 0 ] . offset = 101 ;
lock [ 0 ] . count = 0 ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , ( t ? NT_STATUS_FILE_LOCK_CONFLICT : NT_STATUS_LOCK_NOT_GRANTED ) ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , ( t ? NT_STATUS_FILE_LOCK_CONFLICT : NT_STATUS_LOCK_NOT_GRANTED ) ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , ( t ? NT_STATUS_FILE_LOCK_CONFLICT : NT_STATUS_LOCK_NOT_GRANTED ) ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , ( t ? NT_STATUS_FILE_LOCK_CONFLICT : NT_STATUS_LOCK_NOT_GRANTED ) ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
/* demonstrate the a changing offset, resets the error cache */
lock [ 0 ] . offset = 105 ;
lock [ 0 ] . count = 10 ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , ( t ? NT_STATUS_FILE_LOCK_CONFLICT : NT_STATUS_LOCK_NOT_GRANTED ) ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , ( t ? NT_STATUS_FILE_LOCK_CONFLICT : NT_STATUS_LOCK_NOT_GRANTED ) ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , ( t ? NT_STATUS_FILE_LOCK_CONFLICT : NT_STATUS_LOCK_NOT_GRANTED ) ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , ( t ? NT_STATUS_FILE_LOCK_CONFLICT : NT_STATUS_LOCK_NOT_GRANTED ) ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
lock [ 0 ] . offset = 95 ;
lock [ 0 ] . count = 9 ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , ( t ? NT_STATUS_FILE_LOCK_CONFLICT : NT_STATUS_LOCK_NOT_GRANTED ) ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , ( t ? NT_STATUS_FILE_LOCK_CONFLICT : NT_STATUS_LOCK_NOT_GRANTED ) ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , ( t ? NT_STATUS_FILE_LOCK_CONFLICT : NT_STATUS_LOCK_NOT_GRANTED ) ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , ( t ? NT_STATUS_FILE_LOCK_CONFLICT : NT_STATUS_LOCK_NOT_GRANTED ) ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
/*
* demonstrate the a successful lock in a different range ,
* doesn ' t reset the cache , the failing lock on the 2 nd handle
2009-11-25 03:58:25 +03:00
* resets the cache
2006-05-15 16:25:03 +04:00
*/
lock [ 0 ] . offset = 120 ;
lock [ 0 ] . count = 15 ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , ( t ? NT_STATUS_FILE_LOCK_CONFLICT : NT_STATUS_LOCK_NOT_GRANTED ) ) ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
io . lockx . in . file . fnum = fnum ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , ( t ? NT_STATUS_FILE_LOCK_CONFLICT : NT_STATUS_LOCK_NOT_GRANTED ) ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
/* end of the loop */
if ( t = = 0 ) {
smb_raw_exit ( cli - > session ) ;
t = 1 ;
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing with timeout > 0 (=%d) \n " ,
2009-07-06 17:36:03 +04:00
t ) ;
fname = BASEDIR " \\ test1.txt " ;
2006-05-15 16:25:03 +04:00
goto next_run ;
}
2009-07-06 17:36:03 +04:00
t = 4000 ;
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing special cases with timeout > 0 (=%d) \n " ,
2009-07-06 17:36:03 +04:00
t ) ;
2006-05-15 16:25:03 +04:00
/*
* the following 3 test sections demonstrate that
* the cache is only set when the error is reported
* to the client ( after the timeout went by )
*/
smb_raw_exit ( cli - > session ) ;
2010-04-11 03:39:06 +04:00
torture_comment ( tctx , " Testing a conflict while a lock is pending \n " ) ;
2006-05-15 16:25:03 +04:00
fname = BASEDIR " \\ test2.txt " ;
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( fnum ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to reopen %s - %s \n " ,
fname , smbcli_errstr ( cli - > tree ) ) ) ;
2006-05-15 16:25:03 +04:00
io . lockx . level = RAW_LOCK_LOCKX ;
io . lockx . in . file . fnum = fnum ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . timeout = 0 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . pid = cli - > session - > pid ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
io . lockx . in . locks = & lock [ 0 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2010-09-10 13:51:15 +04:00
start = time_mono ( NULL ) ;
2009-07-06 17:36:03 +04:00
io . lockx . in . timeout = t ;
2006-05-15 16:25:03 +04:00
req = smb_raw_lock_send ( cli - > tree , & io ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( req ! = NULL ) , talloc_asprintf ( tctx ,
" Failed to setup timed lock (%s) \n " , __location__ ) ) ;
2006-05-15 16:25:03 +04:00
io . lockx . in . timeout = 0 ;
lock [ 0 ] . offset = 105 ;
lock [ 0 ] . count = 10 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_LOCK_NOT_GRANTED ) ;
status = smbcli_request_simple_recv ( req ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
2009-07-06 17:36:03 +04:00
delay = t / 1000 ;
if ( TARGET_IS_W2K8 ( tctx ) | | TARGET_IS_WIN7 ( tctx ) ) {
delay / = 2 ;
}
2010-09-10 13:51:15 +04:00
torture_assert ( tctx , ! ( time_mono ( NULL ) < start + delay ) , talloc_asprintf ( tctx ,
2009-07-06 17:36:03 +04:00
" lock comes back to early timeout[%d] delay[%d] "
" (%s) \n " , t , delay , __location__ ) ) ;
2006-05-15 16:25:03 +04:00
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_LOCK_NOT_GRANTED ) ;
2004-10-18 15:47:13 +04:00
smbcli_close ( cli - > tree , fnum ) ;
2006-05-15 16:25:03 +04:00
fname = BASEDIR " \\ test3.txt " ;
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( fnum ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to reopen %s - %s \n " ,
fname , smbcli_errstr ( cli - > tree ) ) ) ;
2006-05-15 16:25:03 +04:00
io . lockx . level = RAW_LOCK_LOCKX ;
io . lockx . in . file . fnum = fnum ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . timeout = 0 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . pid = cli - > session - > pid ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
io . lockx . in . locks = & lock [ 0 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2010-09-10 13:51:15 +04:00
start = time_mono ( NULL ) ;
2009-07-06 17:36:03 +04:00
io . lockx . in . timeout = t ;
2006-05-15 16:25:03 +04:00
req = smb_raw_lock_send ( cli - > tree , & io ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( req ! = NULL ) , talloc_asprintf ( tctx ,
" Failed to setup timed lock (%s) \n " , __location__ ) ) ;
2006-05-15 16:25:03 +04:00
io . lockx . in . timeout = 0 ;
lock [ 0 ] . offset = 105 ;
lock [ 0 ] . count = 10 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_LOCK_NOT_GRANTED ) ;
status = smbcli_request_simple_recv ( req ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
2009-07-06 17:36:03 +04:00
delay = t / 1000 ;
if ( TARGET_IS_W2K8 ( tctx ) | | TARGET_IS_WIN7 ( tctx ) ) {
delay / = 2 ;
}
2010-09-10 13:51:15 +04:00
torture_assert ( tctx , ! ( time_mono ( NULL ) < start + delay ) , talloc_asprintf ( tctx ,
2009-07-06 17:36:03 +04:00
" lock comes back to early timeout[%d] delay[%d] "
" (%s) \n " , t , delay , __location__ ) ) ;
2006-05-15 16:25:03 +04:00
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
smbcli_close ( cli - > tree , fnum ) ;
fname = BASEDIR " \\ test4.txt " ;
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( fnum ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to reopen %s - %s \n " ,
fname , smbcli_errstr ( cli - > tree ) ) ) ;
2006-05-15 16:25:03 +04:00
io . lockx . level = RAW_LOCK_LOCKX ;
io . lockx . in . file . fnum = fnum ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ;
io . lockx . in . timeout = 0 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . pid = cli - > session - > pid ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
io . lockx . in . locks = & lock [ 0 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2010-09-10 13:51:15 +04:00
start = time_mono ( NULL ) ;
2009-07-06 17:36:03 +04:00
io . lockx . in . timeout = t ;
2006-05-15 16:25:03 +04:00
req = smb_raw_lock_send ( cli - > tree , & io ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( req ! = NULL ) , talloc_asprintf ( tctx ,
" Failed to setup timed lock (%s) \n " , __location__ ) ) ;
2006-05-15 16:25:03 +04:00
io . lockx . in . timeout = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_LOCK_NOT_GRANTED ) ;
status = smbcli_request_simple_recv ( req ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
2009-07-06 17:36:03 +04:00
delay = t / 1000 ;
if ( TARGET_IS_W2K8 ( tctx ) | | TARGET_IS_WIN7 ( tctx ) ) {
delay / = 2 ;
}
2010-09-10 13:51:15 +04:00
torture_assert ( tctx , ! ( time_mono ( NULL ) < start + delay ) , talloc_asprintf ( tctx ,
2009-07-06 17:36:03 +04:00
" lock comes back to early timeout[%d] delay[%d] "
" (%s) \n " , t , delay , __location__ ) ) ;
2006-05-15 16:25:03 +04:00
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
done :
2004-10-18 15:47:13 +04:00
smb_raw_exit ( cli - > session ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
/*
test LOCKING_ANDX_CHANGE_LOCKTYPE
*/
2007-08-28 16:54:27 +04:00
static bool test_changetype ( struct torture_context * tctx ,
struct smbcli_state * cli )
2004-10-18 15:47:13 +04:00
{
union smb_lock io ;
struct smb_lock_entry lock [ 2 ] ;
NTSTATUS status ;
2007-10-07 02:28:14 +04:00
bool ret = true ;
2004-10-18 15:47:13 +04:00
int fnum ;
2004-12-04 16:56:25 +03:00
uint8_t c = 0 ;
2004-10-18 15:47:13 +04:00
const char * fname = BASEDIR " \\ test.txt " ;
2012-05-18 09:43:31 +04:00
torture_assert ( tctx , torture_setup_dir ( cli , BASEDIR ) , " Failed to setup up test directory: " BASEDIR ) ;
2004-10-18 15:47:13 +04:00
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Testing LOCKING_ANDX_CHANGE_LOCKTYPE \n " ) ;
2004-10-18 15:47:13 +04:00
io . generic . level = RAW_LOCK_LOCKX ;
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( fnum ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to create %s - %s \n " ,
fname , smbcli_errstr ( cli - > tree ) ) ) ;
2004-10-18 15:47:13 +04:00
io . lockx . level = RAW_LOCK_LOCKX ;
2006-03-13 01:48:25 +03:00
io . lockx . in . file . fnum = fnum ;
2004-10-18 15:47:13 +04:00
io . lockx . in . mode = LOCKING_ANDX_SHARED_LOCK ;
io . lockx . in . timeout = 0 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
lock [ 0 ] . pid = cli - > session - > pid ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
io . lockx . in . locks = & lock [ 0 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
if ( smbcli_write ( cli - > tree , fnum , 0 , & c , 100 , 1 ) = = 1 ) {
2009-04-24 14:28:59 +04:00
torture_result ( tctx , TORTURE_FAIL ,
" allowed write on read locked region (%s) \n " , __location__ ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2004-10-18 15:47:13 +04:00
goto done ;
}
/* windows server don't seem to support this */
io . lockx . in . mode = LOCKING_ANDX_CHANGE_LOCKTYPE ;
status = smb_raw_lock ( cli - > tree , & io ) ;
2005-07-04 09:05:28 +04:00
CHECK_STATUS ( status , NT_STATUS_DOS ( ERRDOS , ERRnoatomiclocks ) ) ;
2004-10-18 15:47:13 +04:00
if ( smbcli_write ( cli - > tree , fnum , 0 , & c , 100 , 1 ) = = 1 ) {
2009-04-24 14:28:59 +04:00
torture_result ( tctx , TORTURE_FAIL ,
" allowed write after lock change (%s) \n " , __location__ ) ;
2007-10-07 02:28:14 +04:00
ret = false ;
2004-10-18 15:47:13 +04:00
goto done ;
}
2004-10-18 12:41:44 +04:00
done :
smbcli_close ( cli - > tree , fnum ) ;
smb_raw_exit ( cli - > session ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
2009-02-10 08:58:50 +03:00
struct double_lock_test {
struct smb_lock_entry lock1 ;
struct smb_lock_entry lock2 ;
NTSTATUS exp_status ;
} ;
/**
* Tests zero byte locks .
*/
2009-11-25 05:38:46 +03:00
static struct double_lock_test zero_byte_tests [ ] = {
2009-02-10 08:58:50 +03:00
/* {pid, offset, count}, {pid, offset, count}, status */
/** First, takes a zero byte lock at offset 10. Then:
* - Taking 0 byte lock at 10 should succeed .
* - Taking 1 byte locks at 9 , 10 , 11 should succeed .
* - Taking 2 byte lock at 9 should fail .
* - Taking 2 byte lock at 10 should succeed .
* - Taking 3 byte lock at 9 should fail .
*/
{ { 1000 , 10 , 0 } , { 1001 , 10 , 0 } , NT_STATUS_OK } ,
{ { 1000 , 10 , 0 } , { 1001 , 9 , 1 } , NT_STATUS_OK } ,
{ { 1000 , 10 , 0 } , { 1001 , 10 , 1 } , NT_STATUS_OK } ,
{ { 1000 , 10 , 0 } , { 1001 , 11 , 1 } , NT_STATUS_OK } ,
{ { 1000 , 10 , 0 } , { 1001 , 9 , 2 } , NT_STATUS_LOCK_NOT_GRANTED } ,
{ { 1000 , 10 , 0 } , { 1001 , 10 , 2 } , NT_STATUS_OK } ,
{ { 1000 , 10 , 0 } , { 1001 , 9 , 3 } , NT_STATUS_LOCK_NOT_GRANTED } ,
/** Same, but opposite order. */
{ { 1001 , 10 , 0 } , { 1000 , 10 , 0 } , NT_STATUS_OK } ,
{ { 1001 , 9 , 1 } , { 1000 , 10 , 0 } , NT_STATUS_OK } ,
{ { 1001 , 10 , 1 } , { 1000 , 10 , 0 } , NT_STATUS_OK } ,
{ { 1001 , 11 , 1 } , { 1000 , 10 , 0 } , NT_STATUS_OK } ,
{ { 1001 , 9 , 2 } , { 1000 , 10 , 0 } , NT_STATUS_LOCK_NOT_GRANTED } ,
{ { 1001 , 10 , 2 } , { 1000 , 10 , 0 } , NT_STATUS_OK } ,
{ { 1001 , 9 , 3 } , { 1000 , 10 , 0 } , NT_STATUS_LOCK_NOT_GRANTED } ,
/** Zero zero case. */
{ { 1000 , 0 , 0 } , { 1001 , 0 , 0 } , NT_STATUS_OK } ,
} ;
static bool test_zerobytelocks ( struct torture_context * tctx , struct smbcli_state * cli )
{
union smb_lock io ;
NTSTATUS status ;
bool ret = true ;
int fnum , i ;
const char * fname = BASEDIR " \\ zero.txt " ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Testing zero length byte range locks: \n " ) ;
2009-02-10 08:58:50 +03:00
2012-05-18 09:43:31 +04:00
torture_assert ( tctx , torture_setup_dir ( cli , BASEDIR ) , " Failed to setup up test directory: " BASEDIR ) ;
2009-02-10 08:58:50 +03:00
io . generic . level = RAW_LOCK_LOCKX ;
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( fnum ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to create %s - %s \n " ,
fname , smbcli_errstr ( cli - > tree ) ) ) ;
2009-02-10 08:58:50 +03:00
/* Setup initial parameters */
io . lockx . level = RAW_LOCK_LOCKX ;
io . lockx . in . file . fnum = fnum ;
io . lockx . in . mode = LOCKING_ANDX_LARGE_FILES ; /* Exclusive */
io . lockx . in . timeout = 0 ;
/* Try every combination of locks in zero_byte_tests. The first lock is
* assumed to succeed . The second lock may contend , depending on the
* expected status . */
for ( i = 0 ;
2009-07-06 17:48:32 +04:00
i < ARRAY_SIZE ( zero_byte_tests ) ;
2009-02-10 08:58:50 +03:00
i + + ) {
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " ... {%d, %llu, %llu} + {%d, %llu, %llu} = %s \n " ,
2009-02-10 08:58:50 +03:00
zero_byte_tests [ i ] . lock1 . pid ,
2010-11-01 13:17:37 +03:00
( unsigned long long ) zero_byte_tests [ i ] . lock1 . offset ,
( unsigned long long ) zero_byte_tests [ i ] . lock1 . count ,
2009-02-10 08:58:50 +03:00
zero_byte_tests [ i ] . lock2 . pid ,
2010-11-01 13:17:37 +03:00
( unsigned long long ) zero_byte_tests [ i ] . lock2 . offset ,
( unsigned long long ) zero_byte_tests [ i ] . lock2 . count ,
2009-02-10 08:58:50 +03:00
nt_errstr ( zero_byte_tests [ i ] . exp_status ) ) ;
/* Lock both locks. */
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
2009-11-20 13:35:13 +03:00
io . lockx . in . locks = discard_const_p ( struct smb_lock_entry ,
& zero_byte_tests [ i ] . lock1 ) ;
2009-02-10 08:58:50 +03:00
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2009-11-20 13:35:13 +03:00
io . lockx . in . locks = discard_const_p ( struct smb_lock_entry ,
& zero_byte_tests [ i ] . lock2 ) ;
2009-02-10 08:58:50 +03:00
status = smb_raw_lock ( cli - > tree , & io ) ;
if ( NT_STATUS_EQUAL ( zero_byte_tests [ i ] . exp_status ,
NT_STATUS_LOCK_NOT_GRANTED ) ) {
/* Allow either of the failure messages and keep going
* if we see the wrong status . */
CHECK_STATUS_OR_CONT ( status ,
NT_STATUS_LOCK_NOT_GRANTED ,
NT_STATUS_FILE_LOCK_CONFLICT ) ;
} else {
CHECK_STATUS_CONT ( status ,
zero_byte_tests [ i ] . exp_status ) ;
}
/* Unlock both locks. */
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
if ( NT_STATUS_EQUAL ( status , NT_STATUS_OK ) ) {
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
}
2009-11-20 13:35:13 +03:00
io . lockx . in . locks = discard_const_p ( struct smb_lock_entry ,
& zero_byte_tests [ i ] . lock1 ) ;
2009-02-10 08:58:50 +03:00
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
}
done :
smbcli_close ( cli - > tree , fnum ) ;
smb_raw_exit ( cli - > session ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
static bool test_unlock ( struct torture_context * tctx , struct smbcli_state * cli )
{
union smb_lock io ;
NTSTATUS status ;
bool ret = true ;
int fnum1 , fnum2 ;
const char * fname = BASEDIR " \\ unlock.txt " ;
struct smb_lock_entry lock1 ;
struct smb_lock_entry lock2 ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Testing LOCKX unlock: \n " ) ;
2009-02-10 08:58:50 +03:00
2012-05-18 09:43:31 +04:00
torture_assert ( tctx , torture_setup_dir ( cli , BASEDIR ) , " Failed to setup up test directory: " BASEDIR ) ;
2009-02-10 08:58:50 +03:00
fnum1 = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( fnum1 ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to create %s - %s \n " ,
fname , smbcli_errstr ( cli - > tree ) ) ) ;
2009-02-10 08:58:50 +03:00
fnum2 = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( fnum2 ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to create %s - %s \n " ,
fname , smbcli_errstr ( cli - > tree ) ) ) ;
2009-02-10 08:58:50 +03:00
/* Setup initial parameters */
io . lockx . level = RAW_LOCK_LOCKX ;
io . lockx . in . timeout = 0 ;
lock1 . pid = cli - > session - > pid ;
lock1 . offset = 0 ;
lock1 . count = 10 ;
lock2 . pid = cli - > session - > pid - 1 ;
lock2 . offset = 0 ;
lock2 . count = 10 ;
/**
* Take exclusive lock , then unlock it with a shared - unlock call .
*/
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " taking exclusive lock. \n " ) ;
2009-02-10 08:58:50 +03:00
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = 0 ;
io . lockx . in . file . fnum = fnum1 ;
io . lockx . in . locks = & lock1 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " unlock the exclusive with a shared unlock call. \n " ) ;
2009-02-10 08:58:50 +03:00
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
io . lockx . in . mode = LOCKING_ANDX_SHARED_LOCK ;
io . lockx . in . file . fnum = fnum1 ;
io . lockx . in . locks = & lock1 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " try shared lock on pid2/fnum2, testing the unlock. \n " ) ;
2009-02-10 08:58:50 +03:00
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = LOCKING_ANDX_SHARED_LOCK ;
io . lockx . in . file . fnum = fnum2 ;
io . lockx . in . locks = & lock2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/**
* Unlock a shared lock with an exclusive - unlock call .
*/
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " unlock new shared lock with exclusive unlock call. \n " ) ;
2009-02-10 08:58:50 +03:00
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
io . lockx . in . mode = 0 ;
io . lockx . in . file . fnum = fnum2 ;
io . lockx . in . locks = & lock2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " try exclusive lock on pid1, testing the unlock. \n " ) ;
2009-02-10 08:58:50 +03:00
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = 0 ;
io . lockx . in . file . fnum = fnum1 ;
io . lockx . in . locks = & lock1 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* cleanup */
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/**
* Test unlocking of 0 - byte locks .
*/
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " lock shared and exclusive 0-byte locks, testing that Windows "
2009-02-10 08:58:50 +03:00
" always unlocks the exclusive first. \n " ) ;
lock1 . pid = cli - > session - > pid ;
lock1 . offset = 10 ;
lock1 . count = 0 ;
lock2 . pid = cli - > session - > pid ;
lock2 . offset = 5 ;
lock2 . count = 10 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . file . fnum = fnum1 ;
io . lockx . in . locks = & lock1 ;
/* lock 0-byte shared
* Note : Order of the shared / exclusive locks doesn ' t matter . */
io . lockx . in . mode = LOCKING_ANDX_SHARED_LOCK ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* lock 0-byte exclusive */
io . lockx . in . mode = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* test contention */
io . lockx . in . mode = LOCKING_ANDX_SHARED_LOCK ;
io . lockx . in . locks = & lock2 ;
io . lockx . in . file . fnum = fnum2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS_OR ( status , NT_STATUS_LOCK_NOT_GRANTED ,
NT_STATUS_FILE_LOCK_CONFLICT ) ;
/* unlock */
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
io . lockx . in . file . fnum = fnum1 ;
io . lockx . in . locks = & lock1 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* test - can we take a shared lock? */
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = LOCKING_ANDX_SHARED_LOCK ;
io . lockx . in . file . fnum = fnum2 ;
io . lockx . in . locks = & lock2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
2009-07-06 17:36:03 +04:00
/* XXX Samba 3 will fail this test. This is temporary(because this isn't
2009-02-10 08:58:50 +03:00
* new to Win7 , it succeeds in WinXP too ) , until I can come to a
* resolution as to whether Samba should support this or not . There is
* code to preference unlocking exclusive locks before shared locks ,
* but its wrapped with " #ifdef ZERO_ZERO " . - zkirsch */
2009-07-06 17:36:03 +04:00
if ( TARGET_IS_SAMBA3 ( tctx ) ) {
2009-02-10 08:58:50 +03:00
CHECK_STATUS_OR ( status , NT_STATUS_LOCK_NOT_GRANTED ,
NT_STATUS_FILE_LOCK_CONFLICT ) ;
2009-07-06 17:36:03 +04:00
} else {
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2009-02-10 08:58:50 +03:00
}
/* cleanup */
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
2009-04-24 17:36:00 +04:00
/* XXX Same as above. */
2009-07-06 17:36:03 +04:00
if ( TARGET_IS_SAMBA3 ( tctx ) ) {
2009-04-24 17:36:00 +04:00
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
2009-07-06 17:36:03 +04:00
} else {
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2009-04-24 17:36:00 +04:00
}
2009-02-10 08:58:50 +03:00
io . lockx . in . file . fnum = fnum1 ;
io . lockx . in . locks = & lock1 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
done :
smbcli_close ( cli - > tree , fnum1 ) ;
smbcli_close ( cli - > tree , fnum2 ) ;
smb_raw_exit ( cli - > session ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
static bool test_multiple_unlock ( struct torture_context * tctx , struct smbcli_state * cli )
{
union smb_lock io ;
NTSTATUS status ;
bool ret = true ;
int fnum1 ;
const char * fname = BASEDIR " \\ unlock_multiple.txt " ;
struct smb_lock_entry lock1 ;
struct smb_lock_entry lock2 ;
struct smb_lock_entry locks [ 2 ] ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Testing LOCKX multiple unlock: \n " ) ;
2009-02-10 08:58:50 +03:00
2012-05-18 09:43:31 +04:00
torture_assert ( tctx , torture_setup_dir ( cli , BASEDIR ) , " Failed to setup up test directory: " BASEDIR ) ;
2009-02-10 08:58:50 +03:00
fnum1 = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( fnum1 ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to create %s - %s \n " ,
fname , smbcli_errstr ( cli - > tree ) ) ) ;
2009-02-10 08:58:50 +03:00
/* Setup initial parameters */
io . lockx . level = RAW_LOCK_LOCKX ;
io . lockx . in . timeout = 0 ;
lock1 . pid = cli - > session - > pid ;
lock1 . offset = 0 ;
lock1 . count = 10 ;
lock2 . pid = cli - > session - > pid ;
lock2 . offset = 10 ;
lock2 . count = 10 ;
locks [ 0 ] = lock1 ;
locks [ 1 ] = lock2 ;
io . lockx . in . file . fnum = fnum1 ;
io . lockx . in . mode = 0 ; /* exclusive */
/** Test1: Take second lock, but not first. */
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " unlock 2 locks, first one not locked. Expect no locks "
2009-02-10 08:58:50 +03:00
" unlocked. \n " ) ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . locks = & lock2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* Try to unlock both locks. */
io . lockx . in . ulock_cnt = 2 ;
io . lockx . in . lock_cnt = 0 ;
io . lockx . in . locks = locks ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
/* Second lock should not be unlocked. */
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . locks = & lock2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_LOCK_NOT_GRANTED ) ;
/* cleanup */
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
io . lockx . in . locks = & lock2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/** Test2: Take first lock, but not second. */
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " unlock 2 locks, second one not locked. Expect first lock "
2009-02-10 08:58:50 +03:00
" unlocked. \n " ) ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . locks = & lock1 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* Try to unlock both locks. */
io . lockx . in . ulock_cnt = 2 ;
io . lockx . in . lock_cnt = 0 ;
io . lockx . in . locks = locks ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
/* First lock should be unlocked. */
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . locks = & lock1 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* cleanup */
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
io . lockx . in . locks = & lock1 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2009-12-01 04:05:27 +03:00
/* Test3: Request 2 locks, second will contend. What happens to the
* first ? */
torture_comment ( tctx , " request 2 locks, second one will contend. "
" Expect both to fail. \n " ) ;
/* Lock the second range */
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . locks = & lock2 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* Request both locks */
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 2 ;
io . lockx . in . locks = locks ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
/* First lock should be unlocked. */
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . locks = & lock1 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* cleanup */
io . lockx . in . ulock_cnt = 2 ;
io . lockx . in . lock_cnt = 0 ;
io . lockx . in . locks = locks ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* Test4: Request unlock and lock. The lock contends, is the unlock
* then re - locked ? */
torture_comment ( tctx , " request unlock and lock, second one will "
" contend. Expect the unlock to succeed. \n " ) ;
/* Lock both ranges */
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 2 ;
io . lockx . in . locks = locks ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* Attempt to unlock the first range and lock the second */
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . locks = locks ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
/* The first lock should've been unlocked */
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . locks = & lock1 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* cleanup */
io . lockx . in . ulock_cnt = 2 ;
io . lockx . in . lock_cnt = 0 ;
io . lockx . in . locks = locks ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2009-02-10 08:58:50 +03:00
done :
smbcli_close ( cli - > tree , fnum1 ) ;
smb_raw_exit ( cli - > session ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
/**
* torture_locktest5 covers stacking pretty well , but its missing two tests :
* - stacking an exclusive on top of shared fails
* - stacking two exclusives fail
*/
static bool test_stacking ( struct torture_context * tctx , struct smbcli_state * cli )
{
union smb_lock io ;
NTSTATUS status ;
bool ret = true ;
int fnum1 ;
const char * fname = BASEDIR " \\ stacking.txt " ;
struct smb_lock_entry lock1 ;
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " Testing stacking: \n " ) ;
2009-02-10 08:58:50 +03:00
2012-05-18 09:43:31 +04:00
torture_assert ( tctx , torture_setup_dir ( cli , BASEDIR ) , " Failed to setup up test directory: " BASEDIR ) ;
2009-02-10 08:58:50 +03:00
io . generic . level = RAW_LOCK_LOCKX ;
fnum1 = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2009-04-24 14:28:59 +04:00
torture_assert ( tctx , ( fnum1 ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to create %s - %s \n " ,
fname , smbcli_errstr ( cli - > tree ) ) ) ;
2009-02-10 08:58:50 +03:00
/* Setup initial parameters */
io . lockx . level = RAW_LOCK_LOCKX ;
io . lockx . in . timeout = 0 ;
lock1 . pid = cli - > session - > pid ;
lock1 . offset = 0 ;
lock1 . count = 10 ;
/**
* Try to take a shared lock , then stack an exclusive .
*/
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " stacking an exclusive on top of a shared lock fails. \n " ) ;
2009-02-10 08:58:50 +03:00
io . lockx . in . file . fnum = fnum1 ;
io . lockx . in . locks = & lock1 ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = LOCKING_ANDX_SHARED_LOCK ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS_OR ( status , NT_STATUS_LOCK_NOT_GRANTED ,
NT_STATUS_FILE_LOCK_CONFLICT ) ;
/* cleanup */
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/**
* Prove that two exclusive locks do not stack .
*/
2009-04-24 14:28:59 +04:00
torture_comment ( tctx , " two exclusive locks do not stack. \n " ) ;
2009-02-10 08:58:50 +03:00
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS_OR ( status , NT_STATUS_LOCK_NOT_GRANTED ,
NT_STATUS_FILE_LOCK_CONFLICT ) ;
/* cleanup */
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
done :
smbcli_close ( cli - > tree , fnum1 ) ;
smb_raw_exit ( cli - > session ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
2004-10-18 12:41:44 +04:00
2009-12-04 05:50:33 +03:00
/**
* Test how 0 - byte read requests contend with byte range locks
*/
static bool test_zerobyteread ( struct torture_context * tctx ,
struct smbcli_state * cli )
{
union smb_lock io ;
union smb_read rd ;
NTSTATUS status ;
bool ret = true ;
int fnum1 , fnum2 ;
const char * fname = BASEDIR " \\ zerobyteread.txt " ;
struct smb_lock_entry lock1 ;
uint8_t c = 1 ;
2012-05-18 09:43:31 +04:00
torture_assert ( tctx , torture_setup_dir ( cli , BASEDIR ) , " Failed to setup up test directory: " BASEDIR ) ;
2009-12-04 05:50:33 +03:00
io . generic . level = RAW_LOCK_LOCKX ;
fnum1 = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
torture_assert ( tctx , ( fnum1 ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to create %s - %s \n " ,
fname , smbcli_errstr ( cli - > tree ) ) ) ;
fnum2 = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
torture_assert ( tctx , ( fnum2 ! = - 1 ) , talloc_asprintf ( tctx ,
" Failed to create %s - %s \n " ,
fname , smbcli_errstr ( cli - > tree ) ) ) ;
/* Setup initial parameters */
io . lockx . level = RAW_LOCK_LOCKX ;
io . lockx . in . timeout = 0 ;
lock1 . pid = cli - > session - > pid ;
lock1 . offset = 0 ;
lock1 . count = 10 ;
ZERO_STRUCT ( rd ) ;
rd . readx . level = RAW_READ_READX ;
torture_comment ( tctx , " Testing zero byte read on lock range: \n " ) ;
/* Take an exclusive lock */
torture_comment ( tctx , " taking exclusive lock. \n " ) ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = LOCKING_ANDX_EXCLUSIVE_LOCK ;
io . lockx . in . file . fnum = fnum1 ;
io . lockx . in . locks = & lock1 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* Try a zero byte read */
torture_comment ( tctx , " reading 0 bytes. \n " ) ;
rd . readx . in . file . fnum = fnum2 ;
rd . readx . in . offset = 5 ;
rd . readx . in . mincnt = 0 ;
rd . readx . in . maxcnt = 0 ;
rd . readx . in . remaining = 0 ;
rd . readx . in . read_for_execute = false ;
rd . readx . out . data = & c ;
status = smb_raw_read ( cli - > tree , & rd ) ;
torture_assert_int_equal_goto ( tctx , rd . readx . out . nread , 0 , ret , done ,
" zero byte read did not return 0 bytes " ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* Unlock lock */
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
io . lockx . in . mode = LOCKING_ANDX_EXCLUSIVE_LOCK ;
io . lockx . in . file . fnum = fnum1 ;
io . lockx . in . locks = & lock1 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
torture_comment ( tctx , " Testing zero byte read on zero byte lock "
" range: \n " ) ;
/* Take an exclusive lock */
torture_comment ( tctx , " taking exclusive 0-byte lock. \n " ) ;
io . lockx . in . ulock_cnt = 0 ;
io . lockx . in . lock_cnt = 1 ;
io . lockx . in . mode = LOCKING_ANDX_EXCLUSIVE_LOCK ;
io . lockx . in . file . fnum = fnum1 ;
io . lockx . in . locks = & lock1 ;
lock1 . offset = 5 ;
lock1 . count = 0 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* Try a zero byte read before the lock */
torture_comment ( tctx , " reading 0 bytes before the lock. \n " ) ;
rd . readx . in . file . fnum = fnum2 ;
rd . readx . in . offset = 4 ;
rd . readx . in . mincnt = 0 ;
rd . readx . in . maxcnt = 0 ;
rd . readx . in . remaining = 0 ;
rd . readx . in . read_for_execute = false ;
rd . readx . out . data = & c ;
status = smb_raw_read ( cli - > tree , & rd ) ;
torture_assert_int_equal_goto ( tctx , rd . readx . out . nread , 0 , ret , done ,
" zero byte read did not return 0 bytes " ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* Try a zero byte read on the lock */
torture_comment ( tctx , " reading 0 bytes on the lock. \n " ) ;
rd . readx . in . file . fnum = fnum2 ;
rd . readx . in . offset = 5 ;
rd . readx . in . mincnt = 0 ;
rd . readx . in . maxcnt = 0 ;
rd . readx . in . remaining = 0 ;
rd . readx . in . read_for_execute = false ;
rd . readx . out . data = & c ;
status = smb_raw_read ( cli - > tree , & rd ) ;
torture_assert_int_equal_goto ( tctx , rd . readx . out . nread , 0 , ret , done ,
" zero byte read did not return 0 bytes " ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* Try a zero byte read after the lock */
torture_comment ( tctx , " reading 0 bytes after the lock. \n " ) ;
rd . readx . in . file . fnum = fnum2 ;
rd . readx . in . offset = 6 ;
rd . readx . in . mincnt = 0 ;
rd . readx . in . maxcnt = 0 ;
rd . readx . in . remaining = 0 ;
rd . readx . in . read_for_execute = false ;
rd . readx . out . data = & c ;
status = smb_raw_read ( cli - > tree , & rd ) ;
torture_assert_int_equal_goto ( tctx , rd . readx . out . nread , 0 , ret , done ,
" zero byte read did not return 0 bytes " ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
/* Unlock lock */
io . lockx . in . ulock_cnt = 1 ;
io . lockx . in . lock_cnt = 0 ;
io . lockx . in . mode = LOCKING_ANDX_EXCLUSIVE_LOCK ;
io . lockx . in . file . fnum = fnum1 ;
io . lockx . in . locks = & lock1 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
done :
smbcli_close ( cli - > tree , fnum1 ) ;
smbcli_close ( cli - > tree , fnum2 ) ;
smb_raw_exit ( cli - > session ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
/*
2004-10-18 12:41:44 +04:00
basic testing of lock calls
*/
2007-08-28 16:54:27 +04:00
struct torture_suite * torture_raw_lock ( TALLOC_CTX * mem_ctx )
2004-10-18 12:41:44 +04:00
{
2010-12-11 05:26:31 +03:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " lock " ) ;
2004-10-18 12:41:44 +04:00
2007-08-28 16:54:27 +04:00
torture_suite_add_1smb_test ( suite , " lockx " , test_lockx ) ;
torture_suite_add_1smb_test ( suite , " lock " , test_lock ) ;
torture_suite_add_1smb_test ( suite , " pidhigh " , test_pidhigh ) ;
torture_suite_add_1smb_test ( suite , " async " , test_async ) ;
torture_suite_add_1smb_test ( suite , " errorcode " , test_errorcode ) ;
torture_suite_add_1smb_test ( suite , " changetype " , test_changetype ) ;
2004-10-18 12:41:44 +04:00
2009-02-10 08:58:50 +03:00
torture_suite_add_1smb_test ( suite , " stacking " , test_stacking ) ;
torture_suite_add_1smb_test ( suite , " unlock " , test_unlock ) ;
torture_suite_add_1smb_test ( suite , " multiple_unlock " ,
test_multiple_unlock ) ;
2010-12-11 05:26:31 +03:00
torture_suite_add_1smb_test ( suite , " zerobytelocks " , test_zerobytelocks ) ;
torture_suite_add_1smb_test ( suite , " zerobyteread " , test_zerobyteread ) ;
2009-02-10 08:58:50 +03:00
2007-08-28 16:54:27 +04:00
return suite ;
2003-08-13 05:53:07 +04:00
}