LCOV - code coverage report
Current view: top level - source4/torture - smbtorture.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 184 402 45.8 %
Date: 2021-09-23 10:06:22 Functions: 8 14 57.1 %

          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    11542736 : static char *prefix_name(TALLOC_CTX *mem_ctx, const char *prefix, const char *name)
      44             : {
      45    11542736 :         if (prefix == NULL)
      46       56985 :                 return talloc_strdup(mem_ctx, name);
      47             :         else
      48    11485751 :                 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             :         struct torture_suite *o;
      54             :         struct torture_tcase *t;
      55             :         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     1112489 : 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     1112489 :         bool ret = true;
      82             :         struct torture_suite *o;
      83             :         struct torture_tcase *t;
      84             :         struct torture_test *p;
      85             : 
      86     2224080 :         for (o = suite->children; o; o = o->next) {
      87     1111591 :                 char *name = NULL;
      88     1111591 :                 name = prefix_name(torture, prefix, o->name);
      89     1111591 :                 if (gen_fnmatch(expr, name) == 0) {
      90        1385 :                         *matched = true;
      91        1385 :                         reload_charcnv(torture->lp_ctx);
      92        1385 :                         if (use_fullname == 1) {
      93           3 :                                 torture_subunit_prefix_reset(torture, prefix);
      94             :                         }
      95        1385 :                         ret &= torture_run_suite_restricted(torture, o, restricted);
      96        1385 :                         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        1385 :                         continue;
     104             :                 }
     105     1110206 :                 ret &= run_matching(torture, name, expr, restricted, o, matched);
     106             :         }
     107             : 
     108     5807878 :         for (t = suite->testcases; t; t = t->next) {
     109     4695389 :                 char *tname = prefix_name(torture, prefix, t->name);
     110     4695389 :                 if (gen_fnmatch(expr, tname) == 0) {
     111        1068 :                         *matched = true;
     112        1068 :                         reload_charcnv(torture->lp_ctx);
     113        1068 :                         if (use_fullname == 1) {
     114           1 :                                 torture_subunit_prefix_reset(torture, prefix);
     115             :                         }
     116        1068 :                         ret &= torture_run_tcase_restricted(torture, t, restricted);
     117        1068 :                         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        1068 :                         continue;
     125             :                 }
     126    10430077 :                 for (p = t->tests; p; p = p->next) {
     127     5735756 :                         char *pname = prefix_name(torture, tname, p->name);
     128     5735756 :                         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     1112489 :         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        2283 : bool torture_run_named_tests(struct torture_context *torture, const char *name,
     153             :                             const char **restricted)
     154             : {
     155        2283 :         bool ret = true;
     156        2283 :         bool matched = false;
     157             :         struct torture_suite *o;
     158             : 
     159        2283 :         torture_ui_report_time(torture);
     160             : 
     161        2283 :         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        2283 :         ret = run_matching(torture, NULL, name, restricted, torture_root, &matched);
     173             : 
     174        2283 :         if (!matched) {
     175           0 :                 printf("Unknown torture operation '%s'\n", name);
     176           0 :                 return false;
     177             :         }
     178             : 
     179        2166 :         return ret;
     180             : }
     181             : 
     182        2275 : bool torture_parse_target(TALLOC_CTX *ctx,
     183             :                                 struct loadparm_context *lp_ctx,
     184             :                                 const char *target)
     185             : {
     186        2275 :         char *host = NULL, *share = NULL;
     187             :         struct dcerpc_binding *binding_struct;
     188             :         NTSTATUS status;
     189             : 
     190             :         /* see if its a RPC transport specifier */
     191        2275 :         if (!smbcli_parse_unc(target, NULL, &host, &share)) {
     192             :                 const char *h;
     193             : 
     194        1187 :                 status = dcerpc_parse_binding(ctx, target, &binding_struct);
     195        1187 :                 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        1187 :                 h = dcerpc_binding_get_string_option(binding_struct, "host");
     201        1187 :                 host = discard_const_p(char, h);
     202        1187 :                 if (host != NULL) {
     203        1181 :                         lpcfg_set_cmdline(lp_ctx, "torture:host", host);
     204             :                 }
     205             : 
     206        1187 :                 if (lpcfg_parm_string(lp_ctx, NULL, "torture", "share") == NULL)
     207        1187 :                         lpcfg_set_cmdline(lp_ctx, "torture:share", "IPC$");
     208        1187 :                 lpcfg_set_cmdline(lp_ctx, "torture:binding", target);
     209             :         } else {
     210        1088 :                 lpcfg_set_cmdline(lp_ctx, "torture:host", host);
     211        1088 :                 lpcfg_set_cmdline(lp_ctx, "torture:share", share);
     212        1088 :                 lpcfg_set_cmdline(lp_ctx, "torture:binding", host);
     213             :         }
     214             : 
     215        2158 :         return true;
     216             : }
     217             : 
     218           7 : static void parse_dns(struct loadparm_context *lp_ctx, const char *dns)
     219             : {
     220             :         char *userdn, *basedn, *secret;
     221             :         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             :         struct torture_suite *o;
     264             :         struct torture_suite *s;
     265             :         struct torture_tcase *t;
     266             :         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             :         struct torture_suite *o;
     302             :         struct torture_suite *s;
     303             :         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       16728 :                 for (s = o->children; s; s = s->next) {
     310       15788 :                         printf("%s.%s\n", o->name, s->name);
     311             :                 }
     312             : 
     313       18501 :                 for (t = o->testcases; t; t = t->next) {
     314       17705 :                         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        2357 : int main(int argc, const char *argv[])
     396             : {
     397             :         int opt, i;
     398        2357 :         bool correct = true;
     399        2357 :         int max_runtime=0;
     400             :         int argc_new;
     401             :         struct torture_context *torture;
     402             :         struct torture_results *results;
     403             :         const struct torture_ui_ops *ui_ops;
     404             :         char **argv_new;
     405             :         poptContext pc;
     406             :         static const char *target = "other";
     407             :         NTSTATUS status;
     408        2357 :         int shell = false;
     409             :         static const char *ui_ops_name = "subunit";
     410        2357 :         const char *basedir = NULL;
     411             :         char *outputdir;
     412        2357 :         const char *extra_module = NULL;
     413             :         static int list_tests = 0, list_testsuites = 0;
     414        2357 :         int num_extra_users = 0;
     415        2357 :         const char **restricted = NULL;
     416        2357 :         int num_restricted = -1;
     417        2357 :         const char *load_list = NULL;
     418             :         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        2357 :         TALLOC_CTX *mem_ctx = NULL;
     422        2357 :         struct loadparm_context *lp_ctx = NULL;
     423             :         bool ok;
     424             : 
     425       14142 :         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        2357 :                 POPT_COMMON_SAMBA
     459        2357 :                 POPT_COMMON_CONNECTION
     460        2357 :                 POPT_COMMON_CREDENTIALS
     461        2357 :                 POPT_COMMON_VERSION
     462        2357 :                 POPT_LEGACY_S4
     463             :                 POPT_TABLEEND
     464             :         };
     465             : 
     466        2357 :         setlinebuf(stdout);
     467             : 
     468        2357 :         mem_ctx = talloc_named_const(NULL, 0, "torture_ctx");
     469        2357 :         if (mem_ctx == NULL) {
     470           0 :                 printf("Unable to allocate torture_ctx\n");
     471           0 :                 exit(1);
     472             :         }
     473             : 
     474        2480 :         printf("smbtorture %s\n", samba_version_string());
     475             : 
     476             :         /* we are never interested in SIGPIPE */
     477        2357 :         BlockSignals(true, SIGPIPE);
     478             : 
     479        2357 :         ok = samba_cmdline_init(mem_ctx,
     480             :                                 SAMBA_CMDLINE_CONFIG_CLIENT,
     481             :                                 false /* require_smbconf */);
     482        2357 :         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        2357 :         pc = samba_popt_get_context(getprogname(),
     489             :                                     argc,
     490             :                                     argv,
     491             :                                     long_options,
     492             :                                     POPT_CONTEXT_KEEP_FIRST);
     493        2357 :         if (pc == NULL) {
     494           0 :                 DBG_ERR("Failed cmdline parser\n");
     495           0 :                 TALLOC_FREE(mem_ctx);
     496           0 :                 exit(1);
     497             :         }
     498             : 
     499        2357 :         poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
     500             : 
     501        2357 :         lp_ctx = samba_cmdline_get_lp_ctx();
     502             : 
     503        2480 :         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        2355 :         if (load_list != NULL) {
     556             :                 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        2355 :         if (strcmp(target, "samba3") == 0) {
     567        1080 :                 lpcfg_set_cmdline(lp_ctx, "torture:samba3", "true");
     568        1080 :                 lpcfg_set_cmdline(lp_ctx, "torture:resume_key_support", "false");
     569        1275 :         } else if (strcmp(target, "samba4") == 0) {
     570        1169 :                 lpcfg_set_cmdline(lp_ctx, "torture:samba4", "true");
     571         106 :         } 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         106 :         } else if (strcmp(target, "winxp") == 0) {
     575           0 :                 lpcfg_set_cmdline(lp_ctx, "torture:winxp", "true");
     576         106 :         } else if (strcmp(target, "w2k3") == 0) {
     577           0 :                 lpcfg_set_cmdline(lp_ctx, "torture:w2k3", "true");
     578         106 :         } 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         106 :         } else if (strcmp(target, "w2k12") == 0) {
     583           0 :                 lpcfg_set_cmdline(lp_ctx, "torture:w2k12", "true");
     584         106 :         } 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         106 :         } 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        2355 :         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        2249 :                 signal(SIGALRM, max_runtime_handler);
     624        2249 :                 alarm(max_runtime);
     625             :         }
     626             : 
     627        2355 :         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        2355 :                 torture_init(mem_ctx);
     641             :         }
     642             : 
     643        2355 :         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        2275 :         argv_new = discard_const_p(char *, poptGetArgs(pc));
     651             : 
     652        2275 :         argc_new = argc;
     653        9108 :         for (i=0; i<argc; i++) {
     654        9104 :                 if (argv_new[i] == NULL) {
     655        2158 :                         argc_new = i;
     656        2158 :                         break;
     657             :                 }
     658             :         }
     659             : 
     660        2275 :         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        2275 :         if (torture_seed == 0) {
     674        2275 :                 torture_seed = time(NULL);
     675             :         } 
     676        2392 :         printf("Using seed %d\n", torture_seed);
     677        2275 :         srandom(torture_seed);
     678             : 
     679        2275 :         if (!strcmp(ui_ops_name, "simple")) {
     680           0 :                 ui_ops = &torture_simple_ui_ops;
     681        2275 :         } else if (!strcmp(ui_ops_name, "subunit")) {
     682        2158 :                 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        2275 :         results = torture_results_init(mem_ctx, ui_ops);
     690             : 
     691        2275 :         torture = torture_context_init(s4_event_context_init(mem_ctx),
     692             :                                        results);
     693        2275 :         if (basedir != NULL) {
     694        2251 :                 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        2251 :                 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", basedir);
     701             :         } else {
     702          24 :                 char *pwd = talloc_size(torture, PATH_MAX);
     703          24 :                 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          24 :                 outputdir = talloc_asprintf(torture, "%s/smbtortureXXXXXX", pwd);
     710             :         }
     711        2275 :         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        2275 :         torture->outputdir = mkdtemp(outputdir);
     718        2275 :         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        2275 :         torture->lp_ctx = lp_ctx;
     726             : 
     727        2275 :         gensec_init();
     728             : 
     729        2275 :         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 anythig more.
     737             :                  */
     738             : 
     739        2275 :                 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        2275 :                 } else if (!torture_parse_target(torture,
     744        2158 :                                         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        4441 :                         for (i=2;i<argc_new;i++) {
     750        2283 :                                 if (!torture_run_named_tests(torture, argv_new[i],
     751             :                                             (const char **)restricted)) {
     752         425 :                                         correct = false;
     753             :                                 }
     754             :                         }
     755             :                 }
     756             :         }
     757             : 
     758             :         /* Now delete the temp dir we created */
     759        2275 :         torture_deltree_outputdir(torture);
     760             : 
     761        2275 :         if (torture->results->returncode && correct) {
     762        1852 :                 poptFreeContext(pc);
     763        1852 :                 talloc_free(mem_ctx);
     764        1852 :                 return(0);
     765             :         } else {
     766         423 :                 poptFreeContext(pc);
     767         423 :                 talloc_free(mem_ctx);
     768         423 :                 return(1);
     769             :         }
     770             : }

Generated by: LCOV version 1.13