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"
32 int torture_numops=100;
33 int torture_entries=1000;
34 int torture_failures=1;
36 static int procnum; /* records process count number when forking */
37 static struct smbcli_state *current_cli;
38 static BOOL use_oplocks;
39 static BOOL use_level_II_oplocks;
41 BOOL torture_showall = False;
43 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
45 static struct smbcli_state *open_nbt_connection(void)
47 struct nbt_name called, calling;
48 struct smbcli_state *cli;
49 const char *host = lp_parm_string(-1, "torture", "host");
51 make_nbt_name_client(&calling, lp_netbios_name());
53 nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
55 cli = smbcli_state_init(NULL);
57 printf("Failed initialize smbcli_struct to connect with %s\n", host);
61 if (!smbcli_socket_connect(cli, host)) {
62 printf("Failed to connect with %s\n", host);
66 if (!smbcli_transport_establish(cli, &calling, &called)) {
67 printf("%s rejected the session\n",host);
78 BOOL torture_open_connection_share(TALLOC_CTX *mem_ctx,
79 struct smbcli_state **c,
81 const char *sharename,
82 struct event_context *ev)
86 status = smbcli_full_connection(mem_ctx, c, hostname,
88 cmdline_credentials, ev);
89 if (!NT_STATUS_IS_OK(status)) {
90 printf("Failed to open connection - %s\n", nt_errstr(status));
94 (*c)->transport->options.use_oplocks = use_oplocks;
95 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
100 BOOL torture_open_connection(struct smbcli_state **c)
102 const char *host = lp_parm_string(-1, "torture", "host");
103 const char *share = lp_parm_string(-1, "torture", "share");
105 return torture_open_connection_share(NULL, c, host, share, NULL);
110 BOOL torture_close_connection(struct smbcli_state *c)
114 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
115 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
122 /* open a rpc connection to the chosen binding string */
123 NTSTATUS torture_rpc_connection(TALLOC_CTX *parent_ctx,
124 struct dcerpc_pipe **p,
125 const char *pipe_name,
126 const char *pipe_uuid,
127 uint32_t pipe_version)
130 const char *binding = lp_parm_string(-1, "torture", "binding");
133 printf("You must specify a ncacn binding string\n");
134 return NT_STATUS_INVALID_PARAMETER;
137 status = dcerpc_pipe_connect(parent_ctx,
138 p, binding, pipe_uuid, pipe_version,
139 cmdline_credentials, NULL);
144 /* open a rpc connection to a specific transport */
145 NTSTATUS torture_rpc_connection_transport(TALLOC_CTX *parent_ctx,
146 struct dcerpc_pipe **p,
147 const char *pipe_name,
148 const char *pipe_uuid,
149 uint32_t pipe_version,
150 enum dcerpc_transport_t transport)
153 const char *binding = lp_parm_string(-1, "torture", "binding");
154 struct dcerpc_binding *b;
155 TALLOC_CTX *mem_ctx = talloc_named(parent_ctx, 0, "torture_rpc_connection_smb");
158 printf("You must specify a ncacn binding string\n");
159 talloc_free(mem_ctx);
160 return NT_STATUS_INVALID_PARAMETER;
163 status = dcerpc_parse_binding(mem_ctx, binding, &b);
164 if (!NT_STATUS_IS_OK(status)) {
165 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
166 talloc_free(mem_ctx);
170 b->transport = transport;
172 status = dcerpc_pipe_connect_b(mem_ctx, p, b, pipe_uuid, pipe_version,
173 cmdline_credentials, NULL);
175 if (NT_STATUS_IS_OK(status)) {
176 *p = talloc_reference(parent_ctx, *p);
180 talloc_free(mem_ctx);
184 /* check if the server produced the expected error code */
185 BOOL check_error(const char *location, struct smbcli_state *c,
186 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
190 status = smbcli_nt_error(c->tree);
191 if (NT_STATUS_IS_DOS(status)) {
193 class = NT_STATUS_DOS_CLASS(status);
194 num = NT_STATUS_DOS_CODE(status);
195 if (eclass != class || ecode != num) {
196 printf("unexpected error code %s\n", nt_errstr(status));
197 printf(" expected %s or %s (at %s)\n",
198 nt_errstr(NT_STATUS_DOS(eclass, ecode)),
199 nt_errstr(nterr), location);
203 if (!NT_STATUS_EQUAL(nterr, status)) {
204 printf("unexpected error code %s\n", nt_errstr(status));
205 printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
214 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
216 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
217 if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
223 static BOOL rw_torture(struct smbcli_state *c)
225 const char *lockfname = "\\torture.lck";
229 pid_t pid2, pid = getpid();
234 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
237 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
239 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
244 for (i=0;i<torture_numops;i++) {
245 uint_t n = (uint_t)random()%10;
247 printf("%d\r", i); fflush(stdout);
249 asprintf(&fname, "\\torture.%u", n);
251 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
255 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
257 printf("open failed (%s)\n", smbcli_errstr(c->tree));
262 if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
263 printf("write failed (%s)\n", smbcli_errstr(c->tree));
268 if (smbcli_write(c->tree, fnum, 0, buf,
269 sizeof(pid)+(j*sizeof(buf)),
270 sizeof(buf)) != sizeof(buf)) {
271 printf("write failed (%s)\n", smbcli_errstr(c->tree));
278 if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
279 printf("read failed (%s)\n", smbcli_errstr(c->tree));
284 printf("data corruption!\n");
288 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
289 printf("close failed (%s)\n", smbcli_errstr(c->tree));
293 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
294 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
298 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
299 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
305 smbcli_close(c->tree, fnum2);
306 smbcli_unlink(c->tree, lockfname);
313 static BOOL run_torture(struct smbcli_state *cli, int dummy)
317 ret = rw_torture(cli);
319 if (!torture_close_connection(cli)) {
327 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
329 const char *lockfname = "\\torture2.lck";
334 uint8_t buf_rd[131072];
336 ssize_t bytes_read, bytes_written;
338 if (smbcli_deltree(c1->tree, lockfname) == -1) {
339 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
342 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
345 printf("first open read/write of %s failed (%s)\n",
346 lockfname, smbcli_errstr(c1->tree));
349 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
352 printf("second open read-only of %s failed (%s)\n",
353 lockfname, smbcli_errstr(c2->tree));
354 smbcli_close(c1->tree, fnum1);
358 printf("Checking data integrity over %d ops\n", torture_numops);
360 for (i=0;i<torture_numops;i++)
362 size_t buf_size = ((uint_t)random()%(sizeof(buf)-1))+ 1;
364 printf("%d\r", i); fflush(stdout);
367 generate_random_buffer(buf, buf_size);
369 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
370 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
371 printf("wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
376 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
377 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
378 printf("read %d, expected %d\n", (int)bytes_read, (int)buf_size);
383 if (memcmp(buf_rd, buf, buf_size) != 0)
385 printf("read/write compare failed\n");
391 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
392 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
395 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
396 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
400 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
401 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
408 #define BOOLSTR(b) ((b) ? "Yes" : "No")
410 static BOOL run_readwritetest(void)
412 struct smbcli_state *cli1, *cli2;
413 BOOL test1, test2 = True;
415 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
419 printf("starting readwritetest\n");
421 test1 = rw_torture2(cli1, cli2);
422 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
425 test2 = rw_torture2(cli1, cli1);
426 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
429 if (!torture_close_connection(cli1)) {
433 if (!torture_close_connection(cli2)) {
437 return (test1 && test2);
441 this checks to see if a secondary tconx can use open files from an
444 static BOOL run_tcon_test(void)
446 struct smbcli_state *cli;
447 const char *fname = "\\tcontest.tmp";
449 uint16_t cnum1, cnum2, cnum3;
450 uint16_t vuid1, vuid2;
453 struct smbcli_tree *tree1;
454 const char *host = lp_parm_string(-1, "torture", "host");
455 const char *share = lp_parm_string(-1, "torture", "share");
456 const char *password = lp_parm_string(-1, "torture", "password");
458 if (!torture_open_connection(&cli)) {
462 printf("starting tcontest\n");
464 if (smbcli_deltree(cli->tree, fname) == -1) {
465 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
468 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
470 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
474 cnum1 = cli->tree->tid;
475 vuid1 = cli->session->vuid;
477 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
478 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
479 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
483 tree1 = cli->tree; /* save old tree connection */
484 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
485 printf("%s refused 2nd tree connect (%s)\n", host,
486 smbcli_errstr(cli->tree));
491 cnum2 = cli->tree->tid;
492 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
493 vuid2 = cli->session->vuid + 1;
495 /* try a write with the wrong tid */
496 cli->tree->tid = cnum2;
498 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
499 printf("* server allows write with wrong TID\n");
502 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
506 /* try a write with an invalid tid */
507 cli->tree->tid = cnum3;
509 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
510 printf("* server allows write with invalid TID\n");
513 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
516 /* try a write with an invalid vuid */
517 cli->session->vuid = vuid2;
518 cli->tree->tid = cnum1;
520 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
521 printf("* server allows write with invalid VUID\n");
524 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
527 cli->session->vuid = vuid1;
528 cli->tree->tid = cnum1;
530 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
531 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
535 cli->tree->tid = cnum2;
537 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
538 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
542 cli->tree = tree1; /* restore initial tree */
543 cli->tree->tid = cnum1;
545 smbcli_unlink(tree1, fname);
547 if (!torture_close_connection(cli)) {
556 static BOOL tcon_devtest(struct smbcli_state *cli,
557 const char *myshare, const char *devtype,
558 NTSTATUS expected_error)
562 const char *password = lp_parm_string(-1, "torture", "password");
564 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
567 printf("Trying share %s with devtype %s\n", myshare, devtype);
569 if (NT_STATUS_IS_OK(expected_error)) {
573 printf("tconX to share %s with type %s "
574 "should have succeeded but failed\n",
581 printf("tconx to share %s with type %s "
582 "should have failed but succeeded\n",
586 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
590 printf("Returned unexpected error\n");
599 checks for correct tconX support
601 static BOOL run_tcon_devtype_test(void)
603 struct smbcli_state *cli1 = NULL;
606 const char *host = lp_parm_string(-1, "torture", "host");
607 const char *share = lp_parm_string(-1, "torture", "share");
609 status = smbcli_full_connection(NULL,
612 cmdline_credentials, NULL);
614 if (!NT_STATUS_IS_OK(status)) {
615 printf("could not open connection\n");
619 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
622 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
625 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
628 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
631 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
634 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
637 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
640 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
643 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
646 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
652 printf("Passed tcondevtest\n");
659 test whether fnums and tids open on one VC are available on another (a major
662 static BOOL run_fdpasstest(void)
664 struct smbcli_state *cli1, *cli2;
665 const char *fname = "\\fdpass.tst";
669 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
673 printf("starting fdpasstest\n");
675 smbcli_unlink(cli1->tree, fname);
677 printf("Opening a file on connection 1\n");
679 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
681 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
685 printf("writing to file on connection 1\n");
687 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
688 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
692 oldtid = cli2->tree->tid;
693 cli2->session->vuid = cli1->session->vuid;
694 cli2->tree->tid = cli1->tree->tid;
695 cli2->session->pid = cli1->session->pid;
697 printf("reading from file on connection 2\n");
699 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
700 printf("read succeeded! nasty security hole [%s]\n",
705 smbcli_close(cli1->tree, fnum1);
706 smbcli_unlink(cli1->tree, fname);
708 cli2->tree->tid = oldtid;
710 torture_close_connection(cli1);
711 torture_close_connection(cli2);
713 printf("finished fdpasstest\n");
719 test the timing of deferred open requests
721 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
723 const char *fname = "\\defer_open_test.dat";
729 printf("failed to connect\n");
733 printf("Testing deferred open requests.\n");
740 tv = timeval_current();
741 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
743 FILE_ATTRIBUTE_NORMAL,
744 NTCREATEX_SHARE_ACCESS_NONE,
745 NTCREATEX_DISP_OPEN_IF, 0, 0);
749 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
750 double e = timeval_elapsed(&tv);
751 if (e < 0.5 || e > 1.5) {
752 fprintf(stderr,"Timing incorrect %.2f violation\n",
756 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
759 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
763 printf("pid %u open %d\n", getpid(), i);
767 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
768 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
774 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
775 /* All until the last unlink will fail with sharing violation. */
776 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
777 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
782 printf("deferred test finished\n");
783 if (!torture_close_connection(cli)) {
790 test how many open files this server supports on the one socket
792 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
794 #define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
796 int fnums[0x11000], i;
797 int retries=4, maxfid;
801 printf("failed to connect\n");
805 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
806 printf("Failed to deltree \\maxfid - %s\n",
807 smbcli_errstr(cli->tree));
810 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
811 printf("Failed to mkdir \\maxfid, error=%s\n",
812 smbcli_errstr(cli->tree));
816 printf("Testing maximum number of open files\n");
818 for (i=0; i<0x11000; i++) {
820 asprintf(&fname, "\\maxfid\\fid%d", i/1000);
821 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
822 printf("Failed to mkdir %s, error=%s\n",
823 fname, smbcli_errstr(cli->tree));
828 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
829 if ((fnums[i] = smbcli_open(cli->tree, fname,
830 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
832 printf("open of %s failed (%s)\n",
833 fname, smbcli_errstr(cli->tree));
834 printf("maximum fnum is %d\n", i);
845 printf("cleaning up\n");
846 for (i=0;i<maxfid/2;i++) {
847 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
848 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
849 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
851 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
852 printf("unlink of %s failed (%s)\n",
853 fname, smbcli_errstr(cli->tree));
858 asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
859 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
860 printf("Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
862 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
863 printf("unlink of %s failed (%s)\n",
864 fname, smbcli_errstr(cli->tree));
869 printf("%6d %6d\r", i, maxfid-i);
873 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
874 printf("Failed to deltree \\maxfid - %s\n",
875 smbcli_errstr(cli->tree));
879 printf("maxfid test finished\n");
880 if (!torture_close_connection(cli)) {
884 #undef MAXFID_TEMPLATE
887 /* send smb negprot commands, not reading the response */
888 static BOOL run_negprot_nowait(void)
891 struct smbcli_state *cli, *cli2;
894 printf("starting negprot nowait test\n");
896 cli = open_nbt_connection();
901 printf("Filling send buffer\n");
903 for (i=0;i<1000;i++) {
904 struct smbcli_request *req;
905 time_t t1 = time(NULL);
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},
2255 /* protocol scanners */
2256 {"SCAN-TRANS2", torture_trans2_scan, 0},
2257 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2258 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2259 {"SCAN-SMB", torture_smb_scan, 0},
2260 {"SCAN-MAXFID", NULL, run_maxfidtest},
2261 {"SCAN-UTABLE", torture_utable, 0},
2262 {"SCAN-CASETABLE", torture_casetable, 0},
2263 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2264 {"SCAN-IOCTL", torture_ioctl_test, 0},
2265 {"SCAN-RAP", torture_rap_scan, 0},
2268 {"RPC-LSA", torture_rpc_lsa, 0},
2269 {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
2270 {"RPC-ECHO", torture_rpc_echo, 0},
2271 {"RPC-DFS", torture_rpc_dfs, 0},
2272 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2273 {"RPC-SAMR", torture_rpc_samr, 0},
2274 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2275 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2276 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2277 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2278 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2279 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2280 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2281 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2282 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2283 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2284 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2285 {"RPC-WINREG", torture_rpc_winreg, 0},
2286 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2287 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2288 {"RPC-REMACT", torture_rpc_remact, 0},
2289 {"RPC-MGMT", torture_rpc_mgmt, 0},
2290 {"RPC-SCANNER", torture_rpc_scanner, 0},
2291 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2292 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2293 {"RPC-MULTIBIND", torture_multi_bind, 0},
2294 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2295 {"RPC-CRACKNAMES", torture_rpc_drsuapi_cracknames, 0},
2296 {"RPC-LOGIN", torture_rpc_login, 0},
2297 {"RPC-ROT", torture_rpc_rot, 0},
2298 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2299 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2300 {"RPC-JOIN", torture_rpc_join, 0},
2301 {"RPC-DSSYNC", torture_rpc_dssync, 0},
2303 /* local (no server) testers */
2304 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2305 {"LOCAL-ICONV", torture_local_iconv, 0},
2306 {"LOCAL-TALLOC", torture_local_talloc, 0},
2307 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2308 {"LOCAL-IRPC", torture_local_irpc, 0},
2309 {"LOCAL-BINDING", torture_local_binding_string, 0},
2310 {"LOCAL-STRLIST", torture_local_util_strlist, 0},
2311 {"LOCAL-FILE", torture_local_util_file, 0},
2312 {"LOCAL-IDTREE", torture_local_idtree, 0},
2313 {"LOCAL-SOCKET", torture_local_socket, 0},
2314 {"LOCAL-PAC", torture_pac, 0},
2315 {"LOCAL-REGISTRY", torture_registry, 0},
2316 {"LOCAL-RESOLVE", torture_local_resolve, 0},
2318 /* COM (Component Object Model) testers */
2319 {"COM-SIMPLE", torture_com_simple, 0 },
2322 {"LDAP-BASIC", torture_ldap_basic, 0},
2323 {"LDAP-CLDAP", torture_cldap, 0},
2326 {"NBT-REGISTER", torture_nbt_register, 0},
2327 {"NBT-WINS", torture_nbt_wins, 0},
2328 {"NBT-DGRAM", torture_nbt_dgram, 0},
2329 {"NBT-WINSREPLICATION-QUICK", torture_nbt_winsreplication_quick, 0},
2330 {"NBT-WINSREPLICATION", torture_nbt_winsreplication, 0},
2333 {"NET-USERINFO", torture_userinfo, 0},
2334 {"NET-USERADD", torture_useradd, 0},
2335 {"NET-USERDEL", torture_userdel, 0},
2336 {"NET-USERMOD", torture_usermod, 0},
2337 {"NET-DOMOPEN", torture_domainopen, 0},
2338 {"NET-API-LOOKUP", torture_lookup, 0},
2339 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2340 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2341 {"NET-API-CREATEUSER", torture_createuser, 0},
2342 {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
2343 {"NET-API-LISTSHARES", torture_listshares, 0},
2344 {"NET-API-DELSHARE", torture_delshare, 0},
2350 /****************************************************************************
2351 run a specified test or "ALL"
2352 ****************************************************************************/
2353 static BOOL run_test(const char *name)
2357 BOOL matched = False;
2359 if (strequal(name,"ALL")) {
2360 for (i=0;torture_ops[i].name;i++) {
2361 if (!run_test(torture_ops[i].name)) {
2368 for (i=0;torture_ops[i].name;i++) {
2369 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
2373 printf("Running %s\n", torture_ops[i].name);
2374 if (torture_ops[i].multi_fn) {
2375 BOOL result = False;
2376 t = torture_create_procs(torture_ops[i].multi_fn,
2380 printf("TEST %s FAILED!\n", torture_ops[i].name);
2384 struct timeval tv = timeval_current();
2385 if (!torture_ops[i].fn()) {
2387 printf("TEST %s FAILED!\n", torture_ops[i].name);
2389 t = timeval_elapsed(&tv);
2391 printf("%s took %g secs\n\n", torture_ops[i].name, t);
2396 printf("Unknown torture operation '%s'\n", name);
2403 static void parse_dns(const char *dns)
2405 char *userdn, *basedn, *secret;
2408 /* retrievieng the userdn */
2409 p = strchr_m(dns, '#');
2411 lp_set_cmdline("torture:ldap_userdn", "");
2412 lp_set_cmdline("torture:ldap_basedn", "");
2413 lp_set_cmdline("torture:ldap_secret", "");
2416 userdn = strndup(dns, p - dns);
2417 lp_set_cmdline("torture:ldap_userdn", userdn);
2419 /* retrieve the basedn */
2421 p = strchr_m(d, '#');
2423 lp_set_cmdline("torture:ldap_basedn", "");
2424 lp_set_cmdline("torture:ldap_secret", "");
2427 basedn = strndup(d, p - d);
2428 lp_set_cmdline("torture:ldap_basedn", basedn);
2430 /* retrieve the secret */
2433 lp_set_cmdline("torture:ldap_secret", "");
2437 lp_set_cmdline("torture:ldap_secret", secret);
2439 printf ("%s - %s - %s\n", userdn, basedn, secret);
2443 static void usage(poptContext pc)
2448 poptPrintUsage(pc, stdout, 0);
2451 printf("The binding format is:\n\n");
2453 printf(" TRANSPORT:host[flags]\n\n");
2455 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2457 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2458 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2459 printf(" string.\n\n");
2461 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2462 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2463 printf(" will be auto-determined.\n\n");
2465 printf(" other recognised flags are:\n\n");
2467 printf(" sign : enable ntlmssp signing\n");
2468 printf(" seal : enable ntlmssp sealing\n");
2469 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2470 printf(" validate: enable the NDR validator\n");
2471 printf(" print: enable debugging of the packets\n");
2472 printf(" bigendian: use bigendian RPC\n");
2473 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2475 printf(" For example, these all connect to the samr pipe:\n\n");
2477 printf(" ncacn_np:myserver\n");
2478 printf(" ncacn_np:myserver[samr]\n");
2479 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2480 printf(" ncacn_np:myserver[/pipe/samr]\n");
2481 printf(" ncacn_np:myserver[samr,sign,print]\n");
2482 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2483 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2484 printf(" ncacn_np:\n");
2485 printf(" ncacn_np:[/pipe/samr]\n\n");
2487 printf(" ncacn_ip_tcp:myserver\n");
2488 printf(" ncacn_ip_tcp:myserver[1024]\n");
2489 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2491 printf("The unc format is:\n\n");
2493 printf(" //server/share\n\n");
2495 printf("tests are:");
2496 for (i=0;torture_ops[i].name;i++) {
2497 if ((i%perline)==0) {
2500 printf("%s ", torture_ops[i].name);
2504 printf("default test is ALL\n");
2509 static BOOL is_binding_string(const char *binding_string)
2511 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2512 struct dcerpc_binding *binding_struct;
2515 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2517 talloc_free(mem_ctx);
2518 return NT_STATUS_IS_OK(status);
2521 static void max_runtime_handler(int sig)
2523 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2527 /****************************************************************************
2529 ****************************************************************************/
2530 int main(int argc,char *argv[])
2534 BOOL correct = True;
2539 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,OPT_DANGEROUS};
2540 struct poptOption long_options[] = {
2542 {"smb-ports", 'p', POPT_ARG_STRING, NULL, 0, "SMB ports", NULL},
2543 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2544 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2545 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2546 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2547 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2548 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2549 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2550 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2551 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2552 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2553 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2554 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2555 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2556 "set maximum time for smbtorture to live", "seconds"},
2558 POPT_COMMON_CONNECTION
2559 POPT_COMMON_CREDENTIALS
2564 #ifdef HAVE_SETBUFFER
2565 setbuffer(stdout, NULL, 0);
2568 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2569 POPT_CONTEXT_KEEP_FIRST);
2571 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2573 while((opt = poptGetNextOpt(pc)) != -1) {
2576 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2579 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2582 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2585 parse_dns(poptGetOptArg(pc));
2588 lp_set_cmdline("torture:dangerous", "Yes");
2591 d_printf("Invalid option %s: %s\n",
2592 poptBadOption(pc, 0), poptStrerror(opt));
2599 /* this will only work if nobody else uses alarm(),
2600 which means it won't work for some tests, but we
2601 can't use the event context method we use for smbd
2602 as so many tests create their own event
2603 context. This will at least catch most cases. */
2604 signal(SIGALRM, max_runtime_handler);
2608 smbtorture_init_subsystems;
2611 if (torture_seed == 0) {
2612 torture_seed = time(NULL);
2614 printf("Using seed %d\n", torture_seed);
2615 srandom(torture_seed);
2617 argv_new = discard_const_p(char *, poptGetArgs(pc));
2620 for (i=0; i<argc; i++) {
2621 if (argv_new[i] == NULL) {
2632 for(p = argv_new[1]; *p; p++) {
2637 /* see if its a RPC transport specifier */
2638 if (is_binding_string(argv_new[1])) {
2639 lp_set_cmdline("torture:binding", argv_new[1]);
2641 char *binding = NULL;
2642 const char *host = NULL, *share = NULL;
2644 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
2645 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
2649 lp_set_cmdline("torture:host", host);
2650 lp_set_cmdline("torture:share", share);
2651 asprintf(&binding, "ncacn_np:%s", host);
2652 lp_set_cmdline("torture:binding", binding);
2655 if (argc_new == 0) {
2656 printf("You must specify a test to run, or 'ALL'\n");
2658 for (i=2;i<argc_new;i++) {
2659 if (!run_test(argv_new[i])) {