s4:smbtorture Create a new random output directory each time, and delete it
[Samba/gebeck_regimport.git] / source4 / torture / smbtorture.c
blob36b8c0f37773c4e234885bdc05cafd0412d1548d
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/cmdline/popt_common.h"
23 #include "system/time.h"
24 #include "system/wait.h"
25 #include "system/filesys.h"
26 #include "system/readline.h"
27 #include "../libcli/smbreadline/smbreadline.h"
28 #include "libcli/libcli.h"
29 #include "lib/events/events.h"
31 #include "torture/smbtorture.h"
32 #include "librpc/rpc/dcerpc.h"
33 #include "auth/gensec/gensec.h"
34 #include "param/param.h"
36 #if HAVE_READLINE_HISTORY_H
37 #include <readline/history.h>
38 #endif
40 static bool run_matching(struct torture_context *torture,
41 const char *prefix,
42 const char *expr,
43 const char **restricted,
44 struct torture_suite *suite,
45 bool *matched)
47 bool ret = true;
48 struct torture_suite *o;
49 struct torture_tcase *t;
50 struct torture_test *p;
52 for (o = suite->children; o; o = o->next) {
53 char *name = NULL;
54 if (prefix == NULL)
55 name = talloc_strdup(torture, o->name);
56 else
57 name = talloc_asprintf(torture, "%s-%s", prefix, o->name);
58 if (gen_fnmatch(expr, name) == 0) {
59 *matched = true;
60 reload_charcnv(torture->lp_ctx);
61 if (restricted != NULL)
62 ret &= torture_run_suite_restricted(torture, o, restricted);
63 else
64 ret &= torture_run_suite(torture, o);
66 ret &= run_matching(torture, name, expr, restricted, o, matched);
69 for (t = suite->testcases; t; t = t->next) {
70 char *name = talloc_asprintf(torture, "%s-%s", prefix, t->name);
71 if (gen_fnmatch(expr, name) == 0) {
72 *matched = true;
73 reload_charcnv(torture->lp_ctx);
74 ret &= torture_run_tcase_restricted(torture, t, restricted);
76 for (p = t->tests; p; p = p->next) {
77 name = talloc_asprintf(torture, "%s-%s-%s", prefix, t->name, p->name);
78 if (gen_fnmatch(expr, name) == 0) {
79 *matched = true;
80 reload_charcnv(torture->lp_ctx);
81 ret &= torture_run_test_restricted(torture, t, p, restricted);
86 return ret;
89 #define MAX_COLS 80 /* FIXME: Determine this at run-time */
91 /****************************************************************************
92 run a specified test or "ALL"
93 ****************************************************************************/
94 bool torture_run_named_tests(struct torture_context *torture, const char *name,
95 const char **restricted)
97 bool ret = true;
98 bool matched = false;
99 struct torture_suite *o;
101 torture_ui_report_time(torture);
103 if (strequal(name, "ALL")) {
104 if (restricted != NULL) {
105 printf("--load-list and ALL are incompatible\n");
106 return false;
108 for (o = torture_root->children; o; o = o->next) {
109 ret &= torture_run_suite(torture, o);
111 return ret;
114 ret = run_matching(torture, NULL, name, restricted, torture_root, &matched);
116 if (!matched) {
117 printf("Unknown torture operation '%s'\n", name);
118 return false;
121 return ret;
124 bool torture_parse_target(struct loadparm_context *lp_ctx, const char *target)
126 char *host = NULL, *share = NULL;
127 struct dcerpc_binding *binding_struct;
128 NTSTATUS status;
130 /* see if its a RPC transport specifier */
131 if (!smbcli_parse_unc(target, NULL, &host, &share)) {
132 status = dcerpc_parse_binding(talloc_autofree_context(), target, &binding_struct);
133 if (NT_STATUS_IS_ERR(status)) {
134 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", target);
135 return false;
137 lpcfg_set_cmdline(lp_ctx, "torture:host", binding_struct->host);
138 if (lpcfg_parm_string(lp_ctx, NULL, "torture", "share") == NULL)
139 lpcfg_set_cmdline(lp_ctx, "torture:share", "IPC$");
140 lpcfg_set_cmdline(lp_ctx, "torture:binding", target);
141 } else {
142 lpcfg_set_cmdline(lp_ctx, "torture:host", host);
143 lpcfg_set_cmdline(lp_ctx, "torture:share", share);
144 lpcfg_set_cmdline(lp_ctx, "torture:binding", host);
147 return true;
150 static void parse_dns(struct loadparm_context *lp_ctx, const char *dns)
152 char *userdn, *basedn, *secret;
153 char *p, *d;
155 /* retrievieng the userdn */
156 p = strchr_m(dns, '#');
157 if (!p) {
158 lpcfg_set_cmdline(lp_ctx, "torture:ldap_userdn", "");
159 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", "");
160 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
161 return;
163 userdn = strndup(dns, p - dns);
164 lpcfg_set_cmdline(lp_ctx, "torture:ldap_userdn", userdn);
166 /* retrieve the basedn */
167 d = p + 1;
168 p = strchr_m(d, '#');
169 if (!p) {
170 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", "");
171 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
172 return;
174 basedn = strndup(d, p - d);
175 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", basedn);
177 /* retrieve the secret */
178 p = p + 1;
179 if (!p) {
180 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
181 return;
183 secret = strdup(p);
184 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", secret);
186 printf ("%s - %s - %s\n", userdn, basedn, secret);
190 /* Print the full test list, formatted into separate labelled test
191 * groups.
193 static void print_structured_test_list(void)
195 struct torture_suite *o;
196 struct torture_suite *s;
197 struct torture_tcase *t;
198 int i;
200 if (torture_root == NULL) {
201 printf("NO TESTS LOADED\n");
202 return;
205 for (o = torture_root->children; o; o = o->next) {
206 printf("\n%s (%s):\n ", o->description, o->name);
208 i = 0;
209 for (s = o->children; s; s = s->next) {
210 if (i + strlen(o->name) + strlen(s->name) >= (MAX_COLS - 3)) {
211 printf("\n ");
212 i = 0;
214 i+=printf("%s-%s ", o->name, s->name);
217 for (t = o->testcases; t; t = t->next) {
218 if (i + strlen(o->name) + strlen(t->name) >= (MAX_COLS - 3)) {
219 printf("\n ");
220 i = 0;
222 i+=printf("%s-%s ", o->name, t->name);
225 if (i) printf("\n");
228 printf("\nThe default test is ALL.\n");
231 static void print_test_list(void)
233 struct torture_suite *o;
234 struct torture_suite *s;
235 struct torture_tcase *t;
237 if (torture_root == NULL)
238 return;
240 for (o = torture_root->children; o; o = o->next) {
241 for (s = o->children; s; s = s->next) {
242 printf("%s-%s\n", o->name, s->name);
245 for (t = o->testcases; t; t = t->next) {
246 printf("%s-%s\n", o->name, t->name);
251 void torture_print_tests(bool structured)
253 if (structured) {
254 print_structured_test_list();
255 } else {
256 print_test_list();
260 _NORETURN_ static void usage(poptContext pc)
262 poptPrintUsage(pc, stdout, 0);
263 printf("\n");
265 printf("The binding format is:\n\n");
267 printf(" TRANSPORT:host[flags]\n\n");
269 printf(" where TRANSPORT is either ncacn_np for SMB, ncacn_ip_tcp for RPC/TCP\n");
270 printf(" or ncalrpc for local connections.\n\n");
272 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
273 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
274 printf(" string.\n\n");
276 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
277 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
278 printf(" will be auto-determined.\n\n");
280 printf(" other recognised flags are:\n\n");
282 printf(" sign : enable ntlmssp signing\n");
283 printf(" seal : enable ntlmssp sealing\n");
284 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
285 printf(" validate: enable the NDR validator\n");
286 printf(" print: enable debugging of the packets\n");
287 printf(" bigendian: use bigendian RPC\n");
288 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
290 printf(" For example, these all connect to the samr pipe:\n\n");
292 printf(" ncacn_np:myserver\n");
293 printf(" ncacn_np:myserver[samr]\n");
294 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
295 printf(" ncacn_np:myserver[/pipe/samr]\n");
296 printf(" ncacn_np:myserver[samr,sign,print]\n");
297 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
298 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
299 printf(" ncacn_np:\n");
300 printf(" ncacn_np:[/pipe/samr]\n\n");
302 printf(" ncacn_ip_tcp:myserver\n");
303 printf(" ncacn_ip_tcp:myserver[1024]\n");
304 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
306 printf(" ncalrpc:\n\n");
308 printf("The UNC format is:\n\n");
310 printf(" //server/share\n\n");
312 printf("Tests are:");
314 print_structured_test_list();
316 exit(1);
319 _NORETURN_ static void max_runtime_handler(int sig)
321 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
322 exit(1);
325 struct timeval last_suite_started;
327 static void simple_suite_start(struct torture_context *ctx,
328 struct torture_suite *suite)
330 last_suite_started = timeval_current();
331 printf("Running %s\n", suite->name);
334 static void simple_suite_finish(struct torture_context *ctx,
335 struct torture_suite *suite)
338 printf("%s took %g secs\n\n", suite->name,
339 timeval_elapsed(&last_suite_started));
342 static void simple_test_result(struct torture_context *context,
343 enum torture_result res, const char *reason)
345 switch (res) {
346 case TORTURE_OK:
347 if (reason)
348 printf("OK: %s\n", reason);
349 break;
350 case TORTURE_FAIL:
351 printf("TEST %s FAILED! - %s\n", context->active_test->name, reason);
352 break;
353 case TORTURE_ERROR:
354 printf("ERROR IN TEST %s! - %s\n", context->active_test->name, reason);
355 break;
356 case TORTURE_SKIP:
357 printf("SKIP: %s - %s\n", context->active_test->name, reason);
358 break;
362 static void simple_comment(struct torture_context *test,
363 const char *comment)
365 printf("%s", comment);
368 static void simple_warning(struct torture_context *test,
369 const char *comment)
371 fprintf(stderr, "WARNING: %s\n", comment);
374 static void simple_progress(struct torture_context *test,
375 int offset, enum torture_progress_whence whence)
379 const static struct torture_ui_ops std_ui_ops = {
380 .comment = simple_comment,
381 .warning = simple_warning,
382 .suite_start = simple_suite_start,
383 .suite_finish = simple_suite_finish,
384 .test_result = simple_test_result,
385 .progress = simple_progress,
388 /****************************************************************************
389 main program
390 ****************************************************************************/
391 int main(int argc,char *argv[])
393 int opt, i;
394 bool correct = true;
395 int max_runtime=0;
396 int argc_new;
397 struct torture_context *torture;
398 struct torture_results *results;
399 const struct torture_ui_ops *ui_ops;
400 char **argv_new;
401 poptContext pc;
402 static const char *target = "other";
403 NTSTATUS status;
404 int shell = false;
405 static const char *ui_ops_name = "subunit";
406 const char *basedir = NULL;
407 char *outputdir;
408 const char *extra_module = NULL;
409 static int list_tests = 0;
410 int num_extra_users = 0;
411 char **restricted = NULL;
412 int num_restricted = -1;
413 const char *load_list = NULL;
414 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS, OPT_LIST,
415 OPT_DANGEROUS,OPT_SMB_PORTS,OPT_ASYNC,OPT_NUMPROGS,
416 OPT_EXTRA_USER,};
418 struct poptOption long_options[] = {
419 POPT_AUTOHELP
420 {"format", 0, POPT_ARG_STRING, &ui_ops_name, 0, "Output format (one of: simple, subunit)", NULL },
421 {"smb-ports", 'p', POPT_ARG_STRING, NULL, OPT_SMB_PORTS, "SMB ports", NULL},
422 {"basedir", 0, POPT_ARG_STRING, &basedir, 0, "base directory", "BASEDIR" },
423 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "Seed to use for randomizer", NULL},
424 {"num-progs", 0, POPT_ARG_INT, NULL, OPT_NUMPROGS, "num progs", NULL},
425 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
426 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
427 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "NBench load file to use", NULL},
428 {"list", 0, POPT_ARG_NONE, &list_tests, 0, "List available tests and exit", NULL },
429 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
430 {"timelimit", 't', POPT_ARG_INT, NULL, OPT_TIMELIMIT, "Set time limit (in seconds)", NULL},
431 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
432 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
433 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS,
434 "run dangerous tests (eg. wiping out password database)", NULL},
435 {"load-module", 0, POPT_ARG_STRING, &extra_module, 0, "load tests from DSO file", "SOFILE"},
436 {"shell", 0, POPT_ARG_NONE, &shell, true, "Run shell", NULL},
437 {"target", 'T', POPT_ARG_STRING, &target, 0, "samba3|samba4|other", NULL},
438 {"async", 'a', POPT_ARG_NONE, NULL, OPT_ASYNC,
439 "run async tests", NULL},
440 {"num-async", 0, POPT_ARG_INT, &torture_numasync, 0,
441 "number of simultaneous async requests", NULL},
442 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
443 "set maximum time for smbtorture to live", "seconds"},
444 {"extra-user", 0, POPT_ARG_STRING, NULL, OPT_EXTRA_USER,
445 "extra user credentials", NULL},
446 {"load-list", 0, POPT_ARG_STRING, &load_list, 0,
447 "load a test id list from a text file", NULL},
448 POPT_COMMON_SAMBA
449 POPT_COMMON_CONNECTION
450 POPT_COMMON_CREDENTIALS
451 POPT_COMMON_VERSION
452 { NULL }
455 setlinebuf(stdout);
457 /* we are never interested in SIGPIPE */
458 BlockSignals(true, SIGPIPE);
460 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
461 POPT_CONTEXT_KEEP_FIRST);
463 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
465 while((opt = poptGetNextOpt(pc)) != -1) {
466 switch (opt) {
467 case OPT_LOADFILE:
468 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:loadfile", poptGetOptArg(pc));
469 break;
470 case OPT_UNCLIST:
471 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:unclist", poptGetOptArg(pc));
472 break;
473 case OPT_TIMELIMIT:
474 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:timelimit", poptGetOptArg(pc));
475 break;
476 case OPT_NUMPROGS:
477 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:nprocs", poptGetOptArg(pc));
478 break;
479 case OPT_DNS:
480 parse_dns(cmdline_lp_ctx, poptGetOptArg(pc));
481 break;
482 case OPT_DANGEROUS:
483 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:dangerous", "Yes");
484 break;
485 case OPT_ASYNC:
486 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:async", "Yes");
487 break;
488 case OPT_SMB_PORTS:
489 lpcfg_set_cmdline(cmdline_lp_ctx, "smb ports", poptGetOptArg(pc));
490 break;
491 case OPT_EXTRA_USER:
493 char *option = talloc_asprintf(NULL, "torture:extra_user%u",
494 ++num_extra_users);
495 const char *value = poptGetOptArg(pc);
496 lpcfg_set_cmdline(cmdline_lp_ctx, option, value);
497 talloc_free(option);
499 break;
500 default:
501 if (opt < 0) {
502 printf("bad command line option %d\n", opt);
503 exit(1);
508 if (load_list != NULL) {
509 restricted = file_lines_load(load_list, &num_restricted, 0,
510 talloc_autofree_context());
511 if (restricted == NULL) {
512 printf("Unable to read load list file '%s'\n", load_list);
513 exit(1);
517 if (strcmp(target, "samba3") == 0) {
518 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:samba3", "true");
519 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:resume_key_support", "false");
520 } else if (strcmp(target, "samba4") == 0) {
521 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:samba4", "true");
522 } else if (strcmp(target, "winxp") == 0) {
523 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:winxp", "true");
524 } else if (strcmp(target, "w2k3") == 0) {
525 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:w2k3", "true");
526 } else if (strcmp(target, "w2k8") == 0) {
527 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:w2k8", "true");
528 lpcfg_set_cmdline(cmdline_lp_ctx,
529 "torture:invalid_lock_range_support", "false");
530 } else if (strcmp(target, "win7") == 0) {
531 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:win7", "true");
532 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:cn_max_buffer_size",
533 "0x00010000");
534 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:resume_key_support", "false");
535 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:rewind_support", "false");
537 /* RAW-SEARCH for fails for inexplicable reasons against win7 */
538 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:search_ea_support", "false");
540 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:hide_on_access_denied",
541 "true");
542 } else if (strcmp(target, "onefs") == 0) {
543 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:onefs", "true");
544 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:openx_deny_dos_support",
545 "false");
546 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:range_not_locked_on_file_close", "false");
547 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:sacl_support", "false");
548 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:ea_support", "false");
549 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:smbexit_pdu_support",
550 "false");
551 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:smblock_pdu_support",
552 "false");
553 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:2_step_break_to_none",
554 "true");
555 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:deny_dos_support", "false");
556 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:deny_fcb_support", "false");
557 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:read_support", "false");
558 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:writeclose_support", "false");
559 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:resume_key_support", "false");
560 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:rewind_support", "false");
561 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:raw_search_search", "false");
562 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:search_ea_size", "false");
565 if (max_runtime) {
566 /* this will only work if nobody else uses alarm(),
567 which means it won't work for some tests, but we
568 can't use the event context method we use for smbd
569 as so many tests create their own event
570 context. This will at least catch most cases. */
571 signal(SIGALRM, max_runtime_handler);
572 alarm(max_runtime);
575 if (extra_module != NULL) {
576 init_module_fn fn = load_module(talloc_autofree_context(), poptGetOptArg(pc));
578 if (fn == NULL)
579 d_printf("Unable to load module from %s\n", poptGetOptArg(pc));
580 else {
581 status = fn();
582 if (NT_STATUS_IS_ERR(status)) {
583 d_printf("Error initializing module %s: %s\n",
584 poptGetOptArg(pc), nt_errstr(status));
587 } else {
588 torture_init();
591 if (list_tests) {
592 print_test_list();
593 return 0;
596 if (torture_seed == 0) {
597 torture_seed = time(NULL);
599 printf("Using seed %d\n", torture_seed);
600 srandom(torture_seed);
602 argv_new = discard_const_p(char *, poptGetArgs(pc));
604 argc_new = argc;
605 for (i=0; i<argc; i++) {
606 if (argv_new[i] == NULL) {
607 argc_new = i;
608 break;
612 if (!strcmp(ui_ops_name, "simple")) {
613 ui_ops = &std_ui_ops;
614 } else if (!strcmp(ui_ops_name, "subunit")) {
615 ui_ops = &torture_subunit_ui_ops;
616 } else {
617 printf("Unknown output format '%s'\n", ui_ops_name);
618 exit(1);
621 results = torture_results_init(talloc_autofree_context(), ui_ops);
623 torture = torture_context_init(s4_event_context_init(talloc_autofree_context()),
624 results);
625 if (basedir != NULL) {
626 if (basedir[0] != '/') {
627 fprintf(stderr, "Please specify an absolute path to --basedir\n");
628 return 1;
630 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", basedir);
631 } else {
632 char *pwd = talloc_size(torture, PATH_MAX);
633 if (!getcwd(pwd, PATH_MAX)) {
634 fprintf(stderr, "Unable to determine current working directory\n");
635 return 1;
637 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", pwd);
639 if (!outputdir) {
640 fprintf(stderr, "Could not allocate per-run output dir\n");
641 return 1;
643 torture->outputdir = mkdtemp(outputdir);
644 if (!torture->outputdir) {
645 perror("Failed to make temp output dir");
648 torture->lp_ctx = cmdline_lp_ctx;
650 gensec_init(cmdline_lp_ctx);
652 if (shell) {
653 /* In shell mode, just ignore any remaining test names. */
654 torture_shell(torture);
655 } else {
657 /* At this point, we should just have a target string,
658 * followed by a series of test names. Unless we are in
659 * shell mode, in which case we don't need anythig more.
662 if (argc_new < 3) {
663 printf("You must specify a test to run, or 'ALL'\n");
664 usage(pc);
665 exit(1);
668 /* Take the target name or binding. */
669 if (!torture_parse_target(cmdline_lp_ctx, argv_new[1])) {
670 usage(pc);
671 exit(1);
674 for (i=2;i<argc_new;i++) {
675 if (!torture_run_named_tests(torture, argv_new[i],
676 (const char **)restricted)) {
677 correct = false;
682 /* Now delete the temp dir we created */
683 torture_deltree_outputdir(torture);
685 if (torture->results->returncode && correct) {
686 return(0);
687 } else {
688 return(1);