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 "dynconfig.h"
24 #include "lib/cmdline/popt_common.h"
25 #include "libcli/raw/libcliraw.h"
26 #include "system/time.h"
27 #include "system/wait.h"
28 #include "system/filesys.h"
30 #include "librpc/gen_ndr/ndr_security.h"
33 int torture_numops=100;
34 int torture_entries=1000;
35 int torture_failures=1;
37 static int procnum; /* records process count number when forking */
38 static struct smbcli_state *current_cli;
39 static BOOL use_oplocks;
40 static BOOL use_level_II_oplocks;
42 BOOL torture_showall = False;
44 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
46 static struct smbcli_state *open_nbt_connection(void)
48 struct nbt_name called, calling;
49 struct smbcli_state *cli;
50 const char *host = lp_parm_string(-1, "torture", "host");
52 make_nbt_name_client(&calling, lp_netbios_name());
54 nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
56 cli = smbcli_state_init(NULL);
58 printf("Failed initialize smbcli_struct to connect with %s\n", host);
62 if (!smbcli_socket_connect(cli, host)) {
63 printf("Failed to connect with %s\n", host);
67 if (!smbcli_transport_establish(cli, &calling, &called)) {
68 printf("%s rejected the session\n",host);
79 BOOL torture_open_connection_share(TALLOC_CTX *mem_ctx,
80 struct smbcli_state **c,
82 const char *sharename,
83 struct event_context *ev)
87 status = smbcli_full_connection(mem_ctx, c, hostname,
89 cmdline_credentials, ev);
90 if (!NT_STATUS_IS_OK(status)) {
91 printf("Failed to open connection - %s\n", nt_errstr(status));
95 (*c)->transport->options.use_oplocks = use_oplocks;
96 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
101 BOOL torture_open_connection(struct smbcli_state **c)
103 const char *host = lp_parm_string(-1, "torture", "host");
104 const char *share = lp_parm_string(-1, "torture", "share");
106 return torture_open_connection_share(NULL, c, host, share, NULL);
111 BOOL torture_close_connection(struct smbcli_state *c)
115 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
116 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
123 /* open a rpc connection to the chosen binding string */
124 NTSTATUS torture_rpc_connection(TALLOC_CTX *parent_ctx,
125 struct dcerpc_pipe **p,
126 const char *pipe_name,
127 const char *pipe_uuid,
128 uint32_t pipe_version)
131 const char *binding = lp_parm_string(-1, "torture", "binding");
134 printf("You must specify a ncacn binding string\n");
135 return NT_STATUS_INVALID_PARAMETER;
138 status = dcerpc_pipe_connect(parent_ctx,
139 p, binding, pipe_uuid, pipe_version,
140 cmdline_credentials, NULL);
145 /* open a rpc connection to a specific transport */
146 NTSTATUS torture_rpc_connection_transport(TALLOC_CTX *parent_ctx,
147 struct dcerpc_pipe **p,
148 const char *pipe_name,
149 const char *pipe_uuid,
150 uint32_t pipe_version,
151 enum dcerpc_transport_t transport)
154 const char *binding = lp_parm_string(-1, "torture", "binding");
155 struct dcerpc_binding *b;
156 TALLOC_CTX *mem_ctx = talloc_named(parent_ctx, 0, "torture_rpc_connection_smb");
159 printf("You must specify a ncacn binding string\n");
160 talloc_free(mem_ctx);
161 return NT_STATUS_INVALID_PARAMETER;
164 status = dcerpc_parse_binding(mem_ctx, binding, &b);
165 if (!NT_STATUS_IS_OK(status)) {
166 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
167 talloc_free(mem_ctx);
171 b->transport = transport;
173 status = dcerpc_pipe_connect_b(mem_ctx, p, b, pipe_uuid, pipe_version,
174 cmdline_credentials, NULL);
176 if (NT_STATUS_IS_OK(status)) {
177 *p = talloc_reference(parent_ctx, *p);
181 talloc_free(mem_ctx);
185 /* check if the server produced the expected error code */
186 BOOL check_error(const char *location, struct smbcli_state *c,
187 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
191 status = smbcli_nt_error(c->tree);
192 if (NT_STATUS_IS_DOS(status)) {
194 class = NT_STATUS_DOS_CLASS(status);
195 num = NT_STATUS_DOS_CODE(status);
196 if (eclass != class || ecode != num) {
197 printf("unexpected error code %s\n", nt_errstr(status));
198 printf(" expected %s or %s (at %s)\n",
199 nt_errstr(NT_STATUS_DOS(eclass, ecode)),
200 nt_errstr(nterr), location);
204 if (!NT_STATUS_EQUAL(nterr, status)) {
205 printf("unexpected error code %s\n", nt_errstr(status));
206 printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
215 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
217 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
218 if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
224 static BOOL rw_torture(struct smbcli_state *c)
226 const char *lockfname = "\\torture.lck";
230 pid_t pid2, pid = getpid();
235 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
238 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
240 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
245 for (i=0;i<torture_numops;i++) {
246 uint_t n = (uint_t)random()%10;
248 printf("%d\r", i); fflush(stdout);
250 asprintf(&fname, "\\torture.%u", n);
252 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
256 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
258 printf("open failed (%s)\n", smbcli_errstr(c->tree));
263 if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
264 printf("write failed (%s)\n", smbcli_errstr(c->tree));
269 if (smbcli_write(c->tree, fnum, 0, buf,
270 sizeof(pid)+(j*sizeof(buf)),
271 sizeof(buf)) != sizeof(buf)) {
272 printf("write failed (%s)\n", smbcli_errstr(c->tree));
279 if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
280 printf("read failed (%s)\n", smbcli_errstr(c->tree));
285 printf("data corruption!\n");
289 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
290 printf("close failed (%s)\n", smbcli_errstr(c->tree));
294 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
295 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
299 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
300 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
306 smbcli_close(c->tree, fnum2);
307 smbcli_unlink(c->tree, lockfname);
314 static BOOL run_torture(struct smbcli_state *cli, int dummy)
318 ret = rw_torture(cli);
320 if (!torture_close_connection(cli)) {
328 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
330 const char *lockfname = "\\torture2.lck";
335 uint8_t buf_rd[131072];
337 ssize_t bytes_read, bytes_written;
339 if (smbcli_deltree(c1->tree, lockfname) == -1) {
340 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
343 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
346 printf("first open read/write of %s failed (%s)\n",
347 lockfname, smbcli_errstr(c1->tree));
350 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
353 printf("second open read-only of %s failed (%s)\n",
354 lockfname, smbcli_errstr(c2->tree));
355 smbcli_close(c1->tree, fnum1);
359 printf("Checking data integrity over %d ops\n", torture_numops);
361 for (i=0;i<torture_numops;i++)
363 size_t buf_size = ((uint_t)random()%(sizeof(buf)-1))+ 1;
365 printf("%d\r", i); fflush(stdout);
368 generate_random_buffer(buf, buf_size);
370 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
371 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
372 printf("wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
377 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
378 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
379 printf("read %d, expected %d\n", (int)bytes_read, (int)buf_size);
384 if (memcmp(buf_rd, buf, buf_size) != 0)
386 printf("read/write compare failed\n");
392 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
393 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
396 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
397 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
401 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
402 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
409 #define BOOLSTR(b) ((b) ? "Yes" : "No")
411 static BOOL run_readwritetest(void)
413 struct smbcli_state *cli1, *cli2;
414 BOOL test1, test2 = True;
416 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
420 printf("starting readwritetest\n");
422 test1 = rw_torture2(cli1, cli2);
423 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
426 test2 = rw_torture2(cli1, cli1);
427 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
430 if (!torture_close_connection(cli1)) {
434 if (!torture_close_connection(cli2)) {
438 return (test1 && test2);
442 this checks to see if a secondary tconx can use open files from an
445 static BOOL run_tcon_test(void)
447 struct smbcli_state *cli;
448 const char *fname = "\\tcontest.tmp";
450 uint16_t cnum1, cnum2, cnum3;
451 uint16_t vuid1, vuid2;
454 struct smbcli_tree *tree1;
455 const char *host = lp_parm_string(-1, "torture", "host");
456 const char *share = lp_parm_string(-1, "torture", "share");
457 const char *password = lp_parm_string(-1, "torture", "password");
459 if (!torture_open_connection(&cli)) {
463 printf("starting tcontest\n");
465 if (smbcli_deltree(cli->tree, fname) == -1) {
466 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
469 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
471 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
475 cnum1 = cli->tree->tid;
476 vuid1 = cli->session->vuid;
478 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
479 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
480 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
484 tree1 = cli->tree; /* save old tree connection */
485 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
486 printf("%s refused 2nd tree connect (%s)\n", host,
487 smbcli_errstr(cli->tree));
492 cnum2 = cli->tree->tid;
493 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
494 vuid2 = cli->session->vuid + 1;
496 /* try a write with the wrong tid */
497 cli->tree->tid = cnum2;
499 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
500 printf("* server allows write with wrong TID\n");
503 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
507 /* try a write with an invalid tid */
508 cli->tree->tid = cnum3;
510 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
511 printf("* server allows write with invalid TID\n");
514 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
517 /* try a write with an invalid vuid */
518 cli->session->vuid = vuid2;
519 cli->tree->tid = cnum1;
521 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
522 printf("* server allows write with invalid VUID\n");
525 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
528 cli->session->vuid = vuid1;
529 cli->tree->tid = cnum1;
531 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
532 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
536 cli->tree->tid = cnum2;
538 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
539 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
543 cli->tree = tree1; /* restore initial tree */
544 cli->tree->tid = cnum1;
546 smbcli_unlink(tree1, fname);
548 if (!torture_close_connection(cli)) {
557 static BOOL tcon_devtest(struct smbcli_state *cli,
558 const char *myshare, const char *devtype,
559 NTSTATUS expected_error)
563 const char *password = lp_parm_string(-1, "torture", "password");
565 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
568 printf("Trying share %s with devtype %s\n", myshare, devtype);
570 if (NT_STATUS_IS_OK(expected_error)) {
574 printf("tconX to share %s with type %s "
575 "should have succeeded but failed\n",
582 printf("tconx to share %s with type %s "
583 "should have failed but succeeded\n",
587 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
591 printf("Returned unexpected error\n");
600 checks for correct tconX support
602 static BOOL run_tcon_devtype_test(void)
604 struct smbcli_state *cli1 = NULL;
607 const char *host = lp_parm_string(-1, "torture", "host");
608 const char *share = lp_parm_string(-1, "torture", "share");
610 status = smbcli_full_connection(NULL,
613 cmdline_credentials, NULL);
615 if (!NT_STATUS_IS_OK(status)) {
616 printf("could not open connection\n");
620 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
623 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
626 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
629 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
632 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
635 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
638 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
641 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
644 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
647 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
653 printf("Passed tcondevtest\n");
660 test whether fnums and tids open on one VC are available on another (a major
663 static BOOL run_fdpasstest(void)
665 struct smbcli_state *cli1, *cli2;
666 const char *fname = "\\fdpass.tst";
670 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
674 printf("starting fdpasstest\n");
676 smbcli_unlink(cli1->tree, fname);
678 printf("Opening a file on connection 1\n");
680 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
682 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
686 printf("writing to file on connection 1\n");
688 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
689 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
693 oldtid = cli2->tree->tid;
694 cli2->session->vuid = cli1->session->vuid;
695 cli2->tree->tid = cli1->tree->tid;
696 cli2->session->pid = cli1->session->pid;
698 printf("reading from file on connection 2\n");
700 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
701 printf("read succeeded! nasty security hole [%s]\n",
706 smbcli_close(cli1->tree, fnum1);
707 smbcli_unlink(cli1->tree, fname);
709 cli2->tree->tid = oldtid;
711 torture_close_connection(cli1);
712 torture_close_connection(cli2);
714 printf("finished fdpasstest\n");
720 test the timing of deferred open requests
722 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
724 const char *fname = "\\defer_open_test.dat";
730 printf("failed to connect\n");
734 printf("Testing deferred open requests.\n");
741 tv = timeval_current();
742 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
744 FILE_ATTRIBUTE_NORMAL,
745 NTCREATEX_SHARE_ACCESS_NONE,
746 NTCREATEX_DISP_OPEN_IF, 0, 0);
750 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
751 double e = timeval_elapsed(&tv);
752 if (e < 0.5 || e > 1.5) {
753 fprintf(stderr,"Timing incorrect %.2f violation\n",
757 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
760 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
764 printf("pid %u open %d\n", getpid(), i);
768 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
769 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
775 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
776 /* All until the last unlink will fail with sharing violation. */
777 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
778 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
783 printf("deferred test finished\n");
784 if (!torture_close_connection(cli)) {
791 test how many open files this server supports on the one socket
793 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
795 #define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
797 int fnums[0x11000], i;
798 int retries=4, maxfid;
802 printf("failed to connect\n");
806 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
807 printf("Failed to deltree \\maxfid - %s\n",
808 smbcli_errstr(cli->tree));
811 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
812 printf("Failed to mkdir \\maxfid, error=%s\n",
813 smbcli_errstr(cli->tree));
817 printf("Testing maximum number of open files\n");
819 for (i=0; i<0x11000; i++) {
821 asprintf(&fname, "\\maxfid\\fid%d", i/1000);
822 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
823 printf("Failed to mkdir %s, error=%s\n",
824 fname, smbcli_errstr(cli->tree));
829 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
830 if ((fnums[i] = smbcli_open(cli->tree, fname,
831 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
833 printf("open of %s failed (%s)\n",
834 fname, smbcli_errstr(cli->tree));
835 printf("maximum fnum is %d\n", i);
846 printf("cleaning up\n");
847 for (i=0;i<maxfid/2;i++) {
848 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
849 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
850 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
852 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
853 printf("unlink of %s failed (%s)\n",
854 fname, smbcli_errstr(cli->tree));
859 asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
860 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
861 printf("Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
863 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
864 printf("unlink of %s failed (%s)\n",
865 fname, smbcli_errstr(cli->tree));
870 printf("%6d %6d\r", i, maxfid-i);
874 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
875 printf("Failed to deltree \\maxfid - %s\n",
876 smbcli_errstr(cli->tree));
880 printf("maxfid test finished\n");
881 if (!torture_close_connection(cli)) {
885 #undef MAXFID_TEMPLATE
888 /* send smb negprot commands, not reading the response */
889 static BOOL run_negprot_nowait(void)
892 struct smbcli_state *cli, *cli2;
895 printf("starting negprot nowait test\n");
897 cli = open_nbt_connection();
902 printf("Filling send buffer\n");
904 for (i=0;i<10000;i++) {
905 struct smbcli_request *req;
906 time_t t1 = time(NULL);
907 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
908 while (req->state == SMBCLI_REQUEST_SEND && time(NULL) < t1+5) {
909 smbcli_transport_process(cli->transport);
911 if (req->state == SMBCLI_REQUEST_ERROR) {
912 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
913 torture_close_connection(cli);
916 if (req->state == SMBCLI_REQUEST_SEND) {
922 printf("send buffer failed to fill\n");
923 if (!torture_close_connection(cli)) {
929 printf("send buffer filled after %d requests\n", i);
931 printf("Opening secondary connection\n");
932 if (!torture_open_connection(&cli2)) {
936 if (!torture_close_connection(cli)) {
940 if (!torture_close_connection(cli2)) {
944 printf("finished negprot nowait test\n");
951 This checks how the getatr calls works
953 static BOOL run_attrtest(void)
955 struct smbcli_state *cli;
958 const char *fname = "\\attrib123456789.tst";
961 printf("starting attrib test\n");
963 if (!torture_open_connection(&cli)) {
967 smbcli_unlink(cli->tree, fname);
968 fnum = smbcli_open(cli->tree, fname,
969 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
970 smbcli_close(cli->tree, fnum);
972 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
973 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
977 printf("New file time is %s", ctime(&t));
979 if (abs(t - time(NULL)) > 60*60*24*10) {
980 printf("ERROR: SMBgetatr bug. time is %s",
986 t2 = t-60*60*24; /* 1 day ago */
988 printf("Setting file time to %s", ctime(&t2));
990 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
991 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
995 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
996 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
1000 printf("Retrieved file time as %s", ctime(&t));
1003 printf("ERROR: getatr/setatr bug. times are\n%s",
1005 printf("%s", ctime(&t2));
1009 smbcli_unlink(cli->tree, fname);
1011 if (!torture_close_connection(cli)) {
1015 printf("attrib test finished\n");
1022 This checks a couple of trans2 calls
1024 static BOOL run_trans2test(void)
1026 struct smbcli_state *cli;
1029 time_t c_time, a_time, m_time, w_time, m_time2;
1030 const char *fname = "\\trans2.tst";
1031 const char *dname = "\\trans2";
1032 const char *fname2 = "\\trans2\\trans2.tst";
1034 BOOL correct = True;
1036 printf("starting trans2 test\n");
1038 if (!torture_open_connection(&cli)) {
1042 smbcli_unlink(cli->tree, fname);
1044 printf("Testing qfileinfo\n");
1046 fnum = smbcli_open(cli->tree, fname,
1047 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1048 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
1050 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
1054 printf("Testing NAME_INFO\n");
1056 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
1057 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
1061 if (!pname || strcmp(pname, fname)) {
1062 printf("qfilename gave different name? [%s] [%s]\n",
1067 smbcli_close(cli->tree, fnum);
1068 smbcli_unlink(cli->tree, fname);
1070 fnum = smbcli_open(cli->tree, fname,
1071 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1073 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1076 smbcli_close(cli->tree, fnum);
1078 printf("Checking for sticky create times\n");
1080 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1081 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
1084 if (c_time != m_time) {
1085 printf("create time=%s", ctime(&c_time));
1086 printf("modify time=%s", ctime(&m_time));
1087 printf("This system appears to have sticky create times\n");
1089 if (a_time % (60*60) == 0) {
1090 printf("access time=%s", ctime(&a_time));
1091 printf("This system appears to set a midnight access time\n");
1095 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1096 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1102 smbcli_unlink(cli->tree, fname);
1103 fnum = smbcli_open(cli->tree, fname,
1104 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1105 smbcli_close(cli->tree, fnum);
1106 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1107 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1110 if (w_time < 60*60*24*2) {
1111 printf("write time=%s", ctime(&w_time));
1112 printf("This system appears to set a initial 0 write time\n");
1117 smbcli_unlink(cli->tree, fname);
1120 /* check if the server updates the directory modification time
1121 when creating a new file */
1122 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1123 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
1127 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1128 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1132 fnum = smbcli_open(cli->tree, fname2,
1133 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1134 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
1135 smbcli_close(cli->tree, fnum);
1136 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
1137 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1140 if (m_time2 == m_time) {
1141 printf("This system does not update directory modification times\n");
1145 smbcli_unlink(cli->tree, fname2);
1146 smbcli_rmdir(cli->tree, dname);
1148 if (!torture_close_connection(cli)) {
1152 printf("trans2 test finished\n");
1159 /* FIRST_DESIRED_ACCESS 0xf019f */
1160 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1161 SEC_FILE_READ_EA| /* 0xf */ \
1162 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1163 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1164 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1165 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1166 /* SECOND_DESIRED_ACCESS 0xe0080 */
1167 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1168 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1169 SEC_STD_WRITE_OWNER /* 0xe0000 */
1172 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1173 READ_CONTROL|WRITE_DAC|\
1174 SEC_FILE_READ_DATA|\
1179 Test ntcreate calls made by xcopy
1181 static BOOL run_xcopy(void)
1183 struct smbcli_state *cli1;
1184 const char *fname = "\\test.txt";
1185 BOOL correct = True;
1188 printf("starting xcopy test\n");
1190 if (!torture_open_connection(&cli1)) {
1194 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1195 FIRST_DESIRED_ACCESS,
1196 FILE_ATTRIBUTE_ARCHIVE,
1197 NTCREATEX_SHARE_ACCESS_NONE,
1198 NTCREATEX_DISP_OVERWRITE_IF,
1202 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
1206 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1207 SECOND_DESIRED_ACCESS, 0,
1208 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1211 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
1215 if (!torture_close_connection(cli1)) {
1224 see how many RPC pipes we can open at once
1226 static BOOL run_pipe_number(void)
1228 struct smbcli_state *cli1;
1229 const char *pipe_name = "\\WKSSVC";
1233 printf("starting pipenumber test\n");
1234 if (!torture_open_connection(&cli1)) {
1239 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1240 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1243 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
1247 printf("%d\r", num_pipes);
1251 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
1252 torture_close_connection(cli1);
1260 open N connections to the server and just hold them open
1261 used for testing performance when there are N idle users
1264 static BOOL torture_holdcon(void)
1267 struct smbcli_state **cli;
1270 printf("Opening %d connections\n", torture_numops);
1272 cli = malloc_array_p(struct smbcli_state *, torture_numops);
1274 for (i=0;i<torture_numops;i++) {
1275 if (!torture_open_connection(&cli[i])) {
1278 printf("opened %d connections\r", i);
1282 printf("\nStarting pings\n");
1285 for (i=0;i<torture_numops;i++) {
1288 status = smbcli_chkpath(cli[i]->tree, "\\");
1289 if (!NT_STATUS_IS_OK(status)) {
1290 printf("Connection %d is dead\n", i);
1298 if (num_dead == torture_numops) {
1299 printf("All connections dead - finishing\n");
1311 Try with a wrong vuid and check error message.
1314 static BOOL run_vuidtest(void)
1316 struct smbcli_state *cli;
1317 const char *fname = "\\vuid.tst";
1320 time_t c_time, a_time, m_time;
1321 BOOL correct = True;
1326 printf("starting vuid test\n");
1328 if (!torture_open_connection(&cli)) {
1332 smbcli_unlink(cli->tree, fname);
1334 fnum = smbcli_open(cli->tree, fname,
1335 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1337 orig_vuid = cli->session->vuid;
1339 cli->session->vuid += 1234;
1341 printf("Testing qfileinfo with wrong vuid\n");
1343 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
1344 &size, &c_time, &a_time,
1345 &m_time, NULL, NULL))) {
1346 printf("ERROR: qfileinfo passed with wrong vuid\n");
1350 if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1351 NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
1352 !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1353 NT_STATUS_INVALID_HANDLE)) {
1354 printf("ERROR: qfileinfo should have returned DOS error "
1355 "ERRSRV:ERRbaduid\n but returned %s\n",
1356 smbcli_errstr(cli->tree));
1360 cli->session->vuid -= 1234;
1362 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1363 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
1367 smbcli_unlink(cli->tree, fname);
1369 if (!torture_close_connection(cli)) {
1373 printf("vuid test finished\n");
1379 Test open mode returns on read-only files.
1381 static BOOL run_opentest(void)
1383 static struct smbcli_state *cli1;
1384 static struct smbcli_state *cli2;
1385 const char *fname = "\\readonly.file";
1386 char *control_char_fname;
1390 BOOL correct = True;
1395 printf("starting open test\n");
1397 if (!torture_open_connection(&cli1)) {
1401 asprintf(&control_char_fname, "\\readonly.afile");
1402 for (i = 1; i <= 0x1f; i++) {
1403 control_char_fname[10] = i;
1404 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
1405 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1407 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
1408 NT_STATUS_OBJECT_NAME_INVALID)) {
1409 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
1410 smbcli_errstr(cli1->tree), i);
1415 smbcli_close(cli1->tree, fnum1);
1417 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
1418 smbcli_unlink(cli1->tree, control_char_fname);
1420 free(control_char_fname);
1423 printf("Create file with control char names passed.\n");
1425 smbcli_setatr(cli1->tree, fname, 0, 0);
1426 smbcli_unlink(cli1->tree, fname);
1428 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1430 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1434 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1435 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1439 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
1440 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
1441 CHECK_MAX_FAILURES(error_test1);
1445 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1447 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1448 CHECK_MAX_FAILURES(error_test1);
1452 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
1453 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1455 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
1456 NT_STATUS_ACCESS_DENIED)) {
1457 printf("correct error code ERRDOS/ERRnoaccess returned\n");
1460 printf("finished open test 1\n");
1462 smbcli_close(cli1->tree, fnum1);
1464 /* Now try not readonly and ensure ERRbadshare is returned. */
1466 smbcli_setatr(cli1->tree, fname, 0, 0);
1468 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1470 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1474 /* This will fail - but the error should be ERRshare. */
1475 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1477 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
1478 NT_STATUS_SHARING_VIOLATION)) {
1479 printf("correct error code ERRDOS/ERRbadshare returned\n");
1482 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1483 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1487 smbcli_unlink(cli1->tree, fname);
1489 printf("finished open test 2\n");
1491 /* Test truncate open disposition on file opened for read. */
1493 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1495 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1499 /* write 20 bytes. */
1501 memset(buf, '\0', 20);
1503 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1504 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1508 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1509 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1513 /* Ensure size == 20. */
1514 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1515 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1516 CHECK_MAX_FAILURES(error_test3);
1521 printf("(3) file size != 20\n");
1522 CHECK_MAX_FAILURES(error_test3);
1526 /* Now test if we can truncate a file opened for readonly. */
1528 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
1530 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1531 CHECK_MAX_FAILURES(error_test3);
1535 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1536 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1540 /* Ensure size == 0. */
1541 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1542 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1543 CHECK_MAX_FAILURES(error_test3);
1548 printf("(3) file size != 0\n");
1549 CHECK_MAX_FAILURES(error_test3);
1552 printf("finished open test 3\n");
1554 smbcli_unlink(cli1->tree, fname);
1557 printf("testing ctemp\n");
1558 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
1560 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1561 CHECK_MAX_FAILURES(error_test4);
1564 printf("ctemp gave path %s\n", tmp_path);
1565 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1566 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1568 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1569 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1572 /* Test the non-io opens... */
1574 if (!torture_open_connection(&cli2)) {
1578 smbcli_setatr(cli2->tree, fname, 0, 0);
1579 smbcli_unlink(cli2->tree, fname);
1581 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1583 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1584 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1587 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1588 CHECK_MAX_FAILURES(error_test10);
1592 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1593 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1595 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1596 CHECK_MAX_FAILURES(error_test10);
1600 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1601 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1604 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1605 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1609 printf("non-io open test #1 passed.\n");
1611 smbcli_unlink(cli1->tree, fname);
1613 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1615 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1616 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1619 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1620 CHECK_MAX_FAILURES(error_test20);
1624 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1625 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1628 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1629 CHECK_MAX_FAILURES(error_test20);
1633 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1634 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1637 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1638 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1642 printf("non-io open test #2 passed.\n");
1644 smbcli_unlink(cli1->tree, fname);
1646 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1648 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1649 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1652 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1653 CHECK_MAX_FAILURES(error_test30);
1657 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1658 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1661 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1662 CHECK_MAX_FAILURES(error_test30);
1666 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1667 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1670 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1671 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1675 printf("non-io open test #3 passed.\n");
1677 smbcli_unlink(cli1->tree, fname);
1679 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1681 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1682 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1685 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1686 CHECK_MAX_FAILURES(error_test40);
1690 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1691 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1694 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1695 CHECK_MAX_FAILURES(error_test40);
1699 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1701 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1702 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1706 printf("non-io open test #4 passed.\n");
1708 smbcli_unlink(cli1->tree, fname);
1710 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1712 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1713 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1716 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1717 CHECK_MAX_FAILURES(error_test50);
1721 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1722 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1725 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1726 CHECK_MAX_FAILURES(error_test50);
1730 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1731 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1735 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1736 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1740 printf("non-io open test #5 passed.\n");
1742 printf("TEST #6 testing 1 non-io open, one io open\n");
1744 smbcli_unlink(cli1->tree, fname);
1746 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1747 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1750 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1751 CHECK_MAX_FAILURES(error_test60);
1755 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1756 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1759 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1760 CHECK_MAX_FAILURES(error_test60);
1764 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1765 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1769 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1770 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1774 printf("non-io open test #6 passed.\n");
1776 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
1778 smbcli_unlink(cli1->tree, fname);
1780 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1781 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1784 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1785 CHECK_MAX_FAILURES(error_test70);
1789 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1790 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1793 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1794 CHECK_MAX_FAILURES(error_test70);
1798 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1800 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1801 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1805 printf("non-io open test #7 passed.\n");
1809 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1811 smbcli_unlink(cli1->tree, fname);
1813 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1815 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1819 /* write 20 bytes. */
1821 memset(buf, '\0', 20);
1823 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1824 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1828 /* Ensure size == 20. */
1829 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1830 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1831 CHECK_MAX_FAILURES(error_test80);
1836 printf("(8) file size != 20\n");
1837 CHECK_MAX_FAILURES(error_test80);
1841 /* Get an exclusive lock on the open file. */
1842 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1843 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1844 CHECK_MAX_FAILURES(error_test80);
1848 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1850 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1854 /* Ensure size == 0. */
1855 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1856 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1857 CHECK_MAX_FAILURES(error_test80);
1862 printf("(8) file size != 0\n");
1863 CHECK_MAX_FAILURES(error_test80);
1867 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1868 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1872 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1873 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1879 printf("open test #8 passed.\n");
1881 smbcli_unlink(cli1->tree, fname);
1883 if (!torture_close_connection(cli1)) {
1886 if (!torture_close_connection(cli2)) {
1895 sees what IOCTLs are supported
1897 BOOL torture_ioctl_test(void)
1899 struct smbcli_state *cli;
1900 uint16_t device, function;
1902 const char *fname = "\\ioctl.dat";
1904 union smb_ioctl parms;
1905 TALLOC_CTX *mem_ctx;
1907 if (!torture_open_connection(&cli)) {
1911 mem_ctx = talloc_init("ioctl_test");
1913 printf("starting ioctl test\n");
1915 smbcli_unlink(cli->tree, fname);
1917 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1919 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1923 parms.ioctl.level = RAW_IOCTL_IOCTL;
1924 parms.ioctl.in.fnum = fnum;
1925 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
1926 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1927 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
1929 for (device=0;device<0x100;device++) {
1930 printf("testing device=0x%x\n", device);
1931 for (function=0;function<0x100;function++) {
1932 parms.ioctl.in.request = (device << 16) | function;
1933 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1935 if (NT_STATUS_IS_OK(status)) {
1936 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
1937 device, function, (int)parms.ioctl.out.blob.length);
1942 if (!torture_close_connection(cli)) {
1951 tries variants of chkpath
1953 BOOL torture_chkpath_test(void)
1955 struct smbcli_state *cli;
1959 if (!torture_open_connection(&cli)) {
1963 printf("starting chkpath test\n");
1965 printf("Testing valid and invalid paths\n");
1967 /* cleanup from an old run */
1968 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1969 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1970 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1972 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1973 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1977 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1978 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1982 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1984 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
1987 smbcli_close(cli->tree, fnum);
1989 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1990 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1994 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1995 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1999 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
2000 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2001 NT_STATUS_NOT_A_DIRECTORY);
2003 printf("* chkpath on a file should fail\n");
2007 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
2008 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2009 NT_STATUS_OBJECT_NAME_NOT_FOUND);
2011 printf("* chkpath on a non existent file should fail\n");
2015 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
2016 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2017 NT_STATUS_OBJECT_PATH_NOT_FOUND);
2019 printf("* chkpath on a non existent component should fail\n");
2023 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
2024 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
2025 smbcli_rmdir(cli->tree, "\\chkpath.dir");
2027 if (!torture_close_connection(cli)) {
2035 static void sigcont(int sig)
2039 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
2042 volatile pid_t *child_status;
2043 volatile BOOL *child_status_out;
2046 double start_time_limit = 10 + (torture_nprocs * 1.5);
2047 char **unc_list = NULL;
2049 int num_unc_names = 0;
2056 signal(SIGCONT, sigcont);
2058 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
2059 if (!child_status) {
2060 printf("Failed to setup shared memory\n");
2064 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
2065 if (!child_status_out) {
2066 printf("Failed to setup result status shared memory\n");
2070 p = lp_parm_string(-1, "torture", "unclist");
2072 unc_list = file_lines_load(p, &num_unc_names, NULL);
2073 if (!unc_list || num_unc_names <= 0) {
2074 printf("Failed to load unc names list from '%s'\n", p);
2079 for (i = 0; i < torture_nprocs; i++) {
2080 child_status[i] = 0;
2081 child_status_out[i] = True;
2084 tv = timeval_current();
2086 for (i=0;i<torture_nprocs;i++) {
2090 const char *hostname=NULL, *sharename;
2092 pid_t mypid = getpid();
2093 srandom(((int)mypid) ^ ((int)time(NULL)));
2095 asprintf(&myname, "CLIENT%d", i);
2096 lp_set_cmdline("netbios name", myname);
2101 if (!smbcli_parse_unc(unc_list[i % num_unc_names],
2102 NULL, &hostname, &sharename)) {
2103 printf("Failed to parse UNC name %s\n",
2104 unc_list[i % num_unc_names]);
2111 if (torture_open_connection_share(NULL,
2118 } else if (torture_open_connection(¤t_cli)) {
2122 printf("pid %d failed to start\n", (int)getpid());
2128 child_status[i] = getpid();
2132 if (child_status[i]) {
2133 printf("Child %d failed to start!\n", i);
2134 child_status_out[i] = 1;
2138 child_status_out[i] = fn(current_cli, i);
2145 for (i=0;i<torture_nprocs;i++) {
2146 if (child_status[i]) synccount++;
2148 if (synccount == torture_nprocs) break;
2150 } while (timeval_elapsed(&tv) < start_time_limit);
2152 if (synccount != torture_nprocs) {
2153 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
2155 return timeval_elapsed(&tv);
2158 printf("Starting %d clients\n", torture_nprocs);
2160 /* start the client load */
2161 tv = timeval_current();
2162 for (i=0;i<torture_nprocs;i++) {
2163 child_status[i] = 0;
2166 printf("%d clients started\n", torture_nprocs);
2170 for (i=0;i<torture_nprocs;i++) {
2172 while ((ret=sys_waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
2173 if (ret == -1 || WEXITSTATUS(status) != 0) {
2180 for (i=0;i<torture_nprocs;i++) {
2181 if (!child_status_out[i]) {
2185 return timeval_elapsed(&tv);
2188 #define FLAG_MULTIPROC 1
2193 BOOL (*multi_fn)(struct smbcli_state *, int );
2196 {"BASE-FDPASS", run_fdpasstest, 0},
2197 {"BASE-LOCK1", torture_locktest1, 0},
2198 {"BASE-LOCK2", torture_locktest2, 0},
2199 {"BASE-LOCK3", torture_locktest3, 0},
2200 {"BASE-LOCK4", torture_locktest4, 0},
2201 {"BASE-LOCK5", torture_locktest5, 0},
2202 {"BASE-LOCK6", torture_locktest6, 0},
2203 {"BASE-LOCK7", torture_locktest7, 0},
2204 {"BASE-UNLINK", torture_unlinktest, 0},
2205 {"BASE-ATTR", run_attrtest, 0},
2206 {"BASE-TRANS2", run_trans2test, 0},
2207 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
2208 {"BASE-DIR1", torture_dirtest1, 0},
2209 {"BASE-DIR2", torture_dirtest2, 0},
2210 {"BASE-DENY1", torture_denytest1, 0},
2211 {"BASE-DENY2", torture_denytest2, 0},
2212 {"BASE-DENY3", torture_denytest3, 0},
2213 {"BASE-DENYDOS", torture_denydos_sharing, 0},
2214 {"BASE-NTDENY1", NULL, torture_ntdenytest1},
2215 {"BASE-NTDENY2", torture_ntdenytest2, 0},
2216 {"BASE-TCON", run_tcon_test, 0},
2217 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
2218 {"BASE-VUID", run_vuidtest, 0},
2219 {"BASE-RW1", run_readwritetest, 0},
2220 {"BASE-OPEN", run_opentest, 0},
2221 {"BASE-DEFER_OPEN", NULL, run_deferopen},
2222 {"BASE-XCOPY", run_xcopy, 0},
2223 {"BASE-RENAME", torture_test_rename, 0},
2224 {"BASE-DELETE", torture_test_delete, 0},
2225 {"BASE-PROPERTIES", torture_test_properties, 0},
2226 {"BASE-MANGLE", torture_mangle, 0},
2227 {"BASE-OPENATTR", torture_openattrtest, 0},
2228 {"BASE-CHARSET", torture_charset, 0},
2229 {"BASE-CHKPATH", torture_chkpath_test, 0},
2230 {"BASE-SECLEAK", torture_sec_leak, 0},
2231 {"BASE-DISCONNECT", torture_disconnect, 0},
2232 {"BASE-DELAYWRITE", torture_delay_write, 0},
2234 /* benchmarking tests */
2235 {"BENCH-HOLDCON", torture_holdcon, 0},
2236 {"BENCH-NBENCH", torture_nbench, 0},
2237 {"BENCH-TORTURE", NULL, run_torture},
2238 {"BENCH-NBT", torture_bench_nbt, 0},
2239 {"BENCH-WINS", torture_bench_wins, 0},
2240 {"BENCH-RPC", torture_bench_rpc, 0},
2241 {"BENCH-CLDAP", torture_bench_cldap, 0},
2244 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
2245 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
2246 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
2247 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
2248 {"RAW-SEARCH", torture_raw_search, 0},
2249 {"RAW-CLOSE", torture_raw_close, 0},
2250 {"RAW-OPEN", torture_raw_open, 0},
2251 {"RAW-MKDIR", torture_raw_mkdir, 0},
2252 {"RAW-OPLOCK", torture_raw_oplock, 0},
2253 {"RAW-NOTIFY", torture_raw_notify, 0},
2254 {"RAW-MUX", torture_raw_mux, 0},
2255 {"RAW-IOCTL", torture_raw_ioctl, 0},
2256 {"RAW-CHKPATH", torture_raw_chkpath, 0},
2257 {"RAW-UNLINK", torture_raw_unlink, 0},
2258 {"RAW-READ", torture_raw_read, 0},
2259 {"RAW-WRITE", torture_raw_write, 0},
2260 {"RAW-LOCK", torture_raw_lock, 0},
2261 {"RAW-CONTEXT", torture_raw_context, 0},
2262 {"RAW-RENAME", torture_raw_rename, 0},
2263 {"RAW-SEEK", torture_raw_seek, 0},
2264 {"RAW-EAS", torture_raw_eas, 0},
2265 {"RAW-EAMAX", torture_max_eas, 0},
2266 {"RAW-STREAMS", torture_raw_streams, 0},
2267 {"RAW-ACLS", torture_raw_acls, 0},
2268 {"RAW-RAP", torture_raw_rap, 0},
2269 {"RAW-COMPOSITE", torture_raw_composite, 0},
2271 /* protocol scanners */
2272 {"SCAN-TRANS2", torture_trans2_scan, 0},
2273 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2274 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2275 {"SCAN-SMB", torture_smb_scan, 0},
2276 {"SCAN-MAXFID", NULL, run_maxfidtest},
2277 {"SCAN-UTABLE", torture_utable, 0},
2278 {"SCAN-CASETABLE", torture_casetable, 0},
2279 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2280 {"SCAN-IOCTL", torture_ioctl_test, 0},
2281 {"SCAN-RAP", torture_rap_scan, 0},
2284 {"RPC-LSA", torture_rpc_lsa, 0},
2285 {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
2286 {"RPC-ECHO", torture_rpc_echo, 0},
2287 {"RPC-DFS", torture_rpc_dfs, 0},
2288 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2289 {"RPC-SAMR", torture_rpc_samr, 0},
2290 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2291 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2292 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2293 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2294 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2295 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2296 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2297 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2298 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2299 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2300 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2301 {"RPC-WINREG", torture_rpc_winreg, 0},
2302 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2303 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2304 {"RPC-REMACT", torture_rpc_remact, 0},
2305 {"RPC-MGMT", torture_rpc_mgmt, 0},
2306 {"RPC-SCANNER", torture_rpc_scanner, 0},
2307 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2308 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2309 {"RPC-MULTIBIND", torture_multi_bind, 0},
2310 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2311 {"RPC-LOGIN", torture_rpc_login, 0},
2312 {"RPC-ROT", torture_rpc_rot, 0},
2313 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2314 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2316 /* local (no server) testers */
2317 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2318 {"LOCAL-ICONV", torture_local_iconv, 0},
2319 {"LOCAL-TALLOC", torture_local_talloc, 0},
2320 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2321 {"LOCAL-IRPC", torture_local_irpc, 0},
2322 {"LOCAL-BINDING", torture_local_binding_string, 0},
2323 {"LOCAL-IDTREE", torture_local_idtree, 0},
2324 {"LOCAL-SOCKET", torture_local_socket, 0},
2325 {"LOCAL-PAC", torture_pac, 0},
2327 /* COM (Component Object Model) testers */
2328 {"COM-SIMPLE", torture_com_simple, 0 },
2331 {"LDAP-BASIC", torture_ldap_basic, 0},
2332 {"LDAP-CLDAP", torture_cldap, 0},
2335 {"NBT-REGISTER", torture_nbt_register, 0},
2336 {"NBT-WINS", torture_nbt_wins, 0},
2337 {"NBT-WINSREPLICATION", torture_nbt_winsreplication, 0},
2338 {"NBT-DGRAM", torture_nbt_dgram, 0},
2341 {"NET-USERINFO", torture_userinfo, 0},
2342 {"NET-USERADD", torture_useradd, 0},
2343 {"NET-USERDEL", torture_userdel, 0},
2344 {"NET-USERMOD", torture_usermod, 0},
2345 {"NET-DOMOPEN", torture_domainopen, 0},
2346 {"NET-API-LOOKUP", torture_lookup, 0},
2347 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2348 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2349 {"NET-API-CREATEUSER", torture_createuser, 0},
2350 {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
2351 {"NET-API-LISTSHARES", torture_listshares, 0},
2352 {"NET-API-DELSHARE", torture_delshare, 0},
2358 /****************************************************************************
2359 run a specified test or "ALL"
2360 ****************************************************************************/
2361 static BOOL run_test(const char *name)
2365 BOOL matched = False;
2367 if (strequal(name,"ALL")) {
2368 for (i=0;torture_ops[i].name;i++) {
2369 if (!run_test(torture_ops[i].name)) {
2376 for (i=0;torture_ops[i].name;i++) {
2377 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
2381 printf("Running %s\n", torture_ops[i].name);
2382 if (torture_ops[i].multi_fn) {
2383 BOOL result = False;
2384 t = torture_create_procs(torture_ops[i].multi_fn,
2388 printf("TEST %s FAILED!\n", torture_ops[i].name);
2392 struct timeval tv = timeval_current();
2393 if (!torture_ops[i].fn()) {
2395 printf("TEST %s FAILED!\n", torture_ops[i].name);
2397 t = timeval_elapsed(&tv);
2399 printf("%s took %g secs\n\n", torture_ops[i].name, t);
2404 printf("Unknown torture operation '%s'\n", name);
2411 static void parse_dns(const char *dns)
2413 char *userdn, *basedn, *secret;
2416 /* retrievieng the userdn */
2417 p = strchr_m(dns, '#');
2419 lp_set_cmdline("torture:ldap_userdn", "");
2420 lp_set_cmdline("torture:ldap_basedn", "");
2421 lp_set_cmdline("torture:ldap_secret", "");
2424 userdn = strndup(dns, p - dns);
2425 lp_set_cmdline("torture:ldap_userdn", userdn);
2427 /* retrieve the basedn */
2429 p = strchr_m(d, '#');
2431 lp_set_cmdline("torture:ldap_basedn", "");
2432 lp_set_cmdline("torture:ldap_secret", "");
2435 basedn = strndup(d, p - d);
2436 lp_set_cmdline("torture:ldap_basedn", basedn);
2438 /* retrieve the secret */
2441 lp_set_cmdline("torture:ldap_secret", "");
2445 lp_set_cmdline("torture:ldap_secret", secret);
2447 printf ("%s - %s - %s\n", userdn, basedn, secret);
2451 static void usage(poptContext pc)
2456 poptPrintUsage(pc, stdout, 0);
2459 printf("The binding format is:\n\n");
2461 printf(" TRANSPORT:host[flags]\n\n");
2463 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2465 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2466 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2467 printf(" string.\n\n");
2469 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2470 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2471 printf(" will be auto-determined.\n\n");
2473 printf(" other recognised flags are:\n\n");
2475 printf(" sign : enable ntlmssp signing\n");
2476 printf(" seal : enable ntlmssp sealing\n");
2477 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2478 printf(" validate: enable the NDR validator\n");
2479 printf(" print: enable debugging of the packets\n");
2480 printf(" bigendian: use bigendian RPC\n");
2481 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2483 printf(" For example, these all connect to the samr pipe:\n\n");
2485 printf(" ncacn_np:myserver\n");
2486 printf(" ncacn_np:myserver[samr]\n");
2487 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2488 printf(" ncacn_np:myserver[/pipe/samr]\n");
2489 printf(" ncacn_np:myserver[samr,sign,print]\n");
2490 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2491 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2492 printf(" ncacn_np:\n");
2493 printf(" ncacn_np:[/pipe/samr]\n\n");
2495 printf(" ncacn_ip_tcp:myserver\n");
2496 printf(" ncacn_ip_tcp:myserver[1024]\n");
2497 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2499 printf("The unc format is:\n\n");
2501 printf(" //server/share\n\n");
2503 printf("tests are:");
2504 for (i=0;torture_ops[i].name;i++) {
2505 if ((i%perline)==0) {
2508 printf("%s ", torture_ops[i].name);
2512 printf("default test is ALL\n");
2517 static BOOL is_binding_string(const char *binding_string)
2519 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2520 struct dcerpc_binding *binding_struct;
2523 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2525 talloc_free(mem_ctx);
2526 return NT_STATUS_IS_OK(status);
2529 static void max_runtime_handler(int sig)
2531 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2535 /****************************************************************************
2537 ****************************************************************************/
2538 int main(int argc,char *argv[])
2542 BOOL correct = True;
2547 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,OPT_DANGEROUS};
2548 struct poptOption long_options[] = {
2550 {"smb-ports", 'p', POPT_ARG_STRING, NULL, 0, "SMB ports", NULL},
2551 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2552 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2553 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2554 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2555 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2556 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2557 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2558 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2559 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2560 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2561 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2562 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2563 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2564 "set maximum time for smbtorture to live", "seconds"},
2566 POPT_COMMON_CONNECTION
2567 POPT_COMMON_CREDENTIALS
2572 #ifdef HAVE_SETBUFFER
2573 setbuffer(stdout, NULL, 0);
2576 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2577 POPT_CONTEXT_KEEP_FIRST);
2579 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2581 while((opt = poptGetNextOpt(pc)) != -1) {
2584 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2587 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2590 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2593 parse_dns(poptGetOptArg(pc));
2596 lp_set_cmdline("torture:dangerous", "Yes");
2599 d_printf("Invalid option %s: %s\n",
2600 poptBadOption(pc, 0), poptStrerror(opt));
2607 /* this will only work if nobody else uses alarm(),
2608 which means it won't work for some tests, but we
2609 can't use the event context method we use for smbd
2610 as so many tests create their own event
2611 context. This will at least catch most cases. */
2612 signal(SIGALRM, max_runtime_handler);
2616 smbtorture_init_subsystems;
2619 if (torture_seed == 0) {
2620 torture_seed = time(NULL);
2622 printf("Using seed %d\n", torture_seed);
2623 srandom(torture_seed);
2625 argv_new = discard_const_p(char *, poptGetArgs(pc));
2628 for (i=0; i<argc; i++) {
2629 if (argv_new[i] == NULL) {
2640 for(p = argv_new[1]; *p; p++) {
2645 /* see if its a RPC transport specifier */
2646 if (is_binding_string(argv_new[1])) {
2647 lp_set_cmdline("torture:binding", argv_new[1]);
2649 char *binding = NULL;
2650 const char *host = NULL, *share = NULL;
2652 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
2653 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
2657 lp_set_cmdline("torture:host", host);
2658 lp_set_cmdline("torture:share", share);
2659 asprintf(&binding, "ncacn_np:%s", host);
2660 lp_set_cmdline("torture:binding", binding);
2663 if (argc_new == 0) {
2664 printf("You must specify a test to run, or 'ALL'\n");
2666 for (i=2;i<argc_new;i++) {
2667 if (!run_test(argv_new[i])) {