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