*/
#include "includes.h"
-#include "dynconfig.h"
-#include "clilist.h"
#include "lib/cmdline/popt_common.h"
#include "libcli/raw/libcliraw.h"
#include "system/time.h"
#include "system/wait.h"
#include "system/filesys.h"
-#include "ioctl.h"
-#include "librpc/gen_ndr/ndr_security.h"
+#include "libcli/raw/ioctl.h"
+#include "libcli/libcli.h"
+#include "lib/ldb/include/ldb.h"
+#include "librpc/rpc/dcerpc_table.h"
+#include "lib/events/events.h"
+#include "libcli/resolve/resolve.h"
+#include "auth/credentials/credentials.h"
+
+#include "torture/basic/proto.h"
+#include "torture/raw/proto.h"
+#include "torture/smb2/proto.h"
+#include "torture/rpc/proto.h"
+#include "torture/rap/proto.h"
+#include "torture/auth/proto.h"
+#include "torture/local/proto.h"
+#include "torture/nbench/proto.h"
+#include "torture/ldap/proto.h"
+#include "torture/com/proto.h"
+#include "torture/nbt/proto.h"
+#include "torture/libnet/proto.h"
+#include "torture/torture.h"
+#include "build.h"
+#include "dlinklist.h"
int torture_nprocs=4;
-int torture_numops=100;
+int torture_numops=10;
int torture_entries=1000;
int torture_failures=1;
int torture_seed=0;
static struct smbcli_state *current_cli;
static BOOL use_oplocks;
static BOOL use_level_II_oplocks;
+#define MAX_COLS 80 /* FIXME: Determine this at run-time */
BOOL torture_showall = False;
struct smbcli_state *cli;
const char *host = lp_parm_string(-1, "torture", "host");
- calling.name = lp_netbios_name();
- calling.type = NBT_NAME_CLIENT;
- calling.scope = NULL;
+ make_nbt_name_client(&calling, lp_netbios_name());
nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
cli = smbcli_state_init(NULL);
if (!cli) {
printf("Failed initialize smbcli_struct to connect with %s\n", host);
- return NULL;
+ goto failed;
}
if (!smbcli_socket_connect(cli, host)) {
printf("Failed to connect with %s\n", host);
- return cli;
+ goto failed;
}
if (!smbcli_transport_establish(cli, &calling, &called)) {
printf("%s rejected the session\n",host);
- smbcli_shutdown(cli);
- return NULL;
+ goto failed;
}
return cli;
+
+failed:
+ talloc_free(cli);
+ return NULL;
}
-BOOL torture_open_connection_share(struct smbcli_state **c,
+BOOL torture_open_connection_share(TALLOC_CTX *mem_ctx,
+ struct smbcli_state **c,
const char *hostname,
- const char *sharename)
+ const char *sharename,
+ struct event_context *ev)
{
NTSTATUS status;
- status = smbcli_full_connection(NULL,
- c, lp_netbios_name(),
- hostname,
+ status = smbcli_full_connection(mem_ctx, c, hostname,
sharename, NULL,
- cmdline_credentials);
+ cmdline_credentials, ev);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to open connection - %s\n", nt_errstr(status));
return False;
const char *host = lp_parm_string(-1, "torture", "host");
const char *share = lp_parm_string(-1, "torture", "share");
- return torture_open_connection_share(c, host, share);
+ return torture_open_connection_share(NULL, c, host, share, NULL);
}
printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
ret = False;
}
- smbcli_shutdown(c);
+ talloc_free(c);
return ret;
}
/* open a rpc connection to the chosen binding string */
-NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p,
- const char *pipe_name,
- const char *pipe_uuid,
- uint32_t pipe_version)
+NTSTATUS torture_rpc_connection(TALLOC_CTX *parent_ctx,
+ struct dcerpc_pipe **p,
+ const struct dcerpc_interface_table *table)
{
NTSTATUS status;
const char *binding = lp_parm_string(-1, "torture", "binding");
return NT_STATUS_INVALID_PARAMETER;
}
- status = dcerpc_pipe_connect(p, binding, pipe_uuid, pipe_version,
- cmdline_credentials);
+ status = dcerpc_pipe_connect(parent_ctx,
+ p, binding, table,
+ cmdline_credentials, NULL);
return status;
}
/* open a rpc connection to a specific transport */
-NTSTATUS torture_rpc_connection_transport(struct dcerpc_pipe **p,
- const char *pipe_name,
- const char *pipe_uuid,
- uint32_t pipe_version,
+NTSTATUS torture_rpc_connection_transport(TALLOC_CTX *parent_ctx,
+ struct dcerpc_pipe **p,
+ const struct dcerpc_interface_table *table,
enum dcerpc_transport_t transport)
{
NTSTATUS status;
const char *binding = lp_parm_string(-1, "torture", "binding");
struct dcerpc_binding *b;
- TALLOC_CTX *mem_ctx = talloc_init("torture_rpc_connection_smb");
+ TALLOC_CTX *mem_ctx = talloc_named(parent_ctx, 0, "torture_rpc_connection_smb");
if (!binding) {
printf("You must specify a ncacn binding string\n");
+ talloc_free(mem_ctx);
return NT_STATUS_INVALID_PARAMETER;
}
b->transport = transport;
- status = dcerpc_pipe_connect_b(p, b, pipe_uuid, pipe_version,
- cmdline_credentials);
+ status = dcerpc_pipe_connect_b(mem_ctx, p, b, table,
+ cmdline_credentials, NULL);
-
+ if (NT_STATUS_IS_OK(status)) {
+ *p = talloc_reference(parent_ctx, *p);
+ } else {
+ *p = NULL;
+ }
+ talloc_free(mem_ctx);
return status;
}
-/* close a rpc connection to a named pipe */
-NTSTATUS torture_rpc_close(struct dcerpc_pipe *p)
-{
- dcerpc_pipe_close(p);
- return NT_STATUS_OK;
-}
-
-
/* check if the server produced the expected error code */
BOOL check_error(const char *location, struct smbcli_state *c,
uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
{
- if (smbcli_is_dos_error(c->tree)) {
- uint8_t class;
- uint32_t num;
-
- /* Check DOS error */
-
- smbcli_dos_error(c, &class, &num);
-
+ 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);
if (eclass != class || ecode != num) {
- printf("unexpected error code class=%d code=%d\n",
- (int)class, (int)num);
- printf(" expected %d/%d %s (at %s)\n",
- (int)eclass, (int)ecode, nt_errstr(nterr), location);
+ 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);
return False;
}
-
} else {
- NTSTATUS status;
-
- /* Check NT error */
-
- status = smbcli_nt_error(c->tree);
-
- if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
+ if (!NT_STATUS_EQUAL(nterr, status)) {
printf("unexpected error code %s\n", nt_errstr(status));
printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
return False;
return ret;
}
-static BOOL rw_torture3(struct smbcli_state *c, const char *lockfname)
-{
- int fnum = -1;
- uint_t i = 0;
- uint8_t buf[131072];
- uint8_t buf_rd[131072];
- uint_t count;
- uint_t countprev = 0;
- ssize_t sent = 0;
- BOOL correct = True;
-
- for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
- {
- SIVAL(buf, i, random());
- }
-
- if (procnum == 0)
- {
- fnum = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
- DENY_NONE);
- if (fnum == -1) {
- printf("first open read/write of %s failed (%s)\n",
- lockfname, smbcli_errstr(c->tree));
- return False;
- }
- }
- else
- {
- for (i = 0; i < 500 && fnum == -1; i++)
- {
- fnum = smbcli_open(c->tree, lockfname, O_RDONLY,
- DENY_NONE);
- msleep(10);
- }
- if (fnum == -1) {
- printf("second open read-only of %s failed (%s)\n",
- lockfname, smbcli_errstr(c->tree));
- return False;
- }
- }
-
- i = 0;
- for (count = 0; count < sizeof(buf); count += sent)
- {
- if (count >= countprev) {
- printf("%d %8d\r", i, count);
- fflush(stdout);
- i++;
- countprev += (sizeof(buf) / 20);
- }
-
- if (procnum == 0)
- {
- sent = ((uint_t)random()%(20))+ 1;
- if (sent > sizeof(buf) - count)
- {
- sent = sizeof(buf) - count;
- }
-
- if (smbcli_write(c->tree, fnum, 0, buf+count, count, (size_t)sent) != sent) {
- printf("write failed (%s)\n", smbcli_errstr(c->tree));
- correct = False;
- }
- }
- else
- {
- sent = smbcli_read(c->tree, fnum, buf_rd+count, count,
- sizeof(buf)-count);
- if (sent < 0)
- {
- printf("read failed offset:%d size:%d (%s)\n",
- count, sizeof(buf)-count,
- smbcli_errstr(c->tree));
- correct = False;
- sent = 0;
- }
- if (sent > 0)
- {
- if (memcmp(buf_rd+count, buf+count, sent) != 0)
- {
- printf("read/write compare failed\n");
- printf("offset: %d req %d recvd %d\n",
- count, sizeof(buf)-count, sent);
- correct = False;
- break;
- }
- }
- }
-
- }
-
- if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
- printf("close failed (%s)\n", smbcli_errstr(c->tree));
- correct = False;
- }
-
- return correct;
-}
static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
{
if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
printf("write failed (%s)\n", smbcli_errstr(c1->tree));
- printf("wrote %d, expected %d\n", bytes_written, buf_size);
+ printf("wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
correct = False;
break;
}
if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
printf("read failed (%s)\n", smbcli_errstr(c2->tree));
- printf("read %d, expected %d\n", bytes_read, buf_size);
+ printf("read %d, expected %d\n", (int)bytes_read, (int)buf_size);
correct = False;
break;
}
return (test1 && test2);
}
-static BOOL run_readwritemulti(struct smbcli_state *cli, int dummy)
-{
- BOOL test;
-
- test = rw_torture3(cli, "\\multitest.txt");
-
- if (!torture_close_connection(cli)) {
- test = False;
- }
-
- return test;
-}
-
-
/*
this checks to see if a secondary tconx can use open files from an
earlier tconx
}
tree1 = cli->tree; /* save old tree connection */
- if (NT_STATUS_IS_ERR(smbcli_send_tconX(cli, share, "?????", password))) {
+ if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
printf("%s refused 2nd tree connect (%s)\n", host,
smbcli_errstr(cli->tree));
- smbcli_shutdown(cli);
+ talloc_free(cli);
return False;
}
cli->tree = tree1; /* restore initial tree */
cli->tree->tid = cnum1;
+ smbcli_unlink(tree1, fname);
+
if (!torture_close_connection(cli)) {
return False;
}
BOOL ret;
const char *password = lp_parm_string(-1, "torture", "password");
- status = NT_STATUS_IS_OK(smbcli_send_tconX(cli, myshare, devtype,
+ status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
password));
printf("Trying share %s with devtype %s\n", myshare, devtype);
const char *share = lp_parm_string(-1, "torture", "share");
status = smbcli_full_connection(NULL,
- &cli1, lp_netbios_name(),
- host,
+ &cli1, host,
share, NULL,
- cmdline_credentials);
+ cmdline_credentials, NULL);
if (!NT_STATUS_IS_OK(status)) {
printf("could not open connection\n");
if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
ret = False;
- smbcli_shutdown(cli1);
+ talloc_free(cli1);
if (ret)
printf("Passed tcondevtest\n");
printf("Filling send buffer\n");
- for (i=0;i<10000;i++) {
+ for (i=0;i<100;i++) {
struct smbcli_request *req;
- time_t t1 = time(NULL);
req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
- while (req->state == SMBCLI_REQUEST_SEND && time(NULL) < t1+5) {
- smbcli_transport_process(cli->transport);
- }
+ event_loop_once(cli->transport->socket->event.ctx);
if (req->state == SMBCLI_REQUEST_ERROR) {
- printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
- torture_close_connection(cli);
- return correct;
- }
- if (req->state == SMBCLI_REQUEST_SEND) {
- break;
- }
- }
-
- if (i == 10000) {
- printf("send buffer failed to fill\n");
- if (!torture_close_connection(cli)) {
- correct = False;
+ if (i > 0) {
+ printf("Failed to fill pipe packet[%d] - %s (ignored)\n", i+1, nt_errstr(req->status));
+ break;
+ } else {
+ printf("Failed to fill pipe - %s \n", nt_errstr(req->status));
+ torture_close_connection(cli);
+ return False;
+ }
}
- return correct;
}
- printf("send buffer filled after %d requests\n", i);
-
printf("Opening secondary connection\n");
if (!torture_open_connection(&cli2)) {
- return False;
- }
-
- if (!torture_close_connection(cli)) {
+ printf("Failed to open secondary connection\n");
correct = False;
}
if (!torture_close_connection(cli2)) {
+ printf("Failed to close secondary connection\n");
correct = False;
}
+ torture_close_connection(cli);
+
printf("finished negprot nowait test\n");
return correct;
correct = False;
}
- if ( (cli->transport->error.etype != ETYPE_DOS) ||
- (cli->transport->error.e.dos.eclass != ERRSRV) ||
- (cli->transport->error.e.dos.ecode != ERRbaduid) ) {
+ if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
+ NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
+ !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
+ NT_STATUS_INVALID_HANDLE)) {
printf("ERROR: qfileinfo should have returned DOS error "
"ERRSRV:ERRbaduid\n but returned %s\n",
smbcli_errstr(cli->tree));
static struct smbcli_state *cli1;
static struct smbcli_state *cli2;
const char *fname = "\\readonly.file";
+ char *control_char_fname;
int fnum1, fnum2;
uint8_t buf[20];
size_t fsize;
BOOL correct = True;
char *tmp_path;
int failures = 0;
+ int i;
printf("starting open test\n");
return False;
}
+ 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");
+
smbcli_setatr(cli1->tree, fname, 0, 0);
smbcli_unlink(cli1->tree, fname);
}
parms.ioctl.level = RAW_IOCTL_IOCTL;
- parms.ioctl.in.fnum = fnum;
+ parms.ioctl.in.file.fnum = fnum;
parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
if (NT_STATUS_IS_OK(status)) {
printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
- device, function, parms.ioctl.out.blob.length);
+ device, function, (int)parms.ioctl.out.blob.length);
}
}
}
}
if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
- ret = check_error(__location__, cli, ERRDOS, ERRbadfile,
+ ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
NT_STATUS_OBJECT_NAME_NOT_FOUND);
} else {
printf("* chkpath on a non existent file should fail\n");
p = lp_parm_string(-1, "torture", "unclist");
if (p) {
- unc_list = file_lines_load(p, &num_unc_names);
+ unc_list = file_lines_load(p, &num_unc_names, NULL);
if (!unc_list || num_unc_names <= 0) {
printf("Failed to load unc names list from '%s'\n", p);
exit(1);
while (1) {
if (hostname) {
- if (torture_open_connection_share(¤t_cli,
+ if (torture_open_connection_share(NULL,
+ ¤t_cli,
hostname,
- sharename)) {
+ sharename,
+ NULL)) {
break;
}
} else if (torture_open_connection(¤t_cli)) {
for (i=0;i<torture_nprocs;i++) {
int ret;
- while ((ret=sys_waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
+ while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
if (ret == -1 || WEXITSTATUS(status) != 0) {
*result = False;
}
const char *name;
BOOL (*fn)(void);
BOOL (*multi_fn)(struct smbcli_state *, int );
-} torture_ops[] = {
+} builtin_torture_ops[] = {
/* base tests */
{"BASE-FDPASS", run_fdpasstest, 0},
{"BASE-LOCK1", torture_locktest1, 0},
{"BASE-TCONDEV", run_tcon_devtype_test, 0},
{"BASE-VUID", run_vuidtest, 0},
{"BASE-RW1", run_readwritetest, 0},
- {"BASE-RW2", NULL, run_readwritemulti},
{"BASE-OPEN", run_opentest, 0},
{"BASE-DEFER_OPEN", NULL, run_deferopen},
{"BASE-XCOPY", run_xcopy, 0},
{"BENCH-TORTURE", NULL, run_torture},
{"BENCH-NBT", torture_bench_nbt, 0},
{"BENCH-WINS", torture_bench_wins, 0},
+ {"BENCH-RPC", torture_bench_rpc, 0},
+ {"BENCH-CLDAP", torture_bench_cldap, 0},
/* RAW smb tests */
{"RAW-QFSINFO", torture_raw_qfsinfo, 0},
{"RAW-RENAME", torture_raw_rename, 0},
{"RAW-SEEK", torture_raw_seek, 0},
{"RAW-EAS", torture_raw_eas, 0},
+ {"RAW-EAMAX", torture_max_eas, 0},
{"RAW-STREAMS", torture_raw_streams, 0},
{"RAW-ACLS", torture_raw_acls, 0},
{"RAW-RAP", torture_raw_rap, 0},
{"RAW-COMPOSITE", torture_raw_composite, 0},
+ /* SMB2 tests */
+ {"SMB2-CONNECT", torture_smb2_connect, 0},
+ {"SMB2-SCAN", torture_smb2_scan, 0},
+ {"SMB2-SCANGETINFO", torture_smb2_getinfo_scan, 0},
+ {"SMB2-SCANSETINFO", torture_smb2_setinfo_scan, 0},
+ {"SMB2-SCANFIND", torture_smb2_find_scan, 0},
+ {"SMB2-GETINFO", torture_smb2_getinfo, 0},
+ {"SMB2-SETINFO", torture_smb2_setinfo, 0},
+ {"SMB2-FIND", torture_smb2_find, 0},
+
/* protocol scanners */
{"SCAN-TRANS2", torture_trans2_scan, 0},
{"SCAN-NTTRANS", torture_nttrans_scan, 0},
/* rpc testers */
{"RPC-LSA", torture_rpc_lsa, 0},
+ {"RPC-LSALOOKUP", torture_rpc_lsa_lookup, 0},
+ {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
{"RPC-ECHO", torture_rpc_echo, 0},
{"RPC-DFS", torture_rpc_dfs, 0},
{"RPC-SPOOLSS", torture_rpc_spoolss, 0},
{"RPC-SAMR", torture_rpc_samr, 0},
+ {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
{"RPC-NETLOGON", torture_rpc_netlogon, 0},
{"RPC-SAMLOGON", torture_rpc_samlogon, 0},
{"RPC-SAMSYNC", torture_rpc_samsync, 0},
{"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
{"RPC-MULTIBIND", torture_multi_bind, 0},
{"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
- {"RPC-LOGIN", torture_rpc_login, 0},
+ {"RPC-CRACKNAMES", torture_rpc_drsuapi_cracknames, 0},
{"RPC-ROT", torture_rpc_rot, 0},
{"RPC-DSSETUP", torture_rpc_dssetup, 0},
{"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
+ {"RPC-JOIN", torture_rpc_join, 0},
+ {"RPC-DSSYNC", torture_rpc_dssync, 0},
/* local (no server) testers */
{"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
{"LOCAL-ICONV", torture_local_iconv, 0},
{"LOCAL-TALLOC", torture_local_talloc, 0},
{"LOCAL-MESSAGING", torture_local_messaging, 0},
+ {"LOCAL-IRPC", torture_local_irpc, 0},
{"LOCAL-BINDING", torture_local_binding_string, 0},
+ {"LOCAL-STRLIST", torture_local_util_strlist, 0},
+ {"LOCAL-FILE", torture_local_util_file, 0},
{"LOCAL-IDTREE", torture_local_idtree, 0},
{"LOCAL-SOCKET", torture_local_socket, 0},
-
- /* COM (Component Object Model) testers */
- {"COM-SIMPLE", torture_com_simple, 0 },
+ {"LOCAL-PAC", torture_pac, 0},
+ {"LOCAL-REGISTRY", torture_registry, 0},
+ {"LOCAL-RESOLVE", torture_local_resolve, 0},
+ {"LOCAL-SDDL", torture_local_sddl, 0},
+ {"LOCAL-NDR", torture_local_ndr, 0},
/* ldap testers */
{"LDAP-BASIC", torture_ldap_basic, 0},
+ {"LDAP-CLDAP", torture_cldap, 0},
/* nbt tests */
{"NBT-REGISTER", torture_nbt_register, 0},
{"NBT-WINS", torture_nbt_wins, 0},
- {"NBT-WINSREPLICATION", torture_nbt_winsreplication, 0},
+ {"NBT-DGRAM", torture_nbt_dgram, 0},
+ {"NBT-BROWSE", torture_nbt_browse, 0},
+ {"NBT-WINSREPLICATION-SIMPLE", torture_nbt_winsreplication_simple, 0},
+ {"NBT-WINSREPLICATION-REPLICA", torture_nbt_winsreplication_replica, 0},
+ {"NBT-WINSREPLICATION-OWNED", torture_nbt_winsreplication_owned, 0},
/* libnet tests */
{"NET-USERINFO", torture_userinfo, 0},
+ {"NET-USERADD", torture_useradd, 0},
+ {"NET-USERDEL", torture_userdel, 0},
+ {"NET-USERMOD", torture_usermod, 0},
+ {"NET-DOMOPEN", torture_domainopen, 0},
+ {"NET-API-LOOKUP", torture_lookup, 0},
+ {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
+ {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
+ {"NET-API-CREATEUSER", torture_createuser, 0},
+ {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
+ {"NET-API-LISTSHARES", torture_listshares, 0},
+ {"NET-API-DELSHARE", torture_delshare, 0},
{NULL, NULL, 0}};
+static void register_builtin_ops(void)
+{
+ int i;
+ for (i = 0; builtin_torture_ops[i].name; i++) {
+ register_torture_op(builtin_torture_ops[i].name,
+ builtin_torture_ops[i].fn,
+ builtin_torture_ops[i].multi_fn);
+ }
+}
+
+
+static struct torture_op {
+ const char *name;
+ BOOL (*fn)(void);
+ BOOL (*multi_fn)(struct smbcli_state *, int );
+ struct torture_op *prev, *next;
+}* torture_ops = NULL;;
+
+static struct torture_op *find_torture_op(const char *name)
+{
+ struct torture_op *o;
+ for (o = torture_ops; o; o = o->next) {
+ if (strcmp(name, o->name) == 0)
+ return o;
+ }
+
+ return NULL;
+}
+NTSTATUS register_torture_op(const char *name, BOOL (*fn)(void), BOOL (*multi_fn)(struct smbcli_state *, int ))
+{
+ struct torture_op *op;
+
+ /* Check for duplicates */
+ if (find_torture_op(name) != NULL) {
+ DEBUG(0,("There already is a torture op registered with the name %s!\n", name));
+ return NT_STATUS_OBJECT_NAME_COLLISION;
+ }
+
+ op = talloc(talloc_autofree_context(), struct torture_op);
+
+ op->name = talloc_strdup(op, name);
+ op->fn = fn;
+ op->multi_fn = multi_fn;
+
+ DLIST_ADD(torture_ops, op);
+
+ return NT_STATUS_OK;
+}
/****************************************************************************
run a specified test or "ALL"
static BOOL run_test(const char *name)
{
BOOL ret = True;
- int i;
+ struct torture_op *o;
BOOL matched = False;
if (strequal(name,"ALL")) {
- for (i=0;torture_ops[i].name;i++) {
- if (!run_test(torture_ops[i].name)) {
+ for (o = torture_ops; o; o = o->next) {
+ if (!run_test(o->name)) {
ret = False;
}
}
return ret;
}
- for (i=0;torture_ops[i].name;i++) {
- if (gen_fnmatch(name, torture_ops[i].name) == 0) {
+ for (o = torture_ops; o; o = o->next) {
+ if (gen_fnmatch(name, o->name) == 0) {
double t;
matched = True;
init_iconv();
- printf("Running %s\n", torture_ops[i].name);
- if (torture_ops[i].multi_fn) {
+ printf("Running %s\n", o->name);
+ if (o->multi_fn) {
BOOL result = False;
- t = torture_create_procs(torture_ops[i].multi_fn,
+ t = torture_create_procs(o->multi_fn,
&result);
if (!result) {
ret = False;
- printf("TEST %s FAILED!\n", torture_ops[i].name);
+ printf("TEST %s FAILED!\n", o->name);
}
} else {
struct timeval tv = timeval_current();
- if (!torture_ops[i].fn()) {
+ if (!o->fn()) {
ret = False;
- printf("TEST %s FAILED!\n", torture_ops[i].name);
+ printf("TEST %s FAILED!\n", o->name);
}
t = timeval_elapsed(&tv);
}
- printf("%s took %g secs\n\n", torture_ops[i].name, t);
+ printf("%s took %g secs\n\n", o->name, t);
}
}
static void usage(poptContext pc)
{
+ struct torture_op *o;
int i;
- int perline = 5;
poptPrintUsage(pc, stdout, 0);
printf("\n");
printf(" //server/share\n\n");
- printf("tests are:");
- for (i=0;torture_ops[i].name;i++) {
- if ((i%perline)==0) {
+ printf("tests are:\n");
+
+ i = 0;
+ for (o = torture_ops; o; o = o->next) {
+ if (i + strlen(o->name) >= MAX_COLS) {
printf("\n");
+ i = 0;
}
- printf("%s ", torture_ops[i].name);
+ i+=printf("%s ", o->name);
}
printf("\n\n");
return NT_STATUS_IS_OK(status);
}
+static void max_runtime_handler(int sig)
+{
+ DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
+ exit(1);
+}
+
/****************************************************************************
main program
****************************************************************************/
int opt, i;
char *p;
BOOL correct = True;
+ int max_runtime=0;
int argc_new;
char **argv_new;
poptContext pc;
- enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,OPT_DANGEROUS};
+ enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,
+ OPT_DANGEROUS,OPT_SMB_PORTS};
+ init_module_fn static_init[] = STATIC_smbtorture_MODULES;
+ init_module_fn *shared_init = load_samba_modules(NULL, "torture");
+
struct poptOption long_options[] = {
POPT_AUTOHELP
- {"smb-ports", 'p', POPT_ARG_STRING, NULL, 0, "SMB ports", NULL},
+ {"smb-ports", 'p', POPT_ARG_STRING, NULL, OPT_SMB_PORTS, "SMB ports", NULL},
{"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
{"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
{"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
{"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
{"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
{"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
+ {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
+ "set maximum time for smbtorture to live", "seconds"},
POPT_COMMON_SAMBA
POPT_COMMON_CONNECTION
POPT_COMMON_CREDENTIALS
POPT_TABLEEND
};
- setup_logging("smbtorture", DEBUG_STDOUT);
-
#ifdef HAVE_SETBUFFER
setbuffer(stdout, NULL, 0);
#endif
+ register_builtin_ops();
+
+ run_init_functions(static_init);
+ run_init_functions(shared_init);
+
+ talloc_free(shared_init);
+
+ /* we are never interested in SIGPIPE */
+ BlockSignals(True,SIGPIPE);
+
pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
- POPT_CONTEXT_KEEP_FIRST);
+ POPT_CONTEXT_KEEP_FIRST);
poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
case OPT_DANGEROUS:
lp_set_cmdline("torture:dangerous", "Yes");
break;
+ case OPT_SMB_PORTS:
+ lp_set_cmdline("smb ports", poptGetOptArg(pc));
+ break;
default:
d_printf("Invalid option %s: %s\n",
poptBadOption(pc, 0), poptStrerror(opt));
}
}
- lp_load(dyn_CONFIGFILE,True,False,False);
- load_interfaces();
+ 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);
+ }
+
+ ldb_global_init();
- smbtorture_init_subsystems;
+ dcerpc_init();
+ dcerpc_table_init();
if (torture_seed == 0) {
torture_seed = time(NULL);