2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-2003
5 Copyright (C) Jelmer Vernooij 2006
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 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "lib/cmdline/popt_common.h"
24 #include "libcli/raw/libcliraw.h"
25 #include "system/time.h"
26 #include "system/wait.h"
27 #include "system/filesys.h"
28 #include "libcli/raw/ioctl.h"
29 #include "libcli/libcli.h"
30 #include "lib/ldb/include/ldb.h"
31 #include "lib/events/events.h"
32 #include "libcli/resolve/resolve.h"
33 #include "auth/credentials/credentials.h"
34 #include "libcli/ldap/ldap_client.h"
35 #include "librpc/gen_ndr/ndr_nbt.h"
37 #include "torture/torture.h"
39 #include "dlinklist.h"
40 #include "librpc/rpc/dcerpc.h"
42 #define MAX_COLS 80 /* FIXME: Determine this at run-time */
44 /****************************************************************************
45 run a specified test or "ALL"
46 ****************************************************************************/
47 static BOOL
run_test(const char *name
)
53 if (strequal(name
,"ALL")) {
54 for (o
= torture_ops
; o
; o
= o
->next
) {
55 if (!run_test(o
->name
)) {
62 for (o
= torture_ops
; o
; o
= o
->next
) {
63 if (gen_fnmatch(name
, o
->name
) == 0) {
67 printf("Running %s\n", o
->name
);
70 t
= torture_create_procs(o
->multi_fn
,
74 printf("TEST %s FAILED!\n", o
->name
);
78 struct timeval tv
= timeval_current();
81 printf("TEST %s FAILED!\n", o
->name
);
83 t
= timeval_elapsed(&tv
);
85 printf("%s took %g secs\n\n", o
->name
, t
);
90 printf("Unknown torture operation '%s'\n", name
);
96 static void parse_dns(const char *dns
)
98 char *userdn
, *basedn
, *secret
;
101 /* retrievieng the userdn */
102 p
= strchr_m(dns
, '#');
104 lp_set_cmdline("torture:ldap_userdn", "");
105 lp_set_cmdline("torture:ldap_basedn", "");
106 lp_set_cmdline("torture:ldap_secret", "");
109 userdn
= strndup(dns
, p
- dns
);
110 lp_set_cmdline("torture:ldap_userdn", userdn
);
112 /* retrieve the basedn */
114 p
= strchr_m(d
, '#');
116 lp_set_cmdline("torture:ldap_basedn", "");
117 lp_set_cmdline("torture:ldap_secret", "");
120 basedn
= strndup(d
, p
- d
);
121 lp_set_cmdline("torture:ldap_basedn", basedn
);
123 /* retrieve the secret */
126 lp_set_cmdline("torture:ldap_secret", "");
130 lp_set_cmdline("torture:ldap_secret", secret
);
132 printf ("%s - %s - %s\n", userdn
, basedn
, secret
);
136 static void usage(poptContext pc
)
138 struct torture_op
*o
;
141 poptPrintUsage(pc
, stdout
, 0);
144 printf("The binding format is:\n\n");
146 printf(" TRANSPORT:host[flags]\n\n");
148 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
150 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
151 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
152 printf(" string.\n\n");
154 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
155 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
156 printf(" will be auto-determined.\n\n");
158 printf(" other recognised flags are:\n\n");
160 printf(" sign : enable ntlmssp signing\n");
161 printf(" seal : enable ntlmssp sealing\n");
162 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
163 printf(" validate: enable the NDR validator\n");
164 printf(" print: enable debugging of the packets\n");
165 printf(" bigendian: use bigendian RPC\n");
166 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
168 printf(" For example, these all connect to the samr pipe:\n\n");
170 printf(" ncacn_np:myserver\n");
171 printf(" ncacn_np:myserver[samr]\n");
172 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
173 printf(" ncacn_np:myserver[/pipe/samr]\n");
174 printf(" ncacn_np:myserver[samr,sign,print]\n");
175 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
176 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
177 printf(" ncacn_np:\n");
178 printf(" ncacn_np:[/pipe/samr]\n\n");
180 printf(" ncacn_ip_tcp:myserver\n");
181 printf(" ncacn_ip_tcp:myserver[1024]\n");
182 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
184 printf("The unc format is:\n\n");
186 printf(" //server/share\n\n");
188 printf("tests are:\n");
191 for (o
= torture_ops
; o
; o
= o
->next
) {
192 if (i
+ strlen(o
->name
) >= MAX_COLS
) {
196 i
+=printf("%s ", o
->name
);
200 printf("default test is ALL\n");
205 static BOOL
is_binding_string(const char *binding_string
)
207 TALLOC_CTX
*mem_ctx
= talloc_init("is_binding_string");
208 struct dcerpc_binding
*binding_struct
;
211 status
= dcerpc_parse_binding(mem_ctx
, binding_string
, &binding_struct
);
213 talloc_free(mem_ctx
);
214 return NT_STATUS_IS_OK(status
);
217 static void max_runtime_handler(int sig
)
219 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
223 /****************************************************************************
225 ****************************************************************************/
226 int main(int argc
,char *argv
[])
235 enum {OPT_LOADFILE
=1000,OPT_UNCLIST
,OPT_TIMELIMIT
,OPT_DNS
,
236 OPT_DANGEROUS
,OPT_SMB_PORTS
};
238 struct poptOption long_options
[] = {
240 {"smb-ports", 'p', POPT_ARG_STRING
, NULL
, OPT_SMB_PORTS
, "SMB ports", NULL
},
241 {"seed", 0, POPT_ARG_INT
, &torture_seed
, 0, "seed", NULL
},
242 {"num-progs", 0, POPT_ARG_INT
, &torture_nprocs
, 0, "num progs", NULL
},
243 {"num-ops", 0, POPT_ARG_INT
, &torture_numops
, 0, "num ops", NULL
},
244 {"entries", 0, POPT_ARG_INT
, &torture_entries
, 0, "entries", NULL
},
245 {"use-oplocks", 'L', POPT_ARG_NONE
, &use_oplocks
, 0, "use oplocks", NULL
},
246 {"show-all", 0, POPT_ARG_NONE
, &torture_showall
, 0, "show all", NULL
},
247 {"loadfile", 0, POPT_ARG_STRING
, NULL
, OPT_LOADFILE
, "loadfile", NULL
},
248 {"unclist", 0, POPT_ARG_STRING
, NULL
, OPT_UNCLIST
, "unclist", NULL
},
249 {"timelimit", 't', POPT_ARG_STRING
, NULL
, OPT_TIMELIMIT
, "timelimit", NULL
},
250 {"failures", 'f', POPT_ARG_INT
, &torture_failures
, 0, "failures", NULL
},
251 {"parse-dns", 'D', POPT_ARG_STRING
, NULL
, OPT_DNS
, "parse-dns", NULL
},
252 {"dangerous", 'X', POPT_ARG_NONE
, NULL
, OPT_DANGEROUS
, "dangerous", NULL
},
253 {"maximum-runtime", 0, POPT_ARG_INT
, &max_runtime
, 0,
254 "set maximum time for smbtorture to live", "seconds"},
256 POPT_COMMON_CONNECTION
257 POPT_COMMON_CREDENTIALS
262 #ifdef HAVE_SETBUFFER
263 setbuffer(stdout
, NULL
, 0);
268 /* we are never interested in SIGPIPE */
269 BlockSignals(True
,SIGPIPE
);
271 pc
= poptGetContext("smbtorture", argc
, (const char **) argv
, long_options
,
272 POPT_CONTEXT_KEEP_FIRST
);
274 poptSetOtherOptionHelp(pc
, "<binding>|<unc> TEST1 TEST2 ...");
276 while((opt
= poptGetNextOpt(pc
)) != -1) {
279 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc
));
282 lp_set_cmdline("torture:unclist", poptGetOptArg(pc
));
285 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc
));
288 parse_dns(poptGetOptArg(pc
));
291 lp_set_cmdline("torture:dangerous", "Yes");
294 lp_set_cmdline("smb ports", poptGetOptArg(pc
));
297 d_printf("Invalid option %s: %s\n",
298 poptBadOption(pc
, 0), poptStrerror(opt
));
305 /* this will only work if nobody else uses alarm(),
306 which means it won't work for some tests, but we
307 can't use the event context method we use for smbd
308 as so many tests create their own event
309 context. This will at least catch most cases. */
310 signal(SIGALRM
, max_runtime_handler
);
316 if (torture_seed
== 0) {
317 torture_seed
= time(NULL
);
319 printf("Using seed %d\n", torture_seed
);
320 srandom(torture_seed
);
322 argv_new
= discard_const_p(char *, poptGetArgs(pc
));
325 for (i
=0; i
<argc
; i
++) {
326 if (argv_new
[i
] == NULL
) {
337 for(p
= argv_new
[1]; *p
; p
++) {
342 /* see if its a RPC transport specifier */
343 if (is_binding_string(argv_new
[1])) {
344 lp_set_cmdline("torture:binding", argv_new
[1]);
346 char *binding
= NULL
;
347 char *host
= NULL
, *share
= NULL
;
349 if (!smbcli_parse_unc(argv_new
[1], NULL
, &host
, &share
)) {
350 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new
[1]);
354 lp_set_cmdline("torture:host", host
);
355 lp_set_cmdline("torture:share", share
);
356 asprintf(&binding
, "ncacn_np:%s", host
);
357 lp_set_cmdline("torture:binding", binding
);
361 printf("You must specify a test to run, or 'ALL'\n");
363 for (i
=2;i
<argc_new
;i
++) {
364 if (!run_test(argv_new
[i
])) {