s3: smbd: dfs: Move lp_msdfs_shuffle_referrals() call out of parse_msdfs_symlink().
[Samba.git] / source4 / torture / smbtorture.c
blob90b2b04cd88b6a8790b3881c43c061e204793117
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 #ifdef 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(TALLOC_CTX *ctx,
154 struct loadparm_context *lp_ctx,
155 const char *target)
157 char *host = NULL, *share = NULL;
158 struct dcerpc_binding *binding_struct;
159 NTSTATUS status;
161 /* see if its a RPC transport specifier */
162 if (!smbcli_parse_unc(target, NULL, &host, &share)) {
163 const char *h;
165 status = dcerpc_parse_binding(ctx, target, &binding_struct);
166 if (NT_STATUS_IS_ERR(status)) {
167 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", target);
168 return false;
171 h = dcerpc_binding_get_string_option(binding_struct, "host");
172 host = discard_const_p(char, h);
173 if (host != NULL) {
174 lpcfg_set_cmdline(lp_ctx, "torture:host", host);
177 if (lpcfg_parm_string(lp_ctx, NULL, "torture", "share") == NULL)
178 lpcfg_set_cmdline(lp_ctx, "torture:share", "IPC$");
179 lpcfg_set_cmdline(lp_ctx, "torture:binding", target);
180 } else {
181 lpcfg_set_cmdline(lp_ctx, "torture:host", host);
182 lpcfg_set_cmdline(lp_ctx, "torture:share", share);
183 lpcfg_set_cmdline(lp_ctx, "torture:binding", host);
186 return true;
189 static void parse_dns(struct loadparm_context *lp_ctx, const char *dns)
191 char *userdn, *basedn, *secret;
192 char *p, *d;
194 /* retrievieng the userdn */
195 p = strchr_m(dns, '#');
196 if (!p) {
197 lpcfg_set_cmdline(lp_ctx, "torture:ldap_userdn", "");
198 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", "");
199 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
200 return;
202 userdn = strndup(dns, p - dns);
203 lpcfg_set_cmdline(lp_ctx, "torture:ldap_userdn", userdn);
205 /* retrieve the basedn */
206 d = p + 1;
207 p = strchr_m(d, '#');
208 if (!p) {
209 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", "");
210 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
211 return;
213 basedn = strndup(d, p - d);
214 lpcfg_set_cmdline(lp_ctx, "torture:ldap_basedn", basedn);
216 /* retrieve the secret */
217 p = p + 1;
218 if (!p) {
219 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", "");
220 return;
222 secret = strdup(p);
223 lpcfg_set_cmdline(lp_ctx, "torture:ldap_secret", secret);
225 printf ("%s - %s - %s\n", userdn, basedn, secret);
229 /* Print the full test list, formatted into separate labelled test
230 * groups.
232 static void print_structured_testsuite_list(void)
234 struct torture_suite *o;
235 struct torture_suite *s;
236 struct torture_tcase *t;
237 int i;
239 if (torture_root == NULL) {
240 printf("NO TESTS LOADED\n");
241 return;
244 for (o = torture_root->children; o; o = o->next) {
245 printf("\n%s (%s):\n ", o->description, o->name);
247 i = 0;
248 for (s = o->children; s; s = s->next) {
249 if (i + strlen(o->name) + strlen(s->name) >= (MAX_COLS - 3)) {
250 printf("\n ");
251 i = 0;
253 i+=printf("%s.%s ", o->name, s->name);
256 for (t = o->testcases; t; t = t->next) {
257 if (i + strlen(o->name) + strlen(t->name) >= (MAX_COLS - 3)) {
258 printf("\n ");
259 i = 0;
261 i+=printf("%s.%s ", o->name, t->name);
264 if (i) printf("\n");
267 printf("\nThe default test is ALL.\n");
270 static void print_testsuite_list(void)
272 struct torture_suite *o;
273 struct torture_suite *s;
274 struct torture_tcase *t;
276 if (torture_root == NULL)
277 return;
279 for (o = torture_root->children; o; o = o->next) {
280 for (s = o->children; s; s = s->next) {
281 printf("%s.%s\n", o->name, s->name);
284 for (t = o->testcases; t; t = t->next) {
285 printf("%s.%s\n", o->name, t->name);
290 void torture_print_testsuites(bool structured)
292 if (structured) {
293 print_structured_testsuite_list();
294 } else {
295 print_testsuite_list();
299 static void usage(poptContext pc)
301 poptPrintUsage(pc, stdout, 0);
302 printf("\n");
304 printf("The binding format is:\n\n");
306 printf(" TRANSPORT:host[flags]\n\n");
308 printf(" where TRANSPORT is either ncacn_np for SMB, ncacn_ip_tcp for RPC/TCP\n");
309 printf(" or ncalrpc for local connections.\n\n");
311 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
312 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
313 printf(" string.\n\n");
315 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
316 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
317 printf(" will be auto-determined.\n\n");
319 printf(" other recognised flags are:\n\n");
321 printf(" sign : enable ntlmssp signing\n");
322 printf(" seal : enable ntlmssp sealing\n");
323 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
324 printf(" validate: enable the NDR validator\n");
325 printf(" print: enable debugging of the packets\n");
326 printf(" bigendian: use bigendian RPC\n");
327 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
329 printf(" For example, these all connect to the samr pipe:\n\n");
331 printf(" ncacn_np:myserver\n");
332 printf(" ncacn_np:myserver[samr]\n");
333 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
334 printf(" ncacn_np:myserver[/pipe/samr]\n");
335 printf(" ncacn_np:myserver[samr,sign,print]\n");
336 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
337 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
338 printf(" ncacn_np:\n");
339 printf(" ncacn_np:[/pipe/samr]\n\n");
341 printf(" ncacn_ip_tcp:myserver\n");
342 printf(" ncacn_ip_tcp:myserver[1024]\n");
343 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
345 printf(" ncalrpc:\n\n");
347 printf("The UNC format is:\n\n");
349 printf(" //server/share\n\n");
351 printf("Tests are:");
353 print_structured_testsuite_list();
357 _NORETURN_ static void max_runtime_handler(int sig)
359 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
360 exit(1);
363 /****************************************************************************
364 main program
365 ****************************************************************************/
366 int main(int argc, const char *argv[])
368 int opt, i;
369 bool correct = true;
370 int max_runtime=0;
371 int argc_new;
372 struct torture_context *torture;
373 struct torture_results *results;
374 const struct torture_ui_ops *ui_ops;
375 char **argv_new;
376 poptContext pc;
377 static const char *target = "other";
378 NTSTATUS status;
379 int shell = false;
380 static const char *ui_ops_name = "subunit";
381 const char *basedir = NULL;
382 char *outputdir;
383 const char *extra_module = NULL;
384 static int list_tests = 0, list_testsuites = 0;
385 int num_extra_users = 0;
386 const char **restricted = NULL;
387 int num_restricted = -1;
388 const char *load_list = NULL;
389 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS, OPT_LIST,
390 OPT_DANGEROUS,OPT_SMB_PORTS,OPT_ASYNC,OPT_NUMPROGS,
391 OPT_EXTRA_USER,};
392 TALLOC_CTX *mem_ctx = NULL;
394 struct poptOption long_options[] = {
395 POPT_AUTOHELP
396 {"format", 0, POPT_ARG_STRING, &ui_ops_name, 0, "Output format (one of: simple, subunit)", NULL },
397 {"smb-ports", 'p', POPT_ARG_STRING, NULL, OPT_SMB_PORTS, "SMB ports", NULL},
398 {"basedir", 0, POPT_ARG_STRING, &basedir, 0, "base directory", "BASEDIR" },
399 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "Seed to use for randomizer", NULL},
400 {"num-progs", 0, POPT_ARG_INT, NULL, OPT_NUMPROGS, "num progs", NULL},
401 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
402 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
403 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "NBench load file to use", NULL},
404 {"list-suites", 0, POPT_ARG_NONE, &list_testsuites, 0, "List available testsuites and exit", NULL },
405 {"list", 0, POPT_ARG_NONE, &list_tests, 0, "List available tests in specified suites and exit", NULL },
406 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
407 {"timelimit", 't', POPT_ARG_INT, NULL, OPT_TIMELIMIT, "Set time limit (in seconds)", NULL},
408 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
409 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
410 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS,
411 "run dangerous tests (eg. wiping out password database)", NULL},
412 {"load-module", 0, POPT_ARG_STRING, &extra_module, 0, "load tests from DSO file", "SOFILE"},
413 {"shell", 0, POPT_ARG_NONE, &shell, true, "Run shell", NULL},
414 {"target", 'T', POPT_ARG_STRING, &target, 0, "samba3|samba4|other", NULL},
415 {"async", 'a', POPT_ARG_NONE, NULL, OPT_ASYNC,
416 "run async tests", NULL},
417 {"num-async", 0, POPT_ARG_INT, &torture_numasync, 0,
418 "number of simultaneous async requests", NULL},
419 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
420 "set maximum time for smbtorture to live", "seconds"},
421 {"extra-user", 0, POPT_ARG_STRING, NULL, OPT_EXTRA_USER,
422 "extra user credentials", NULL},
423 {"load-list", 0, POPT_ARG_STRING, &load_list, 0,
424 "load a test id list from a text file", NULL},
425 POPT_COMMON_SAMBA
426 POPT_COMMON_CONNECTION
427 POPT_COMMON_CREDENTIALS
428 POPT_COMMON_VERSION
429 { NULL }
432 setlinebuf(stdout);
434 mem_ctx = talloc_named_const(NULL, 0, "torture_ctx");
435 if (mem_ctx == NULL) {
436 printf("Unable to allocate torture_ctx\n");
437 exit(1);
440 printf("smbtorture %s\n", samba_version_string());
442 /* we are never interested in SIGPIPE */
443 BlockSignals(true, SIGPIPE);
445 pc = poptGetContext("smbtorture", argc, argv, long_options,
446 POPT_CONTEXT_KEEP_FIRST);
448 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
450 while((opt = poptGetNextOpt(pc)) != -1) {
451 switch (opt) {
452 case OPT_LOADFILE:
453 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:loadfile", poptGetOptArg(pc));
454 break;
455 case OPT_UNCLIST:
456 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:unclist", poptGetOptArg(pc));
457 break;
458 case OPT_TIMELIMIT:
459 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:timelimit", poptGetOptArg(pc));
460 break;
461 case OPT_NUMPROGS:
462 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:nprocs", poptGetOptArg(pc));
463 break;
464 case OPT_DNS:
465 parse_dns(cmdline_lp_ctx, poptGetOptArg(pc));
466 break;
467 case OPT_DANGEROUS:
468 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:dangerous", "Yes");
469 break;
470 case OPT_ASYNC:
471 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:async", "Yes");
472 break;
473 case OPT_SMB_PORTS:
474 lpcfg_set_cmdline(cmdline_lp_ctx, "smb ports", poptGetOptArg(pc));
475 break;
476 case OPT_EXTRA_USER:
478 char *option = talloc_asprintf(mem_ctx,
479 "torture:extra_user%u",
480 ++num_extra_users);
481 const char *value = poptGetOptArg(pc);
482 if (option == NULL) {
483 printf("talloc fail\n");
484 talloc_free(mem_ctx);
485 exit(1);
487 lpcfg_set_cmdline(cmdline_lp_ctx, option, value);
488 talloc_free(option);
490 break;
491 default:
492 if (opt < 0) {
493 printf("bad command line option %d\n", opt);
494 talloc_free(mem_ctx);
495 exit(1);
500 if (load_list != NULL) {
501 char **r;
502 r = file_lines_load(load_list, &num_restricted, 0, mem_ctx);
503 restricted = discard_const_p(const char *, r);
504 if (restricted == NULL) {
505 printf("Unable to read load list file '%s'\n", load_list);
506 talloc_free(mem_ctx);
507 exit(1);
511 if (strcmp(target, "samba3") == 0) {
512 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:samba3", "true");
513 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:resume_key_support", "false");
514 } else if (strcmp(target, "samba4") == 0) {
515 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:samba4", "true");
516 } else if (strcmp(target, "samba4-ntvfs") == 0) {
517 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:samba4", "true");
518 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:samba4-ntvfs", "true");
519 } else if (strcmp(target, "winxp") == 0) {
520 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:winxp", "true");
521 } else if (strcmp(target, "w2k3") == 0) {
522 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:w2k3", "true");
523 } else if (strcmp(target, "w2k8") == 0) {
524 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:w2k8", "true");
525 lpcfg_set_cmdline(cmdline_lp_ctx,
526 "torture:invalid_lock_range_support", "false");
527 } else if (strcmp(target, "w2k12") == 0) {
528 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:w2k12", "true");
529 } else if (strcmp(target, "win7") == 0) {
530 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:win7", "true");
531 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:resume_key_support", "false");
532 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:rewind_support", "false");
534 /* RAW-SEARCH for fails for inexplicable reasons against win7 */
535 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:search_ea_support", "false");
537 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:hide_on_access_denied",
538 "true");
539 } else if (strcmp(target, "onefs") == 0) {
540 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:onefs", "true");
541 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:openx_deny_dos_support",
542 "false");
543 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:range_not_locked_on_file_close", "false");
544 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:sacl_support", "false");
545 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:ea_support", "false");
546 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:smbexit_pdu_support",
547 "false");
548 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:smblock_pdu_support",
549 "false");
550 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:2_step_break_to_none",
551 "true");
552 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:deny_dos_support", "false");
553 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:deny_fcb_support", "false");
554 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:read_support", "false");
555 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:writeclose_support", "false");
556 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:resume_key_support", "false");
557 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:rewind_support", "false");
558 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:raw_search_search", "false");
559 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:search_ea_size", "false");
562 if (max_runtime) {
563 /* this will only work if nobody else uses alarm(),
564 which means it won't work for some tests, but we
565 can't use the event context method we use for smbd
566 as so many tests create their own event
567 context. This will at least catch most cases. */
568 signal(SIGALRM, max_runtime_handler);
569 alarm(max_runtime);
572 if (extra_module != NULL) {
573 init_module_fn fn = load_module(poptGetOptArg(pc), false, NULL);
575 if (fn == NULL)
576 d_printf("Unable to load module from %s\n", poptGetOptArg(pc));
577 else {
578 status = fn(mem_ctx);
579 if (NT_STATUS_IS_ERR(status)) {
580 d_printf("Error initializing module %s: %s\n",
581 poptGetOptArg(pc), nt_errstr(status));
584 } else {
585 torture_init(mem_ctx);
588 if (list_testsuites) {
589 print_testsuite_list();
590 poptFreeContext(pc);
591 talloc_free(mem_ctx);
592 popt_free_cmdline_credentials();
593 return 0;
596 argv_new = discard_const_p(char *, poptGetArgs(pc));
598 argc_new = argc;
599 for (i=0; i<argc; i++) {
600 if (argv_new[i] == NULL) {
601 argc_new = i;
602 break;
606 if (list_tests) {
607 if (argc_new == 1) {
608 print_test_list(torture_root, NULL, "");
609 } else {
610 for (i=1;i<argc_new;i++) {
611 print_test_list(torture_root, NULL, argv_new[i]);
614 poptFreeContext(pc);
615 talloc_free(mem_ctx);
616 popt_free_cmdline_credentials();
617 return 0;
620 if (torture_seed == 0) {
621 torture_seed = time(NULL);
623 printf("Using seed %d\n", torture_seed);
624 srandom(torture_seed);
626 if (!strcmp(ui_ops_name, "simple")) {
627 ui_ops = &torture_simple_ui_ops;
628 } else if (!strcmp(ui_ops_name, "subunit")) {
629 ui_ops = &torture_subunit_ui_ops;
630 } else {
631 printf("Unknown output format '%s'\n", ui_ops_name);
632 talloc_free(mem_ctx);
633 exit(1);
636 results = torture_results_init(mem_ctx, ui_ops);
638 torture = torture_context_init(s4_event_context_init(mem_ctx),
639 results);
640 if (basedir != NULL) {
641 if (basedir[0] != '/') {
642 fprintf(stderr, "Please specify an absolute path to --basedir\n");
643 poptFreeContext(pc);
644 talloc_free(mem_ctx);
645 return 1;
647 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", basedir);
648 } else {
649 char *pwd = talloc_size(torture, PATH_MAX);
650 if (!getcwd(pwd, PATH_MAX)) {
651 fprintf(stderr, "Unable to determine current working directory\n");
652 poptFreeContext(pc);
653 talloc_free(mem_ctx);
654 return 1;
656 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", pwd);
658 if (!outputdir) {
659 fprintf(stderr, "Could not allocate per-run output dir\n");
660 poptFreeContext(pc);
661 talloc_free(mem_ctx);
662 return 1;
664 torture->outputdir = mkdtemp(outputdir);
665 if (!torture->outputdir) {
666 perror("Failed to make temp output dir");
667 poptFreeContext(pc);
668 talloc_free(mem_ctx);
669 return 1;
672 torture->lp_ctx = cmdline_lp_ctx;
674 gensec_init();
676 if (shell) {
677 /* In shell mode, just ignore any remaining test names. */
678 torture_shell(torture);
679 } else {
681 /* At this point, we should just have a target string,
682 * followed by a series of test names. Unless we are in
683 * shell mode, in which case we don't need anythig more.
686 if (argc_new < 3) {
687 printf("You must specify a test to run, or 'ALL'\n");
688 usage(pc);
689 torture->results->returncode = 1;
690 } else if (!torture_parse_target(torture,
691 cmdline_lp_ctx, argv_new[1])) {
692 /* Take the target name or binding. */
693 usage(pc);
694 torture->results->returncode = 1;
695 } else {
696 for (i=2;i<argc_new;i++) {
697 if (!torture_run_named_tests(torture, argv_new[i],
698 (const char **)restricted)) {
699 correct = false;
705 /* Now delete the temp dir we created */
706 torture_deltree_outputdir(torture);
708 if (torture->results->returncode && correct) {
709 poptFreeContext(pc);
710 talloc_free(mem_ctx);
711 popt_free_cmdline_credentials();
712 return(0);
713 } else {
714 poptFreeContext(pc);
715 talloc_free(mem_ctx);
716 return(1);