s3-printing: Fix obvious memory leak in printer_list_get_printer().
[Samba/wip.git] / source4 / torture / smbtorture.c
blob78f7dade26ec4c26ff71edcda539e2a27aace16e
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"
35 #include "lib/util/samba_modules.h"
37 #if HAVE_READLINE_HISTORY_H
38 #include <readline/history.h>
39 #endif
41 static char *prefix_name(TALLOC_CTX *mem_ctx, const char *prefix, const char *name)
43 if (prefix == NULL)
44 return talloc_strdup(mem_ctx, name);
45 else
46 return talloc_asprintf(mem_ctx, "%s.%s", prefix, name);
49 static void print_test_list(const struct torture_suite *suite, const char *prefix, const char *expr)
51 struct torture_suite *o;
52 struct torture_tcase *t;
53 struct torture_test *p;
55 for (o = suite->children; o; o = o->next) {
56 char *name = prefix_name(NULL, prefix, o->name);
57 print_test_list(o, name, expr);
58 talloc_free(name);
61 for (t = suite->testcases; t; t = t->next) {
62 for (p = t->tests; p; p = p->next) {
63 char *name = talloc_asprintf(NULL, "%s.%s.%s", prefix, t->name, p->name);
64 if (strncmp(name, expr, strlen(expr)) == 0) {
65 printf("%s\n", name);
67 talloc_free(name);
72 static bool run_matching(struct torture_context *torture,
73 const char *prefix,
74 const char *expr,
75 const char **restricted,
76 struct torture_suite *suite,
77 bool *matched)
79 bool ret = true;
80 struct torture_suite *o;
81 struct torture_tcase *t;
82 struct torture_test *p;
84 for (o = suite->children; o; o = o->next) {
85 char *name = NULL;
86 name = prefix_name(torture, prefix, o->name);
87 if (gen_fnmatch(expr, name) == 0) {
88 *matched = true;
89 reload_charcnv(torture->lp_ctx);
90 if (restricted != NULL)
91 ret &= torture_run_suite_restricted(torture, o, restricted);
92 else
93 ret &= torture_run_suite(torture, o);
95 ret &= run_matching(torture, name, expr, restricted, o, matched);
98 for (t = suite->testcases; t; t = t->next) {
99 char *name = talloc_asprintf(torture, "%s.%s", prefix, t->name);
100 if (gen_fnmatch(expr, name) == 0) {
101 *matched = true;
102 reload_charcnv(torture->lp_ctx);
103 ret &= torture_run_tcase_restricted(torture, t, restricted);
105 for (p = t->tests; p; p = p->next) {
106 name = talloc_asprintf(torture, "%s.%s.%s", prefix, t->name, p->name);
107 if (gen_fnmatch(expr, name) == 0) {
108 *matched = true;
109 reload_charcnv(torture->lp_ctx);
110 ret &= torture_run_test_restricted(torture, t, p, restricted);
115 return ret;
118 #define MAX_COLS 80 /* FIXME: Determine this at run-time */
120 /****************************************************************************
121 run a specified test or "ALL"
122 ****************************************************************************/
123 bool torture_run_named_tests(struct torture_context *torture, const char *name,
124 const char **restricted)
126 bool ret = true;
127 bool matched = false;
128 struct torture_suite *o;
130 torture_ui_report_time(torture);
132 if (strequal(name, "ALL")) {
133 if (restricted != NULL) {
134 printf("--load-list and ALL are incompatible\n");
135 return false;
137 for (o = torture_root->children; o; o = o->next) {
138 ret &= torture_run_suite(torture, o);
140 return ret;
143 ret = run_matching(torture, NULL, name, restricted, torture_root, &matched);
145 if (!matched) {
146 printf("Unknown torture operation '%s'\n", name);
147 return false;
150 return ret;
153 bool torture_parse_target(struct loadparm_context *lp_ctx, const char *target)
155 char *host = NULL, *share = NULL;
156 struct dcerpc_binding *binding_struct;
157 NTSTATUS status;
159 /* see if its a RPC transport specifier */
160 if (!smbcli_parse_unc(target, NULL, &host, &share)) {
161 status = dcerpc_parse_binding(talloc_autofree_context(), target, &binding_struct);
162 if (NT_STATUS_IS_ERR(status)) {
163 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", target);
164 return false;
167 host = dcerpc_binding_get_string_option(binding_struct, "host");
168 if (host != NULL) {
169 lpcfg_set_cmdline(lp_ctx, "torture:host", host);
172 if (lpcfg_parm_string(lp_ctx, NULL, "torture", "share") == NULL)
173 lpcfg_set_cmdline(lp_ctx, "torture:share", "IPC$");
174 lpcfg_set_cmdline(lp_ctx, "torture:binding", target);
175 } else {
176 lpcfg_set_cmdline(lp_ctx, "torture:host", host);
177 lpcfg_set_cmdline(lp_ctx, "torture:share", share);
178 lpcfg_set_cmdline(lp_ctx, "torture:binding", host);
181 return true;
184 static void parse_dns(struct loadparm_context *lp_ctx, const char *dns)
186 char *userdn, *basedn, *secret;
187 char *p, *d;
189 /* retrievieng the userdn */
190 p = strchr_m(dns, '#');
191 if (!p) {
192 lpcfg_set_cmdline(lp_ctx, "torture:ldap_userdn", "");
193 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", "");
194 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
195 return;
197 userdn = strndup(dns, p - dns);
198 lpcfg_set_cmdline(lp_ctx, "torture:ldap_userdn", userdn);
200 /* retrieve the basedn */
201 d = p + 1;
202 p = strchr_m(d, '#');
203 if (!p) {
204 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", "");
205 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
206 return;
208 basedn = strndup(d, p - d);
209 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", basedn);
211 /* retrieve the secret */
212 p = p + 1;
213 if (!p) {
214 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
215 return;
217 secret = strdup(p);
218 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", secret);
220 printf ("%s - %s - %s\n", userdn, basedn, secret);
224 /* Print the full test list, formatted into separate labelled test
225 * groups.
227 static void print_structured_testsuite_list(void)
229 struct torture_suite *o;
230 struct torture_suite *s;
231 struct torture_tcase *t;
232 int i;
234 if (torture_root == NULL) {
235 printf("NO TESTS LOADED\n");
236 return;
239 for (o = torture_root->children; o; o = o->next) {
240 printf("\n%s (%s):\n ", o->description, o->name);
242 i = 0;
243 for (s = o->children; s; s = s->next) {
244 if (i + strlen(o->name) + strlen(s->name) >= (MAX_COLS - 3)) {
245 printf("\n ");
246 i = 0;
248 i+=printf("%s.%s ", o->name, s->name);
251 for (t = o->testcases; t; t = t->next) {
252 if (i + strlen(o->name) + strlen(t->name) >= (MAX_COLS - 3)) {
253 printf("\n ");
254 i = 0;
256 i+=printf("%s.%s ", o->name, t->name);
259 if (i) printf("\n");
262 printf("\nThe default test is ALL.\n");
265 static void print_testsuite_list(void)
267 struct torture_suite *o;
268 struct torture_suite *s;
269 struct torture_tcase *t;
271 if (torture_root == NULL)
272 return;
274 for (o = torture_root->children; o; o = o->next) {
275 for (s = o->children; s; s = s->next) {
276 printf("%s.%s\n", o->name, s->name);
279 for (t = o->testcases; t; t = t->next) {
280 printf("%s.%s\n", o->name, t->name);
285 void torture_print_testsuites(bool structured)
287 if (structured) {
288 print_structured_testsuite_list();
289 } else {
290 print_testsuite_list();
294 static void usage(poptContext pc)
296 poptPrintUsage(pc, stdout, 0);
297 printf("\n");
299 printf("The binding format is:\n\n");
301 printf(" TRANSPORT:host[flags]\n\n");
303 printf(" where TRANSPORT is either ncacn_np for SMB, ncacn_ip_tcp for RPC/TCP\n");
304 printf(" or ncalrpc for local connections.\n\n");
306 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
307 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
308 printf(" string.\n\n");
310 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
311 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
312 printf(" will be auto-determined.\n\n");
314 printf(" other recognised flags are:\n\n");
316 printf(" sign : enable ntlmssp signing\n");
317 printf(" seal : enable ntlmssp sealing\n");
318 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
319 printf(" validate: enable the NDR validator\n");
320 printf(" print: enable debugging of the packets\n");
321 printf(" bigendian: use bigendian RPC\n");
322 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
324 printf(" For example, these all connect to the samr pipe:\n\n");
326 printf(" ncacn_np:myserver\n");
327 printf(" ncacn_np:myserver[samr]\n");
328 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
329 printf(" ncacn_np:myserver[/pipe/samr]\n");
330 printf(" ncacn_np:myserver[samr,sign,print]\n");
331 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
332 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
333 printf(" ncacn_np:\n");
334 printf(" ncacn_np:[/pipe/samr]\n\n");
336 printf(" ncacn_ip_tcp:myserver\n");
337 printf(" ncacn_ip_tcp:myserver[1024]\n");
338 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
340 printf(" ncalrpc:\n\n");
342 printf("The UNC format is:\n\n");
344 printf(" //server/share\n\n");
346 printf("Tests are:");
348 print_structured_testsuite_list();
352 _NORETURN_ static void max_runtime_handler(int sig)
354 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
355 exit(1);
358 /****************************************************************************
359 main program
360 ****************************************************************************/
361 int main(int argc,char *argv[])
363 int opt, i;
364 bool correct = true;
365 int max_runtime=0;
366 int argc_new;
367 struct torture_context *torture;
368 struct torture_results *results;
369 const struct torture_ui_ops *ui_ops;
370 char **argv_new;
371 poptContext pc;
372 static const char *target = "other";
373 NTSTATUS status;
374 int shell = false;
375 static const char *ui_ops_name = "subunit";
376 const char *basedir = NULL;
377 char *outputdir;
378 const char *extra_module = NULL;
379 static int list_tests = 0, list_testsuites = 0;
380 int num_extra_users = 0;
381 char **restricted = NULL;
382 int num_restricted = -1;
383 const char *load_list = NULL;
384 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS, OPT_LIST,
385 OPT_DANGEROUS,OPT_SMB_PORTS,OPT_ASYNC,OPT_NUMPROGS,
386 OPT_EXTRA_USER,};
388 struct poptOption long_options[] = {
389 POPT_AUTOHELP
390 {"format", 0, POPT_ARG_STRING, &ui_ops_name, 0, "Output format (one of: simple, subunit)", NULL },
391 {"smb-ports", 'p', POPT_ARG_STRING, NULL, OPT_SMB_PORTS, "SMB ports", NULL},
392 {"basedir", 0, POPT_ARG_STRING, &basedir, 0, "base directory", "BASEDIR" },
393 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "Seed to use for randomizer", NULL},
394 {"num-progs", 0, POPT_ARG_INT, NULL, OPT_NUMPROGS, "num progs", NULL},
395 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
396 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
397 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "NBench load file to use", NULL},
398 {"list-suites", 0, POPT_ARG_NONE, &list_testsuites, 0, "List available testsuites and exit", NULL },
399 {"list", 0, POPT_ARG_NONE, &list_tests, 0, "List available tests in specified suites and exit", NULL },
400 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
401 {"timelimit", 't', POPT_ARG_INT, NULL, OPT_TIMELIMIT, "Set time limit (in seconds)", NULL},
402 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
403 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
404 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS,
405 "run dangerous tests (eg. wiping out password database)", NULL},
406 {"load-module", 0, POPT_ARG_STRING, &extra_module, 0, "load tests from DSO file", "SOFILE"},
407 {"shell", 0, POPT_ARG_NONE, &shell, true, "Run shell", NULL},
408 {"target", 'T', POPT_ARG_STRING, &target, 0, "samba3|samba4|other", NULL},
409 {"async", 'a', POPT_ARG_NONE, NULL, OPT_ASYNC,
410 "run async tests", NULL},
411 {"num-async", 0, POPT_ARG_INT, &torture_numasync, 0,
412 "number of simultaneous async requests", NULL},
413 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
414 "set maximum time for smbtorture to live", "seconds"},
415 {"extra-user", 0, POPT_ARG_STRING, NULL, OPT_EXTRA_USER,
416 "extra user credentials", NULL},
417 {"load-list", 0, POPT_ARG_STRING, &load_list, 0,
418 "load a test id list from a text file", NULL},
419 POPT_COMMON_SAMBA
420 POPT_COMMON_CONNECTION
421 POPT_COMMON_CREDENTIALS
422 POPT_COMMON_VERSION
423 { NULL }
426 setlinebuf(stdout);
428 printf("smbtorture %s\n", samba_version_string());
430 /* we are never interested in SIGPIPE */
431 BlockSignals(true, SIGPIPE);
433 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
434 POPT_CONTEXT_KEEP_FIRST);
436 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
438 while((opt = poptGetNextOpt(pc)) != -1) {
439 switch (opt) {
440 case OPT_LOADFILE:
441 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:loadfile", poptGetOptArg(pc));
442 break;
443 case OPT_UNCLIST:
444 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:unclist", poptGetOptArg(pc));
445 break;
446 case OPT_TIMELIMIT:
447 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:timelimit", poptGetOptArg(pc));
448 break;
449 case OPT_NUMPROGS:
450 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:nprocs", poptGetOptArg(pc));
451 break;
452 case OPT_DNS:
453 parse_dns(cmdline_lp_ctx, poptGetOptArg(pc));
454 break;
455 case OPT_DANGEROUS:
456 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:dangerous", "Yes");
457 break;
458 case OPT_ASYNC:
459 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:async", "Yes");
460 break;
461 case OPT_SMB_PORTS:
462 lpcfg_set_cmdline(cmdline_lp_ctx, "smb ports", poptGetOptArg(pc));
463 break;
464 case OPT_EXTRA_USER:
466 char *option = talloc_asprintf(NULL, "torture:extra_user%u",
467 ++num_extra_users);
468 const char *value = poptGetOptArg(pc);
469 lpcfg_set_cmdline(cmdline_lp_ctx, option, value);
470 talloc_free(option);
472 break;
473 default:
474 if (opt < 0) {
475 printf("bad command line option %d\n", opt);
476 exit(1);
481 if (load_list != NULL) {
482 restricted = file_lines_load(load_list, &num_restricted, 0,
483 talloc_autofree_context());
484 if (restricted == NULL) {
485 printf("Unable to read load list file '%s'\n", load_list);
486 exit(1);
490 if (strcmp(target, "samba3") == 0) {
491 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:samba3", "true");
492 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:resume_key_support", "false");
493 } else if (strcmp(target, "samba4") == 0) {
494 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:samba4", "true");
495 } else if (strcmp(target, "samba4-ntvfs") == 0) {
496 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:samba4", "true");
497 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:samba4-ntvfs", "true");
498 } else if (strcmp(target, "winxp") == 0) {
499 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:winxp", "true");
500 } else if (strcmp(target, "w2k3") == 0) {
501 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:w2k3", "true");
502 } else if (strcmp(target, "w2k8") == 0) {
503 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:w2k8", "true");
504 lpcfg_set_cmdline(cmdline_lp_ctx,
505 "torture:invalid_lock_range_support", "false");
506 } else if (strcmp(target, "w2k12") == 0) {
507 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:w2k12", "true");
508 } else if (strcmp(target, "win7") == 0) {
509 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:win7", "true");
510 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:cn_max_buffer_size",
511 "0x00010000");
512 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:resume_key_support", "false");
513 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:rewind_support", "false");
515 /* RAW-SEARCH for fails for inexplicable reasons against win7 */
516 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:search_ea_support", "false");
518 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:hide_on_access_denied",
519 "true");
520 } else if (strcmp(target, "onefs") == 0) {
521 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:onefs", "true");
522 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:openx_deny_dos_support",
523 "false");
524 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:range_not_locked_on_file_close", "false");
525 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:sacl_support", "false");
526 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:ea_support", "false");
527 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:smbexit_pdu_support",
528 "false");
529 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:smblock_pdu_support",
530 "false");
531 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:2_step_break_to_none",
532 "true");
533 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:deny_dos_support", "false");
534 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:deny_fcb_support", "false");
535 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:read_support", "false");
536 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:writeclose_support", "false");
537 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:resume_key_support", "false");
538 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:rewind_support", "false");
539 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:raw_search_search", "false");
540 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:search_ea_size", "false");
543 if (max_runtime) {
544 /* this will only work if nobody else uses alarm(),
545 which means it won't work for some tests, but we
546 can't use the event context method we use for smbd
547 as so many tests create their own event
548 context. This will at least catch most cases. */
549 signal(SIGALRM, max_runtime_handler);
550 alarm(max_runtime);
553 if (extra_module != NULL) {
554 init_module_fn fn = load_module(poptGetOptArg(pc), false, NULL);
556 if (fn == NULL)
557 d_printf("Unable to load module from %s\n", poptGetOptArg(pc));
558 else {
559 status = fn();
560 if (NT_STATUS_IS_ERR(status)) {
561 d_printf("Error initializing module %s: %s\n",
562 poptGetOptArg(pc), nt_errstr(status));
565 } else {
566 torture_init();
569 if (list_testsuites) {
570 print_testsuite_list();
571 return 0;
574 argv_new = discard_const_p(char *, poptGetArgs(pc));
576 argc_new = argc;
577 for (i=0; i<argc; i++) {
578 if (argv_new[i] == NULL) {
579 argc_new = i;
580 break;
584 if (list_tests) {
585 if (argc_new == 1) {
586 print_test_list(torture_root, NULL, "");
587 } else {
588 for (i=1;i<argc_new;i++) {
589 print_test_list(torture_root, NULL, argv_new[i]);
592 return 0;
595 if (torture_seed == 0) {
596 torture_seed = time(NULL);
598 printf("Using seed %d\n", torture_seed);
599 srandom(torture_seed);
601 if (!strcmp(ui_ops_name, "simple")) {
602 ui_ops = &torture_simple_ui_ops;
603 } else if (!strcmp(ui_ops_name, "subunit")) {
604 ui_ops = &torture_subunit_ui_ops;
605 } else {
606 printf("Unknown output format '%s'\n", ui_ops_name);
607 exit(1);
610 results = torture_results_init(talloc_autofree_context(), ui_ops);
612 torture = torture_context_init(s4_event_context_init(talloc_autofree_context()),
613 results);
614 if (basedir != NULL) {
615 if (basedir[0] != '/') {
616 fprintf(stderr, "Please specify an absolute path to --basedir\n");
617 return 1;
619 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", basedir);
620 } else {
621 char *pwd = talloc_size(torture, PATH_MAX);
622 if (!getcwd(pwd, PATH_MAX)) {
623 fprintf(stderr, "Unable to determine current working directory\n");
624 return 1;
626 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", pwd);
628 if (!outputdir) {
629 fprintf(stderr, "Could not allocate per-run output dir\n");
630 return 1;
632 torture->outputdir = mkdtemp(outputdir);
633 if (!torture->outputdir) {
634 perror("Failed to make temp output dir");
637 torture->lp_ctx = cmdline_lp_ctx;
639 gensec_init();
641 if (shell) {
642 /* In shell mode, just ignore any remaining test names. */
643 torture_shell(torture);
644 } else {
646 /* At this point, we should just have a target string,
647 * followed by a series of test names. Unless we are in
648 * shell mode, in which case we don't need anythig more.
651 if (argc_new < 3) {
652 printf("You must specify a test to run, or 'ALL'\n");
653 usage(pc);
654 torture->results->returncode = 1;
655 } else if (!torture_parse_target(cmdline_lp_ctx, argv_new[1])) {
656 /* Take the target name or binding. */
657 usage(pc);
658 torture->results->returncode = 1;
659 } else {
660 for (i=2;i<argc_new;i++) {
661 if (!torture_run_named_tests(torture, argv_new[i],
662 (const char **)restricted)) {
663 correct = false;
669 /* Now delete the temp dir we created */
670 torture_deltree_outputdir(torture);
672 if (torture->results->returncode && correct) {
673 return(0);
674 } else {
675 return(1);