auth:credentials: Check for NT hash being NULL
[Samba.git] / source4 / torture / smbtorture.c
blobad1280be7d818c7c6da0b9a882958de7f3a06116
1 /*
2 Unix SMB/CIFS implementation.
3 SMB torture tester
4 Copyright (C) Andrew Tridgell 1997-2003
5 Copyright (C) Jelmer Vernooij 2006-2008
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 3 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, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "lib/util/util_file.h"
23 #include "lib/cmdline/cmdline.h"
24 #include "system/time.h"
25 #include "system/wait.h"
26 #include "system/filesys.h"
27 #include "system/readline.h"
28 #include "../libcli/smbreadline/smbreadline.h"
29 #include "libcli/libcli.h"
30 #include "lib/events/events.h"
32 #include "torture/smbtorture.h"
33 #include "librpc/rpc/dcerpc.h"
34 #include "auth/gensec/gensec.h"
35 #include "param/param.h"
36 #include "lib/util/samba_modules.h"
38 #ifdef HAVE_READLINE_HISTORY_H
39 #include <readline/history.h>
40 #endif
42 static int use_fullname;
44 static char *prefix_name(TALLOC_CTX *mem_ctx, const char *prefix, const char *name)
46 if (prefix == NULL)
47 return talloc_strdup(mem_ctx, name);
48 else
49 return talloc_asprintf(mem_ctx, "%s.%s", prefix, name);
52 static void print_test_list(const struct torture_suite *suite, const char *prefix, const char *expr)
54 struct torture_suite *o;
55 struct torture_tcase *t;
56 struct torture_test *p;
58 for (o = suite->children; o; o = o->next) {
59 char *name = prefix_name(NULL, prefix, o->name);
60 print_test_list(o, name, expr);
61 talloc_free(name);
64 for (t = suite->testcases; t; t = t->next) {
65 for (p = t->tests; p; p = p->next) {
66 char *name = talloc_asprintf(NULL, "%s.%s.%s", prefix, t->name, p->name);
67 if (strncmp(name, expr, strlen(expr)) == 0) {
68 printf("%s\n", name);
70 talloc_free(name);
75 static bool run_matching(struct torture_context *torture,
76 const char *prefix,
77 const char *expr,
78 const char **restricted,
79 struct torture_suite *suite,
80 bool *matched)
82 bool ret = true;
83 struct torture_suite *o;
84 struct torture_tcase *t;
85 struct torture_test *p;
87 for (o = suite->children; o; o = o->next) {
88 char *name = NULL;
89 name = prefix_name(torture, prefix, o->name);
90 if (gen_fnmatch(expr, name) == 0) {
91 *matched = true;
92 reload_charcnv(torture->lp_ctx);
93 if (use_fullname == 1) {
94 torture_subunit_prefix_reset(torture, prefix);
96 ret &= torture_run_suite_restricted(torture, o, restricted);
97 if (use_fullname == 1) {
98 torture_subunit_prefix_reset(torture, NULL);
101 * torture_run_suite_restricted() already implements
102 * recursion, so we're done with this child suite.
104 continue;
106 ret &= run_matching(torture, name, expr, restricted, o, matched);
109 for (t = suite->testcases; t; t = t->next) {
110 char *tname = prefix_name(torture, prefix, t->name);
111 if (gen_fnmatch(expr, tname) == 0) {
112 *matched = true;
113 reload_charcnv(torture->lp_ctx);
114 if (use_fullname == 1) {
115 torture_subunit_prefix_reset(torture, prefix);
117 ret &= torture_run_tcase_restricted(torture, t, restricted);
118 if (use_fullname == 1) {
119 torture_subunit_prefix_reset(torture, NULL);
122 * torture_run_tcase_restricted() already implements
123 * recursion, so we're done for this tcase.
125 continue;
127 for (p = t->tests; p; p = p->next) {
128 char *pname = prefix_name(torture, tname, p->name);
129 if (gen_fnmatch(expr, pname) == 0) {
130 *matched = true;
131 reload_charcnv(torture->lp_ctx);
132 if (use_fullname == 1) {
133 torture_subunit_prefix_reset(torture,
134 tname);
136 ret &= torture_run_test_restricted(torture, t, p, restricted);
137 if (use_fullname == 1) {
138 torture_subunit_prefix_reset(torture,
139 NULL);
145 return ret;
148 #define MAX_COLS 80 /* FIXME: Determine this at run-time */
150 /****************************************************************************
151 run a specified test or "ALL"
152 ****************************************************************************/
153 bool torture_run_named_tests(struct torture_context *torture, const char *name,
154 const char **restricted)
156 bool ret = true;
157 bool matched = false;
158 struct torture_suite *o;
160 torture_ui_report_time(torture);
162 if (strequal(name, "ALL")) {
163 if (restricted != NULL) {
164 printf("--load-list and ALL are incompatible\n");
165 return false;
167 for (o = torture_root->children; o; o = o->next) {
168 ret &= torture_run_suite(torture, o);
170 return ret;
173 ret = run_matching(torture, NULL, name, restricted, torture_root, &matched);
175 if (!matched) {
176 printf("Unknown torture operation '%s'\n", name);
177 return false;
180 return ret;
183 bool torture_parse_target(TALLOC_CTX *ctx,
184 struct loadparm_context *lp_ctx,
185 const char *target)
187 char *host = NULL, *share = NULL;
188 struct dcerpc_binding *binding_struct;
189 NTSTATUS status;
191 /* see if its a RPC transport specifier */
192 if (!smbcli_parse_unc(target, NULL, &host, &share)) {
193 const char *h;
195 status = dcerpc_parse_binding(ctx, target, &binding_struct);
196 if (NT_STATUS_IS_ERR(status)) {
197 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", target);
198 return false;
201 h = dcerpc_binding_get_string_option(binding_struct, "host");
202 host = discard_const_p(char, h);
203 if (host != NULL) {
204 lpcfg_set_cmdline(lp_ctx, "torture:host", host);
207 if (lpcfg_parm_string(lp_ctx, NULL, "torture", "share") == NULL)
208 lpcfg_set_cmdline(lp_ctx, "torture:share", "IPC$");
209 lpcfg_set_cmdline(lp_ctx, "torture:binding", target);
210 } else {
211 lpcfg_set_cmdline(lp_ctx, "torture:host", host);
212 lpcfg_set_cmdline(lp_ctx, "torture:share", share);
213 lpcfg_set_cmdline(lp_ctx, "torture:binding", host);
216 return true;
219 static void parse_dns(struct loadparm_context *lp_ctx, const char *dns)
221 char *userdn, *basedn, *secret;
222 char *p, *d;
224 /* retrieve the userdn */
225 p = strchr_m(dns, '#');
226 if (!p) {
227 lpcfg_set_cmdline(lp_ctx, "torture:ldap_userdn", "");
228 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", "");
229 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
230 return;
232 userdn = strndup(dns, p - dns);
233 lpcfg_set_cmdline(lp_ctx, "torture:ldap_userdn", userdn);
235 /* retrieve the basedn */
236 d = p + 1;
237 p = strchr_m(d, '#');
238 if (!p) {
239 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", "");
240 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
241 return;
243 basedn = strndup(d, p - d);
244 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", basedn);
246 /* retrieve the secret */
247 p = p + 1;
248 if (!p) {
249 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
250 return;
252 secret = strdup(p);
253 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", secret);
255 printf ("%s - %s - %s\n", userdn, basedn, secret);
259 /* Print the full test list, formatted into separate labelled test
260 * groups.
262 static void print_structured_testsuite_list(void)
264 struct torture_suite *o;
265 struct torture_suite *s;
266 struct torture_tcase *t;
267 int i;
269 if (torture_root == NULL) {
270 printf("NO TESTS LOADED\n");
271 return;
274 for (o = torture_root->children; o; o = o->next) {
275 printf("\n%s (%s):\n ", o->description, o->name);
277 i = 0;
278 for (s = o->children; s; s = s->next) {
279 if (i + strlen(o->name) + strlen(s->name) >= (MAX_COLS - 3)) {
280 printf("\n ");
281 i = 0;
283 i+=printf("%s.%s ", o->name, s->name);
286 for (t = o->testcases; t; t = t->next) {
287 if (i + strlen(o->name) + strlen(t->name) >= (MAX_COLS - 3)) {
288 printf("\n ");
289 i = 0;
291 i+=printf("%s.%s ", o->name, t->name);
294 if (i) printf("\n");
297 printf("\nThe default test is ALL.\n");
300 static void print_testsuite_list(void)
302 struct torture_suite *o;
303 struct torture_suite *s;
304 struct torture_tcase *t;
306 if (torture_root == NULL)
307 return;
309 for (o = torture_root->children; o; o = o->next) {
310 for (s = o->children; s; s = s->next) {
311 printf("%s.%s\n", o->name, s->name);
314 for (t = o->testcases; t; t = t->next) {
315 printf("%s.%s\n", o->name, t->name);
320 void torture_print_testsuites(bool structured)
322 if (structured) {
323 print_structured_testsuite_list();
324 } else {
325 print_testsuite_list();
329 static void usage(poptContext pc)
331 poptPrintUsage(pc, stdout, 0);
332 printf("\n");
334 printf("The binding format is:\n\n");
336 printf(" TRANSPORT:host[flags]\n\n");
338 printf(" where TRANSPORT is either ncacn_np for SMB, ncacn_ip_tcp for RPC/TCP\n");
339 printf(" or ncalrpc for local connections.\n\n");
341 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
342 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
343 printf(" string.\n\n");
345 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
346 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
347 printf(" will be auto-determined.\n\n");
349 printf(" other recognised flags are:\n\n");
351 printf(" sign : enable ntlmssp signing\n");
352 printf(" seal : enable ntlmssp sealing\n");
353 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
354 printf(" validate: enable the NDR validator\n");
355 printf(" print: enable debugging of the packets\n");
356 printf(" bigendian: use bigendian RPC\n");
357 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
359 printf(" For example, these all connect to the samr pipe:\n\n");
361 printf(" ncacn_np:myserver\n");
362 printf(" ncacn_np:myserver[samr]\n");
363 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
364 printf(" ncacn_np:myserver[/pipe/samr]\n");
365 printf(" ncacn_np:myserver[samr,sign,print]\n");
366 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
367 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
368 printf(" ncacn_np:\n");
369 printf(" ncacn_np:[/pipe/samr]\n\n");
371 printf(" ncacn_ip_tcp:myserver\n");
372 printf(" ncacn_ip_tcp:myserver[1024]\n");
373 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
375 printf(" ncalrpc:\n\n");
377 printf("The UNC format is:\n\n");
379 printf(" //server/share\n\n");
381 printf("Tests are:");
383 print_structured_testsuite_list();
387 _NORETURN_ static void max_runtime_handler(int sig)
389 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
390 exit(1);
393 /****************************************************************************
394 main program
395 ****************************************************************************/
396 int main(int argc, const char *argv[])
398 int opt, i;
399 bool correct = true;
400 int max_runtime=0;
401 int argc_new;
402 struct torture_context *torture;
403 struct torture_results *results;
404 const struct torture_ui_ops *ui_ops;
405 char **argv_new;
406 poptContext pc;
407 static const char *target = "other";
408 NTSTATUS status;
409 int shell = false;
410 static const char *ui_ops_name = "subunit";
411 const char *basedir = NULL;
412 char *outputdir;
413 const char *extra_module = NULL;
414 static int list_tests = 0, list_testsuites = 0;
415 int num_extra_users = 0;
416 const char **restricted = NULL;
417 int num_restricted = -1;
418 const char *load_list = NULL;
419 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS, OPT_LIST,
420 OPT_DANGEROUS,OPT_SMB_PORTS,OPT_ASYNC,OPT_NUMPROGS,
421 OPT_EXTRA_USER,};
422 TALLOC_CTX *mem_ctx = NULL;
423 struct loadparm_context *lp_ctx = NULL;
424 bool ok;
426 struct poptOption long_options[] = {
427 POPT_AUTOHELP
428 {"fullname", 0, POPT_ARG_NONE, &use_fullname, 0,
429 "use full name for the test", NULL },
430 {"format", 0, POPT_ARG_STRING, &ui_ops_name, 0, "Output format (one of: simple, subunit)", NULL },
431 {"smb-ports", 'p', POPT_ARG_STRING, NULL, OPT_SMB_PORTS, "SMB ports", NULL},
432 {"basedir", 0, POPT_ARG_STRING, &basedir, 0, "base directory", "BASEDIR" },
433 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "Seed to use for randomizer", NULL},
434 {"num-progs", 0, POPT_ARG_INT, NULL, OPT_NUMPROGS, "num progs", NULL},
435 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
436 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
437 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "NBench load file to use", NULL},
438 {"list-suites", 0, POPT_ARG_NONE, &list_testsuites, 0, "List available testsuites and exit", NULL },
439 {"list", 0, POPT_ARG_NONE, &list_tests, 0, "List available tests in specified suites and exit", NULL },
440 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
441 {"timelimit", 't', POPT_ARG_INT, NULL, OPT_TIMELIMIT, "Set time limit (in seconds)", NULL},
442 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
443 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
444 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS,
445 "run dangerous tests (eg. wiping out password database)", NULL},
446 {"load-module", 0, POPT_ARG_STRING, &extra_module, 0, "load tests from DSO file", "SOFILE"},
447 {"shell", 0, POPT_ARG_NONE, &shell, true, "Run shell", NULL},
448 {"target", 'T', POPT_ARG_STRING, &target, 0, "samba3|samba4|other", NULL},
449 {"async", 'a', POPT_ARG_NONE, NULL, OPT_ASYNC,
450 "run async tests", NULL},
451 {"num-async", 0, POPT_ARG_INT, &torture_numasync, 0,
452 "number of simultaneous async requests", NULL},
453 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
454 "set maximum time for smbtorture to live", "seconds"},
455 {"extra-user", 0, POPT_ARG_STRING, NULL, OPT_EXTRA_USER,
456 "extra user credentials", NULL},
457 {"load-list", 0, POPT_ARG_STRING, &load_list, 0,
458 "load a test id list from a text file", NULL},
459 POPT_COMMON_SAMBA
460 POPT_COMMON_CONNECTION
461 POPT_COMMON_CREDENTIALS
462 POPT_COMMON_VERSION
463 POPT_LEGACY_S4
464 POPT_TABLEEND
467 setlinebuf(stdout);
469 mem_ctx = talloc_named_const(NULL, 0, "torture_ctx");
470 if (mem_ctx == NULL) {
471 printf("Unable to allocate torture_ctx\n");
472 exit(1);
475 printf("smbtorture %s\n", samba_version_string());
477 /* we are never interested in SIGPIPE */
478 BlockSignals(true, SIGPIPE);
480 ok = samba_cmdline_init(mem_ctx,
481 SAMBA_CMDLINE_CONFIG_CLIENT,
482 false /* require_smbconf */);
483 if (!ok) {
484 DBG_ERR("Unable to init cmdline parser\n");
485 TALLOC_FREE(mem_ctx);
486 exit(1);
489 pc = samba_popt_get_context(getprogname(),
490 argc,
491 argv,
492 long_options,
493 POPT_CONTEXT_KEEP_FIRST);
494 if (pc == NULL) {
495 DBG_ERR("Failed cmdline parser\n");
496 TALLOC_FREE(mem_ctx);
497 exit(1);
500 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
502 lp_ctx = samba_cmdline_get_lp_ctx();
504 while((opt = poptGetNextOpt(pc)) != -1) {
505 switch (opt) {
506 case OPT_LOADFILE:
507 lpcfg_set_cmdline(lp_ctx, "torture:loadfile", poptGetOptArg(pc));
508 break;
509 case OPT_UNCLIST:
510 lpcfg_set_cmdline(lp_ctx, "torture:unclist", poptGetOptArg(pc));
511 break;
512 case OPT_TIMELIMIT:
513 lpcfg_set_cmdline(lp_ctx, "torture:timelimit", poptGetOptArg(pc));
514 break;
515 case OPT_NUMPROGS:
516 lpcfg_set_cmdline(lp_ctx, "torture:nprocs", poptGetOptArg(pc));
517 break;
518 case OPT_DNS:
519 parse_dns(lp_ctx, poptGetOptArg(pc));
520 break;
521 case OPT_DANGEROUS:
522 lpcfg_set_cmdline(lp_ctx, "torture:dangerous", "Yes");
523 break;
524 case OPT_ASYNC:
525 lpcfg_set_cmdline(lp_ctx, "torture:async", "Yes");
526 break;
527 case OPT_SMB_PORTS:
528 lpcfg_set_cmdline(lp_ctx, "smb ports", poptGetOptArg(pc));
529 break;
530 case OPT_EXTRA_USER:
532 char *option = talloc_asprintf(mem_ctx,
533 "torture:extra_user%u",
534 ++num_extra_users);
535 const char *value = poptGetOptArg(pc);
536 if (option == NULL) {
537 printf("talloc fail\n");
538 talloc_free(mem_ctx);
539 exit(1);
541 lpcfg_set_cmdline(lp_ctx, option, value);
542 talloc_free(option);
544 break;
545 default:
546 if (opt < 0) {
547 printf("Invalid command line option %s (%d)\n",
548 poptBadOption(pc, 0),
549 opt);
550 talloc_free(mem_ctx);
551 exit(1);
556 if (load_list != NULL) {
557 char **r;
558 r = file_lines_load(load_list, &num_restricted, 0, mem_ctx);
559 restricted = discard_const_p(const char *, r);
560 if (restricted == NULL) {
561 printf("Unable to read load list file '%s'\n", load_list);
562 talloc_free(mem_ctx);
563 exit(1);
567 if (strcmp(target, "samba3") == 0) {
568 lpcfg_set_cmdline(lp_ctx, "torture:samba3", "true");
569 lpcfg_set_cmdline(lp_ctx, "torture:resume_key_support", "false");
570 } else if (strcmp(target, "samba4") == 0) {
571 lpcfg_set_cmdline(lp_ctx, "torture:samba4", "true");
572 } else if (strcmp(target, "samba4-ntvfs") == 0) {
573 lpcfg_set_cmdline(lp_ctx, "torture:samba4", "true");
574 lpcfg_set_cmdline(lp_ctx, "torture:samba4-ntvfs", "true");
575 } else if (strcmp(target, "winxp") == 0) {
576 lpcfg_set_cmdline(lp_ctx, "torture:winxp", "true");
577 } else if (strcmp(target, "w2k3") == 0) {
578 lpcfg_set_cmdline(lp_ctx, "torture:w2k3", "true");
579 } else if (strcmp(target, "w2k8") == 0) {
580 lpcfg_set_cmdline(lp_ctx, "torture:w2k8", "true");
581 lpcfg_set_cmdline(lp_ctx,
582 "torture:invalid_lock_range_support", "false");
583 } else if (strcmp(target, "w2k12") == 0) {
584 lpcfg_set_cmdline(lp_ctx, "torture:w2k12", "true");
585 } else if (strcmp(target, "win7") == 0) {
586 lpcfg_set_cmdline(lp_ctx, "torture:win7", "true");
587 lpcfg_set_cmdline(lp_ctx, "torture:resume_key_support", "false");
588 lpcfg_set_cmdline(lp_ctx, "torture:rewind_support", "false");
590 /* RAW-SEARCH for fails for inexplicable reasons against win7 */
591 lpcfg_set_cmdline(lp_ctx, "torture:search_ea_support", "false");
593 lpcfg_set_cmdline(lp_ctx, "torture:hide_on_access_denied",
594 "true");
595 } else if (strcmp(target, "onefs") == 0) {
596 lpcfg_set_cmdline(lp_ctx, "torture:onefs", "true");
597 lpcfg_set_cmdline(lp_ctx, "torture:openx_deny_dos_support",
598 "false");
599 lpcfg_set_cmdline(lp_ctx, "torture:range_not_locked_on_file_close", "false");
600 lpcfg_set_cmdline(lp_ctx, "torture:sacl_support", "false");
601 lpcfg_set_cmdline(lp_ctx, "torture:ea_support", "false");
602 lpcfg_set_cmdline(lp_ctx, "torture:smbexit_pdu_support",
603 "false");
604 lpcfg_set_cmdline(lp_ctx, "torture:smblock_pdu_support",
605 "false");
606 lpcfg_set_cmdline(lp_ctx, "torture:2_step_break_to_none",
607 "true");
608 lpcfg_set_cmdline(lp_ctx, "torture:deny_dos_support", "false");
609 lpcfg_set_cmdline(lp_ctx, "torture:deny_fcb_support", "false");
610 lpcfg_set_cmdline(lp_ctx, "torture:read_support", "false");
611 lpcfg_set_cmdline(lp_ctx, "torture:writeclose_support", "false");
612 lpcfg_set_cmdline(lp_ctx, "torture:resume_key_support", "false");
613 lpcfg_set_cmdline(lp_ctx, "torture:rewind_support", "false");
614 lpcfg_set_cmdline(lp_ctx, "torture:raw_search_search", "false");
615 lpcfg_set_cmdline(lp_ctx, "torture:search_ea_size", "false");
618 if (max_runtime) {
619 /* this will only work if nobody else uses alarm(),
620 which means it won't work for some tests, but we
621 can't use the event context method we use for smbd
622 as so many tests create their own event
623 context. This will at least catch most cases. */
624 signal(SIGALRM, max_runtime_handler);
625 alarm(max_runtime);
628 if (extra_module != NULL) {
629 init_module_fn fn = load_module(poptGetOptArg(pc), false, NULL);
631 if (fn == NULL)
632 d_printf("Unable to load module from %s\n", poptGetOptArg(pc));
633 else {
634 status = fn(mem_ctx);
635 if (NT_STATUS_IS_ERR(status)) {
636 d_printf("Error initializing module %s: %s\n",
637 poptGetOptArg(pc), nt_errstr(status));
640 } else {
641 torture_init(mem_ctx);
644 if (list_testsuites) {
645 print_testsuite_list();
646 poptFreeContext(pc);
647 talloc_free(mem_ctx);
648 return 0;
651 argv_new = discard_const_p(char *, poptGetArgs(pc));
653 argc_new = argc;
654 for (i=0; i<argc; i++) {
655 if (argv_new[i] == NULL) {
656 argc_new = i;
657 break;
661 if (list_tests) {
662 if (argc_new == 1) {
663 print_test_list(torture_root, NULL, "");
664 } else {
665 for (i=1;i<argc_new;i++) {
666 print_test_list(torture_root, NULL, argv_new[i]);
669 poptFreeContext(pc);
670 talloc_free(mem_ctx);
671 return 0;
674 if (torture_seed == 0) {
675 torture_seed = time(NULL);
677 printf("Using seed %d\n", torture_seed);
678 srandom(torture_seed);
680 if (!strcmp(ui_ops_name, "simple")) {
681 ui_ops = &torture_simple_ui_ops;
682 } else if (!strcmp(ui_ops_name, "subunit")) {
683 ui_ops = &torture_subunit_ui_ops;
684 } else {
685 printf("Unknown output format '%s'\n", ui_ops_name);
686 talloc_free(mem_ctx);
687 exit(1);
690 results = torture_results_init(mem_ctx, ui_ops);
692 torture = torture_context_init(s4_event_context_init(mem_ctx),
693 results);
694 if (basedir != NULL) {
695 if (basedir[0] != '/') {
696 fprintf(stderr, "Please specify an absolute path to --basedir\n");
697 poptFreeContext(pc);
698 talloc_free(mem_ctx);
699 return 1;
701 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", basedir);
702 } else {
703 char *pwd = talloc_size(torture, PATH_MAX);
704 if (!getcwd(pwd, PATH_MAX)) {
705 fprintf(stderr, "Unable to determine current working directory\n");
706 poptFreeContext(pc);
707 talloc_free(mem_ctx);
708 return 1;
710 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", pwd);
712 if (!outputdir) {
713 fprintf(stderr, "Could not allocate per-run output dir\n");
714 poptFreeContext(pc);
715 talloc_free(mem_ctx);
716 return 1;
718 torture->outputdir = mkdtemp(outputdir);
719 if (!torture->outputdir) {
720 perror("Failed to make temp output dir");
721 poptFreeContext(pc);
722 talloc_free(mem_ctx);
723 return 1;
726 torture->lp_ctx = lp_ctx;
728 gensec_init();
730 if (shell) {
731 /* In shell mode, just ignore any remaining test names. */
732 torture_shell(torture);
733 } else {
735 /* At this point, we should just have a target string,
736 * followed by a series of test names. Unless we are in
737 * shell mode, in which case we don't need anything more.
740 if (argc_new < 3) {
741 printf("You must specify a test to run, or 'ALL'\n");
742 usage(pc);
743 torture->results->returncode = 1;
744 } else if (!torture_parse_target(torture,
745 lp_ctx, argv_new[1])) {
746 /* Take the target name or binding. */
747 usage(pc);
748 torture->results->returncode = 1;
749 } else {
750 for (i=2;i<argc_new;i++) {
751 if (!torture_run_named_tests(torture, argv_new[i],
752 (const char **)restricted)) {
753 correct = false;
759 /* Now delete the temp dir we created */
760 torture_deltree_outputdir(torture);
762 if (torture->results->returncode && correct) {
763 poptFreeContext(pc);
764 talloc_free(mem_ctx);
765 return(0);
766 } else {
767 poptFreeContext(pc);
768 talloc_free(mem_ctx);
769 return(1);