2003-08-13 01:53:07 +00: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 02:07:03 +00:00
the Free Software Foundation ; either version 3 of the License , or
2003-08-13 01:53:07 +00:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 02:07:03 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2003-08-13 01:53:07 +00:00
*/
# include "includes.h"
2006-01-03 13:41:17 +00:00
# include "torture/torture.h"
2004-11-01 01:03:22 +00:00
# include "libcli/raw/libcliraw.h"
2004-11-02 00:24:21 +00:00
# include "system/time.h"
2005-02-10 05:09:35 +00:00
# include "system/filesys.h"
2006-01-03 15:40:05 +00:00
# include "libcli/libcli.h"
2006-03-17 17:59:58 +00:00
# include "torture/util.h"
2006-05-15 12:25:03 +00:00
# include "libcli/composite/composite.h"
# include "libcli/smb_composite/smb_composite.h"
# include "lib/cmdline/popt_common.h"
2007-09-08 12:42:09 +00:00
# include "param/param.h"
2003-08-13 01:53:07 +00:00
# define CHECK_STATUS(status, correct) do { \
if ( ! NT_STATUS_EQUAL ( status , correct ) ) { \
2004-10-18 08:41:44 +00:00
printf ( " (%s) Incorrect status %s - should be %s \n " , \
__location__ , nt_errstr ( status ) , nt_errstr ( correct ) ) ; \
2003-08-13 01:53:07 +00:00
ret = False ; \
goto done ; \
} } while ( 0 )
# define BASEDIR "\\testlock"
/*
test SMBlock and SMBunlock ops
*/
2007-08-28 12:54:27 +00:00
static bool test_lock ( struct torture_context * tctx , struct smbcli_state * cli )
2003-08-13 01:53:07 +00:00
{
union smb_lock io ;
NTSTATUS status ;
BOOL ret = True ;
int fnum ;
const char * fname = BASEDIR " \\ test.txt " ;
2004-11-12 09:37:59 +00:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2003-08-13 01:53:07 +00:00
return False ;
}
printf ( " Testing RAW_LOCK_LOCK \n " ) ;
io . generic . level = RAW_LOCK_LOCK ;
2004-08-04 13:23:35 +00:00
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2003-08-13 01:53:07 +00:00
if ( fnum = = - 1 ) {
2004-08-04 13:23:35 +00:00
printf ( " Failed to create %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 01:53:07 +00:00
ret = False ;
goto done ;
}
printf ( " Trying 0/0 lock \n " ) ;
io . lock . level = RAW_LOCK_LOCK ;
2006-03-12 22:48:25 +00:00
io . lock . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00: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 ) ;
printf ( " Trying 0/1 lock \n " ) ;
io . lock . level = RAW_LOCK_LOCK ;
2006-03-12 22:48:25 +00:00
io . lock . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00: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 ) ;
2004-10-18 07:40:17 +00:00
printf ( " Trying 0xEEFFFFFF lock \n " ) ;
io . lock . level = RAW_LOCK_LOCK ;
2006-03-12 22:48:25 +00:00
io . lock . in . file . fnum = fnum ;
2004-10-18 07:40:17 +00: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 ) ;
printf ( " Trying 0xEF000000 lock \n " ) ;
io . lock . level = RAW_LOCK_LOCK ;
2006-03-12 22:48:25 +00:00
io . lock . in . file . fnum = fnum ;
2004-10-18 07:40:17 +00: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 ) ;
2003-08-13 01:53:07 +00:00
printf ( " Trying max lock \n " ) ;
io . lock . level = RAW_LOCK_LOCK ;
2006-03-12 22:48:25 +00:00
io . lock . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00:00
io . lock . in . count = 4000 ;
2004-10-18 07:40:17 +00:00
io . lock . in . offset = 0xEF000000 ;
2003-08-13 01:53:07 +00: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 ) ;
printf ( " Trying wrong pid unlock \n " ) ;
io . lock . level = RAW_LOCK_LOCK ;
2006-03-12 22:48:25 +00:00
io . lock . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00: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 13:23:35 +00:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 01:53:07 +00:00
smb_raw_exit ( cli - > session ) ;
2004-08-04 13:23:35 +00:00
smbcli_deltree ( cli - > tree , BASEDIR ) ;
2003-08-13 01:53:07 +00:00
return ret ;
}
/*
test locking & X ops
*/
2007-08-28 12:54:27 +00:00
static bool test_lockx ( struct torture_context * tctx , struct smbcli_state * cli )
2003-08-13 01:53:07 +00:00
{
union smb_lock io ;
struct smb_lock_entry lock [ 1 ] ;
NTSTATUS status ;
BOOL ret = True ;
int fnum ;
const char * fname = BASEDIR " \\ test.txt " ;
2004-11-12 09:37:59 +00:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2003-08-13 01:53:07 +00:00
return False ;
}
printf ( " Testing RAW_LOCK_LOCKX \n " ) ;
io . generic . level = RAW_LOCK_LOCKX ;
2004-08-04 13:23:35 +00:00
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2003-08-13 01:53:07 +00:00
if ( fnum = = - 1 ) {
2004-08-04 13:23:35 +00:00
printf ( " Failed to create %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 01:53:07 +00:00
ret = False ;
goto done ;
}
io . lockx . level = RAW_LOCK_LOCKX ;
2006-03-12 22:48:25 +00:00
io . lockx . in . file . fnum = fnum ;
2003-08-13 01:53:07 +00: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 08:41:44 +00:00
lock [ 0 ] . offset = 10 ;
lock [ 0 ] . count = 1 ;
2003-08-13 01:53:07 +00:00
io . lockx . in . locks = & lock [ 0 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2004-10-18 08:41:44 +00:00
printf ( " Trying 0xEEFFFFFF lock \n " ) ;
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 ) ;
printf ( " Trying 0xEF000000 lock \n " ) ;
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 ) ;
printf ( " Trying zero lock \n " ) ;
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 ) ;
printf ( " Trying max lock \n " ) ;
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 ) ;
printf ( " Trying 2^63 \n " ) ;
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 ) ;
printf ( " Trying 2^63 - 1 \n " ) ;
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 ) ;
printf ( " Trying max lock 2 \n " ) ;
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 ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
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 ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
2003-08-13 01:53:07 +00:00
done :
2004-08-04 13:23:35 +00:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 02:04:44 +00:00
smb_raw_exit ( cli - > session ) ;
2004-08-04 13:23:35 +00:00
smbcli_deltree ( cli - > tree , BASEDIR ) ;
2003-08-13 02:04:44 +00:00
return ret ;
}
/*
test high pid
*/
2007-08-28 12:54:27 +00:00
static bool test_pidhigh ( struct torture_context * tctx ,
struct smbcli_state * cli )
2003-08-13 02:04:44 +00:00
{
union smb_lock io ;
struct smb_lock_entry lock [ 1 ] ;
NTSTATUS status ;
BOOL ret = True ;
int fnum ;
const char * fname = BASEDIR " \\ test.txt " ;
2004-12-04 13:56:25 +00:00
uint8_t c = 1 ;
2003-08-13 02:04:44 +00:00
2004-11-12 09:37:59 +00:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2003-08-13 02:04:44 +00:00
return False ;
}
printf ( " Testing high pid \n " ) ;
io . generic . level = RAW_LOCK_LOCKX ;
cli - > session - > pid = 1 ;
2004-08-04 13:23:35 +00:00
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2003-08-13 02:04:44 +00:00
if ( fnum = = - 1 ) {
2004-08-04 13:23:35 +00:00
printf ( " Failed to create %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 02:04:44 +00:00
ret = False ;
goto done ;
}
2004-08-04 13:23:35 +00:00
if ( smbcli_write ( cli - > tree , fnum , 0 , & c , 0 , 1 ) ! = 1 ) {
printf ( " Failed to write 1 byte - %s \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 02:04:44 +00:00
ret = False ;
goto done ;
}
io . lockx . level = RAW_LOCK_LOCKX ;
2006-03-12 22:48:25 +00:00
io . lockx . in . file . fnum = fnum ;
2003-08-13 02:04:44 +00: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 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , & c , 0 , 1 ) ! = 1 ) {
printf ( " Failed to read 1 byte - %s \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 02:04:44 +00:00
ret = False ;
goto done ;
}
cli - > session - > pid | = 0x10000 ;
cli - > session - > pid = 2 ;
2004-08-04 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , & c , 0 , 1 ) = = 1 ) {
2003-08-13 02:04:44 +00:00
printf ( " pid is incorrect handled for read with lock! \n " ) ;
ret = False ;
goto done ;
}
cli - > session - > pid = 0x10001 ;
2004-08-04 13:23:35 +00:00
if ( smbcli_read ( cli - > tree , fnum , & c , 0 , 1 ) ! = 1 ) {
2003-08-13 02:04:44 +00:00
printf ( " High pid is used on this server! \n " ) ;
ret = False ;
} else {
printf ( " High pid is not used on this server (correct) \n " ) ;
}
done :
2004-08-04 13:23:35 +00:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 01:53:07 +00:00
smb_raw_exit ( cli - > session ) ;
2004-08-04 13:23:35 +00:00
smbcli_deltree ( cli - > tree , BASEDIR ) ;
2003-08-13 01:53:07 +00:00
return ret ;
}
2004-10-18 08:41:44 +00:00
/*
test locking & X async operation
2003-08-13 01:53:07 +00:00
*/
2007-08-28 12:54:27 +00:00
static bool test_async ( struct torture_context * tctx ,
struct smbcli_state * cli )
2003-08-13 01:53:07 +00:00
{
2006-05-15 12:25:03 +00: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 08:41:44 +00:00
union smb_lock io ;
struct smb_lock_entry lock [ 2 ] ;
NTSTATUS status ;
2003-08-13 01:53:07 +00:00
BOOL ret = True ;
2004-10-18 08:41:44 +00:00
int fnum ;
const char * fname = BASEDIR " \\ test.txt " ;
time_t t ;
struct smbcli_request * req ;
2003-08-13 01:53:07 +00:00
2004-11-12 09:37:59 +00:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2003-08-13 01:53:07 +00:00
return False ;
}
2004-10-18 11:47:13 +00:00
printf ( " Testing LOCKING_ANDX_CANCEL_LOCK \n " ) ;
2004-10-18 08:41:44 +00:00
io . generic . level = RAW_LOCK_LOCKX ;
2006-05-15 12:25:03 +00:00
2004-10-18 08:41:44 +00:00
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
if ( fnum = = - 1 ) {
printf ( " Failed to create %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 01:53:07 +00:00
ret = False ;
2004-10-18 08:41:44 +00:00
goto done ;
2003-08-13 01:53:07 +00:00
}
2004-10-18 08:41:44 +00:00
io . lockx . level = RAW_LOCK_LOCKX ;
2006-03-12 22:48:25 +00:00
io . lockx . in . file . fnum = fnum ;
2004-10-18 08:41:44 +00: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 ;
io . lockx . in . locks = & lock [ 0 ] ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
t = time ( NULL ) ;
2004-10-18 11:47:13 +00:00
printf ( " testing cancel by CANCEL_LOCK \n " ) ;
2004-10-18 08:41:44 +00:00
/* setup a timed lock */
io . lockx . in . timeout = 10000 ;
req = smb_raw_lock_send ( cli - > tree , & io ) ;
if ( req = = NULL ) {
printf ( " Failed to setup timed lock (%s) \n " , __location__ ) ;
2003-08-13 01:53:07 +00:00
ret = False ;
2004-10-18 08:41:44 +00:00
goto done ;
2003-08-13 01:53:07 +00:00
}
2004-10-18 08:41:44 +00: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 05:05:28 +00:00
CHECK_STATUS ( status , NT_STATUS_DOS ( ERRDOS , ERRcancelviolation ) ) ;
2004-10-18 08:41:44 +00: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 05:05:28 +00:00
CHECK_STATUS ( status , NT_STATUS_DOS ( ERRDOS , ERRcancelviolation ) ) ;
2004-10-18 08:41:44 +00: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 ) ;
if ( time ( NULL ) > t + 2 ) {
printf ( " lock cancel was not immediate (%s) \n " , __location__ ) ;
2003-08-13 02:04:44 +00:00
ret = False ;
2004-10-18 08:41:44 +00:00
goto done ;
2003-08-13 02:04:44 +00:00
}
2004-10-18 11:47:13 +00:00
printf ( " testing cancel by unlock \n " ) ;
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 ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
io . lockx . in . timeout = 5000 ;
req = smb_raw_lock_send ( cli - > tree , & io ) ;
if ( req = = NULL ) {
printf ( " Failed to setup timed lock (%s) \n " , __location__ ) ;
ret = False ;
goto done ;
}
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 ) ;
2005-05-02 16:00:18 +00:00
t = time ( NULL ) ;
2004-10-18 11:47:13 +00:00
status = smbcli_request_simple_recv ( req ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
if ( time ( NULL ) > t + 2 ) {
2005-05-02 16:00:18 +00:00
printf ( " lock cancel by unlock was not immediate (%s) - took %d secs \n " ,
2005-05-09 02:29:22 +00:00
__location__ , ( int ) ( time ( NULL ) - t ) ) ;
2004-10-18 11:47:13 +00:00
ret = False ;
goto done ;
}
printf ( " testing cancel by close \n " ) ;
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 ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
2006-05-15 12:25:03 +00:00
t = time ( NULL ) ;
2004-10-18 11:47:13 +00:00
io . lockx . in . timeout = 10000 ;
req = smb_raw_lock_send ( cli - > tree , & io ) ;
if ( req = = NULL ) {
printf ( " Failed to setup timed lock (%s) \n " , __location__ ) ;
ret = False ;
goto done ;
}
2006-05-15 12:25:03 +00:00
status = smbcli_close ( cli - > tree , fnum ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
2004-10-18 11:47:13 +00:00
status = smbcli_request_simple_recv ( req ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
if ( time ( NULL ) > t + 2 ) {
2006-05-15 12:25:03 +00:00
printf ( " lock cancel by close was not immediate (%s) \n " , __location__ ) ;
ret = False ;
goto done ;
}
printf ( " create a new sessions \n " ) ;
2007-08-28 12:54:27 +00:00
session = smbcli_session_init ( cli - > transport , tctx , False ) ;
2006-05-15 12:25:03 +00:00
setup . in . sesskey = cli - > transport - > negotiate . sesskey ;
setup . in . capabilities = cli - > transport - > negotiate . capabilities ;
setup . in . workgroup = lp_workgroup ( ) ;
setup . in . credentials = cmdline_credentials ;
status = smb_composite_sesssetup ( session , & setup ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
session - > vuid = setup . out . vuid ;
printf ( " create new tree context \n " ) ;
share = lp_parm_string ( - 1 , " torture " , " share " ) ;
host = lp_parm_string ( - 1 , " torture " , " host " ) ;
2007-08-28 12:54:27 +00:00
tree = smbcli_tree_init ( session , tctx , False ) ;
2006-05-15 12:25:03 +00:00
tcon . generic . level = RAW_TCON_TCONX ;
tcon . tconx . in . flags = 0 ;
tcon . tconx . in . password = data_blob ( NULL , 0 ) ;
2007-08-28 12:54:27 +00:00
tcon . tconx . in . path = talloc_asprintf ( tctx , " \\ \\ %s \\ %s " , host , share ) ;
2006-05-15 12:25:03 +00:00
tcon . tconx . in . device = " A: " ;
2007-08-28 12:54:27 +00:00
status = smb_raw_tcon ( tree , tctx , & tcon ) ;
2006-05-15 12:25:03 +00:00
CHECK_STATUS ( status , NT_STATUS_OK ) ;
tree - > tid = tcon . tconx . out . tid ;
printf ( " testing cancel by exit \n " ) ;
fname = BASEDIR " \\ test_exit.txt " ;
fnum = smbcli_open ( tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
if ( fnum = = - 1 ) {
printf ( " Failed to reopen %s - %s \n " , fname , smbcli_errstr ( tree ) ) ;
ret = False ;
goto done ;
}
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 ;
t = time ( NULL ) ;
req = smb_raw_lock_send ( tree , & io ) ;
if ( req = = NULL ) {
printf ( " Failed to setup timed lock (%s) \n " , __location__ ) ;
ret = False ;
goto done ;
}
status = smb_raw_exit ( session ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
status = smbcli_request_simple_recv ( req ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
if ( time ( NULL ) > t + 2 ) {
printf ( " lock cancel by exit was not immediate (%s) \n " , __location__ ) ;
ret = False ;
goto done ;
}
printf ( " testing cancel by ulogoff \n " ) ;
fname = BASEDIR " \\ test_ulogoff.txt " ;
fnum = smbcli_open ( tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
if ( fnum = = - 1 ) {
printf ( " Failed to reopen %s - %s \n " , fname , smbcli_errstr ( tree ) ) ;
ret = False ;
goto done ;
}
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 ;
t = time ( NULL ) ;
req = smb_raw_lock_send ( tree , & io ) ;
if ( req = = NULL ) {
printf ( " Failed to setup timed lock (%s) \n " , __location__ ) ;
ret = False ;
goto done ;
}
status = smb_raw_ulogoff ( session ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
status = smbcli_request_simple_recv ( req ) ;
if ( NT_STATUS_EQUAL ( NT_STATUS_FILE_LOCK_CONFLICT , status ) ) {
printf ( " 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 ) ;
if ( time ( NULL ) > t + 2 ) {
printf ( " lock cancel by ulogoff was not immediate (%s) \n " , __location__ ) ;
ret = False ;
goto done ;
}
printf ( " testing cancel by tdis \n " ) ;
tree - > session = cli - > session ;
fname = BASEDIR " \\ test_tdis.txt " ;
fnum = smbcli_open ( tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
if ( fnum = = - 1 ) {
printf ( " Failed to reopen %s - %s \n " , fname , smbcli_errstr ( tree ) ) ;
ret = False ;
goto done ;
}
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 ;
t = time ( NULL ) ;
req = smb_raw_lock_send ( tree , & io ) ;
if ( req = = NULL ) {
printf ( " Failed to setup timed lock (%s) \n " , __location__ ) ;
ret = False ;
goto done ;
}
status = smb_tree_disconnect ( tree ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
status = smbcli_request_simple_recv ( req ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
if ( time ( NULL ) > t + 2 ) {
printf ( " lock cancel by tdis was not immediate (%s) \n " , __location__ ) ;
2004-10-18 11:47:13 +00:00
ret = False ;
goto done ;
}
done :
2006-05-15 12:25:03 +00: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 12:54:27 +00:00
static bool test_errorcode ( struct torture_context * tctx ,
struct smbcli_state * cli )
2006-05-15 12:25:03 +00:00
{
union smb_lock io ;
union smb_open op ;
struct smb_lock_entry lock [ 2 ] ;
NTSTATUS status ;
BOOL ret = True ;
int fnum , fnum2 ;
const char * fname ;
struct smbcli_request * req ;
time_t start ;
int t ;
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
return False ;
}
printf ( " Testing LOCK_NOT_GRANTED vs. FILE_LOCK_CONFLICT \n " ) ;
printf ( " testing with timeout = 0 \n " ) ;
fname = BASEDIR " \\ test0.txt " ;
t = 0 ;
/*
* the first run is with t = 0 ,
* the second with t > 0 ( = 1 )
*/
next_run :
/*
* use the DENY_DOS mode , that creates two fnum ' s of one low - level file handle ,
* this demonstrates that the cache is per fnum
*/
op . openx . level = RAW_OPEN_OPENX ;
op . openx . in . fname = fname ;
op . openx . in . flags = OPENX_FLAGS_ADDITIONAL_INFO ;
op . openx . in . open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_DOS ;
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 12:54:27 +00:00
status = smb_raw_open ( cli - > tree , tctx , & op ) ;
2006-05-15 12:25:03 +00:00
CHECK_STATUS ( status , NT_STATUS_OK ) ;
fnum = op . openx . out . file . fnum ;
2007-08-28 12:54:27 +00:00
status = smb_raw_open ( cli - > tree , tctx , & op ) ;
2006-05-15 12:25:03 +00: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
* resets the resets the cache
*/
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 ) ;
printf ( " testing with timeout > 0 (=1) \n " ) ;
fname = BASEDIR " \\ test1.txt " ;
t = 1 ;
goto next_run ;
}
/*
* 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 ) ;
printf ( " testing a conflict while a lock is pending \n " ) ;
fname = BASEDIR " \\ test2.txt " ;
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
if ( fnum = = - 1 ) {
printf ( " Failed to reopen %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
ret = False ;
goto done ;
}
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 ) ;
start = time ( NULL ) ;
io . lockx . in . timeout = 1000 ;
req = smb_raw_lock_send ( cli - > tree , & io ) ;
if ( req = = NULL ) {
printf ( " Failed to setup timed lock (%s) \n " , __location__ ) ;
ret = False ;
goto done ;
}
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 ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_LOCK_NOT_GRANTED ) ;
if ( time ( NULL ) < start + 1 ) {
printf ( " lock comes back to early (%s) \n " , __location__ ) ;
ret = False ;
goto done ;
}
2004-10-18 11:47:13 +00:00
smbcli_close ( cli - > tree , fnum ) ;
2006-05-15 12:25:03 +00:00
fname = BASEDIR " \\ test3.txt " ;
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
if ( fnum = = - 1 ) {
printf ( " Failed to reopen %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
ret = False ;
goto done ;
}
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 ) ;
start = time ( NULL ) ;
io . lockx . in . timeout = 1000 ;
req = smb_raw_lock_send ( cli - > tree , & io ) ;
if ( req = = NULL ) {
printf ( " Failed to setup timed lock (%s) \n " , __location__ ) ;
ret = False ;
goto done ;
}
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 ) ;
lock [ 0 ] . offset = 100 ;
lock [ 0 ] . count = 10 ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
if ( time ( NULL ) < start + 1 ) {
printf ( " lock comes back to early (%s) \n " , __location__ ) ;
ret = False ;
goto done ;
}
smbcli_close ( cli - > tree , fnum ) ;
fname = BASEDIR " \\ test4.txt " ;
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
if ( fnum = = - 1 ) {
printf ( " Failed to reopen %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
ret = False ;
goto done ;
}
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 ) ;
start = time ( NULL ) ;
io . lockx . in . timeout = 1000 ;
req = smb_raw_lock_send ( cli - > tree , & io ) ;
if ( req = = NULL ) {
printf ( " Failed to setup timed lock (%s) \n " , __location__ ) ;
ret = False ;
goto done ;
}
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 ) ;
status = smb_raw_lock ( cli - > tree , & io ) ;
CHECK_STATUS ( status , NT_STATUS_FILE_LOCK_CONFLICT ) ;
if ( time ( NULL ) < start + 1 ) {
printf ( " lock comes back to early (%s) \n " , __location__ ) ;
ret = False ;
goto done ;
}
done :
2004-10-18 11:47:13 +00:00
smb_raw_exit ( cli - > session ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
/*
test LOCKING_ANDX_CHANGE_LOCKTYPE
*/
2007-08-28 12:54:27 +00:00
static bool test_changetype ( struct torture_context * tctx ,
struct smbcli_state * cli )
2004-10-18 11:47:13 +00:00
{
union smb_lock io ;
struct smb_lock_entry lock [ 2 ] ;
NTSTATUS status ;
BOOL ret = True ;
int fnum ;
2004-12-04 13:56:25 +00:00
uint8_t c = 0 ;
2004-10-18 11:47:13 +00:00
const char * fname = BASEDIR " \\ test.txt " ;
2004-11-12 09:37:59 +00:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2004-10-18 11:47:13 +00:00
return False ;
}
printf ( " Testing LOCKING_ANDX_CHANGE_LOCKTYPE \n " ) ;
io . generic . level = RAW_LOCK_LOCKX ;
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
if ( fnum = = - 1 ) {
printf ( " Failed to create %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
ret = False ;
goto done ;
}
io . lockx . level = RAW_LOCK_LOCKX ;
2006-03-12 22:48:25 +00:00
io . lockx . in . file . fnum = fnum ;
2004-10-18 11:47:13 +00: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 ) {
printf ( " allowed write on read locked region (%s) \n " , __location__ ) ;
ret = False ;
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 05:05:28 +00:00
CHECK_STATUS ( status , NT_STATUS_DOS ( ERRDOS , ERRnoatomiclocks ) ) ;
2004-10-18 11:47:13 +00:00
if ( smbcli_write ( cli - > tree , fnum , 0 , & c , 100 , 1 ) = = 1 ) {
printf ( " allowed write after lock change (%s) \n " , __location__ ) ;
ret = False ;
goto done ;
}
2004-10-18 08:41:44 +00:00
done :
smbcli_close ( cli - > tree , fnum ) ;
smb_raw_exit ( cli - > session ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
/*
basic testing of lock calls
*/
2007-08-28 12:54:27 +00:00
struct torture_suite * torture_raw_lock ( TALLOC_CTX * mem_ctx )
2004-10-18 08:41:44 +00:00
{
2007-08-28 12:54:27 +00:00
struct torture_suite * suite = torture_suite_create ( mem_ctx , " LOCK " ) ;
2004-10-18 08:41:44 +00:00
2007-08-28 12:54:27 +00: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 08:41:44 +00:00
2007-08-28 12:54:27 +00:00
return suite ;
2003-08-13 01:53:07 +00:00
}