root/source4/torture/smbtorture.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. run_matching
  2. run_test
  3. parse_target
  4. parse_dns
  5. print_test_list
  6. usage
  7. max_runtime_handler
  8. simple_suite_start
  9. simple_suite_finish
  10. simple_test_result
  11. simple_comment
  12. simple_warning
  13. quiet_suite_start
  14. quiet_suite_finish
  15. quiet_test_result
  16. run_shell
  17. main

   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/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 "lib/smbreadline/smbreadline.h"
  28 #include "libcli/libcli.h"
  29 #include "lib/ldb/include/ldb.h"
  30 #include "lib/events/events.h"
  31 #include "dynconfig/dynconfig.h"
  32 
  33 #include "torture/smbtorture.h"
  34 #include "../lib/util/dlinklist.h"
  35 #include "librpc/rpc/dcerpc.h"
  36 #include "auth/gensec/gensec.h"
  37 #include "param/param.h"
  38 
  39 #include "auth/credentials/credentials.h"
  40 
  41 static bool run_matching(struct torture_context *torture,
     /* [<][>][^][v][top][bottom][index][help] */
  42                                                  const char *prefix, 
  43                                                  const char *expr,
  44                                                  struct torture_suite *suite,
  45                                                  bool *matched)
  46 {
  47         bool ret = true;
  48 
  49         if (suite == NULL) {
  50                 struct torture_suite *o;
  51 
  52                 for (o = (torture_root == NULL?NULL:torture_root->children); o; o = o->next) {
  53                         if (gen_fnmatch(expr, o->name) == 0) {
  54                                 *matched = true;
  55                                 reload_charcnv(torture->lp_ctx);
  56                                 ret &= torture_run_suite(torture, o);
  57                                 continue;
  58                         }
  59 
  60                         ret &= run_matching(torture, o->name, expr, o, matched);
  61                 }
  62         } else {
  63                 char *name;
  64                 struct torture_suite *c;
  65                 struct torture_tcase *t;
  66 
  67                 for (c = suite->children; c; c = c->next) {
  68                         asprintf(&name, "%s-%s", prefix, c->name);
  69 
  70                         if (gen_fnmatch(expr, name) == 0) {
  71                                 *matched = true;
  72                                 reload_charcnv(torture->lp_ctx);
  73                                 torture->active_testname = talloc_strdup(torture, prefix);
  74                                 ret &= torture_run_suite(torture, c);
  75                                 free(name);
  76                                 continue;
  77                         }
  78                         
  79                         ret &= run_matching(torture, name, expr, c, matched);
  80 
  81                         free(name);
  82                 }
  83 
  84                 for (t = suite->testcases; t; t = t->next) {
  85                         asprintf(&name, "%s-%s", prefix, t->name);
  86                         if (gen_fnmatch(expr, name) == 0) {
  87                                 *matched = true;
  88                                 reload_charcnv(torture->lp_ctx);
  89                                 torture->active_testname = talloc_strdup(torture, prefix);
  90                                 ret &= torture_run_tcase(torture, t);
  91                                 talloc_free(torture->active_testname);
  92                         }
  93                         free(name);
  94                 }
  95         }
  96 
  97         return ret;
  98 }
  99 
 100 #define MAX_COLS 80 /* FIXME: Determine this at run-time */
 101 
 102 /****************************************************************************
 103 run a specified test or "ALL"
 104 ****************************************************************************/
 105 static bool run_test(struct torture_context *torture, const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 106 {
 107         bool ret = true;
 108         bool matched = false;
 109         struct torture_suite *o;
 110 
 111         if (strequal(name, "ALL")) {
 112                 for (o = torture_root->children; o; o = o->next) {
 113                         ret &= torture_run_suite(torture, o);
 114                 }
 115                 return ret;
 116         }
 117 
 118         ret = run_matching(torture, NULL, name, NULL, &matched);
 119 
 120         if (!matched) {
 121                 printf("Unknown torture operation '%s'\n", name);
 122                 return false;
 123         }
 124 
 125         return ret;
 126 }
 127 
 128 static bool parse_target(struct loadparm_context *lp_ctx, const char *target)
     /* [<][>][^][v][top][bottom][index][help] */
 129 {
 130         char *host = NULL, *share = NULL;
 131         struct dcerpc_binding *binding_struct;
 132         NTSTATUS status;
 133 
 134         /* see if its a RPC transport specifier */
 135         if (!smbcli_parse_unc(target, NULL, &host, &share)) {
 136                 status = dcerpc_parse_binding(talloc_autofree_context(), target, &binding_struct);
 137                 if (NT_STATUS_IS_ERR(status)) {
 138                         d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", target);
 139                         return false;
 140                 }
 141                 lp_set_cmdline(lp_ctx, "torture:host", binding_struct->host);
 142                 if (lp_parm_string(lp_ctx, NULL, "torture", "share") == NULL)
 143                         lp_set_cmdline(lp_ctx, "torture:share", "IPC$");
 144                 lp_set_cmdline(lp_ctx, "torture:binding", target);
 145         } else {
 146                 lp_set_cmdline(lp_ctx, "torture:host", host);
 147                 lp_set_cmdline(lp_ctx, "torture:share", share);
 148                 lp_set_cmdline(lp_ctx, "torture:binding", host);
 149         }
 150 
 151         return true;
 152 }
 153 
 154 static void parse_dns(struct loadparm_context *lp_ctx, const char *dns)
     /* [<][>][^][v][top][bottom][index][help] */
 155 {
 156         char *userdn, *basedn, *secret;
 157         char *p, *d;
 158 
 159         /* retrievieng the userdn */
 160         p = strchr_m(dns, '#');
 161         if (!p) {
 162                 lp_set_cmdline(lp_ctx, "torture:ldap_userdn", "");
 163                 lp_set_cmdline(lp_ctx, "torture:ldap_basedn", "");
 164                 lp_set_cmdline(lp_ctx, "torture:ldap_secret", "");
 165                 return;
 166         }
 167         userdn = strndup(dns, p - dns);
 168         lp_set_cmdline(lp_ctx, "torture:ldap_userdn", userdn);
 169 
 170         /* retrieve the basedn */
 171         d = p + 1;
 172         p = strchr_m(d, '#');
 173         if (!p) {
 174                 lp_set_cmdline(lp_ctx, "torture:ldap_basedn", "");
 175                 lp_set_cmdline(lp_ctx, "torture:ldap_secret", "");
 176                 return;
 177         }
 178         basedn = strndup(d, p - d);
 179         lp_set_cmdline(lp_ctx, "torture:ldap_basedn", basedn);
 180 
 181         /* retrieve the secret */
 182         p = p + 1;
 183         if (!p) {
 184                 lp_set_cmdline(lp_ctx, "torture:ldap_secret", "");
 185                 return;
 186         }
 187         secret = strdup(p);
 188         lp_set_cmdline(lp_ctx, "torture:ldap_secret", secret);
 189 
 190         printf ("%s - %s - %s\n", userdn, basedn, secret);
 191 
 192 }
 193 
 194 static void print_test_list(void)
     /* [<][>][^][v][top][bottom][index][help] */
 195 {
 196         struct torture_suite *o;
 197         struct torture_suite *s;
 198         struct torture_tcase *t;
 199 
 200         if (torture_root == NULL)
 201                 return;
 202 
 203         for (o = torture_root->children; o; o = o->next) {
 204                 for (s = o->children; s; s = s->next) {
 205                         printf("%s-%s\n", o->name, s->name);
 206                 }
 207 
 208                 for (t = o->testcases; t; t = t->next) {
 209                         printf("%s-%s\n", o->name, t->name);
 210                 }
 211         }
 212 }
 213 
 214 _NORETURN_ static void usage(poptContext pc)
     /* [<][>][^][v][top][bottom][index][help] */
 215 {
 216         struct torture_suite *o;
 217         struct torture_suite *s;
 218         struct torture_tcase *t;
 219         int i;
 220 
 221         poptPrintUsage(pc, stdout, 0);
 222         printf("\n");
 223 
 224         printf("The binding format is:\n\n");
 225 
 226         printf("  TRANSPORT:host[flags]\n\n");
 227 
 228         printf("  where TRANSPORT is either ncacn_np for SMB, ncacn_ip_tcp for RPC/TCP\n");
 229         printf("  or ncalrpc for local connections.\n\n");
 230 
 231         printf("  'host' is an IP or hostname or netbios name. If the binding string\n");
 232         printf("  identifies the server side of an endpoint, 'host' may be an empty\n");
 233         printf("  string.\n\n");
 234 
 235         printf("  'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
 236         printf("  a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
 237         printf("  will be auto-determined.\n\n");
 238 
 239         printf("  other recognised flags are:\n\n");
 240 
 241         printf("    sign : enable ntlmssp signing\n");
 242         printf("    seal : enable ntlmssp sealing\n");
 243         printf("    connect : enable rpc connect level auth (auth, but no sign or seal)\n");
 244         printf("    validate: enable the NDR validator\n");
 245         printf("    print: enable debugging of the packets\n");
 246         printf("    bigendian: use bigendian RPC\n");
 247         printf("    padcheck: check reply data for non-zero pad bytes\n\n");
 248 
 249         printf("  For example, these all connect to the samr pipe:\n\n");
 250 
 251         printf("    ncacn_np:myserver\n");
 252         printf("    ncacn_np:myserver[samr]\n");
 253         printf("    ncacn_np:myserver[\\pipe\\samr]\n");
 254         printf("    ncacn_np:myserver[/pipe/samr]\n");
 255         printf("    ncacn_np:myserver[samr,sign,print]\n");
 256         printf("    ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
 257         printf("    ncacn_np:myserver[/pipe/samr,seal,validate]\n");
 258         printf("    ncacn_np:\n");
 259         printf("    ncacn_np:[/pipe/samr]\n\n");
 260 
 261         printf("    ncacn_ip_tcp:myserver\n");
 262         printf("    ncacn_ip_tcp:myserver[1024]\n");
 263         printf("    ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
 264 
 265         printf("    ncalrpc:\n\n");
 266 
 267         printf("The UNC format is:\n\n");
 268 
 269         printf("  //server/share\n\n");
 270 
 271         printf("Tests are:");
 272 
 273         if (torture_root == NULL) {
 274             printf("NO TESTS LOADED\n");
 275             exit(1);
 276         }
 277 
 278         for (o = torture_root->children; o; o = o->next) {
 279                 printf("\n%s (%s):\n  ", o->description, o->name);
 280 
 281                 i = 0;
 282                 for (s = o->children; s; s = s->next) {
 283                         if (i + strlen(o->name) + strlen(s->name) >= (MAX_COLS - 3)) {
 284                                 printf("\n  ");
 285                                 i = 0;
 286                         }
 287                         i+=printf("%s-%s ", o->name, s->name);
 288                 }
 289 
 290                 for (t = o->testcases; t; t = t->next) {
 291                         if (i + strlen(o->name) + strlen(t->name) >= (MAX_COLS - 3)) {
 292                                 printf("\n  ");
 293                                 i = 0;
 294                         }
 295                         i+=printf("%s-%s ", o->name, t->name);
 296                 }
 297 
 298                 if (i) printf("\n");
 299         }
 300 
 301         printf("\nThe default test is ALL.\n");
 302 
 303         exit(1);
 304 }
 305 
 306 _NORETURN_ static void max_runtime_handler(int sig)
     /* [<][>][^][v][top][bottom][index][help] */
 307 {
 308         DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
 309         exit(1);
 310 }
 311 
 312 struct timeval last_suite_started;
 313 
 314 static void simple_suite_start(struct torture_context *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 315                                struct torture_suite *suite)
 316 {
 317         last_suite_started = timeval_current();
 318         printf("Running %s\n", suite->name);
 319 }
 320 
 321 static void simple_suite_finish(struct torture_context *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 322                                 struct torture_suite *suite)
 323 {
 324 
 325         printf("%s took %g secs\n\n", suite->name, 
 326                    timeval_elapsed(&last_suite_started));
 327 }
 328 
 329 static void simple_test_result(struct torture_context *context, 
     /* [<][>][^][v][top][bottom][index][help] */
 330                                enum torture_result res, const char *reason)
 331 {
 332         switch (res) {
 333         case TORTURE_OK:
 334                 if (reason)
 335                         printf("OK: %s\n", reason);
 336                 break;
 337         case TORTURE_FAIL:
 338                 printf("TEST %s FAILED! - %s\n", context->active_test->name, reason);
 339                 break;
 340         case TORTURE_ERROR:
 341                 printf("ERROR IN TEST %s! - %s\n", context->active_test->name, reason); 
 342                 break;
 343         case TORTURE_SKIP:
 344                 printf("SKIP: %s - %s\n", context->active_test->name, reason);
 345                 break;
 346         }
 347 }
 348 
 349 static void simple_comment(struct torture_context *test, 
     /* [<][>][^][v][top][bottom][index][help] */
 350                            const char *comment)
 351 {
 352         printf("%s", comment);
 353 }
 354 
 355 static void simple_warning(struct torture_context *test, 
     /* [<][>][^][v][top][bottom][index][help] */
 356                            const char *comment)
 357 {
 358         fprintf(stderr, "WARNING: %s\n", comment);
 359 }
 360 
 361 const static struct torture_ui_ops std_ui_ops = {
 362         .comment = simple_comment,
 363         .warning = simple_warning,
 364         .suite_start = simple_suite_start,
 365         .suite_finish = simple_suite_finish,
 366         .test_result = simple_test_result
 367 };
 368 
 369 
 370 static void quiet_suite_start(struct torture_context *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 371                               struct torture_suite *suite)
 372 {
 373         int i;
 374         ctx->results->quiet = true;
 375         for (i = 1; i < ctx->level; i++) putchar('\t');
 376         printf("%s: ", suite->name);
 377         fflush(stdout);
 378 }
 379 
 380 static void quiet_suite_finish(struct torture_context *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 381                                struct torture_suite *suite)
 382 {
 383         putchar('\n');
 384 }
 385 
 386 static void quiet_test_result(struct torture_context *context, 
     /* [<][>][^][v][top][bottom][index][help] */
 387                               enum torture_result res, const char *reason)
 388 {
 389         fflush(stdout);
 390         switch (res) {
 391         case TORTURE_OK: putchar('.'); break;
 392         case TORTURE_FAIL: putchar('F'); break;
 393         case TORTURE_ERROR: putchar('E'); break;
 394         case TORTURE_SKIP: putchar('I'); break;
 395         }
 396 }
 397 
 398 const static struct torture_ui_ops quiet_ui_ops = {
 399         .suite_start = quiet_suite_start,
 400         .suite_finish = quiet_suite_finish,
 401         .test_result = quiet_test_result
 402 };
 403 
 404 static void run_shell(struct torture_context *tctx)
     /* [<][>][^][v][top][bottom][index][help] */
 405 {
 406         char *cline;
 407         int argc;
 408         const char **argv;
 409         int ret;
 410 
 411         while (1) {
 412                 cline = smb_readline("torture> ", NULL, NULL);
 413 
 414                 if (cline == NULL)
 415                         return;
 416         
 417                 ret = poptParseArgvString(cline, &argc, &argv);
 418                 if (ret != 0) {
 419                         fprintf(stderr, "Error parsing line\n");
 420                         continue;
 421                 }
 422 
 423                 if (!strcmp(argv[0], "quit")) {
 424                         return;
 425                 } else if (!strcmp(argv[0], "set")) {
 426                         if (argc < 3) {
 427                                 fprintf(stderr, "Usage: set <variable> <value>\n");
 428                         } else {
 429                                 char *name = talloc_asprintf(NULL, "torture:%s", argv[1]);
 430                                 lp_set_cmdline(tctx->lp_ctx, name, argv[2]);
 431                                 talloc_free(name);
 432                         }
 433                 } else if (!strcmp(argv[0], "help")) {
 434                         fprintf(stderr, "Available commands:\n"
 435                                                         " help - This help command\n"
 436                                                         " run - Run test\n"
 437                                                         " set - Change variables\n"
 438                                                         "\n");
 439                 } else if (!strcmp(argv[0], "run")) {
 440                         if (argc < 2) {
 441                                 fprintf(stderr, "Usage: run TEST-NAME [OPTIONS...]\n");
 442                         } else {
 443                                 run_test(tctx, argv[1]);
 444                         }
 445                 }
 446                 free(cline);
 447         }
 448 }
 449 
 450 /****************************************************************************
 451   main program
 452 ****************************************************************************/
 453 int main(int argc,char *argv[])
     /* [<][>][^][v][top][bottom][index][help] */
 454 {
 455         int opt, i;
 456         bool correct = true;
 457         int max_runtime=0;
 458         int argc_new;
 459         struct torture_context *torture;
 460         struct torture_results *results;
 461         const struct torture_ui_ops *ui_ops;
 462         char **argv_new;
 463         poptContext pc;
 464         static const char *target = "other";
 465         NTSTATUS status;
 466         int shell = false;
 467         static const char *ui_ops_name = "simple";
 468         const char *basedir = NULL;
 469         const char *extra_module = NULL;
 470         static int list_tests = 0;
 471         int num_extra_users = 0;
 472         enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS, OPT_LIST,
 473               OPT_DANGEROUS,OPT_SMB_PORTS,OPT_ASYNC,OPT_NUMPROGS,OPT_EXTRA_USER};
 474         
 475         struct poptOption long_options[] = {
 476                 POPT_AUTOHELP
 477                 {"format", 0, POPT_ARG_STRING, &ui_ops_name, 0, "Output format (one of: simple, subunit)", NULL },
 478                 {"smb-ports",   'p', POPT_ARG_STRING, NULL,     OPT_SMB_PORTS,  "SMB ports",    NULL},
 479                 {"basedir",       0, POPT_ARG_STRING, &basedir, 0, "base directory", "BASEDIR" },
 480                 {"seed",          0, POPT_ARG_INT,  &torture_seed,      0,      "Seed to use for randomizer",   NULL},
 481                 {"num-progs",     0, POPT_ARG_INT,  NULL,       OPT_NUMPROGS,   "num progs",    NULL},
 482                 {"num-ops",       0, POPT_ARG_INT,  &torture_numops,    0,      "num ops",      NULL},
 483                 {"entries",       0, POPT_ARG_INT,  &torture_entries,   0,      "entries",      NULL},
 484                 {"loadfile",      0, POPT_ARG_STRING,   NULL,   OPT_LOADFILE,   "NBench load file to use",      NULL},
 485                 {"list",          0, POPT_ARG_NONE, &list_tests, 0, "List available tests and exit", NULL },
 486                 {"unclist",       0, POPT_ARG_STRING,   NULL,   OPT_UNCLIST,    "unclist",      NULL},
 487                 {"timelimit",   't', POPT_ARG_INT,      NULL,   OPT_TIMELIMIT,  "Set time limit (in seconds)",  NULL},
 488                 {"failures",    'f', POPT_ARG_INT,  &torture_failures,  0,      "failures",     NULL},
 489                 {"parse-dns",   'D', POPT_ARG_STRING,   NULL,   OPT_DNS,        "parse-dns",    NULL},
 490                 {"dangerous",   'X', POPT_ARG_NONE,     NULL,   OPT_DANGEROUS,
 491                  "run dangerous tests (eg. wiping out password database)", NULL},
 492                 {"load-module",  0,  POPT_ARG_STRING, &extra_module,     0, "load tests from DSO file",    "SOFILE"},
 493                 {"shell",               0, POPT_ARG_NONE, &shell, true, "Run shell", NULL},
 494                 {"target",              'T', POPT_ARG_STRING, &target, 0, "samba3|samba4|other", NULL},
 495                 {"async",       'a', POPT_ARG_NONE,     NULL,   OPT_ASYNC,
 496                  "run async tests", NULL},
 497                 {"num-async",    0, POPT_ARG_INT,  &torture_numasync,  0,
 498                  "number of simultaneous async requests", NULL},
 499                 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0, 
 500                  "set maximum time for smbtorture to live", "seconds"},
 501                 {"extra-user",   0, POPT_ARG_STRING, NULL, OPT_EXTRA_USER,
 502                  "extra user credentials", NULL},
 503                 POPT_COMMON_SAMBA
 504                 POPT_COMMON_CONNECTION
 505                 POPT_COMMON_CREDENTIALS
 506                 POPT_COMMON_VERSION
 507                 { NULL }
 508         };
 509 
 510         setlinebuf(stdout);
 511 
 512         /* we are never interested in SIGPIPE */
 513         BlockSignals(true, SIGPIPE);
 514 
 515         pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options, 
 516                             POPT_CONTEXT_KEEP_FIRST);
 517 
 518         poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
 519 
 520         while((opt = poptGetNextOpt(pc)) != -1) {
 521                 switch (opt) {
 522                 case OPT_LOADFILE:
 523                         lp_set_cmdline(cmdline_lp_ctx, "torture:loadfile", poptGetOptArg(pc));
 524                         break;
 525                 case OPT_UNCLIST:
 526                         lp_set_cmdline(cmdline_lp_ctx, "torture:unclist", poptGetOptArg(pc));
 527                         break;
 528                 case OPT_TIMELIMIT:
 529                         lp_set_cmdline(cmdline_lp_ctx, "torture:timelimit", poptGetOptArg(pc));
 530                         break;
 531                 case OPT_NUMPROGS:
 532                         lp_set_cmdline(cmdline_lp_ctx, "torture:nprocs", poptGetOptArg(pc));
 533                         break;
 534                 case OPT_DNS:
 535                         parse_dns(cmdline_lp_ctx, poptGetOptArg(pc));
 536                         break;
 537                 case OPT_DANGEROUS:
 538                         lp_set_cmdline(cmdline_lp_ctx, "torture:dangerous", "Yes");
 539                         break;
 540                 case OPT_ASYNC:
 541                         lp_set_cmdline(cmdline_lp_ctx, "torture:async", "Yes");
 542                         break;
 543                 case OPT_SMB_PORTS:
 544                         lp_set_cmdline(cmdline_lp_ctx, "smb ports", poptGetOptArg(pc));
 545                         break;
 546                 case OPT_EXTRA_USER:
 547                         {
 548                                 char *option = talloc_asprintf(NULL, "torture:extra_user%u",
 549                                                                ++num_extra_users);
 550                                 char *value = poptGetOptArg(pc);
 551                                 lp_set_cmdline(cmdline_lp_ctx, option, value);
 552                                 talloc_free(option);
 553                         }
 554                         break;
 555                 }
 556         }
 557 
 558         if (strcmp(target, "samba3") == 0) {
 559                 lp_set_cmdline(cmdline_lp_ctx, "torture:samba3", "true");
 560         } else if (strcmp(target, "samba4") == 0) {
 561                 lp_set_cmdline(cmdline_lp_ctx, "torture:samba4", "true");
 562         } else if (strcmp(target, "win7") == 0) {
 563                 lp_set_cmdline(cmdline_lp_ctx, "torture:win7", "true");
 564         }
 565 
 566         if (max_runtime) {
 567                 /* this will only work if nobody else uses alarm(),
 568                    which means it won't work for some tests, but we
 569                    can't use the event context method we use for smbd
 570                    as so many tests create their own event
 571                    context. This will at least catch most cases. */
 572                 signal(SIGALRM, max_runtime_handler);
 573                 alarm(max_runtime);
 574         }
 575 
 576         if (extra_module != NULL) {
 577             init_module_fn fn = load_module(talloc_autofree_context(), poptGetOptArg(pc));
 578 
 579             if (fn == NULL) 
 580                 d_printf("Unable to load module from %s\n", poptGetOptArg(pc));
 581             else {
 582                 status = fn();
 583                 if (NT_STATUS_IS_ERR(status)) {
 584                     d_printf("Error initializing module %s: %s\n", 
 585                              poptGetOptArg(pc), nt_errstr(status));
 586                 }
 587             }
 588         } else { 
 589                 torture_init();
 590         }
 591 
 592         if (list_tests) {
 593                 print_test_list();
 594                 return 0;
 595         }
 596 
 597         if (torture_seed == 0) {
 598                 torture_seed = time(NULL);
 599         } 
 600         printf("Using seed %d\n", torture_seed);
 601         srandom(torture_seed);
 602 
 603         argv_new = discard_const_p(char *, poptGetArgs(pc));
 604 
 605         argc_new = argc;
 606         for (i=0; i<argc; i++) {
 607                 if (argv_new[i] == NULL) {
 608                         argc_new = i;
 609                         break;
 610                 }
 611         }
 612 
 613         if (!(argc_new >= 3 || (shell && argc_new >= 2))) {
 614                 usage(pc);
 615                 exit(1);
 616         }
 617 
 618         if (!parse_target(cmdline_lp_ctx, argv_new[1])) {
 619                 usage(pc);
 620                 exit(1);
 621         }
 622 
 623         if (!strcmp(ui_ops_name, "simple")) {
 624                 ui_ops = &std_ui_ops;
 625         } else if (!strcmp(ui_ops_name, "subunit")) {
 626                 ui_ops = &torture_subunit_ui_ops;
 627         } else if (!strcmp(ui_ops_name, "quiet")) {
 628                 ui_ops = &quiet_ui_ops;
 629         } else {
 630                 printf("Unknown output format '%s'\n", ui_ops_name);
 631                 exit(1);
 632         }
 633 
 634         results = torture_results_init(talloc_autofree_context(), ui_ops);
 635 
 636         torture = torture_context_init(s4_event_context_init(NULL), results);
 637         if (basedir != NULL) {
 638                 if (basedir[0] != '/') {
 639                         fprintf(stderr, "Please specify an absolute path to --basedir\n");
 640                         return 1;
 641                 }
 642                 torture->outputdir = basedir;
 643         } else {
 644                 char *pwd = talloc_size(torture, PATH_MAX);
 645                 if (!getcwd(pwd, PATH_MAX)) {
 646                         fprintf(stderr, "Unable to determine current working directory\n");
 647                         return 1;
 648                 }
 649                 torture->outputdir = pwd;
 650         }
 651 
 652         torture->lp_ctx = cmdline_lp_ctx;
 653 
 654         gensec_init(cmdline_lp_ctx);
 655 
 656         if (argc_new == 0) {
 657                 printf("You must specify a test to run, or 'ALL'\n");
 658         } else if (shell) {
 659                 run_shell(torture);
 660         } else {
 661                 for (i=2;i<argc_new;i++) {
 662                         if (!run_test(torture, argv_new[i])) {
 663                                 correct = false;
 664                         }
 665                 }
 666         }
 667 
 668         if (torture->results->returncode && correct) {
 669                 return(0);
 670         } else {
 671                 return(1);
 672         }
 673 }

/* [<][>][^][v][top][bottom][index][help] */