2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "lib/cmdline/popt_common.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "system/time.h"
25 #include "system/wait.h"
26 #include "system/filesys.h"
30 int torture_numops=10;
31 int torture_entries=1000;
32 int torture_failures=1;
34 static int procnum; /* records process count number when forking */
35 static struct smbcli_state *current_cli;
36 static BOOL use_oplocks;
37 static BOOL use_level_II_oplocks;
39 BOOL torture_showall = False;
41 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
43 static struct smbcli_state *open_nbt_connection(void)
45 struct nbt_name called, calling;
46 struct smbcli_state *cli;
47 const char *host = lp_parm_string(-1, "torture", "host");
49 make_nbt_name_client(&calling, lp_netbios_name());
51 nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
53 cli = smbcli_state_init(NULL);
55 printf("Failed initialize smbcli_struct to connect with %s\n", host);
59 if (!smbcli_socket_connect(cli, host)) {
60 printf("Failed to connect with %s\n", host);
64 if (!smbcli_transport_establish(cli, &calling, &called)) {
65 printf("%s rejected the session\n",host);
76 BOOL torture_open_connection_share(TALLOC_CTX *mem_ctx,
77 struct smbcli_state **c,
79 const char *sharename,
80 struct event_context *ev)
84 status = smbcli_full_connection(mem_ctx, c, hostname,
86 cmdline_credentials, ev);
87 if (!NT_STATUS_IS_OK(status)) {
88 printf("Failed to open connection - %s\n", nt_errstr(status));
92 (*c)->transport->options.use_oplocks = use_oplocks;
93 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
98 BOOL torture_open_connection(struct smbcli_state **c)
100 const char *host = lp_parm_string(-1, "torture", "host");
101 const char *share = lp_parm_string(-1, "torture", "share");
103 return torture_open_connection_share(NULL, c, host, share, NULL);
108 BOOL torture_close_connection(struct smbcli_state *c)
112 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
113 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
120 /* open a rpc connection to the chosen binding string */
121 NTSTATUS torture_rpc_connection(TALLOC_CTX *parent_ctx,
122 struct dcerpc_pipe **p,
123 const struct dcerpc_interface_table *table)
126 const char *binding = lp_parm_string(-1, "torture", "binding");
129 printf("You must specify a ncacn binding string\n");
130 return NT_STATUS_INVALID_PARAMETER;
133 status = dcerpc_pipe_connect(parent_ctx,
135 cmdline_credentials, NULL);
140 /* open a rpc connection to a specific transport */
141 NTSTATUS torture_rpc_connection_transport(TALLOC_CTX *parent_ctx,
142 struct dcerpc_pipe **p,
143 const struct dcerpc_interface_table *table,
144 enum dcerpc_transport_t transport)
147 const char *binding = lp_parm_string(-1, "torture", "binding");
148 struct dcerpc_binding *b;
149 TALLOC_CTX *mem_ctx = talloc_named(parent_ctx, 0, "torture_rpc_connection_smb");
152 printf("You must specify a ncacn binding string\n");
153 talloc_free(mem_ctx);
154 return NT_STATUS_INVALID_PARAMETER;
157 status = dcerpc_parse_binding(mem_ctx, binding, &b);
158 if (!NT_STATUS_IS_OK(status)) {
159 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
160 talloc_free(mem_ctx);
164 b->transport = transport;
166 status = dcerpc_pipe_connect_b(mem_ctx, p, b, table,
167 cmdline_credentials, NULL);
169 if (NT_STATUS_IS_OK(status)) {
170 *p = talloc_reference(parent_ctx, *p);
174 talloc_free(mem_ctx);
178 /* check if the server produced the expected error code */
179 BOOL check_error(const char *location, struct smbcli_state *c,
180 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
184 status = smbcli_nt_error(c->tree);
185 if (NT_STATUS_IS_DOS(status)) {
187 class = NT_STATUS_DOS_CLASS(status);
188 num = NT_STATUS_DOS_CODE(status);
189 if (eclass != class || ecode != num) {
190 printf("unexpected error code %s\n", nt_errstr(status));
191 printf(" expected %s or %s (at %s)\n",
192 nt_errstr(NT_STATUS_DOS(eclass, ecode)),
193 nt_errstr(nterr), location);
197 if (!NT_STATUS_EQUAL(nterr, status)) {
198 printf("unexpected error code %s\n", nt_errstr(status));
199 printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
208 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
210 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
211 if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
217 static BOOL rw_torture(struct smbcli_state *c)
219 const char *lockfname = "\\torture.lck";
223 pid_t pid2, pid = getpid();
228 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
231 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
233 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
238 for (i=0;i<torture_numops;i++) {
239 uint_t n = (uint_t)random()%10;
241 printf("%d\r", i); fflush(stdout);
243 asprintf(&fname, "\\torture.%u", n);
245 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
249 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
251 printf("open failed (%s)\n", smbcli_errstr(c->tree));
256 if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
257 printf("write failed (%s)\n", smbcli_errstr(c->tree));
262 if (smbcli_write(c->tree, fnum, 0, buf,
263 sizeof(pid)+(j*sizeof(buf)),
264 sizeof(buf)) != sizeof(buf)) {
265 printf("write failed (%s)\n", smbcli_errstr(c->tree));
272 if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
273 printf("read failed (%s)\n", smbcli_errstr(c->tree));
278 printf("data corruption!\n");
282 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
283 printf("close failed (%s)\n", smbcli_errstr(c->tree));
287 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
288 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
292 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
293 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
299 smbcli_close(c->tree, fnum2);
300 smbcli_unlink(c->tree, lockfname);
307 static BOOL run_torture(struct smbcli_state *cli, int dummy)
311 ret = rw_torture(cli);
313 if (!torture_close_connection(cli)) {
321 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
323 const char *lockfname = "\\torture2.lck";
328 uint8_t buf_rd[131072];
330 ssize_t bytes_read, bytes_written;
332 if (smbcli_deltree(c1->tree, lockfname) == -1) {
333 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
336 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
339 printf("first open read/write of %s failed (%s)\n",
340 lockfname, smbcli_errstr(c1->tree));
343 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
346 printf("second open read-only of %s failed (%s)\n",
347 lockfname, smbcli_errstr(c2->tree));
348 smbcli_close(c1->tree, fnum1);
352 printf("Checking data integrity over %d ops\n", torture_numops);
354 for (i=0;i<torture_numops;i++)
356 size_t buf_size = ((uint_t)random()%(sizeof(buf)-1))+ 1;
358 printf("%d\r", i); fflush(stdout);
361 generate_random_buffer(buf, buf_size);
363 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
364 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
365 printf("wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
370 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
371 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
372 printf("read %d, expected %d\n", (int)bytes_read, (int)buf_size);
377 if (memcmp(buf_rd, buf, buf_size) != 0)
379 printf("read/write compare failed\n");
385 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
386 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
389 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
390 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
394 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
395 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
402 #define BOOLSTR(b) ((b) ? "Yes" : "No")
404 static BOOL run_readwritetest(void)
406 struct smbcli_state *cli1, *cli2;
407 BOOL test1, test2 = True;
409 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
413 printf("starting readwritetest\n");
415 test1 = rw_torture2(cli1, cli2);
416 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
419 test2 = rw_torture2(cli1, cli1);
420 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
423 if (!torture_close_connection(cli1)) {
427 if (!torture_close_connection(cli2)) {
431 return (test1 && test2);
435 this checks to see if a secondary tconx can use open files from an
438 static BOOL run_tcon_test(void)
440 struct smbcli_state *cli;
441 const char *fname = "\\tcontest.tmp";
443 uint16_t cnum1, cnum2, cnum3;
444 uint16_t vuid1, vuid2;
447 struct smbcli_tree *tree1;
448 const char *host = lp_parm_string(-1, "torture", "host");
449 const char *share = lp_parm_string(-1, "torture", "share");
450 const char *password = lp_parm_string(-1, "torture", "password");
452 if (!torture_open_connection(&cli)) {
456 printf("starting tcontest\n");
458 if (smbcli_deltree(cli->tree, fname) == -1) {
459 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
462 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
464 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
468 cnum1 = cli->tree->tid;
469 vuid1 = cli->session->vuid;
471 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
472 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
473 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
477 tree1 = cli->tree; /* save old tree connection */
478 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
479 printf("%s refused 2nd tree connect (%s)\n", host,
480 smbcli_errstr(cli->tree));
485 cnum2 = cli->tree->tid;
486 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
487 vuid2 = cli->session->vuid + 1;
489 /* try a write with the wrong tid */
490 cli->tree->tid = cnum2;
492 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
493 printf("* server allows write with wrong TID\n");
496 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
500 /* try a write with an invalid tid */
501 cli->tree->tid = cnum3;
503 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
504 printf("* server allows write with invalid TID\n");
507 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
510 /* try a write with an invalid vuid */
511 cli->session->vuid = vuid2;
512 cli->tree->tid = cnum1;
514 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
515 printf("* server allows write with invalid VUID\n");
518 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
521 cli->session->vuid = vuid1;
522 cli->tree->tid = cnum1;
524 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
525 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
529 cli->tree->tid = cnum2;
531 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
532 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
536 cli->tree = tree1; /* restore initial tree */
537 cli->tree->tid = cnum1;
539 smbcli_unlink(tree1, fname);
541 if (!torture_close_connection(cli)) {
550 static BOOL tcon_devtest(struct smbcli_state *cli,
551 const char *myshare, const char *devtype,
552 NTSTATUS expected_error)
556 const char *password = lp_parm_string(-1, "torture", "password");
558 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
561 printf("Trying share %s with devtype %s\n", myshare, devtype);
563 if (NT_STATUS_IS_OK(expected_error)) {
567 printf("tconX to share %s with type %s "
568 "should have succeeded but failed\n",
575 printf("tconx to share %s with type %s "
576 "should have failed but succeeded\n",
580 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
584 printf("Returned unexpected error\n");
593 checks for correct tconX support
595 static BOOL run_tcon_devtype_test(void)
597 struct smbcli_state *cli1 = NULL;
600 const char *host = lp_parm_string(-1, "torture", "host");
601 const char *share = lp_parm_string(-1, "torture", "share");
603 status = smbcli_full_connection(NULL,
606 cmdline_credentials, NULL);
608 if (!NT_STATUS_IS_OK(status)) {
609 printf("could not open connection\n");
613 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
616 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
619 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
622 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
625 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
628 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
631 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
634 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
637 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
640 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
646 printf("Passed tcondevtest\n");
653 test whether fnums and tids open on one VC are available on another (a major
656 static BOOL run_fdpasstest(void)
658 struct smbcli_state *cli1, *cli2;
659 const char *fname = "\\fdpass.tst";
663 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
667 printf("starting fdpasstest\n");
669 smbcli_unlink(cli1->tree, fname);
671 printf("Opening a file on connection 1\n");
673 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
675 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
679 printf("writing to file on connection 1\n");
681 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
682 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
686 oldtid = cli2->tree->tid;
687 cli2->session->vuid = cli1->session->vuid;
688 cli2->tree->tid = cli1->tree->tid;
689 cli2->session->pid = cli1->session->pid;
691 printf("reading from file on connection 2\n");
693 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
694 printf("read succeeded! nasty security hole [%s]\n",
699 smbcli_close(cli1->tree, fnum1);
700 smbcli_unlink(cli1->tree, fname);
702 cli2->tree->tid = oldtid;
704 torture_close_connection(cli1);
705 torture_close_connection(cli2);
707 printf("finished fdpasstest\n");
713 test the timing of deferred open requests
715 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
717 const char *fname = "\\defer_open_test.dat";
723 printf("failed to connect\n");
727 printf("Testing deferred open requests.\n");
734 tv = timeval_current();
735 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
737 FILE_ATTRIBUTE_NORMAL,
738 NTCREATEX_SHARE_ACCESS_NONE,
739 NTCREATEX_DISP_OPEN_IF, 0, 0);
743 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
744 double e = timeval_elapsed(&tv);
745 if (e < 0.5 || e > 1.5) {
746 fprintf(stderr,"Timing incorrect %.2f violation\n",
750 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
753 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
757 printf("pid %u open %d\n", getpid(), i);
761 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
762 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
768 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
769 /* All until the last unlink will fail with sharing violation. */
770 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
771 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
776 printf("deferred test finished\n");
777 if (!torture_close_connection(cli)) {
784 test how many open files this server supports on the one socket
786 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
788 #define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
790 int fnums[0x11000], i;
791 int retries=4, maxfid;
795 printf("failed to connect\n");
799 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
800 printf("Failed to deltree \\maxfid - %s\n",
801 smbcli_errstr(cli->tree));
804 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
805 printf("Failed to mkdir \\maxfid, error=%s\n",
806 smbcli_errstr(cli->tree));
810 printf("Testing maximum number of open files\n");
812 for (i=0; i<0x11000; i++) {
814 asprintf(&fname, "\\maxfid\\fid%d", i/1000);
815 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
816 printf("Failed to mkdir %s, error=%s\n",
817 fname, smbcli_errstr(cli->tree));
822 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
823 if ((fnums[i] = smbcli_open(cli->tree, fname,
824 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
826 printf("open of %s failed (%s)\n",
827 fname, smbcli_errstr(cli->tree));
828 printf("maximum fnum is %d\n", i);
839 printf("cleaning up\n");
840 for (i=0;i<maxfid/2;i++) {
841 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
842 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
843 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
845 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
846 printf("unlink of %s failed (%s)\n",
847 fname, smbcli_errstr(cli->tree));
852 asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
853 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
854 printf("Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
856 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
857 printf("unlink of %s failed (%s)\n",
858 fname, smbcli_errstr(cli->tree));
863 printf("%6d %6d\r", i, maxfid-i);
867 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
868 printf("Failed to deltree \\maxfid - %s\n",
869 smbcli_errstr(cli->tree));
873 printf("maxfid test finished\n");
874 if (!torture_close_connection(cli)) {
878 #undef MAXFID_TEMPLATE
881 /* send smb negprot commands, not reading the response */
882 static BOOL run_negprot_nowait(void)
885 struct smbcli_state *cli, *cli2;
888 printf("starting negprot nowait test\n");
890 cli = open_nbt_connection();
895 printf("Filling send buffer\n");
897 for (i=0;i<1000;i++) {
898 struct smbcli_request *req;
899 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
900 smbcli_transport_process(cli->transport);
901 if (req->state == SMBCLI_REQUEST_ERROR) {
902 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
903 torture_close_connection(cli);
908 printf("Opening secondary connection\n");
909 if (!torture_open_connection(&cli2)) {
913 if (!torture_close_connection(cli)) {
917 if (!torture_close_connection(cli2)) {
921 printf("finished negprot nowait test\n");
928 This checks how the getatr calls works
930 static BOOL run_attrtest(void)
932 struct smbcli_state *cli;
935 const char *fname = "\\attrib123456789.tst";
938 printf("starting attrib test\n");
940 if (!torture_open_connection(&cli)) {
944 smbcli_unlink(cli->tree, fname);
945 fnum = smbcli_open(cli->tree, fname,
946 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
947 smbcli_close(cli->tree, fnum);
949 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
950 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
954 printf("New file time is %s", ctime(&t));
956 if (abs(t - time(NULL)) > 60*60*24*10) {
957 printf("ERROR: SMBgetatr bug. time is %s",
963 t2 = t-60*60*24; /* 1 day ago */
965 printf("Setting file time to %s", ctime(&t2));
967 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
968 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
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("Retrieved file time as %s", ctime(&t));
980 printf("ERROR: getatr/setatr bug. times are\n%s",
982 printf("%s", ctime(&t2));
986 smbcli_unlink(cli->tree, fname);
988 if (!torture_close_connection(cli)) {
992 printf("attrib test finished\n");
999 This checks a couple of trans2 calls
1001 static BOOL run_trans2test(void)
1003 struct smbcli_state *cli;
1006 time_t c_time, a_time, m_time, w_time, m_time2;
1007 const char *fname = "\\trans2.tst";
1008 const char *dname = "\\trans2";
1009 const char *fname2 = "\\trans2\\trans2.tst";
1011 BOOL correct = True;
1013 printf("starting trans2 test\n");
1015 if (!torture_open_connection(&cli)) {
1019 smbcli_unlink(cli->tree, fname);
1021 printf("Testing qfileinfo\n");
1023 fnum = smbcli_open(cli->tree, fname,
1024 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1025 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
1027 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
1031 printf("Testing NAME_INFO\n");
1033 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
1034 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
1038 if (!pname || strcmp(pname, fname)) {
1039 printf("qfilename gave different name? [%s] [%s]\n",
1044 smbcli_close(cli->tree, fnum);
1045 smbcli_unlink(cli->tree, fname);
1047 fnum = smbcli_open(cli->tree, fname,
1048 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1050 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1053 smbcli_close(cli->tree, fnum);
1055 printf("Checking for sticky create times\n");
1057 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1058 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
1061 if (c_time != m_time) {
1062 printf("create time=%s", ctime(&c_time));
1063 printf("modify time=%s", ctime(&m_time));
1064 printf("This system appears to have sticky create times\n");
1066 if (a_time % (60*60) == 0) {
1067 printf("access time=%s", ctime(&a_time));
1068 printf("This system appears to set a midnight access time\n");
1072 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1073 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1079 smbcli_unlink(cli->tree, fname);
1080 fnum = smbcli_open(cli->tree, fname,
1081 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1082 smbcli_close(cli->tree, fnum);
1083 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1084 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1087 if (w_time < 60*60*24*2) {
1088 printf("write time=%s", ctime(&w_time));
1089 printf("This system appears to set a initial 0 write time\n");
1094 smbcli_unlink(cli->tree, fname);
1097 /* check if the server updates the directory modification time
1098 when creating a new file */
1099 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1100 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
1104 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1105 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1109 fnum = smbcli_open(cli->tree, fname2,
1110 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1111 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
1112 smbcli_close(cli->tree, fnum);
1113 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
1114 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1117 if (m_time2 == m_time) {
1118 printf("This system does not update directory modification times\n");
1122 smbcli_unlink(cli->tree, fname2);
1123 smbcli_rmdir(cli->tree, dname);
1125 if (!torture_close_connection(cli)) {
1129 printf("trans2 test finished\n");
1136 /* FIRST_DESIRED_ACCESS 0xf019f */
1137 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1138 SEC_FILE_READ_EA| /* 0xf */ \
1139 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1140 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1141 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1142 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1143 /* SECOND_DESIRED_ACCESS 0xe0080 */
1144 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1145 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1146 SEC_STD_WRITE_OWNER /* 0xe0000 */
1149 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1150 READ_CONTROL|WRITE_DAC|\
1151 SEC_FILE_READ_DATA|\
1156 Test ntcreate calls made by xcopy
1158 static BOOL run_xcopy(void)
1160 struct smbcli_state *cli1;
1161 const char *fname = "\\test.txt";
1162 BOOL correct = True;
1165 printf("starting xcopy test\n");
1167 if (!torture_open_connection(&cli1)) {
1171 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1172 FIRST_DESIRED_ACCESS,
1173 FILE_ATTRIBUTE_ARCHIVE,
1174 NTCREATEX_SHARE_ACCESS_NONE,
1175 NTCREATEX_DISP_OVERWRITE_IF,
1179 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
1183 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1184 SECOND_DESIRED_ACCESS, 0,
1185 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1188 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
1192 if (!torture_close_connection(cli1)) {
1201 see how many RPC pipes we can open at once
1203 static BOOL run_pipe_number(void)
1205 struct smbcli_state *cli1;
1206 const char *pipe_name = "\\WKSSVC";
1210 printf("starting pipenumber test\n");
1211 if (!torture_open_connection(&cli1)) {
1216 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1217 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1220 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
1224 printf("%d\r", num_pipes);
1228 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
1229 torture_close_connection(cli1);
1237 open N connections to the server and just hold them open
1238 used for testing performance when there are N idle users
1241 static BOOL torture_holdcon(void)
1244 struct smbcli_state **cli;
1247 printf("Opening %d connections\n", torture_numops);
1249 cli = malloc_array_p(struct smbcli_state *, torture_numops);
1251 for (i=0;i<torture_numops;i++) {
1252 if (!torture_open_connection(&cli[i])) {
1255 printf("opened %d connections\r", i);
1259 printf("\nStarting pings\n");
1262 for (i=0;i<torture_numops;i++) {
1265 status = smbcli_chkpath(cli[i]->tree, "\\");
1266 if (!NT_STATUS_IS_OK(status)) {
1267 printf("Connection %d is dead\n", i);
1275 if (num_dead == torture_numops) {
1276 printf("All connections dead - finishing\n");
1288 Try with a wrong vuid and check error message.
1291 static BOOL run_vuidtest(void)
1293 struct smbcli_state *cli;
1294 const char *fname = "\\vuid.tst";
1297 time_t c_time, a_time, m_time;
1298 BOOL correct = True;
1303 printf("starting vuid test\n");
1305 if (!torture_open_connection(&cli)) {
1309 smbcli_unlink(cli->tree, fname);
1311 fnum = smbcli_open(cli->tree, fname,
1312 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1314 orig_vuid = cli->session->vuid;
1316 cli->session->vuid += 1234;
1318 printf("Testing qfileinfo with wrong vuid\n");
1320 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
1321 &size, &c_time, &a_time,
1322 &m_time, NULL, NULL))) {
1323 printf("ERROR: qfileinfo passed with wrong vuid\n");
1327 if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1328 NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
1329 !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1330 NT_STATUS_INVALID_HANDLE)) {
1331 printf("ERROR: qfileinfo should have returned DOS error "
1332 "ERRSRV:ERRbaduid\n but returned %s\n",
1333 smbcli_errstr(cli->tree));
1337 cli->session->vuid -= 1234;
1339 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1340 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
1344 smbcli_unlink(cli->tree, fname);
1346 if (!torture_close_connection(cli)) {
1350 printf("vuid test finished\n");
1356 Test open mode returns on read-only files.
1358 static BOOL run_opentest(void)
1360 static struct smbcli_state *cli1;
1361 static struct smbcli_state *cli2;
1362 const char *fname = "\\readonly.file";
1363 char *control_char_fname;
1367 BOOL correct = True;
1372 printf("starting open test\n");
1374 if (!torture_open_connection(&cli1)) {
1378 asprintf(&control_char_fname, "\\readonly.afile");
1379 for (i = 1; i <= 0x1f; i++) {
1380 control_char_fname[10] = i;
1381 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
1382 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1384 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
1385 NT_STATUS_OBJECT_NAME_INVALID)) {
1386 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
1387 smbcli_errstr(cli1->tree), i);
1392 smbcli_close(cli1->tree, fnum1);
1394 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
1395 smbcli_unlink(cli1->tree, control_char_fname);
1397 free(control_char_fname);
1400 printf("Create file with control char names passed.\n");
1402 smbcli_setatr(cli1->tree, fname, 0, 0);
1403 smbcli_unlink(cli1->tree, fname);
1405 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1407 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1411 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1412 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1416 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
1417 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
1418 CHECK_MAX_FAILURES(error_test1);
1422 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1424 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1425 CHECK_MAX_FAILURES(error_test1);
1429 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
1430 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1432 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
1433 NT_STATUS_ACCESS_DENIED)) {
1434 printf("correct error code ERRDOS/ERRnoaccess returned\n");
1437 printf("finished open test 1\n");
1439 smbcli_close(cli1->tree, fnum1);
1441 /* Now try not readonly and ensure ERRbadshare is returned. */
1443 smbcli_setatr(cli1->tree, fname, 0, 0);
1445 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1447 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1451 /* This will fail - but the error should be ERRshare. */
1452 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1454 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
1455 NT_STATUS_SHARING_VIOLATION)) {
1456 printf("correct error code ERRDOS/ERRbadshare returned\n");
1459 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1460 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1464 smbcli_unlink(cli1->tree, fname);
1466 printf("finished open test 2\n");
1468 /* Test truncate open disposition on file opened for read. */
1470 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1472 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1476 /* write 20 bytes. */
1478 memset(buf, '\0', 20);
1480 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1481 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1485 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1486 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1490 /* Ensure size == 20. */
1491 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1492 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1493 CHECK_MAX_FAILURES(error_test3);
1498 printf("(3) file size != 20\n");
1499 CHECK_MAX_FAILURES(error_test3);
1503 /* Now test if we can truncate a file opened for readonly. */
1505 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
1507 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1508 CHECK_MAX_FAILURES(error_test3);
1512 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1513 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1517 /* Ensure size == 0. */
1518 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1519 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1520 CHECK_MAX_FAILURES(error_test3);
1525 printf("(3) file size != 0\n");
1526 CHECK_MAX_FAILURES(error_test3);
1529 printf("finished open test 3\n");
1531 smbcli_unlink(cli1->tree, fname);
1534 printf("testing ctemp\n");
1535 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
1537 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1538 CHECK_MAX_FAILURES(error_test4);
1541 printf("ctemp gave path %s\n", tmp_path);
1542 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1543 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1545 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1546 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1549 /* Test the non-io opens... */
1551 if (!torture_open_connection(&cli2)) {
1555 smbcli_setatr(cli2->tree, fname, 0, 0);
1556 smbcli_unlink(cli2->tree, fname);
1558 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1560 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1561 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1564 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1565 CHECK_MAX_FAILURES(error_test10);
1569 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1570 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1572 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1573 CHECK_MAX_FAILURES(error_test10);
1577 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1578 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1581 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1582 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1586 printf("non-io open test #1 passed.\n");
1588 smbcli_unlink(cli1->tree, fname);
1590 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1592 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1593 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1596 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1597 CHECK_MAX_FAILURES(error_test20);
1601 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1602 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1605 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1606 CHECK_MAX_FAILURES(error_test20);
1610 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1611 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1614 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1615 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1619 printf("non-io open test #2 passed.\n");
1621 smbcli_unlink(cli1->tree, fname);
1623 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1625 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1626 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1629 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1630 CHECK_MAX_FAILURES(error_test30);
1634 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1635 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1638 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1639 CHECK_MAX_FAILURES(error_test30);
1643 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1644 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1647 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1648 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1652 printf("non-io open test #3 passed.\n");
1654 smbcli_unlink(cli1->tree, fname);
1656 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1658 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1659 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1662 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1663 CHECK_MAX_FAILURES(error_test40);
1667 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1668 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1671 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1672 CHECK_MAX_FAILURES(error_test40);
1676 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1678 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1679 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1683 printf("non-io open test #4 passed.\n");
1685 smbcli_unlink(cli1->tree, fname);
1687 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1689 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1690 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1693 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1694 CHECK_MAX_FAILURES(error_test50);
1698 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1699 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1702 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1703 CHECK_MAX_FAILURES(error_test50);
1707 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1708 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1712 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1713 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1717 printf("non-io open test #5 passed.\n");
1719 printf("TEST #6 testing 1 non-io open, one io open\n");
1721 smbcli_unlink(cli1->tree, fname);
1723 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1724 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1727 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1728 CHECK_MAX_FAILURES(error_test60);
1732 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1733 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1736 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1737 CHECK_MAX_FAILURES(error_test60);
1741 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1742 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1746 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1747 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1751 printf("non-io open test #6 passed.\n");
1753 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
1755 smbcli_unlink(cli1->tree, fname);
1757 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1758 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1761 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1762 CHECK_MAX_FAILURES(error_test70);
1766 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1767 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1770 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1771 CHECK_MAX_FAILURES(error_test70);
1775 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1777 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1778 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1782 printf("non-io open test #7 passed.\n");
1786 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1788 smbcli_unlink(cli1->tree, fname);
1790 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1792 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1796 /* write 20 bytes. */
1798 memset(buf, '\0', 20);
1800 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1801 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1805 /* Ensure size == 20. */
1806 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1807 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1808 CHECK_MAX_FAILURES(error_test80);
1813 printf("(8) file size != 20\n");
1814 CHECK_MAX_FAILURES(error_test80);
1818 /* Get an exclusive lock on the open file. */
1819 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1820 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1821 CHECK_MAX_FAILURES(error_test80);
1825 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1827 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1831 /* Ensure size == 0. */
1832 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1833 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1834 CHECK_MAX_FAILURES(error_test80);
1839 printf("(8) file size != 0\n");
1840 CHECK_MAX_FAILURES(error_test80);
1844 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1845 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1849 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1850 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1856 printf("open test #8 passed.\n");
1858 smbcli_unlink(cli1->tree, fname);
1860 if (!torture_close_connection(cli1)) {
1863 if (!torture_close_connection(cli2)) {
1872 sees what IOCTLs are supported
1874 BOOL torture_ioctl_test(void)
1876 struct smbcli_state *cli;
1877 uint16_t device, function;
1879 const char *fname = "\\ioctl.dat";
1881 union smb_ioctl parms;
1882 TALLOC_CTX *mem_ctx;
1884 if (!torture_open_connection(&cli)) {
1888 mem_ctx = talloc_init("ioctl_test");
1890 printf("starting ioctl test\n");
1892 smbcli_unlink(cli->tree, fname);
1894 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1896 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1900 parms.ioctl.level = RAW_IOCTL_IOCTL;
1901 parms.ioctl.in.fnum = fnum;
1902 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
1903 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1904 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
1906 for (device=0;device<0x100;device++) {
1907 printf("testing device=0x%x\n", device);
1908 for (function=0;function<0x100;function++) {
1909 parms.ioctl.in.request = (device << 16) | function;
1910 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1912 if (NT_STATUS_IS_OK(status)) {
1913 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
1914 device, function, (int)parms.ioctl.out.blob.length);
1919 if (!torture_close_connection(cli)) {
1928 tries variants of chkpath
1930 BOOL torture_chkpath_test(void)
1932 struct smbcli_state *cli;
1936 if (!torture_open_connection(&cli)) {
1940 printf("starting chkpath test\n");
1942 printf("Testing valid and invalid paths\n");
1944 /* cleanup from an old run */
1945 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1946 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1947 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1949 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1950 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1954 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1955 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1959 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1961 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
1964 smbcli_close(cli->tree, fnum);
1966 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1967 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1971 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1972 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1976 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1977 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1978 NT_STATUS_NOT_A_DIRECTORY);
1980 printf("* chkpath on a file should fail\n");
1984 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
1985 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1986 NT_STATUS_OBJECT_NAME_NOT_FOUND);
1988 printf("* chkpath on a non existent file should fail\n");
1992 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
1993 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1994 NT_STATUS_OBJECT_PATH_NOT_FOUND);
1996 printf("* chkpath on a non existent component should fail\n");
2000 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
2001 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
2002 smbcli_rmdir(cli->tree, "\\chkpath.dir");
2004 if (!torture_close_connection(cli)) {
2012 static void sigcont(int sig)
2016 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
2019 volatile pid_t *child_status;
2020 volatile BOOL *child_status_out;
2023 double start_time_limit = 10 + (torture_nprocs * 1.5);
2024 char **unc_list = NULL;
2026 int num_unc_names = 0;
2033 signal(SIGCONT, sigcont);
2035 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
2036 if (!child_status) {
2037 printf("Failed to setup shared memory\n");
2041 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
2042 if (!child_status_out) {
2043 printf("Failed to setup result status shared memory\n");
2047 p = lp_parm_string(-1, "torture", "unclist");
2049 unc_list = file_lines_load(p, &num_unc_names, NULL);
2050 if (!unc_list || num_unc_names <= 0) {
2051 printf("Failed to load unc names list from '%s'\n", p);
2056 for (i = 0; i < torture_nprocs; i++) {
2057 child_status[i] = 0;
2058 child_status_out[i] = True;
2061 tv = timeval_current();
2063 for (i=0;i<torture_nprocs;i++) {
2067 const char *hostname=NULL, *sharename;
2069 pid_t mypid = getpid();
2070 srandom(((int)mypid) ^ ((int)time(NULL)));
2072 asprintf(&myname, "CLIENT%d", i);
2073 lp_set_cmdline("netbios name", myname);
2078 if (!smbcli_parse_unc(unc_list[i % num_unc_names],
2079 NULL, &hostname, &sharename)) {
2080 printf("Failed to parse UNC name %s\n",
2081 unc_list[i % num_unc_names]);
2088 if (torture_open_connection_share(NULL,
2095 } else if (torture_open_connection(¤t_cli)) {
2099 printf("pid %d failed to start\n", (int)getpid());
2105 child_status[i] = getpid();
2109 if (child_status[i]) {
2110 printf("Child %d failed to start!\n", i);
2111 child_status_out[i] = 1;
2115 child_status_out[i] = fn(current_cli, i);
2122 for (i=0;i<torture_nprocs;i++) {
2123 if (child_status[i]) synccount++;
2125 if (synccount == torture_nprocs) break;
2127 } while (timeval_elapsed(&tv) < start_time_limit);
2129 if (synccount != torture_nprocs) {
2130 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
2132 return timeval_elapsed(&tv);
2135 printf("Starting %d clients\n", torture_nprocs);
2137 /* start the client load */
2138 tv = timeval_current();
2139 for (i=0;i<torture_nprocs;i++) {
2140 child_status[i] = 0;
2143 printf("%d clients started\n", torture_nprocs);
2147 for (i=0;i<torture_nprocs;i++) {
2149 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
2150 if (ret == -1 || WEXITSTATUS(status) != 0) {
2157 for (i=0;i<torture_nprocs;i++) {
2158 if (!child_status_out[i]) {
2162 return timeval_elapsed(&tv);
2165 #define FLAG_MULTIPROC 1
2170 BOOL (*multi_fn)(struct smbcli_state *, int );
2173 {"BASE-FDPASS", run_fdpasstest, 0},
2174 {"BASE-LOCK1", torture_locktest1, 0},
2175 {"BASE-LOCK2", torture_locktest2, 0},
2176 {"BASE-LOCK3", torture_locktest3, 0},
2177 {"BASE-LOCK4", torture_locktest4, 0},
2178 {"BASE-LOCK5", torture_locktest5, 0},
2179 {"BASE-LOCK6", torture_locktest6, 0},
2180 {"BASE-LOCK7", torture_locktest7, 0},
2181 {"BASE-UNLINK", torture_unlinktest, 0},
2182 {"BASE-ATTR", run_attrtest, 0},
2183 {"BASE-TRANS2", run_trans2test, 0},
2184 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
2185 {"BASE-DIR1", torture_dirtest1, 0},
2186 {"BASE-DIR2", torture_dirtest2, 0},
2187 {"BASE-DENY1", torture_denytest1, 0},
2188 {"BASE-DENY2", torture_denytest2, 0},
2189 {"BASE-DENY3", torture_denytest3, 0},
2190 {"BASE-DENYDOS", torture_denydos_sharing, 0},
2191 {"BASE-NTDENY1", NULL, torture_ntdenytest1},
2192 {"BASE-NTDENY2", torture_ntdenytest2, 0},
2193 {"BASE-TCON", run_tcon_test, 0},
2194 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
2195 {"BASE-VUID", run_vuidtest, 0},
2196 {"BASE-RW1", run_readwritetest, 0},
2197 {"BASE-OPEN", run_opentest, 0},
2198 {"BASE-DEFER_OPEN", NULL, run_deferopen},
2199 {"BASE-XCOPY", run_xcopy, 0},
2200 {"BASE-RENAME", torture_test_rename, 0},
2201 {"BASE-DELETE", torture_test_delete, 0},
2202 {"BASE-PROPERTIES", torture_test_properties, 0},
2203 {"BASE-MANGLE", torture_mangle, 0},
2204 {"BASE-OPENATTR", torture_openattrtest, 0},
2205 {"BASE-CHARSET", torture_charset, 0},
2206 {"BASE-CHKPATH", torture_chkpath_test, 0},
2207 {"BASE-SECLEAK", torture_sec_leak, 0},
2208 {"BASE-DISCONNECT", torture_disconnect, 0},
2209 {"BASE-DELAYWRITE", torture_delay_write, 0},
2211 /* benchmarking tests */
2212 {"BENCH-HOLDCON", torture_holdcon, 0},
2213 {"BENCH-NBENCH", torture_nbench, 0},
2214 {"BENCH-TORTURE", NULL, run_torture},
2215 {"BENCH-NBT", torture_bench_nbt, 0},
2216 {"BENCH-WINS", torture_bench_wins, 0},
2217 {"BENCH-RPC", torture_bench_rpc, 0},
2218 {"BENCH-CLDAP", torture_bench_cldap, 0},
2221 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
2222 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
2223 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
2224 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
2225 {"RAW-SEARCH", torture_raw_search, 0},
2226 {"RAW-CLOSE", torture_raw_close, 0},
2227 {"RAW-OPEN", torture_raw_open, 0},
2228 {"RAW-MKDIR", torture_raw_mkdir, 0},
2229 {"RAW-OPLOCK", torture_raw_oplock, 0},
2230 {"RAW-NOTIFY", torture_raw_notify, 0},
2231 {"RAW-MUX", torture_raw_mux, 0},
2232 {"RAW-IOCTL", torture_raw_ioctl, 0},
2233 {"RAW-CHKPATH", torture_raw_chkpath, 0},
2234 {"RAW-UNLINK", torture_raw_unlink, 0},
2235 {"RAW-READ", torture_raw_read, 0},
2236 {"RAW-WRITE", torture_raw_write, 0},
2237 {"RAW-LOCK", torture_raw_lock, 0},
2238 {"RAW-CONTEXT", torture_raw_context, 0},
2239 {"RAW-RENAME", torture_raw_rename, 0},
2240 {"RAW-SEEK", torture_raw_seek, 0},
2241 {"RAW-EAS", torture_raw_eas, 0},
2242 {"RAW-EAMAX", torture_max_eas, 0},
2243 {"RAW-STREAMS", torture_raw_streams, 0},
2244 {"RAW-ACLS", torture_raw_acls, 0},
2245 {"RAW-RAP", torture_raw_rap, 0},
2246 {"RAW-COMPOSITE", torture_raw_composite, 0},
2249 {"SMB2-CONNECT", torture_smb2_connect, 0},
2250 {"SMB2-SCAN", torture_smb2_scan, 0},
2251 {"SMB2-SCANGETINFO", torture_smb2_getinfo_scan, 0},
2252 {"SMB2-SCANSETINFO", torture_smb2_setinfo_scan, 0},
2253 {"SMB2-SCANFIND", torture_smb2_find_scan, 0},
2254 {"SMB2-GETINFO", torture_smb2_getinfo, 0},
2255 {"SMB2-SETINFO", torture_smb2_setinfo, 0},
2256 {"SMB2-FIND", torture_smb2_find, 0},
2258 /* protocol scanners */
2259 {"SCAN-TRANS2", torture_trans2_scan, 0},
2260 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2261 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2262 {"SCAN-SMB", torture_smb_scan, 0},
2263 {"SCAN-MAXFID", NULL, run_maxfidtest},
2264 {"SCAN-UTABLE", torture_utable, 0},
2265 {"SCAN-CASETABLE", torture_casetable, 0},
2266 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2267 {"SCAN-IOCTL", torture_ioctl_test, 0},
2268 {"SCAN-RAP", torture_rap_scan, 0},
2271 {"RPC-LSA", torture_rpc_lsa, 0},
2272 {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
2273 {"RPC-ECHO", torture_rpc_echo, 0},
2274 {"RPC-DFS", torture_rpc_dfs, 0},
2275 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2276 {"RPC-SAMR", torture_rpc_samr, 0},
2277 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2278 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2279 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2280 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2281 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2282 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2283 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2284 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2285 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2286 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2287 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2288 {"RPC-WINREG", torture_rpc_winreg, 0},
2289 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2290 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2291 {"RPC-REMACT", torture_rpc_remact, 0},
2292 {"RPC-MGMT", torture_rpc_mgmt, 0},
2293 {"RPC-SCANNER", torture_rpc_scanner, 0},
2294 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2295 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2296 {"RPC-MULTIBIND", torture_multi_bind, 0},
2297 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2298 {"RPC-CRACKNAMES", torture_rpc_drsuapi_cracknames, 0},
2299 {"RPC-ROT", torture_rpc_rot, 0},
2300 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2301 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2302 {"RPC-JOIN", torture_rpc_join, 0},
2303 {"RPC-DSSYNC", torture_rpc_dssync, 0},
2305 /* local (no server) testers */
2306 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2307 {"LOCAL-ICONV", torture_local_iconv, 0},
2308 {"LOCAL-TALLOC", torture_local_talloc, 0},
2309 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2310 {"LOCAL-IRPC", torture_local_irpc, 0},
2311 {"LOCAL-BINDING", torture_local_binding_string, 0},
2312 {"LOCAL-STRLIST", torture_local_util_strlist, 0},
2313 {"LOCAL-FILE", torture_local_util_file, 0},
2314 {"LOCAL-IDTREE", torture_local_idtree, 0},
2315 {"LOCAL-SOCKET", torture_local_socket, 0},
2316 {"LOCAL-PAC", torture_pac, 0},
2317 {"LOCAL-REGISTRY", torture_registry, 0},
2318 {"LOCAL-RESOLVE", torture_local_resolve, 0},
2319 {"LOCAL-SDDL", torture_local_sddl, 0},
2320 {"LOCAL-NDR", torture_local_ndr, 0},
2322 /* COM (Component Object Model) testers */
2323 {"COM-SIMPLE", torture_com_simple, 0 },
2326 {"LDAP-BASIC", torture_ldap_basic, 0},
2327 {"LDAP-CLDAP", torture_cldap, 0},
2330 {"NBT-REGISTER", torture_nbt_register, 0},
2331 {"NBT-WINS", torture_nbt_wins, 0},
2332 {"NBT-DGRAM", torture_nbt_dgram, 0},
2333 {"NBT-WINSREPLICATION", torture_nbt_winsreplication, 0},
2336 {"NET-USERINFO", torture_userinfo, 0},
2337 {"NET-USERADD", torture_useradd, 0},
2338 {"NET-USERDEL", torture_userdel, 0},
2339 {"NET-USERMOD", torture_usermod, 0},
2340 {"NET-DOMOPEN", torture_domainopen, 0},
2341 {"NET-API-LOOKUP", torture_lookup, 0},
2342 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2343 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2344 {"NET-API-CREATEUSER", torture_createuser, 0},
2345 {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
2346 {"NET-API-LISTSHARES", torture_listshares, 0},
2347 {"NET-API-DELSHARE", torture_delshare, 0},
2353 /****************************************************************************
2354 run a specified test or "ALL"
2355 ****************************************************************************/
2356 static BOOL run_test(const char *name)
2360 BOOL matched = False;
2362 if (strequal(name,"ALL")) {
2363 for (i=0;torture_ops[i].name;i++) {
2364 if (!run_test(torture_ops[i].name)) {
2371 for (i=0;torture_ops[i].name;i++) {
2372 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
2376 printf("Running %s\n", torture_ops[i].name);
2377 if (torture_ops[i].multi_fn) {
2378 BOOL result = False;
2379 t = torture_create_procs(torture_ops[i].multi_fn,
2383 printf("TEST %s FAILED!\n", torture_ops[i].name);
2387 struct timeval tv = timeval_current();
2388 if (!torture_ops[i].fn()) {
2390 printf("TEST %s FAILED!\n", torture_ops[i].name);
2392 t = timeval_elapsed(&tv);
2394 printf("%s took %g secs\n\n", torture_ops[i].name, t);
2399 printf("Unknown torture operation '%s'\n", name);
2406 static void parse_dns(const char *dns)
2408 char *userdn, *basedn, *secret;
2411 /* retrievieng the userdn */
2412 p = strchr_m(dns, '#');
2414 lp_set_cmdline("torture:ldap_userdn", "");
2415 lp_set_cmdline("torture:ldap_basedn", "");
2416 lp_set_cmdline("torture:ldap_secret", "");
2419 userdn = strndup(dns, p - dns);
2420 lp_set_cmdline("torture:ldap_userdn", userdn);
2422 /* retrieve the basedn */
2424 p = strchr_m(d, '#');
2426 lp_set_cmdline("torture:ldap_basedn", "");
2427 lp_set_cmdline("torture:ldap_secret", "");
2430 basedn = strndup(d, p - d);
2431 lp_set_cmdline("torture:ldap_basedn", basedn);
2433 /* retrieve the secret */
2436 lp_set_cmdline("torture:ldap_secret", "");
2440 lp_set_cmdline("torture:ldap_secret", secret);
2442 printf ("%s - %s - %s\n", userdn, basedn, secret);
2446 static void usage(poptContext pc)
2451 poptPrintUsage(pc, stdout, 0);
2454 printf("The binding format is:\n\n");
2456 printf(" TRANSPORT:host[flags]\n\n");
2458 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2460 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2461 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2462 printf(" string.\n\n");
2464 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2465 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2466 printf(" will be auto-determined.\n\n");
2468 printf(" other recognised flags are:\n\n");
2470 printf(" sign : enable ntlmssp signing\n");
2471 printf(" seal : enable ntlmssp sealing\n");
2472 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2473 printf(" validate: enable the NDR validator\n");
2474 printf(" print: enable debugging of the packets\n");
2475 printf(" bigendian: use bigendian RPC\n");
2476 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2478 printf(" For example, these all connect to the samr pipe:\n\n");
2480 printf(" ncacn_np:myserver\n");
2481 printf(" ncacn_np:myserver[samr]\n");
2482 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2483 printf(" ncacn_np:myserver[/pipe/samr]\n");
2484 printf(" ncacn_np:myserver[samr,sign,print]\n");
2485 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2486 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2487 printf(" ncacn_np:\n");
2488 printf(" ncacn_np:[/pipe/samr]\n\n");
2490 printf(" ncacn_ip_tcp:myserver\n");
2491 printf(" ncacn_ip_tcp:myserver[1024]\n");
2492 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2494 printf("The unc format is:\n\n");
2496 printf(" //server/share\n\n");
2498 printf("tests are:");
2499 for (i=0;torture_ops[i].name;i++) {
2500 if ((i%perline)==0) {
2503 printf("%s ", torture_ops[i].name);
2507 printf("default test is ALL\n");
2512 static BOOL is_binding_string(const char *binding_string)
2514 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2515 struct dcerpc_binding *binding_struct;
2518 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2520 talloc_free(mem_ctx);
2521 return NT_STATUS_IS_OK(status);
2524 static void max_runtime_handler(int sig)
2526 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2530 /****************************************************************************
2532 ****************************************************************************/
2533 int main(int argc,char *argv[])
2537 BOOL correct = True;
2542 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,OPT_DANGEROUS};
2543 struct poptOption long_options[] = {
2545 {"smb-ports", 'p', POPT_ARG_STRING, NULL, 0, "SMB ports", NULL},
2546 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2547 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2548 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2549 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2550 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2551 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2552 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2553 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2554 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2555 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2556 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2557 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2558 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2559 "set maximum time for smbtorture to live", "seconds"},
2561 POPT_COMMON_CONNECTION
2562 POPT_COMMON_CREDENTIALS
2567 #ifdef HAVE_SETBUFFER
2568 setbuffer(stdout, NULL, 0);
2571 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2572 POPT_CONTEXT_KEEP_FIRST);
2574 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2576 while((opt = poptGetNextOpt(pc)) != -1) {
2579 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2582 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2585 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2588 parse_dns(poptGetOptArg(pc));
2591 lp_set_cmdline("torture:dangerous", "Yes");
2594 d_printf("Invalid option %s: %s\n",
2595 poptBadOption(pc, 0), poptStrerror(opt));
2602 /* this will only work if nobody else uses alarm(),
2603 which means it won't work for some tests, but we
2604 can't use the event context method we use for smbd
2605 as so many tests create their own event
2606 context. This will at least catch most cases. */
2607 signal(SIGALRM, max_runtime_handler);
2613 dcerpc_table_init();
2615 if (torture_seed == 0) {
2616 torture_seed = time(NULL);
2618 printf("Using seed %d\n", torture_seed);
2619 srandom(torture_seed);
2621 argv_new = discard_const_p(char *, poptGetArgs(pc));
2624 for (i=0; i<argc; i++) {
2625 if (argv_new[i] == NULL) {
2636 for(p = argv_new[1]; *p; p++) {
2641 /* see if its a RPC transport specifier */
2642 if (is_binding_string(argv_new[1])) {
2643 lp_set_cmdline("torture:binding", argv_new[1]);
2645 char *binding = NULL;
2646 const char *host = NULL, *share = NULL;
2648 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
2649 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
2653 lp_set_cmdline("torture:host", host);
2654 lp_set_cmdline("torture:share", share);
2655 asprintf(&binding, "ncacn_np:%s", host);
2656 lp_set_cmdline("torture:binding", binding);
2659 if (argc_new == 0) {
2660 printf("You must specify a test to run, or 'ALL'\n");
2662 for (i=2;i<argc_new;i++) {
2663 if (!run_test(argv_new[i])) {