s4-lib-policy: fix type of enum
[Samba.git] / source4 / torture / smbtorture.c
blobdcce7328647a763068ad1b27211a6468d725e77d
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(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:cn_max_buffer_size",
532 "0x00010000");
533 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:resume_key_support", "false");
534 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:rewind_support", "false");
536 /* RAW-SEARCH for fails for inexplicable reasons against win7 */
537 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:search_ea_support", "false");
539 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:hide_on_access_denied",
540 "true");
541 } else if (strcmp(target, "onefs") == 0) {
542 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:onefs", "true");
543 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:openx_deny_dos_support",
544 "false");
545 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:range_not_locked_on_file_close", "false");
546 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:sacl_support", "false");
547 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:ea_support", "false");
548 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:smbexit_pdu_support",
549 "false");
550 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:smblock_pdu_support",
551 "false");
552 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:2_step_break_to_none",
553 "true");
554 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:deny_dos_support", "false");
555 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:deny_fcb_support", "false");
556 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:read_support", "false");
557 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:writeclose_support", "false");
558 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:resume_key_support", "false");
559 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:rewind_support", "false");
560 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:raw_search_search", "false");
561 lpcfg_set_cmdline(cmdline_lp_ctx, "torture:search_ea_size", "false");
564 if (max_runtime) {
565 /* this will only work if nobody else uses alarm(),
566 which means it won't work for some tests, but we
567 can't use the event context method we use for smbd
568 as so many tests create their own event
569 context. This will at least catch most cases. */
570 signal(SIGALRM, max_runtime_handler);
571 alarm(max_runtime);
574 if (extra_module != NULL) {
575 init_module_fn fn = load_module(poptGetOptArg(pc), false, NULL);
577 if (fn == NULL)
578 d_printf("Unable to load module from %s\n", poptGetOptArg(pc));
579 else {
580 status = fn(mem_ctx);
581 if (NT_STATUS_IS_ERR(status)) {
582 d_printf("Error initializing module %s: %s\n",
583 poptGetOptArg(pc), nt_errstr(status));
586 } else {
587 torture_init(mem_ctx);
590 if (list_testsuites) {
591 print_testsuite_list();
592 talloc_free(mem_ctx);
593 popt_free_cmdline_credentials();
594 return 0;
597 argv_new = discard_const_p(char *, poptGetArgs(pc));
599 argc_new = argc;
600 for (i=0; i<argc; i++) {
601 if (argv_new[i] == NULL) {
602 argc_new = i;
603 break;
607 if (list_tests) {
608 if (argc_new == 1) {
609 print_test_list(torture_root, NULL, "");
610 } else {
611 for (i=1;i<argc_new;i++) {
612 print_test_list(torture_root, NULL, argv_new[i]);
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 talloc_free(mem_ctx);
644 return 1;
646 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", basedir);
647 } else {
648 char *pwd = talloc_size(torture, PATH_MAX);
649 if (!getcwd(pwd, PATH_MAX)) {
650 fprintf(stderr, "Unable to determine current working directory\n");
651 talloc_free(mem_ctx);
652 return 1;
654 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", pwd);
656 if (!outputdir) {
657 fprintf(stderr, "Could not allocate per-run output dir\n");
658 talloc_free(mem_ctx);
659 return 1;
661 torture->outputdir = mkdtemp(outputdir);
662 if (!torture->outputdir) {
663 perror("Failed to make temp output dir");
664 talloc_free(mem_ctx);
665 return 1;
668 torture->lp_ctx = cmdline_lp_ctx;
670 gensec_init();
672 if (shell) {
673 /* In shell mode, just ignore any remaining test names. */
674 torture_shell(torture);
675 } else {
677 /* At this point, we should just have a target string,
678 * followed by a series of test names. Unless we are in
679 * shell mode, in which case we don't need anythig more.
682 if (argc_new < 3) {
683 printf("You must specify a test to run, or 'ALL'\n");
684 usage(pc);
685 torture->results->returncode = 1;
686 } else if (!torture_parse_target(torture,
687 cmdline_lp_ctx, argv_new[1])) {
688 /* Take the target name or binding. */
689 usage(pc);
690 torture->results->returncode = 1;
691 } else {
692 for (i=2;i<argc_new;i++) {
693 if (!torture_run_named_tests(torture, argv_new[i],
694 (const char **)restricted)) {
695 correct = false;
701 /* Now delete the temp dir we created */
702 torture_deltree_outputdir(torture);
704 if (torture->results->returncode && correct) {
705 talloc_free(mem_ctx);
706 popt_free_cmdline_credentials();
707 return(0);
708 } else {
709 talloc_free(mem_ctx);
710 return(1);