LCOV - code coverage report
Current view: top level - source4/torture - smbtorture.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 208 436 47.7 %
Date: 2024-05-31 13:13:24 Functions: 7 12 58.3 %

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

Generated by: LCOV version 1.14