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
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# 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"
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"
2003-08-13 05:53:07 +04:00
# define CHECK_STATUS(status, correct) do { \
if ( ! NT_STATUS_EQUAL ( status , correct ) ) { \
2004-10-18 12:41:44 +04:00
printf ( " (%s) Incorrect status %s - should be %s \n " , \
__location__ , nt_errstr ( status ) , nt_errstr ( correct ) ) ; \
2003-08-13 05:53:07 +04:00
ret = False ; \
goto done ; \
} } while ( 0 )
# define CHECK_VALUE(v, correct) do { \
if ( ( v ) ! = ( correct ) ) { \
2004-10-18 12:41:44 +04:00
printf ( " (%s) Incorrect value %s=%d - should be %d \n " , \
__location__ , # v , v , correct ) ; \
2003-08-13 05:53:07 +04:00
ret = False ; \
goto done ; \
} } while ( 0 )
# define BASEDIR "\\testlock"
/*
test SMBlock and SMBunlock ops
*/
2004-08-04 17:23:35 +04:00
static BOOL test_lock ( struct smbcli_state * cli , TALLOC_CTX * mem_ctx )
2003-08-13 05:53:07 +04:00
{
union smb_lock io ;
NTSTATUS status ;
BOOL ret = True ;
int fnum ;
const char * fname = BASEDIR " \\ test.txt " ;
2004-11-12 12:37:59 +03:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2003-08-13 05:53:07 +04:00
return False ;
}
printf ( " Testing RAW_LOCK_LOCK \n " ) ;
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 ) ;
2003-08-13 05:53:07 +04:00
if ( fnum = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " Failed to create %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
ret = False ;
goto done ;
}
printf ( " Trying 0/0 lock \n " ) ;
io . lock . level = RAW_LOCK_LOCK ;
2006-03-10 23:49:20 +03:00
io . lock . 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 ) ;
printf ( " Trying 0/1 lock \n " ) ;
io . lock . level = RAW_LOCK_LOCK ;
2006-03-10 23:49:20 +03:00
io . lock . 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 ) ;
2004-10-18 11:40:17 +04:00
printf ( " Trying 0xEEFFFFFF lock \n " ) ;
io . lock . level = RAW_LOCK_LOCK ;
2006-03-10 23:49:20 +03:00
io . lock . 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 ) ;
printf ( " Trying 0xEF000000 lock \n " ) ;
io . lock . level = RAW_LOCK_LOCK ;
2006-03-10 23:49:20 +03:00
io . lock . 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 ) ;
2003-08-13 05:53:07 +04:00
printf ( " Trying max lock \n " ) ;
io . lock . level = RAW_LOCK_LOCK ;
2006-03-10 23:49:20 +03:00
io . lock . 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 ) ;
printf ( " Trying wrong pid unlock \n " ) ;
io . lock . level = RAW_LOCK_LOCK ;
2006-03-10 23:49:20 +03:00
io . lock . 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
*/
2004-08-04 17:23:35 +04:00
static BOOL test_lockx ( struct smbcli_state * cli , TALLOC_CTX * mem_ctx )
2003-08-13 05:53:07 +04: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 12:37:59 +03:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2003-08-13 05:53:07 +04:00
return False ;
}
printf ( " Testing RAW_LOCK_LOCKX \n " ) ;
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 ) ;
2003-08-13 05:53:07 +04:00
if ( fnum = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " Failed to create %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
ret = False ;
goto done ;
}
io . lockx . level = RAW_LOCK_LOCKX ;
2006-03-10 23:49:20 +03:00
io . lockx . 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
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 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
*/
2004-08-04 17:23:35 +04:00
static BOOL test_pidhigh ( struct smbcli_state * cli , TALLOC_CTX * mem_ctx )
2003-08-13 06:04:44 +04: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 16:56:25 +03:00
uint8_t c = 1 ;
2003-08-13 06:04:44 +04:00
2004-11-12 12:37:59 +03:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2003-08-13 06:04:44 +04:00
return False ;
}
printf ( " Testing high pid \n " ) ;
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 ) ;
2003-08-13 06:04:44 +04:00
if ( fnum = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " Failed to create %s - %s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 06:04:44 +04:00
ret = False ;
goto done ;
}
2004-08-04 17:23:35 +04: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 06:04:44 +04:00
ret = False ;
goto done ;
}
io . lockx . level = RAW_LOCK_LOCKX ;
2006-03-10 23:49:20 +03:00
io . lockx . 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 ) {
printf ( " Failed to read 1 byte - %s \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 06:04:44 +04:00
ret = False ;
goto done ;
}
cli - > session - > pid | = 0x10000 ;
cli - > session - > pid = 2 ;
2004-08-04 17:23:35 +04:00
if ( smbcli_read ( cli - > tree , fnum , & c , 0 , 1 ) = = 1 ) {
2003-08-13 06:04:44 +04:00
printf ( " pid is incorrect handled for read with lock! \n " ) ;
ret = False ;
goto done ;
}
cli - > session - > pid = 0x10001 ;
2004-08-04 17:23:35 +04:00
if ( smbcli_read ( cli - > tree , fnum , & c , 0 , 1 ) ! = 1 ) {
2003-08-13 06:04:44 +04: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 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
*/
2004-10-18 12:41:44 +04:00
static BOOL test_async ( struct smbcli_state * cli , TALLOC_CTX * mem_ctx )
2003-08-13 05:53:07 +04:00
{
2004-10-18 12:41:44 +04:00
union smb_lock io ;
struct smb_lock_entry lock [ 2 ] ;
NTSTATUS status ;
2003-08-13 05:53:07 +04:00
BOOL ret = True ;
2004-10-18 12:41:44 +04:00
int fnum ;
const char * fname = BASEDIR " \\ test.txt " ;
time_t t ;
struct smbcli_request * req ;
2003-08-13 05:53:07 +04:00
2004-11-12 12:37:59 +03:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2003-08-13 05:53:07 +04:00
return False ;
}
2004-10-18 15:47:13 +04:00
printf ( " Testing LOCKING_ANDX_CANCEL_LOCK \n " ) ;
2004-10-18 12:41:44 +04:00
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 ) ) ;
2003-08-13 05:53:07 +04:00
ret = False ;
2004-10-18 12:41:44 +04:00
goto done ;
2003-08-13 05:53:07 +04:00
}
2004-10-18 12:41:44 +04:00
io . lockx . level = RAW_LOCK_LOCKX ;
2006-03-10 23:49:20 +03:00
io . lockx . 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 ;
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 15:47:13 +04:00
printf ( " testing cancel by CANCEL_LOCK \n " ) ;
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 ) ;
if ( req = = NULL ) {
printf ( " Failed to setup timed lock (%s) \n " , __location__ ) ;
2003-08-13 05:53:07 +04:00
ret = False ;
2004-10-18 12:41:44 +04:00
goto done ;
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 ) ;
if ( time ( NULL ) > t + 2 ) {
printf ( " lock cancel was not immediate (%s) \n " , __location__ ) ;
2003-08-13 06:04:44 +04:00
ret = False ;
2004-10-18 12:41:44 +04:00
goto done ;
2003-08-13 06:04:44 +04:00
}
2004-10-18 15:47:13 +04: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 20:00:18 +04:00
t = time ( NULL ) ;
2004-10-18 15:47:13 +04:00
status = smbcli_request_simple_recv ( req ) ;
CHECK_STATUS ( status , NT_STATUS_OK ) ;
if ( time ( NULL ) > t + 2 ) {
2005-05-02 20:00:18 +04:00
printf ( " lock cancel by unlock was not immediate (%s) - took %d secs \n " ,
2005-05-09 06:29:22 +04:00
__location__ , ( int ) ( time ( NULL ) - t ) ) ;
2004-10-18 15:47:13 +04: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 ) ;
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 ;
}
smbcli_close ( cli - > tree , fnum ) ;
status = smbcli_request_simple_recv ( req ) ;
CHECK_STATUS ( status , NT_STATUS_RANGE_NOT_LOCKED ) ;
if ( time ( NULL ) > t + 2 ) {
printf ( " lock cancel by unlock was not immediate (%s) \n " , __location__ ) ;
ret = False ;
goto done ;
}
done :
smbcli_close ( cli - > tree , fnum ) ;
smb_raw_exit ( cli - > session ) ;
smbcli_deltree ( cli - > tree , BASEDIR ) ;
return ret ;
}
/*
test LOCKING_ANDX_CHANGE_LOCKTYPE
*/
static BOOL test_changetype ( struct smbcli_state * cli , TALLOC_CTX * mem_ctx )
{
union smb_lock io ;
struct smb_lock_entry lock [ 2 ] ;
NTSTATUS status ;
BOOL ret = True ;
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 " ;
2004-11-12 12:37:59 +03:00
if ( ! torture_setup_dir ( cli , BASEDIR ) ) {
2004-10-18 15:47:13 +04: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-10 23:49:20 +03:00
io . lockx . 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 ) {
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 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 ) {
printf ( " allowed write after lock change (%s) \n " , __location__ ) ;
ret = False ;
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 ;
}
/*
basic testing of lock calls
*/
2004-10-28 17:40:50 +04:00
BOOL torture_raw_lock ( void )
2004-10-18 12:41:44 +04:00
{
struct smbcli_state * cli ;
BOOL ret = True ;
TALLOC_CTX * mem_ctx ;
if ( ! torture_open_connection ( & cli ) ) {
return False ;
}
mem_ctx = talloc_init ( " torture_raw_lock " ) ;
ret & = test_lockx ( cli , mem_ctx ) ;
ret & = test_lock ( cli , mem_ctx ) ;
ret & = test_pidhigh ( cli , mem_ctx ) ;
ret & = test_async ( cli , mem_ctx ) ;
2004-10-18 15:47:13 +04:00
ret & = test_changetype ( cli , mem_ctx ) ;
2004-10-18 12:41:44 +04:00
2003-08-13 05:53:07 +04:00
torture_close_connection ( cli ) ;
2005-01-27 10:08:20 +03:00
talloc_free ( mem_ctx ) ;
2003-08-13 05:53:07 +04:00
return ret ;
}