2006-03-17 19:27:22 +03:00
/*
Unix SMB / CIFS implementation .
SMB torture tester
Copyright ( C ) Andrew Tridgell 1997 - 2003
2008-05-23 18:19:00 +04:00
Copyright ( C ) Jelmer Vernooij 2006 - 2008
2006-03-17 19:27:22 +03:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-10 06:07:03 +04:00
the Free Software Foundation ; either version 3 of the License , or
2006-03-17 19:27:22 +03:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 06:07:03 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2006-03-17 19:27:22 +03:00
*/
# include "includes.h"
# include "lib/cmdline/popt_common.h"
# include "system/time.h"
# include "system/wait.h"
# include "system/filesys.h"
2006-10-30 04:19:31 +03:00
# include "system/readline.h"
# include "lib/smbreadline/smbreadline.h"
2006-03-17 19:27:22 +03:00
# include "libcli/libcli.h"
# include "lib/events/events.h"
2008-04-27 17:02:46 +04:00
# include "torture/smbtorture.h"
2006-03-18 18:42:57 +03:00
# include "librpc/rpc/dcerpc.h"
2008-11-03 01:58:49 +03:00
# include "auth/gensec/gensec.h"
2007-09-08 16:42:09 +04:00
# include "param/param.h"
2006-03-17 19:27:22 +03:00
2008-04-14 20:43:37 +04:00
2006-10-16 17:06:41 +04:00
static bool run_matching ( struct torture_context * torture ,
const char * prefix ,
const char * expr ,
struct torture_suite * suite ,
bool * matched )
{
bool ret = true ;
if ( suite = = NULL ) {
2006-10-17 03:09:15 +04:00
struct torture_suite * o ;
2006-10-16 17:06:41 +04:00
2008-12-22 20:53:19 +03:00
for ( o = ( torture_root = = NULL ? NULL : torture_root - > children ) ; o ; o = o - > next ) {
2006-10-17 03:09:15 +04:00
if ( gen_fnmatch ( expr , o - > name ) = = 0 ) {
2006-10-16 17:06:41 +04:00
* matched = true ;
2007-12-14 00:46:09 +03:00
reload_charcnv ( torture - > lp_ctx ) ;
2006-10-17 03:09:15 +04:00
ret & = torture_run_suite ( torture , o ) ;
2006-10-16 17:06:41 +04:00
continue ;
}
2006-10-18 02:06:43 +04:00
ret & = run_matching ( torture , o - > name , expr , o , matched ) ;
2006-10-16 17:06:41 +04:00
}
} else {
char * name ;
struct torture_suite * c ;
struct torture_tcase * t ;
for ( c = suite - > children ; c ; c = c - > next ) {
asprintf ( & name , " %s-%s " , prefix , c - > name ) ;
2006-11-03 01:17:11 +03:00
2006-10-16 17:06:41 +04:00
if ( gen_fnmatch ( expr , name ) = = 0 ) {
* matched = true ;
2007-12-14 00:46:09 +03:00
reload_charcnv ( torture - > lp_ctx ) ;
2006-11-03 01:17:11 +03:00
torture - > active_testname = talloc_strdup ( torture , prefix ) ;
2006-10-16 17:06:41 +04:00
ret & = torture_run_suite ( torture , c ) ;
free ( name ) ;
continue ;
}
ret & = run_matching ( torture , name , expr , c , matched ) ;
free ( name ) ;
}
for ( t = suite - > testcases ; t ; t = t - > next ) {
asprintf ( & name , " %s-%s " , prefix , t - > name ) ;
if ( gen_fnmatch ( expr , name ) = = 0 ) {
* matched = true ;
2007-12-14 00:46:09 +03:00
reload_charcnv ( torture - > lp_ctx ) ;
2006-11-03 01:17:11 +03:00
torture - > active_testname = talloc_strdup ( torture , prefix ) ;
2006-10-16 17:06:41 +04:00
ret & = torture_run_tcase ( torture , t ) ;
2006-11-03 01:17:11 +03:00
talloc_free ( torture - > active_testname ) ;
2006-10-16 17:06:41 +04:00
}
free ( name ) ;
}
}
return ret ;
}
2006-03-17 19:27:22 +03:00
# define MAX_COLS 80 /* FIXME: Determine this at run-time */
/****************************************************************************
run a specified test or " ALL "
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-10-16 17:06:41 +04:00
static bool run_test ( struct torture_context * torture , const char * name )
2006-03-17 19:27:22 +03:00
{
2006-10-16 17:06:41 +04:00
bool ret = true ;
bool matched = false ;
2006-10-17 03:09:15 +04:00
struct torture_suite * o ;
2006-03-17 19:27:22 +03:00
2006-10-16 17:06:41 +04:00
if ( strequal ( name , " ALL " ) ) {
2006-10-17 03:09:15 +04:00
for ( o = torture_root - > children ; o ; o = o - > next ) {
ret & = torture_run_suite ( torture , o ) ;
2006-03-17 19:27:22 +03:00
}
return ret ;
}
2006-10-16 17:06:41 +04:00
ret = run_matching ( torture , NULL , name , NULL , & matched ) ;
2006-03-17 19:27:22 +03:00
if ( ! matched ) {
printf ( " Unknown torture operation '%s' \n " , name ) ;
2006-10-16 17:06:41 +04:00
return false ;
2006-03-17 19:27:22 +03:00
}
return ret ;
}
2007-12-03 02:28:22 +03:00
static bool parse_target ( struct loadparm_context * lp_ctx , const char * target )
{
char * host = NULL , * share = NULL ;
struct dcerpc_binding * binding_struct ;
NTSTATUS status ;
/* see if its a RPC transport specifier */
if ( ! smbcli_parse_unc ( target , NULL , & host , & share ) ) {
status = dcerpc_parse_binding ( talloc_autofree_context ( ) , target , & binding_struct ) ;
if ( NT_STATUS_IS_ERR ( status ) ) {
d_printf ( " Invalid option: %s is not a valid torture target (share or binding string) \n \n " , target ) ;
return false ;
}
lp_set_cmdline ( lp_ctx , " torture:host " , binding_struct - > host ) ;
if ( lp_parm_string ( lp_ctx , NULL , " torture " , " share " ) = = NULL )
lp_set_cmdline ( lp_ctx , " torture:share " , " IPC$ " ) ;
lp_set_cmdline ( lp_ctx , " torture:binding " , target ) ;
} else {
lp_set_cmdline ( lp_ctx , " torture:host " , host ) ;
lp_set_cmdline ( lp_ctx , " torture:share " , share ) ;
lp_set_cmdline ( lp_ctx , " torture:binding " , host ) ;
}
return true ;
}
static void parse_dns ( struct loadparm_context * lp_ctx , const char * dns )
2006-03-17 19:27:22 +03:00
{
char * userdn , * basedn , * secret ;
char * p , * d ;
/* retrievieng the userdn */
p = strchr_m ( dns , ' # ' ) ;
if ( ! p ) {
2007-12-03 02:28:22 +03:00
lp_set_cmdline ( lp_ctx , " torture:ldap_userdn " , " " ) ;
lp_set_cmdline ( lp_ctx , " torture:ldap_basedn " , " " ) ;
lp_set_cmdline ( lp_ctx , " torture:ldap_secret " , " " ) ;
2006-03-17 19:27:22 +03:00
return ;
}
userdn = strndup ( dns , p - dns ) ;
2007-12-03 02:28:22 +03:00
lp_set_cmdline ( lp_ctx , " torture:ldap_userdn " , userdn ) ;
2006-03-17 19:27:22 +03:00
/* retrieve the basedn */
d = p + 1 ;
p = strchr_m ( d , ' # ' ) ;
if ( ! p ) {
2007-12-03 02:28:22 +03:00
lp_set_cmdline ( lp_ctx , " torture:ldap_basedn " , " " ) ;
lp_set_cmdline ( lp_ctx , " torture:ldap_secret " , " " ) ;
2006-03-17 19:27:22 +03:00
return ;
}
basedn = strndup ( d , p - d ) ;
2007-12-03 02:28:22 +03:00
lp_set_cmdline ( lp_ctx , " torture:ldap_basedn " , basedn ) ;
2006-03-17 19:27:22 +03:00
/* retrieve the secret */
p = p + 1 ;
if ( ! p ) {
2007-12-03 02:28:22 +03:00
lp_set_cmdline ( lp_ctx , " torture:ldap_secret " , " " ) ;
2006-03-17 19:27:22 +03:00
return ;
}
secret = strdup ( p ) ;
2007-12-03 02:28:22 +03:00
lp_set_cmdline ( lp_ctx , " torture:ldap_secret " , secret ) ;
2006-03-17 19:27:22 +03:00
printf ( " %s - %s - %s \n " , userdn , basedn , secret ) ;
}
2007-01-26 16:03:28 +03:00
static void print_test_list ( void )
{
struct torture_suite * o ;
struct torture_suite * s ;
struct torture_tcase * t ;
2007-10-06 00:33:55 +04:00
if ( torture_root = = NULL )
return ;
2007-01-26 16:03:28 +03:00
for ( o = torture_root - > children ; o ; o = o - > next ) {
for ( s = o - > children ; s ; s = s - > next ) {
printf ( " %s-%s \n " , o - > name , s - > name ) ;
}
for ( t = o - > testcases ; t ; t = t - > next ) {
printf ( " %s-%s \n " , o - > name , t - > name ) ;
}
}
}
2007-09-07 17:31:15 +04:00
_NORETURN_ static void usage ( poptContext pc )
2006-03-17 19:27:22 +03:00
{
2006-10-17 03:09:15 +04:00
struct torture_suite * o ;
2006-10-16 17:06:41 +04:00
struct torture_suite * s ;
struct torture_tcase * t ;
2006-03-17 19:27:22 +03:00
int i ;
poptPrintUsage ( pc , stdout , 0 ) ;
printf ( " \n " ) ;
printf ( " The binding format is: \n \n " ) ;
printf ( " TRANSPORT:host[flags] \n \n " ) ;
2006-05-27 16:16:48 +04:00
printf ( " where TRANSPORT is either ncacn_np for SMB, ncacn_ip_tcp for RPC/TCP \n " ) ;
printf ( " or ncalrpc for local connections. \n \n " ) ;
2006-03-17 19:27:22 +03:00
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 " ) ;
2006-05-27 16:16:48 +04:00
printf ( " ncalrpc: \n \n " ) ;
2006-04-19 07:06:50 +04:00
printf ( " The UNC format is: \n \n " ) ;
2006-03-17 19:27:22 +03:00
2006-04-19 07:06:50 +04:00
printf ( " //server/share \n \n " ) ;
2006-03-17 19:27:22 +03:00
2006-04-19 07:06:50 +04:00
printf ( " Tests are: " ) ;
2006-03-17 19:27:22 +03:00
2007-08-31 22:35:30 +04:00
if ( torture_root = = NULL ) {
printf ( " NO TESTS LOADED \n " ) ;
exit ( 1 ) ;
}
2006-10-17 03:09:15 +04:00
for ( o = torture_root - > children ; o ; o = o - > next ) {
printf ( " \n %s (%s): \n " , o - > description , o - > name ) ;
2006-10-16 17:06:41 +04:00
i = 0 ;
2006-10-17 03:09:15 +04:00
for ( s = o - > children ; s ; s = s - > next ) {
if ( i + strlen ( o - > name ) + strlen ( s - > name ) > = ( MAX_COLS - 3 ) ) {
2006-10-16 17:06:41 +04:00
printf ( " \n " ) ;
2006-04-19 07:06:50 +04:00
i = 0 ;
}
2006-10-17 03:09:15 +04:00
i + = printf ( " %s-%s " , o - > name , s - > name ) ;
2006-04-19 07:06:50 +04:00
}
2006-10-17 03:09:15 +04:00
for ( t = o - > testcases ; t ; t = t - > next ) {
if ( i + strlen ( o - > name ) + strlen ( t - > name ) > = ( MAX_COLS - 3 ) ) {
2006-10-16 17:06:41 +04:00
printf ( " \n " ) ;
i = 0 ;
}
2006-10-17 03:09:15 +04:00
i + = printf ( " %s-%s " , o - > name , t - > name ) ;
2006-03-17 19:27:22 +03:00
}
2006-10-16 17:06:41 +04:00
if ( i ) printf ( " \n " ) ;
2006-03-17 19:27:22 +03:00
}
2006-10-16 17:06:41 +04:00
printf ( " \n The default test is ALL. \n " ) ;
2006-03-17 19:27:22 +03:00
exit ( 1 ) ;
}
2007-09-07 17:31:15 +04:00
_NORETURN_ static void max_runtime_handler ( int sig )
2006-03-17 19:27:22 +03:00
{
DEBUG ( 0 , ( " maximum runtime exceeded for smbtorture - terminating \n " ) ) ;
exit ( 1 ) ;
}
2006-06-17 04:17:50 +04:00
struct timeval last_suite_started ;
static void simple_suite_start ( struct torture_context * ctx ,
2007-10-05 12:51:26 +04:00
struct torture_suite * suite )
2006-03-25 22:12:08 +03:00
{
2006-06-17 04:17:50 +04:00
last_suite_started = timeval_current ( ) ;
printf ( " Running %s \n " , suite - > name ) ;
2006-03-25 22:12:08 +03:00
}
2006-06-17 04:17:50 +04:00
static void simple_suite_finish ( struct torture_context * ctx ,
2007-10-05 12:51:26 +04:00
struct torture_suite * suite )
2006-06-17 02:06:09 +04:00
{
2006-06-17 04:17:50 +04:00
printf ( " %s took %g secs \n \n " , suite - > name ,
timeval_elapsed ( & last_suite_started ) ) ;
2006-06-17 02:06:09 +04:00
}
2007-10-05 12:51:26 +04:00
static void simple_test_result ( struct torture_context * context ,
enum torture_result res , const char * reason )
2006-03-25 22:12:08 +03:00
{
2006-06-13 03:03:02 +04:00
switch ( res ) {
case TORTURE_OK :
if ( reason )
printf ( " OK: %s \n " , reason ) ;
break ;
case TORTURE_FAIL :
2006-06-17 04:17:50 +04:00
printf ( " TEST %s FAILED! - %s \n " , context - > active_test - > name , reason ) ;
2006-06-13 03:03:02 +04:00
break ;
2006-10-17 23:36:55 +04:00
case TORTURE_ERROR :
printf ( " ERROR IN TEST %s! - %s \n " , context - > active_test - > name , reason ) ;
break ;
2006-06-13 03:03:02 +04:00
case TORTURE_SKIP :
2006-06-17 02:06:09 +04:00
printf ( " SKIP: %s - %s \n " , context - > active_test - > name , reason ) ;
2006-06-13 03:03:02 +04:00
break ;
}
2006-03-25 22:12:08 +03:00
}
2007-10-05 12:51:26 +04:00
static void simple_comment ( struct torture_context * test ,
const char * comment )
2006-03-25 22:12:08 +03:00
{
2006-10-16 17:06:41 +04:00
printf ( " %s " , comment ) ;
2006-03-25 22:12:08 +03:00
}
2007-03-06 00:28:55 +03:00
static void simple_warning ( struct torture_context * test ,
2007-10-05 12:51:26 +04:00
const char * comment )
2007-03-06 00:28:55 +03:00
{
fprintf ( stderr , " WARNING: %s \n " , comment ) ;
}
2006-03-25 22:12:08 +03:00
const static struct torture_ui_ops std_ui_ops = {
. comment = simple_comment ,
2007-03-06 00:28:55 +03:00
. warning = simple_warning ,
2006-06-17 04:17:50 +04:00
. suite_start = simple_suite_start ,
. suite_finish = simple_suite_finish ,
2006-03-25 22:12:08 +03:00
. test_result = simple_test_result
} ;
2006-06-12 16:24:33 +04:00
2008-10-20 20:59:51 +04:00
static void run_shell ( struct torture_context * tctx )
2006-10-30 04:19:31 +03:00
{
char * cline ;
int argc ;
2006-11-03 00:41:50 +03:00
const char * * argv ;
2006-10-30 04:19:31 +03:00
int ret ;
while ( 1 ) {
cline = smb_readline ( " torture> " , NULL , NULL ) ;
if ( cline = = NULL )
return ;
ret = poptParseArgvString ( cline , & argc , & argv ) ;
if ( ret ! = 0 ) {
fprintf ( stderr , " Error parsing line \n " ) ;
continue ;
}
if ( ! strcmp ( argv [ 0 ] , " quit " ) ) {
return ;
} else if ( ! strcmp ( argv [ 0 ] , " set " ) ) {
if ( argc < 3 ) {
fprintf ( stderr , " Usage: set <variable> <value> \n " ) ;
} else {
char * name = talloc_asprintf ( NULL , " torture:%s " , argv [ 1 ] ) ;
2007-12-03 04:58:12 +03:00
lp_set_cmdline ( tctx - > lp_ctx , name , argv [ 2 ] ) ;
2006-10-30 04:19:31 +03:00
talloc_free ( name ) ;
}
} else if ( ! strcmp ( argv [ 0 ] , " help " ) ) {
fprintf ( stderr , " Available commands: \n "
" help - This help command \n "
" run - Run test \n "
" set - Change variables \n "
" \n " ) ;
} else if ( ! strcmp ( argv [ 0 ] , " run " ) ) {
if ( argc < 2 ) {
fprintf ( stderr , " Usage: run TEST-NAME [OPTIONS...] \n " ) ;
} else {
run_test ( tctx , argv [ 1 ] ) ;
}
}
2007-12-14 16:04:56 +03:00
free ( cline ) ;
2006-10-30 04:19:31 +03:00
}
}
2006-06-17 03:10:15 +04:00
2006-03-17 19:27:22 +03:00
/****************************************************************************
main program
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-10-30 04:19:31 +03:00
int main ( int argc , char * argv [ ] )
2006-03-17 19:27:22 +03:00
{
int opt , i ;
2006-10-16 17:06:41 +04:00
bool correct = true ;
2006-03-17 19:27:22 +03:00
int max_runtime = 0 ;
int argc_new ;
2006-03-25 22:12:08 +03:00
struct torture_context * torture ;
2008-11-01 02:24:55 +03:00
struct torture_results * results ;
2006-10-18 02:06:43 +04:00
const struct torture_ui_ops * ui_ops ;
2006-03-17 19:27:22 +03:00
char * * argv_new ;
poptContext pc ;
2007-12-20 02:02:15 +03:00
static const char * target = " other " ;
2006-11-24 18:50:18 +03:00
NTSTATUS status ;
2007-10-07 02:28:14 +04:00
int shell = false ;
2009-06-13 18:14:39 +04:00
static const char * ui_ops_name = " subunit " ;
2007-08-28 18:42:37 +04:00
const char * basedir = NULL ;
2007-08-31 22:35:30 +04:00
const char * extra_module = NULL ;
2007-12-20 02:02:15 +03:00
static int list_tests = 0 ;
2008-05-14 11:47:18 +04:00
int num_extra_users = 0 ;
2007-01-26 16:03:28 +03:00
enum { OPT_LOADFILE = 1000 , OPT_UNCLIST , OPT_TIMELIMIT , OPT_DNS , OPT_LIST ,
2009-10-03 04:02:20 +04:00
OPT_DANGEROUS , OPT_SMB_PORTS , OPT_ASYNC , OPT_NUMPROGS ,
OPT_EXTRA_USER , } ;
2006-03-17 19:27:22 +03:00
struct poptOption long_options [ ] = {
POPT_AUTOHELP
2007-08-28 04:16:58 +04:00
{ " format " , 0 , POPT_ARG_STRING , & ui_ops_name , 0 , " Output format (one of: simple, subunit) " , NULL } ,
2006-03-17 19:27:22 +03:00
{ " smb-ports " , ' p ' , POPT_ARG_STRING , NULL , OPT_SMB_PORTS , " SMB ports " , NULL } ,
2007-08-28 18:42:37 +04:00
{ " basedir " , 0 , POPT_ARG_STRING , & basedir , 0 , " base directory " , " BASEDIR " } ,
2007-11-12 01:36:57 +03:00
{ " seed " , 0 , POPT_ARG_INT , & torture_seed , 0 , " Seed to use for randomizer " , NULL } ,
2006-11-05 07:28:45 +03:00
{ " num-progs " , 0 , POPT_ARG_INT , NULL , OPT_NUMPROGS , " num progs " , NULL } ,
2006-03-17 19:27:22 +03:00
{ " num-ops " , 0 , POPT_ARG_INT , & torture_numops , 0 , " num ops " , NULL } ,
{ " entries " , 0 , POPT_ARG_INT , & torture_entries , 0 , " entries " , NULL } ,
2007-11-12 01:36:57 +03:00
{ " loadfile " , 0 , POPT_ARG_STRING , NULL , OPT_LOADFILE , " NBench load file to use " , NULL } ,
{ " list " , 0 , POPT_ARG_NONE , & list_tests , 0 , " List available tests and exit " , NULL } ,
2006-03-17 19:27:22 +03:00
{ " unclist " , 0 , POPT_ARG_STRING , NULL , OPT_UNCLIST , " unclist " , NULL } ,
2007-11-12 01:36:57 +03:00
{ " timelimit " , ' t ' , POPT_ARG_INT , NULL , OPT_TIMELIMIT , " Set time limit (in seconds) " , NULL } ,
2006-03-17 19:27:22 +03:00
{ " failures " , ' f ' , POPT_ARG_INT , & torture_failures , 0 , " failures " , NULL } ,
{ " parse-dns " , ' D ' , POPT_ARG_STRING , NULL , OPT_DNS , " parse-dns " , NULL } ,
2006-05-05 13:52:12 +04:00
{ " dangerous " , ' X ' , POPT_ARG_NONE , NULL , OPT_DANGEROUS ,
" run dangerous tests (eg. wiping out password database) " , NULL } ,
2007-08-31 22:35:30 +04:00
{ " load-module " , 0 , POPT_ARG_STRING , & extra_module , 0 , " load tests from DSO file " , " SOFILE " } ,
2007-10-07 02:28:14 +04:00
{ " shell " , 0 , POPT_ARG_NONE , & shell , true , " Run shell " , NULL } ,
2006-09-12 11:35:04 +04:00
{ " target " , ' T ' , POPT_ARG_STRING , & target , 0 , " samba3|samba4|other " , NULL } ,
2006-05-05 13:52:12 +04:00
{ " async " , ' a ' , POPT_ARG_NONE , NULL , OPT_ASYNC ,
" run async tests " , NULL } ,
{ " num-async " , 0 , POPT_ARG_INT , & torture_numasync , 0 ,
" number of simultaneous async requests " , NULL } ,
2006-03-17 19:27:22 +03:00
{ " maximum-runtime " , 0 , POPT_ARG_INT , & max_runtime , 0 ,
" set maximum time for smbtorture to live " , " seconds " } ,
2008-05-14 11:47:18 +04:00
{ " extra-user " , 0 , POPT_ARG_STRING , NULL , OPT_EXTRA_USER ,
" extra user credentials " , NULL } ,
2006-03-17 19:27:22 +03:00
POPT_COMMON_SAMBA
POPT_COMMON_CONNECTION
POPT_COMMON_CREDENTIALS
POPT_COMMON_VERSION
2006-09-06 16:28:01 +04:00
{ NULL }
2006-03-17 19:27:22 +03:00
} ;
2006-09-10 18:19:38 +04:00
setlinebuf ( stdout ) ;
2006-03-17 19:27:22 +03:00
/* we are never interested in SIGPIPE */
2006-10-30 14:34:59 +03:00
BlockSignals ( true , SIGPIPE ) ;
2006-03-17 19:27:22 +03:00
pc = poptGetContext ( " smbtorture " , argc , ( const char * * ) argv , long_options ,
POPT_CONTEXT_KEEP_FIRST ) ;
poptSetOtherOptionHelp ( pc , " <binding>|<unc> TEST1 TEST2 ... " ) ;
while ( ( opt = poptGetNextOpt ( pc ) ) ! = - 1 ) {
switch ( opt ) {
case OPT_LOADFILE :
2007-12-10 06:33:16 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:loadfile " , poptGetOptArg ( pc ) ) ;
2006-03-17 19:27:22 +03:00
break ;
case OPT_UNCLIST :
2007-12-10 06:33:16 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:unclist " , poptGetOptArg ( pc ) ) ;
2006-03-17 19:27:22 +03:00
break ;
case OPT_TIMELIMIT :
2007-12-10 06:33:16 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:timelimit " , poptGetOptArg ( pc ) ) ;
2006-03-17 19:27:22 +03:00
break ;
2006-11-05 07:28:45 +03:00
case OPT_NUMPROGS :
2007-12-10 06:33:16 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:nprocs " , poptGetOptArg ( pc ) ) ;
2006-11-05 07:28:45 +03:00
break ;
2006-03-17 19:27:22 +03:00
case OPT_DNS :
2007-12-10 06:33:16 +03:00
parse_dns ( cmdline_lp_ctx , poptGetOptArg ( pc ) ) ;
2006-03-17 19:27:22 +03:00
break ;
case OPT_DANGEROUS :
2007-12-10 06:33:16 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:dangerous " , " Yes " ) ;
2006-03-17 19:27:22 +03:00
break ;
2006-05-05 13:52:12 +04:00
case OPT_ASYNC :
2007-12-10 06:33:16 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:async " , " Yes " ) ;
2006-05-05 13:52:12 +04:00
break ;
2006-03-17 19:27:22 +03:00
case OPT_SMB_PORTS :
2007-12-10 06:33:16 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " smb ports " , poptGetOptArg ( pc ) ) ;
2006-03-17 19:27:22 +03:00
break ;
2008-05-14 11:47:18 +04:00
case OPT_EXTRA_USER :
{
char * option = talloc_asprintf ( NULL , " torture:extra_user%u " ,
+ + num_extra_users ) ;
2009-10-18 00:39:15 +04:00
const char * value = poptGetOptArg ( pc ) ;
2008-05-14 11:47:18 +04:00
lp_set_cmdline ( cmdline_lp_ctx , option , value ) ;
talloc_free ( option ) ;
}
break ;
2009-10-15 11:27:57 +04:00
default :
printf ( " bad command line option \n " ) ;
exit ( 1 ) ;
2006-03-17 19:27:22 +03:00
}
}
2006-10-17 16:06:20 +04:00
if ( strcmp ( target , " samba3 " ) = = 0 ) {
2007-12-10 06:33:16 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:samba3 " , " true " ) ;
2009-11-18 03:29:23 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:resume_key_support " , " false " ) ;
2006-10-17 16:06:20 +04:00
} else if ( strcmp ( target , " samba4 " ) = = 0 ) {
2007-12-10 06:33:16 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:samba4 " , " true " ) ;
2009-12-02 03:27:10 +03:00
} else if ( strcmp ( target , " winxp " ) = = 0 ) {
lp_set_cmdline ( cmdline_lp_ctx , " torture:winxp " , " true " ) ;
} else if ( strcmp ( target , " w2k3 " ) = = 0 ) {
lp_set_cmdline ( cmdline_lp_ctx , " torture:w2k3 " , " true " ) ;
2009-07-06 17:36:03 +04:00
} else if ( strcmp ( target , " w2k8 " ) = = 0 ) {
lp_set_cmdline ( cmdline_lp_ctx , " torture:w2k8 " , " true " ) ;
2009-11-14 02:13:19 +03:00
lp_set_cmdline ( cmdline_lp_ctx ,
" torture:invalid_lock_range_support " , " false " ) ;
2009-02-10 08:58:50 +03:00
} else if ( strcmp ( target , " win7 " ) = = 0 ) {
lp_set_cmdline ( cmdline_lp_ctx , " torture:win7 " , " true " ) ;
2009-11-18 02:30:11 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:cn_max_buffer_size " ,
2009-11-25 03:58:25 +03:00
" 0x00010000 " ) ;
2009-11-18 03:29:23 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:resume_key_support " , " false " ) ;
lp_set_cmdline ( cmdline_lp_ctx , " torture:rewind_support " , " false " ) ;
/* RAW-SEARCH for fails for inexplicable reasons against win7 */
lp_set_cmdline ( cmdline_lp_ctx , " torture:search_ea_support " , " false " ) ;
2009-12-05 03:07:35 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:hide_on_access_denied " ,
" true " ) ;
2009-10-03 04:02:20 +04:00
} else if ( strcmp ( target , " onefs " ) = = 0 ) {
2009-11-25 03:58:25 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:onefs " , " true " ) ;
lp_set_cmdline ( cmdline_lp_ctx , " torture:openx_deny_dos_support " ,
" false " ) ;
2010-01-11 03:06:57 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:range_not_locked_on_file_close " , " false " ) ;
2009-10-03 04:02:20 +04:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:sacl_support " , " false " ) ;
2009-11-18 03:29:23 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:ea_support " , " false " ) ;
2010-01-11 03:06:57 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:smbexit_pdu_support " ,
" false " ) ;
2009-11-25 03:58:25 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:smblock_pdu_support " ,
" false " ) ;
2009-12-02 02:29:00 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:2_step_break_to_none " ,
" true " ) ;
2009-11-09 21:32:06 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:deny_dos_support " , " false " ) ;
lp_set_cmdline ( cmdline_lp_ctx , " torture:deny_fcb_support " , " false " ) ;
2009-11-17 00:13:26 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:read_support " , " false " ) ;
2009-11-18 03:29:21 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:writeclose_support " , " false " ) ;
2009-11-18 03:29:23 +03:00
lp_set_cmdline ( cmdline_lp_ctx , " torture:resume_key_support " , " false " ) ;
lp_set_cmdline ( cmdline_lp_ctx , " torture:rewind_support " , " false " ) ;
2006-10-17 16:06:20 +04:00
}
2006-03-17 19:27:22 +03: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 ) ;
}
2007-08-31 22:35:30 +04:00
if ( extra_module ! = NULL ) {
init_module_fn fn = load_module ( talloc_autofree_context ( ) , poptGetOptArg ( pc ) ) ;
if ( fn = = NULL )
d_printf ( " Unable to load module from %s \n " , poptGetOptArg ( pc ) ) ;
else {
status = fn ( ) ;
if ( NT_STATUS_IS_ERR ( status ) ) {
d_printf ( " Error initializing module %s: %s \n " ,
poptGetOptArg ( pc ) , nt_errstr ( status ) ) ;
}
}
} else {
torture_init ( ) ;
}
2007-01-26 16:03:28 +03:00
if ( list_tests ) {
print_test_list ( ) ;
return 0 ;
}
2006-03-17 19:27:22 +03:00
if ( torture_seed = = 0 ) {
torture_seed = time ( NULL ) ;
}
printf ( " Using seed %d \n " , torture_seed ) ;
srandom ( torture_seed ) ;
argv_new = discard_const_p ( char * , poptGetArgs ( pc ) ) ;
argc_new = argc ;
for ( i = 0 ; i < argc ; i + + ) {
if ( argv_new [ i ] = = NULL ) {
argc_new = i ;
break ;
}
}
2006-10-30 04:19:31 +03:00
if ( ! ( argc_new > = 3 | | ( shell & & argc_new > = 2 ) ) ) {
2006-03-17 19:27:22 +03:00
usage ( pc ) ;
exit ( 1 ) ;
}
2007-12-10 06:33:16 +03:00
if ( ! parse_target ( cmdline_lp_ctx , argv_new [ 1 ] ) ) {
2007-12-03 02:28:22 +03:00
usage ( pc ) ;
exit ( 1 ) ;
2006-03-17 19:27:22 +03:00
}
2006-06-12 16:24:33 +04:00
if ( ! strcmp ( ui_ops_name , " simple " ) ) {
2006-10-18 02:06:43 +04:00
ui_ops = & std_ui_ops ;
2006-06-12 16:24:33 +04:00
} else if ( ! strcmp ( ui_ops_name , " subunit " ) ) {
2008-10-23 23:30:41 +04:00
ui_ops = & torture_subunit_ui_ops ;
2006-06-12 16:24:33 +04:00
} else {
printf ( " Unknown output format '%s' \n " , ui_ops_name ) ;
exit ( 1 ) ;
}
2006-03-25 22:12:08 +03:00
2008-11-01 02:24:55 +03:00
results = torture_results_init ( talloc_autofree_context ( ) , ui_ops ) ;
torture = torture_context_init ( s4_event_context_init ( NULL ) , results ) ;
2007-09-02 20:12:49 +04:00
if ( basedir ! = NULL ) {
if ( basedir [ 0 ] ! = ' / ' ) {
fprintf ( stderr , " Please specify an absolute path to --basedir \n " ) ;
return 1 ;
}
torture - > outputdir = basedir ;
} else {
char * pwd = talloc_size ( torture , PATH_MAX ) ;
if ( ! getcwd ( pwd , PATH_MAX ) ) {
fprintf ( stderr , " Unable to determine current working directory \n " ) ;
return 1 ;
}
torture - > outputdir = pwd ;
}
2006-10-18 02:06:43 +04:00
2007-12-10 06:33:16 +03:00
torture - > lp_ctx = cmdline_lp_ctx ;
2007-12-03 02:28:22 +03:00
2008-11-03 01:58:49 +03:00
gensec_init ( cmdline_lp_ctx ) ;
2006-03-17 19:27:22 +03:00
if ( argc_new = = 0 ) {
printf ( " You must specify a test to run, or 'ALL' \n " ) ;
2006-10-30 04:19:31 +03:00
} else if ( shell ) {
run_shell ( torture ) ;
2006-03-17 19:27:22 +03:00
} else {
for ( i = 2 ; i < argc_new ; i + + ) {
2007-01-14 08:06:50 +03:00
if ( ! run_test ( torture , argv_new [ i ] ) ) {
2006-10-16 17:06:41 +04:00
correct = false ;
2006-03-17 19:27:22 +03:00
}
}
}
2008-11-01 02:24:55 +03:00
if ( torture - > results - > returncode & & correct ) {
2006-03-17 19:27:22 +03:00
return ( 0 ) ;
} else {
return ( 1 ) ;
}
}