2003-08-13 05:53:07 +04:00
/*
Unix SMB / CIFS implementation .
SMB torture tester
Copyright ( C ) Andrew Tridgell 1997 - 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"
2004-11-30 08:37:57 +03:00
# include "clilist.h"
2004-11-02 05:57:18 +03:00
# include "lib/cmdline/popt_common.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"
2004-11-02 07:51:57 +03:00
# include "system/wait.h"
2005-02-10 08:09:35 +03:00
# include "system/filesys.h"
2004-11-02 09:42:15 +03:00
# include "ioctl.h"
2004-11-30 07:33:27 +03:00
# include "librpc/gen_ndr/ndr_security.h"
2003-08-13 05:53:07 +04:00
2004-03-09 05:13:13 +03:00
int torture_nprocs = 4 ;
2003-08-13 05:53:07 +04:00
int torture_numops = 100 ;
int torture_entries = 1000 ;
int torture_failures = 1 ;
2004-10-30 08:59:52 +04:00
int torture_seed = 0 ;
2003-08-13 05:53:07 +04:00
static int procnum ; /* records process count number when forking */
2004-08-04 17:23:35 +04:00
static struct smbcli_state * current_cli ;
2003-08-13 05:53:07 +04:00
static BOOL use_oplocks ;
static BOOL use_level_II_oplocks ;
BOOL torture_showall = False ;
# define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
2004-08-04 17:23:35 +04:00
static struct smbcli_state * open_nbt_connection ( void )
2003-08-13 05:53:07 +04:00
{
2005-01-21 14:18:56 +03:00
struct nbt_name called , calling ;
2004-08-04 17:23:35 +04:00
struct smbcli_state * cli ;
2004-06-14 03:50:55 +04:00
const char * host = lp_parm_string ( - 1 , " torture " , " host " ) ;
2003-08-13 05:53:07 +04:00
2005-05-22 14:23:01 +04:00
make_nbt_name_client ( & calling , lp_netbios_name ( ) ) ;
2005-01-21 14:18:56 +03:00
nbt_choose_called_name ( NULL , & called , host , NBT_NAME_SERVER ) ;
2003-08-13 05:53:07 +04:00
2004-09-28 09:44:59 +04:00
cli = smbcli_state_init ( NULL ) ;
2003-08-13 05:53:07 +04:00
if ( ! cli ) {
2004-08-04 17:23:35 +04:00
printf ( " Failed initialize smbcli_struct to connect with %s \n " , host ) ;
2005-06-18 04:02:36 +04:00
goto failed ;
2003-08-13 05:53:07 +04:00
}
2004-08-19 00:13:08 +04:00
if ( ! smbcli_socket_connect ( cli , host ) ) {
2003-08-13 05:53:07 +04:00
printf ( " Failed to connect with %s \n " , host ) ;
2005-06-18 04:02:36 +04:00
goto failed ;
2003-08-13 05:53:07 +04:00
}
2004-08-04 17:23:35 +04:00
if ( ! smbcli_transport_establish ( cli , & calling , & called ) ) {
2005-01-21 14:18:56 +03:00
printf ( " %s rejected the session \n " , host ) ;
2005-06-18 04:02:36 +04:00
goto failed ;
2003-08-13 05:53:07 +04:00
}
return cli ;
2005-06-18 04:02:36 +04:00
failed :
talloc_free ( cli ) ;
return NULL ;
2003-08-13 05:53:07 +04:00
}
2005-08-24 17:15:01 +04:00
BOOL torture_open_connection_share ( TALLOC_CTX * mem_ctx ,
struct smbcli_state * * c ,
2004-03-09 12:04:06 +03:00
const char * hostname ,
2005-08-24 17:15:01 +04:00
const char * sharename ,
struct event_context * ev )
2003-08-13 05:53:07 +04:00
{
NTSTATUS status ;
2005-08-24 17:15:01 +04:00
status = smbcli_full_connection ( mem_ctx , c , hostname ,
2005-01-15 14:58:52 +03:00
sharename , NULL ,
2005-08-24 17:15:01 +04:00
cmdline_credentials , ev ) ;
2003-08-13 05:53:07 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2003-08-13 20:04:21 +04:00
printf ( " Failed to open connection - %s \n " , nt_errstr ( status ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
( * c ) - > transport - > options . use_oplocks = use_oplocks ;
( * c ) - > transport - > options . use_level2_oplocks = use_level_II_oplocks ;
return True ;
}
2004-08-04 17:23:35 +04:00
BOOL torture_open_connection ( struct smbcli_state * * c )
2004-03-09 12:04:06 +03:00
{
2004-06-14 03:50:55 +04:00
const char * host = lp_parm_string ( - 1 , " torture " , " host " ) ;
const char * share = lp_parm_string ( - 1 , " torture " , " share " ) ;
2004-03-09 12:04:06 +03:00
2005-08-24 17:15:01 +04:00
return torture_open_connection_share ( NULL , c , host , share , NULL ) ;
2004-03-09 12:04:06 +03:00
}
2004-08-04 17:23:35 +04:00
BOOL torture_close_connection ( struct smbcli_state * c )
2003-08-13 05:53:07 +04:00
{
BOOL ret = True ;
if ( ! c ) return True ;
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_tdis ( c ) ) ) {
printf ( " tdis failed (%s) \n " , smbcli_errstr ( c - > tree ) ) ;
2003-08-13 05:53:07 +04:00
ret = False ;
}
2005-06-18 04:02:36 +04:00
talloc_free ( c ) ;
2003-08-13 05:53:07 +04:00
return ret ;
}
2004-09-02 15:26:58 +04:00
/* open a rpc connection to the chosen binding string */
2005-03-22 11:00:45 +03:00
NTSTATUS torture_rpc_connection ( TALLOC_CTX * parent_ctx ,
struct dcerpc_pipe * * p ,
2003-11-24 16:19:00 +03:00
const char * pipe_name ,
const char * pipe_uuid ,
2004-05-25 20:24:13 +04:00
uint32_t pipe_version )
2003-11-24 15:40:47 +03:00
{
NTSTATUS status ;
2004-06-14 03:50:55 +04:00
const char * binding = lp_parm_string ( - 1 , " torture " , " binding " ) ;
2003-11-26 04:16:41 +03:00
2003-12-15 06:29:55 +03:00
if ( ! binding ) {
printf ( " You must specify a ncacn binding string \n " ) ;
return NT_STATUS_INVALID_PARAMETER ;
2003-11-24 16:19:00 +03:00
}
2005-03-22 11:00:45 +03:00
status = dcerpc_pipe_connect ( parent_ctx ,
p , binding , pipe_uuid , pipe_version ,
2005-06-16 15:36:09 +04:00
cmdline_credentials , NULL ) ;
2003-11-24 15:40:47 +03:00
return status ;
}
2004-09-03 12:28:24 +04:00
/* open a rpc connection to a specific transport */
2005-03-22 11:00:45 +03:00
NTSTATUS torture_rpc_connection_transport ( TALLOC_CTX * parent_ctx ,
struct dcerpc_pipe * * p ,
2004-09-03 12:28:24 +04:00
const char * pipe_name ,
const char * pipe_uuid ,
uint32_t pipe_version ,
enum dcerpc_transport_t transport )
2004-09-02 15:26:58 +04:00
{
NTSTATUS status ;
const char * binding = lp_parm_string ( - 1 , " torture " , " binding " ) ;
r5902: A rather large change...
I wanted to add a simple 'workstation' argument to the DCERPC
authenticated binding calls, but this patch kind of grew from there.
With SCHANNEL, the 'workstation' name (the netbios name of the client)
matters, as this is what ties the session between the NETLOGON ops and
the SCHANNEL bind. This changes a lot of files, and these will again
be changed when jelmer does the credentials work.
I also correct some schannel IDL to distinguish between workstation
names and account names. The distinction matters for domain trust
accounts.
Issues in handling this (issues with lifetime of talloc pointers)
caused me to change the 'creds_CredentialsState' and 'struct
dcerpc_binding' pointers to always be talloc()ed pointers.
In the schannel DB, we now store both the domain and computername, and
query on both. This should ensure we fault correctly when the domain
is specified incorrectly in the SCHANNEL bind.
In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out,
where the comment claimed we re-used a connection, but in fact we made
a new connection.
This was achived by breaking apart some of the
dcerpc_secondary_connection() logic.
The addition of workstation handling was also propogated to NTLMSSP
and GENSEC, for completeness.
The RPC-SAMSYNC test has been cleaned up a little, using a loop over
usernames/passwords rather than manually expanded tests. This will be
expanded further (the code in #if 0 in this patch) to use a newly
created user account for testing.
In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO
server, caused by the removal of [ref] and the assoicated pointer from
the IDL. This has been re-added, until the underlying pidl issues are
solved.
(This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9)
2005-03-19 11:34:43 +03:00
struct dcerpc_binding * b ;
2005-03-22 11:00:45 +03:00
TALLOC_CTX * mem_ctx = talloc_named ( parent_ctx , 0 , " torture_rpc_connection_smb " ) ;
2004-09-02 15:26:58 +04:00
if ( ! binding ) {
printf ( " You must specify a ncacn binding string \n " ) ;
2005-03-22 11:00:45 +03:00
talloc_free ( mem_ctx ) ;
2004-09-02 15:26:58 +04:00
return NT_STATUS_INVALID_PARAMETER ;
}
status = dcerpc_parse_binding ( mem_ctx , binding , & b ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " Failed to parse dcerpc binding '%s' \n " , binding ) ) ;
2005-01-27 10:08:20 +03:00
talloc_free ( mem_ctx ) ;
2004-09-02 15:26:58 +04:00
return status ;
}
r5902: A rather large change...
I wanted to add a simple 'workstation' argument to the DCERPC
authenticated binding calls, but this patch kind of grew from there.
With SCHANNEL, the 'workstation' name (the netbios name of the client)
matters, as this is what ties the session between the NETLOGON ops and
the SCHANNEL bind. This changes a lot of files, and these will again
be changed when jelmer does the credentials work.
I also correct some schannel IDL to distinguish between workstation
names and account names. The distinction matters for domain trust
accounts.
Issues in handling this (issues with lifetime of talloc pointers)
caused me to change the 'creds_CredentialsState' and 'struct
dcerpc_binding' pointers to always be talloc()ed pointers.
In the schannel DB, we now store both the domain and computername, and
query on both. This should ensure we fault correctly when the domain
is specified incorrectly in the SCHANNEL bind.
In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out,
where the comment claimed we re-used a connection, but in fact we made
a new connection.
This was achived by breaking apart some of the
dcerpc_secondary_connection() logic.
The addition of workstation handling was also propogated to NTLMSSP
and GENSEC, for completeness.
The RPC-SAMSYNC test has been cleaned up a little, using a loop over
usernames/passwords rather than manually expanded tests. This will be
expanded further (the code in #if 0 in this patch) to use a newly
created user account for testing.
In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO
server, caused by the removal of [ref] and the assoicated pointer from
the IDL. This has been re-added, until the underlying pidl issues are
solved.
(This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9)
2005-03-19 11:34:43 +03:00
b - > transport = transport ;
2004-09-02 15:26:58 +04:00
2005-03-22 11:00:45 +03:00
status = dcerpc_pipe_connect_b ( mem_ctx , p , b , pipe_uuid , pipe_version ,
2005-06-16 15:36:09 +04:00
cmdline_credentials , NULL ) ;
2005-03-22 00:22:07 +03:00
2005-03-22 11:00:45 +03:00
if ( NT_STATUS_IS_OK ( status ) ) {
* p = talloc_reference ( parent_ctx , * p ) ;
} else {
* p = NULL ;
}
talloc_free ( mem_ctx ) ;
2004-09-02 15:26:58 +04:00
return status ;
}
2003-08-13 05:53:07 +04:00
/* check if the server produced the expected error code */
2004-10-17 06:52:37 +04:00
BOOL check_error ( const char * location , struct smbcli_state * c ,
uint8_t eclass , uint32_t ecode , NTSTATUS nterr )
2003-08-13 05:53:07 +04:00
{
2005-07-04 05:23:38 +04:00
NTSTATUS status ;
status = smbcli_nt_error ( c - > tree ) ;
if ( NT_STATUS_IS_DOS ( status ) ) {
int class , num ;
class = NT_STATUS_DOS_CLASS ( status ) ;
num = NT_STATUS_DOS_CODE ( status ) ;
2003-08-13 05:53:07 +04:00
if ( eclass ! = class | | ecode ! = num ) {
2005-07-04 09:05:28 +04:00
printf ( " unexpected error code %s \n " , nt_errstr ( status ) ) ;
printf ( " expected %s or %s (at %s) \n " ,
nt_errstr ( NT_STATUS_DOS ( eclass , ecode ) ) ,
nt_errstr ( nterr ) , location ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
} else {
2005-07-04 05:23:38 +04:00
if ( ! NT_STATUS_EQUAL ( nterr , status ) ) {
2003-08-13 05:53:07 +04:00
printf ( " unexpected error code %s \n " , nt_errstr ( status ) ) ;
2004-10-17 06:52:37 +04:00
printf ( " expected %s (at %s) \n " , nt_errstr ( nterr ) , location ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
}
return True ;
}
2004-08-04 17:23:35 +04:00
static BOOL wait_lock ( struct smbcli_state * c , int fnum , uint32_t offset , uint32_t len )
2003-08-13 05:53:07 +04:00
{
2004-08-04 17:23:35 +04:00
while ( NT_STATUS_IS_ERR ( smbcli_lock ( c - > tree , fnum , offset , len , - 1 , WRITE_LOCK ) ) ) {
2004-10-17 06:52:37 +04:00
if ( ! check_error ( __location__ , c , ERRDOS , ERRlock , NT_STATUS_LOCK_NOT_GRANTED ) ) return False ;
2003-08-13 05:53:07 +04:00
}
return True ;
}
2004-08-04 17:23:35 +04:00
static BOOL rw_torture ( struct smbcli_state * c )
2003-08-13 05:53:07 +04:00
{
const char * lockfname = " \\ torture.lck " ;
char * fname ;
int fnum ;
int fnum2 ;
pid_t pid2 , pid = getpid ( ) ;
int i , j ;
2004-12-04 16:56:25 +03:00
uint8_t buf [ 1024 ] ;
2003-08-13 05:53:07 +04:00
BOOL correct = True ;
2004-08-04 17:23:35 +04:00
fnum2 = smbcli_open ( c - > tree , lockfname , O_RDWR | O_CREAT | O_EXCL ,
2003-08-13 05:53:07 +04:00
DENY_NONE ) ;
if ( fnum2 = = - 1 )
2004-08-04 17:23:35 +04:00
fnum2 = smbcli_open ( c - > tree , lockfname , O_RDWR , DENY_NONE ) ;
2003-08-13 05:53:07 +04:00
if ( fnum2 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " open of %s failed (%s) \n " , lockfname , smbcli_errstr ( c - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
for ( i = 0 ; i < torture_numops ; i + + ) {
2005-01-21 16:16:33 +03:00
uint_t n = ( uint_t ) random ( ) % 10 ;
2003-08-13 05:53:07 +04:00
if ( i % 10 = = 0 ) {
printf ( " %d \r " , i ) ; fflush ( stdout ) ;
}
asprintf ( & fname , " \\ torture.%u " , n ) ;
if ( ! wait_lock ( c , fnum2 , n * sizeof ( int ) , sizeof ( int ) ) ) {
return False ;
}
2004-08-04 17:23:35 +04:00
fnum = smbcli_open ( c - > tree , fname , O_RDWR | O_CREAT | O_TRUNC , DENY_ALL ) ;
2003-08-13 05:53:07 +04:00
if ( fnum = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " open failed (%s) \n " , smbcli_errstr ( c - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
break ;
}
2004-12-04 16:56:25 +03:00
if ( smbcli_write ( c - > tree , fnum , 0 , & pid , 0 , sizeof ( pid ) ) ! = sizeof ( pid ) ) {
2004-08-04 17:23:35 +04:00
printf ( " write failed (%s) \n " , smbcli_errstr ( c - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
}
for ( j = 0 ; j < 50 ; j + + ) {
2004-12-04 16:56:25 +03:00
if ( smbcli_write ( c - > tree , fnum , 0 , buf ,
2003-08-13 05:53:07 +04:00
sizeof ( pid ) + ( j * sizeof ( buf ) ) ,
sizeof ( buf ) ) ! = sizeof ( buf ) ) {
2004-08-04 17:23:35 +04:00
printf ( " write failed (%s) \n " , smbcli_errstr ( c - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
}
}
pid2 = 0 ;
2004-12-04 16:56:25 +03:00
if ( smbcli_read ( c - > tree , fnum , & pid2 , 0 , sizeof ( pid ) ) ! = sizeof ( pid ) ) {
2004-08-04 17:23:35 +04:00
printf ( " read failed (%s) \n " , smbcli_errstr ( c - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
}
if ( pid2 ! = pid ) {
printf ( " data corruption! \n " ) ;
correct = False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( c - > tree , fnum ) ) ) {
printf ( " close failed (%s) \n " , smbcli_errstr ( c - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_unlink ( c - > tree , fname ) ) ) {
printf ( " unlink failed (%s) \n " , smbcli_errstr ( c - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_unlock ( c - > tree , fnum2 , n * sizeof ( int ) , sizeof ( int ) ) ) ) {
printf ( " unlock failed (%s) \n " , smbcli_errstr ( c - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
}
free ( fname ) ;
}
2004-08-04 17:23:35 +04:00
smbcli_close ( c - > tree , fnum2 ) ;
smbcli_unlink ( c - > tree , lockfname ) ;
2003-08-13 05:53:07 +04:00
printf ( " %d \n " , i ) ;
return correct ;
}
2004-08-04 17:23:35 +04:00
static BOOL run_torture ( struct smbcli_state * cli , int dummy )
2003-08-13 05:53:07 +04:00
{
BOOL ret ;
ret = rw_torture ( cli ) ;
if ( ! torture_close_connection ( cli ) ) {
ret = False ;
}
return ret ;
}
2004-08-04 17:23:35 +04:00
static BOOL rw_torture2 ( struct smbcli_state * c1 , struct smbcli_state * c2 )
2003-08-13 05:53:07 +04:00
{
const char * lockfname = " \\ torture2.lck " ;
int fnum1 ;
int fnum2 ;
int i ;
2004-06-01 12:30:34 +04:00
uint8_t buf [ 131072 ] ;
uint8_t buf_rd [ 131072 ] ;
2003-08-13 05:53:07 +04:00
BOOL correct = True ;
ssize_t bytes_read , bytes_written ;
2004-08-04 17:23:35 +04:00
if ( smbcli_deltree ( c1 - > tree , lockfname ) = = - 1 ) {
printf ( " unlink failed (%s) \n " , smbcli_errstr ( c1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
}
2004-08-04 17:23:35 +04:00
fnum1 = smbcli_open ( c1 - > tree , lockfname , O_RDWR | O_CREAT | O_EXCL ,
2003-08-13 05:53:07 +04:00
DENY_NONE ) ;
if ( fnum1 = = - 1 ) {
printf ( " first open read/write of %s failed (%s) \n " ,
2004-08-04 17:23:35 +04:00
lockfname , smbcli_errstr ( c1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
2004-08-04 17:23:35 +04:00
fnum2 = smbcli_open ( c2 - > tree , lockfname , O_RDONLY ,
2003-08-13 05:53:07 +04:00
DENY_NONE ) ;
if ( fnum2 = = - 1 ) {
printf ( " second open read-only of %s failed (%s) \n " ,
2004-08-04 17:23:35 +04:00
lockfname , smbcli_errstr ( c2 - > tree ) ) ;
smbcli_close ( c1 - > tree , fnum1 ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
printf ( " Checking data integrity over %d ops \n " , torture_numops ) ;
for ( i = 0 ; i < torture_numops ; i + + )
{
2005-01-21 16:16:33 +03:00
size_t buf_size = ( ( uint_t ) random ( ) % ( sizeof ( buf ) - 1 ) ) + 1 ;
2003-08-13 05:53:07 +04:00
if ( i % 10 = = 0 ) {
printf ( " %d \r " , i ) ; fflush ( stdout ) ;
}
2004-07-14 16:14:07 +04:00
generate_random_buffer ( buf , buf_size ) ;
2003-08-13 05:53:07 +04:00
2004-08-04 17:23:35 +04:00
if ( ( bytes_written = smbcli_write ( c1 - > tree , fnum1 , 0 , buf , 0 , buf_size ) ) ! = buf_size ) {
printf ( " write failed (%s) \n " , smbcli_errstr ( c1 - > tree ) ) ;
2005-07-17 13:20:52 +04:00
printf ( " wrote %d, expected %d \n " , ( int ) bytes_written , ( int ) buf_size ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
break ;
}
2004-08-04 17:23:35 +04:00
if ( ( bytes_read = smbcli_read ( c2 - > tree , fnum2 , buf_rd , 0 , buf_size ) ) ! = buf_size ) {
printf ( " read failed (%s) \n " , smbcli_errstr ( c2 - > tree ) ) ;
2005-07-17 13:20:52 +04:00
printf ( " read %d, expected %d \n " , ( int ) bytes_read , ( int ) buf_size ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
break ;
}
if ( memcmp ( buf_rd , buf , buf_size ) ! = 0 )
{
printf ( " read/write compare failed \n " ) ;
correct = False ;
break ;
}
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( c2 - > tree , fnum2 ) ) ) {
printf ( " close failed (%s) \n " , smbcli_errstr ( c2 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( c1 - > tree , fnum1 ) ) ) {
printf ( " close failed (%s) \n " , smbcli_errstr ( c1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_unlink ( c1 - > tree , lockfname ) ) ) {
printf ( " unlink failed (%s) \n " , smbcli_errstr ( c1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
}
return correct ;
}
2005-02-10 10:39:14 +03:00
# define BOOLSTR(b) ((b) ? "Yes" : "No")
2004-10-28 17:40:50 +04:00
static BOOL run_readwritetest ( void )
2003-08-13 05:53:07 +04:00
{
2004-08-04 17:23:35 +04:00
struct smbcli_state * cli1 , * cli2 ;
2003-08-13 05:53:07 +04:00
BOOL test1 , test2 = True ;
if ( ! torture_open_connection ( & cli1 ) | | ! torture_open_connection ( & cli2 ) ) {
return False ;
}
printf ( " starting readwritetest \n " ) ;
test1 = rw_torture2 ( cli1 , cli2 ) ;
printf ( " Passed readwritetest v1: %s \n " , BOOLSTR ( test1 ) ) ;
if ( test1 ) {
test2 = rw_torture2 ( cli1 , cli1 ) ;
printf ( " Passed readwritetest v2: %s \n " , BOOLSTR ( test2 ) ) ;
}
if ( ! torture_close_connection ( cli1 ) ) {
test1 = False ;
}
if ( ! torture_close_connection ( cli2 ) ) {
test2 = False ;
}
return ( test1 & & test2 ) ;
}
/*
this checks to see if a secondary tconx can use open files from an
earlier tconx
*/
2004-10-28 17:40:50 +04:00
static BOOL run_tcon_test ( void )
2003-08-13 05:53:07 +04:00
{
2004-08-04 17:23:35 +04:00
struct smbcli_state * cli ;
2003-08-13 05:53:07 +04:00
const char * fname = " \\ tcontest.tmp " ;
int fnum1 ;
2004-05-25 21:24:24 +04:00
uint16_t cnum1 , cnum2 , cnum3 ;
uint16_t vuid1 , vuid2 ;
2004-12-04 16:56:25 +03:00
uint8_t buf [ 4 ] ;
2003-08-13 05:53:07 +04:00
BOOL ret = True ;
2004-08-04 17:23:35 +04:00
struct smbcli_tree * tree1 ;
2004-06-14 03:50:55 +04:00
const char * host = lp_parm_string ( - 1 , " torture " , " host " ) ;
const char * share = lp_parm_string ( - 1 , " torture " , " share " ) ;
const char * password = lp_parm_string ( - 1 , " torture " , " password " ) ;
2003-08-13 05:53:07 +04:00
if ( ! torture_open_connection ( & cli ) ) {
return False ;
}
printf ( " starting tcontest \n " ) ;
2004-08-04 17:23:35 +04:00
if ( smbcli_deltree ( cli - > tree , fname ) = = - 1 ) {
printf ( " unlink of %s failed (%s) \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
}
2004-08-04 17:23:35 +04:00
fnum1 = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT | O_EXCL , DENY_NONE ) ;
2003-08-13 05:53:07 +04:00
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " open of %s failed (%s) \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
cnum1 = cli - > tree - > tid ;
vuid1 = cli - > session - > vuid ;
memset ( & buf , 0 , 4 ) ; /* init buf so valgrind won't complain */
2004-08-04 17:23:35 +04:00
if ( smbcli_write ( cli - > tree , fnum1 , 0 , buf , 130 , 4 ) ! = 4 ) {
printf ( " initial write failed (%s) \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
tree1 = cli - > tree ; /* save old tree connection */
2005-06-11 07:35:28 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_tconX ( cli , share , " ????? " , password ) ) ) {
2003-08-13 05:53:07 +04:00
printf ( " %s refused 2nd tree connect (%s) \n " , host ,
2004-08-04 17:23:35 +04:00
smbcli_errstr ( cli - > tree ) ) ;
2005-06-18 04:02:36 +04:00
talloc_free ( cli ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
cnum2 = cli - > tree - > tid ;
cnum3 = MAX ( cnum1 , cnum2 ) + 1 ; /* any invalid number */
vuid2 = cli - > session - > vuid + 1 ;
/* try a write with the wrong tid */
cli - > tree - > tid = cnum2 ;
2004-08-04 17:23:35 +04:00
if ( smbcli_write ( cli - > tree , fnum1 , 0 , buf , 130 , 4 ) = = 4 ) {
2003-08-13 05:53:07 +04:00
printf ( " * server allows write with wrong TID \n " ) ;
ret = False ;
} else {
2004-08-04 17:23:35 +04:00
printf ( " server fails write with wrong TID : %s \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
}
/* try a write with an invalid tid */
cli - > tree - > tid = cnum3 ;
2004-08-04 17:23:35 +04:00
if ( smbcli_write ( cli - > tree , fnum1 , 0 , buf , 130 , 4 ) = = 4 ) {
2003-08-13 05:53:07 +04:00
printf ( " * server allows write with invalid TID \n " ) ;
ret = False ;
} else {
2004-08-04 17:23:35 +04:00
printf ( " server fails write with invalid TID : %s \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
}
/* try a write with an invalid vuid */
cli - > session - > vuid = vuid2 ;
cli - > tree - > tid = cnum1 ;
2004-08-04 17:23:35 +04:00
if ( smbcli_write ( cli - > tree , fnum1 , 0 , buf , 130 , 4 ) = = 4 ) {
2003-08-13 05:53:07 +04:00
printf ( " * server allows write with invalid VUID \n " ) ;
ret = False ;
} else {
2004-08-04 17:23:35 +04:00
printf ( " server fails write with invalid VUID : %s \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
}
cli - > session - > vuid = vuid1 ;
cli - > tree - > tid = cnum1 ;
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli - > tree , fnum1 ) ) ) {
printf ( " close failed (%s) \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
cli - > tree - > tid = cnum2 ;
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_tdis ( cli ) ) ) {
printf ( " secondary tdis failed (%s) \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
cli - > tree = tree1 ; /* restore initial tree */
cli - > tree - > tid = cnum1 ;
2005-07-03 21:35:19 +04:00
smbcli_unlink ( tree1 , fname ) ;
2003-08-13 05:53:07 +04:00
if ( ! torture_close_connection ( cli ) ) {
return False ;
}
return ret ;
}
2004-08-04 17:23:35 +04:00
static BOOL tcon_devtest ( struct smbcli_state * cli ,
2003-08-13 05:53:07 +04:00
const char * myshare , const char * devtype ,
NTSTATUS expected_error )
{
BOOL status ;
BOOL ret ;
2004-06-14 03:50:55 +04:00
const char * password = lp_parm_string ( - 1 , " torture " , " password " ) ;
2003-08-13 05:53:07 +04:00
2005-06-11 07:35:28 +04:00
status = NT_STATUS_IS_OK ( smbcli_tconX ( cli , myshare , devtype ,
2004-02-10 14:33:35 +03:00
password ) ) ;
2003-08-13 05:53:07 +04:00
printf ( " Trying share %s with devtype %s \n " , myshare , devtype ) ;
if ( NT_STATUS_IS_OK ( expected_error ) ) {
if ( status ) {
ret = True ;
} else {
printf ( " tconX to share %s with type %s "
" should have succeeded but failed \n " ,
myshare , devtype ) ;
ret = False ;
}
2004-08-04 17:23:35 +04:00
smbcli_tdis ( cli ) ;
2003-08-13 05:53:07 +04:00
} else {
if ( status ) {
printf ( " tconx to share %s with type %s "
" should have failed but succeeded \n " ,
myshare , devtype ) ;
ret = False ;
} else {
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_EQUAL ( smbcli_nt_error ( cli - > tree ) ,
2003-08-13 05:53:07 +04:00
expected_error ) ) {
ret = True ;
} else {
printf ( " Returned unexpected error \n " ) ;
ret = False ;
}
}
}
return ret ;
}
/*
checks for correct tconX support
*/
2004-10-28 17:40:50 +04:00
static BOOL run_tcon_devtype_test ( void )
2003-08-13 05:53:07 +04:00
{
2004-08-04 17:23:35 +04:00
struct smbcli_state * cli1 = NULL ;
2003-08-13 05:53:07 +04:00
NTSTATUS status ;
BOOL ret = True ;
2004-06-14 03:50:55 +04:00
const char * host = lp_parm_string ( - 1 , " torture " , " host " ) ;
const char * share = lp_parm_string ( - 1 , " torture " , " share " ) ;
2003-08-13 05:53:07 +04:00
2004-09-28 09:44:59 +04:00
status = smbcli_full_connection ( NULL ,
r6028: A MAJOR update to intergrate the new credentails system fully with
GENSEC, and to pull SCHANNEL into GENSEC, by making it less 'special'.
GENSEC now no longer has it's own handling of 'set username' etc,
instead it uses cli_credentials calls.
In order to link the credentails code right though Samba, a lot of
interfaces have changed to remove 'username, domain, password'
arguments, and these have been replaced with a single 'struct
cli_credentials'.
In the session setup code, a new parameter 'workgroup' contains the
client/server current workgroup, which seems unrelated to the
authentication exchange (it was being filled in from the auth info).
This allows in particular kerberos to only call back for passwords
when it actually needs to perform the kinit.
The kerberos code has been modified not to use the SPNEGO provided
'principal name' (in the mechListMIC), but to instead use the name the
host was connected to as. This better matches Microsoft behaviour,
is more secure and allows better use of standard kerberos functions.
To achieve this, I made changes to our socket code so that the
hostname (before name resolution) is now recorded on the socket.
In schannel, most of the code from librpc/rpc/dcerpc_schannel.c is now
in libcli/auth/schannel.c, and it looks much more like a standard
GENSEC module. The actual sign/seal code moved to
libcli/auth/schannel_sign.c in a previous commit.
The schannel credentails structure is now merged with the rest of the
credentails, as many of the values (username, workstation, domain)
where already present there. This makes handling this in a generic
manner much easier, as there is no longer a custom entry-point.
The auth_domain module continues to be developed, but is now just as
functional as auth_winbind. The changes here are consequential to the
schannel changes.
The only removed function at this point is the RPC-LOGIN test
(simulating the load of a WinXP login), which needs much more work to
clean it up (it contains copies of too much code from all over the
torture suite, and I havn't been able to penetrate its 'structure').
Andrew Bartlett
(This used to be commit 2301a4b38a21aa60917973451687063d83d18d66)
2005-03-24 07:14:06 +03:00
& cli1 , host ,
2005-01-15 14:58:52 +03:00
share , NULL ,
2005-06-16 15:36:09 +04:00
cmdline_credentials , NULL ) ;
2003-08-13 05:53:07 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " could not open connection \n " ) ;
return False ;
}
if ( ! tcon_devtest ( cli1 , " IPC$ " , " A: " , NT_STATUS_BAD_DEVICE_TYPE ) )
ret = False ;
if ( ! tcon_devtest ( cli1 , " IPC$ " , " ????? " , NT_STATUS_OK ) )
ret = False ;
if ( ! tcon_devtest ( cli1 , " IPC$ " , " LPT: " , NT_STATUS_BAD_DEVICE_TYPE ) )
ret = False ;
if ( ! tcon_devtest ( cli1 , " IPC$ " , " IPC " , NT_STATUS_OK ) )
ret = False ;
if ( ! tcon_devtest ( cli1 , " IPC$ " , " FOOBA " , NT_STATUS_BAD_DEVICE_TYPE ) )
ret = False ;
if ( ! tcon_devtest ( cli1 , share , " A: " , NT_STATUS_OK ) )
ret = False ;
if ( ! tcon_devtest ( cli1 , share , " ????? " , NT_STATUS_OK ) )
ret = False ;
if ( ! tcon_devtest ( cli1 , share , " LPT: " , NT_STATUS_BAD_DEVICE_TYPE ) )
ret = False ;
if ( ! tcon_devtest ( cli1 , share , " IPC " , NT_STATUS_BAD_DEVICE_TYPE ) )
ret = False ;
if ( ! tcon_devtest ( cli1 , share , " FOOBA " , NT_STATUS_BAD_DEVICE_TYPE ) )
ret = False ;
2005-06-18 04:02:36 +04:00
talloc_free ( cli1 ) ;
2003-08-13 05:53:07 +04:00
if ( ret )
printf ( " Passed tcondevtest \n " ) ;
return ret ;
}
/*
test whether fnums and tids open on one VC are available on another ( a major
security hole )
*/
2004-10-28 17:40:50 +04:00
static BOOL run_fdpasstest ( void )
2003-08-13 05:53:07 +04:00
{
2004-08-04 17:23:35 +04:00
struct smbcli_state * cli1 , * cli2 ;
2003-08-13 05:53:07 +04:00
const char * fname = " \\ fdpass.tst " ;
int fnum1 , oldtid ;
2004-12-04 16:56:25 +03:00
uint8_t buf [ 1024 ] ;
2003-08-13 05:53:07 +04:00
if ( ! torture_open_connection ( & cli1 ) | | ! torture_open_connection ( & cli2 ) ) {
return False ;
}
printf ( " starting fdpasstest \n " ) ;
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
printf ( " Opening a file on connection 1 \n " ) ;
2004-08-04 17:23:35 +04:00
fnum1 = smbcli_open ( cli1 - > tree , fname , O_RDWR | O_CREAT | O_EXCL , DENY_NONE ) ;
2003-08-13 05:53:07 +04:00
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " open of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
printf ( " writing to file on connection 1 \n " ) ;
2004-08-04 17:23:35 +04:00
if ( smbcli_write ( cli1 - > tree , fnum1 , 0 , " hello world \n " , 0 , 13 ) ! = 13 ) {
printf ( " write failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
oldtid = cli2 - > tree - > tid ;
cli2 - > session - > vuid = cli1 - > session - > vuid ;
cli2 - > tree - > tid = cli1 - > tree - > tid ;
cli2 - > session - > pid = cli1 - > session - > pid ;
printf ( " reading from file on connection 2 \n " ) ;
2004-08-04 17:23:35 +04:00
if ( smbcli_read ( cli2 - > tree , fnum1 , buf , 0 , 13 ) = = 13 ) {
2003-08-13 05:53:07 +04:00
printf ( " read succeeded! nasty security hole [%s] \n " ,
buf ) ;
return False ;
}
2004-08-04 17:23:35 +04:00
smbcli_close ( cli1 - > tree , fnum1 ) ;
smbcli_unlink ( cli1 - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
cli2 - > tree - > tid = oldtid ;
torture_close_connection ( cli1 ) ;
torture_close_connection ( cli2 ) ;
printf ( " finished fdpasstest \n " ) ;
return True ;
}
2004-06-08 23:25:26 +04:00
/*
2004-08-03 08:44:27 +04:00
test the timing of deferred open requests
2004-06-08 23:25:26 +04:00
*/
2004-08-04 17:23:35 +04:00
static BOOL run_deferopen ( struct smbcli_state * cli , int dummy )
2004-06-08 23:25:26 +04:00
{
2004-06-14 03:50:55 +04:00
const char * fname = " \\ defer_open_test.dat " ;
2004-06-08 23:25:26 +04:00
int retries = 4 ;
int i = 0 ;
BOOL correct = True ;
if ( retries < = 0 ) {
printf ( " failed to connect \n " ) ;
return False ;
}
printf ( " Testing deferred open requests. \n " ) ;
while ( i < 4 ) {
int fnum = - 1 ;
2004-06-09 04:07:59 +04:00
2004-06-08 23:25:26 +04:00
do {
2004-11-03 13:09:48 +03:00
struct timeval tv ;
tv = timeval_current ( ) ;
2004-11-30 07:33:27 +03:00
fnum = smbcli_nt_create_full ( cli - > tree , fname , 0 ,
2004-12-02 07:37:36 +03:00
SEC_RIGHTS_FILE_ALL ,
2004-11-30 07:33:27 +03:00
FILE_ATTRIBUTE_NORMAL ,
NTCREATEX_SHARE_ACCESS_NONE ,
NTCREATEX_DISP_OPEN_IF , 0 , 0 ) ;
2004-06-08 23:25:26 +04:00
if ( fnum ! = - 1 ) {
break ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_EQUAL ( smbcli_nt_error ( cli - > tree ) , NT_STATUS_SHARING_VIOLATION ) ) {
2004-11-03 13:09:48 +03:00
double e = timeval_elapsed ( & tv ) ;
if ( e < 0.5 | | e > 1.5 ) {
fprintf ( stderr , " Timing incorrect %.2f violation \n " ,
e ) ;
2004-06-09 04:07:59 +04:00
}
}
2004-08-04 17:23:35 +04:00
} while ( NT_STATUS_EQUAL ( smbcli_nt_error ( cli - > tree ) , NT_STATUS_SHARING_VIOLATION ) ) ;
2004-06-08 23:25:26 +04:00
if ( fnum = = - 1 ) {
2004-08-04 17:23:35 +04:00
fprintf ( stderr , " Failed to open %s, error=%s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2004-06-08 23:25:26 +04:00
return False ;
}
printf ( " pid %u open %d \n " , getpid ( ) , i ) ;
sleep ( 10 ) ;
i + + ;
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli - > tree , fnum ) ) ) {
fprintf ( stderr , " Failed to close %s, error=%s \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2004-06-08 23:25:26 +04:00
return False ;
}
sleep ( 2 ) ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_unlink ( cli - > tree , fname ) ) ) {
2004-06-08 23:25:26 +04:00
/* All until the last unlink will fail with sharing violation. */
2004-08-04 17:23:35 +04:00
if ( ! NT_STATUS_EQUAL ( smbcli_nt_error ( cli - > tree ) , NT_STATUS_SHARING_VIOLATION ) ) {
printf ( " unlink of %s failed (%s) \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2004-06-08 23:25:26 +04:00
correct = False ;
}
}
printf ( " deferred test finished \n " ) ;
if ( ! torture_close_connection ( cli ) ) {
correct = False ;
}
return correct ;
}
2003-08-13 05:53:07 +04:00
/*
test how many open files this server supports on the one socket
*/
2004-08-04 17:23:35 +04:00
static BOOL run_maxfidtest ( struct smbcli_state * cli , int dummy )
2003-08-13 05:53:07 +04:00
{
2004-10-19 10:30:52 +04:00
# define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
2003-08-13 05:53:07 +04:00
char * fname ;
int fnums [ 0x11000 ] , i ;
2004-10-19 10:30:52 +04:00
int retries = 4 , maxfid ;
2003-08-13 05:53:07 +04:00
BOOL correct = True ;
if ( retries < = 0 ) {
printf ( " failed to connect \n " ) ;
return False ;
}
2004-10-19 10:30:52 +04:00
if ( smbcli_deltree ( cli - > tree , " \\ maxfid " ) = = - 1 ) {
printf ( " Failed to deltree \\ maxfid - %s \n " ,
smbcli_errstr ( cli - > tree ) ) ;
return False ;
}
if ( NT_STATUS_IS_ERR ( smbcli_mkdir ( cli - > tree , " \\ maxfid " ) ) ) {
printf ( " Failed to mkdir \\ maxfid, error=%s \n " ,
smbcli_errstr ( cli - > tree ) ) ;
return False ;
}
2003-08-13 05:53:07 +04:00
printf ( " Testing maximum number of open files \n " ) ;
for ( i = 0 ; i < 0x11000 ; i + + ) {
2004-10-19 10:30:52 +04:00
if ( i % 1000 = = 0 ) {
asprintf ( & fname , " \\ maxfid \\ fid%d " , i / 1000 ) ;
if ( NT_STATUS_IS_ERR ( smbcli_mkdir ( cli - > tree , fname ) ) ) {
printf ( " Failed to mkdir %s, error=%s \n " ,
fname , smbcli_errstr ( cli - > tree ) ) ;
return False ;
}
free ( fname ) ;
}
asprintf ( & fname , MAXFID_TEMPLATE , i / 1000 , i , ( int ) getpid ( ) ) ;
2004-08-04 17:23:35 +04:00
if ( ( fnums [ i ] = smbcli_open ( cli - > tree , fname ,
2003-08-13 05:53:07 +04:00
O_RDWR | O_CREAT | O_TRUNC , DENY_NONE ) ) = =
- 1 ) {
printf ( " open of %s failed (%s) \n " ,
2004-08-04 17:23:35 +04:00
fname , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
printf ( " maximum fnum is %d \n " , i ) ;
break ;
}
free ( fname ) ;
printf ( " %6d \r " , i ) ;
}
printf ( " %6d \n " , i ) ;
i - - ;
2004-10-19 10:30:52 +04:00
maxfid = i ;
2003-08-13 05:53:07 +04:00
printf ( " cleaning up \n " ) ;
2004-10-19 10:30:52 +04:00
for ( i = 0 ; i < maxfid / 2 ; i + + ) {
asprintf ( & fname , MAXFID_TEMPLATE , i / 1000 , i , ( int ) getpid ( ) ) ;
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli - > tree , fnums [ i ] ) ) ) {
printf ( " Close of fnum %d failed - %s \n " , fnums [ i ] , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_unlink ( cli - > tree , fname ) ) ) {
2003-08-13 05:53:07 +04:00
printf ( " unlink of %s failed (%s) \n " ,
2004-08-04 17:23:35 +04:00
fname , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
}
free ( fname ) ;
2004-10-19 10:30:52 +04:00
asprintf ( & fname , MAXFID_TEMPLATE , ( maxfid - i ) / 1000 , maxfid - i , ( int ) getpid ( ) ) ;
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli - > tree , fnums [ maxfid - i ] ) ) ) {
printf ( " Close of fnum %d failed - %s \n " , fnums [ maxfid - i ] , smbcli_errstr ( cli - > tree ) ) ;
}
if ( NT_STATUS_IS_ERR ( smbcli_unlink ( cli - > tree , fname ) ) ) {
printf ( " unlink of %s failed (%s) \n " ,
fname , smbcli_errstr ( cli - > tree ) ) ;
correct = False ;
}
free ( fname ) ;
printf ( " %6d %6d \r " , i , maxfid - i ) ;
2003-08-13 05:53:07 +04:00
}
printf ( " %6d \n " , 0 ) ;
2004-10-19 10:30:52 +04:00
if ( smbcli_deltree ( cli - > tree , " \\ maxfid " ) = = - 1 ) {
printf ( " Failed to deltree \\ maxfid - %s \n " ,
smbcli_errstr ( cli - > tree ) ) ;
return False ;
}
2003-08-13 05:53:07 +04:00
printf ( " maxfid test finished \n " ) ;
if ( ! torture_close_connection ( cli ) ) {
correct = False ;
}
return correct ;
2004-08-25 11:30:58 +04:00
# undef MAXFID_TEMPLATE
2003-08-13 05:53:07 +04:00
}
/* send smb negprot commands, not reading the response */
2004-10-28 17:40:50 +04:00
static BOOL run_negprot_nowait ( void )
2003-08-13 05:53:07 +04:00
{
int i ;
2004-08-04 17:23:35 +04:00
struct smbcli_state * cli , * cli2 ;
2003-08-13 05:53:07 +04:00
BOOL correct = True ;
printf ( " starting negprot nowait test \n " ) ;
cli = open_nbt_connection ( ) ;
if ( ! cli ) {
return False ;
}
2004-08-03 12:04:51 +04:00
printf ( " Filling send buffer \n " ) ;
2003-08-13 05:53:07 +04:00
2005-11-11 04:38:39 +03:00
for ( i = 0 ; i < 1000 ; i + + ) {
2004-08-04 17:23:35 +04:00
struct smbcli_request * req ;
2005-01-15 14:58:52 +03:00
req = smb_raw_negotiate_send ( cli - > transport , PROTOCOL_NT1 ) ;
2005-11-11 04:38:39 +03:00
smbcli_transport_process ( cli - > transport ) ;
2004-08-04 17:23:35 +04:00
if ( req - > state = = SMBCLI_REQUEST_ERROR ) {
2004-08-03 12:04:51 +04:00
printf ( " Failed to fill pipe - %s \n " , nt_errstr ( req - > status ) ) ;
torture_close_connection ( cli ) ;
return correct ;
}
}
printf ( " Opening secondary connection \n " ) ;
if ( ! torture_open_connection ( & cli2 ) ) {
return False ;
2003-08-13 05:53:07 +04:00
}
if ( ! torture_close_connection ( cli ) ) {
correct = False ;
}
2004-08-03 12:04:51 +04:00
if ( ! torture_close_connection ( cli2 ) ) {
correct = False ;
}
2003-08-13 05:53:07 +04:00
printf ( " finished negprot nowait test \n " ) ;
return correct ;
}
/*
This checks how the getatr calls works
*/
2004-10-28 17:40:50 +04:00
static BOOL run_attrtest ( void )
2003-08-13 05:53:07 +04:00
{
2004-08-04 17:23:35 +04:00
struct smbcli_state * cli ;
2003-08-13 05:53:07 +04:00
int fnum ;
time_t t , t2 ;
const char * fname = " \\ attrib123456789.tst " ;
BOOL correct = True ;
printf ( " starting attrib test \n " ) ;
if ( ! torture_open_connection ( & cli ) ) {
return False ;
}
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli - > tree , fname ) ;
fnum = smbcli_open ( cli - > tree , fname ,
2003-08-13 05:53:07 +04:00
O_RDWR | O_CREAT | O_TRUNC , DENY_NONE ) ;
2004-08-04 17:23:35 +04:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 05:53:07 +04:00
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_getatr ( cli - > tree , fname , NULL , NULL , & t ) ) ) {
printf ( " getatr failed (%s) \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
}
printf ( " New file time is %s " , ctime ( & t ) ) ;
if ( abs ( t - time ( NULL ) ) > 60 * 60 * 24 * 10 ) {
printf ( " ERROR: SMBgetatr bug. time is %s " ,
ctime ( & t ) ) ;
t = time ( NULL ) ;
correct = False ;
}
t2 = t - 60 * 60 * 24 ; /* 1 day ago */
printf ( " Setting file time to %s " , ctime ( & t2 ) ) ;
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_setatr ( cli - > tree , fname , 0 , t2 ) ) ) {
printf ( " setatr failed (%s) \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = True ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_getatr ( cli - > tree , fname , NULL , NULL , & t ) ) ) {
printf ( " getatr failed (%s) \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = True ;
}
printf ( " Retrieved file time as %s " , ctime ( & t ) ) ;
if ( t ! = t2 ) {
printf ( " ERROR: getatr/setatr bug. times are \n %s " ,
ctime ( & t ) ) ;
printf ( " %s " , ctime ( & t2 ) ) ;
correct = True ;
}
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
if ( ! torture_close_connection ( cli ) ) {
correct = False ;
}
printf ( " attrib test finished \n " ) ;
return correct ;
}
/*
This checks a couple of trans2 calls
*/
2004-10-28 17:40:50 +04:00
static BOOL run_trans2test ( void )
2003-08-13 05:53:07 +04:00
{
2004-08-04 17:23:35 +04:00
struct smbcli_state * cli ;
2003-08-13 05:53:07 +04:00
int fnum ;
size_t size ;
time_t c_time , a_time , m_time , w_time , m_time2 ;
const char * fname = " \\ trans2.tst " ;
const char * dname = " \\ trans2 " ;
const char * fname2 = " \\ trans2 \\ trans2.tst " ;
const char * pname ;
BOOL correct = True ;
printf ( " starting trans2 test \n " ) ;
if ( ! torture_open_connection ( & cli ) ) {
return False ;
}
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
printf ( " Testing qfileinfo \n " ) ;
2004-08-04 17:23:35 +04:00
fnum = smbcli_open ( cli - > tree , fname ,
2003-08-13 05:53:07 +04:00
O_RDWR | O_CREAT | O_TRUNC , DENY_NONE ) ;
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_qfileinfo ( cli - > tree , fnum , NULL , & size , & c_time , & a_time , & m_time ,
2004-02-10 14:33:35 +03:00
NULL , NULL ) ) ) {
2004-08-04 17:23:35 +04:00
printf ( " ERROR: qfileinfo failed (%s) \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
}
printf ( " Testing NAME_INFO \n " ) ;
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_qfilename ( cli - > tree , fnum , & pname ) ) ) {
printf ( " ERROR: qfilename failed (%s) \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
}
if ( ! pname | | strcmp ( pname , fname ) ) {
printf ( " qfilename gave different name? [%s] [%s] \n " ,
fname , pname ) ;
correct = False ;
}
2004-08-04 17:23:35 +04:00
smbcli_close ( cli - > tree , fnum ) ;
smbcli_unlink ( cli - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
2004-08-04 17:23:35 +04:00
fnum = smbcli_open ( cli - > tree , fname ,
2003-08-13 05:53:07 +04:00
O_RDWR | O_CREAT | O_TRUNC , DENY_NONE ) ;
if ( fnum = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " open of %s failed (%s) \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
2004-08-04 17:23:35 +04:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 05:53:07 +04:00
printf ( " Checking for sticky create times \n " ) ;
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_qpathinfo ( cli - > tree , fname , & c_time , & a_time , & m_time , & size , NULL ) ) ) {
printf ( " ERROR: qpathinfo failed (%s) \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
} else {
if ( c_time ! = m_time ) {
printf ( " create time=%s " , ctime ( & c_time ) ) ;
printf ( " modify time=%s " , ctime ( & m_time ) ) ;
printf ( " This system appears to have sticky create times \n " ) ;
}
if ( a_time % ( 60 * 60 ) = = 0 ) {
printf ( " access time=%s " , ctime ( & a_time ) ) ;
printf ( " This system appears to set a midnight access time \n " ) ;
correct = False ;
}
if ( abs ( m_time - time ( NULL ) ) > 60 * 60 * 24 * 7 ) {
printf ( " ERROR: totally incorrect times - maybe word reversed? mtime=%s " , ctime ( & m_time ) ) ;
correct = False ;
}
}
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli - > tree , fname ) ;
fnum = smbcli_open ( cli - > tree , fname ,
2003-08-13 05:53:07 +04:00
O_RDWR | O_CREAT | O_TRUNC , DENY_NONE ) ;
2004-08-04 17:23:35 +04:00
smbcli_close ( cli - > tree , fnum ) ;
if ( NT_STATUS_IS_ERR ( smbcli_qpathinfo2 ( cli - > tree , fname , & c_time , & a_time , & m_time , & w_time , & size , NULL , NULL ) ) ) {
printf ( " ERROR: qpathinfo2 failed (%s) \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
} else {
if ( w_time < 60 * 60 * 24 * 2 ) {
printf ( " write time=%s " , ctime ( & w_time ) ) ;
printf ( " This system appears to set a initial 0 write time \n " ) ;
correct = False ;
}
}
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
/* check if the server updates the directory modification time
when creating a new file */
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_mkdir ( cli - > tree , dname ) ) ) {
printf ( " ERROR: mkdir failed (%s) \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
}
sleep ( 3 ) ;
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_qpathinfo2 ( cli - > tree , " \\ trans2 \\ " , & c_time , & a_time , & m_time , & w_time , & size , NULL , NULL ) ) ) {
printf ( " ERROR: qpathinfo2 failed (%s) \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
}
2004-08-04 17:23:35 +04:00
fnum = smbcli_open ( cli - > tree , fname2 ,
2003-08-13 05:53:07 +04:00
O_RDWR | O_CREAT | O_TRUNC , DENY_NONE ) ;
2004-12-04 16:56:25 +03:00
smbcli_write ( cli - > tree , fnum , 0 , & fnum , 0 , sizeof ( fnum ) ) ;
2004-08-04 17:23:35 +04:00
smbcli_close ( cli - > tree , fnum ) ;
if ( NT_STATUS_IS_ERR ( smbcli_qpathinfo2 ( cli - > tree , " \\ trans2 \\ " , & c_time , & a_time , & m_time2 , & w_time , & size , NULL , NULL ) ) ) {
printf ( " ERROR: qpathinfo2 failed (%s) \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
} else {
if ( m_time2 = = m_time ) {
printf ( " This system does not update directory modification times \n " ) ;
correct = False ;
}
}
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli - > tree , fname2 ) ;
smbcli_rmdir ( cli - > tree , dname ) ;
2003-08-13 05:53:07 +04:00
if ( ! torture_close_connection ( cli ) ) {
correct = False ;
}
printf ( " trans2 test finished \n " ) ;
return correct ;
}
/* FIRST_DESIRED_ACCESS 0xf019f */
2004-11-30 07:33:27 +03:00
# define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
SEC_FILE_READ_EA | /* 0xf */ \
SEC_FILE_WRITE_EA | SEC_FILE_READ_ATTRIBUTE | /* 0x90 */ \
SEC_FILE_WRITE_ATTRIBUTE | /* 0x100 */ \
SEC_STD_DELETE | SEC_STD_READ_CONTROL | \
SEC_STD_WRITE_DAC | SEC_STD_WRITE_OWNER /* 0xf0000 */
2003-08-13 05:53:07 +04:00
/* SECOND_DESIRED_ACCESS 0xe0080 */
2004-11-30 07:33:27 +03:00
# define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
SEC_STD_READ_CONTROL | SEC_STD_WRITE_DAC | \
SEC_STD_WRITE_OWNER /* 0xe0000 */
2003-08-13 05:53:07 +04:00
#if 0
2004-11-30 07:33:27 +03:00
# define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
READ_CONTROL | WRITE_DAC | \
SEC_FILE_READ_DATA | \
WRITE_OWNER /* */
2003-08-13 05:53:07 +04:00
# endif
/*
Test ntcreate calls made by xcopy
*/
2004-10-28 17:40:50 +04:00
static BOOL run_xcopy ( void )
2003-08-13 05:53:07 +04:00
{
2004-08-04 17:23:35 +04:00
struct smbcli_state * cli1 ;
2003-08-13 05:53:07 +04:00
const char * fname = " \\ test.txt " ;
BOOL correct = True ;
int fnum1 , fnum2 ;
printf ( " starting xcopy test \n " ) ;
if ( ! torture_open_connection ( & cli1 ) ) {
return False ;
}
2004-08-04 17:23:35 +04:00
fnum1 = smbcli_nt_create_full ( cli1 - > tree , fname , 0 ,
2004-11-30 07:33:27 +03:00
FIRST_DESIRED_ACCESS ,
FILE_ATTRIBUTE_ARCHIVE ,
NTCREATEX_SHARE_ACCESS_NONE ,
NTCREATEX_DISP_OVERWRITE_IF ,
0x4044 , 0 ) ;
2003-08-13 05:53:07 +04:00
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " First open failed - %s \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
2004-08-04 17:23:35 +04:00
fnum2 = smbcli_nt_create_full ( cli1 - > tree , fname , 0 ,
2003-08-13 05:53:07 +04:00
SECOND_DESIRED_ACCESS , 0 ,
NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE | NTCREATEX_SHARE_ACCESS_DELETE , NTCREATEX_DISP_OPEN ,
0x200000 , 0 ) ;
if ( fnum2 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " second open failed - %s \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
if ( ! torture_close_connection ( cli1 ) ) {
correct = False ;
}
return correct ;
}
2004-08-03 08:44:27 +04:00
/*
see how many RPC pipes we can open at once
*/
2004-10-28 17:40:50 +04:00
static BOOL run_pipe_number ( void )
2003-08-13 05:53:07 +04:00
{
2004-08-04 17:23:35 +04:00
struct smbcli_state * cli1 ;
2003-11-18 08:01:10 +03:00
const char * pipe_name = " \\ WKSSVC " ;
2003-08-13 05:53:07 +04:00
int fnum ;
int num_pipes = 0 ;
printf ( " starting pipenumber test \n " ) ;
if ( ! torture_open_connection ( & cli1 ) ) {
return False ;
}
while ( 1 ) {
2004-11-30 07:33:27 +03:00
fnum = smbcli_nt_create_full ( cli1 - > tree , pipe_name , 0 , SEC_FILE_READ_DATA , FILE_ATTRIBUTE_NORMAL ,
2003-08-13 05:53:07 +04:00
NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE , NTCREATEX_DISP_OPEN_IF , 0 , 0 ) ;
if ( fnum = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " Open of pipe %s failed with error (%s) \n " , pipe_name , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
break ;
}
num_pipes + + ;
2004-08-03 08:44:27 +04:00
printf ( " %d \r " , num_pipes ) ;
fflush ( stdout ) ;
2003-08-13 05:53:07 +04:00
}
printf ( " pipe_number test - we can open %d %s pipes. \n " , num_pipes , pipe_name ) ;
torture_close_connection ( cli1 ) ;
return True ;
}
2004-02-21 07:02:55 +03:00
/*
open N connections to the server and just hold them open
used for testing performance when there are N idle users
already connected
*/
2004-10-28 17:40:50 +04:00
static BOOL torture_holdcon ( void )
2004-02-21 07:02:55 +03:00
{
int i ;
2004-08-04 17:23:35 +04:00
struct smbcli_state * * cli ;
2004-02-21 07:02:55 +03:00
int num_dead = 0 ;
printf ( " Opening %d connections \n " , torture_numops ) ;
2004-12-03 09:24:38 +03:00
cli = malloc_array_p ( struct smbcli_state * , torture_numops ) ;
2004-02-21 07:02:55 +03:00
for ( i = 0 ; i < torture_numops ; i + + ) {
if ( ! torture_open_connection ( & cli [ i ] ) ) {
return False ;
}
printf ( " opened %d connections \r " , i ) ;
fflush ( stdout ) ;
}
printf ( " \n Starting pings \n " ) ;
while ( 1 ) {
for ( i = 0 ; i < torture_numops ; i + + ) {
NTSTATUS status ;
if ( cli [ i ] ) {
2004-08-04 17:23:35 +04:00
status = smbcli_chkpath ( cli [ i ] - > tree , " \\ " ) ;
2004-02-21 07:02:55 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
printf ( " Connection %d is dead \n " , i ) ;
cli [ i ] = NULL ;
num_dead + + ;
}
usleep ( 100 ) ;
}
}
if ( num_dead = = torture_numops ) {
printf ( " All connections dead - finishing \n " ) ;
break ;
}
printf ( " . " ) ;
fflush ( stdout ) ;
}
return True ;
}
2004-04-28 16:45:16 +04:00
/*
Try with a wrong vuid and check error message .
*/
2004-10-28 17:40:50 +04:00
static BOOL run_vuidtest ( void )
2004-04-28 16:45:16 +04:00
{
2004-08-04 17:23:35 +04:00
struct smbcli_state * cli ;
2004-04-28 16:45:16 +04:00
const char * fname = " \\ vuid.tst " ;
int fnum ;
size_t size ;
2004-06-06 11:14:10 +04:00
time_t c_time , a_time , m_time ;
2004-04-28 16:45:16 +04:00
BOOL correct = True ;
2004-05-25 21:24:24 +04:00
uint16_t orig_vuid ;
2004-04-28 16:45:16 +04:00
NTSTATUS result ;
printf ( " starting vuid test \n " ) ;
if ( ! torture_open_connection ( & cli ) ) {
return False ;
}
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli - > tree , fname ) ;
2004-04-28 16:45:16 +04:00
2004-08-04 17:23:35 +04:00
fnum = smbcli_open ( cli - > tree , fname ,
2004-04-28 16:45:16 +04:00
O_RDWR | O_CREAT | O_TRUNC , DENY_NONE ) ;
orig_vuid = cli - > session - > vuid ;
cli - > session - > vuid + = 1234 ;
2004-02-21 07:02:55 +03:00
2004-04-28 16:45:16 +04:00
printf ( " Testing qfileinfo with wrong vuid \n " ) ;
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_OK ( result = smbcli_qfileinfo ( cli - > tree , fnum , NULL ,
2004-04-28 16:45:16 +04:00
& size , & c_time , & a_time ,
& m_time , NULL , NULL ) ) ) {
printf ( " ERROR: qfileinfo passed with wrong vuid \n " ) ;
correct = False ;
}
2005-07-04 05:23:38 +04:00
if ( ! NT_STATUS_EQUAL ( cli - > transport - > error . e . nt_status ,
2005-07-04 09:16:57 +04:00
NT_STATUS_DOS ( ERRSRV , ERRbaduid ) ) & &
! NT_STATUS_EQUAL ( cli - > transport - > error . e . nt_status ,
NT_STATUS_INVALID_HANDLE ) ) {
2004-04-28 16:45:16 +04:00
printf ( " ERROR: qfileinfo should have returned DOS error "
" ERRSRV:ERRbaduid \n but returned %s \n " ,
2004-08-04 17:23:35 +04:00
smbcli_errstr ( cli - > tree ) ) ;
2004-04-28 16:45:16 +04:00
correct = False ;
}
cli - > session - > vuid - = 1234 ;
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli - > tree , fnum ) ) ) {
printf ( " close failed (%s) \n " , smbcli_errstr ( cli - > tree ) ) ;
2004-04-28 16:45:16 +04:00
correct = False ;
}
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli - > tree , fname ) ;
2004-04-28 16:45:16 +04:00
if ( ! torture_close_connection ( cli ) ) {
correct = False ;
}
printf ( " vuid test finished \n " ) ;
return correct ;
}
2004-02-21 07:02:55 +03:00
2003-08-13 05:53:07 +04:00
/*
Test open mode returns on read - only files .
*/
2004-10-28 17:40:50 +04:00
static BOOL run_opentest ( void )
2003-08-13 05:53:07 +04:00
{
2004-08-04 17:23:35 +04:00
static struct smbcli_state * cli1 ;
static struct smbcli_state * cli2 ;
2003-08-13 05:53:07 +04:00
const char * fname = " \\ readonly.file " ;
2005-05-25 23:16:18 +04:00
char * control_char_fname ;
2003-08-13 05:53:07 +04:00
int fnum1 , fnum2 ;
2004-12-04 16:56:25 +03:00
uint8_t buf [ 20 ] ;
2003-08-13 05:53:07 +04:00
size_t fsize ;
BOOL correct = True ;
char * tmp_path ;
int failures = 0 ;
2005-05-25 23:16:18 +04:00
int i ;
2003-08-13 05:53:07 +04:00
printf ( " starting open test \n " ) ;
if ( ! torture_open_connection ( & cli1 ) ) {
return False ;
}
2005-05-25 23:16:18 +04:00
asprintf ( & control_char_fname , " \\ readonly.afile " ) ;
for ( i = 1 ; i < = 0x1f ; i + + ) {
control_char_fname [ 10 ] = i ;
fnum1 = smbcli_nt_create_full ( cli1 - > tree , control_char_fname , 0 , SEC_FILE_WRITE_DATA , FILE_ATTRIBUTE_NORMAL ,
NTCREATEX_SHARE_ACCESS_NONE , NTCREATEX_DISP_OVERWRITE_IF , 0 , 0 ) ;
if ( ! check_error ( __location__ , cli1 , ERRDOS , ERRinvalidname ,
NT_STATUS_OBJECT_NAME_INVALID ) ) {
printf ( " Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char \n " ,
smbcli_errstr ( cli1 - > tree ) , i ) ;
failures + + ;
}
if ( fnum1 ! = - 1 ) {
smbcli_close ( cli1 - > tree , fnum1 ) ;
}
smbcli_setatr ( cli1 - > tree , control_char_fname , 0 , 0 ) ;
smbcli_unlink ( cli1 - > tree , control_char_fname ) ;
}
free ( control_char_fname ) ;
if ( ! failures )
printf ( " Create file with control char names passed. \n " ) ;
2004-08-04 17:23:35 +04:00
smbcli_setatr ( cli1 - > tree , fname , 0 , 0 ) ;
smbcli_unlink ( cli1 - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
2004-08-04 17:23:35 +04:00
fnum1 = smbcli_open ( cli1 - > tree , fname , O_RDWR | O_CREAT | O_EXCL , DENY_NONE ) ;
2003-08-13 05:53:07 +04:00
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " open of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli1 - > tree , fnum1 ) ) ) {
printf ( " close2 failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_setatr ( cli1 - > tree , fname , FILE_ATTRIBUTE_READONLY , 0 ) ) ) {
printf ( " smbcli_setatr failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test1 ) ;
return False ;
}
2004-08-04 17:23:35 +04:00
fnum1 = smbcli_open ( cli1 - > tree , fname , O_RDONLY , DENY_WRITE ) ;
2003-08-13 05:53:07 +04:00
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " open of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test1 ) ;
return False ;
}
/* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
2004-08-04 17:23:35 +04:00
fnum2 = smbcli_open ( cli1 - > tree , fname , O_RDWR , DENY_ALL ) ;
2003-08-13 05:53:07 +04:00
2004-10-17 06:52:37 +04:00
if ( check_error ( __location__ , cli1 , ERRDOS , ERRnoaccess ,
2003-08-13 05:53:07 +04:00
NT_STATUS_ACCESS_DENIED ) ) {
printf ( " correct error code ERRDOS/ERRnoaccess returned \n " ) ;
}
printf ( " finished open test 1 \n " ) ;
error_test1 :
2004-08-04 17:23:35 +04:00
smbcli_close ( cli1 - > tree , fnum1 ) ;
2003-08-13 05:53:07 +04:00
/* Now try not readonly and ensure ERRbadshare is returned. */
2004-08-04 17:23:35 +04:00
smbcli_setatr ( cli1 - > tree , fname , 0 , 0 ) ;
2003-08-13 05:53:07 +04:00
2004-08-04 17:23:35 +04:00
fnum1 = smbcli_open ( cli1 - > tree , fname , O_RDONLY , DENY_WRITE ) ;
2003-08-13 05:53:07 +04:00
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " open of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
/* This will fail - but the error should be ERRshare. */
2004-08-04 17:23:35 +04:00
fnum2 = smbcli_open ( cli1 - > tree , fname , O_RDWR , DENY_ALL ) ;
2003-08-13 05:53:07 +04:00
2004-10-17 06:52:37 +04:00
if ( check_error ( __location__ , cli1 , ERRDOS , ERRbadshare ,
2003-08-13 05:53:07 +04:00
NT_STATUS_SHARING_VIOLATION ) ) {
printf ( " correct error code ERRDOS/ERRbadshare returned \n " ) ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli1 - > tree , fnum1 ) ) ) {
printf ( " close2 failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
printf ( " finished open test 2 \n " ) ;
/* Test truncate open disposition on file opened for read. */
2004-08-04 17:23:35 +04:00
fnum1 = smbcli_open ( cli1 - > tree , fname , O_RDWR | O_CREAT | O_EXCL , DENY_NONE ) ;
2003-08-13 05:53:07 +04:00
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " (3) open (1) of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
/* write 20 bytes. */
memset ( buf , ' \0 ' , 20 ) ;
2004-08-04 17:23:35 +04:00
if ( smbcli_write ( cli1 - > tree , fnum1 , 0 , buf , 0 , 20 ) ! = 20 ) {
printf ( " write failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
correct = False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli1 - > tree , fnum1 ) ) ) {
printf ( " (3) close1 failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
/* Ensure size == 20. */
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_getatr ( cli1 - > tree , fname , NULL , & fsize , NULL ) ) ) {
printf ( " (3) getatr failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test3 ) ;
return False ;
}
if ( fsize ! = 20 ) {
printf ( " (3) file size != 20 \n " ) ;
CHECK_MAX_FAILURES ( error_test3 ) ;
return False ;
}
/* Now test if we can truncate a file opened for readonly. */
2004-08-04 17:23:35 +04:00
fnum1 = smbcli_open ( cli1 - > tree , fname , O_RDONLY | O_TRUNC , DENY_NONE ) ;
2003-08-13 05:53:07 +04:00
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " (3) open (2) of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test3 ) ;
return False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli1 - > tree , fnum1 ) ) ) {
printf ( " close2 failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
/* Ensure size == 0. */
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_getatr ( cli1 - > tree , fname , NULL , & fsize , NULL ) ) ) {
printf ( " (3) getatr failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test3 ) ;
return False ;
}
if ( fsize ! = 0 ) {
printf ( " (3) file size != 0 \n " ) ;
CHECK_MAX_FAILURES ( error_test3 ) ;
return False ;
}
printf ( " finished open test 3 \n " ) ;
error_test3 :
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
printf ( " testing ctemp \n " ) ;
2004-08-04 17:23:35 +04:00
fnum1 = smbcli_ctemp ( cli1 - > tree , " \\ " , & tmp_path ) ;
2003-08-13 05:53:07 +04:00
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " ctemp failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test4 ) ;
return False ;
}
printf ( " ctemp gave path %s \n " , tmp_path ) ;
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli1 - > tree , fnum1 ) ) ) {
printf ( " close of temp failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_unlink ( cli1 - > tree , tmp_path ) ) ) {
printf ( " unlink of temp failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
}
error_test4 :
/* Test the non-io opens... */
if ( ! torture_open_connection ( & cli2 ) ) {
return False ;
}
2004-08-04 17:23:35 +04:00
smbcli_setatr ( cli2 - > tree , fname , 0 , 0 ) ;
smbcli_unlink ( cli2 - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
printf ( " TEST #1 testing 2 non-io opens (no delete) \n " ) ;
2004-11-30 07:33:27 +03:00
fnum1 = smbcli_nt_create_full ( cli1 - > tree , fname , 0 , SEC_FILE_READ_ATTRIBUTE , FILE_ATTRIBUTE_NORMAL ,
2003-08-13 05:53:07 +04:00
NTCREATEX_SHARE_ACCESS_NONE , NTCREATEX_DISP_OVERWRITE_IF , 0 , 0 ) ;
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " test 1 open 1 of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test10 ) ;
return False ;
}
2004-11-30 07:33:27 +03:00
fnum2 = smbcli_nt_create_full ( cli2 - > tree , fname , 0 , SEC_FILE_READ_ATTRIBUTE , FILE_ATTRIBUTE_NORMAL ,
2003-08-13 05:53:07 +04:00
NTCREATEX_SHARE_ACCESS_NONE , NTCREATEX_DISP_OPEN_IF , 0 , 0 ) ;
if ( fnum2 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " test 1 open 2 of %s failed (%s) \n " , fname , smbcli_errstr ( cli2 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test10 ) ;
return False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli1 - > tree , fnum1 ) ) ) {
printf ( " test 1 close 1 of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli2 - > tree , fnum2 ) ) ) {
printf ( " test 1 close 2 of %s failed (%s) \n " , fname , smbcli_errstr ( cli2 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
printf ( " non-io open test #1 passed. \n " ) ;
error_test10 :
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
printf ( " TEST #2 testing 2 non-io opens (first with delete) \n " ) ;
2004-11-30 07:33:27 +03:00
fnum1 = smbcli_nt_create_full ( cli1 - > tree , fname , 0 , SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE , FILE_ATTRIBUTE_NORMAL ,
2003-08-13 05:53:07 +04:00
NTCREATEX_SHARE_ACCESS_NONE , NTCREATEX_DISP_OVERWRITE_IF , 0 , 0 ) ;
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " test 2 open 1 of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test20 ) ;
return False ;
}
2004-11-30 07:33:27 +03:00
fnum2 = smbcli_nt_create_full ( cli2 - > tree , fname , 0 , SEC_FILE_READ_ATTRIBUTE , FILE_ATTRIBUTE_NORMAL ,
2003-08-13 05:53:07 +04:00
NTCREATEX_SHARE_ACCESS_NONE , NTCREATEX_DISP_OPEN_IF , 0 , 0 ) ;
if ( fnum2 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " test 2 open 2 of %s failed (%s) \n " , fname , smbcli_errstr ( cli2 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test20 ) ;
return False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli1 - > tree , fnum1 ) ) ) {
printf ( " test 1 close 1 of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli2 - > tree , fnum2 ) ) ) {
printf ( " test 1 close 2 of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
printf ( " non-io open test #2 passed. \n " ) ;
error_test20 :
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
printf ( " TEST #3 testing 2 non-io opens (second with delete) \n " ) ;
2004-11-30 07:33:27 +03:00
fnum1 = smbcli_nt_create_full ( cli1 - > tree , fname , 0 , SEC_FILE_READ_ATTRIBUTE , FILE_ATTRIBUTE_NORMAL ,
2003-08-13 05:53:07 +04:00
NTCREATEX_SHARE_ACCESS_NONE , NTCREATEX_DISP_OVERWRITE_IF , 0 , 0 ) ;
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " test 3 open 1 of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test30 ) ;
return False ;
}
2004-11-30 07:33:27 +03:00
fnum2 = smbcli_nt_create_full ( cli2 - > tree , fname , 0 , SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE , FILE_ATTRIBUTE_NORMAL ,
2003-08-13 05:53:07 +04:00
NTCREATEX_SHARE_ACCESS_NONE , NTCREATEX_DISP_OPEN_IF , 0 , 0 ) ;
if ( fnum2 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " test 3 open 2 of %s failed (%s) \n " , fname , smbcli_errstr ( cli2 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test30 ) ;
return False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli1 - > tree , fnum1 ) ) ) {
printf ( " test 3 close 1 of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli2 - > tree , fnum2 ) ) ) {
printf ( " test 3 close 2 of %s failed (%s) \n " , fname , smbcli_errstr ( cli2 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
printf ( " non-io open test #3 passed. \n " ) ;
error_test30 :
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
printf ( " TEST #4 testing 2 non-io opens (both with delete) \n " ) ;
2004-11-30 07:33:27 +03:00
fnum1 = smbcli_nt_create_full ( cli1 - > tree , fname , 0 , SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE , FILE_ATTRIBUTE_NORMAL ,
2003-08-13 05:53:07 +04:00
NTCREATEX_SHARE_ACCESS_NONE , NTCREATEX_DISP_OVERWRITE_IF , 0 , 0 ) ;
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " test 4 open 1 of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test40 ) ;
return False ;
}
2004-11-30 07:33:27 +03:00
fnum2 = smbcli_nt_create_full ( cli2 - > tree , fname , 0 , SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE , FILE_ATTRIBUTE_NORMAL ,
2003-08-13 05:53:07 +04:00
NTCREATEX_SHARE_ACCESS_NONE , NTCREATEX_DISP_OPEN_IF , 0 , 0 ) ;
if ( fnum2 ! = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " test 4 open 2 of %s SUCCEEDED - should have failed (%s) \n " , fname , smbcli_errstr ( cli2 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test40 ) ;
return False ;
}
2004-08-04 17:23:35 +04:00
printf ( " test 4 open 2 of %s gave %s (correct error should be %s) \n " , fname , smbcli_errstr ( cli2 - > tree ) , " sharing violation " ) ;
2003-08-13 05:53:07 +04:00
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli1 - > tree , fnum1 ) ) ) {
printf ( " test 4 close 1 of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
printf ( " non-io open test #4 passed. \n " ) ;
error_test40 :
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
printf ( " TEST #5 testing 2 non-io opens (both with delete - both with file share delete) \n " ) ;
2004-11-30 07:33:27 +03:00
fnum1 = smbcli_nt_create_full ( cli1 - > tree , fname , 0 , SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE , FILE_ATTRIBUTE_NORMAL ,
2003-08-13 05:53:07 +04:00
NTCREATEX_SHARE_ACCESS_DELETE , NTCREATEX_DISP_OVERWRITE_IF , 0 , 0 ) ;
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " test 5 open 1 of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test50 ) ;
return False ;
}
2004-11-30 07:33:27 +03:00
fnum2 = smbcli_nt_create_full ( cli2 - > tree , fname , 0 , SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE , FILE_ATTRIBUTE_NORMAL ,
2003-08-13 05:53:07 +04:00
NTCREATEX_SHARE_ACCESS_DELETE , NTCREATEX_DISP_OPEN_IF , 0 , 0 ) ;
if ( fnum2 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " test 5 open 2 of %s failed (%s) \n " , fname , smbcli_errstr ( cli2 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test50 ) ;
return False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli1 - > tree , fnum1 ) ) ) {
printf ( " test 5 close 1 of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli2 - > tree , fnum2 ) ) ) {
printf ( " test 5 close 2 of %s failed (%s) \n " , fname , smbcli_errstr ( cli2 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
printf ( " non-io open test #5 passed. \n " ) ;
error_test50 :
printf ( " TEST #6 testing 1 non-io open, one io open \n " ) ;
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
2004-11-30 07:33:27 +03:00
fnum1 = smbcli_nt_create_full ( cli1 - > tree , fname , 0 , SEC_FILE_READ_DATA , FILE_ATTRIBUTE_NORMAL ,
2003-08-13 05:53:07 +04:00
NTCREATEX_SHARE_ACCESS_NONE , NTCREATEX_DISP_OVERWRITE_IF , 0 , 0 ) ;
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " test 6 open 1 of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test60 ) ;
return False ;
}
2004-11-30 07:33:27 +03:00
fnum2 = smbcli_nt_create_full ( cli2 - > tree , fname , 0 , SEC_FILE_READ_ATTRIBUTE , FILE_ATTRIBUTE_NORMAL ,
2003-08-13 05:53:07 +04:00
NTCREATEX_SHARE_ACCESS_READ , NTCREATEX_DISP_OPEN_IF , 0 , 0 ) ;
if ( fnum2 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " test 6 open 2 of %s failed (%s) \n " , fname , smbcli_errstr ( cli2 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test60 ) ;
return False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli1 - > tree , fnum1 ) ) ) {
printf ( " test 6 close 1 of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli2 - > tree , fnum2 ) ) ) {
printf ( " test 6 close 2 of %s failed (%s) \n " , fname , smbcli_errstr ( cli2 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
printf ( " non-io open test #6 passed. \n " ) ;
error_test60 :
printf ( " TEST #7 testing 1 non-io open, one io open with delete \n " ) ;
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
2004-11-30 07:33:27 +03:00
fnum1 = smbcli_nt_create_full ( cli1 - > tree , fname , 0 , SEC_FILE_READ_DATA , FILE_ATTRIBUTE_NORMAL ,
2003-08-13 05:53:07 +04:00
NTCREATEX_SHARE_ACCESS_NONE , NTCREATEX_DISP_OVERWRITE_IF , 0 , 0 ) ;
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " test 7 open 1 of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test70 ) ;
return False ;
}
2004-11-30 07:33:27 +03:00
fnum2 = smbcli_nt_create_full ( cli2 - > tree , fname , 0 , SEC_STD_DELETE | SEC_FILE_READ_ATTRIBUTE , FILE_ATTRIBUTE_NORMAL ,
2003-08-13 05:53:07 +04:00
NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_DELETE , NTCREATEX_DISP_OPEN_IF , 0 , 0 ) ;
if ( fnum2 ! = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " test 7 open 2 of %s SUCCEEDED - should have failed (%s) \n " , fname , smbcli_errstr ( cli2 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
CHECK_MAX_FAILURES ( error_test70 ) ;
return False ;
}
2004-08-04 17:23:35 +04:00
printf ( " test 7 open 2 of %s gave %s (correct error should be %s) \n " , fname , smbcli_errstr ( cli2 - > tree ) , " sharing violation " ) ;
2003-08-13 05:53:07 +04:00
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli1 - > tree , fnum1 ) ) ) {
printf ( " test 7 close 1 of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
printf ( " non-io open test #7 passed. \n " ) ;
2004-05-15 02:07:43 +04:00
2003-08-13 05:53:07 +04:00
error_test70 :
2004-05-15 02:07:43 +04:00
2004-05-25 03:40:50 +04:00
printf ( " TEST #8 testing one normal open, followed by lock, followed by open with truncate \n " ) ;
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2004-05-25 03:40:50 +04:00
2004-08-04 17:23:35 +04:00
fnum1 = smbcli_open ( cli1 - > tree , fname , O_RDWR | O_CREAT , DENY_NONE ) ;
2004-05-25 03:40:50 +04:00
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " (8) open (1) of %s failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2004-05-25 03:40:50 +04:00
return False ;
}
/* write 20 bytes. */
memset ( buf , ' \0 ' , 20 ) ;
2004-08-04 17:23:35 +04:00
if ( smbcli_write ( cli1 - > tree , fnum1 , 0 , buf , 0 , 20 ) ! = 20 ) {
printf ( " (8) write failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2004-05-25 03:40:50 +04:00
correct = False ;
}
/* Ensure size == 20. */
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_getatr ( cli1 - > tree , fname , NULL , & fsize , NULL ) ) ) {
printf ( " (8) getatr (1) failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2004-05-25 03:40:50 +04:00
CHECK_MAX_FAILURES ( error_test80 ) ;
return False ;
}
if ( fsize ! = 20 ) {
printf ( " (8) file size != 20 \n " ) ;
CHECK_MAX_FAILURES ( error_test80 ) ;
return False ;
}
/* Get an exclusive lock on the open file. */
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_lock ( cli1 - > tree , fnum1 , 0 , 4 , 0 , WRITE_LOCK ) ) ) {
printf ( " (8) lock1 failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2004-05-25 03:40:50 +04:00
CHECK_MAX_FAILURES ( error_test80 ) ;
return False ;
}
2004-08-04 17:23:35 +04:00
fnum2 = smbcli_open ( cli1 - > tree , fname , O_RDWR | O_TRUNC , DENY_NONE ) ;
2004-05-25 03:40:50 +04:00
if ( fnum1 = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " (8) open (2) of %s with truncate failed (%s) \n " , fname , smbcli_errstr ( cli1 - > tree ) ) ;
2004-05-25 03:40:50 +04:00
return False ;
}
/* Ensure size == 0. */
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_getatr ( cli1 - > tree , fname , NULL , & fsize , NULL ) ) ) {
printf ( " (8) getatr (2) failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2004-05-25 03:40:50 +04:00
CHECK_MAX_FAILURES ( error_test80 ) ;
return False ;
}
if ( fsize ! = 0 ) {
printf ( " (8) file size != 0 \n " ) ;
CHECK_MAX_FAILURES ( error_test80 ) ;
return False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli1 - > tree , fnum1 ) ) ) {
printf ( " (8) close1 failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2004-05-25 03:40:50 +04:00
return False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_close ( cli1 - > tree , fnum2 ) ) ) {
printf ( " (8) close1 failed (%s) \n " , smbcli_errstr ( cli1 - > tree ) ) ;
2004-05-25 03:40:50 +04:00
return False ;
}
error_test80 :
printf ( " open test #8 passed. \n " ) ;
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli1 - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
if ( ! torture_close_connection ( cli1 ) ) {
correct = False ;
}
if ( ! torture_close_connection ( cli2 ) ) {
correct = False ;
}
return correct ;
}
/*
sees what IOCTLs are supported
*/
2004-10-28 17:40:50 +04:00
BOOL torture_ioctl_test ( void )
2003-08-13 05:53:07 +04:00
{
2004-08-04 17:23:35 +04:00
struct smbcli_state * cli ;
2004-05-25 21:24:24 +04:00
uint16_t device , function ;
2003-08-13 05:53:07 +04:00
int fnum ;
const char * fname = " \\ ioctl.dat " ;
NTSTATUS status ;
2003-12-04 05:03:06 +03:00
union smb_ioctl parms ;
2003-08-13 05:53:07 +04:00
TALLOC_CTX * mem_ctx ;
if ( ! torture_open_connection ( & cli ) ) {
return False ;
}
mem_ctx = talloc_init ( " ioctl_test " ) ;
printf ( " starting ioctl test \n " ) ;
2004-08-04 17:23:35 +04:00
smbcli_unlink ( cli - > tree , fname ) ;
2003-08-13 05:53:07 +04:00
2004-08-04 17:23:35 +04:00
fnum = smbcli_open ( cli - > tree , fname , O_RDWR | O_CREAT | O_EXCL , DENY_NONE ) ;
2003-08-13 05:53:07 +04:00
if ( fnum = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " open of %s failed (%s) \n " , fname , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
2003-12-04 05:03:06 +03:00
parms . ioctl . level = RAW_IOCTL_IOCTL ;
2004-08-03 08:44:27 +04:00
parms . ioctl . in . fnum = fnum ;
2003-12-04 05:03:06 +03:00
parms . ioctl . in . request = IOCTL_QUERY_JOB_INFO ;
2003-08-13 05:53:07 +04:00
status = smb_raw_ioctl ( cli - > tree , mem_ctx , & parms ) ;
2004-08-04 17:23:35 +04:00
printf ( " ioctl job info: %s \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
for ( device = 0 ; device < 0x100 ; device + + ) {
printf ( " testing device=0x%x \n " , device ) ;
for ( function = 0 ; function < 0x100 ; function + + ) {
2003-12-04 05:03:06 +03:00
parms . ioctl . in . request = ( device < < 16 ) | function ;
2003-08-13 05:53:07 +04:00
status = smb_raw_ioctl ( cli - > tree , mem_ctx , & parms ) ;
if ( NT_STATUS_IS_OK ( status ) ) {
printf ( " ioctl device=0x%x function=0x%x OK : %d bytes \n " ,
2005-07-17 13:20:52 +04:00
device , function , ( int ) parms . ioctl . out . blob . length ) ;
2003-08-13 05:53:07 +04:00
}
}
}
if ( ! torture_close_connection ( cli ) ) {
return False ;
}
return True ;
}
/*
tries variants of chkpath
*/
2004-10-28 17:40:50 +04:00
BOOL torture_chkpath_test ( void )
2003-08-13 05:53:07 +04:00
{
2004-08-04 17:23:35 +04:00
struct smbcli_state * cli ;
2003-08-13 05:53:07 +04:00
int fnum ;
BOOL ret ;
if ( ! torture_open_connection ( & cli ) ) {
return False ;
}
printf ( " starting chkpath test \n " ) ;
printf ( " Testing valid and invalid paths \n " ) ;
/* cleanup from an old run */
2004-08-04 17:23:35 +04:00
smbcli_rmdir ( cli - > tree , " \\ chkpath.dir \\ dir2 " ) ;
smbcli_unlink ( cli - > tree , " \\ chkpath.dir \\ * " ) ;
smbcli_rmdir ( cli - > tree , " \\ chkpath.dir " ) ;
2003-08-13 05:53:07 +04:00
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_mkdir ( cli - > tree , " \\ chkpath.dir " ) ) ) {
printf ( " mkdir1 failed : %s \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_mkdir ( cli - > tree , " \\ chkpath.dir \\ dir2 " ) ) ) {
printf ( " mkdir2 failed : %s \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
2004-08-04 17:23:35 +04:00
fnum = smbcli_open ( cli - > tree , " \\ chkpath.dir \\ foo.txt " , O_RDWR | O_CREAT | O_EXCL , DENY_NONE ) ;
2003-08-13 05:53:07 +04:00
if ( fnum = = - 1 ) {
2004-08-04 17:23:35 +04:00
printf ( " open1 failed (%s) \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
return False ;
}
2004-08-04 17:23:35 +04:00
smbcli_close ( cli - > tree , fnum ) ;
2003-08-13 05:53:07 +04:00
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_chkpath ( cli - > tree , " \\ chkpath.dir " ) ) ) {
printf ( " chkpath1 failed: %s \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
ret = False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_chkpath ( cli - > tree , " \\ chkpath.dir \\ dir2 " ) ) ) {
printf ( " chkpath2 failed: %s \n " , smbcli_errstr ( cli - > tree ) ) ;
2003-08-13 05:53:07 +04:00
ret = False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_chkpath ( cli - > tree , " \\ chkpath.dir \\ foo.txt " ) ) ) {
2004-10-17 06:52:37 +04:00
ret = check_error ( __location__ , cli , ERRDOS , ERRbadpath ,
2003-08-13 05:53:07 +04:00
NT_STATUS_NOT_A_DIRECTORY ) ;
} else {
printf ( " * chkpath on a file should fail \n " ) ;
ret = False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_chkpath ( cli - > tree , " \\ chkpath.dir \\ bar.txt " ) ) ) {
2005-07-06 07:13:17 +04:00
ret = check_error ( __location__ , cli , ERRDOS , ERRbadpath ,
2003-08-13 05:53:07 +04:00
NT_STATUS_OBJECT_NAME_NOT_FOUND ) ;
} else {
printf ( " * chkpath on a non existent file should fail \n " ) ;
ret = False ;
}
2004-08-04 17:23:35 +04:00
if ( NT_STATUS_IS_ERR ( smbcli_chkpath ( cli - > tree , " \\ chkpath.dir \\ dirxx \\ bar.txt " ) ) ) {
2004-10-17 06:52:37 +04:00
ret = check_error ( __location__ , cli , ERRDOS , ERRbadpath ,
2003-08-13 05:53:07 +04:00
NT_STATUS_OBJECT_PATH_NOT_FOUND ) ;
} else {
printf ( " * chkpath on a non existent component should fail \n " ) ;
ret = False ;
}
2004-08-04 17:23:35 +04:00
smbcli_rmdir ( cli - > tree , " \\ chkpath.dir \\ dir2 " ) ;
smbcli_unlink ( cli - > tree , " \\ chkpath.dir \\ * " ) ;
smbcli_rmdir ( cli - > tree , " \\ chkpath.dir " ) ;
2003-08-13 05:53:07 +04:00
if ( ! torture_close_connection ( cli ) ) {
return False ;
}
return ret ;
}
2004-10-28 17:19:39 +04:00
static void sigcont ( int sig )
2003-10-29 07:21:58 +03:00
{
}
2004-08-04 17:23:35 +04:00
double torture_create_procs ( BOOL ( * fn ) ( struct smbcli_state * , int ) , BOOL * result )
2003-08-13 05:53:07 +04:00
{
int i , status ;
volatile pid_t * child_status ;
volatile BOOL * child_status_out ;
int synccount ;
int tries = 8 ;
2004-03-09 05:13:13 +03:00
double start_time_limit = 10 + ( torture_nprocs * 1.5 ) ;
2004-03-09 12:04:06 +03:00
char * * unc_list = NULL ;
2004-06-14 03:50:55 +04:00
const char * p ;
2004-03-09 12:04:06 +03:00
int num_unc_names = 0 ;
2004-11-03 13:09:48 +03:00
struct timeval tv ;
2003-08-13 05:53:07 +04:00
2005-01-02 10:51:13 +03:00
* result = True ;
2003-08-13 05:53:07 +04:00
synccount = 0 ;
2003-10-29 07:21:58 +03:00
signal ( SIGCONT , sigcont ) ;
2004-03-09 05:13:13 +03:00
child_status = ( volatile pid_t * ) shm_setup ( sizeof ( pid_t ) * torture_nprocs ) ;
2003-08-13 05:53:07 +04:00
if ( ! child_status ) {
printf ( " Failed to setup shared memory \n " ) ;
return - 1 ;
}
2004-03-09 05:13:13 +03:00
child_status_out = ( volatile BOOL * ) shm_setup ( sizeof ( BOOL ) * torture_nprocs ) ;
2003-08-13 05:53:07 +04:00
if ( ! child_status_out ) {
printf ( " Failed to setup result status shared memory \n " ) ;
return - 1 ;
}
2004-03-09 12:04:06 +03:00
p = lp_parm_string ( - 1 , " torture " , " unclist " ) ;
if ( p ) {
2005-07-10 05:10:09 +04:00
unc_list = file_lines_load ( p , & num_unc_names , NULL ) ;
2004-03-09 12:04:06 +03:00
if ( ! unc_list | | num_unc_names < = 0 ) {
2004-09-10 06:16:41 +04:00
printf ( " Failed to load unc names list from '%s' \n " , p ) ;
2004-03-09 12:04:06 +03:00
exit ( 1 ) ;
}
}
2004-03-09 05:13:13 +03:00
for ( i = 0 ; i < torture_nprocs ; i + + ) {
2003-08-13 05:53:07 +04:00
child_status [ i ] = 0 ;
child_status_out [ i ] = True ;
}
2004-11-03 13:09:48 +03:00
tv = timeval_current ( ) ;
2003-08-13 05:53:07 +04:00
2004-03-09 05:13:13 +03:00
for ( i = 0 ; i < torture_nprocs ; i + + ) {
2003-08-13 05:53:07 +04:00
procnum = i ;
if ( fork ( ) = = 0 ) {
char * myname ;
2005-01-15 14:58:52 +03:00
const char * hostname = NULL , * sharename ;
2004-03-09 12:04:06 +03:00
2003-08-13 05:53:07 +04:00
pid_t mypid = getpid ( ) ;
2005-01-21 16:16:33 +03:00
srandom ( ( ( int ) mypid ) ^ ( ( int ) time ( NULL ) ) ) ;
2003-08-13 05:53:07 +04:00
asprintf ( & myname , " CLIENT%d " , i ) ;
lp_set_cmdline ( " netbios name " , myname ) ;
free ( myname ) ;
2004-03-09 12:04:06 +03:00
if ( unc_list ) {
2005-01-15 14:58:52 +03:00
if ( ! smbcli_parse_unc ( unc_list [ i % num_unc_names ] ,
NULL , & hostname , & sharename ) ) {
2004-03-09 12:04:06 +03:00
printf ( " Failed to parse UNC name %s \n " ,
unc_list [ i % num_unc_names ] ) ;
exit ( 1 ) ;
}
}
2003-08-13 05:53:07 +04:00
while ( 1 ) {
2004-03-09 12:04:06 +03:00
if ( hostname ) {
2005-08-24 17:15:01 +04:00
if ( torture_open_connection_share ( NULL ,
& current_cli ,
2004-03-09 12:04:06 +03:00
hostname ,
2005-08-24 17:15:01 +04:00
sharename ,
NULL ) ) {
2004-03-09 12:04:06 +03:00
break ;
}
} else if ( torture_open_connection ( & current_cli ) ) {
break ;
}
2003-08-13 05:53:07 +04:00
if ( tries - - = = 0 ) {
printf ( " pid %d failed to start \n " , ( int ) getpid ( ) ) ;
_exit ( 1 ) ;
}
2003-09-29 10:04:23 +04:00
msleep ( 100 ) ;
2003-08-13 05:53:07 +04:00
}
child_status [ i ] = getpid ( ) ;
2003-10-29 07:21:58 +03:00
pause ( ) ;
2003-09-29 10:04:23 +04:00
if ( child_status [ i ] ) {
printf ( " Child %d failed to start! \n " , i ) ;
child_status_out [ i ] = 1 ;
_exit ( 1 ) ;
}
2003-08-13 05:53:07 +04:00
2004-03-09 05:13:13 +03:00
child_status_out [ i ] = fn ( current_cli , i ) ;
2003-08-13 05:53:07 +04:00
_exit ( 0 ) ;
}
}
do {
synccount = 0 ;
2004-03-09 05:13:13 +03:00
for ( i = 0 ; i < torture_nprocs ; i + + ) {
2003-08-13 05:53:07 +04:00
if ( child_status [ i ] ) synccount + + ;
}
2004-03-09 05:13:13 +03:00
if ( synccount = = torture_nprocs ) break ;
2003-09-29 10:04:23 +04:00
msleep ( 100 ) ;
2004-11-03 13:09:48 +03:00
} while ( timeval_elapsed ( & tv ) < start_time_limit ) ;
2003-08-13 05:53:07 +04:00
2004-03-09 05:13:13 +03:00
if ( synccount ! = torture_nprocs ) {
printf ( " FAILED TO START %d CLIENTS (started %d) \n " , torture_nprocs , synccount ) ;
2003-08-13 05:53:07 +04:00
* result = False ;
2004-11-03 13:09:48 +03:00
return timeval_elapsed ( & tv ) ;
2003-08-13 05:53:07 +04:00
}
2004-03-09 05:13:13 +03:00
printf ( " Starting %d clients \n " , torture_nprocs ) ;
2003-09-29 10:04:23 +04:00
2003-08-13 05:53:07 +04:00
/* start the client load */
2004-11-03 13:09:48 +03:00
tv = timeval_current ( ) ;
2004-03-09 05:13:13 +03:00
for ( i = 0 ; i < torture_nprocs ; i + + ) {
2003-08-13 05:53:07 +04:00
child_status [ i ] = 0 ;
}
2004-03-09 05:13:13 +03:00
printf ( " %d clients started \n " , torture_nprocs ) ;
2003-08-13 05:53:07 +04:00
2004-11-25 01:26:19 +03:00
kill ( 0 , SIGCONT ) ;
2004-03-09 05:13:13 +03:00
for ( i = 0 ; i < torture_nprocs ; i + + ) {
2003-09-29 10:04:23 +04:00
int ret ;
2005-09-23 04:38:22 +04:00
while ( ( ret = waitpid ( 0 , & status , 0 ) ) = = - 1 & & errno = = EINTR ) /* noop */ ;
2003-09-29 10:04:23 +04:00
if ( ret = = - 1 | | WEXITSTATUS ( status ) ! = 0 ) {
* result = False ;
}
2003-08-13 05:53:07 +04:00
}
printf ( " \n " ) ;
2004-03-09 05:13:13 +03:00
for ( i = 0 ; i < torture_nprocs ; i + + ) {
2003-08-13 05:53:07 +04:00
if ( ! child_status_out [ i ] ) {
* result = False ;
}
}
2004-11-03 13:09:48 +03:00
return timeval_elapsed ( & tv ) ;
2003-08-13 05:53:07 +04:00
}
# define FLAG_MULTIPROC 1
static struct {
const char * name ;
2004-10-28 17:40:50 +04:00
BOOL ( * fn ) ( void ) ;
BOOL ( * multi_fn ) ( struct smbcli_state * , int ) ;
2003-08-13 05:53:07 +04:00
} torture_ops [ ] = {
2004-08-03 08:44:27 +04:00
/* base tests */
{ " BASE-FDPASS " , run_fdpasstest , 0 } ,
2004-10-17 06:52:37 +04:00
{ " BASE-LOCK1 " , torture_locktest1 , 0 } ,
{ " BASE-LOCK2 " , torture_locktest2 , 0 } ,
{ " BASE-LOCK3 " , torture_locktest3 , 0 } ,
{ " BASE-LOCK4 " , torture_locktest4 , 0 } ,
{ " BASE-LOCK5 " , torture_locktest5 , 0 } ,
{ " BASE-LOCK6 " , torture_locktest6 , 0 } ,
{ " BASE-LOCK7 " , torture_locktest7 , 0 } ,
2004-11-06 12:12:53 +03:00
{ " BASE-UNLINK " , torture_unlinktest , 0 } ,
2004-08-03 08:44:27 +04:00
{ " BASE-ATTR " , run_attrtest , 0 } ,
{ " BASE-TRANS2 " , run_trans2test , 0 } ,
{ " BASE-NEGNOWAIT " , run_negprot_nowait , 0 } ,
2004-10-25 11:24:46 +04:00
{ " BASE-DIR1 " , torture_dirtest1 , 0 } ,
{ " BASE-DIR2 " , torture_dirtest2 , 0 } ,
2004-08-03 08:44:27 +04:00
{ " BASE-DENY1 " , torture_denytest1 , 0 } ,
{ " BASE-DENY2 " , torture_denytest2 , 0 } ,
2004-10-25 11:24:46 +04:00
{ " BASE-DENY3 " , torture_denytest3 , 0 } ,
2004-11-08 04:21:45 +03:00
{ " BASE-DENYDOS " , torture_denydos_sharing , 0 } ,
2004-10-30 08:59:52 +04:00
{ " BASE-NTDENY1 " , NULL , torture_ntdenytest1 } ,
{ " BASE-NTDENY2 " , torture_ntdenytest2 , 0 } ,
2004-08-03 08:44:27 +04:00
{ " BASE-TCON " , run_tcon_test , 0 } ,
{ " BASE-TCONDEV " , run_tcon_devtype_test , 0 } ,
{ " BASE-VUID " , run_vuidtest , 0 } ,
{ " BASE-RW1 " , run_readwritetest , 0 } ,
{ " BASE-OPEN " , run_opentest , 0 } ,
2004-10-28 17:40:50 +04:00
{ " BASE-DEFER_OPEN " , NULL , run_deferopen } ,
2004-08-03 08:44:27 +04:00
{ " BASE-XCOPY " , run_xcopy , 0 } ,
2004-10-25 06:59:48 +04:00
{ " BASE-RENAME " , torture_test_rename , 0 } ,
2004-10-24 13:08:52 +04:00
{ " BASE-DELETE " , torture_test_delete , 0 } ,
2004-11-25 01:26:19 +03:00
{ " BASE-PROPERTIES " , torture_test_properties , 0 } ,
2004-08-03 08:44:27 +04:00
{ " BASE-MANGLE " , torture_mangle , 0 } ,
2004-10-26 12:32:16 +04:00
{ " BASE-OPENATTR " , torture_openattrtest , 0 } ,
2004-08-03 08:44:27 +04:00
{ " BASE-CHARSET " , torture_charset , 0 } ,
{ " BASE-CHKPATH " , torture_chkpath_test , 0 } ,
2004-09-24 10:56:11 +04:00
{ " BASE-SECLEAK " , torture_sec_leak , 0 } ,
2004-11-09 12:26:47 +03:00
{ " BASE-DISCONNECT " , torture_disconnect , 0 } ,
2004-11-12 12:37:59 +03:00
{ " BASE-DELAYWRITE " , torture_delay_write , 0 } ,
2004-08-03 08:44:27 +04:00
/* benchmarking tests */
{ " BENCH-HOLDCON " , torture_holdcon , 0 } ,
{ " BENCH-NBENCH " , torture_nbench , 0 } ,
2004-10-28 17:40:50 +04:00
{ " BENCH-TORTURE " , NULL , run_torture } ,
2005-01-31 12:54:39 +03:00
{ " BENCH-NBT " , torture_bench_nbt , 0 } ,
2005-02-15 07:55:56 +03:00
{ " BENCH-WINS " , torture_bench_wins , 0 } ,
2005-05-01 14:18:19 +04:00
{ " BENCH-RPC " , torture_bench_rpc , 0 } ,
2005-05-18 08:17:24 +04:00
{ " BENCH-CLDAP " , torture_bench_cldap , 0 } ,
2004-08-03 08:44:27 +04:00
/* RAW smb tests */
2003-08-13 05:53:07 +04:00
{ " RAW-QFSINFO " , torture_raw_qfsinfo , 0 } ,
{ " RAW-QFILEINFO " , torture_raw_qfileinfo , 0 } ,
{ " RAW-SFILEINFO " , torture_raw_sfileinfo , 0 } ,
{ " RAW-SFILEINFO-BUG " , torture_raw_sfileinfo_bug , 0 } ,
{ " RAW-SEARCH " , torture_raw_search , 0 } ,
{ " RAW-CLOSE " , torture_raw_close , 0 } ,
{ " RAW-OPEN " , torture_raw_open , 0 } ,
{ " RAW-MKDIR " , torture_raw_mkdir , 0 } ,
{ " RAW-OPLOCK " , torture_raw_oplock , 0 } ,
{ " RAW-NOTIFY " , torture_raw_notify , 0 } ,
{ " RAW-MUX " , torture_raw_mux , 0 } ,
{ " RAW-IOCTL " , torture_raw_ioctl , 0 } ,
{ " RAW-CHKPATH " , torture_raw_chkpath , 0 } ,
{ " RAW-UNLINK " , torture_raw_unlink , 0 } ,
{ " RAW-READ " , torture_raw_read , 0 } ,
{ " RAW-WRITE " , torture_raw_write , 0 } ,
{ " RAW-LOCK " , torture_raw_lock , 0 } ,
{ " RAW-CONTEXT " , torture_raw_context , 0 } ,
{ " RAW-RENAME " , torture_raw_rename , 0 } ,
{ " RAW-SEEK " , torture_raw_seek , 0 } ,
2004-11-15 09:55:27 +03:00
{ " RAW-EAS " , torture_raw_eas , 0 } ,
2005-07-01 15:50:30 +04:00
{ " RAW-EAMAX " , torture_max_eas , 0 } ,
2004-11-15 09:55:27 +03:00
{ " RAW-STREAMS " , torture_raw_streams , 0 } ,
2004-11-18 04:02:27 +03:00
{ " RAW-ACLS " , torture_raw_acls , 0 } ,
2004-07-12 20:35:48 +04:00
{ " RAW-RAP " , torture_raw_rap , 0 } ,
2005-01-12 10:03:29 +03:00
{ " RAW-COMPOSITE " , torture_raw_composite , 0 } ,
2004-08-03 08:44:27 +04:00
2005-11-11 07:46:48 +03:00
/* SMB2 tests */
{ " SMB2-CONNECT " , torture_smb2_connect , 0 } ,
2005-11-12 05:37:51 +03:00
{ " SMB2-SCAN " , torture_smb2_scan , 0 } ,
2005-11-12 10:48:56 +03:00
{ " SMB2-SCANGETINFO " , torture_smb2_getinfo_scan , 0 } ,
2005-11-18 12:25:25 +03:00
{ " SMB2-SCANSETINFO " , torture_smb2_setinfo_scan , 0 } ,
2005-11-15 07:38:59 +03:00
{ " SMB2-GETINFO " , torture_smb2_getinfo , 0 } ,
2005-11-18 09:31:33 +03:00
{ " SMB2-SETINFO " , torture_smb2_setinfo , 0 } ,
2005-11-11 07:46:48 +03:00
2004-08-03 08:44:27 +04:00
/* protocol scanners */
2003-08-13 05:53:07 +04:00
{ " SCAN-TRANS2 " , torture_trans2_scan , 0 } ,
{ " SCAN-NTTRANS " , torture_nttrans_scan , 0 } ,
{ " SCAN-ALIASES " , torture_trans2_aliases , 0 } ,
2003-08-14 02:23:18 +04:00
{ " SCAN-SMB " , torture_smb_scan , 0 } ,
2004-10-28 17:40:50 +04:00
{ " SCAN-MAXFID " , NULL , run_maxfidtest } ,
2004-08-03 08:44:27 +04:00
{ " SCAN-UTABLE " , torture_utable , 0 } ,
{ " SCAN-CASETABLE " , torture_casetable , 0 } ,
{ " SCAN-PIPE_NUMBER " , run_pipe_number , 0 } ,
{ " SCAN-IOCTL " , torture_ioctl_test , 0 } ,
2005-01-25 04:21:59 +03:00
{ " SCAN-RAP " , torture_rap_scan , 0 } ,
2004-08-03 08:44:27 +04:00
/* rpc testers */
2003-11-03 09:22:45 +03:00
{ " RPC-LSA " , torture_rpc_lsa , 0 } ,
2005-06-17 15:48:01 +04:00
{ " RPC-SECRETS " , torture_rpc_lsa_secrets , 0 } ,
2003-11-03 10:26:30 +03:00
{ " RPC-ECHO " , torture_rpc_echo , 0 } ,
2003-11-13 12:26:53 +03:00
{ " RPC-DFS " , torture_rpc_dfs , 0 } ,
2003-11-15 08:42:49 +03:00
{ " RPC-SPOOLSS " , torture_rpc_spoolss , 0 } ,
2003-11-15 09:00:21 +03:00
{ " RPC-SAMR " , torture_rpc_samr , 0 } ,
2005-05-19 19:45:25 +04:00
{ " RPC-UNIXINFO " , torture_rpc_unixinfo , 0 } ,
2003-12-01 04:41:38 +03:00
{ " RPC-NETLOGON " , torture_rpc_netlogon , 0 } ,
2004-11-11 07:32:01 +03:00
{ " RPC-SAMLOGON " , torture_rpc_samlogon , 0 } ,
2004-11-12 02:24:30 +03:00
{ " RPC-SAMSYNC " , torture_rpc_samsync , 0 } ,
2004-06-06 11:14:10 +04:00
{ " RPC-SCHANNEL " , torture_rpc_schannel , 0 } ,
2003-11-17 15:43:18 +03:00
{ " RPC-WKSSVC " , torture_rpc_wkssvc , 0 } ,
2003-11-19 12:15:46 +03:00
{ " RPC-SRVSVC " , torture_rpc_srvsvc , 0 } ,
2004-08-02 04:24:04 +04:00
{ " RPC-SVCCTL " , torture_rpc_svcctl , 0 } ,
2003-11-20 06:27:56 +03:00
{ " RPC-ATSVC " , torture_rpc_atsvc , 0 } ,
2003-11-21 00:52:40 +03:00
{ " RPC-EVENTLOG " , torture_rpc_eventlog , 0 } ,
2003-11-21 16:14:17 +03:00
{ " RPC-EPMAPPER " , torture_rpc_epmapper , 0 } ,
2003-11-21 08:28:36 +03:00
{ " RPC-WINREG " , torture_rpc_winreg , 0 } ,
2005-03-17 23:28:01 +03:00
{ " RPC-INITSHUTDOWN " , torture_rpc_initshutdown , 0 } ,
2004-09-28 23:20:00 +04:00
{ " RPC-OXIDRESOLVE " , torture_rpc_oxidresolve , 0 } ,
2004-10-31 21:37:59 +03:00
{ " RPC-REMACT " , torture_rpc_remact , 0 } ,
2003-11-24 04:24:29 +03:00
{ " RPC-MGMT " , torture_rpc_mgmt , 0 } ,
2003-11-27 08:34:28 +03:00
{ " RPC-SCANNER " , torture_rpc_scanner , 0 } ,
2003-11-28 11:51:09 +03:00
{ " RPC-AUTOIDL " , torture_rpc_autoidl , 0 } ,
2004-10-08 05:15:25 +04:00
{ " RPC-COUNTCALLS " , torture_rpc_countcalls , 0 } ,
2004-06-17 04:31:24 +04:00
{ " RPC-MULTIBIND " , torture_multi_bind , 0 } ,
2004-07-13 22:05:02 +04:00
{ " RPC-DRSUAPI " , torture_rpc_drsuapi , 0 } ,
2005-08-29 08:15:08 +04:00
{ " RPC-CRACKNAMES " , torture_rpc_drsuapi_cracknames , 0 } ,
2004-11-10 19:50:15 +03:00
{ " RPC-LOGIN " , torture_rpc_login , 0 } ,
2004-11-20 21:51:58 +03:00
{ " RPC-ROT " , torture_rpc_rot , 0 } ,
2004-12-31 13:49:35 +03:00
{ " RPC-DSSETUP " , torture_rpc_dssetup , 0 } ,
2005-01-09 12:38:16 +03:00
{ " RPC-ALTERCONTEXT " , torture_rpc_alter_context , 0 } ,
2005-09-25 16:26:07 +04:00
{ " RPC-JOIN " , torture_rpc_join , 0 } ,
r10865: merge branches/SOC/SAMBA_4_0 into main the main SAMBA_4_0 tree
metze
r8017@SERNOX: metze | 2005-06-30 13:44:23 +0200
create the SAMBA_4_0 branch for the Summer Of Code Project
metze
r8730@SERNOX: brad | 2005-07-24 03:09:48 +0200
Branching Samba 4
r8731@SERNOX: brad | 2005-07-24 06:39:00 +0200
added 'make installmisc' to howto.txt
added existing 'compression' option to level8 drsuapi torture test
added new 'neighbour_writeable' option to level8 drsuapi torture test
r8732@SERNOX: brad | 2005-07-24 06:42:38 +0200
added metze's dssync patch as source/torture/rpc/dssync.c
r8739@SERNOX: brad | 2005-07-25 00:24:46 +0200
added a test called RPC-DSSYNC to config.mk
hacking at dssync.c in an attempt to make it compile
r8754@SERNOX: brad | 2005-07-25 15:19:21 +0200
Changing dssync.c to use ldb routines for accessing ldap rather than raw ldap calls.
r8765@SERNOX: brad | 2005-07-26 03:35:38 +0200
more ldb changes to test_CompleteJoin(), it mostly kind of almost works now!
r8766@SERNOX: brad | 2005-07-26 03:56:00 +0200
Trying to fix the crazy nesting in the branch
r8769@SERNOX: brad | 2005-07-26 04:48:29 +0200
merging latest changes
r8770@SERNOX: brad | 2005-07-26 04:53:43 +0200
removing nested branch
r8793@SERNOX: jerry | 2005-07-27 05:04:57 +0200
merging on of Brad missing changes from the nested 4.0 branch debacle
r8794@SERNOX: jerry | 2005-07-27 05:14:42 +0200
syncing up with the main 4_0 branch for Brad
r8842@SERNOX: brad | 2005-07-29 00:26:30 +0200
merging changes from branches/SAMBA_4_0
r8850@SERNOX: brad | 2005-07-29 21:07:57 +0200
Bringing my tree up to date
r8851@SERNOX: brad | 2005-07-30 00:48:04 +0200
making dssync.c more ldb-centric, reverted samlogon.c from rev. 8845 to get my branch to compile again.
r8856@SERNOX: brad | 2005-07-30 03:20:33 +0200
I think I have the ldb code down in test_CompleteJoin (not complete yet though)
r8860@SERNOX: brad | 2005-07-30 07:08:13 +0200
Changed comments to C style /**/ (thanks Richard), some more changes to test_CompleteJoin().
r8862@SERNOX: brad | 2005-07-31 04:45:32 +0200
Bringing the SOC/SAMBA_4_0 branch up to date.
r8863@SERNOX: brad | 2005-07-31 20:00:41 +0200
Updated some missing files from the branch
r8864@SERNOX: brad | 2005-07-31 20:25:50 +0200
Removing autogenerated files from branch
r8865@SERNOX: brad | 2005-07-31 20:43:58 +0200
last of the unneeded files in SOC/SAMBA_4_0
r9004@SERNOX: brad | 2005-08-03 18:51:23 +0200
r5214@buttercup: j0j0 | 2005-08-03 10:44:30 -0600
r@buttercup: j0j0 | 2005-08-02 22:54:13 -0600
creating a local branch of branches/SAMBA_4_0
r9013@SERNOX: brad | 2005-08-03 20:57:48 +0200
r5228@buttercup: j0j0 | 2005-08-03 13:00:11 -0600
Fixing differences between this branch and /branches/SAMBA_4_0
r9014@SERNOX: brad | 2005-08-03 21:18:05 +0200
r5231@buttercup: j0j0 | 2005-08-03 13:23:12 -0600
Updating config.mk so that smbtorture builds again
r9061@SERNOX: brad | 2005-08-04 18:17:36 +0200
r5249@buttercup: j0j0 | 2005-08-03 21:01:02 -0600
Start using libnet_Join() for DC join.
r9062@SERNOX: brad | 2005-08-04 18:17:47 +0200
r5250@buttercup: j0j0 | 2005-08-04 10:21:34 -0600
Some more work towards performing a dc join.
r9064@SERNOX: brad | 2005-08-04 18:53:51 +0200
r5253@buttercup: j0j0 | 2005-08-04 10:53:00 -0600
Fixed a bug (passing a TALLOC_CTX to libnet_context_init() )
r9069@SERNOX: brad | 2005-08-04 21:59:55 +0200
r5279@buttercup: j0j0 | 2005-08-04 14:04:55 -0600
Some more work on the domain join
r9117@SERNOX: brad | 2005-08-05 16:50:26 +0200
r5281@buttercup: j0j0 | 2005-08-05 08:55:58 -0600
Committing minor changes before merge
r9180@SERNOX: brad | 2005-08-07 17:25:25 +0200
r5314@buttercup: j0j0 | 2005-08-07 09:30:12 -0600
Reworked libnet_join to use two join levels, AUTOMATIC and SPECIFIED.
r9181@SERNOX: brad | 2005-08-07 17:25:36 +0200
r5315@buttercup: j0j0 | 2005-08-07 09:31:22 -0600
Working with libnet_Join(), code cleanup needed in the near future.
r9192@SERNOX: brad | 2005-08-07 21:40:22 +0200
r5373@buttercup: j0j0 | 2005-08-07 13:46:09 -0600
Some code cleanup to make things a little more readable.
r9249@SERNOX: brad | 2005-08-12 01:31:48 +0200
r5375@buttercup: j0j0 | 2005-08-11 17:38:44 -0600
Split libnet_JoinDomain() into libnet_JoinDomain() and libnet_JoinADSDomain().
r9256@SERNOX: brad | 2005-08-12 04:55:11 +0200
r5413@buttercup: j0j0 | 2005-08-11 21:02:27 -0600
Clean up libnet_JoinADSDomain() a little, added a comment to the test_join struct.
r9314@SERNOX: brad | 2005-08-16 03:53:20 +0200
r5436@buttercup: j0j0 | 2005-08-15 20:01:21 -0600
libnet_JoinDomain() should honour LIBNET_JOIN_TORTURE now.
torture_join_domain() should properly use libnet_JoinDomain().
dssync.c uses torture_join_domain() again.
r9351@SERNOX: brad | 2005-08-17 07:15:31 +0200
r5438@buttercup: j0j0 | 2005-08-16 23:23:58 -0600
Removed LIBNET_JOIN_TORTURE level, as it became unnecessary once libnet_Join_primary_domain() handled netbios names better.
Corrected libnet_JoinDomain() and libnet_JoinADSDomain().
r9352@SERNOX: brad | 2005-08-17 07:24:49 +0200
r5440@buttercup: j0j0 | 2005-08-16 23:33:25 -0600
Fixed a typo.
r9354@SERNOX: metze | 2005-08-17 10:28:25 +0200
remove object files from svn
metze
r9376@SERNOX: brad | 2005-08-18 05:15:48 +0200
r5476@buttercup: j0j0 | 2005-08-17 21:24:33 -0600
Proof that I shouldn't code when i'm tired (silly bugfixes).
r9405@SERNOX: brad | 2005-08-19 22:50:10 +0200
r5500@buttercup: j0j0 | 2005-08-19 14:56:25 -0600
Get dssync.c compiling again after merge (ldb_dn changes from rev. 9391).
r9407@SERNOX: brad | 2005-08-20 03:22:42 +0200
r5502@buttercup: j0j0 | 2005-08-19 19:28:22 -0600
libnet/libnet_join.c
Some more fixes so ldb uses ldb_dn's.
torture/rpc/dssync.c
Some debugging printf()'s.
ldb_dn fixes.
torture/rpc/testjoin.c
Change torture_join_domain() to use libnet_JoinDomain() rather than libnet_Join().
Some more debugging statements.
I'm not sure why, but GUID_all_zero(user_handle.uuid) is returning true in torture_leave_domain() when called it from torture_destroy_context() in torture/rpc/dssync.c.
That's what i'm working out now.
r9427@SERNOX: brad | 2005-08-20 18:38:29 +0200
r5504@buttercup: j0j0 | 2005-08-20 10:44:52 -0600
Some bugfixes.
Removed a bunch of debugging code.
torture_leave_domain() works again! not 100% perfect yet though...
r9428@SERNOX: brad | 2005-08-20 19:09:26 +0200
r5506@buttercup: j0j0 | 2005-08-20 11:15:54 -0600
Restructure torture_join_domain() so that it joins itself, removes itself, and joins itself to the domain again to ensure that its account information is all current and as expected.
r9452@SERNOX: brad | 2005-08-21 19:33:51 +0200
r5508@buttercup: j0j0 | 2005-08-21 11:40:36 -0600
Bugfixes, trying to get things straight between contexts.
r9467@SERNOX: brad | 2005-08-22 04:00:48 +0200
r5510@buttercup: j0j0 | 2005-08-21 20:06:55 -0600
Another round of bugfixing.
r9521@SERNOX: brad | 2005-08-23 15:26:44 +0200
r5596@buttercup: j0j0 | 2005-08-23 07:33:06 -0600
Merging changes
r9524@SERNOX: metze | 2005-08-23 16:09:42 +0200
- fix the build caused by changes in the main samba4 tree,
- add an option "dssync:german=yes" to allow me to run against my german w2k3 server
this should be replaces by CLDAP calls to get the Default-First-Site-Name dynamicly
- remove some temporary comments, as DsAddEntry works now
metze
r9528@SERNOX: metze | 2005-08-23 18:22:22 +0200
the RPC-DSSYNC test is now able to fetch the whole tree,
including the unicodePwd, ntPwdHistory fields
metze
r9559@SERNOX: brad | 2005-08-24 04:11:47 +0200
r5612@buttercup: j0j0 | 2005-08-23 20:19:12 -0600
Some fixes around using talloc in a hierarchical fashion.
Still not right, but better.
r9564@SERNOX: brad | 2005-08-24 05:43:11 +0200
r5614@buttercup: j0j0 | 2005-08-23 21:50:38 -0600
Gave libnet_JoinADSDomain() its own tmp_ctx rather than passing it from libnet_JoinDomain() as a parameter (yuk).
As a side effect, it proves that my bug lies in libnet_JoinDomain(), not libnet_JoinADSDomain().
r9565@SERNOX: brad | 2005-08-24 06:09:46 +0200
r5616@buttercup: j0j0 | 2005-08-23 22:17:12 -0600
Small fix, if r->out.error_string and r2->samr_handle.out.error_string weren't set to NULL, torture_join_domain() would segfault on the second join.
r9630@SERNOX: brad | 2005-08-26 06:42:50 +0200
Commented out the parts of the dssync test which perform the dc join and create/remove associated ldap entries.
Commented out the test for the 'german' dssync option, because now we detect the Site-Name using CLDAP. If cldap_netlogon() does not return ok, the code defaults to 'Default-First-Site-Name'.
r9670@SERNOX: brad | 2005-08-27 02:30:11 +0200
Added a patch from metze.
To showcase what i've learned today, i've created two new parameters which can be set at runtime, drsuapi:last_usn and drsuapi:partition.
drsuapi:last_usn takes an integer representing the USN of the last recieved replication update for a particular partition (uses the domain dn if drsuapi:parition isn't set).
That value is passed in the DsGetNCChanges() call so that only info which has been updated since that point in time is returned. If this option is not set, 0 is used by default, and all updates for that partition are returned.
drsuapi:partition takes a string dn and uses that as the name of the AD partition to replicate.
Some debugging output was also added.
r9723@SERNOX: brad | 2005-08-29 01:07:51 +0200
Added some copyright notices.
Changed some things in net_join.c to try and figure out why 'net join <domain> bdc' segfaults.
It occurs when the last talloc_free() happens, so i'm sure it's something to do with the memory fiddling i'm doing in libnet_join.
Added some drsuapi attribute ids that I figured out today.
I put some (many, dry) notes together while doing that, so i'll try to put them up on a blog at samba.org a little later tonight.
r9740@SERNOX: metze | 2005-08-29 16:58:03 +0200
fix up the DsGetNCchanges loop,
and remove misleading comments
metze
r9743@SERNOX: metze | 2005-08-29 17:26:45 +0200
make the logic a bit clearer
metze
r9815@SERNOX: brad | 2005-08-31 02:36:21 +0200
Added cldap_netlogon() AD Site-Name lookup into libnet/libnet_join.c.
Bugfixing rampage in libnet_join.c to resolve misunderstanding of talloc_steal().
libnet_join now creates the CN=<netbios name>,CN=Servers,CN=<site name>,CN=Sites,CN=Configuration,<domain dn> container on a dc join.
r9858@SERNOX: brad | 2005-09-01 03:17:17 +0200
Removed extraneous NDR_ALL subsystem requirement from torture/config.mk.
Added lots of error checking as per metze's advice.
Removed commented out code.
More bug chasing.
r9863@SERNOX: brad | 2005-09-01 05:53:19 +0200
Cleaned up dssync.c, removed the unneeded DsCrackNames() call, removed DC join/leave related stuff.
It no longer looks like my house does!
r9887@SERNOX: metze | 2005-09-01 11:34:03 +0200
- fix dssync:highest_usn parameter handling
- ask for LINKED_ATTRIBUTE replication
metze
r9891@SERNOX: metze | 2005-09-01 14:13:18 +0200
make the code more readable, and fix a few bugs
metze
r9911@SERNOX: brad | 2005-09-01 20:36:27 +0200
Bugfixes in libnet_join.c.
Cleaned up comments.
Added domain_dn_str and account_dn_str to struct libnet_JoinDomain.
Removed struct dcerpc_pipe *samr_pipe and struct policy_handle user_handle from struct libnet_Join.
r9920@SERNOX: brad | 2005-09-01 23:34:13 +0200
Added disclaimer (I can't seem to get libnet_JoinDomain() to keep the samr_pipe and u_handle open past the function call, grrrr....).
r9921@SERNOX: brad | 2005-09-01 23:37:54 +0200
Added copyright statement.
Cleaned up unneeded variables from torture_join_domain().
r9932@SERNOX: brad | 2005-09-02 01:49:42 +0200
Really rushed project notes.
r10841@SERNOX: metze | 2005-10-08 20:01:45 +0200
remove diff to main SAMBA_4_0 branch
metze
r10862@SERNOX: metze | 2005-10-10 10:31:52 +0200
remove the differences between SAMBA_4_0 and SOC/SAMBA_4_0
metze
r10863@SERNOX: metze | 2005-10-10 10:34:26 +0200
fix the build
metze
r10864@SERNOX: metze | 2005-10-10 11:10:08 +0200
remove README file to reduce, diffs to main SAMBA_4_0 branch:
metze
README:
This project was centered around adding a torture test to Samba 4, which used drsuapi_DsGetNCChanges() to retrieve the contents of an Active Directory in the same manner as an Active Directory DC replication event.
As the project unfolded, I also applied some changes to the functionality of the libnet library related to joining a machine account to a domain.
One of the first things that I implemented in this project was a 'neighbour_writeable' option for the RPC-DRSUAPI torture test. The command line to execute this torture test is as follows:
smbtorture --option=drsuapi:neighbour_writeable=True -W <domain name> -U <admin username>%<password> ncacn_ip_tcp:<domain controller dns name> RPC-DRSUAPI
This option provides us with runtime control over the DRSUAPI_DS_REPLICA_NEIGHBOUR_WRITEABLE flag in the struct drsuapi_DsGetNCChanges.in.req.req<level>.replica_flags, allowing us to easily test for differences in the behaviour of AD replication with the switch on or off.
In the course of the project, I also implemented two more flags for the RPC-DSSYNC test. dssync:last_usn takes an integer representing the USN (Universal Serial Number) of the last recieved replication update for a particular partition (uses the domain DN if drsuapi:parition isn't set). That value is passed in the DsGetNCChanges() call so that only info which has been updated since that point in time is returned. If this option is not set, 0 is used by default, and all updates for that partition are returned. dssync:partition takes a string DN and uses that as the name of the AD partition to replicate.
Based initially on a patch provided to me by one of my mentors, Stephan (metze) Metzmacher, the RPC-DSSYNC test was implemented for this project. Initially functionality was included to perform a DC join prior to initiating replication, but the code was removed when it was realized that replication could indeed take place without being a member of the domain in any way. It has been recently suggested that we may need a DC join after all to get all of the information we may want from the AD replication. This is probably best added using a torture_join_domain() call once the libnet code is able to keep the user policy handle and SAMR RPC pipe open.
The DC join code was taken out of the RPC-DSSYNC and implemented for the most part in the libnet libraries. To test this, the RPC-NETLOGON test was modified to perform a domain join, leave and rejoin. Currently, the test has a fault in that it is unable to leave the domain using the same SAMR RPC pipe and user_policy information as was used for the first join. This is because I was unable to get the code working properly in libnet to provide that functionality. Currently missing from the DC join in libnet is the code to create the CN=NTDS Settings,CN=<DC NETBIOS NAME>,CN=<Site-Name>,CN=Sites,CN=Configuration,<domain DN> container using the dcerpc_drsuapi_DsAddEntry() call. I did not want to implement this functionality in libnet while there were still problems with the code.
I also provided the ability in libnet and the RPC-DSSYNC test to look up the proper site name using the cldap library.
In my investigations, I was unable to find out any information regarding the UnicodePwd attribute, except that the same password is represented differently for two different users in the same directory.
I was also able to resolve and confirm the meaning of some DRSUAPI_ATTRIBUTE ID's.
DRSUAPI_OBJECTCLASS_domain (0xA0042)
DRSUAPI_OBJECTCLASS_domainDNS (0xA0043)
wellKnownObjects (0x9026A)
fSMORoleOwner (0x90171)
name or dc (0x90001)
whenCreated (0x20002)
instanceType (0x20001)
gPLink (0x9037B)
These were added to the IDL for drsuapi (source/librpc/idl/drsuapi.idl).
I would like to thank everyone on the Samba team who worked with me and assisted me with this project, specifically all the work done by Stephan Metzmacher, Andrew Bartlett and Jerry Carter. Working on this project with the Samba team really has been a life changing experience, as corny as that sounds.
I've realized that I was born to be a systems developer, and it has helped confirm in my mind that Open Source (specifically Samba) development is exactly what i've been missing!
I would also like to take this opportunity to thank Chris Dibona and Google for the amazing opportunity. I don't know if I would have taken the leap in other circumstances.
I know these notes sound a little rushed, but it is 23:55 after all! :)
(This used to be commit 55552b41cbaa8c57a30373a53176e7f3ae945290)
2005-10-10 13:33:06 +04:00
{ " RPC-DSSYNC " , torture_rpc_dssync , 0 } ,
2004-08-03 08:44:27 +04:00
2004-09-01 08:39:06 +04:00
/* local (no server) testers */
{ " LOCAL-NTLMSSP " , torture_ntlmssp_self_check , 0 } ,
{ " LOCAL-ICONV " , torture_local_iconv , 0 } ,
2004-09-28 09:42:02 +04:00
{ " LOCAL-TALLOC " , torture_local_talloc , 0 } ,
2004-10-17 14:04:49 +04:00
{ " LOCAL-MESSAGING " , torture_local_messaging , 0 } ,
2005-06-05 10:53:07 +04:00
{ " LOCAL-IRPC " , torture_local_irpc , 0 } ,
2004-10-24 17:00:51 +04:00
{ " LOCAL-BINDING " , torture_local_binding_string , 0 } ,
2005-09-26 21:42:12 +04:00
{ " LOCAL-STRLIST " , torture_local_util_strlist , 0 } ,
2005-09-29 01:54:29 +04:00
{ " LOCAL-FILE " , torture_local_util_file , 0 } ,
2004-10-22 10:46:04 +04:00
{ " LOCAL-IDTREE " , torture_local_idtree , 0 } ,
2005-01-19 06:20:20 +03:00
{ " LOCAL-SOCKET " , torture_local_socket , 0 } ,
2005-07-04 06:36:16 +04:00
{ " LOCAL-PAC " , torture_pac , 0 } ,
2005-09-29 02:16:30 +04:00
{ " LOCAL-REGISTRY " , torture_registry , 0 } ,
2005-09-13 16:44:33 +04:00
{ " LOCAL-RESOLVE " , torture_local_resolve , 0 } ,
2004-08-03 08:44:27 +04:00
2005-02-21 17:30:49 +03:00
/* COM (Component Object Model) testers */
{ " COM-SIMPLE " , torture_com_simple , 0 } ,
2004-08-12 12:00:45 +04:00
/* ldap testers */
{ " LDAP-BASIC " , torture_ldap_basic , 0 } ,
2005-05-10 06:03:47 +04:00
{ " LDAP-CLDAP " , torture_cldap , 0 } ,
2004-08-12 12:00:45 +04:00
2005-02-01 09:16:12 +03:00
/* nbt tests */
{ " NBT-REGISTER " , torture_nbt_register , 0 } ,
2005-02-10 06:22:47 +03:00
{ " NBT-WINS " , torture_nbt_wins , 0 } ,
2005-04-06 15:17:08 +04:00
{ " NBT-DGRAM " , torture_nbt_dgram , 0 } ,
2005-10-15 16:30:08 +04:00
{ " NBT-WINSREPLICATION-QUICK " , torture_nbt_winsreplication_quick , 0 } ,
{ " NBT-WINSREPLICATION " , torture_nbt_winsreplication , 0 } ,
2005-03-04 03:24:21 +03:00
/* libnet tests */
{ " NET-USERINFO " , torture_userinfo , 0 } ,
2005-04-21 05:01:26 +04:00
{ " NET-USERADD " , torture_useradd , 0 } ,
2005-04-21 11:25:16 +04:00
{ " NET-USERDEL " , torture_userdel , 0 } ,
2005-07-22 02:33:47 +04:00
{ " NET-USERMOD " , torture_usermod , 0 } ,
2005-06-06 13:01:27 +04:00
{ " NET-DOMOPEN " , torture_domainopen , 0 } ,
2005-06-19 03:18:31 +04:00
{ " NET-API-LOOKUP " , torture_lookup , 0 } ,
2005-06-22 00:22:38 +04:00
{ " NET-API-LOOKUPHOST " , torture_lookup_host , 0 } ,
{ " NET-API-LOOKUPPDC " , torture_lookup_pdc , 0 } ,
2005-06-08 03:27:49 +04:00
{ " NET-API-CREATEUSER " , torture_createuser , 0 } ,
2005-07-02 18:38:05 +04:00
{ " NET-API-RPCCONNECT " , torture_rpc_connect , 0 } ,
2005-08-02 22:15:23 +04:00
{ " NET-API-LISTSHARES " , torture_listshares , 0 } ,
2005-08-03 07:28:10 +04:00
{ " NET-API-DELSHARE " , torture_delshare , 0 } ,
2005-02-01 09:16:12 +03:00
2003-08-13 05:53:07 +04:00
{ NULL , NULL , 0 } } ;
/****************************************************************************
run a specified test or " ALL "
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL run_test ( const char * name )
{
BOOL ret = True ;
int i ;
BOOL matched = False ;
if ( strequal ( name , " ALL " ) ) {
for ( i = 0 ; torture_ops [ i ] . name ; i + + ) {
if ( ! run_test ( torture_ops [ i ] . name ) ) {
ret = False ;
}
}
return ret ;
}
for ( i = 0 ; torture_ops [ i ] . name ; i + + ) {
if ( gen_fnmatch ( name , torture_ops [ i ] . name ) = = 0 ) {
double t ;
matched = True ;
2004-10-02 16:18:59 +04:00
init_iconv ( ) ;
2003-08-13 05:53:07 +04:00
printf ( " Running %s \n " , torture_ops [ i ] . name ) ;
2004-10-28 17:40:50 +04:00
if ( torture_ops [ i ] . multi_fn ) {
2005-01-02 10:51:13 +03:00
BOOL result = False ;
2004-10-28 17:40:50 +04:00
t = torture_create_procs ( torture_ops [ i ] . multi_fn ,
& result ) ;
2003-08-13 05:53:07 +04:00
if ( ! result ) {
ret = False ;
printf ( " TEST %s FAILED! \n " , torture_ops [ i ] . name ) ;
}
} else {
2004-11-03 13:09:48 +03:00
struct timeval tv = timeval_current ( ) ;
2004-10-28 17:40:50 +04:00
if ( ! torture_ops [ i ] . fn ( ) ) {
2003-08-13 05:53:07 +04:00
ret = False ;
printf ( " TEST %s FAILED! \n " , torture_ops [ i ] . name ) ;
}
2004-11-03 13:09:48 +03:00
t = timeval_elapsed ( & tv ) ;
2003-08-13 05:53:07 +04:00
}
printf ( " %s took %g secs \n \n " , torture_ops [ i ] . name , t ) ;
}
}
if ( ! matched ) {
printf ( " Unknown torture operation '%s' \n " , name ) ;
}
return ret ;
}
2004-08-13 02:25:01 +04:00
static void parse_dns ( const char * dns )
{
char * userdn , * basedn , * secret ;
char * p , * d ;
/* retrievieng the userdn */
p = strchr_m ( dns , ' # ' ) ;
if ( ! p ) {
lp_set_cmdline ( " torture:ldap_userdn " , " " ) ;
lp_set_cmdline ( " torture:ldap_basedn " , " " ) ;
lp_set_cmdline ( " torture:ldap_secret " , " " ) ;
return ;
}
userdn = strndup ( dns , p - dns ) ;
lp_set_cmdline ( " torture:ldap_userdn " , userdn ) ;
/* retrieve the basedn */
d = p + 1 ;
p = strchr_m ( d , ' # ' ) ;
if ( ! p ) {
lp_set_cmdline ( " torture:ldap_basedn " , " " ) ;
lp_set_cmdline ( " torture:ldap_secret " , " " ) ;
return ;
}
basedn = strndup ( d , p - d ) ;
lp_set_cmdline ( " torture:ldap_basedn " , basedn ) ;
/* retrieve the secret */
p = p + 1 ;
if ( ! p ) {
lp_set_cmdline ( " torture:ldap_secret " , " " ) ;
return ;
}
secret = strdup ( p ) ;
lp_set_cmdline ( " torture:ldap_secret " , secret ) ;
printf ( " %s - %s - %s \n " , userdn , basedn , secret ) ;
}
2004-08-25 18:31:59 +04:00
static void usage ( poptContext pc )
2003-08-13 05:53:07 +04:00
{
int i ;
2004-08-25 18:31:59 +04:00
int perline = 5 ;
2003-08-13 05:53:07 +04:00
2004-08-25 18:31:59 +04:00
poptPrintUsage ( pc , stdout , 0 ) ;
printf ( " \n " ) ;
2003-08-13 05:53:07 +04:00
2004-12-13 12:26:13 +03:00
printf ( " The binding format is: \n \n " ) ;
printf ( " TRANSPORT:host[flags] \n \n " ) ;
printf ( " where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP \n \n " ) ;
printf ( " 'host' is an IP or hostname or netbios name. If the binding string \n " ) ;
printf ( " identifies the server side of an endpoint, 'host' may be an empty \n " ) ;
printf ( " string. \n \n " ) ;
printf ( " 'flags' can include a SMB pipe name if using the ncacn_np transport or \n " ) ;
printf ( " a TCP port number if using the ncacn_ip_tcp transport, otherwise they \n " ) ;
printf ( " will be auto-determined. \n \n " ) ;
printf ( " other recognised flags are: \n \n " ) ;
printf ( " sign : enable ntlmssp signing \n " ) ;
printf ( " seal : enable ntlmssp sealing \n " ) ;
printf ( " connect : enable rpc connect level auth (auth, but no sign or seal) \n " ) ;
printf ( " validate: enable the NDR validator \n " ) ;
printf ( " print: enable debugging of the packets \n " ) ;
printf ( " bigendian: use bigendian RPC \n " ) ;
printf ( " padcheck: check reply data for non-zero pad bytes \n \n " ) ;
printf ( " For example, these all connect to the samr pipe: \n \n " ) ;
printf ( " ncacn_np:myserver \n " ) ;
printf ( " ncacn_np:myserver[samr] \n " ) ;
printf ( " ncacn_np:myserver[ \\ pipe \\ samr] \n " ) ;
printf ( " ncacn_np:myserver[/pipe/samr] \n " ) ;
printf ( " ncacn_np:myserver[samr,sign,print] \n " ) ;
printf ( " ncacn_np:myserver[ \\ pipe \\ samr,sign,seal,bigendian] \n " ) ;
printf ( " ncacn_np:myserver[/pipe/samr,seal,validate] \n " ) ;
printf ( " ncacn_np: \n " ) ;
printf ( " ncacn_np:[/pipe/samr] \n \n " ) ;
printf ( " ncacn_ip_tcp:myserver \n " ) ;
printf ( " ncacn_ip_tcp:myserver[1024] \n " ) ;
printf ( " ncacn_ip_tcp:myserver[1024,sign,seal] \n \n " ) ;
printf ( " The unc format is: \n \n " ) ;
printf ( " //server/share \n \n " ) ;
2003-08-13 05:53:07 +04:00
printf ( " tests are: " ) ;
for ( i = 0 ; torture_ops [ i ] . name ; i + + ) {
2004-08-25 18:31:59 +04:00
if ( ( i % perline ) = = 0 ) {
printf ( " \n " ) ;
}
printf ( " %s " , torture_ops [ i ] . name ) ;
2003-08-13 05:53:07 +04:00
}
2004-08-25 18:31:59 +04:00
printf ( " \n \n " ) ;
2003-08-13 05:53:07 +04:00
printf ( " default test is ALL \n " ) ;
2004-12-13 12:26:13 +03:00
2003-08-13 05:53:07 +04:00
exit ( 1 ) ;
}
2004-10-18 19:33:34 +04:00
static BOOL is_binding_string ( const char * binding_string )
{
TALLOC_CTX * mem_ctx = talloc_init ( " is_binding_string " ) ;
r5902: A rather large change...
I wanted to add a simple 'workstation' argument to the DCERPC
authenticated binding calls, but this patch kind of grew from there.
With SCHANNEL, the 'workstation' name (the netbios name of the client)
matters, as this is what ties the session between the NETLOGON ops and
the SCHANNEL bind. This changes a lot of files, and these will again
be changed when jelmer does the credentials work.
I also correct some schannel IDL to distinguish between workstation
names and account names. The distinction matters for domain trust
accounts.
Issues in handling this (issues with lifetime of talloc pointers)
caused me to change the 'creds_CredentialsState' and 'struct
dcerpc_binding' pointers to always be talloc()ed pointers.
In the schannel DB, we now store both the domain and computername, and
query on both. This should ensure we fault correctly when the domain
is specified incorrectly in the SCHANNEL bind.
In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out,
where the comment claimed we re-used a connection, but in fact we made
a new connection.
This was achived by breaking apart some of the
dcerpc_secondary_connection() logic.
The addition of workstation handling was also propogated to NTLMSSP
and GENSEC, for completeness.
The RPC-SAMSYNC test has been cleaned up a little, using a loop over
usernames/passwords rather than manually expanded tests. This will be
expanded further (the code in #if 0 in this patch) to use a newly
created user account for testing.
In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO
server, caused by the removal of [ref] and the assoicated pointer from
the IDL. This has been re-added, until the underlying pidl issues are
solved.
(This used to be commit 824289dcc20908ddec957a4a892a103eec2da9b9)
2005-03-19 11:34:43 +03:00
struct dcerpc_binding * binding_struct ;
2004-10-18 19:33:34 +04:00
NTSTATUS status ;
status = dcerpc_parse_binding ( mem_ctx , binding_string , & binding_struct ) ;
2005-01-27 10:08:20 +03:00
talloc_free ( mem_ctx ) ;
2004-10-18 19:33:34 +04:00
return NT_STATUS_IS_OK ( status ) ;
}
2005-06-12 05:28:20 +04:00
static void max_runtime_handler ( int sig )
{
DEBUG ( 0 , ( " maximum runtime exceeded for smbtorture - terminating \n " ) ) ;
exit ( 1 ) ;
}
2003-08-13 05:53:07 +04:00
/****************************************************************************
main program
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int main ( int argc , char * argv [ ] )
{
int opt , i ;
char * p ;
BOOL correct = True ;
2005-06-12 05:28:20 +04:00
int max_runtime = 0 ;
2004-08-25 18:31:59 +04:00
int argc_new ;
char * * argv_new ;
poptContext pc ;
2004-09-10 06:16:41 +04:00
enum { OPT_LOADFILE = 1000 , OPT_UNCLIST , OPT_TIMELIMIT , OPT_DNS , OPT_DANGEROUS } ;
2004-08-25 18:31:59 +04:00
struct poptOption long_options [ ] = {
POPT_AUTOHELP
{ " smb-ports " , ' p ' , POPT_ARG_STRING , NULL , 0 , " SMB ports " , NULL } ,
2004-10-30 08:59:52 +04:00
{ " seed " , 0 , POPT_ARG_INT , & torture_seed , 0 , " seed " , NULL } ,
2004-09-10 07:39:11 +04:00
{ " num-progs " , 0 , POPT_ARG_INT , & torture_nprocs , 0 , " num progs " , NULL } ,
{ " num-ops " , 0 , POPT_ARG_INT , & torture_numops , 0 , " num ops " , NULL } ,
{ " entries " , 0 , POPT_ARG_INT , & torture_entries , 0 , " entries " , NULL } ,
2004-09-10 06:16:41 +04:00
{ " use-oplocks " , ' L ' , POPT_ARG_NONE , & use_oplocks , 0 , " use oplocks " , NULL } ,
2004-09-10 07:39:11 +04:00
{ " show-all " , 0 , POPT_ARG_NONE , & torture_showall , 0 , " show all " , NULL } ,
2004-09-10 06:16:41 +04:00
{ " loadfile " , 0 , POPT_ARG_STRING , NULL , OPT_LOADFILE , " loadfile " , NULL } ,
{ " unclist " , 0 , POPT_ARG_STRING , NULL , OPT_UNCLIST , " unclist " , NULL } ,
{ " timelimit " , ' t ' , POPT_ARG_STRING , NULL , OPT_TIMELIMIT , " timelimit " , NULL } ,
2004-09-10 07:39:11 +04:00
{ " failures " , ' f ' , POPT_ARG_INT , & torture_failures , 0 , " failures " , NULL } ,
2004-09-10 06:16:41 +04:00
{ " parse-dns " , ' D ' , POPT_ARG_STRING , NULL , OPT_DNS , " parse-dns " , NULL } ,
{ " dangerous " , ' X ' , POPT_ARG_NONE , NULL , OPT_DANGEROUS , " dangerous " , NULL } ,
2005-06-12 05:28:20 +04:00
{ " maximum-runtime " , 0 , POPT_ARG_INT , & max_runtime , 0 ,
" set maximum time for smbtorture to live " , " seconds " } ,
2004-08-25 18:31:59 +04:00
POPT_COMMON_SAMBA
POPT_COMMON_CONNECTION
POPT_COMMON_CREDENTIALS
POPT_COMMON_VERSION
POPT_TABLEEND
} ;
2003-08-13 05:53:07 +04:00
# ifdef HAVE_SETBUFFER
setbuffer ( stdout , NULL , 0 ) ;
# endif
2004-08-25 18:31:59 +04:00
pc = poptGetContext ( " smbtorture " , argc , ( const char * * ) argv , long_options ,
2005-03-22 11:00:45 +03:00
POPT_CONTEXT_KEEP_FIRST ) ;
2004-08-25 18:31:59 +04:00
poptSetOtherOptionHelp ( pc , " <binding>|<unc> TEST1 TEST2 ... " ) ;
while ( ( opt = poptGetNextOpt ( pc ) ) ! = - 1 ) {
switch ( opt ) {
2004-09-10 06:16:41 +04:00
case OPT_LOADFILE :
2004-08-25 18:31:59 +04:00
lp_set_cmdline ( " torture:loadfile " , poptGetOptArg ( pc ) ) ;
break ;
2004-09-10 06:16:41 +04:00
case OPT_UNCLIST :
2004-08-25 18:31:59 +04:00
lp_set_cmdline ( " torture:unclist " , poptGetOptArg ( pc ) ) ;
break ;
2004-09-10 06:16:41 +04:00
case OPT_TIMELIMIT :
2004-08-25 18:31:59 +04:00
lp_set_cmdline ( " torture:timelimit " , poptGetOptArg ( pc ) ) ;
break ;
2004-09-10 06:16:41 +04:00
case OPT_DNS :
2004-08-25 18:31:59 +04:00
parse_dns ( poptGetOptArg ( pc ) ) ;
break ;
2004-09-10 06:16:41 +04:00
case OPT_DANGEROUS :
2004-12-31 04:02:22 +03:00
lp_set_cmdline ( " torture:dangerous " , " Yes " ) ;
2004-08-25 18:31:59 +04:00
break ;
default :
d_printf ( " Invalid option %s: %s \n " ,
poptBadOption ( pc , 0 ) , poptStrerror ( opt ) ) ;
usage ( pc ) ;
exit ( 1 ) ;
}
}
2005-06-12 05:28:20 +04:00
if ( max_runtime ) {
/* this will only work if nobody else uses alarm(),
which means it won ' t work for some tests , but we
can ' t use the event context method we use for smbd
as so many tests create their own event
context . This will at least catch most cases . */
signal ( SIGALRM , max_runtime_handler ) ;
alarm ( max_runtime ) ;
}
2004-11-09 12:26:47 +03:00
smbtorture_init_subsystems ;
2004-10-30 08:59:52 +04:00
if ( torture_seed = = 0 ) {
torture_seed = time ( NULL ) ;
}
printf ( " Using seed %d \n " , torture_seed ) ;
srandom ( torture_seed ) ;
2004-08-25 18:31:59 +04:00
2004-10-28 17:40:50 +04:00
argv_new = discard_const_p ( char * , poptGetArgs ( pc ) ) ;
2003-08-13 05:53:07 +04:00
2004-08-25 18:31:59 +04:00
argc_new = argc ;
for ( i = 0 ; i < argc ; i + + ) {
if ( argv_new [ i ] = = NULL ) {
argc_new = i ;
break ;
}
2003-08-13 05:53:07 +04:00
}
2004-08-25 18:31:59 +04:00
if ( argc_new < 3 ) {
usage ( pc ) ;
exit ( 1 ) ;
}
2003-08-13 05:53:07 +04:00
2004-08-25 18:31:59 +04:00
for ( p = argv_new [ 1 ] ; * p ; p + + ) {
if ( * p = = ' \\ ' )
* p = ' / ' ;
}
2003-11-24 16:19:00 +03:00
/* see if its a RPC transport specifier */
2004-10-18 19:33:34 +04:00
if ( is_binding_string ( argv_new [ 1 ] ) ) {
2004-08-25 18:31:59 +04:00
lp_set_cmdline ( " torture:binding " , argv_new [ 1 ] ) ;
2003-11-24 16:19:00 +03:00
} else {
2004-02-04 00:53:51 +03:00
char * binding = NULL ;
2005-01-15 14:58:52 +03:00
const char * host = NULL , * share = NULL ;
2003-11-24 16:19:00 +03:00
2005-01-15 14:58:52 +03:00
if ( ! smbcli_parse_unc ( argv_new [ 1 ] , NULL , & host , & share ) ) {
2004-10-31 02:10:14 +04:00
d_printf ( " Invalid option: %s is not a valid torture target (share or binding string) \n \n " , argv_new [ 1 ] ) ;
2004-08-25 18:31:59 +04:00
usage ( pc ) ;
2003-11-24 16:19:00 +03:00
}
2004-03-09 12:04:06 +03:00
2003-11-24 16:19:00 +03:00
lp_set_cmdline ( " torture:host " , host ) ;
lp_set_cmdline ( " torture:share " , share ) ;
2004-02-04 00:53:51 +03:00
asprintf ( & binding , " ncacn_np:%s " , host ) ;
lp_set_cmdline ( " torture:binding " , binding ) ;
2003-08-13 05:53:07 +04:00
}
2004-08-25 18:31:59 +04:00
if ( argc_new = = 0 ) {
2003-08-13 05:53:07 +04:00
printf ( " You must specify a test to run, or 'ALL' \n " ) ;
} else {
2004-08-25 18:31:59 +04:00
for ( i = 2 ; i < argc_new ; i + + ) {
if ( ! run_test ( argv_new [ i ] ) ) {
2003-08-13 05:53:07 +04:00
correct = False ;
}
}
}
if ( correct ) {
return ( 0 ) ;
} else {
return ( 1 ) ;
}
}