2010-03-20 07:24:15 +03:00
/*
Unix SMB / CIFS implementation .
SMB torture tester
Copyright ( C ) Andrew Tridgell 1997 - 2003
Copyright ( C ) Jelmer Vernooij 2006 - 2008
2010-03-20 08:04:08 +03:00
Copyright ( C ) James Peach 2010
2010-03-20 07:24:15 +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
the Free Software Foundation ; either version 3 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 , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
# include "system/readline.h"
2010-10-01 12:34:14 +04:00
# include "../libcli/smbreadline/smbreadline.h"
2010-03-22 07:56:05 +03:00
# include "lib/cmdline/popt_common.h"
# include "auth/credentials/credentials.h"
2010-03-20 07:24:15 +03:00
# include "torture/smbtorture.h"
2010-06-22 01:11:58 +04:00
# include "param/param.h"
2010-03-20 07:24:15 +03:00
2010-03-20 08:04:08 +03:00
struct shell_command ;
typedef void ( * shell_function ) ( const struct shell_command * ,
struct torture_context * , int , const char * * ) ;
static void shell_quit ( const struct shell_command * ,
struct torture_context * , int , const char * * ) ;
static void shell_help ( const struct shell_command * ,
struct torture_context * , int , const char * * ) ;
static void shell_set ( const struct shell_command * ,
struct torture_context * , int , const char * * ) ;
static void shell_run ( const struct shell_command * ,
struct torture_context * , int , const char * * ) ;
static void shell_list ( const struct shell_command * ,
struct torture_context * , int , const char * * ) ;
2010-03-22 07:56:05 +03:00
static void shell_auth ( const struct shell_command * ,
struct torture_context * , int , const char * * ) ;
2010-03-23 07:55:49 +03:00
static void shell_target ( const struct shell_command * ,
struct torture_context * , int , const char * * ) ;
2010-03-20 08:04:08 +03:00
static void shell_usage ( const struct shell_command * ) ;
static bool match_command ( const char * , const struct shell_command * ) ;
struct shell_command
{
shell_function handler ;
const char * name ;
const char * usage ;
const char * help ;
} shell_command ;
static const struct shell_command commands [ ] =
{
{
2010-03-22 08:04:37 +03:00
shell_auth , " auth " ,
" [[username | principal | domain | realm | password] STRING] " ,
" set authentication parameters "
2010-03-20 08:04:08 +03:00
} ,
{
2010-03-22 08:04:37 +03:00
shell_help , " help " , NULL ,
" print this help message "
2010-03-20 08:04:08 +03:00
} ,
{
shell_list , " list " , NULL ,
" list the available tests "
} ,
{
2010-03-22 08:04:37 +03:00
shell_quit , " quit " , NULL ,
" exit smbtorture "
2010-03-20 08:04:08 +03:00
} ,
{
shell_run , " run " , " [TESTNAME] " ,
" run the specified test "
2010-03-22 07:56:05 +03:00
} ,
{
2010-03-22 08:04:37 +03:00
shell_set , " set " , " [NAME VALUE] " ,
" print or set test configuration parameters "
2010-03-23 07:55:49 +03:00
} ,
{
shell_target , " target " , " [TARGET] " ,
" print or set the test target "
2010-03-20 08:04:08 +03:00
}
2010-03-22 08:04:37 +03:00
2010-03-20 08:04:08 +03:00
} ;
2010-03-20 07:24:15 +03:00
void torture_shell ( struct torture_context * tctx )
{
char * cline ;
int argc ;
const char * * argv ;
int ret ;
2010-03-20 08:04:08 +03:00
int i ;
2010-03-20 07:24:15 +03:00
2010-03-22 07:56:05 +03:00
/* If we don't have a specified password, specify it as empty. This
* stops the credentials system prompting when we use the " auth "
* command to display the current auth parameters .
*/
2017-05-10 02:10:03 +03:00
cli_credentials_set_password ( popt_get_cmdline_credentials ( ) ,
" " , CRED_GUESS_ENV ) ;
2010-03-22 07:56:05 +03:00
2010-03-20 07:24:15 +03:00
while ( 1 ) {
cline = smb_readline ( " torture> " , NULL , NULL ) ;
if ( cline = = NULL )
return ;
2018-11-21 13:38:24 +03:00
# ifdef HAVE_ADD_HISTORY
2010-03-20 07:24:15 +03:00
add_history ( cline ) ;
# endif
ret = poptParseArgvString ( cline , & argc , & argv ) ;
if ( ret ! = 0 ) {
fprintf ( stderr , " Error parsing line \n " ) ;
continue ;
}
2010-03-20 08:04:08 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( commands ) ; i + + ) {
if ( match_command ( argv [ 0 ] , & commands [ i ] ) ) {
argc - - ;
argv + + ;
commands [ i ] . handler ( & commands [ i ] ,
tctx , argc , argv ) ;
break ;
2010-03-20 07:24:15 +03:00
}
}
2010-03-20 08:04:08 +03:00
2010-03-20 07:24:15 +03:00
free ( cline ) ;
}
}
2010-03-20 08:04:08 +03:00
static void shell_quit ( const struct shell_command * command ,
struct torture_context * tctx , int argc , const char * * argv )
{
exit ( 0 ) ;
}
static void shell_help ( const struct shell_command * command ,
struct torture_context * tctx , int argc , const char * * argv )
{
int i ;
2010-03-22 08:04:37 +03:00
if ( argc = = 1 ) {
for ( i = 0 ; i < ARRAY_SIZE ( commands ) ; i + + ) {
if ( match_command ( argv [ 0 ] , & commands [ i ] ) ) {
shell_usage ( & commands [ i ] ) ;
return ;
}
}
} else {
fprintf ( stdout , " Available commands: \n " ) ;
for ( i = 0 ; i < ARRAY_SIZE ( commands ) ; i + + ) {
fprintf ( stdout , " \t %s - %s \n " ,
commands [ i ] . name , commands [ i ] . help ) ;
}
2010-03-20 08:04:08 +03:00
}
}
static void shell_set ( const struct shell_command * command ,
struct torture_context * tctx , int argc , const char * * argv )
{
switch ( argc ) {
case 0 :
2010-07-16 08:32:42 +04:00
lpcfg_dump ( tctx - > lp_ctx , stdout ,
2010-03-20 08:04:08 +03:00
false /* show_defaults */ ,
0 /* skip services */ ) ;
break ;
case 2 :
2010-07-16 22:07:31 +04:00
/* We want to allow users to set any config option. Top level
* options will get checked against their static definition , but
* parametric options can ' t be checked and will just get stashed
* as they are provided .
*/
lpcfg_set_cmdline ( tctx - > lp_ctx , argv [ 0 ] , argv [ 1 ] ) ;
2010-03-20 08:04:08 +03:00
break ;
default :
shell_usage ( command ) ;
}
}
static void shell_run ( const struct shell_command * command ,
struct torture_context * tctx , int argc , const char * * argv )
{
if ( argc ! = 1 ) {
shell_usage ( command ) ;
return ;
}
torture_run_named_tests ( tctx , argv [ 0 ] , NULL /* restricted */ ) ;
}
static void shell_list ( const struct shell_command * command ,
struct torture_context * tctx , int argc , const char * * argv )
{
if ( argc ! = 0 ) {
shell_usage ( command ) ;
return ;
}
2010-12-09 18:57:45 +03:00
torture_print_testsuites ( true ) ;
2010-03-20 08:04:08 +03:00
}
2010-03-22 07:56:05 +03:00
static void shell_auth ( const struct shell_command * command ,
struct torture_context * tctx , int argc , const char * * argv )
{
if ( argc = = 0 ) {
const char * username ;
const char * domain ;
const char * realm ;
const char * password ;
const char * principal ;
2017-05-10 02:10:03 +03:00
username = cli_credentials_get_username (
popt_get_cmdline_credentials ( ) ) ;
principal = cli_credentials_get_principal (
popt_get_cmdline_credentials ( ) , tctx ) ;
domain = cli_credentials_get_domain ( popt_get_cmdline_credentials ( ) ) ;
realm = cli_credentials_get_realm ( popt_get_cmdline_credentials ( ) ) ;
password = cli_credentials_get_password (
popt_get_cmdline_credentials ( ) ) ;
2010-03-22 07:56:05 +03:00
printf ( " Username: %s \n " , username ? username : " " ) ;
printf ( " User Principal: %s \n " , principal ? principal : " " ) ;
printf ( " Domain: %s \n " , domain ? domain : " " ) ;
printf ( " Realm: %s \n " , realm ? realm : " " ) ;
printf ( " Password: %s \n " , password ? password : " " ) ;
} else if ( argc = = 2 ) {
bool result ;
if ( ! strcmp ( argv [ 0 ] , " username " ) ) {
result = cli_credentials_set_username (
2017-05-10 02:10:03 +03:00
popt_get_cmdline_credentials ( ) ,
argv [ 1 ] , CRED_SPECIFIED ) ;
2010-03-22 07:56:05 +03:00
} else if ( ! strcmp ( argv [ 0 ] , " principal " ) ) {
result = cli_credentials_set_principal (
2017-05-10 02:10:03 +03:00
popt_get_cmdline_credentials ( ) ,
argv [ 1 ] , CRED_SPECIFIED ) ;
2010-03-22 07:56:05 +03:00
} else if ( ! strcmp ( argv [ 0 ] , " domain " ) ) {
result = cli_credentials_set_domain (
2017-05-10 02:10:03 +03:00
popt_get_cmdline_credentials ( ) ,
argv [ 1 ] , CRED_SPECIFIED ) ;
2010-03-22 07:56:05 +03:00
} else if ( ! strcmp ( argv [ 0 ] , " realm " ) ) {
result = cli_credentials_set_realm (
2017-05-10 02:10:03 +03:00
popt_get_cmdline_credentials ( ) ,
argv [ 1 ] , CRED_SPECIFIED ) ;
2010-03-22 07:56:05 +03:00
} else if ( ! strcmp ( argv [ 0 ] , " password " ) ) {
result = cli_credentials_set_password (
2017-05-10 02:10:03 +03:00
popt_get_cmdline_credentials ( ) ,
argv [ 1 ] , CRED_SPECIFIED ) ;
2010-03-22 07:56:05 +03:00
} else {
shell_usage ( command ) ;
return ;
}
if ( ! result ) {
printf ( " failed to set %s \n " , argv [ 0 ] ) ;
}
} else {
shell_usage ( command ) ;
}
}
2010-03-23 07:55:49 +03:00
static void shell_target ( const struct shell_command * command ,
struct torture_context * tctx , int argc , const char * * argv )
{
if ( argc = = 0 ) {
const char * host ;
const char * share ;
const char * binding ;
host = torture_setting_string ( tctx , " host " , NULL ) ;
share = torture_setting_string ( tctx , " share " , NULL ) ;
binding = torture_setting_string ( tctx , " binding " , NULL ) ;
printf ( " Target host: %s \n " , host ? host : " " ) ;
printf ( " Target share: %s \n " , share ? share : " " ) ;
printf ( " Target binding: %s \n " , binding ? binding : " " ) ;
} else if ( argc = = 1 ) {
2017-04-25 02:00:17 +03:00
torture_parse_target ( tctx , tctx - > lp_ctx , argv [ 0 ] ) ;
2010-03-23 07:55:49 +03:00
} else {
shell_usage ( command ) ;
}
}
2010-03-20 08:04:08 +03:00
static void shell_usage ( const struct shell_command * command )
{
if ( command - > usage ) {
fprintf ( stderr , " Usage: %s %s \n " ,
command - > name , command - > usage ) ;
} else {
fprintf ( stderr , " Usage: %s \n " ,
command - > name ) ;
}
}
static bool match_command ( const char * name ,
const struct shell_command * command )
{
if ( ! strcmp ( name , command - > name ) ) {
return true ;
}
if ( name [ 0 ] = = command - > name [ 0 ] & & name [ 1 ] = = ' \0 ' ) {
return true ;
}
return false ;
}