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.
23 #include "lib/cmdline/popt_common.h"
24 #include "libcli/raw/libcliraw.h"
25 #include "system/time.h"
26 #include "system/wait.h"
27 #include "system/filesys.h"
29 #include "librpc/gen_ndr/ndr_security.h"
30 #include "smb_build.h"
33 int torture_numops=10;
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<1000;i++) {
905 struct smbcli_request *req;
906 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
907 smbcli_transport_process(cli->transport);
908 if (req->state == SMBCLI_REQUEST_ERROR) {
909 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
910 torture_close_connection(cli);
915 printf("Opening secondary connection\n");
916 if (!torture_open_connection(&cli2)) {
920 if (!torture_close_connection(cli)) {
924 if (!torture_close_connection(cli2)) {
928 printf("finished negprot nowait test\n");
935 This checks how the getatr calls works
937 static BOOL run_attrtest(void)
939 struct smbcli_state *cli;
942 const char *fname = "\\attrib123456789.tst";
945 printf("starting attrib test\n");
947 if (!torture_open_connection(&cli)) {
951 smbcli_unlink(cli->tree, fname);
952 fnum = smbcli_open(cli->tree, fname,
953 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
954 smbcli_close(cli->tree, fnum);
956 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
957 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
961 printf("New file time is %s", ctime(&t));
963 if (abs(t - time(NULL)) > 60*60*24*10) {
964 printf("ERROR: SMBgetatr bug. time is %s",
970 t2 = t-60*60*24; /* 1 day ago */
972 printf("Setting file time to %s", ctime(&t2));
974 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
975 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
979 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
980 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
984 printf("Retrieved file time as %s", ctime(&t));
987 printf("ERROR: getatr/setatr bug. times are\n%s",
989 printf("%s", ctime(&t2));
993 smbcli_unlink(cli->tree, fname);
995 if (!torture_close_connection(cli)) {
999 printf("attrib test finished\n");
1006 This checks a couple of trans2 calls
1008 static BOOL run_trans2test(void)
1010 struct smbcli_state *cli;
1013 time_t c_time, a_time, m_time, w_time, m_time2;
1014 const char *fname = "\\trans2.tst";
1015 const char *dname = "\\trans2";
1016 const char *fname2 = "\\trans2\\trans2.tst";
1018 BOOL correct = True;
1020 printf("starting trans2 test\n");
1022 if (!torture_open_connection(&cli)) {
1026 smbcli_unlink(cli->tree, fname);
1028 printf("Testing qfileinfo\n");
1030 fnum = smbcli_open(cli->tree, fname,
1031 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1032 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
1034 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
1038 printf("Testing NAME_INFO\n");
1040 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
1041 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
1045 if (!pname || strcmp(pname, fname)) {
1046 printf("qfilename gave different name? [%s] [%s]\n",
1051 smbcli_close(cli->tree, fnum);
1052 smbcli_unlink(cli->tree, fname);
1054 fnum = smbcli_open(cli->tree, fname,
1055 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1057 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1060 smbcli_close(cli->tree, fnum);
1062 printf("Checking for sticky create times\n");
1064 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1065 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
1068 if (c_time != m_time) {
1069 printf("create time=%s", ctime(&c_time));
1070 printf("modify time=%s", ctime(&m_time));
1071 printf("This system appears to have sticky create times\n");
1073 if (a_time % (60*60) == 0) {
1074 printf("access time=%s", ctime(&a_time));
1075 printf("This system appears to set a midnight access time\n");
1079 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1080 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1086 smbcli_unlink(cli->tree, fname);
1087 fnum = smbcli_open(cli->tree, fname,
1088 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1089 smbcli_close(cli->tree, fnum);
1090 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1091 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1094 if (w_time < 60*60*24*2) {
1095 printf("write time=%s", ctime(&w_time));
1096 printf("This system appears to set a initial 0 write time\n");
1101 smbcli_unlink(cli->tree, fname);
1104 /* check if the server updates the directory modification time
1105 when creating a new file */
1106 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1107 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
1111 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1112 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1116 fnum = smbcli_open(cli->tree, fname2,
1117 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1118 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
1119 smbcli_close(cli->tree, fnum);
1120 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
1121 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1124 if (m_time2 == m_time) {
1125 printf("This system does not update directory modification times\n");
1129 smbcli_unlink(cli->tree, fname2);
1130 smbcli_rmdir(cli->tree, dname);
1132 if (!torture_close_connection(cli)) {
1136 printf("trans2 test finished\n");
1143 /* FIRST_DESIRED_ACCESS 0xf019f */
1144 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1145 SEC_FILE_READ_EA| /* 0xf */ \
1146 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1147 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1148 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1149 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1150 /* SECOND_DESIRED_ACCESS 0xe0080 */
1151 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1152 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1153 SEC_STD_WRITE_OWNER /* 0xe0000 */
1156 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1157 READ_CONTROL|WRITE_DAC|\
1158 SEC_FILE_READ_DATA|\
1163 Test ntcreate calls made by xcopy
1165 static BOOL run_xcopy(void)
1167 struct smbcli_state *cli1;
1168 const char *fname = "\\test.txt";
1169 BOOL correct = True;
1172 printf("starting xcopy test\n");
1174 if (!torture_open_connection(&cli1)) {
1178 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1179 FIRST_DESIRED_ACCESS,
1180 FILE_ATTRIBUTE_ARCHIVE,
1181 NTCREATEX_SHARE_ACCESS_NONE,
1182 NTCREATEX_DISP_OVERWRITE_IF,
1186 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
1190 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1191 SECOND_DESIRED_ACCESS, 0,
1192 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1195 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
1199 if (!torture_close_connection(cli1)) {
1208 see how many RPC pipes we can open at once
1210 static BOOL run_pipe_number(void)
1212 struct smbcli_state *cli1;
1213 const char *pipe_name = "\\WKSSVC";
1217 printf("starting pipenumber test\n");
1218 if (!torture_open_connection(&cli1)) {
1223 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1224 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1227 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
1231 printf("%d\r", num_pipes);
1235 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
1236 torture_close_connection(cli1);
1244 open N connections to the server and just hold them open
1245 used for testing performance when there are N idle users
1248 static BOOL torture_holdcon(void)
1251 struct smbcli_state **cli;
1254 printf("Opening %d connections\n", torture_numops);
1256 cli = malloc_array_p(struct smbcli_state *, torture_numops);
1258 for (i=0;i<torture_numops;i++) {
1259 if (!torture_open_connection(&cli[i])) {
1262 printf("opened %d connections\r", i);
1266 printf("\nStarting pings\n");
1269 for (i=0;i<torture_numops;i++) {
1272 status = smbcli_chkpath(cli[i]->tree, "\\");
1273 if (!NT_STATUS_IS_OK(status)) {
1274 printf("Connection %d is dead\n", i);
1282 if (num_dead == torture_numops) {
1283 printf("All connections dead - finishing\n");
1295 Try with a wrong vuid and check error message.
1298 static BOOL run_vuidtest(void)
1300 struct smbcli_state *cli;
1301 const char *fname = "\\vuid.tst";
1304 time_t c_time, a_time, m_time;
1305 BOOL correct = True;
1310 printf("starting vuid test\n");
1312 if (!torture_open_connection(&cli)) {
1316 smbcli_unlink(cli->tree, fname);
1318 fnum = smbcli_open(cli->tree, fname,
1319 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1321 orig_vuid = cli->session->vuid;
1323 cli->session->vuid += 1234;
1325 printf("Testing qfileinfo with wrong vuid\n");
1327 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
1328 &size, &c_time, &a_time,
1329 &m_time, NULL, NULL))) {
1330 printf("ERROR: qfileinfo passed with wrong vuid\n");
1334 if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1335 NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
1336 !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1337 NT_STATUS_INVALID_HANDLE)) {
1338 printf("ERROR: qfileinfo should have returned DOS error "
1339 "ERRSRV:ERRbaduid\n but returned %s\n",
1340 smbcli_errstr(cli->tree));
1344 cli->session->vuid -= 1234;
1346 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1347 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
1351 smbcli_unlink(cli->tree, fname);
1353 if (!torture_close_connection(cli)) {
1357 printf("vuid test finished\n");
1363 Test open mode returns on read-only files.
1365 static BOOL run_opentest(void)
1367 static struct smbcli_state *cli1;
1368 static struct smbcli_state *cli2;
1369 const char *fname = "\\readonly.file";
1370 char *control_char_fname;
1374 BOOL correct = True;
1379 printf("starting open test\n");
1381 if (!torture_open_connection(&cli1)) {
1385 asprintf(&control_char_fname, "\\readonly.afile");
1386 for (i = 1; i <= 0x1f; i++) {
1387 control_char_fname[10] = i;
1388 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
1389 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1391 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
1392 NT_STATUS_OBJECT_NAME_INVALID)) {
1393 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
1394 smbcli_errstr(cli1->tree), i);
1399 smbcli_close(cli1->tree, fnum1);
1401 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
1402 smbcli_unlink(cli1->tree, control_char_fname);
1404 free(control_char_fname);
1407 printf("Create file with control char names passed.\n");
1409 smbcli_setatr(cli1->tree, fname, 0, 0);
1410 smbcli_unlink(cli1->tree, fname);
1412 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1414 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1418 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1419 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1423 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
1424 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
1425 CHECK_MAX_FAILURES(error_test1);
1429 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1431 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1432 CHECK_MAX_FAILURES(error_test1);
1436 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
1437 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1439 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
1440 NT_STATUS_ACCESS_DENIED)) {
1441 printf("correct error code ERRDOS/ERRnoaccess returned\n");
1444 printf("finished open test 1\n");
1446 smbcli_close(cli1->tree, fnum1);
1448 /* Now try not readonly and ensure ERRbadshare is returned. */
1450 smbcli_setatr(cli1->tree, fname, 0, 0);
1452 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1454 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1458 /* This will fail - but the error should be ERRshare. */
1459 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1461 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
1462 NT_STATUS_SHARING_VIOLATION)) {
1463 printf("correct error code ERRDOS/ERRbadshare returned\n");
1466 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1467 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1471 smbcli_unlink(cli1->tree, fname);
1473 printf("finished open test 2\n");
1475 /* Test truncate open disposition on file opened for read. */
1477 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1479 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1483 /* write 20 bytes. */
1485 memset(buf, '\0', 20);
1487 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1488 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1492 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1493 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1497 /* Ensure size == 20. */
1498 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1499 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1500 CHECK_MAX_FAILURES(error_test3);
1505 printf("(3) file size != 20\n");
1506 CHECK_MAX_FAILURES(error_test3);
1510 /* Now test if we can truncate a file opened for readonly. */
1512 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
1514 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1515 CHECK_MAX_FAILURES(error_test3);
1519 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1520 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1524 /* Ensure size == 0. */
1525 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1526 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1527 CHECK_MAX_FAILURES(error_test3);
1532 printf("(3) file size != 0\n");
1533 CHECK_MAX_FAILURES(error_test3);
1536 printf("finished open test 3\n");
1538 smbcli_unlink(cli1->tree, fname);
1541 printf("testing ctemp\n");
1542 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
1544 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1545 CHECK_MAX_FAILURES(error_test4);
1548 printf("ctemp gave path %s\n", tmp_path);
1549 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1550 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1552 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1553 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1556 /* Test the non-io opens... */
1558 if (!torture_open_connection(&cli2)) {
1562 smbcli_setatr(cli2->tree, fname, 0, 0);
1563 smbcli_unlink(cli2->tree, fname);
1565 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1567 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1568 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1571 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1572 CHECK_MAX_FAILURES(error_test10);
1576 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1577 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1579 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1580 CHECK_MAX_FAILURES(error_test10);
1584 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1585 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1588 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1589 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1593 printf("non-io open test #1 passed.\n");
1595 smbcli_unlink(cli1->tree, fname);
1597 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1599 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1600 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1603 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1604 CHECK_MAX_FAILURES(error_test20);
1608 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1609 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1612 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1613 CHECK_MAX_FAILURES(error_test20);
1617 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1618 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1621 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1622 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1626 printf("non-io open test #2 passed.\n");
1628 smbcli_unlink(cli1->tree, fname);
1630 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1632 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1633 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1636 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1637 CHECK_MAX_FAILURES(error_test30);
1641 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1642 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1645 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1646 CHECK_MAX_FAILURES(error_test30);
1650 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1651 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1654 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1655 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1659 printf("non-io open test #3 passed.\n");
1661 smbcli_unlink(cli1->tree, fname);
1663 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1665 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1666 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1669 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1670 CHECK_MAX_FAILURES(error_test40);
1674 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1675 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1678 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1679 CHECK_MAX_FAILURES(error_test40);
1683 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1685 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1686 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1690 printf("non-io open test #4 passed.\n");
1692 smbcli_unlink(cli1->tree, fname);
1694 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1696 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1697 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1700 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1701 CHECK_MAX_FAILURES(error_test50);
1705 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1706 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1709 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1710 CHECK_MAX_FAILURES(error_test50);
1714 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1715 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1719 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1720 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1724 printf("non-io open test #5 passed.\n");
1726 printf("TEST #6 testing 1 non-io open, one io open\n");
1728 smbcli_unlink(cli1->tree, fname);
1730 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1731 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1734 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1735 CHECK_MAX_FAILURES(error_test60);
1739 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1740 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1743 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1744 CHECK_MAX_FAILURES(error_test60);
1748 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1749 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1753 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1754 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1758 printf("non-io open test #6 passed.\n");
1760 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
1762 smbcli_unlink(cli1->tree, fname);
1764 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1765 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1768 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1769 CHECK_MAX_FAILURES(error_test70);
1773 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1774 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1777 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1778 CHECK_MAX_FAILURES(error_test70);
1782 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1784 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1785 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1789 printf("non-io open test #7 passed.\n");
1793 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1795 smbcli_unlink(cli1->tree, fname);
1797 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1799 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1803 /* write 20 bytes. */
1805 memset(buf, '\0', 20);
1807 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1808 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1812 /* Ensure size == 20. */
1813 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1814 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1815 CHECK_MAX_FAILURES(error_test80);
1820 printf("(8) file size != 20\n");
1821 CHECK_MAX_FAILURES(error_test80);
1825 /* Get an exclusive lock on the open file. */
1826 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1827 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1828 CHECK_MAX_FAILURES(error_test80);
1832 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1834 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1838 /* Ensure size == 0. */
1839 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1840 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1841 CHECK_MAX_FAILURES(error_test80);
1846 printf("(8) file size != 0\n");
1847 CHECK_MAX_FAILURES(error_test80);
1851 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1852 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1856 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1857 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1863 printf("open test #8 passed.\n");
1865 smbcli_unlink(cli1->tree, fname);
1867 if (!torture_close_connection(cli1)) {
1870 if (!torture_close_connection(cli2)) {
1879 sees what IOCTLs are supported
1881 BOOL torture_ioctl_test(void)
1883 struct smbcli_state *cli;
1884 uint16_t device, function;
1886 const char *fname = "\\ioctl.dat";
1888 union smb_ioctl parms;
1889 TALLOC_CTX *mem_ctx;
1891 if (!torture_open_connection(&cli)) {
1895 mem_ctx = talloc_init("ioctl_test");
1897 printf("starting ioctl test\n");
1899 smbcli_unlink(cli->tree, fname);
1901 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1903 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1907 parms.ioctl.level = RAW_IOCTL_IOCTL;
1908 parms.ioctl.in.fnum = fnum;
1909 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
1910 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1911 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
1913 for (device=0;device<0x100;device++) {
1914 printf("testing device=0x%x\n", device);
1915 for (function=0;function<0x100;function++) {
1916 parms.ioctl.in.request = (device << 16) | function;
1917 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1919 if (NT_STATUS_IS_OK(status)) {
1920 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
1921 device, function, (int)parms.ioctl.out.blob.length);
1926 if (!torture_close_connection(cli)) {
1935 tries variants of chkpath
1937 BOOL torture_chkpath_test(void)
1939 struct smbcli_state *cli;
1943 if (!torture_open_connection(&cli)) {
1947 printf("starting chkpath test\n");
1949 printf("Testing valid and invalid paths\n");
1951 /* cleanup from an old run */
1952 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1953 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1954 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1956 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1957 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1961 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1962 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1966 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1968 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
1971 smbcli_close(cli->tree, fnum);
1973 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1974 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1978 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1979 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1983 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1984 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1985 NT_STATUS_NOT_A_DIRECTORY);
1987 printf("* chkpath on a file should fail\n");
1991 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
1992 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1993 NT_STATUS_OBJECT_NAME_NOT_FOUND);
1995 printf("* chkpath on a non existent file should fail\n");
1999 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
2000 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2001 NT_STATUS_OBJECT_PATH_NOT_FOUND);
2003 printf("* chkpath on a non existent component should fail\n");
2007 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
2008 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
2009 smbcli_rmdir(cli->tree, "\\chkpath.dir");
2011 if (!torture_close_connection(cli)) {
2019 static void sigcont(int sig)
2023 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
2026 volatile pid_t *child_status;
2027 volatile BOOL *child_status_out;
2030 double start_time_limit = 10 + (torture_nprocs * 1.5);
2031 char **unc_list = NULL;
2033 int num_unc_names = 0;
2040 signal(SIGCONT, sigcont);
2042 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
2043 if (!child_status) {
2044 printf("Failed to setup shared memory\n");
2048 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
2049 if (!child_status_out) {
2050 printf("Failed to setup result status shared memory\n");
2054 p = lp_parm_string(-1, "torture", "unclist");
2056 unc_list = file_lines_load(p, &num_unc_names, NULL);
2057 if (!unc_list || num_unc_names <= 0) {
2058 printf("Failed to load unc names list from '%s'\n", p);
2063 for (i = 0; i < torture_nprocs; i++) {
2064 child_status[i] = 0;
2065 child_status_out[i] = True;
2068 tv = timeval_current();
2070 for (i=0;i<torture_nprocs;i++) {
2074 const char *hostname=NULL, *sharename;
2076 pid_t mypid = getpid();
2077 srandom(((int)mypid) ^ ((int)time(NULL)));
2079 asprintf(&myname, "CLIENT%d", i);
2080 lp_set_cmdline("netbios name", myname);
2085 if (!smbcli_parse_unc(unc_list[i % num_unc_names],
2086 NULL, &hostname, &sharename)) {
2087 printf("Failed to parse UNC name %s\n",
2088 unc_list[i % num_unc_names]);
2095 if (torture_open_connection_share(NULL,
2102 } else if (torture_open_connection(¤t_cli)) {
2106 printf("pid %d failed to start\n", (int)getpid());
2112 child_status[i] = getpid();
2116 if (child_status[i]) {
2117 printf("Child %d failed to start!\n", i);
2118 child_status_out[i] = 1;
2122 child_status_out[i] = fn(current_cli, i);
2129 for (i=0;i<torture_nprocs;i++) {
2130 if (child_status[i]) synccount++;
2132 if (synccount == torture_nprocs) break;
2134 } while (timeval_elapsed(&tv) < start_time_limit);
2136 if (synccount != torture_nprocs) {
2137 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
2139 return timeval_elapsed(&tv);
2142 printf("Starting %d clients\n", torture_nprocs);
2144 /* start the client load */
2145 tv = timeval_current();
2146 for (i=0;i<torture_nprocs;i++) {
2147 child_status[i] = 0;
2150 printf("%d clients started\n", torture_nprocs);
2154 for (i=0;i<torture_nprocs;i++) {
2156 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
2157 if (ret == -1 || WEXITSTATUS(status) != 0) {
2164 for (i=0;i<torture_nprocs;i++) {
2165 if (!child_status_out[i]) {
2169 return timeval_elapsed(&tv);
2172 #define FLAG_MULTIPROC 1
2177 BOOL (*multi_fn)(struct smbcli_state *, int );
2180 {"BASE-FDPASS", run_fdpasstest, 0},
2181 {"BASE-LOCK1", torture_locktest1, 0},
2182 {"BASE-LOCK2", torture_locktest2, 0},
2183 {"BASE-LOCK3", torture_locktest3, 0},
2184 {"BASE-LOCK4", torture_locktest4, 0},
2185 {"BASE-LOCK5", torture_locktest5, 0},
2186 {"BASE-LOCK6", torture_locktest6, 0},
2187 {"BASE-LOCK7", torture_locktest7, 0},
2188 {"BASE-UNLINK", torture_unlinktest, 0},
2189 {"BASE-ATTR", run_attrtest, 0},
2190 {"BASE-TRANS2", run_trans2test, 0},
2191 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
2192 {"BASE-DIR1", torture_dirtest1, 0},
2193 {"BASE-DIR2", torture_dirtest2, 0},
2194 {"BASE-DENY1", torture_denytest1, 0},
2195 {"BASE-DENY2", torture_denytest2, 0},
2196 {"BASE-DENY3", torture_denytest3, 0},
2197 {"BASE-DENYDOS", torture_denydos_sharing, 0},
2198 {"BASE-NTDENY1", NULL, torture_ntdenytest1},
2199 {"BASE-NTDENY2", torture_ntdenytest2, 0},
2200 {"BASE-TCON", run_tcon_test, 0},
2201 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
2202 {"BASE-VUID", run_vuidtest, 0},
2203 {"BASE-RW1", run_readwritetest, 0},
2204 {"BASE-OPEN", run_opentest, 0},
2205 {"BASE-DEFER_OPEN", NULL, run_deferopen},
2206 {"BASE-XCOPY", run_xcopy, 0},
2207 {"BASE-RENAME", torture_test_rename, 0},
2208 {"BASE-DELETE", torture_test_delete, 0},
2209 {"BASE-PROPERTIES", torture_test_properties, 0},
2210 {"BASE-MANGLE", torture_mangle, 0},
2211 {"BASE-OPENATTR", torture_openattrtest, 0},
2212 {"BASE-CHARSET", torture_charset, 0},
2213 {"BASE-CHKPATH", torture_chkpath_test, 0},
2214 {"BASE-SECLEAK", torture_sec_leak, 0},
2215 {"BASE-DISCONNECT", torture_disconnect, 0},
2216 {"BASE-DELAYWRITE", torture_delay_write, 0},
2218 /* benchmarking tests */
2219 {"BENCH-HOLDCON", torture_holdcon, 0},
2220 {"BENCH-NBENCH", torture_nbench, 0},
2221 {"BENCH-TORTURE", NULL, run_torture},
2222 {"BENCH-NBT", torture_bench_nbt, 0},
2223 {"BENCH-WINS", torture_bench_wins, 0},
2224 {"BENCH-RPC", torture_bench_rpc, 0},
2225 {"BENCH-CLDAP", torture_bench_cldap, 0},
2228 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
2229 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
2230 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
2231 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
2232 {"RAW-SEARCH", torture_raw_search, 0},
2233 {"RAW-CLOSE", torture_raw_close, 0},
2234 {"RAW-OPEN", torture_raw_open, 0},
2235 {"RAW-MKDIR", torture_raw_mkdir, 0},
2236 {"RAW-OPLOCK", torture_raw_oplock, 0},
2237 {"RAW-NOTIFY", torture_raw_notify, 0},
2238 {"RAW-MUX", torture_raw_mux, 0},
2239 {"RAW-IOCTL", torture_raw_ioctl, 0},
2240 {"RAW-CHKPATH", torture_raw_chkpath, 0},
2241 {"RAW-UNLINK", torture_raw_unlink, 0},
2242 {"RAW-READ", torture_raw_read, 0},
2243 {"RAW-WRITE", torture_raw_write, 0},
2244 {"RAW-LOCK", torture_raw_lock, 0},
2245 {"RAW-CONTEXT", torture_raw_context, 0},
2246 {"RAW-RENAME", torture_raw_rename, 0},
2247 {"RAW-SEEK", torture_raw_seek, 0},
2248 {"RAW-EAS", torture_raw_eas, 0},
2249 {"RAW-EAMAX", torture_max_eas, 0},
2250 {"RAW-STREAMS", torture_raw_streams, 0},
2251 {"RAW-ACLS", torture_raw_acls, 0},
2252 {"RAW-RAP", torture_raw_rap, 0},
2253 {"RAW-COMPOSITE", torture_raw_composite, 0},
2256 {"SMB2-CONNECT", torture_smb2_connect, 0},
2257 {"SMB2-SCAN", torture_smb2_scan, 0},
2258 {"SMB2-SCANGETINFO", torture_smb2_getinfo_scan, 0},
2259 {"SMB2-SCANSETINFO", torture_smb2_setinfo_scan, 0},
2260 {"SMB2-SCANFIND", torture_smb2_find_scan, 0},
2261 {"SMB2-GETINFO", torture_smb2_getinfo, 0},
2262 {"SMB2-SETINFO", torture_smb2_setinfo, 0},
2263 {"SMB2-FIND", torture_smb2_find, 0},
2265 /* protocol scanners */
2266 {"SCAN-TRANS2", torture_trans2_scan, 0},
2267 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2268 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2269 {"SCAN-SMB", torture_smb_scan, 0},
2270 {"SCAN-MAXFID", NULL, run_maxfidtest},
2271 {"SCAN-UTABLE", torture_utable, 0},
2272 {"SCAN-CASETABLE", torture_casetable, 0},
2273 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2274 {"SCAN-IOCTL", torture_ioctl_test, 0},
2275 {"SCAN-RAP", torture_rap_scan, 0},
2278 {"RPC-LSA", torture_rpc_lsa, 0},
2279 {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
2280 {"RPC-ECHO", torture_rpc_echo, 0},
2281 {"RPC-DFS", torture_rpc_dfs, 0},
2282 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2283 {"RPC-SAMR", torture_rpc_samr, 0},
2284 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2285 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2286 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2287 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2288 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2289 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2290 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2291 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2292 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2293 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2294 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2295 {"RPC-WINREG", torture_rpc_winreg, 0},
2296 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2297 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2298 {"RPC-REMACT", torture_rpc_remact, 0},
2299 {"RPC-MGMT", torture_rpc_mgmt, 0},
2300 {"RPC-SCANNER", torture_rpc_scanner, 0},
2301 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2302 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2303 {"RPC-MULTIBIND", torture_multi_bind, 0},
2304 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2305 {"RPC-CRACKNAMES", torture_rpc_drsuapi_cracknames, 0},
2306 {"RPC-ROT", torture_rpc_rot, 0},
2307 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2308 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2309 {"RPC-JOIN", torture_rpc_join, 0},
2310 {"RPC-DSSYNC", torture_rpc_dssync, 0},
2312 /* local (no server) testers */
2313 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2314 {"LOCAL-ICONV", torture_local_iconv, 0},
2315 {"LOCAL-TALLOC", torture_local_talloc, 0},
2316 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2317 {"LOCAL-IRPC", torture_local_irpc, 0},
2318 {"LOCAL-BINDING", torture_local_binding_string, 0},
2319 {"LOCAL-STRLIST", torture_local_util_strlist, 0},
2320 {"LOCAL-FILE", torture_local_util_file, 0},
2321 {"LOCAL-IDTREE", torture_local_idtree, 0},
2322 {"LOCAL-SOCKET", torture_local_socket, 0},
2323 {"LOCAL-PAC", torture_pac, 0},
2324 {"LOCAL-REGISTRY", torture_registry, 0},
2325 {"LOCAL-RESOLVE", torture_local_resolve, 0},
2326 {"LOCAL-SDDL", torture_local_sddl, 0},
2328 /* COM (Component Object Model) testers */
2329 {"COM-SIMPLE", torture_com_simple, 0 },
2332 {"LDAP-BASIC", torture_ldap_basic, 0},
2333 {"LDAP-CLDAP", torture_cldap, 0},
2336 {"NBT-REGISTER", torture_nbt_register, 0},
2337 {"NBT-WINS", torture_nbt_wins, 0},
2338 {"NBT-DGRAM", torture_nbt_dgram, 0},
2339 {"NBT-WINSREPLICATION", torture_nbt_winsreplication, 0},
2342 {"NET-USERINFO", torture_userinfo, 0},
2343 {"NET-USERADD", torture_useradd, 0},
2344 {"NET-USERDEL", torture_userdel, 0},
2345 {"NET-USERMOD", torture_usermod, 0},
2346 {"NET-DOMOPEN", torture_domainopen, 0},
2347 {"NET-API-LOOKUP", torture_lookup, 0},
2348 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2349 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2350 {"NET-API-CREATEUSER", torture_createuser, 0},
2351 {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
2352 {"NET-API-LISTSHARES", torture_listshares, 0},
2353 {"NET-API-DELSHARE", torture_delshare, 0},
2359 /****************************************************************************
2360 run a specified test or "ALL"
2361 ****************************************************************************/
2362 static BOOL run_test(const char *name)
2366 BOOL matched = False;
2368 if (strequal(name,"ALL")) {
2369 for (i=0;torture_ops[i].name;i++) {
2370 if (!run_test(torture_ops[i].name)) {
2377 for (i=0;torture_ops[i].name;i++) {
2378 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
2382 printf("Running %s\n", torture_ops[i].name);
2383 if (torture_ops[i].multi_fn) {
2384 BOOL result = False;
2385 t = torture_create_procs(torture_ops[i].multi_fn,
2389 printf("TEST %s FAILED!\n", torture_ops[i].name);
2393 struct timeval tv = timeval_current();
2394 if (!torture_ops[i].fn()) {
2396 printf("TEST %s FAILED!\n", torture_ops[i].name);
2398 t = timeval_elapsed(&tv);
2400 printf("%s took %g secs\n\n", torture_ops[i].name, t);
2405 printf("Unknown torture operation '%s'\n", name);
2412 static void parse_dns(const char *dns)
2414 char *userdn, *basedn, *secret;
2417 /* retrievieng the userdn */
2418 p = strchr_m(dns, '#');
2420 lp_set_cmdline("torture:ldap_userdn", "");
2421 lp_set_cmdline("torture:ldap_basedn", "");
2422 lp_set_cmdline("torture:ldap_secret", "");
2425 userdn = strndup(dns, p - dns);
2426 lp_set_cmdline("torture:ldap_userdn", userdn);
2428 /* retrieve the basedn */
2430 p = strchr_m(d, '#');
2432 lp_set_cmdline("torture:ldap_basedn", "");
2433 lp_set_cmdline("torture:ldap_secret", "");
2436 basedn = strndup(d, p - d);
2437 lp_set_cmdline("torture:ldap_basedn", basedn);
2439 /* retrieve the secret */
2442 lp_set_cmdline("torture:ldap_secret", "");
2446 lp_set_cmdline("torture:ldap_secret", secret);
2448 printf ("%s - %s - %s\n", userdn, basedn, secret);
2452 static void usage(poptContext pc)
2457 poptPrintUsage(pc, stdout, 0);
2460 printf("The binding format is:\n\n");
2462 printf(" TRANSPORT:host[flags]\n\n");
2464 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2466 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2467 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2468 printf(" string.\n\n");
2470 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2471 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2472 printf(" will be auto-determined.\n\n");
2474 printf(" other recognised flags are:\n\n");
2476 printf(" sign : enable ntlmssp signing\n");
2477 printf(" seal : enable ntlmssp sealing\n");
2478 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2479 printf(" validate: enable the NDR validator\n");
2480 printf(" print: enable debugging of the packets\n");
2481 printf(" bigendian: use bigendian RPC\n");
2482 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2484 printf(" For example, these all connect to the samr pipe:\n\n");
2486 printf(" ncacn_np:myserver\n");
2487 printf(" ncacn_np:myserver[samr]\n");
2488 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2489 printf(" ncacn_np:myserver[/pipe/samr]\n");
2490 printf(" ncacn_np:myserver[samr,sign,print]\n");
2491 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2492 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2493 printf(" ncacn_np:\n");
2494 printf(" ncacn_np:[/pipe/samr]\n\n");
2496 printf(" ncacn_ip_tcp:myserver\n");
2497 printf(" ncacn_ip_tcp:myserver[1024]\n");
2498 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2500 printf("The unc format is:\n\n");
2502 printf(" //server/share\n\n");
2504 printf("tests are:");
2505 for (i=0;torture_ops[i].name;i++) {
2506 if ((i%perline)==0) {
2509 printf("%s ", torture_ops[i].name);
2513 printf("default test is ALL\n");
2518 static BOOL is_binding_string(const char *binding_string)
2520 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2521 struct dcerpc_binding *binding_struct;
2524 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2526 talloc_free(mem_ctx);
2527 return NT_STATUS_IS_OK(status);
2530 static void max_runtime_handler(int sig)
2532 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2536 /****************************************************************************
2538 ****************************************************************************/
2539 int main(int argc,char *argv[])
2543 BOOL correct = True;
2548 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,OPT_DANGEROUS};
2549 struct poptOption long_options[] = {
2551 {"smb-ports", 'p', POPT_ARG_STRING, NULL, 0, "SMB ports", NULL},
2552 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2553 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2554 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2555 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2556 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2557 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2558 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2559 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2560 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2561 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2562 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2563 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2564 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2565 "set maximum time for smbtorture to live", "seconds"},
2567 POPT_COMMON_CONNECTION
2568 POPT_COMMON_CREDENTIALS
2573 #ifdef HAVE_SETBUFFER
2574 setbuffer(stdout, NULL, 0);
2577 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2578 POPT_CONTEXT_KEEP_FIRST);
2580 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2582 while((opt = poptGetNextOpt(pc)) != -1) {
2585 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2588 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2591 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2594 parse_dns(poptGetOptArg(pc));
2597 lp_set_cmdline("torture:dangerous", "Yes");
2600 d_printf("Invalid option %s: %s\n",
2601 poptBadOption(pc, 0), poptStrerror(opt));
2608 /* this will only work if nobody else uses alarm(),
2609 which means it won't work for some tests, but we
2610 can't use the event context method we use for smbd
2611 as so many tests create their own event
2612 context. This will at least catch most cases. */
2613 signal(SIGALRM, max_runtime_handler);
2617 smbtorture_init_subsystems;
2620 if (torture_seed == 0) {
2621 torture_seed = time(NULL);
2623 printf("Using seed %d\n", torture_seed);
2624 srandom(torture_seed);
2626 argv_new = discard_const_p(char *, poptGetArgs(pc));
2629 for (i=0; i<argc; i++) {
2630 if (argv_new[i] == NULL) {
2641 for(p = argv_new[1]; *p; p++) {
2646 /* see if its a RPC transport specifier */
2647 if (is_binding_string(argv_new[1])) {
2648 lp_set_cmdline("torture:binding", argv_new[1]);
2650 char *binding = NULL;
2651 const char *host = NULL, *share = NULL;
2653 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
2654 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
2658 lp_set_cmdline("torture:host", host);
2659 lp_set_cmdline("torture:share", share);
2660 asprintf(&binding, "ncacn_np:%s", host);
2661 lp_set_cmdline("torture:binding", binding);
2664 if (argc_new == 0) {
2665 printf("You must specify a test to run, or 'ALL'\n");
2667 for (i=2;i<argc_new;i++) {
2668 if (!run_test(argv_new[i])) {