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"
32 #include "torture/basic/proto.h"
33 #include "torture/raw/proto.h"
34 #include "torture/smb2/proto.h"
35 #include "torture/rpc/proto.h"
36 #include "torture/rap/proto.h"
37 #include "torture/auth/proto.h"
38 #include "torture/local/proto.h"
39 #include "torture/nbench/proto.h"
40 #include "torture/ldap/proto.h"
41 #include "torture/com/proto.h"
42 #include "torture/nbt/proto.h"
43 #include "torture/libnet/proto.h"
46 int torture_numops=10;
47 int torture_entries=1000;
48 int torture_failures=1;
50 static int procnum; /* records process count number when forking */
51 static struct smbcli_state *current_cli;
52 static BOOL use_oplocks;
53 static BOOL use_level_II_oplocks;
55 BOOL torture_showall = False;
57 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
59 static struct smbcli_state *open_nbt_connection(void)
61 struct nbt_name called, calling;
62 struct smbcli_state *cli;
63 const char *host = lp_parm_string(-1, "torture", "host");
65 make_nbt_name_client(&calling, lp_netbios_name());
67 nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
69 cli = smbcli_state_init(NULL);
71 printf("Failed initialize smbcli_struct to connect with %s\n", host);
75 if (!smbcli_socket_connect(cli, host)) {
76 printf("Failed to connect with %s\n", host);
80 if (!smbcli_transport_establish(cli, &calling, &called)) {
81 printf("%s rejected the session\n",host);
92 BOOL torture_open_connection_share(TALLOC_CTX *mem_ctx,
93 struct smbcli_state **c,
95 const char *sharename,
96 struct event_context *ev)
100 status = smbcli_full_connection(mem_ctx, c, hostname,
102 cmdline_credentials, ev);
103 if (!NT_STATUS_IS_OK(status)) {
104 printf("Failed to open connection - %s\n", nt_errstr(status));
108 (*c)->transport->options.use_oplocks = use_oplocks;
109 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
114 BOOL torture_open_connection(struct smbcli_state **c)
116 const char *host = lp_parm_string(-1, "torture", "host");
117 const char *share = lp_parm_string(-1, "torture", "share");
119 return torture_open_connection_share(NULL, c, host, share, NULL);
124 BOOL torture_close_connection(struct smbcli_state *c)
128 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
129 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
136 /* open a rpc connection to the chosen binding string */
137 NTSTATUS torture_rpc_connection(TALLOC_CTX *parent_ctx,
138 struct dcerpc_pipe **p,
139 const struct dcerpc_interface_table *table)
142 const char *binding = lp_parm_string(-1, "torture", "binding");
145 printf("You must specify a ncacn binding string\n");
146 return NT_STATUS_INVALID_PARAMETER;
149 status = dcerpc_pipe_connect(parent_ctx,
151 cmdline_credentials, NULL);
156 /* open a rpc connection to a specific transport */
157 NTSTATUS torture_rpc_connection_transport(TALLOC_CTX *parent_ctx,
158 struct dcerpc_pipe **p,
159 const struct dcerpc_interface_table *table,
160 enum dcerpc_transport_t transport)
163 const char *binding = lp_parm_string(-1, "torture", "binding");
164 struct dcerpc_binding *b;
165 TALLOC_CTX *mem_ctx = talloc_named(parent_ctx, 0, "torture_rpc_connection_smb");
168 printf("You must specify a ncacn binding string\n");
169 talloc_free(mem_ctx);
170 return NT_STATUS_INVALID_PARAMETER;
173 status = dcerpc_parse_binding(mem_ctx, binding, &b);
174 if (!NT_STATUS_IS_OK(status)) {
175 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
176 talloc_free(mem_ctx);
180 b->transport = transport;
182 status = dcerpc_pipe_connect_b(mem_ctx, p, b, table,
183 cmdline_credentials, NULL);
185 if (NT_STATUS_IS_OK(status)) {
186 *p = talloc_reference(parent_ctx, *p);
190 talloc_free(mem_ctx);
194 /* check if the server produced the expected error code */
195 BOOL check_error(const char *location, struct smbcli_state *c,
196 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
200 status = smbcli_nt_error(c->tree);
201 if (NT_STATUS_IS_DOS(status)) {
203 class = NT_STATUS_DOS_CLASS(status);
204 num = NT_STATUS_DOS_CODE(status);
205 if (eclass != class || ecode != num) {
206 printf("unexpected error code %s\n", nt_errstr(status));
207 printf(" expected %s or %s (at %s)\n",
208 nt_errstr(NT_STATUS_DOS(eclass, ecode)),
209 nt_errstr(nterr), location);
213 if (!NT_STATUS_EQUAL(nterr, status)) {
214 printf("unexpected error code %s\n", nt_errstr(status));
215 printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
224 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
226 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
227 if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
233 static BOOL rw_torture(struct smbcli_state *c)
235 const char *lockfname = "\\torture.lck";
239 pid_t pid2, pid = getpid();
244 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
247 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
249 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
254 for (i=0;i<torture_numops;i++) {
255 uint_t n = (uint_t)random()%10;
257 printf("%d\r", i); fflush(stdout);
259 asprintf(&fname, "\\torture.%u", n);
261 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
265 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
267 printf("open failed (%s)\n", smbcli_errstr(c->tree));
272 if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
273 printf("write failed (%s)\n", smbcli_errstr(c->tree));
278 if (smbcli_write(c->tree, fnum, 0, buf,
279 sizeof(pid)+(j*sizeof(buf)),
280 sizeof(buf)) != sizeof(buf)) {
281 printf("write failed (%s)\n", smbcli_errstr(c->tree));
288 if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
289 printf("read failed (%s)\n", smbcli_errstr(c->tree));
294 printf("data corruption!\n");
298 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
299 printf("close failed (%s)\n", smbcli_errstr(c->tree));
303 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
304 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
308 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
309 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
315 smbcli_close(c->tree, fnum2);
316 smbcli_unlink(c->tree, lockfname);
323 static BOOL run_torture(struct smbcli_state *cli, int dummy)
327 ret = rw_torture(cli);
329 if (!torture_close_connection(cli)) {
337 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
339 const char *lockfname = "\\torture2.lck";
344 uint8_t buf_rd[131072];
346 ssize_t bytes_read, bytes_written;
348 if (smbcli_deltree(c1->tree, lockfname) == -1) {
349 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
352 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
355 printf("first open read/write of %s failed (%s)\n",
356 lockfname, smbcli_errstr(c1->tree));
359 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
362 printf("second open read-only of %s failed (%s)\n",
363 lockfname, smbcli_errstr(c2->tree));
364 smbcli_close(c1->tree, fnum1);
368 printf("Checking data integrity over %d ops\n", torture_numops);
370 for (i=0;i<torture_numops;i++)
372 size_t buf_size = ((uint_t)random()%(sizeof(buf)-1))+ 1;
374 printf("%d\r", i); fflush(stdout);
377 generate_random_buffer(buf, buf_size);
379 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
380 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
381 printf("wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
386 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
387 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
388 printf("read %d, expected %d\n", (int)bytes_read, (int)buf_size);
393 if (memcmp(buf_rd, buf, buf_size) != 0)
395 printf("read/write compare failed\n");
401 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
402 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
405 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
406 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
410 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
411 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
418 #define BOOLSTR(b) ((b) ? "Yes" : "No")
420 static BOOL run_readwritetest(void)
422 struct smbcli_state *cli1, *cli2;
423 BOOL test1, test2 = True;
425 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
429 printf("starting readwritetest\n");
431 test1 = rw_torture2(cli1, cli2);
432 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
435 test2 = rw_torture2(cli1, cli1);
436 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
439 if (!torture_close_connection(cli1)) {
443 if (!torture_close_connection(cli2)) {
447 return (test1 && test2);
451 this checks to see if a secondary tconx can use open files from an
454 static BOOL run_tcon_test(void)
456 struct smbcli_state *cli;
457 const char *fname = "\\tcontest.tmp";
459 uint16_t cnum1, cnum2, cnum3;
460 uint16_t vuid1, vuid2;
463 struct smbcli_tree *tree1;
464 const char *host = lp_parm_string(-1, "torture", "host");
465 const char *share = lp_parm_string(-1, "torture", "share");
466 const char *password = lp_parm_string(-1, "torture", "password");
468 if (!torture_open_connection(&cli)) {
472 printf("starting tcontest\n");
474 if (smbcli_deltree(cli->tree, fname) == -1) {
475 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
478 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
480 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
484 cnum1 = cli->tree->tid;
485 vuid1 = cli->session->vuid;
487 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
488 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
489 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
493 tree1 = cli->tree; /* save old tree connection */
494 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
495 printf("%s refused 2nd tree connect (%s)\n", host,
496 smbcli_errstr(cli->tree));
501 cnum2 = cli->tree->tid;
502 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
503 vuid2 = cli->session->vuid + 1;
505 /* try a write with the wrong tid */
506 cli->tree->tid = cnum2;
508 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
509 printf("* server allows write with wrong TID\n");
512 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
516 /* try a write with an invalid tid */
517 cli->tree->tid = cnum3;
519 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
520 printf("* server allows write with invalid TID\n");
523 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
526 /* try a write with an invalid vuid */
527 cli->session->vuid = vuid2;
528 cli->tree->tid = cnum1;
530 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
531 printf("* server allows write with invalid VUID\n");
534 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
537 cli->session->vuid = vuid1;
538 cli->tree->tid = cnum1;
540 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
541 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
545 cli->tree->tid = cnum2;
547 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
548 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
552 cli->tree = tree1; /* restore initial tree */
553 cli->tree->tid = cnum1;
555 smbcli_unlink(tree1, fname);
557 if (!torture_close_connection(cli)) {
566 static BOOL tcon_devtest(struct smbcli_state *cli,
567 const char *myshare, const char *devtype,
568 NTSTATUS expected_error)
572 const char *password = lp_parm_string(-1, "torture", "password");
574 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
577 printf("Trying share %s with devtype %s\n", myshare, devtype);
579 if (NT_STATUS_IS_OK(expected_error)) {
583 printf("tconX to share %s with type %s "
584 "should have succeeded but failed\n",
591 printf("tconx to share %s with type %s "
592 "should have failed but succeeded\n",
596 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
600 printf("Returned unexpected error\n");
609 checks for correct tconX support
611 static BOOL run_tcon_devtype_test(void)
613 struct smbcli_state *cli1 = NULL;
616 const char *host = lp_parm_string(-1, "torture", "host");
617 const char *share = lp_parm_string(-1, "torture", "share");
619 status = smbcli_full_connection(NULL,
622 cmdline_credentials, NULL);
624 if (!NT_STATUS_IS_OK(status)) {
625 printf("could not open connection\n");
629 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
632 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
635 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
638 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
641 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
644 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
647 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
650 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
653 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
656 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
662 printf("Passed tcondevtest\n");
669 test whether fnums and tids open on one VC are available on another (a major
672 static BOOL run_fdpasstest(void)
674 struct smbcli_state *cli1, *cli2;
675 const char *fname = "\\fdpass.tst";
679 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
683 printf("starting fdpasstest\n");
685 smbcli_unlink(cli1->tree, fname);
687 printf("Opening a file on connection 1\n");
689 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
691 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
695 printf("writing to file on connection 1\n");
697 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
698 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
702 oldtid = cli2->tree->tid;
703 cli2->session->vuid = cli1->session->vuid;
704 cli2->tree->tid = cli1->tree->tid;
705 cli2->session->pid = cli1->session->pid;
707 printf("reading from file on connection 2\n");
709 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
710 printf("read succeeded! nasty security hole [%s]\n",
715 smbcli_close(cli1->tree, fnum1);
716 smbcli_unlink(cli1->tree, fname);
718 cli2->tree->tid = oldtid;
720 torture_close_connection(cli1);
721 torture_close_connection(cli2);
723 printf("finished fdpasstest\n");
729 test the timing of deferred open requests
731 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
733 const char *fname = "\\defer_open_test.dat";
739 printf("failed to connect\n");
743 printf("Testing deferred open requests.\n");
750 tv = timeval_current();
751 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
753 FILE_ATTRIBUTE_NORMAL,
754 NTCREATEX_SHARE_ACCESS_NONE,
755 NTCREATEX_DISP_OPEN_IF, 0, 0);
759 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
760 double e = timeval_elapsed(&tv);
761 if (e < 0.5 || e > 1.5) {
762 fprintf(stderr,"Timing incorrect %.2f violation\n",
766 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
769 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
773 printf("pid %u open %d\n", getpid(), i);
777 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
778 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
784 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
785 /* All until the last unlink will fail with sharing violation. */
786 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
787 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
792 printf("deferred test finished\n");
793 if (!torture_close_connection(cli)) {
800 test how many open files this server supports on the one socket
802 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
804 #define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
806 int fnums[0x11000], i;
807 int retries=4, maxfid;
811 printf("failed to connect\n");
815 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
816 printf("Failed to deltree \\maxfid - %s\n",
817 smbcli_errstr(cli->tree));
820 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
821 printf("Failed to mkdir \\maxfid, error=%s\n",
822 smbcli_errstr(cli->tree));
826 printf("Testing maximum number of open files\n");
828 for (i=0; i<0x11000; i++) {
830 asprintf(&fname, "\\maxfid\\fid%d", i/1000);
831 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
832 printf("Failed to mkdir %s, error=%s\n",
833 fname, smbcli_errstr(cli->tree));
838 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
839 if ((fnums[i] = smbcli_open(cli->tree, fname,
840 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
842 printf("open of %s failed (%s)\n",
843 fname, smbcli_errstr(cli->tree));
844 printf("maximum fnum is %d\n", i);
855 printf("cleaning up\n");
856 for (i=0;i<maxfid/2;i++) {
857 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
858 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
859 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
861 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
862 printf("unlink of %s failed (%s)\n",
863 fname, smbcli_errstr(cli->tree));
868 asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
869 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
870 printf("Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
872 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
873 printf("unlink of %s failed (%s)\n",
874 fname, smbcli_errstr(cli->tree));
879 printf("%6d %6d\r", i, maxfid-i);
883 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
884 printf("Failed to deltree \\maxfid - %s\n",
885 smbcli_errstr(cli->tree));
889 printf("maxfid test finished\n");
890 if (!torture_close_connection(cli)) {
894 #undef MAXFID_TEMPLATE
897 /* send smb negprot commands, not reading the response */
898 static BOOL run_negprot_nowait(void)
901 struct smbcli_state *cli, *cli2;
904 printf("starting negprot nowait test\n");
906 cli = open_nbt_connection();
911 printf("Filling send buffer\n");
913 for (i=0;i<1000;i++) {
914 struct smbcli_request *req;
915 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
916 smbcli_transport_process(cli->transport);
917 if (req->state == SMBCLI_REQUEST_ERROR) {
918 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
919 torture_close_connection(cli);
924 printf("Opening secondary connection\n");
925 if (!torture_open_connection(&cli2)) {
929 if (!torture_close_connection(cli)) {
933 if (!torture_close_connection(cli2)) {
937 printf("finished negprot nowait test\n");
944 This checks how the getatr calls works
946 static BOOL run_attrtest(void)
948 struct smbcli_state *cli;
951 const char *fname = "\\attrib123456789.tst";
954 printf("starting attrib test\n");
956 if (!torture_open_connection(&cli)) {
960 smbcli_unlink(cli->tree, fname);
961 fnum = smbcli_open(cli->tree, fname,
962 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
963 smbcli_close(cli->tree, fnum);
965 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
966 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
970 printf("New file time is %s", ctime(&t));
972 if (abs(t - time(NULL)) > 60*60*24*10) {
973 printf("ERROR: SMBgetatr bug. time is %s",
979 t2 = t-60*60*24; /* 1 day ago */
981 printf("Setting file time to %s", ctime(&t2));
983 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
984 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
988 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
989 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
993 printf("Retrieved file time as %s", ctime(&t));
996 printf("ERROR: getatr/setatr bug. times are\n%s",
998 printf("%s", ctime(&t2));
1002 smbcli_unlink(cli->tree, fname);
1004 if (!torture_close_connection(cli)) {
1008 printf("attrib test finished\n");
1015 This checks a couple of trans2 calls
1017 static BOOL run_trans2test(void)
1019 struct smbcli_state *cli;
1022 time_t c_time, a_time, m_time, w_time, m_time2;
1023 const char *fname = "\\trans2.tst";
1024 const char *dname = "\\trans2";
1025 const char *fname2 = "\\trans2\\trans2.tst";
1027 BOOL correct = True;
1029 printf("starting trans2 test\n");
1031 if (!torture_open_connection(&cli)) {
1035 smbcli_unlink(cli->tree, fname);
1037 printf("Testing qfileinfo\n");
1039 fnum = smbcli_open(cli->tree, fname,
1040 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1041 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
1043 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
1047 printf("Testing NAME_INFO\n");
1049 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
1050 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
1054 if (!pname || strcmp(pname, fname)) {
1055 printf("qfilename gave different name? [%s] [%s]\n",
1060 smbcli_close(cli->tree, fnum);
1061 smbcli_unlink(cli->tree, fname);
1063 fnum = smbcli_open(cli->tree, fname,
1064 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1066 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1069 smbcli_close(cli->tree, fnum);
1071 printf("Checking for sticky create times\n");
1073 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1074 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
1077 if (c_time != m_time) {
1078 printf("create time=%s", ctime(&c_time));
1079 printf("modify time=%s", ctime(&m_time));
1080 printf("This system appears to have sticky create times\n");
1082 if (a_time % (60*60) == 0) {
1083 printf("access time=%s", ctime(&a_time));
1084 printf("This system appears to set a midnight access time\n");
1088 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1089 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1095 smbcli_unlink(cli->tree, fname);
1096 fnum = smbcli_open(cli->tree, fname,
1097 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1098 smbcli_close(cli->tree, fnum);
1099 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1100 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1103 if (w_time < 60*60*24*2) {
1104 printf("write time=%s", ctime(&w_time));
1105 printf("This system appears to set a initial 0 write time\n");
1110 smbcli_unlink(cli->tree, fname);
1113 /* check if the server updates the directory modification time
1114 when creating a new file */
1115 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1116 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
1120 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1121 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1125 fnum = smbcli_open(cli->tree, fname2,
1126 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1127 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
1128 smbcli_close(cli->tree, fnum);
1129 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
1130 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1133 if (m_time2 == m_time) {
1134 printf("This system does not update directory modification times\n");
1138 smbcli_unlink(cli->tree, fname2);
1139 smbcli_rmdir(cli->tree, dname);
1141 if (!torture_close_connection(cli)) {
1145 printf("trans2 test finished\n");
1152 /* FIRST_DESIRED_ACCESS 0xf019f */
1153 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1154 SEC_FILE_READ_EA| /* 0xf */ \
1155 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1156 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1157 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1158 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1159 /* SECOND_DESIRED_ACCESS 0xe0080 */
1160 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1161 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1162 SEC_STD_WRITE_OWNER /* 0xe0000 */
1165 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1166 READ_CONTROL|WRITE_DAC|\
1167 SEC_FILE_READ_DATA|\
1172 Test ntcreate calls made by xcopy
1174 static BOOL run_xcopy(void)
1176 struct smbcli_state *cli1;
1177 const char *fname = "\\test.txt";
1178 BOOL correct = True;
1181 printf("starting xcopy test\n");
1183 if (!torture_open_connection(&cli1)) {
1187 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1188 FIRST_DESIRED_ACCESS,
1189 FILE_ATTRIBUTE_ARCHIVE,
1190 NTCREATEX_SHARE_ACCESS_NONE,
1191 NTCREATEX_DISP_OVERWRITE_IF,
1195 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
1199 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1200 SECOND_DESIRED_ACCESS, 0,
1201 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1204 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
1208 if (!torture_close_connection(cli1)) {
1217 see how many RPC pipes we can open at once
1219 static BOOL run_pipe_number(void)
1221 struct smbcli_state *cli1;
1222 const char *pipe_name = "\\WKSSVC";
1226 printf("starting pipenumber test\n");
1227 if (!torture_open_connection(&cli1)) {
1232 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1233 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1236 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
1240 printf("%d\r", num_pipes);
1244 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
1245 torture_close_connection(cli1);
1253 open N connections to the server and just hold them open
1254 used for testing performance when there are N idle users
1257 static BOOL torture_holdcon(void)
1260 struct smbcli_state **cli;
1263 printf("Opening %d connections\n", torture_numops);
1265 cli = malloc_array_p(struct smbcli_state *, torture_numops);
1267 for (i=0;i<torture_numops;i++) {
1268 if (!torture_open_connection(&cli[i])) {
1271 printf("opened %d connections\r", i);
1275 printf("\nStarting pings\n");
1278 for (i=0;i<torture_numops;i++) {
1281 status = smbcli_chkpath(cli[i]->tree, "\\");
1282 if (!NT_STATUS_IS_OK(status)) {
1283 printf("Connection %d is dead\n", i);
1291 if (num_dead == torture_numops) {
1292 printf("All connections dead - finishing\n");
1304 Try with a wrong vuid and check error message.
1307 static BOOL run_vuidtest(void)
1309 struct smbcli_state *cli;
1310 const char *fname = "\\vuid.tst";
1313 time_t c_time, a_time, m_time;
1314 BOOL correct = True;
1319 printf("starting vuid test\n");
1321 if (!torture_open_connection(&cli)) {
1325 smbcli_unlink(cli->tree, fname);
1327 fnum = smbcli_open(cli->tree, fname,
1328 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1330 orig_vuid = cli->session->vuid;
1332 cli->session->vuid += 1234;
1334 printf("Testing qfileinfo with wrong vuid\n");
1336 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
1337 &size, &c_time, &a_time,
1338 &m_time, NULL, NULL))) {
1339 printf("ERROR: qfileinfo passed with wrong vuid\n");
1343 if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1344 NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
1345 !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1346 NT_STATUS_INVALID_HANDLE)) {
1347 printf("ERROR: qfileinfo should have returned DOS error "
1348 "ERRSRV:ERRbaduid\n but returned %s\n",
1349 smbcli_errstr(cli->tree));
1353 cli->session->vuid -= 1234;
1355 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1356 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
1360 smbcli_unlink(cli->tree, fname);
1362 if (!torture_close_connection(cli)) {
1366 printf("vuid test finished\n");
1372 Test open mode returns on read-only files.
1374 static BOOL run_opentest(void)
1376 static struct smbcli_state *cli1;
1377 static struct smbcli_state *cli2;
1378 const char *fname = "\\readonly.file";
1379 char *control_char_fname;
1383 BOOL correct = True;
1388 printf("starting open test\n");
1390 if (!torture_open_connection(&cli1)) {
1394 asprintf(&control_char_fname, "\\readonly.afile");
1395 for (i = 1; i <= 0x1f; i++) {
1396 control_char_fname[10] = i;
1397 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
1398 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1400 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
1401 NT_STATUS_OBJECT_NAME_INVALID)) {
1402 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
1403 smbcli_errstr(cli1->tree), i);
1408 smbcli_close(cli1->tree, fnum1);
1410 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
1411 smbcli_unlink(cli1->tree, control_char_fname);
1413 free(control_char_fname);
1416 printf("Create file with control char names passed.\n");
1418 smbcli_setatr(cli1->tree, fname, 0, 0);
1419 smbcli_unlink(cli1->tree, fname);
1421 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1423 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1427 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1428 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1432 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
1433 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
1434 CHECK_MAX_FAILURES(error_test1);
1438 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1440 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1441 CHECK_MAX_FAILURES(error_test1);
1445 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
1446 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1448 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
1449 NT_STATUS_ACCESS_DENIED)) {
1450 printf("correct error code ERRDOS/ERRnoaccess returned\n");
1453 printf("finished open test 1\n");
1455 smbcli_close(cli1->tree, fnum1);
1457 /* Now try not readonly and ensure ERRbadshare is returned. */
1459 smbcli_setatr(cli1->tree, fname, 0, 0);
1461 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1463 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1467 /* This will fail - but the error should be ERRshare. */
1468 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1470 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
1471 NT_STATUS_SHARING_VIOLATION)) {
1472 printf("correct error code ERRDOS/ERRbadshare returned\n");
1475 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1476 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1480 smbcli_unlink(cli1->tree, fname);
1482 printf("finished open test 2\n");
1484 /* Test truncate open disposition on file opened for read. */
1486 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1488 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1492 /* write 20 bytes. */
1494 memset(buf, '\0', 20);
1496 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1497 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1501 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1502 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1506 /* Ensure size == 20. */
1507 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1508 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1509 CHECK_MAX_FAILURES(error_test3);
1514 printf("(3) file size != 20\n");
1515 CHECK_MAX_FAILURES(error_test3);
1519 /* Now test if we can truncate a file opened for readonly. */
1521 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
1523 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1524 CHECK_MAX_FAILURES(error_test3);
1528 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1529 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1533 /* Ensure size == 0. */
1534 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1535 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1536 CHECK_MAX_FAILURES(error_test3);
1541 printf("(3) file size != 0\n");
1542 CHECK_MAX_FAILURES(error_test3);
1545 printf("finished open test 3\n");
1547 smbcli_unlink(cli1->tree, fname);
1550 printf("testing ctemp\n");
1551 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
1553 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1554 CHECK_MAX_FAILURES(error_test4);
1557 printf("ctemp gave path %s\n", tmp_path);
1558 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1559 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1561 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1562 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1565 /* Test the non-io opens... */
1567 if (!torture_open_connection(&cli2)) {
1571 smbcli_setatr(cli2->tree, fname, 0, 0);
1572 smbcli_unlink(cli2->tree, fname);
1574 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1576 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1577 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1580 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1581 CHECK_MAX_FAILURES(error_test10);
1585 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1586 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1588 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1589 CHECK_MAX_FAILURES(error_test10);
1593 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1594 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1597 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1598 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1602 printf("non-io open test #1 passed.\n");
1604 smbcli_unlink(cli1->tree, fname);
1606 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1608 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1609 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1612 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1613 CHECK_MAX_FAILURES(error_test20);
1617 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1618 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1621 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1622 CHECK_MAX_FAILURES(error_test20);
1626 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1627 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1630 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1631 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1635 printf("non-io open test #2 passed.\n");
1637 smbcli_unlink(cli1->tree, fname);
1639 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1641 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1642 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1645 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1646 CHECK_MAX_FAILURES(error_test30);
1650 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1651 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1654 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1655 CHECK_MAX_FAILURES(error_test30);
1659 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1660 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1663 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1664 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1668 printf("non-io open test #3 passed.\n");
1670 smbcli_unlink(cli1->tree, fname);
1672 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1674 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1675 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1678 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1679 CHECK_MAX_FAILURES(error_test40);
1683 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1684 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1687 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1688 CHECK_MAX_FAILURES(error_test40);
1692 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1694 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1695 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1699 printf("non-io open test #4 passed.\n");
1701 smbcli_unlink(cli1->tree, fname);
1703 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1705 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1706 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1709 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1710 CHECK_MAX_FAILURES(error_test50);
1714 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1715 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1718 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1719 CHECK_MAX_FAILURES(error_test50);
1723 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1724 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1728 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1729 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1733 printf("non-io open test #5 passed.\n");
1735 printf("TEST #6 testing 1 non-io open, one io open\n");
1737 smbcli_unlink(cli1->tree, fname);
1739 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1740 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1743 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1744 CHECK_MAX_FAILURES(error_test60);
1748 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1749 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1752 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1753 CHECK_MAX_FAILURES(error_test60);
1757 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1758 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1762 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1763 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1767 printf("non-io open test #6 passed.\n");
1769 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
1771 smbcli_unlink(cli1->tree, fname);
1773 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1774 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1777 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1778 CHECK_MAX_FAILURES(error_test70);
1782 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1783 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1786 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1787 CHECK_MAX_FAILURES(error_test70);
1791 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1793 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1794 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1798 printf("non-io open test #7 passed.\n");
1802 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1804 smbcli_unlink(cli1->tree, fname);
1806 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1808 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1812 /* write 20 bytes. */
1814 memset(buf, '\0', 20);
1816 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1817 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1821 /* Ensure size == 20. */
1822 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1823 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1824 CHECK_MAX_FAILURES(error_test80);
1829 printf("(8) file size != 20\n");
1830 CHECK_MAX_FAILURES(error_test80);
1834 /* Get an exclusive lock on the open file. */
1835 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1836 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1837 CHECK_MAX_FAILURES(error_test80);
1841 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1843 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1847 /* Ensure size == 0. */
1848 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1849 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1850 CHECK_MAX_FAILURES(error_test80);
1855 printf("(8) file size != 0\n");
1856 CHECK_MAX_FAILURES(error_test80);
1860 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1861 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1865 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1866 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1872 printf("open test #8 passed.\n");
1874 smbcli_unlink(cli1->tree, fname);
1876 if (!torture_close_connection(cli1)) {
1879 if (!torture_close_connection(cli2)) {
1888 sees what IOCTLs are supported
1890 BOOL torture_ioctl_test(void)
1892 struct smbcli_state *cli;
1893 uint16_t device, function;
1895 const char *fname = "\\ioctl.dat";
1897 union smb_ioctl parms;
1898 TALLOC_CTX *mem_ctx;
1900 if (!torture_open_connection(&cli)) {
1904 mem_ctx = talloc_init("ioctl_test");
1906 printf("starting ioctl test\n");
1908 smbcli_unlink(cli->tree, fname);
1910 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1912 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1916 parms.ioctl.level = RAW_IOCTL_IOCTL;
1917 parms.ioctl.in.fnum = fnum;
1918 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
1919 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1920 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
1922 for (device=0;device<0x100;device++) {
1923 printf("testing device=0x%x\n", device);
1924 for (function=0;function<0x100;function++) {
1925 parms.ioctl.in.request = (device << 16) | function;
1926 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1928 if (NT_STATUS_IS_OK(status)) {
1929 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
1930 device, function, (int)parms.ioctl.out.blob.length);
1935 if (!torture_close_connection(cli)) {
1944 tries variants of chkpath
1946 BOOL torture_chkpath_test(void)
1948 struct smbcli_state *cli;
1952 if (!torture_open_connection(&cli)) {
1956 printf("starting chkpath test\n");
1958 printf("Testing valid and invalid paths\n");
1960 /* cleanup from an old run */
1961 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1962 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1963 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1965 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1966 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1970 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1971 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1975 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1977 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
1980 smbcli_close(cli->tree, fnum);
1982 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1983 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1987 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1988 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1992 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1993 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1994 NT_STATUS_NOT_A_DIRECTORY);
1996 printf("* chkpath on a file should fail\n");
2000 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
2001 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2002 NT_STATUS_OBJECT_NAME_NOT_FOUND);
2004 printf("* chkpath on a non existent file should fail\n");
2008 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
2009 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2010 NT_STATUS_OBJECT_PATH_NOT_FOUND);
2012 printf("* chkpath on a non existent component should fail\n");
2016 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
2017 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
2018 smbcli_rmdir(cli->tree, "\\chkpath.dir");
2020 if (!torture_close_connection(cli)) {
2028 static void sigcont(int sig)
2032 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
2035 volatile pid_t *child_status;
2036 volatile BOOL *child_status_out;
2039 double start_time_limit = 10 + (torture_nprocs * 1.5);
2040 char **unc_list = NULL;
2042 int num_unc_names = 0;
2049 signal(SIGCONT, sigcont);
2051 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
2052 if (!child_status) {
2053 printf("Failed to setup shared memory\n");
2057 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
2058 if (!child_status_out) {
2059 printf("Failed to setup result status shared memory\n");
2063 p = lp_parm_string(-1, "torture", "unclist");
2065 unc_list = file_lines_load(p, &num_unc_names, NULL);
2066 if (!unc_list || num_unc_names <= 0) {
2067 printf("Failed to load unc names list from '%s'\n", p);
2072 for (i = 0; i < torture_nprocs; i++) {
2073 child_status[i] = 0;
2074 child_status_out[i] = True;
2077 tv = timeval_current();
2079 for (i=0;i<torture_nprocs;i++) {
2083 const char *hostname=NULL, *sharename;
2085 pid_t mypid = getpid();
2086 srandom(((int)mypid) ^ ((int)time(NULL)));
2088 asprintf(&myname, "CLIENT%d", i);
2089 lp_set_cmdline("netbios name", myname);
2094 if (!smbcli_parse_unc(unc_list[i % num_unc_names],
2095 NULL, &hostname, &sharename)) {
2096 printf("Failed to parse UNC name %s\n",
2097 unc_list[i % num_unc_names]);
2104 if (torture_open_connection_share(NULL,
2111 } else if (torture_open_connection(¤t_cli)) {
2115 printf("pid %d failed to start\n", (int)getpid());
2121 child_status[i] = getpid();
2125 if (child_status[i]) {
2126 printf("Child %d failed to start!\n", i);
2127 child_status_out[i] = 1;
2131 child_status_out[i] = fn(current_cli, i);
2138 for (i=0;i<torture_nprocs;i++) {
2139 if (child_status[i]) synccount++;
2141 if (synccount == torture_nprocs) break;
2143 } while (timeval_elapsed(&tv) < start_time_limit);
2145 if (synccount != torture_nprocs) {
2146 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
2148 return timeval_elapsed(&tv);
2151 printf("Starting %d clients\n", torture_nprocs);
2153 /* start the client load */
2154 tv = timeval_current();
2155 for (i=0;i<torture_nprocs;i++) {
2156 child_status[i] = 0;
2159 printf("%d clients started\n", torture_nprocs);
2163 for (i=0;i<torture_nprocs;i++) {
2165 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
2166 if (ret == -1 || WEXITSTATUS(status) != 0) {
2173 for (i=0;i<torture_nprocs;i++) {
2174 if (!child_status_out[i]) {
2178 return timeval_elapsed(&tv);
2181 #define FLAG_MULTIPROC 1
2186 BOOL (*multi_fn)(struct smbcli_state *, int );
2189 {"BASE-FDPASS", run_fdpasstest, 0},
2190 {"BASE-LOCK1", torture_locktest1, 0},
2191 {"BASE-LOCK2", torture_locktest2, 0},
2192 {"BASE-LOCK3", torture_locktest3, 0},
2193 {"BASE-LOCK4", torture_locktest4, 0},
2194 {"BASE-LOCK5", torture_locktest5, 0},
2195 {"BASE-LOCK6", torture_locktest6, 0},
2196 {"BASE-LOCK7", torture_locktest7, 0},
2197 {"BASE-UNLINK", torture_unlinktest, 0},
2198 {"BASE-ATTR", run_attrtest, 0},
2199 {"BASE-TRANS2", run_trans2test, 0},
2200 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
2201 {"BASE-DIR1", torture_dirtest1, 0},
2202 {"BASE-DIR2", torture_dirtest2, 0},
2203 {"BASE-DENY1", torture_denytest1, 0},
2204 {"BASE-DENY2", torture_denytest2, 0},
2205 {"BASE-DENY3", torture_denytest3, 0},
2206 {"BASE-DENYDOS", torture_denydos_sharing, 0},
2207 {"BASE-NTDENY1", NULL, torture_ntdenytest1},
2208 {"BASE-NTDENY2", torture_ntdenytest2, 0},
2209 {"BASE-TCON", run_tcon_test, 0},
2210 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
2211 {"BASE-VUID", run_vuidtest, 0},
2212 {"BASE-RW1", run_readwritetest, 0},
2213 {"BASE-OPEN", run_opentest, 0},
2214 {"BASE-DEFER_OPEN", NULL, run_deferopen},
2215 {"BASE-XCOPY", run_xcopy, 0},
2216 {"BASE-RENAME", torture_test_rename, 0},
2217 {"BASE-DELETE", torture_test_delete, 0},
2218 {"BASE-PROPERTIES", torture_test_properties, 0},
2219 {"BASE-MANGLE", torture_mangle, 0},
2220 {"BASE-OPENATTR", torture_openattrtest, 0},
2221 {"BASE-CHARSET", torture_charset, 0},
2222 {"BASE-CHKPATH", torture_chkpath_test, 0},
2223 {"BASE-SECLEAK", torture_sec_leak, 0},
2224 {"BASE-DISCONNECT", torture_disconnect, 0},
2225 {"BASE-DELAYWRITE", torture_delay_write, 0},
2227 /* benchmarking tests */
2228 {"BENCH-HOLDCON", torture_holdcon, 0},
2229 {"BENCH-NBENCH", torture_nbench, 0},
2230 {"BENCH-TORTURE", NULL, run_torture},
2231 {"BENCH-NBT", torture_bench_nbt, 0},
2232 {"BENCH-WINS", torture_bench_wins, 0},
2233 {"BENCH-RPC", torture_bench_rpc, 0},
2234 {"BENCH-CLDAP", torture_bench_cldap, 0},
2237 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
2238 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
2239 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
2240 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
2241 {"RAW-SEARCH", torture_raw_search, 0},
2242 {"RAW-CLOSE", torture_raw_close, 0},
2243 {"RAW-OPEN", torture_raw_open, 0},
2244 {"RAW-MKDIR", torture_raw_mkdir, 0},
2245 {"RAW-OPLOCK", torture_raw_oplock, 0},
2246 {"RAW-NOTIFY", torture_raw_notify, 0},
2247 {"RAW-MUX", torture_raw_mux, 0},
2248 {"RAW-IOCTL", torture_raw_ioctl, 0},
2249 {"RAW-CHKPATH", torture_raw_chkpath, 0},
2250 {"RAW-UNLINK", torture_raw_unlink, 0},
2251 {"RAW-READ", torture_raw_read, 0},
2252 {"RAW-WRITE", torture_raw_write, 0},
2253 {"RAW-LOCK", torture_raw_lock, 0},
2254 {"RAW-CONTEXT", torture_raw_context, 0},
2255 {"RAW-RENAME", torture_raw_rename, 0},
2256 {"RAW-SEEK", torture_raw_seek, 0},
2257 {"RAW-EAS", torture_raw_eas, 0},
2258 {"RAW-EAMAX", torture_max_eas, 0},
2259 {"RAW-STREAMS", torture_raw_streams, 0},
2260 {"RAW-ACLS", torture_raw_acls, 0},
2261 {"RAW-RAP", torture_raw_rap, 0},
2262 {"RAW-COMPOSITE", torture_raw_composite, 0},
2265 {"SMB2-CONNECT", torture_smb2_connect, 0},
2266 {"SMB2-SCAN", torture_smb2_scan, 0},
2267 {"SMB2-SCANGETINFO", torture_smb2_getinfo_scan, 0},
2268 {"SMB2-SCANSETINFO", torture_smb2_setinfo_scan, 0},
2269 {"SMB2-SCANFIND", torture_smb2_find_scan, 0},
2270 {"SMB2-GETINFO", torture_smb2_getinfo, 0},
2271 {"SMB2-SETINFO", torture_smb2_setinfo, 0},
2272 {"SMB2-FIND", torture_smb2_find, 0},
2274 /* protocol scanners */
2275 {"SCAN-TRANS2", torture_trans2_scan, 0},
2276 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2277 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2278 {"SCAN-SMB", torture_smb_scan, 0},
2279 {"SCAN-MAXFID", NULL, run_maxfidtest},
2280 {"SCAN-UTABLE", torture_utable, 0},
2281 {"SCAN-CASETABLE", torture_casetable, 0},
2282 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2283 {"SCAN-IOCTL", torture_ioctl_test, 0},
2284 {"SCAN-RAP", torture_rap_scan, 0},
2287 {"RPC-LSA", torture_rpc_lsa, 0},
2288 {"RPC-LSALOOKUP", torture_rpc_lsa_lookup, 0},
2289 {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
2290 {"RPC-ECHO", torture_rpc_echo, 0},
2291 {"RPC-DFS", torture_rpc_dfs, 0},
2292 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2293 {"RPC-SAMR", torture_rpc_samr, 0},
2294 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2295 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2296 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2297 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2298 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2299 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2300 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2301 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2302 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2303 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2304 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2305 {"RPC-WINREG", torture_rpc_winreg, 0},
2306 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2307 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2308 {"RPC-REMACT", torture_rpc_remact, 0},
2309 {"RPC-MGMT", torture_rpc_mgmt, 0},
2310 {"RPC-SCANNER", torture_rpc_scanner, 0},
2311 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2312 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2313 {"RPC-MULTIBIND", torture_multi_bind, 0},
2314 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2315 {"RPC-CRACKNAMES", torture_rpc_drsuapi_cracknames, 0},
2316 {"RPC-ROT", torture_rpc_rot, 0},
2317 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2318 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2319 {"RPC-JOIN", torture_rpc_join, 0},
2320 {"RPC-DSSYNC", torture_rpc_dssync, 0},
2322 /* local (no server) testers */
2323 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2324 {"LOCAL-ICONV", torture_local_iconv, 0},
2325 {"LOCAL-TALLOC", torture_local_talloc, 0},
2326 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2327 {"LOCAL-IRPC", torture_local_irpc, 0},
2328 {"LOCAL-BINDING", torture_local_binding_string, 0},
2329 {"LOCAL-STRLIST", torture_local_util_strlist, 0},
2330 {"LOCAL-FILE", torture_local_util_file, 0},
2331 {"LOCAL-IDTREE", torture_local_idtree, 0},
2332 {"LOCAL-SOCKET", torture_local_socket, 0},
2333 {"LOCAL-PAC", torture_pac, 0},
2334 {"LOCAL-REGISTRY", torture_registry, 0},
2335 {"LOCAL-RESOLVE", torture_local_resolve, 0},
2336 {"LOCAL-SDDL", torture_local_sddl, 0},
2337 {"LOCAL-NDR", torture_local_ndr, 0},
2339 /* COM (Component Object Model) testers */
2340 {"COM-SIMPLE", torture_com_simple, 0 },
2343 {"LDAP-BASIC", torture_ldap_basic, 0},
2344 {"LDAP-CLDAP", torture_cldap, 0},
2347 {"NBT-REGISTER", torture_nbt_register, 0},
2348 {"NBT-WINS", torture_nbt_wins, 0},
2349 {"NBT-DGRAM", torture_nbt_dgram, 0},
2350 {"NBT-BROWSE", torture_nbt_browse, 0},
2351 {"NBT-WINSREPLICATION-SIMPLE", torture_nbt_winsreplication_simple, 0},
2352 {"NBT-WINSREPLICATION-REPLICA", torture_nbt_winsreplication_replica, 0},
2353 {"NBT-WINSREPLICATION-OWNED", torture_nbt_winsreplication_owned, 0},
2356 {"NET-USERINFO", torture_userinfo, 0},
2357 {"NET-USERADD", torture_useradd, 0},
2358 {"NET-USERDEL", torture_userdel, 0},
2359 {"NET-USERMOD", torture_usermod, 0},
2360 {"NET-DOMOPEN", torture_domainopen, 0},
2361 {"NET-API-LOOKUP", torture_lookup, 0},
2362 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2363 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2364 {"NET-API-CREATEUSER", torture_createuser, 0},
2365 {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
2366 {"NET-API-LISTSHARES", torture_listshares, 0},
2367 {"NET-API-DELSHARE", torture_delshare, 0},
2373 /****************************************************************************
2374 run a specified test or "ALL"
2375 ****************************************************************************/
2376 static BOOL run_test(const char *name)
2380 BOOL matched = False;
2382 if (strequal(name,"ALL")) {
2383 for (i=0;torture_ops[i].name;i++) {
2384 if (!run_test(torture_ops[i].name)) {
2391 for (i=0;torture_ops[i].name;i++) {
2392 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
2396 printf("Running %s\n", torture_ops[i].name);
2397 if (torture_ops[i].multi_fn) {
2398 BOOL result = False;
2399 t = torture_create_procs(torture_ops[i].multi_fn,
2403 printf("TEST %s FAILED!\n", torture_ops[i].name);
2407 struct timeval tv = timeval_current();
2408 if (!torture_ops[i].fn()) {
2410 printf("TEST %s FAILED!\n", torture_ops[i].name);
2412 t = timeval_elapsed(&tv);
2414 printf("%s took %g secs\n\n", torture_ops[i].name, t);
2419 printf("Unknown torture operation '%s'\n", name);
2426 static void parse_dns(const char *dns)
2428 char *userdn, *basedn, *secret;
2431 /* retrievieng the userdn */
2432 p = strchr_m(dns, '#');
2434 lp_set_cmdline("torture:ldap_userdn", "");
2435 lp_set_cmdline("torture:ldap_basedn", "");
2436 lp_set_cmdline("torture:ldap_secret", "");
2439 userdn = strndup(dns, p - dns);
2440 lp_set_cmdline("torture:ldap_userdn", userdn);
2442 /* retrieve the basedn */
2444 p = strchr_m(d, '#');
2446 lp_set_cmdline("torture:ldap_basedn", "");
2447 lp_set_cmdline("torture:ldap_secret", "");
2450 basedn = strndup(d, p - d);
2451 lp_set_cmdline("torture:ldap_basedn", basedn);
2453 /* retrieve the secret */
2456 lp_set_cmdline("torture:ldap_secret", "");
2460 lp_set_cmdline("torture:ldap_secret", secret);
2462 printf ("%s - %s - %s\n", userdn, basedn, secret);
2466 static void usage(poptContext pc)
2471 poptPrintUsage(pc, stdout, 0);
2474 printf("The binding format is:\n\n");
2476 printf(" TRANSPORT:host[flags]\n\n");
2478 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2480 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2481 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2482 printf(" string.\n\n");
2484 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2485 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2486 printf(" will be auto-determined.\n\n");
2488 printf(" other recognised flags are:\n\n");
2490 printf(" sign : enable ntlmssp signing\n");
2491 printf(" seal : enable ntlmssp sealing\n");
2492 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2493 printf(" validate: enable the NDR validator\n");
2494 printf(" print: enable debugging of the packets\n");
2495 printf(" bigendian: use bigendian RPC\n");
2496 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2498 printf(" For example, these all connect to the samr pipe:\n\n");
2500 printf(" ncacn_np:myserver\n");
2501 printf(" ncacn_np:myserver[samr]\n");
2502 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2503 printf(" ncacn_np:myserver[/pipe/samr]\n");
2504 printf(" ncacn_np:myserver[samr,sign,print]\n");
2505 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2506 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2507 printf(" ncacn_np:\n");
2508 printf(" ncacn_np:[/pipe/samr]\n\n");
2510 printf(" ncacn_ip_tcp:myserver\n");
2511 printf(" ncacn_ip_tcp:myserver[1024]\n");
2512 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2514 printf("The unc format is:\n\n");
2516 printf(" //server/share\n\n");
2518 printf("tests are:");
2519 for (i=0;torture_ops[i].name;i++) {
2520 if ((i%perline)==0) {
2523 printf("%s ", torture_ops[i].name);
2527 printf("default test is ALL\n");
2532 static BOOL is_binding_string(const char *binding_string)
2534 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2535 struct dcerpc_binding *binding_struct;
2538 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2540 talloc_free(mem_ctx);
2541 return NT_STATUS_IS_OK(status);
2544 static void max_runtime_handler(int sig)
2546 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2550 /****************************************************************************
2552 ****************************************************************************/
2553 int main(int argc,char *argv[])
2557 BOOL correct = True;
2562 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,
2563 OPT_DANGEROUS,OPT_SMB_PORTS};
2565 struct poptOption long_options[] = {
2567 {"smb-ports", 'p', POPT_ARG_STRING, NULL, OPT_SMB_PORTS, "SMB ports", NULL},
2568 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2569 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2570 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2571 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2572 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2573 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2574 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2575 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2576 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2577 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2578 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2579 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2580 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2581 "set maximum time for smbtorture to live", "seconds"},
2583 POPT_COMMON_CONNECTION
2584 POPT_COMMON_CREDENTIALS
2589 #ifdef HAVE_SETBUFFER
2590 setbuffer(stdout, NULL, 0);
2593 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2594 POPT_CONTEXT_KEEP_FIRST);
2596 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2598 while((opt = poptGetNextOpt(pc)) != -1) {
2601 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2604 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2607 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2610 parse_dns(poptGetOptArg(pc));
2613 lp_set_cmdline("torture:dangerous", "Yes");
2616 lp_set_cmdline("smb ports", poptGetOptArg(pc));
2619 d_printf("Invalid option %s: %s\n",
2620 poptBadOption(pc, 0), poptStrerror(opt));
2627 /* this will only work if nobody else uses alarm(),
2628 which means it won't work for some tests, but we
2629 can't use the event context method we use for smbd
2630 as so many tests create their own event
2631 context. This will at least catch most cases. */
2632 signal(SIGALRM, max_runtime_handler);
2640 dcerpc_table_init();
2642 if (torture_seed == 0) {
2643 torture_seed = time(NULL);
2645 printf("Using seed %d\n", torture_seed);
2646 srandom(torture_seed);
2648 argv_new = discard_const_p(char *, poptGetArgs(pc));
2651 for (i=0; i<argc; i++) {
2652 if (argv_new[i] == NULL) {
2663 for(p = argv_new[1]; *p; p++) {
2668 /* see if its a RPC transport specifier */
2669 if (is_binding_string(argv_new[1])) {
2670 lp_set_cmdline("torture:binding", argv_new[1]);
2672 char *binding = NULL;
2673 const char *host = NULL, *share = NULL;
2675 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
2676 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
2680 lp_set_cmdline("torture:host", host);
2681 lp_set_cmdline("torture:share", share);
2682 asprintf(&binding, "ncacn_np:%s", host);
2683 lp_set_cmdline("torture:binding", binding);
2686 if (argc_new == 0) {
2687 printf("You must specify a test to run, or 'ALL'\n");
2689 for (i=2;i<argc_new;i++) {
2690 if (!run_test(argv_new[i])) {