2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "lib/cmdline/popt_common.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "system/time.h"
25 #include "system/wait.h"
26 #include "system/filesys.h"
27 #include "libcli/raw/ioctl.h"
28 #include "libcli/libcli.h"
29 #include "lib/ldb/include/ldb.h"
30 #include "librpc/rpc/dcerpc_table.h"
31 #include "lib/events/events.h"
32 #include "libcli/resolve/resolve.h"
34 #include "torture/basic/proto.h"
35 #include "torture/raw/proto.h"
36 #include "torture/smb2/proto.h"
37 #include "torture/rpc/proto.h"
38 #include "torture/rap/proto.h"
39 #include "torture/auth/proto.h"
40 #include "torture/local/proto.h"
41 #include "torture/nbench/proto.h"
42 #include "torture/ldap/proto.h"
43 #include "torture/com/proto.h"
44 #include "torture/nbt/proto.h"
45 #include "torture/libnet/proto.h"
46 #include "torture/torture.h"
49 int torture_numops=10;
50 int torture_entries=1000;
51 int torture_failures=1;
53 static int procnum; /* records process count number when forking */
54 static struct smbcli_state *current_cli;
55 static BOOL use_oplocks;
56 static BOOL use_level_II_oplocks;
58 BOOL torture_showall = False;
60 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
62 static struct smbcli_state *open_nbt_connection(void)
64 struct nbt_name called, calling;
65 struct smbcli_state *cli;
66 const char *host = lp_parm_string(-1, "torture", "host");
68 make_nbt_name_client(&calling, lp_netbios_name());
70 nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
72 cli = smbcli_state_init(NULL);
74 printf("Failed initialize smbcli_struct to connect with %s\n", host);
78 if (!smbcli_socket_connect(cli, host)) {
79 printf("Failed to connect with %s\n", host);
83 if (!smbcli_transport_establish(cli, &calling, &called)) {
84 printf("%s rejected the session\n",host);
95 BOOL torture_open_connection_share(TALLOC_CTX *mem_ctx,
96 struct smbcli_state **c,
98 const char *sharename,
99 struct event_context *ev)
103 status = smbcli_full_connection(mem_ctx, c, hostname,
105 cmdline_credentials, ev);
106 if (!NT_STATUS_IS_OK(status)) {
107 printf("Failed to open connection - %s\n", nt_errstr(status));
111 (*c)->transport->options.use_oplocks = use_oplocks;
112 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
117 BOOL torture_open_connection(struct smbcli_state **c)
119 const char *host = lp_parm_string(-1, "torture", "host");
120 const char *share = lp_parm_string(-1, "torture", "share");
122 return torture_open_connection_share(NULL, c, host, share, NULL);
127 BOOL torture_close_connection(struct smbcli_state *c)
131 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
132 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
139 /* open a rpc connection to the chosen binding string */
140 NTSTATUS torture_rpc_connection(TALLOC_CTX *parent_ctx,
141 struct dcerpc_pipe **p,
142 const struct dcerpc_interface_table *table)
145 const char *binding = lp_parm_string(-1, "torture", "binding");
148 printf("You must specify a ncacn binding string\n");
149 return NT_STATUS_INVALID_PARAMETER;
152 status = dcerpc_pipe_connect(parent_ctx,
154 cmdline_credentials, NULL);
159 /* open a rpc connection to a specific transport */
160 NTSTATUS torture_rpc_connection_transport(TALLOC_CTX *parent_ctx,
161 struct dcerpc_pipe **p,
162 const struct dcerpc_interface_table *table,
163 enum dcerpc_transport_t transport)
166 const char *binding = lp_parm_string(-1, "torture", "binding");
167 struct dcerpc_binding *b;
168 TALLOC_CTX *mem_ctx = talloc_named(parent_ctx, 0, "torture_rpc_connection_smb");
171 printf("You must specify a ncacn binding string\n");
172 talloc_free(mem_ctx);
173 return NT_STATUS_INVALID_PARAMETER;
176 status = dcerpc_parse_binding(mem_ctx, binding, &b);
177 if (!NT_STATUS_IS_OK(status)) {
178 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
179 talloc_free(mem_ctx);
183 b->transport = transport;
185 status = dcerpc_pipe_connect_b(mem_ctx, p, b, table,
186 cmdline_credentials, NULL);
188 if (NT_STATUS_IS_OK(status)) {
189 *p = talloc_reference(parent_ctx, *p);
193 talloc_free(mem_ctx);
197 /* check if the server produced the expected error code */
198 BOOL check_error(const char *location, struct smbcli_state *c,
199 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
203 status = smbcli_nt_error(c->tree);
204 if (NT_STATUS_IS_DOS(status)) {
206 class = NT_STATUS_DOS_CLASS(status);
207 num = NT_STATUS_DOS_CODE(status);
208 if (eclass != class || ecode != num) {
209 printf("unexpected error code %s\n", nt_errstr(status));
210 printf(" expected %s or %s (at %s)\n",
211 nt_errstr(NT_STATUS_DOS(eclass, ecode)),
212 nt_errstr(nterr), location);
216 if (!NT_STATUS_EQUAL(nterr, status)) {
217 printf("unexpected error code %s\n", nt_errstr(status));
218 printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
227 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
229 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
230 if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
236 static BOOL rw_torture(struct smbcli_state *c)
238 const char *lockfname = "\\torture.lck";
242 pid_t pid2, pid = getpid();
247 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
250 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
252 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
257 for (i=0;i<torture_numops;i++) {
258 uint_t n = (uint_t)random()%10;
260 printf("%d\r", i); fflush(stdout);
262 asprintf(&fname, "\\torture.%u", n);
264 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
268 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
270 printf("open failed (%s)\n", smbcli_errstr(c->tree));
275 if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
276 printf("write failed (%s)\n", smbcli_errstr(c->tree));
281 if (smbcli_write(c->tree, fnum, 0, buf,
282 sizeof(pid)+(j*sizeof(buf)),
283 sizeof(buf)) != sizeof(buf)) {
284 printf("write failed (%s)\n", smbcli_errstr(c->tree));
291 if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
292 printf("read failed (%s)\n", smbcli_errstr(c->tree));
297 printf("data corruption!\n");
301 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
302 printf("close failed (%s)\n", smbcli_errstr(c->tree));
306 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
307 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
311 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
312 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
318 smbcli_close(c->tree, fnum2);
319 smbcli_unlink(c->tree, lockfname);
326 static BOOL run_torture(struct smbcli_state *cli, int dummy)
330 ret = rw_torture(cli);
332 if (!torture_close_connection(cli)) {
340 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
342 const char *lockfname = "\\torture2.lck";
347 uint8_t buf_rd[131072];
349 ssize_t bytes_read, bytes_written;
351 if (smbcli_deltree(c1->tree, lockfname) == -1) {
352 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
355 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
358 printf("first open read/write of %s failed (%s)\n",
359 lockfname, smbcli_errstr(c1->tree));
362 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
365 printf("second open read-only of %s failed (%s)\n",
366 lockfname, smbcli_errstr(c2->tree));
367 smbcli_close(c1->tree, fnum1);
371 printf("Checking data integrity over %d ops\n", torture_numops);
373 for (i=0;i<torture_numops;i++)
375 size_t buf_size = ((uint_t)random()%(sizeof(buf)-1))+ 1;
377 printf("%d\r", i); fflush(stdout);
380 generate_random_buffer(buf, buf_size);
382 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
383 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
384 printf("wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
389 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
390 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
391 printf("read %d, expected %d\n", (int)bytes_read, (int)buf_size);
396 if (memcmp(buf_rd, buf, buf_size) != 0)
398 printf("read/write compare failed\n");
404 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
405 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
408 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
409 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
413 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
414 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
421 #define BOOLSTR(b) ((b) ? "Yes" : "No")
423 static BOOL run_readwritetest(void)
425 struct smbcli_state *cli1, *cli2;
426 BOOL test1, test2 = True;
428 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
432 printf("starting readwritetest\n");
434 test1 = rw_torture2(cli1, cli2);
435 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
438 test2 = rw_torture2(cli1, cli1);
439 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
442 if (!torture_close_connection(cli1)) {
446 if (!torture_close_connection(cli2)) {
450 return (test1 && test2);
454 this checks to see if a secondary tconx can use open files from an
457 static BOOL run_tcon_test(void)
459 struct smbcli_state *cli;
460 const char *fname = "\\tcontest.tmp";
462 uint16_t cnum1, cnum2, cnum3;
463 uint16_t vuid1, vuid2;
466 struct smbcli_tree *tree1;
467 const char *host = lp_parm_string(-1, "torture", "host");
468 const char *share = lp_parm_string(-1, "torture", "share");
469 const char *password = lp_parm_string(-1, "torture", "password");
471 if (!torture_open_connection(&cli)) {
475 printf("starting tcontest\n");
477 if (smbcli_deltree(cli->tree, fname) == -1) {
478 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
481 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
483 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
487 cnum1 = cli->tree->tid;
488 vuid1 = cli->session->vuid;
490 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
491 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
492 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
496 tree1 = cli->tree; /* save old tree connection */
497 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
498 printf("%s refused 2nd tree connect (%s)\n", host,
499 smbcli_errstr(cli->tree));
504 cnum2 = cli->tree->tid;
505 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
506 vuid2 = cli->session->vuid + 1;
508 /* try a write with the wrong tid */
509 cli->tree->tid = cnum2;
511 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
512 printf("* server allows write with wrong TID\n");
515 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
519 /* try a write with an invalid tid */
520 cli->tree->tid = cnum3;
522 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
523 printf("* server allows write with invalid TID\n");
526 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
529 /* try a write with an invalid vuid */
530 cli->session->vuid = vuid2;
531 cli->tree->tid = cnum1;
533 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
534 printf("* server allows write with invalid VUID\n");
537 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
540 cli->session->vuid = vuid1;
541 cli->tree->tid = cnum1;
543 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
544 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
548 cli->tree->tid = cnum2;
550 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
551 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
555 cli->tree = tree1; /* restore initial tree */
556 cli->tree->tid = cnum1;
558 smbcli_unlink(tree1, fname);
560 if (!torture_close_connection(cli)) {
569 static BOOL tcon_devtest(struct smbcli_state *cli,
570 const char *myshare, const char *devtype,
571 NTSTATUS expected_error)
575 const char *password = lp_parm_string(-1, "torture", "password");
577 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
580 printf("Trying share %s with devtype %s\n", myshare, devtype);
582 if (NT_STATUS_IS_OK(expected_error)) {
586 printf("tconX to share %s with type %s "
587 "should have succeeded but failed\n",
594 printf("tconx to share %s with type %s "
595 "should have failed but succeeded\n",
599 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
603 printf("Returned unexpected error\n");
612 checks for correct tconX support
614 static BOOL run_tcon_devtype_test(void)
616 struct smbcli_state *cli1 = NULL;
619 const char *host = lp_parm_string(-1, "torture", "host");
620 const char *share = lp_parm_string(-1, "torture", "share");
622 status = smbcli_full_connection(NULL,
625 cmdline_credentials, NULL);
627 if (!NT_STATUS_IS_OK(status)) {
628 printf("could not open connection\n");
632 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
635 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
638 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
641 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
644 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
647 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
650 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
653 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
656 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
659 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
665 printf("Passed tcondevtest\n");
672 test whether fnums and tids open on one VC are available on another (a major
675 static BOOL run_fdpasstest(void)
677 struct smbcli_state *cli1, *cli2;
678 const char *fname = "\\fdpass.tst";
682 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
686 printf("starting fdpasstest\n");
688 smbcli_unlink(cli1->tree, fname);
690 printf("Opening a file on connection 1\n");
692 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
694 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
698 printf("writing to file on connection 1\n");
700 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
701 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
705 oldtid = cli2->tree->tid;
706 cli2->session->vuid = cli1->session->vuid;
707 cli2->tree->tid = cli1->tree->tid;
708 cli2->session->pid = cli1->session->pid;
710 printf("reading from file on connection 2\n");
712 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
713 printf("read succeeded! nasty security hole [%s]\n",
718 smbcli_close(cli1->tree, fnum1);
719 smbcli_unlink(cli1->tree, fname);
721 cli2->tree->tid = oldtid;
723 torture_close_connection(cli1);
724 torture_close_connection(cli2);
726 printf("finished fdpasstest\n");
732 test the timing of deferred open requests
734 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
736 const char *fname = "\\defer_open_test.dat";
742 printf("failed to connect\n");
746 printf("Testing deferred open requests.\n");
753 tv = timeval_current();
754 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
756 FILE_ATTRIBUTE_NORMAL,
757 NTCREATEX_SHARE_ACCESS_NONE,
758 NTCREATEX_DISP_OPEN_IF, 0, 0);
762 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
763 double e = timeval_elapsed(&tv);
764 if (e < 0.5 || e > 1.5) {
765 fprintf(stderr,"Timing incorrect %.2f violation\n",
769 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
772 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
776 printf("pid %u open %d\n", getpid(), i);
780 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
781 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
787 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
788 /* All until the last unlink will fail with sharing violation. */
789 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
790 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
795 printf("deferred test finished\n");
796 if (!torture_close_connection(cli)) {
803 test how many open files this server supports on the one socket
805 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
807 #define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
809 int fnums[0x11000], i;
810 int retries=4, maxfid;
814 printf("failed to connect\n");
818 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
819 printf("Failed to deltree \\maxfid - %s\n",
820 smbcli_errstr(cli->tree));
823 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
824 printf("Failed to mkdir \\maxfid, error=%s\n",
825 smbcli_errstr(cli->tree));
829 printf("Testing maximum number of open files\n");
831 for (i=0; i<0x11000; i++) {
833 asprintf(&fname, "\\maxfid\\fid%d", i/1000);
834 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
835 printf("Failed to mkdir %s, error=%s\n",
836 fname, smbcli_errstr(cli->tree));
841 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
842 if ((fnums[i] = smbcli_open(cli->tree, fname,
843 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
845 printf("open of %s failed (%s)\n",
846 fname, smbcli_errstr(cli->tree));
847 printf("maximum fnum is %d\n", i);
858 printf("cleaning up\n");
859 for (i=0;i<maxfid/2;i++) {
860 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
861 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
862 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
864 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
865 printf("unlink of %s failed (%s)\n",
866 fname, smbcli_errstr(cli->tree));
871 asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
872 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
873 printf("Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
875 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
876 printf("unlink of %s failed (%s)\n",
877 fname, smbcli_errstr(cli->tree));
882 printf("%6d %6d\r", i, maxfid-i);
886 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
887 printf("Failed to deltree \\maxfid - %s\n",
888 smbcli_errstr(cli->tree));
892 printf("maxfid test finished\n");
893 if (!torture_close_connection(cli)) {
897 #undef MAXFID_TEMPLATE
900 /* send smb negprot commands, not reading the response */
901 static BOOL run_negprot_nowait(void)
904 struct smbcli_state *cli, *cli2;
907 printf("starting negprot nowait test\n");
909 cli = open_nbt_connection();
914 printf("Filling send buffer\n");
916 for (i=0;i<100;i++) {
917 struct smbcli_request *req;
918 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
919 event_loop_once(cli->transport->socket->event.ctx);
920 if (req->state == SMBCLI_REQUEST_ERROR) {
921 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
922 torture_close_connection(cli);
927 printf("Opening secondary connection\n");
928 if (!torture_open_connection(&cli2)) {
932 if (!torture_close_connection(cli)) {
936 if (!torture_close_connection(cli2)) {
940 printf("finished negprot nowait test\n");
947 This checks how the getatr calls works
949 static BOOL run_attrtest(void)
951 struct smbcli_state *cli;
954 const char *fname = "\\attrib123456789.tst";
957 printf("starting attrib test\n");
959 if (!torture_open_connection(&cli)) {
963 smbcli_unlink(cli->tree, fname);
964 fnum = smbcli_open(cli->tree, fname,
965 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
966 smbcli_close(cli->tree, fnum);
968 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
969 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
973 printf("New file time is %s", ctime(&t));
975 if (abs(t - time(NULL)) > 60*60*24*10) {
976 printf("ERROR: SMBgetatr bug. time is %s",
982 t2 = t-60*60*24; /* 1 day ago */
984 printf("Setting file time to %s", ctime(&t2));
986 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
987 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
991 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
992 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
996 printf("Retrieved file time as %s", ctime(&t));
999 printf("ERROR: getatr/setatr bug. times are\n%s",
1001 printf("%s", ctime(&t2));
1005 smbcli_unlink(cli->tree, fname);
1007 if (!torture_close_connection(cli)) {
1011 printf("attrib test finished\n");
1018 This checks a couple of trans2 calls
1020 static BOOL run_trans2test(void)
1022 struct smbcli_state *cli;
1025 time_t c_time, a_time, m_time, w_time, m_time2;
1026 const char *fname = "\\trans2.tst";
1027 const char *dname = "\\trans2";
1028 const char *fname2 = "\\trans2\\trans2.tst";
1030 BOOL correct = True;
1032 printf("starting trans2 test\n");
1034 if (!torture_open_connection(&cli)) {
1038 smbcli_unlink(cli->tree, fname);
1040 printf("Testing qfileinfo\n");
1042 fnum = smbcli_open(cli->tree, fname,
1043 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1044 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
1046 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
1050 printf("Testing NAME_INFO\n");
1052 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
1053 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
1057 if (!pname || strcmp(pname, fname)) {
1058 printf("qfilename gave different name? [%s] [%s]\n",
1063 smbcli_close(cli->tree, fnum);
1064 smbcli_unlink(cli->tree, fname);
1066 fnum = smbcli_open(cli->tree, fname,
1067 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1069 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1072 smbcli_close(cli->tree, fnum);
1074 printf("Checking for sticky create times\n");
1076 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1077 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
1080 if (c_time != m_time) {
1081 printf("create time=%s", ctime(&c_time));
1082 printf("modify time=%s", ctime(&m_time));
1083 printf("This system appears to have sticky create times\n");
1085 if (a_time % (60*60) == 0) {
1086 printf("access time=%s", ctime(&a_time));
1087 printf("This system appears to set a midnight access time\n");
1091 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1092 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1098 smbcli_unlink(cli->tree, fname);
1099 fnum = smbcli_open(cli->tree, fname,
1100 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1101 smbcli_close(cli->tree, fnum);
1102 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1103 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1106 if (w_time < 60*60*24*2) {
1107 printf("write time=%s", ctime(&w_time));
1108 printf("This system appears to set a initial 0 write time\n");
1113 smbcli_unlink(cli->tree, fname);
1116 /* check if the server updates the directory modification time
1117 when creating a new file */
1118 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1119 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
1123 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1124 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1128 fnum = smbcli_open(cli->tree, fname2,
1129 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1130 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
1131 smbcli_close(cli->tree, fnum);
1132 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
1133 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1136 if (m_time2 == m_time) {
1137 printf("This system does not update directory modification times\n");
1141 smbcli_unlink(cli->tree, fname2);
1142 smbcli_rmdir(cli->tree, dname);
1144 if (!torture_close_connection(cli)) {
1148 printf("trans2 test finished\n");
1155 /* FIRST_DESIRED_ACCESS 0xf019f */
1156 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1157 SEC_FILE_READ_EA| /* 0xf */ \
1158 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1159 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1160 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1161 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1162 /* SECOND_DESIRED_ACCESS 0xe0080 */
1163 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1164 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1165 SEC_STD_WRITE_OWNER /* 0xe0000 */
1168 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1169 READ_CONTROL|WRITE_DAC|\
1170 SEC_FILE_READ_DATA|\
1175 Test ntcreate calls made by xcopy
1177 static BOOL run_xcopy(void)
1179 struct smbcli_state *cli1;
1180 const char *fname = "\\test.txt";
1181 BOOL correct = True;
1184 printf("starting xcopy test\n");
1186 if (!torture_open_connection(&cli1)) {
1190 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1191 FIRST_DESIRED_ACCESS,
1192 FILE_ATTRIBUTE_ARCHIVE,
1193 NTCREATEX_SHARE_ACCESS_NONE,
1194 NTCREATEX_DISP_OVERWRITE_IF,
1198 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
1202 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1203 SECOND_DESIRED_ACCESS, 0,
1204 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1207 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
1211 if (!torture_close_connection(cli1)) {
1220 see how many RPC pipes we can open at once
1222 static BOOL run_pipe_number(void)
1224 struct smbcli_state *cli1;
1225 const char *pipe_name = "\\WKSSVC";
1229 printf("starting pipenumber test\n");
1230 if (!torture_open_connection(&cli1)) {
1235 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1236 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1239 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
1243 printf("%d\r", num_pipes);
1247 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
1248 torture_close_connection(cli1);
1256 open N connections to the server and just hold them open
1257 used for testing performance when there are N idle users
1260 static BOOL torture_holdcon(void)
1263 struct smbcli_state **cli;
1266 printf("Opening %d connections\n", torture_numops);
1268 cli = malloc_array_p(struct smbcli_state *, torture_numops);
1270 for (i=0;i<torture_numops;i++) {
1271 if (!torture_open_connection(&cli[i])) {
1274 printf("opened %d connections\r", i);
1278 printf("\nStarting pings\n");
1281 for (i=0;i<torture_numops;i++) {
1284 status = smbcli_chkpath(cli[i]->tree, "\\");
1285 if (!NT_STATUS_IS_OK(status)) {
1286 printf("Connection %d is dead\n", i);
1294 if (num_dead == torture_numops) {
1295 printf("All connections dead - finishing\n");
1307 Try with a wrong vuid and check error message.
1310 static BOOL run_vuidtest(void)
1312 struct smbcli_state *cli;
1313 const char *fname = "\\vuid.tst";
1316 time_t c_time, a_time, m_time;
1317 BOOL correct = True;
1322 printf("starting vuid test\n");
1324 if (!torture_open_connection(&cli)) {
1328 smbcli_unlink(cli->tree, fname);
1330 fnum = smbcli_open(cli->tree, fname,
1331 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1333 orig_vuid = cli->session->vuid;
1335 cli->session->vuid += 1234;
1337 printf("Testing qfileinfo with wrong vuid\n");
1339 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
1340 &size, &c_time, &a_time,
1341 &m_time, NULL, NULL))) {
1342 printf("ERROR: qfileinfo passed with wrong vuid\n");
1346 if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1347 NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
1348 !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1349 NT_STATUS_INVALID_HANDLE)) {
1350 printf("ERROR: qfileinfo should have returned DOS error "
1351 "ERRSRV:ERRbaduid\n but returned %s\n",
1352 smbcli_errstr(cli->tree));
1356 cli->session->vuid -= 1234;
1358 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1359 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
1363 smbcli_unlink(cli->tree, fname);
1365 if (!torture_close_connection(cli)) {
1369 printf("vuid test finished\n");
1375 Test open mode returns on read-only files.
1377 static BOOL run_opentest(void)
1379 static struct smbcli_state *cli1;
1380 static struct smbcli_state *cli2;
1381 const char *fname = "\\readonly.file";
1382 char *control_char_fname;
1386 BOOL correct = True;
1391 printf("starting open test\n");
1393 if (!torture_open_connection(&cli1)) {
1397 asprintf(&control_char_fname, "\\readonly.afile");
1398 for (i = 1; i <= 0x1f; i++) {
1399 control_char_fname[10] = i;
1400 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
1401 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1403 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
1404 NT_STATUS_OBJECT_NAME_INVALID)) {
1405 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
1406 smbcli_errstr(cli1->tree), i);
1411 smbcli_close(cli1->tree, fnum1);
1413 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
1414 smbcli_unlink(cli1->tree, control_char_fname);
1416 free(control_char_fname);
1419 printf("Create file with control char names passed.\n");
1421 smbcli_setatr(cli1->tree, fname, 0, 0);
1422 smbcli_unlink(cli1->tree, fname);
1424 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1426 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1430 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1431 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1435 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
1436 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
1437 CHECK_MAX_FAILURES(error_test1);
1441 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1443 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1444 CHECK_MAX_FAILURES(error_test1);
1448 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
1449 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1451 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
1452 NT_STATUS_ACCESS_DENIED)) {
1453 printf("correct error code ERRDOS/ERRnoaccess returned\n");
1456 printf("finished open test 1\n");
1458 smbcli_close(cli1->tree, fnum1);
1460 /* Now try not readonly and ensure ERRbadshare is returned. */
1462 smbcli_setatr(cli1->tree, fname, 0, 0);
1464 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1466 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1470 /* This will fail - but the error should be ERRshare. */
1471 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1473 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
1474 NT_STATUS_SHARING_VIOLATION)) {
1475 printf("correct error code ERRDOS/ERRbadshare returned\n");
1478 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1479 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1483 smbcli_unlink(cli1->tree, fname);
1485 printf("finished open test 2\n");
1487 /* Test truncate open disposition on file opened for read. */
1489 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1491 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1495 /* write 20 bytes. */
1497 memset(buf, '\0', 20);
1499 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1500 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1504 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1505 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1509 /* Ensure size == 20. */
1510 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1511 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1512 CHECK_MAX_FAILURES(error_test3);
1517 printf("(3) file size != 20\n");
1518 CHECK_MAX_FAILURES(error_test3);
1522 /* Now test if we can truncate a file opened for readonly. */
1524 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
1526 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1527 CHECK_MAX_FAILURES(error_test3);
1531 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1532 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1536 /* Ensure size == 0. */
1537 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1538 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1539 CHECK_MAX_FAILURES(error_test3);
1544 printf("(3) file size != 0\n");
1545 CHECK_MAX_FAILURES(error_test3);
1548 printf("finished open test 3\n");
1550 smbcli_unlink(cli1->tree, fname);
1553 printf("testing ctemp\n");
1554 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
1556 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1557 CHECK_MAX_FAILURES(error_test4);
1560 printf("ctemp gave path %s\n", tmp_path);
1561 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1562 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1564 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1565 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1568 /* Test the non-io opens... */
1570 if (!torture_open_connection(&cli2)) {
1574 smbcli_setatr(cli2->tree, fname, 0, 0);
1575 smbcli_unlink(cli2->tree, fname);
1577 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1579 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1580 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1583 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1584 CHECK_MAX_FAILURES(error_test10);
1588 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1589 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1591 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1592 CHECK_MAX_FAILURES(error_test10);
1596 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1597 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1600 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1601 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1605 printf("non-io open test #1 passed.\n");
1607 smbcli_unlink(cli1->tree, fname);
1609 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1611 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1612 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1615 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1616 CHECK_MAX_FAILURES(error_test20);
1620 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1621 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1624 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1625 CHECK_MAX_FAILURES(error_test20);
1629 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1630 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1633 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1634 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1638 printf("non-io open test #2 passed.\n");
1640 smbcli_unlink(cli1->tree, fname);
1642 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1644 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1645 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1648 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1649 CHECK_MAX_FAILURES(error_test30);
1653 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1654 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1657 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1658 CHECK_MAX_FAILURES(error_test30);
1662 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1663 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1666 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1667 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1671 printf("non-io open test #3 passed.\n");
1673 smbcli_unlink(cli1->tree, fname);
1675 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1677 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1678 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1681 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1682 CHECK_MAX_FAILURES(error_test40);
1686 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1687 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1690 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1691 CHECK_MAX_FAILURES(error_test40);
1695 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1697 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1698 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1702 printf("non-io open test #4 passed.\n");
1704 smbcli_unlink(cli1->tree, fname);
1706 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1708 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1709 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1712 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1713 CHECK_MAX_FAILURES(error_test50);
1717 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1718 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1721 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1722 CHECK_MAX_FAILURES(error_test50);
1726 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1727 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1731 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1732 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1736 printf("non-io open test #5 passed.\n");
1738 printf("TEST #6 testing 1 non-io open, one io open\n");
1740 smbcli_unlink(cli1->tree, fname);
1742 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1743 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1746 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1747 CHECK_MAX_FAILURES(error_test60);
1751 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1752 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1755 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1756 CHECK_MAX_FAILURES(error_test60);
1760 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1761 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1765 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1766 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1770 printf("non-io open test #6 passed.\n");
1772 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
1774 smbcli_unlink(cli1->tree, fname);
1776 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1777 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1780 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1781 CHECK_MAX_FAILURES(error_test70);
1785 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1786 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1789 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1790 CHECK_MAX_FAILURES(error_test70);
1794 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1796 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1797 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1801 printf("non-io open test #7 passed.\n");
1805 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1807 smbcli_unlink(cli1->tree, fname);
1809 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1811 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1815 /* write 20 bytes. */
1817 memset(buf, '\0', 20);
1819 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1820 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1824 /* Ensure size == 20. */
1825 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1826 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1827 CHECK_MAX_FAILURES(error_test80);
1832 printf("(8) file size != 20\n");
1833 CHECK_MAX_FAILURES(error_test80);
1837 /* Get an exclusive lock on the open file. */
1838 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1839 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1840 CHECK_MAX_FAILURES(error_test80);
1844 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1846 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1850 /* Ensure size == 0. */
1851 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1852 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1853 CHECK_MAX_FAILURES(error_test80);
1858 printf("(8) file size != 0\n");
1859 CHECK_MAX_FAILURES(error_test80);
1863 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1864 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1868 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1869 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1875 printf("open test #8 passed.\n");
1877 smbcli_unlink(cli1->tree, fname);
1879 if (!torture_close_connection(cli1)) {
1882 if (!torture_close_connection(cli2)) {
1891 sees what IOCTLs are supported
1893 BOOL torture_ioctl_test(void)
1895 struct smbcli_state *cli;
1896 uint16_t device, function;
1898 const char *fname = "\\ioctl.dat";
1900 union smb_ioctl parms;
1901 TALLOC_CTX *mem_ctx;
1903 if (!torture_open_connection(&cli)) {
1907 mem_ctx = talloc_init("ioctl_test");
1909 printf("starting ioctl test\n");
1911 smbcli_unlink(cli->tree, fname);
1913 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1915 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1919 parms.ioctl.level = RAW_IOCTL_IOCTL;
1920 parms.ioctl.in.fnum = fnum;
1921 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
1922 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1923 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
1925 for (device=0;device<0x100;device++) {
1926 printf("testing device=0x%x\n", device);
1927 for (function=0;function<0x100;function++) {
1928 parms.ioctl.in.request = (device << 16) | function;
1929 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1931 if (NT_STATUS_IS_OK(status)) {
1932 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
1933 device, function, (int)parms.ioctl.out.blob.length);
1938 if (!torture_close_connection(cli)) {
1947 tries variants of chkpath
1949 BOOL torture_chkpath_test(void)
1951 struct smbcli_state *cli;
1955 if (!torture_open_connection(&cli)) {
1959 printf("starting chkpath test\n");
1961 printf("Testing valid and invalid paths\n");
1963 /* cleanup from an old run */
1964 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1965 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1966 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1968 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1969 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1973 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1974 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1978 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1980 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
1983 smbcli_close(cli->tree, fnum);
1985 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1986 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1990 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1991 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1995 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1996 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1997 NT_STATUS_NOT_A_DIRECTORY);
1999 printf("* chkpath on a file should fail\n");
2003 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
2004 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2005 NT_STATUS_OBJECT_NAME_NOT_FOUND);
2007 printf("* chkpath on a non existent file should fail\n");
2011 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
2012 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2013 NT_STATUS_OBJECT_PATH_NOT_FOUND);
2015 printf("* chkpath on a non existent component should fail\n");
2019 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
2020 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
2021 smbcli_rmdir(cli->tree, "\\chkpath.dir");
2023 if (!torture_close_connection(cli)) {
2031 static void sigcont(int sig)
2035 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
2038 volatile pid_t *child_status;
2039 volatile BOOL *child_status_out;
2042 double start_time_limit = 10 + (torture_nprocs * 1.5);
2043 char **unc_list = NULL;
2045 int num_unc_names = 0;
2052 signal(SIGCONT, sigcont);
2054 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
2055 if (!child_status) {
2056 printf("Failed to setup shared memory\n");
2060 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
2061 if (!child_status_out) {
2062 printf("Failed to setup result status shared memory\n");
2066 p = lp_parm_string(-1, "torture", "unclist");
2068 unc_list = file_lines_load(p, &num_unc_names, NULL);
2069 if (!unc_list || num_unc_names <= 0) {
2070 printf("Failed to load unc names list from '%s'\n", p);
2075 for (i = 0; i < torture_nprocs; i++) {
2076 child_status[i] = 0;
2077 child_status_out[i] = True;
2080 tv = timeval_current();
2082 for (i=0;i<torture_nprocs;i++) {
2086 const char *hostname=NULL, *sharename;
2088 pid_t mypid = getpid();
2089 srandom(((int)mypid) ^ ((int)time(NULL)));
2091 asprintf(&myname, "CLIENT%d", i);
2092 lp_set_cmdline("netbios name", myname);
2097 if (!smbcli_parse_unc(unc_list[i % num_unc_names],
2098 NULL, &hostname, &sharename)) {
2099 printf("Failed to parse UNC name %s\n",
2100 unc_list[i % num_unc_names]);
2107 if (torture_open_connection_share(NULL,
2114 } else if (torture_open_connection(¤t_cli)) {
2118 printf("pid %d failed to start\n", (int)getpid());
2124 child_status[i] = getpid();
2128 if (child_status[i]) {
2129 printf("Child %d failed to start!\n", i);
2130 child_status_out[i] = 1;
2134 child_status_out[i] = fn(current_cli, i);
2141 for (i=0;i<torture_nprocs;i++) {
2142 if (child_status[i]) synccount++;
2144 if (synccount == torture_nprocs) break;
2146 } while (timeval_elapsed(&tv) < start_time_limit);
2148 if (synccount != torture_nprocs) {
2149 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
2151 return timeval_elapsed(&tv);
2154 printf("Starting %d clients\n", torture_nprocs);
2156 /* start the client load */
2157 tv = timeval_current();
2158 for (i=0;i<torture_nprocs;i++) {
2159 child_status[i] = 0;
2162 printf("%d clients started\n", torture_nprocs);
2166 for (i=0;i<torture_nprocs;i++) {
2168 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
2169 if (ret == -1 || WEXITSTATUS(status) != 0) {
2176 for (i=0;i<torture_nprocs;i++) {
2177 if (!child_status_out[i]) {
2181 return timeval_elapsed(&tv);
2184 #define FLAG_MULTIPROC 1
2189 BOOL (*multi_fn)(struct smbcli_state *, int );
2192 {"BASE-FDPASS", run_fdpasstest, 0},
2193 {"BASE-LOCK1", torture_locktest1, 0},
2194 {"BASE-LOCK2", torture_locktest2, 0},
2195 {"BASE-LOCK3", torture_locktest3, 0},
2196 {"BASE-LOCK4", torture_locktest4, 0},
2197 {"BASE-LOCK5", torture_locktest5, 0},
2198 {"BASE-LOCK6", torture_locktest6, 0},
2199 {"BASE-LOCK7", torture_locktest7, 0},
2200 {"BASE-UNLINK", torture_unlinktest, 0},
2201 {"BASE-ATTR", run_attrtest, 0},
2202 {"BASE-TRANS2", run_trans2test, 0},
2203 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
2204 {"BASE-DIR1", torture_dirtest1, 0},
2205 {"BASE-DIR2", torture_dirtest2, 0},
2206 {"BASE-DENY1", torture_denytest1, 0},
2207 {"BASE-DENY2", torture_denytest2, 0},
2208 {"BASE-DENY3", torture_denytest3, 0},
2209 {"BASE-DENYDOS", torture_denydos_sharing, 0},
2210 {"BASE-NTDENY1", NULL, torture_ntdenytest1},
2211 {"BASE-NTDENY2", torture_ntdenytest2, 0},
2212 {"BASE-TCON", run_tcon_test, 0},
2213 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
2214 {"BASE-VUID", run_vuidtest, 0},
2215 {"BASE-RW1", run_readwritetest, 0},
2216 {"BASE-OPEN", run_opentest, 0},
2217 {"BASE-DEFER_OPEN", NULL, run_deferopen},
2218 {"BASE-XCOPY", run_xcopy, 0},
2219 {"BASE-RENAME", torture_test_rename, 0},
2220 {"BASE-DELETE", torture_test_delete, 0},
2221 {"BASE-PROPERTIES", torture_test_properties, 0},
2222 {"BASE-MANGLE", torture_mangle, 0},
2223 {"BASE-OPENATTR", torture_openattrtest, 0},
2224 {"BASE-CHARSET", torture_charset, 0},
2225 {"BASE-CHKPATH", torture_chkpath_test, 0},
2226 {"BASE-SECLEAK", torture_sec_leak, 0},
2227 {"BASE-DISCONNECT", torture_disconnect, 0},
2228 {"BASE-DELAYWRITE", torture_delay_write, 0},
2230 /* benchmarking tests */
2231 {"BENCH-HOLDCON", torture_holdcon, 0},
2232 {"BENCH-NBENCH", torture_nbench, 0},
2233 {"BENCH-TORTURE", NULL, run_torture},
2234 {"BENCH-NBT", torture_bench_nbt, 0},
2235 {"BENCH-WINS", torture_bench_wins, 0},
2236 {"BENCH-RPC", torture_bench_rpc, 0},
2237 {"BENCH-CLDAP", torture_bench_cldap, 0},
2240 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
2241 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
2242 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
2243 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
2244 {"RAW-SEARCH", torture_raw_search, 0},
2245 {"RAW-CLOSE", torture_raw_close, 0},
2246 {"RAW-OPEN", torture_raw_open, 0},
2247 {"RAW-MKDIR", torture_raw_mkdir, 0},
2248 {"RAW-OPLOCK", torture_raw_oplock, 0},
2249 {"RAW-NOTIFY", torture_raw_notify, 0},
2250 {"RAW-MUX", torture_raw_mux, 0},
2251 {"RAW-IOCTL", torture_raw_ioctl, 0},
2252 {"RAW-CHKPATH", torture_raw_chkpath, 0},
2253 {"RAW-UNLINK", torture_raw_unlink, 0},
2254 {"RAW-READ", torture_raw_read, 0},
2255 {"RAW-WRITE", torture_raw_write, 0},
2256 {"RAW-LOCK", torture_raw_lock, 0},
2257 {"RAW-CONTEXT", torture_raw_context, 0},
2258 {"RAW-RENAME", torture_raw_rename, 0},
2259 {"RAW-SEEK", torture_raw_seek, 0},
2260 {"RAW-EAS", torture_raw_eas, 0},
2261 {"RAW-EAMAX", torture_max_eas, 0},
2262 {"RAW-STREAMS", torture_raw_streams, 0},
2263 {"RAW-ACLS", torture_raw_acls, 0},
2264 {"RAW-RAP", torture_raw_rap, 0},
2265 {"RAW-COMPOSITE", torture_raw_composite, 0},
2268 {"SMB2-CONNECT", torture_smb2_connect, 0},
2269 {"SMB2-SCAN", torture_smb2_scan, 0},
2270 {"SMB2-SCANGETINFO", torture_smb2_getinfo_scan, 0},
2271 {"SMB2-SCANSETINFO", torture_smb2_setinfo_scan, 0},
2272 {"SMB2-SCANFIND", torture_smb2_find_scan, 0},
2273 {"SMB2-GETINFO", torture_smb2_getinfo, 0},
2274 {"SMB2-SETINFO", torture_smb2_setinfo, 0},
2275 {"SMB2-FIND", torture_smb2_find, 0},
2277 /* protocol scanners */
2278 {"SCAN-TRANS2", torture_trans2_scan, 0},
2279 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2280 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2281 {"SCAN-SMB", torture_smb_scan, 0},
2282 {"SCAN-MAXFID", NULL, run_maxfidtest},
2283 {"SCAN-UTABLE", torture_utable, 0},
2284 {"SCAN-CASETABLE", torture_casetable, 0},
2285 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2286 {"SCAN-IOCTL", torture_ioctl_test, 0},
2287 {"SCAN-RAP", torture_rap_scan, 0},
2290 {"RPC-LSA", torture_rpc_lsa, 0},
2291 {"RPC-LSALOOKUP", torture_rpc_lsa_lookup, 0},
2292 {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
2293 {"RPC-ECHO", torture_rpc_echo, 0},
2294 {"RPC-DFS", torture_rpc_dfs, 0},
2295 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2296 {"RPC-SAMR", torture_rpc_samr, 0},
2297 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2298 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2299 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2300 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2301 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2302 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2303 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2304 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2305 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2306 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2307 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2308 {"RPC-WINREG", torture_rpc_winreg, 0},
2309 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2310 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2311 {"RPC-REMACT", torture_rpc_remact, 0},
2312 {"RPC-MGMT", torture_rpc_mgmt, 0},
2313 {"RPC-SCANNER", torture_rpc_scanner, 0},
2314 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2315 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2316 {"RPC-MULTIBIND", torture_multi_bind, 0},
2317 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2318 {"RPC-CRACKNAMES", torture_rpc_drsuapi_cracknames, 0},
2319 {"RPC-ROT", torture_rpc_rot, 0},
2320 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2321 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2322 {"RPC-JOIN", torture_rpc_join, 0},
2323 {"RPC-DSSYNC", torture_rpc_dssync, 0},
2325 /* local (no server) testers */
2326 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2327 {"LOCAL-ICONV", torture_local_iconv, 0},
2328 {"LOCAL-TALLOC", torture_local_talloc, 0},
2329 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2330 {"LOCAL-IRPC", torture_local_irpc, 0},
2331 {"LOCAL-BINDING", torture_local_binding_string, 0},
2332 {"LOCAL-STRLIST", torture_local_util_strlist, 0},
2333 {"LOCAL-FILE", torture_local_util_file, 0},
2334 {"LOCAL-IDTREE", torture_local_idtree, 0},
2335 {"LOCAL-SOCKET", torture_local_socket, 0},
2336 {"LOCAL-PAC", torture_pac, 0},
2337 {"LOCAL-REGISTRY", torture_registry, 0},
2338 {"LOCAL-RESOLVE", torture_local_resolve, 0},
2339 {"LOCAL-SDDL", torture_local_sddl, 0},
2340 {"LOCAL-NDR", torture_local_ndr, 0},
2342 /* COM (Component Object Model) testers */
2343 {"COM-SIMPLE", torture_com_simple, 0 },
2346 {"LDAP-BASIC", torture_ldap_basic, 0},
2347 {"LDAP-CLDAP", torture_cldap, 0},
2350 {"NBT-REGISTER", torture_nbt_register, 0},
2351 {"NBT-WINS", torture_nbt_wins, 0},
2352 {"NBT-DGRAM", torture_nbt_dgram, 0},
2353 {"NBT-BROWSE", torture_nbt_browse, 0},
2354 {"NBT-WINSREPLICATION-SIMPLE", torture_nbt_winsreplication_simple, 0},
2355 {"NBT-WINSREPLICATION-REPLICA", torture_nbt_winsreplication_replica, 0},
2356 {"NBT-WINSREPLICATION-OWNED", torture_nbt_winsreplication_owned, 0},
2359 {"NET-USERINFO", torture_userinfo, 0},
2360 {"NET-USERADD", torture_useradd, 0},
2361 {"NET-USERDEL", torture_userdel, 0},
2362 {"NET-USERMOD", torture_usermod, 0},
2363 {"NET-DOMOPEN", torture_domainopen, 0},
2364 {"NET-API-LOOKUP", torture_lookup, 0},
2365 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2366 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2367 {"NET-API-CREATEUSER", torture_createuser, 0},
2368 {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
2369 {"NET-API-LISTSHARES", torture_listshares, 0},
2370 {"NET-API-DELSHARE", torture_delshare, 0},
2376 /****************************************************************************
2377 run a specified test or "ALL"
2378 ****************************************************************************/
2379 static BOOL run_test(const char *name)
2383 BOOL matched = False;
2385 if (strequal(name,"ALL")) {
2386 for (i=0;torture_ops[i].name;i++) {
2387 if (!run_test(torture_ops[i].name)) {
2394 for (i=0;torture_ops[i].name;i++) {
2395 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
2399 printf("Running %s\n", torture_ops[i].name);
2400 if (torture_ops[i].multi_fn) {
2401 BOOL result = False;
2402 t = torture_create_procs(torture_ops[i].multi_fn,
2406 printf("TEST %s FAILED!\n", torture_ops[i].name);
2410 struct timeval tv = timeval_current();
2411 if (!torture_ops[i].fn()) {
2413 printf("TEST %s FAILED!\n", torture_ops[i].name);
2415 t = timeval_elapsed(&tv);
2417 printf("%s took %g secs\n\n", torture_ops[i].name, t);
2422 printf("Unknown torture operation '%s'\n", name);
2429 static void parse_dns(const char *dns)
2431 char *userdn, *basedn, *secret;
2434 /* retrievieng the userdn */
2435 p = strchr_m(dns, '#');
2437 lp_set_cmdline("torture:ldap_userdn", "");
2438 lp_set_cmdline("torture:ldap_basedn", "");
2439 lp_set_cmdline("torture:ldap_secret", "");
2442 userdn = strndup(dns, p - dns);
2443 lp_set_cmdline("torture:ldap_userdn", userdn);
2445 /* retrieve the basedn */
2447 p = strchr_m(d, '#');
2449 lp_set_cmdline("torture:ldap_basedn", "");
2450 lp_set_cmdline("torture:ldap_secret", "");
2453 basedn = strndup(d, p - d);
2454 lp_set_cmdline("torture:ldap_basedn", basedn);
2456 /* retrieve the secret */
2459 lp_set_cmdline("torture:ldap_secret", "");
2463 lp_set_cmdline("torture:ldap_secret", secret);
2465 printf ("%s - %s - %s\n", userdn, basedn, secret);
2469 static void usage(poptContext pc)
2474 poptPrintUsage(pc, stdout, 0);
2477 printf("The binding format is:\n\n");
2479 printf(" TRANSPORT:host[flags]\n\n");
2481 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2483 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2484 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2485 printf(" string.\n\n");
2487 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2488 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2489 printf(" will be auto-determined.\n\n");
2491 printf(" other recognised flags are:\n\n");
2493 printf(" sign : enable ntlmssp signing\n");
2494 printf(" seal : enable ntlmssp sealing\n");
2495 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2496 printf(" validate: enable the NDR validator\n");
2497 printf(" print: enable debugging of the packets\n");
2498 printf(" bigendian: use bigendian RPC\n");
2499 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2501 printf(" For example, these all connect to the samr pipe:\n\n");
2503 printf(" ncacn_np:myserver\n");
2504 printf(" ncacn_np:myserver[samr]\n");
2505 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2506 printf(" ncacn_np:myserver[/pipe/samr]\n");
2507 printf(" ncacn_np:myserver[samr,sign,print]\n");
2508 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2509 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2510 printf(" ncacn_np:\n");
2511 printf(" ncacn_np:[/pipe/samr]\n\n");
2513 printf(" ncacn_ip_tcp:myserver\n");
2514 printf(" ncacn_ip_tcp:myserver[1024]\n");
2515 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2517 printf("The unc format is:\n\n");
2519 printf(" //server/share\n\n");
2521 printf("tests are:");
2522 for (i=0;torture_ops[i].name;i++) {
2523 if ((i%perline)==0) {
2526 printf("%s ", torture_ops[i].name);
2530 printf("default test is ALL\n");
2535 static BOOL is_binding_string(const char *binding_string)
2537 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2538 struct dcerpc_binding *binding_struct;
2541 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2543 talloc_free(mem_ctx);
2544 return NT_STATUS_IS_OK(status);
2547 static void max_runtime_handler(int sig)
2549 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2553 /****************************************************************************
2555 ****************************************************************************/
2556 int main(int argc,char *argv[])
2560 BOOL correct = True;
2565 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,
2566 OPT_DANGEROUS,OPT_SMB_PORTS};
2568 struct poptOption long_options[] = {
2570 {"smb-ports", 'p', POPT_ARG_STRING, NULL, OPT_SMB_PORTS, "SMB ports", NULL},
2571 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2572 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2573 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2574 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2575 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2576 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2577 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2578 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2579 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2580 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2581 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2582 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2583 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2584 "set maximum time for smbtorture to live", "seconds"},
2586 POPT_COMMON_CONNECTION
2587 POPT_COMMON_CREDENTIALS
2592 #ifdef HAVE_SETBUFFER
2593 setbuffer(stdout, NULL, 0);
2596 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2597 POPT_CONTEXT_KEEP_FIRST);
2599 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2601 while((opt = poptGetNextOpt(pc)) != -1) {
2604 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2607 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2610 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2613 parse_dns(poptGetOptArg(pc));
2616 lp_set_cmdline("torture:dangerous", "Yes");
2619 lp_set_cmdline("smb ports", poptGetOptArg(pc));
2622 d_printf("Invalid option %s: %s\n",
2623 poptBadOption(pc, 0), poptStrerror(opt));
2630 /* this will only work if nobody else uses alarm(),
2631 which means it won't work for some tests, but we
2632 can't use the event context method we use for smbd
2633 as so many tests create their own event
2634 context. This will at least catch most cases. */
2635 signal(SIGALRM, max_runtime_handler);
2643 dcerpc_table_init();
2645 if (torture_seed == 0) {
2646 torture_seed = time(NULL);
2648 printf("Using seed %d\n", torture_seed);
2649 srandom(torture_seed);
2651 argv_new = discard_const_p(char *, poptGetArgs(pc));
2654 for (i=0; i<argc; i++) {
2655 if (argv_new[i] == NULL) {
2666 for(p = argv_new[1]; *p; p++) {
2671 /* see if its a RPC transport specifier */
2672 if (is_binding_string(argv_new[1])) {
2673 lp_set_cmdline("torture:binding", argv_new[1]);
2675 char *binding = NULL;
2676 const char *host = NULL, *share = NULL;
2678 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
2679 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
2683 lp_set_cmdline("torture:host", host);
2684 lp_set_cmdline("torture:share", share);
2685 asprintf(&binding, "ncacn_np:%s", host);
2686 lp_set_cmdline("torture:binding", binding);
2689 if (argc_new == 0) {
2690 printf("You must specify a test to run, or 'ALL'\n");
2692 for (i=2;i<argc_new;i++) {
2693 if (!run_test(argv_new[i])) {