2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-2003
5 Copyright (C) Jelmer Vernooij 2006
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "lib/cmdline/popt_common.h"
24 #include "libcli/raw/libcliraw.h"
25 #include "system/time.h"
26 #include "system/wait.h"
27 #include "system/filesys.h"
28 #include "libcli/raw/ioctl.h"
29 #include "libcli/libcli.h"
30 #include "lib/ldb/include/ldb.h"
31 #include "lib/events/events.h"
32 #include "libcli/resolve/resolve.h"
33 #include "auth/credentials/credentials.h"
34 #include "libcli/ldap/ldap_client.h"
35 #include "librpc/gen_ndr/ndr_nbt.h"
37 #include "torture/torture.h"
39 #include "dlinklist.h"
41 #define MAX_COLS 80 /* FIXME: Determine this at run-time */
43 /****************************************************************************
44 run a specified test or "ALL"
45 ****************************************************************************/
46 static BOOL run_test(const char *name)
52 if (strequal(name,"ALL")) {
53 for (o = torture_ops; o; o = o->next) {
54 if (!run_test(o->name)) {
61 for (o = torture_ops; o; o = o->next) {
62 if (gen_fnmatch(name, o->name) == 0) {
66 printf("Running %s\n", o->name);
69 t = torture_create_procs(o->multi_fn,
73 printf("TEST %s FAILED!\n", o->name);
77 struct timeval tv = timeval_current();
80 printf("TEST %s FAILED!\n", o->name);
82 t = timeval_elapsed(&tv);
84 printf("%s took %g secs\n\n", o->name, t);
89 printf("Unknown torture operation '%s'\n", name);
95 static void parse_dns(const char *dns)
97 char *userdn, *basedn, *secret;
100 /* retrievieng the userdn */
101 p = strchr_m(dns, '#');
103 lp_set_cmdline("torture:ldap_userdn", "");
104 lp_set_cmdline("torture:ldap_basedn", "");
105 lp_set_cmdline("torture:ldap_secret", "");
108 userdn = strndup(dns, p - dns);
109 lp_set_cmdline("torture:ldap_userdn", userdn);
111 /* retrieve the basedn */
113 p = strchr_m(d, '#');
115 lp_set_cmdline("torture:ldap_basedn", "");
116 lp_set_cmdline("torture:ldap_secret", "");
119 basedn = strndup(d, p - d);
120 lp_set_cmdline("torture:ldap_basedn", basedn);
122 /* retrieve the secret */
125 lp_set_cmdline("torture:ldap_secret", "");
129 lp_set_cmdline("torture:ldap_secret", secret);
131 printf ("%s - %s - %s\n", userdn, basedn, secret);
135 static void usage(poptContext pc)
137 struct torture_op *o;
140 poptPrintUsage(pc, stdout, 0);
143 printf("The binding format is:\n\n");
145 printf(" TRANSPORT:host[flags]\n\n");
147 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
149 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
150 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
151 printf(" string.\n\n");
153 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
154 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
155 printf(" will be auto-determined.\n\n");
157 printf(" other recognised flags are:\n\n");
159 printf(" sign : enable ntlmssp signing\n");
160 printf(" seal : enable ntlmssp sealing\n");
161 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
162 printf(" validate: enable the NDR validator\n");
163 printf(" print: enable debugging of the packets\n");
164 printf(" bigendian: use bigendian RPC\n");
165 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
167 printf(" For example, these all connect to the samr pipe:\n\n");
169 printf(" ncacn_np:myserver\n");
170 printf(" ncacn_np:myserver[samr]\n");
171 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
172 printf(" ncacn_np:myserver[/pipe/samr]\n");
173 printf(" ncacn_np:myserver[samr,sign,print]\n");
174 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
175 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
176 printf(" ncacn_np:\n");
177 printf(" ncacn_np:[/pipe/samr]\n\n");
179 printf(" ncacn_ip_tcp:myserver\n");
180 printf(" ncacn_ip_tcp:myserver[1024]\n");
181 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
183 printf("The unc format is:\n\n");
185 printf(" //server/share\n\n");
187 printf("tests are:\n");
190 for (o = torture_ops; o; o = o->next) {
191 if (i + strlen(o->name) >= MAX_COLS) {
195 i+=printf("%s ", o->name);
199 printf("default test is ALL\n");
204 static BOOL is_binding_string(const char *binding_string)
206 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
207 struct dcerpc_binding *binding_struct;
210 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
212 talloc_free(mem_ctx);
213 return NT_STATUS_IS_OK(status);
216 static void max_runtime_handler(int sig)
218 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
222 /****************************************************************************
224 ****************************************************************************/
225 int main(int argc,char *argv[])
234 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,
235 OPT_DANGEROUS,OPT_SMB_PORTS};
237 struct poptOption long_options[] = {
239 {"smb-ports", 'p', POPT_ARG_STRING, NULL, OPT_SMB_PORTS, "SMB ports", NULL},
240 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
241 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
242 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
243 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
244 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
245 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
246 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
247 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
248 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
249 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
250 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
251 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
252 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
253 "set maximum time for smbtorture to live", "seconds"},
255 POPT_COMMON_CONNECTION
256 POPT_COMMON_CREDENTIALS
261 #ifdef HAVE_SETBUFFER
262 setbuffer(stdout, NULL, 0);
267 /* we are never interested in SIGPIPE */
268 BlockSignals(True,SIGPIPE);
270 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
271 POPT_CONTEXT_KEEP_FIRST);
273 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
275 while((opt = poptGetNextOpt(pc)) != -1) {
278 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
281 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
284 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
287 parse_dns(poptGetOptArg(pc));
290 lp_set_cmdline("torture:dangerous", "Yes");
293 lp_set_cmdline("smb ports", poptGetOptArg(pc));
296 d_printf("Invalid option %s: %s\n",
297 poptBadOption(pc, 0), poptStrerror(opt));
304 /* this will only work if nobody else uses alarm(),
305 which means it won't work for some tests, but we
306 can't use the event context method we use for smbd
307 as so many tests create their own event
308 context. This will at least catch most cases. */
309 signal(SIGALRM, max_runtime_handler);
315 if (torture_seed == 0) {
316 torture_seed = time(NULL);
318 printf("Using seed %d\n", torture_seed);
319 srandom(torture_seed);
321 argv_new = discard_const_p(char *, poptGetArgs(pc));
324 for (i=0; i<argc; i++) {
325 if (argv_new[i] == NULL) {
336 for(p = argv_new[1]; *p; p++) {
341 /* see if its a RPC transport specifier */
342 if (is_binding_string(argv_new[1])) {
343 lp_set_cmdline("torture:binding", argv_new[1]);
345 char *binding = NULL;
346 char *host = NULL, *share = NULL;
348 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
349 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
353 lp_set_cmdline("torture:host", host);
354 lp_set_cmdline("torture:share", share);
355 asprintf(&binding, "ncacn_np:%s", host);
356 lp_set_cmdline("torture:binding", binding);
360 printf("You must specify a test to run, or 'ALL'\n");
362 for (i=2;i<argc_new;i++) {
363 if (!run_test(argv_new[i])) {