From 74d539f5573a3ed3ff1b96c54752a389da4c3e14 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 17 Nov 1998 16:19:04 +0000 Subject: - group database API. oops and oh dear, the threat has been carried out: the pre-alpha "domain group" etc parameters have disappeared. - interactive debug detection - re-added mem_man (andrew's memory management, detects memory corruption) - american spellings of "initialise" replaced with english spelling of "initialise". - started on "lookup_name()" and "lookup_sid()" functions. proper ones. - moved lots of functions around. created some modules of commonly used code. e.g the password file locking code, which is used in groupfile.c and aliasfile.c and smbpass.c - moved RID_TYPE_MASK up another bit. this is really unfortunate, but there is no other "fast" way to identify users from groups from aliases. i do not believe that this code saves us anything (the multipliers) and puts us at a disadvantage (reduces the useable rid space). the designers of NT aren't silly: if they can get away with a user- interface-speed LsaLookupNames / LsaLookupSids, then so can we. i spoke with isaac at the cifs conference, the only time for example that they do a security context check is on file create. certainly not on individual file reads / writes, which would drastically hit their performance and ours, too. - renamed myworkgroup to global_sam_name, amongst other things, when used in the rpc code. there is also a global_member_name, as we are always responsible for a SAM database, the scope of which is limited by the role of the machine (e.g if a member of a workgroup, your SAM is for _local_ logins only, and its name is the name of your server. you even still have a SID. see LsaQueryInfoPolicy, levels 3 and 5). - updated functionality of groupname.c to be able to cope with names like DOMAIN\group and SERVER\alias. used this code to be able to do aliases as well as groups. this code may actually be better off being used in username mapping, too. - created a connect to serverlist function in clientgen.c and used it in password.c - initialisation in server.c depends on the role of the server. well, it does now. - rpctorture. smbtorture. EXERCISE EXTREME CAUTION. (This used to be commit 0d21e1e6090b933f396c764af535ca3388a562db) --- source3/utils/rpctorture.c | 503 ++++++++++++++++++++++++++++++++++++++++----- source3/utils/smbpasswd.c | 2 +- source3/utils/torture.c | 421 +++++++++++++++++++++++-------------- 3 files changed, 721 insertions(+), 205 deletions(-) (limited to 'source3/utils') diff --git a/source3/utils/rpctorture.c b/source3/utils/rpctorture.c index 96d1181ca0..dac64a22e3 100644 --- a/source3/utils/rpctorture.c +++ b/source3/utils/rpctorture.c @@ -49,7 +49,36 @@ struct cli_state *smb_cli = &smbcli; FILE *out_hnd; +static pstring user_name; /* local copy only, if one is entered */ static pstring password; /* local copy only, if one is entered */ +static pstring domain; /* local copy only, if one is entered */ +BOOL got_pass = False; + +static struct nmb_name calling; +static struct nmb_name called; + +static void get_passwd(void) +{ + /* set the password cache info */ + if (got_pass) + { + if (password[0] == 0) + { + pwd_set_nullpwd(&(smb_cli->pwd)); + } + else + { + pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */ + } + } + else + { + char *pwd = getpass("Enter Password:"); + safe_strcpy(password, pwd, sizeof(password)); + pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */ + got_pass = True; + } +} /**************************************************************************** initialise smb client structure @@ -59,6 +88,23 @@ void rpcclient_init(void) bzero(smb_cli, sizeof(smb_cli)); cli_initialise(smb_cli); smb_cli->capabilities |= CAP_NT_SMBS; + smb_cli->capabilities |= CAP_STATUS32; + + pstrcpy(smb_cli->user_name, user_name); + smb_cli->nt_pipe_fnum = 0xffff; + + get_passwd(); + + if (*domain == 0) + { + pstrcpy(smb_cli->domain,lp_workgroup()); + } + else + { + pstrcpy(smb_cli->domain, domain); + } + + strupper(smb_cli->domain); } /**************************************************************************** @@ -66,11 +112,7 @@ make smb client connection ****************************************************************************/ static BOOL rpcclient_connect(struct client_info *info) { - struct nmb_name calling; - struct nmb_name called; - - make_nmb_name(&called , dns_to_netbios_name(info->dest_host ), info->name_type, scope); - make_nmb_name(&calling, dns_to_netbios_name(info->myhostname), 0x0 , scope); + rpcclient_init(); if (!cli_establish_connection(smb_cli, info->dest_host, &info->dest_ip, @@ -97,7 +139,7 @@ static void rpcclient_stop(void) /**************************************************************************** log in as an nt user, log out again. ****************************************************************************/ -void run_enums_test(int num_ops, struct client_info *cli_info, struct cli_state *cli) +void run_enums_test(int num_ops, struct client_info *cli_info) { pstring cmd; int i; @@ -105,8 +147,8 @@ void run_enums_test(int num_ops, struct client_info *cli_info, struct cli_state /* establish connections. nothing to stop these being re-established. */ rpcclient_connect(cli_info); - DEBUG(5,("rpcclient_connect: cli->fd:%d\n", cli->fd)); - if (cli->fd <= 0) + DEBUG(5,("rpcclient_connect: smb_cli->fd:%d\n", smb_cli->fd)); + if (smb_cli->fd <= 0) { fprintf(out_hnd, "warning: connection could not be established to %s<%02x>\n", cli_info->dest_host, cli_info->name_type); @@ -141,7 +183,7 @@ void run_enums_test(int num_ops, struct client_info *cli_info, struct cli_state /**************************************************************************** log in as an nt user, log out again. ****************************************************************************/ -void run_ntlogin_test(int num_ops, struct client_info *cli_info, struct cli_state *cli) +void run_ntlogin_test(int num_ops, struct client_info *cli_info) { pstring cmd; int i; @@ -149,8 +191,8 @@ void run_ntlogin_test(int num_ops, struct client_info *cli_info, struct cli_stat /* establish connections. nothing to stop these being re-established. */ rpcclient_connect(cli_info); - DEBUG(5,("rpcclient_connect: cli->fd:%d\n", cli->fd)); - if (cli->fd <= 0) + DEBUG(5,("rpcclient_connect: smb_cli->fd:%d\n", smb_cli->fd)); + if (smb_cli->fd <= 0) { fprintf(out_hnd, "warning: connection could not be established to %s<%02x>\n", cli_info->dest_host, cli_info->name_type); @@ -159,7 +201,7 @@ void run_ntlogin_test(int num_ops, struct client_info *cli_info, struct cli_stat for (i = 0; i < num_ops; i++) { - slprintf(cmd, sizeof(cmd)-1, "%s %s", cli->user_name, password); + slprintf(cmd, sizeof(cmd)-1, "%s %s", smb_cli->user_name, password); set_first_token(cmd); cmd_netlogon_login_test(cli_info); @@ -169,12 +211,387 @@ void run_ntlogin_test(int num_ops, struct client_info *cli_info, struct cli_stat } +/* generate a random buffer */ +static void rand_buf(char *buf, int len) +{ + while (len--) { + *buf = sys_random(); + buf++; + } +} + +/**************************************************************************** +do a random rpc command +****************************************************************************/ +BOOL do_random_rpc(struct cli_state *cli, int max_len) +{ + prs_struct rbuf; + prs_struct buf; + uint8 opcode; + int param_len; + BOOL response = False; + + if ((sys_random() % 20) == 0) + { + param_len = (sys_random() % 256) + 4; + } + else + { + param_len = (sys_random() % max_len) + 4; + } + + prs_init(&buf , param_len, 4, SAFETY_MARGIN, False); + prs_init(&rbuf, 0 , 4, SAFETY_MARGIN, True ); + + opcode = sys_random() % 256; + + /* turn parameters into data stream */ + rand_buf(mem_data(&buf.data, 0), param_len); + buf.offset = param_len; + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, opcode, &buf, &rbuf)) + { + response = rbuf.offset != 0; + + if (response) + { + DEBUG(0,("response! opcode: 0x%x\n", opcode)); + DEBUG(0,("request: length %d\n", param_len)); + dump_data(0, mem_data(&buf.data , 0), MIN(param_len, 128)); + DEBUG(0,("response: length %d\n", rbuf.data->offset.end)); + dump_data(0, mem_data(&rbuf.data, 0), rbuf.data->offset.end); + } + } + + prs_mem_free(&rbuf); + prs_mem_free(&buf ); + + return response; +} + + +/* send random IPC commands */ +static void random_rpc_pipe_enc(char *pipe_name, struct client_info *cli_info, + int numops) +{ + int i; + + DEBUG(0,("starting random rpc test on %s (encryped)\n", pipe_name)); + + /* establish connections. nothing to stop these being re-established. */ + if (!rpcclient_connect(cli_info)) + { + DEBUG(0,("random rpc test: connection failed\n")); + return; + } + + cli_nt_set_ntlmssp_flgs(smb_cli, + NTLMSSP_NEGOTIATE_UNICODE | + NTLMSSP_NEGOTIATE_OEM | + NTLMSSP_NEGOTIATE_SIGN | + NTLMSSP_NEGOTIATE_SEAL | + NTLMSSP_NEGOTIATE_LM_KEY | + NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_NEGOTIATE_ALWAYS_SIGN | + NTLMSSP_NEGOTIATE_00001000 | + NTLMSSP_NEGOTIATE_00002000); + + for (i = 1; i <= numops * 100; i++) + { + /* open session. */ + cli_nt_session_open(smb_cli, pipe_name); + + do_random_rpc(smb_cli, 1024); + if (i % 500 == 0) + { + DEBUG(0,("calls: %i\n", i)); + } + + /* close the session */ + cli_nt_session_close(smb_cli); + } + + /* close the rpc pipe */ + rpcclient_stop(); + + DEBUG(0,("finished random rpc test on %s\n", pipe_name)); +} + +/* send random IPC commands */ +static void random_rpc_pipe(char *pipe_name, struct client_info *cli_info, + int numops) +{ + int i; + + DEBUG(0,("starting random rpc test on %s\n", pipe_name)); + + /* establish connections. nothing to stop these being re-established. */ + if (!rpcclient_connect(cli_info)) + { + DEBUG(0,("random rpc test: connection failed\n")); + return; + } + + /* open session. */ + if (!cli_nt_session_open(smb_cli, pipe_name)) + { + DEBUG(0,("random rpc test: session open failed\n")); + return; + } + + for (i = 1; i <= numops * 100; i++) + { + do_random_rpc(smb_cli, 8192); + if (i % 500 == 0) + { + DEBUG(0,("calls: %i\n", i)); + } + } + + /* close the session */ + cli_nt_session_close(smb_cli); + + /* close the rpc pipe */ + rpcclient_stop(); + + DEBUG(0,("finished random rpc test on %s\n", pipe_name)); +} + +static void run_randomrpc(int numops, struct client_info *cli_info) +{ + char *pipes[] = + { + PIPE_SAMR , + PIPE_WINREG , + PIPE_SRVSVC , + PIPE_WKSSVC , + PIPE_NETLOGON , + PIPE_NTSVCS , + PIPE_LSARPC , + NULL + }; + + int i = 0; + + while (pipes[i] != NULL) + { + random_rpc_pipe(pipes[i], cli_info, numops); +#if 0 + random_rpc_pipe_enc(pipes[i], cli_info, numops); +#endif + + i++; + } +} + + +static void run_samhandles(int numops, struct client_info *cli_info) +{ + int i; + int count = 0; + int failed = 0; + int retry = 500; + fstring srv_name; + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, cli_info->dest_host); + strupper(srv_name); + + DEBUG(0,("starting sam handle test\n")); + + /* establish connections. nothing to stop these being re-established. */ + while (retry > 0 && !rpcclient_connect(cli_info)) + { + retry--; + } + + if (retry == 0) + { + DEBUG(0,("samhandle test: connection failed\n")); + return; + } + + /* open session. */ + if (!cli_nt_session_open(smb_cli, PIPE_SAMR)) + { + DEBUG(0,("samhandle test: session open failed\n")); + return; + } + + for (i = 1; i <= numops * 100; i++) + { + POLICY_HND pol; + POLICY_HND dom; + if (!do_samr_connect(smb_cli, srv_name, 0x20, &pol)) + { + failed++; + } +/* + if (!do_samr_open_domain(smb_cli, srv_name, 0x00000020, &pol)) + { + DEBUG(0,("samhandle domain open test (%i): failed\n", i)); + } + */ + if (i % 500 == 0) + { + DEBUG(0,("calls: %i\n", i)); + } + count++; + } + + /* close the session */ + cli_nt_session_close(smb_cli); + + /* close the rpc pipe */ + rpcclient_stop(); + + DEBUG(0,("finished samhandle test. count: %d failed: %d\n", count, failed)); +} + + +static void run_lsahandles(int numops, struct client_info *cli_info) +{ + int i; + int count = 0; + int failed = 0; + int retry = 500; + fstring srv_name; + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, cli_info->myhostname); + strupper(srv_name); + + DEBUG(0,("starting lsa handle test\n")); + + /* establish connections. nothing to stop these being re-established. */ + while (retry > 0 && !rpcclient_connect(cli_info)) + { + retry--; + } + + if (retry == 0) + { + DEBUG(0,("lsahandle test: connection failed\n")); + return; + } + /* open session. */ + if (!cli_nt_session_open(smb_cli, PIPE_LSARPC)) + { + DEBUG(0,("lsahandle test: session open failed\n")); + return; + } + + for (i = 1; i <= numops * 100; i++) + { + POLICY_HND pol; + if (!do_lsa_open_policy(smb_cli, srv_name, &pol, False)) + { + failed++; + } + if (i % 500 == 0) + { + DEBUG(0,("calls: %i\n", i)); + } + count++; + } + + /* close the session */ + cli_nt_session_close(smb_cli); + + /* close the rpc pipe */ + rpcclient_stop(); + + DEBUG(0,("finished lsahandle test. count: %d failed: %d\n", count, failed)); +} + + +static void run_pipegobble(int numops, struct client_info *cli_info, char *pipe_name) +{ + int i; + int count = 0; + int failed = 0; + int retry = 500; + fstring srv_name; + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, cli_info->myhostname); + strupper(srv_name); + + DEBUG(0,("starting pipe gobble test (%s)\n", pipe_name)); + + /* establish connections. nothing to stop these being re-established. */ + while (retry > 0 && !rpcclient_connect(cli_info)) + { + retry--; + } + + if (retry == 0) + { + DEBUG(0,("pipe gobble test: connection failed\n")); + return; + } + for (i = 1; i <= numops * 100; i++) + { + /* open session. */ + if (!cli_nt_session_open(smb_cli, pipe_name)) + { + DEBUG(0,("pipe gobble test: session open failed\n")); + } + + if (i % 500 == 0) + { + DEBUG(0,("calls: %i\n", i)); + } + count++; + } + + rpcclient_stop(); + + DEBUG(0,("finished pipe gobble test (%s). count: %d failed: %d\n", + pipe_name, count, failed)); +} + + +static void run_handles(int numops, struct client_info *cli_info) +{ + run_samhandles(numops, cli_info); + run_lsahandles(numops, cli_info); +} + +static void run_pipegobbler(int numops, struct client_info *cli_info) +{ +/* + run_pipegobble(numops, cli_info, PIPE_SAMR); +*/ + run_pipegobble(numops, cli_info, PIPE_LSARPC); +} + +/**************************************************************************** +make tcp connection +****************************************************************************/ +static void run_tcpconnect(int numops, struct client_info *info) +{ + int i; + int failed = 0; + + for (i = 0; i < numops; i++) + { + rpcclient_init(); + + if (!cli_connect(smb_cli, info->dest_host, &info->dest_ip)) + { + failed++; + } + cli_shutdown(smb_cli); + } + + DEBUG(0,("tcp connections: count: %d failed: %d\n", numops, failed)); +} + /**************************************************************************** runs n simultaneous functions. ****************************************************************************/ static void create_procs(int nprocs, int numops, - struct client_info *cli_info, struct cli_state *cli, - void (*fn)(int, struct client_info *, struct cli_state *)) + struct client_info *cli_info, + void (*fn)(int, struct client_info *)) { int i, status; @@ -184,8 +601,8 @@ static void create_procs(int nprocs, int numops, { int mypid = getpid(); sys_srandom(mypid ^ time(NULL)); - fn(numops, cli_info, cli); - fflush(out_hnd); + fn(numops, cli_info); + dbgflush(); _exit(0); } } @@ -195,6 +612,8 @@ static void create_procs(int nprocs, int numops, waitpid(0, &status, 0); } } + + /**************************************************************************** usage on the program - OUT OF DATE! ****************************************************************************/ @@ -235,7 +654,6 @@ enum client_action extern int optind; static pstring servicesf = CONFIGFILE; pstring term_code; - BOOL got_pass = False; char *cmd_str=""; mode_t myumask = 0755; enum client_action cli_action = CLIENT_NONE; @@ -246,8 +664,6 @@ enum client_action out_hnd = stdout; - rpcclient_init(); - #ifdef KANJI pstrcpy(term_code, KANJI); #else /* KANJI */ @@ -285,8 +701,6 @@ enum client_action pstrcpy(cli_info.cur_dir , "\\"); pstrcpy(cli_info.file_sel, ""); pstrcpy(cli_info.base_dir, ""); - pstrcpy(smb_cli->domain, ""); - pstrcpy(smb_cli->user_name, ""); pstrcpy(cli_info.myhostname, ""); pstrcpy(cli_info.dest_host, ""); @@ -299,7 +713,6 @@ enum client_action ZERO_STRUCT(cli_info.dom.level5_sid); pstrcpy(cli_info.dom.level5_dom, ""); - smb_cli->nt_pipe_fnum = 0xffff; setup_logging(pname, True); @@ -403,8 +816,8 @@ enum client_action case 'U': { char *lp; - pstrcpy(smb_cli->user_name,optarg); - if ((lp=strchr(smb_cli->user_name,'%'))) + pstrcpy(user_name,optarg); + if ((lp=strchr(user_name,'%'))) { *lp = 0; pstrcpy(password,lp+1); @@ -416,7 +829,7 @@ enum client_action case 'W': { - pstrcpy(smb_cli->domain,optarg); + pstrcpy(domain,optarg); break; } @@ -516,12 +929,6 @@ enum client_action DEBUG(3,("%s client started (version %s)\n",timestring(),VERSION)); - if (*smb_cli->domain == 0) - { - pstrcpy(smb_cli->domain,lp_workgroup()); - } - strupper(smb_cli->domain); - load_interfaces(); if (cli_action == CLIENT_IPC) @@ -534,31 +941,25 @@ enum client_action strupper(cli_info.mach_acct); fstrcat(cli_info.mach_acct, "$"); - /* set the password cache info */ - if (got_pass) - { - if (password[0] == 0) - { - pwd_set_nullpwd(&(smb_cli->pwd)); - } - else - { - pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */ - } - } - else - { - char *pwd = getpass("Enter Password:"); - safe_strcpy(password, pwd, sizeof(password)); - pwd_make_lm_nt_16(&(smb_cli->pwd), password); /* generate 16 byte hashes */ - } + make_nmb_name(&called , dns_to_netbios_name(cli_info.dest_host ), cli_info.name_type, scope); + make_nmb_name(&calling, dns_to_netbios_name(cli_info.myhostname), 0x0 , scope); - create_procs(nprocs, numops, &cli_info, smb_cli, run_enums_test); + get_passwd(); +/* + create_procs(nprocs, numops, &cli_info, run_enums_test); if (password[0] != 0) { - create_procs(nprocs, numops, &cli_info, smb_cli, run_ntlogin_test); + create_procs(nprocs, numops, &cli_info, run_ntlogin_test); } +*/ + + create_procs(nprocs, numops, &cli_info, run_tcpconnect); +/* + create_procs(nprocs, numops, &cli_info, run_pipegobbler); + create_procs(nprocs, numops, &cli_info, run_handles); + create_procs(nprocs, numops, &cli_info, run_randomrpc); +*/ fflush(out_hnd); diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index 902f59b245..3249103a27 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -554,7 +554,7 @@ int main(int argc, char **argv) charset_initialise(); - if(!initialize_password_db()) { + if(!initialise_password_db()) { fprintf(stderr, "Can't setup password database vectors.\n"); exit(1); } diff --git a/source3/utils/torture.c b/source3/utils/torture.c index 81fa33fc75..fb09f515cf 100644 --- a/source3/utils/torture.c +++ b/source3/utils/torture.c @@ -23,6 +23,9 @@ #include "includes.h" +extern int DEBUGLEVEL; +extern pstring debugf; + static fstring host, workgroup, share, password, username, myname; static int max_protocol = PROTOCOL_NT1; static char *sockops=""; @@ -42,8 +45,27 @@ static double end_timer(void) (tp2.tv_usec - tp1.tv_usec)*1.0e-6); } +#define FAILED_NO_ERROR 0 +#define FAILED_TCP_CONNECT 1 +#define FAILED_SESSION_REQ 2 +#define FAILED_SMB_SESS_SETUP 3 +#define FAILED_SMB_TCON 4 +#define FAILED_SMB_NEGPROT 5 +#define FAILED_CLI_STATE_INIT 6 +#define NUM_ERR_STATES 7 -static BOOL open_connection(struct cli_state *c) +static char *smb_messages[] = +{ + "No errors in connection", + "TCP connection ", + "NetBIOS Session Request", + "SMB Session Setup ", + "SMB Tcon ", + "SMB Negprot ", + "Client initialisation " +}; + +static int open_connection(struct cli_state *c) { struct nmb_name called, calling; @@ -52,48 +74,53 @@ static BOOL open_connection(struct cli_state *c) make_nmb_name(&calling, myname, 0x0, ""); make_nmb_name(&called , host, 0x20, ""); - if (!cli_initialise(c) || !cli_connect(c, host, NULL)) { - printf("Failed to connect with %s\n", host); - return False; + if (!cli_initialise(c)) + { + DEBUG(0,("Failed to connect with %s\n", host)); + return FAILED_CLI_STATE_INIT; + } + + if (!cli_connect(c, host, NULL)) { + DEBUG(0,("Failed to connect with %s\n", host)); + return FAILED_TCP_CONNECT; } if (!cli_session_request(c, &calling, &called)) { cli_shutdown(c); - printf("%s rejected the session\n",host); - return False; + DEBUG(0,("%s rejected the session\n",host)); + return FAILED_SESSION_REQ; } if (!cli_negprot(c)) { - printf("%s rejected the negprot (%s)\n",host, cli_errstr(c)); + DEBUG(0,("%s rejected the negprot (%s)\n",host, cli_errstr(c))); cli_shutdown(c); - return False; + return FAILED_SMB_NEGPROT; } if (!cli_session_setup(c, username, password, strlen(password), password, strlen(password), workgroup)) { + DEBUG(0,("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c))); cli_shutdown(c); - printf("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c)); - return False; + return FAILED_SMB_SESS_SETUP; } if (!cli_send_tconX(c, share, "?????", password, strlen(password)+1)) { - printf("%s refused tree connect (%s)\n", host, cli_errstr(c)); + DEBUG(0,("%s refused tree connect (%s)\n", host, cli_errstr(c))); cli_shutdown(c); - return False; + return FAILED_SMB_TCON; } - return True; + return FAILED_NO_ERROR; } - static void close_connection(struct cli_state *c) { if (!cli_tdis(c)) { - printf("tdis failed (%s)\n", cli_errstr(c)); + DEBUG(0,("tdis failed (%s)\n", cli_errstr(c))); } cli_shutdown(c); @@ -110,10 +137,10 @@ static BOOL check_error(struct cli_state *c, eno = cli_error(c, &class, &num); if ((eclass != class || ecode != num) && num != (nterr&0xFFFFFF)) { - printf("unexpected error code class=%d code=%d\n", - (int)class, (int)num); - printf(" expected %d/%d %d\n", - (int)eclass, (int)ecode, (int)nterr); + DEBUG(0,("unexpected error code class=%d code=%d\n", + (int)class, (int)num)); + DEBUG(0,(" expected %d/%d %d\n", + (int)eclass, (int)ecode, (int)nterr)); return False; } return True; @@ -144,7 +171,7 @@ static BOOL rw_torture(struct cli_state *c, int numops) if (fnum2 == -1) fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE); if (fnum2 == -1) { - printf("open of %s failed (%s)\n", lockfname, cli_errstr(c)); + DEBUG(0,("open of %s failed (%s)\n", lockfname, cli_errstr(c))); return False; } @@ -152,7 +179,7 @@ static BOOL rw_torture(struct cli_state *c, int numops) for (i=0;i n) { fnum--; slprintf(fname,sizeof(fname)-1,template, fnum,getpid()); if (cli_unlink(&cli, fname)) { - printf("unlink of %s failed (%s)\n", - fname, cli_errstr(&cli)); + DEBUG(0,("unlink of %s failed (%s)\n", + fname, cli_errstr(&cli))); } } - printf("maxfid test finished\n"); + DEBUG(0,("maxfid test finished\n")); close_connection(&cli); } @@ -713,24 +746,41 @@ static void rand_buf(char *buf, int len) } /* send random IPC commands */ -static void run_randomipc(void) +static void run_randomipc(int numops) { char *rparam = NULL; char *rdata = NULL; int rdrcnt,rprcnt; - pstring param; + char param[BUFFER_SIZE]; int api, param_len, i; + int reconnect_count = 50; static struct cli_state cli; - printf("starting random ipc test\n"); + DEBUG(0,("starting random ipc test\n")); + + while (reconnect_count > 0 && open_connection(&cli) != 0) + { + DEBUG(0,("connection failed: retrying %d\n", reconnect_count)); + msleep(sys_random() % 1000); + reconnect_count--; + } - if (!open_connection(&cli)) { + if (reconnect_count == 0) + { return; } - for (i=0;i<50000;i++) { + for (i=0;i 2) { - printf("ERROR: SMBgetatr bug. time is %s", - ctime(&t)); + DEBUG(0,("ERROR: SMBgetatr bug. time is %s", + ctime(&t))); t = time(NULL); } t2 = t-60*60*24; /* 1 day ago */ if (!cli_setatr(&cli, fname, 0, t2)) { - printf("setatr failed (%s)\n", cli_errstr(&cli)); + DEBUG(0,("setatr failed (%s)\n", cli_errstr(&cli))); } if (!cli_getatr(&cli, fname, NULL, NULL, &t)) { - printf("getatr failed (%s)\n", cli_errstr(&cli)); + DEBUG(0,("getatr failed (%s)\n", cli_errstr(&cli))); } if (t != t2) { - printf("ERROR: getatr/setatr bug. times are\n%s", - ctime(&t)); - printf("%s", ctime(&t2)); + DEBUG(0,("ERROR: getatr/setatr bug. times are\n%s", + ctime(&t))); + DEBUG(0,("%s", ctime(&t2))); } cli_unlink(&cli, fname); close_connection(&cli); - printf("attrib test finished\n"); + DEBUG(0,("attrib test finished\n")); } @@ -855,9 +905,9 @@ static void run_trans2test(void) char *dname = "\\trans2"; char *fname2 = "\\trans2\\trans2.tst"; - printf("starting trans2 test\n"); + DEBUG(0,("starting trans2 test\n")); - if (!open_connection(&cli)) { + if (open_connection(&cli) != 0) { return; } @@ -866,7 +916,7 @@ static void run_trans2test(void) O_RDWR | O_CREAT | O_TRUNC, DENY_NONE); if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time, NULL, NULL)) { - printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli)); + DEBUG(0,("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli))); } cli_close(&cli, fnum); @@ -878,20 +928,20 @@ static void run_trans2test(void) cli_close(&cli, fnum); if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) { - printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli)); + DEBUG(0,("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli))); } 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"); + DEBUG(0,("create time=%s", ctime(&c_time))); + DEBUG(0,("modify time=%s", ctime(&m_time))); + DEBUG(0,("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"); + DEBUG(0,("access time=%s", ctime(&a_time))); + DEBUG(0,("This system appears to set a midnight access time\n")); } if (abs(m_time - time(NULL)) > 60*60*24*7) { - printf("ERROR: totally incorrect times - maybe word reversed?\n"); + DEBUG(0,("ERROR: totally incorrect times - maybe word reversed?\n")); } } @@ -902,11 +952,11 @@ static void run_trans2test(void) cli_close(&cli, fnum); if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL)) { - printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)); + DEBUG(0,("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli))); } 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"); + DEBUG(0,("write time=%s", ctime(&w_time))); + DEBUG(0,("This system appears to set a initial 0 write time\n")); } } @@ -916,12 +966,12 @@ static void run_trans2test(void) /* check if the server updates the directory modification time when creating a new file */ if (!cli_mkdir(&cli, dname)) { - printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli)); + DEBUG(0,("ERROR: mkdir failed (%s)\n", cli_errstr(&cli))); } sleep(3); if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL)) { - printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)); + DEBUG(0,("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli))); } fnum = cli_open(&cli, fname2, @@ -930,10 +980,10 @@ static void run_trans2test(void) cli_close(&cli, fnum); if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL)) { - printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli)); + DEBUG(0,("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli))); } else { if (m_time2 == m_time) - printf("This system does not update directory modification times\n"); + DEBUG(0,("This system does not update directory modification times\n")); } cli_unlink(&cli, fname2); cli_rmdir(&cli, dname); @@ -941,29 +991,83 @@ static void run_trans2test(void) close_connection(&cli); - printf("trans2 test finished\n"); + DEBUG(0,("trans2 test finished\n")); } +static void run_connection(int numops) +{ + struct cli_state c; + int count = 0; + int failed[NUM_ERR_STATES]; + int i; + + DEBUG(0,("Connection test starts:\n")); + + for (i = 0; i < NUM_ERR_STATES; i++) + { + failed[i] = 0; + } + + for (i = 0; i < numops; i++) + { + int err; + DEBUG(0,("Connection test %d %d\n", i, numops)); + if ((err = open_connection(&c))) + { + failed[err]++; + } + count++; + } + + { + int failtotal = 0; + + for (i = 0, failtotal = 0; i < NUM_ERR_STATES; i++) + { + failtotal += failed[i]; + } + DEBUG(0,("Connection test results: count %d success %d\n", count, count-failtotal)); + } + for (i = 0; i < NUM_ERR_STATES; i++) + { + DEBUG(0,("%s: failed: %d\n", smb_messages[i], failed[i])); + } +} + static void create_procs(int nprocs, int numops, void (*fn)(int )) { int i, status; - for (i=0;i