2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "dynconfig.h"
24 #include "lib/cmdline/popt_common.h"
25 #include "libcli/raw/libcliraw.h"
26 #include "system/time.h"
27 #include "system/wait.h"
28 #include "system/filesys.h"
30 #include "librpc/gen_ndr/ndr_security.h"
33 int torture_numops=100;
34 int torture_entries=1000;
35 int torture_failures=1;
37 static int procnum; /* records process count number when forking */
38 static struct smbcli_state *current_cli;
39 static BOOL use_oplocks;
40 static BOOL use_level_II_oplocks;
42 BOOL torture_showall = False;
44 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
46 static struct smbcli_state *open_nbt_connection(void)
48 struct nbt_name called, calling;
49 struct smbcli_state *cli;
50 const char *host = lp_parm_string(-1, "torture", "host");
52 make_nbt_name_client(&calling, lp_netbios_name());
54 nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
56 cli = smbcli_state_init(NULL);
58 printf("Failed initialize smbcli_struct to connect with %s\n", host);
62 if (!smbcli_socket_connect(cli, host)) {
63 printf("Failed to connect with %s\n", host);
67 if (!smbcli_transport_establish(cli, &calling, &called)) {
68 printf("%s rejected the session\n",host);
79 BOOL torture_open_connection_share(struct smbcli_state **c,
81 const char *sharename)
85 status = smbcli_full_connection(NULL,
88 cmdline_credentials, NULL);
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(c, host, share);
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", bytes_written, 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", bytes_read, 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<10000;i++) {
904 struct smbcli_request *req;
905 time_t t1 = time(NULL);
906 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
907 while (req->state == SMBCLI_REQUEST_SEND && time(NULL) < t1+5) {
908 smbcli_transport_process(cli->transport);
910 if (req->state == SMBCLI_REQUEST_ERROR) {
911 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
912 torture_close_connection(cli);
915 if (req->state == SMBCLI_REQUEST_SEND) {
921 printf("send buffer failed to fill\n");
922 if (!torture_close_connection(cli)) {
928 printf("send buffer filled after %d requests\n", i);
930 printf("Opening secondary connection\n");
931 if (!torture_open_connection(&cli2)) {
935 if (!torture_close_connection(cli)) {
939 if (!torture_close_connection(cli2)) {
943 printf("finished negprot nowait test\n");
950 This checks how the getatr calls works
952 static BOOL run_attrtest(void)
954 struct smbcli_state *cli;
957 const char *fname = "\\attrib123456789.tst";
960 printf("starting attrib test\n");
962 if (!torture_open_connection(&cli)) {
966 smbcli_unlink(cli->tree, fname);
967 fnum = smbcli_open(cli->tree, fname,
968 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
969 smbcli_close(cli->tree, fnum);
971 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
972 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
976 printf("New file time is %s", ctime(&t));
978 if (abs(t - time(NULL)) > 60*60*24*10) {
979 printf("ERROR: SMBgetatr bug. time is %s",
985 t2 = t-60*60*24; /* 1 day ago */
987 printf("Setting file time to %s", ctime(&t2));
989 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
990 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
994 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
995 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
999 printf("Retrieved file time as %s", ctime(&t));
1002 printf("ERROR: getatr/setatr bug. times are\n%s",
1004 printf("%s", ctime(&t2));
1008 smbcli_unlink(cli->tree, fname);
1010 if (!torture_close_connection(cli)) {
1014 printf("attrib test finished\n");
1021 This checks a couple of trans2 calls
1023 static BOOL run_trans2test(void)
1025 struct smbcli_state *cli;
1028 time_t c_time, a_time, m_time, w_time, m_time2;
1029 const char *fname = "\\trans2.tst";
1030 const char *dname = "\\trans2";
1031 const char *fname2 = "\\trans2\\trans2.tst";
1033 BOOL correct = True;
1035 printf("starting trans2 test\n");
1037 if (!torture_open_connection(&cli)) {
1041 smbcli_unlink(cli->tree, fname);
1043 printf("Testing qfileinfo\n");
1045 fnum = smbcli_open(cli->tree, fname,
1046 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1047 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
1049 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
1053 printf("Testing NAME_INFO\n");
1055 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
1056 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
1060 if (!pname || strcmp(pname, fname)) {
1061 printf("qfilename gave different name? [%s] [%s]\n",
1066 smbcli_close(cli->tree, fnum);
1067 smbcli_unlink(cli->tree, fname);
1069 fnum = smbcli_open(cli->tree, fname,
1070 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1072 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1075 smbcli_close(cli->tree, fnum);
1077 printf("Checking for sticky create times\n");
1079 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1080 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
1083 if (c_time != m_time) {
1084 printf("create time=%s", ctime(&c_time));
1085 printf("modify time=%s", ctime(&m_time));
1086 printf("This system appears to have sticky create times\n");
1088 if (a_time % (60*60) == 0) {
1089 printf("access time=%s", ctime(&a_time));
1090 printf("This system appears to set a midnight access time\n");
1094 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1095 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1101 smbcli_unlink(cli->tree, fname);
1102 fnum = smbcli_open(cli->tree, fname,
1103 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1104 smbcli_close(cli->tree, fnum);
1105 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1106 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1109 if (w_time < 60*60*24*2) {
1110 printf("write time=%s", ctime(&w_time));
1111 printf("This system appears to set a initial 0 write time\n");
1116 smbcli_unlink(cli->tree, fname);
1119 /* check if the server updates the directory modification time
1120 when creating a new file */
1121 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1122 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
1126 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1127 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1131 fnum = smbcli_open(cli->tree, fname2,
1132 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1133 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
1134 smbcli_close(cli->tree, fnum);
1135 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
1136 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1139 if (m_time2 == m_time) {
1140 printf("This system does not update directory modification times\n");
1144 smbcli_unlink(cli->tree, fname2);
1145 smbcli_rmdir(cli->tree, dname);
1147 if (!torture_close_connection(cli)) {
1151 printf("trans2 test finished\n");
1158 /* FIRST_DESIRED_ACCESS 0xf019f */
1159 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1160 SEC_FILE_READ_EA| /* 0xf */ \
1161 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1162 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1163 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1164 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1165 /* SECOND_DESIRED_ACCESS 0xe0080 */
1166 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1167 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1168 SEC_STD_WRITE_OWNER /* 0xe0000 */
1171 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1172 READ_CONTROL|WRITE_DAC|\
1173 SEC_FILE_READ_DATA|\
1178 Test ntcreate calls made by xcopy
1180 static BOOL run_xcopy(void)
1182 struct smbcli_state *cli1;
1183 const char *fname = "\\test.txt";
1184 BOOL correct = True;
1187 printf("starting xcopy test\n");
1189 if (!torture_open_connection(&cli1)) {
1193 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1194 FIRST_DESIRED_ACCESS,
1195 FILE_ATTRIBUTE_ARCHIVE,
1196 NTCREATEX_SHARE_ACCESS_NONE,
1197 NTCREATEX_DISP_OVERWRITE_IF,
1201 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
1205 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1206 SECOND_DESIRED_ACCESS, 0,
1207 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1210 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
1214 if (!torture_close_connection(cli1)) {
1223 see how many RPC pipes we can open at once
1225 static BOOL run_pipe_number(void)
1227 struct smbcli_state *cli1;
1228 const char *pipe_name = "\\WKSSVC";
1232 printf("starting pipenumber test\n");
1233 if (!torture_open_connection(&cli1)) {
1238 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1239 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1242 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
1246 printf("%d\r", num_pipes);
1250 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
1251 torture_close_connection(cli1);
1259 open N connections to the server and just hold them open
1260 used for testing performance when there are N idle users
1263 static BOOL torture_holdcon(void)
1266 struct smbcli_state **cli;
1269 printf("Opening %d connections\n", torture_numops);
1271 cli = malloc_array_p(struct smbcli_state *, torture_numops);
1273 for (i=0;i<torture_numops;i++) {
1274 if (!torture_open_connection(&cli[i])) {
1277 printf("opened %d connections\r", i);
1281 printf("\nStarting pings\n");
1284 for (i=0;i<torture_numops;i++) {
1287 status = smbcli_chkpath(cli[i]->tree, "\\");
1288 if (!NT_STATUS_IS_OK(status)) {
1289 printf("Connection %d is dead\n", i);
1297 if (num_dead == torture_numops) {
1298 printf("All connections dead - finishing\n");
1310 Try with a wrong vuid and check error message.
1313 static BOOL run_vuidtest(void)
1315 struct smbcli_state *cli;
1316 const char *fname = "\\vuid.tst";
1319 time_t c_time, a_time, m_time;
1320 BOOL correct = True;
1325 printf("starting vuid test\n");
1327 if (!torture_open_connection(&cli)) {
1331 smbcli_unlink(cli->tree, fname);
1333 fnum = smbcli_open(cli->tree, fname,
1334 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1336 orig_vuid = cli->session->vuid;
1338 cli->session->vuid += 1234;
1340 printf("Testing qfileinfo with wrong vuid\n");
1342 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
1343 &size, &c_time, &a_time,
1344 &m_time, NULL, NULL))) {
1345 printf("ERROR: qfileinfo passed with wrong vuid\n");
1349 if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1350 NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
1351 !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1352 NT_STATUS_INVALID_HANDLE)) {
1353 printf("ERROR: qfileinfo should have returned DOS error "
1354 "ERRSRV:ERRbaduid\n but returned %s\n",
1355 smbcli_errstr(cli->tree));
1359 cli->session->vuid -= 1234;
1361 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1362 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
1366 smbcli_unlink(cli->tree, fname);
1368 if (!torture_close_connection(cli)) {
1372 printf("vuid test finished\n");
1378 Test open mode returns on read-only files.
1380 static BOOL run_opentest(void)
1382 static struct smbcli_state *cli1;
1383 static struct smbcli_state *cli2;
1384 const char *fname = "\\readonly.file";
1385 char *control_char_fname;
1389 BOOL correct = True;
1394 printf("starting open test\n");
1396 if (!torture_open_connection(&cli1)) {
1400 asprintf(&control_char_fname, "\\readonly.afile");
1401 for (i = 1; i <= 0x1f; i++) {
1402 control_char_fname[10] = i;
1403 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
1404 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1406 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
1407 NT_STATUS_OBJECT_NAME_INVALID)) {
1408 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
1409 smbcli_errstr(cli1->tree), i);
1414 smbcli_close(cli1->tree, fnum1);
1416 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
1417 smbcli_unlink(cli1->tree, control_char_fname);
1419 free(control_char_fname);
1422 printf("Create file with control char names passed.\n");
1424 smbcli_setatr(cli1->tree, fname, 0, 0);
1425 smbcli_unlink(cli1->tree, fname);
1427 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1429 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1433 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1434 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1438 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
1439 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
1440 CHECK_MAX_FAILURES(error_test1);
1444 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1446 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1447 CHECK_MAX_FAILURES(error_test1);
1451 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
1452 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1454 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
1455 NT_STATUS_ACCESS_DENIED)) {
1456 printf("correct error code ERRDOS/ERRnoaccess returned\n");
1459 printf("finished open test 1\n");
1461 smbcli_close(cli1->tree, fnum1);
1463 /* Now try not readonly and ensure ERRbadshare is returned. */
1465 smbcli_setatr(cli1->tree, fname, 0, 0);
1467 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1469 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1473 /* This will fail - but the error should be ERRshare. */
1474 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1476 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
1477 NT_STATUS_SHARING_VIOLATION)) {
1478 printf("correct error code ERRDOS/ERRbadshare returned\n");
1481 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1482 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1486 smbcli_unlink(cli1->tree, fname);
1488 printf("finished open test 2\n");
1490 /* Test truncate open disposition on file opened for read. */
1492 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1494 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1498 /* write 20 bytes. */
1500 memset(buf, '\0', 20);
1502 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1503 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1507 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1508 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1512 /* Ensure size == 20. */
1513 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1514 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1515 CHECK_MAX_FAILURES(error_test3);
1520 printf("(3) file size != 20\n");
1521 CHECK_MAX_FAILURES(error_test3);
1525 /* Now test if we can truncate a file opened for readonly. */
1527 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
1529 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1530 CHECK_MAX_FAILURES(error_test3);
1534 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1535 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1539 /* Ensure size == 0. */
1540 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1541 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1542 CHECK_MAX_FAILURES(error_test3);
1547 printf("(3) file size != 0\n");
1548 CHECK_MAX_FAILURES(error_test3);
1551 printf("finished open test 3\n");
1553 smbcli_unlink(cli1->tree, fname);
1556 printf("testing ctemp\n");
1557 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
1559 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1560 CHECK_MAX_FAILURES(error_test4);
1563 printf("ctemp gave path %s\n", tmp_path);
1564 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1565 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1567 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1568 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1571 /* Test the non-io opens... */
1573 if (!torture_open_connection(&cli2)) {
1577 smbcli_setatr(cli2->tree, fname, 0, 0);
1578 smbcli_unlink(cli2->tree, fname);
1580 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1582 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1583 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1586 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1587 CHECK_MAX_FAILURES(error_test10);
1591 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1592 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1594 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1595 CHECK_MAX_FAILURES(error_test10);
1599 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1600 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1603 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1604 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1608 printf("non-io open test #1 passed.\n");
1610 smbcli_unlink(cli1->tree, fname);
1612 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1614 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1615 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1618 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1619 CHECK_MAX_FAILURES(error_test20);
1623 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1624 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1627 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1628 CHECK_MAX_FAILURES(error_test20);
1632 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1633 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1636 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1637 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1641 printf("non-io open test #2 passed.\n");
1643 smbcli_unlink(cli1->tree, fname);
1645 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1647 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1648 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1651 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1652 CHECK_MAX_FAILURES(error_test30);
1656 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1657 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1660 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1661 CHECK_MAX_FAILURES(error_test30);
1665 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1666 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1669 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1670 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1674 printf("non-io open test #3 passed.\n");
1676 smbcli_unlink(cli1->tree, fname);
1678 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1680 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1681 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1684 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1685 CHECK_MAX_FAILURES(error_test40);
1689 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1690 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1693 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1694 CHECK_MAX_FAILURES(error_test40);
1698 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1700 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1701 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1705 printf("non-io open test #4 passed.\n");
1707 smbcli_unlink(cli1->tree, fname);
1709 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1711 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1712 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1715 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1716 CHECK_MAX_FAILURES(error_test50);
1720 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1721 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1724 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1725 CHECK_MAX_FAILURES(error_test50);
1729 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1730 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1734 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1735 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1739 printf("non-io open test #5 passed.\n");
1741 printf("TEST #6 testing 1 non-io open, one io open\n");
1743 smbcli_unlink(cli1->tree, fname);
1745 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1746 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1749 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1750 CHECK_MAX_FAILURES(error_test60);
1754 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1755 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1758 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1759 CHECK_MAX_FAILURES(error_test60);
1763 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1764 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1768 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1769 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1773 printf("non-io open test #6 passed.\n");
1775 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
1777 smbcli_unlink(cli1->tree, fname);
1779 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1780 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1783 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1784 CHECK_MAX_FAILURES(error_test70);
1788 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1789 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1792 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1793 CHECK_MAX_FAILURES(error_test70);
1797 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1799 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1800 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1804 printf("non-io open test #7 passed.\n");
1808 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1810 smbcli_unlink(cli1->tree, fname);
1812 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1814 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1818 /* write 20 bytes. */
1820 memset(buf, '\0', 20);
1822 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1823 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1827 /* Ensure size == 20. */
1828 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1829 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1830 CHECK_MAX_FAILURES(error_test80);
1835 printf("(8) file size != 20\n");
1836 CHECK_MAX_FAILURES(error_test80);
1840 /* Get an exclusive lock on the open file. */
1841 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1842 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1843 CHECK_MAX_FAILURES(error_test80);
1847 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1849 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1853 /* Ensure size == 0. */
1854 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1855 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1856 CHECK_MAX_FAILURES(error_test80);
1861 printf("(8) file size != 0\n");
1862 CHECK_MAX_FAILURES(error_test80);
1866 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1867 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1871 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1872 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1878 printf("open test #8 passed.\n");
1880 smbcli_unlink(cli1->tree, fname);
1882 if (!torture_close_connection(cli1)) {
1885 if (!torture_close_connection(cli2)) {
1894 sees what IOCTLs are supported
1896 BOOL torture_ioctl_test(void)
1898 struct smbcli_state *cli;
1899 uint16_t device, function;
1901 const char *fname = "\\ioctl.dat";
1903 union smb_ioctl parms;
1904 TALLOC_CTX *mem_ctx;
1906 if (!torture_open_connection(&cli)) {
1910 mem_ctx = talloc_init("ioctl_test");
1912 printf("starting ioctl test\n");
1914 smbcli_unlink(cli->tree, fname);
1916 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1918 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1922 parms.ioctl.level = RAW_IOCTL_IOCTL;
1923 parms.ioctl.in.fnum = fnum;
1924 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
1925 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1926 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
1928 for (device=0;device<0x100;device++) {
1929 printf("testing device=0x%x\n", device);
1930 for (function=0;function<0x100;function++) {
1931 parms.ioctl.in.request = (device << 16) | function;
1932 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1934 if (NT_STATUS_IS_OK(status)) {
1935 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
1936 device, function, parms.ioctl.out.blob.length);
1941 if (!torture_close_connection(cli)) {
1950 tries variants of chkpath
1952 BOOL torture_chkpath_test(void)
1954 struct smbcli_state *cli;
1958 if (!torture_open_connection(&cli)) {
1962 printf("starting chkpath test\n");
1964 printf("Testing valid and invalid paths\n");
1966 /* cleanup from an old run */
1967 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1968 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1969 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1971 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1972 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1976 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1977 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1981 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1983 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
1986 smbcli_close(cli->tree, fnum);
1988 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1989 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1993 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1994 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1998 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1999 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2000 NT_STATUS_NOT_A_DIRECTORY);
2002 printf("* chkpath on a file should fail\n");
2006 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
2007 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2008 NT_STATUS_OBJECT_NAME_NOT_FOUND);
2010 printf("* chkpath on a non existent file should fail\n");
2014 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
2015 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2016 NT_STATUS_OBJECT_PATH_NOT_FOUND);
2018 printf("* chkpath on a non existent component should fail\n");
2022 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
2023 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
2024 smbcli_rmdir(cli->tree, "\\chkpath.dir");
2026 if (!torture_close_connection(cli)) {
2034 static void sigcont(int sig)
2038 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
2041 volatile pid_t *child_status;
2042 volatile BOOL *child_status_out;
2045 double start_time_limit = 10 + (torture_nprocs * 1.5);
2046 char **unc_list = NULL;
2048 int num_unc_names = 0;
2055 signal(SIGCONT, sigcont);
2057 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
2058 if (!child_status) {
2059 printf("Failed to setup shared memory\n");
2063 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
2064 if (!child_status_out) {
2065 printf("Failed to setup result status shared memory\n");
2069 p = lp_parm_string(-1, "torture", "unclist");
2071 unc_list = file_lines_load(p, &num_unc_names, NULL);
2072 if (!unc_list || num_unc_names <= 0) {
2073 printf("Failed to load unc names list from '%s'\n", p);
2078 for (i = 0; i < torture_nprocs; i++) {
2079 child_status[i] = 0;
2080 child_status_out[i] = True;
2083 tv = timeval_current();
2085 for (i=0;i<torture_nprocs;i++) {
2089 const char *hostname=NULL, *sharename;
2091 pid_t mypid = getpid();
2092 srandom(((int)mypid) ^ ((int)time(NULL)));
2094 asprintf(&myname, "CLIENT%d", i);
2095 lp_set_cmdline("netbios name", myname);
2100 if (!smbcli_parse_unc(unc_list[i % num_unc_names],
2101 NULL, &hostname, &sharename)) {
2102 printf("Failed to parse UNC name %s\n",
2103 unc_list[i % num_unc_names]);
2110 if (torture_open_connection_share(¤t_cli,
2115 } else if (torture_open_connection(¤t_cli)) {
2119 printf("pid %d failed to start\n", (int)getpid());
2125 child_status[i] = getpid();
2129 if (child_status[i]) {
2130 printf("Child %d failed to start!\n", i);
2131 child_status_out[i] = 1;
2135 child_status_out[i] = fn(current_cli, i);
2142 for (i=0;i<torture_nprocs;i++) {
2143 if (child_status[i]) synccount++;
2145 if (synccount == torture_nprocs) break;
2147 } while (timeval_elapsed(&tv) < start_time_limit);
2149 if (synccount != torture_nprocs) {
2150 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
2152 return timeval_elapsed(&tv);
2155 printf("Starting %d clients\n", torture_nprocs);
2157 /* start the client load */
2158 tv = timeval_current();
2159 for (i=0;i<torture_nprocs;i++) {
2160 child_status[i] = 0;
2163 printf("%d clients started\n", torture_nprocs);
2167 for (i=0;i<torture_nprocs;i++) {
2169 while ((ret=sys_waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
2170 if (ret == -1 || WEXITSTATUS(status) != 0) {
2177 for (i=0;i<torture_nprocs;i++) {
2178 if (!child_status_out[i]) {
2182 return timeval_elapsed(&tv);
2185 #define FLAG_MULTIPROC 1
2190 BOOL (*multi_fn)(struct smbcli_state *, int );
2193 {"BASE-FDPASS", run_fdpasstest, 0},
2194 {"BASE-LOCK1", torture_locktest1, 0},
2195 {"BASE-LOCK2", torture_locktest2, 0},
2196 {"BASE-LOCK3", torture_locktest3, 0},
2197 {"BASE-LOCK4", torture_locktest4, 0},
2198 {"BASE-LOCK5", torture_locktest5, 0},
2199 {"BASE-LOCK6", torture_locktest6, 0},
2200 {"BASE-LOCK7", torture_locktest7, 0},
2201 {"BASE-UNLINK", torture_unlinktest, 0},
2202 {"BASE-ATTR", run_attrtest, 0},
2203 {"BASE-TRANS2", run_trans2test, 0},
2204 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
2205 {"BASE-DIR1", torture_dirtest1, 0},
2206 {"BASE-DIR2", torture_dirtest2, 0},
2207 {"BASE-DENY1", torture_denytest1, 0},
2208 {"BASE-DENY2", torture_denytest2, 0},
2209 {"BASE-DENY3", torture_denytest3, 0},
2210 {"BASE-DENYDOS", torture_denydos_sharing, 0},
2211 {"BASE-NTDENY1", NULL, torture_ntdenytest1},
2212 {"BASE-NTDENY2", torture_ntdenytest2, 0},
2213 {"BASE-TCON", run_tcon_test, 0},
2214 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
2215 {"BASE-VUID", run_vuidtest, 0},
2216 {"BASE-RW1", run_readwritetest, 0},
2217 {"BASE-OPEN", run_opentest, 0},
2218 {"BASE-DEFER_OPEN", NULL, run_deferopen},
2219 {"BASE-XCOPY", run_xcopy, 0},
2220 {"BASE-RENAME", torture_test_rename, 0},
2221 {"BASE-DELETE", torture_test_delete, 0},
2222 {"BASE-PROPERTIES", torture_test_properties, 0},
2223 {"BASE-MANGLE", torture_mangle, 0},
2224 {"BASE-OPENATTR", torture_openattrtest, 0},
2225 {"BASE-CHARSET", torture_charset, 0},
2226 {"BASE-CHKPATH", torture_chkpath_test, 0},
2227 {"BASE-SECLEAK", torture_sec_leak, 0},
2228 {"BASE-DISCONNECT", torture_disconnect, 0},
2229 {"BASE-DELAYWRITE", torture_delay_write, 0},
2231 /* benchmarking tests */
2232 {"BENCH-HOLDCON", torture_holdcon, 0},
2233 {"BENCH-NBENCH", torture_nbench, 0},
2234 {"BENCH-TORTURE", NULL, run_torture},
2235 {"BENCH-NBT", torture_bench_nbt, 0},
2236 {"BENCH-WINS", torture_bench_wins, 0},
2237 {"BENCH-RPC", torture_bench_rpc, 0},
2238 {"BENCH-CLDAP", torture_bench_cldap, 0},
2241 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
2242 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
2243 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
2244 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
2245 {"RAW-SEARCH", torture_raw_search, 0},
2246 {"RAW-CLOSE", torture_raw_close, 0},
2247 {"RAW-OPEN", torture_raw_open, 0},
2248 {"RAW-MKDIR", torture_raw_mkdir, 0},
2249 {"RAW-OPLOCK", torture_raw_oplock, 0},
2250 {"RAW-NOTIFY", torture_raw_notify, 0},
2251 {"RAW-MUX", torture_raw_mux, 0},
2252 {"RAW-IOCTL", torture_raw_ioctl, 0},
2253 {"RAW-CHKPATH", torture_raw_chkpath, 0},
2254 {"RAW-UNLINK", torture_raw_unlink, 0},
2255 {"RAW-READ", torture_raw_read, 0},
2256 {"RAW-WRITE", torture_raw_write, 0},
2257 {"RAW-LOCK", torture_raw_lock, 0},
2258 {"RAW-CONTEXT", torture_raw_context, 0},
2259 {"RAW-RENAME", torture_raw_rename, 0},
2260 {"RAW-SEEK", torture_raw_seek, 0},
2261 {"RAW-EAS", torture_raw_eas, 0},
2262 {"RAW-EAMAX", torture_max_eas, 0},
2263 {"RAW-STREAMS", torture_raw_streams, 0},
2264 {"RAW-ACLS", torture_raw_acls, 0},
2265 {"RAW-RAP", torture_raw_rap, 0},
2266 {"RAW-COMPOSITE", torture_raw_composite, 0},
2268 /* protocol scanners */
2269 {"SCAN-TRANS2", torture_trans2_scan, 0},
2270 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2271 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2272 {"SCAN-SMB", torture_smb_scan, 0},
2273 {"SCAN-MAXFID", NULL, run_maxfidtest},
2274 {"SCAN-UTABLE", torture_utable, 0},
2275 {"SCAN-CASETABLE", torture_casetable, 0},
2276 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2277 {"SCAN-IOCTL", torture_ioctl_test, 0},
2278 {"SCAN-RAP", torture_rap_scan, 0},
2281 {"RPC-LSA", torture_rpc_lsa, 0},
2282 {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
2283 {"RPC-ECHO", torture_rpc_echo, 0},
2284 {"RPC-DFS", torture_rpc_dfs, 0},
2285 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2286 {"RPC-SAMR", torture_rpc_samr, 0},
2287 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2288 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2289 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2290 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2291 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2292 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2293 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2294 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2295 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2296 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2297 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2298 {"RPC-WINREG", torture_rpc_winreg, 0},
2299 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2300 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2301 {"RPC-REMACT", torture_rpc_remact, 0},
2302 {"RPC-MGMT", torture_rpc_mgmt, 0},
2303 {"RPC-SCANNER", torture_rpc_scanner, 0},
2304 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2305 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2306 {"RPC-MULTIBIND", torture_multi_bind, 0},
2307 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2308 {"RPC-LOGIN", torture_rpc_login, 0},
2309 {"RPC-ROT", torture_rpc_rot, 0},
2310 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2311 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2313 /* local (no server) testers */
2314 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2315 {"LOCAL-ICONV", torture_local_iconv, 0},
2316 {"LOCAL-TALLOC", torture_local_talloc, 0},
2317 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2318 {"LOCAL-IRPC", torture_local_irpc, 0},
2319 {"LOCAL-BINDING", torture_local_binding_string, 0},
2320 {"LOCAL-IDTREE", torture_local_idtree, 0},
2321 {"LOCAL-SOCKET", torture_local_socket, 0},
2322 {"LOCAL-PAC", torture_pac, 0},
2324 /* COM (Component Object Model) testers */
2325 {"COM-SIMPLE", torture_com_simple, 0 },
2328 {"LDAP-BASIC", torture_ldap_basic, 0},
2329 {"LDAP-CLDAP", torture_cldap, 0},
2332 {"NBT-REGISTER", torture_nbt_register, 0},
2333 {"NBT-WINS", torture_nbt_wins, 0},
2334 {"NBT-WINSREPLICATION", torture_nbt_winsreplication, 0},
2335 {"NBT-DGRAM", torture_nbt_dgram, 0},
2338 {"NET-USERINFO", torture_userinfo, 0},
2339 {"NET-USERADD", torture_useradd, 0},
2340 {"NET-USERDEL", torture_userdel, 0},
2341 {"NET-DOMOPEN", torture_domainopen, 0},
2342 {"NET-API-LOOKUP", torture_lookup, 0},
2343 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2344 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2345 {"NET-API-CREATEUSER", torture_createuser, 0},
2346 {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
2352 /****************************************************************************
2353 run a specified test or "ALL"
2354 ****************************************************************************/
2355 static BOOL run_test(const char *name)
2359 BOOL matched = False;
2361 if (strequal(name,"ALL")) {
2362 for (i=0;torture_ops[i].name;i++) {
2363 if (!run_test(torture_ops[i].name)) {
2370 for (i=0;torture_ops[i].name;i++) {
2371 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
2375 printf("Running %s\n", torture_ops[i].name);
2376 if (torture_ops[i].multi_fn) {
2377 BOOL result = False;
2378 t = torture_create_procs(torture_ops[i].multi_fn,
2382 printf("TEST %s FAILED!\n", torture_ops[i].name);
2386 struct timeval tv = timeval_current();
2387 if (!torture_ops[i].fn()) {
2389 printf("TEST %s FAILED!\n", torture_ops[i].name);
2391 t = timeval_elapsed(&tv);
2393 printf("%s took %g secs\n\n", torture_ops[i].name, t);
2398 printf("Unknown torture operation '%s'\n", name);
2405 static void parse_dns(const char *dns)
2407 char *userdn, *basedn, *secret;
2410 /* retrievieng the userdn */
2411 p = strchr_m(dns, '#');
2413 lp_set_cmdline("torture:ldap_userdn", "");
2414 lp_set_cmdline("torture:ldap_basedn", "");
2415 lp_set_cmdline("torture:ldap_secret", "");
2418 userdn = strndup(dns, p - dns);
2419 lp_set_cmdline("torture:ldap_userdn", userdn);
2421 /* retrieve the basedn */
2423 p = strchr_m(d, '#');
2425 lp_set_cmdline("torture:ldap_basedn", "");
2426 lp_set_cmdline("torture:ldap_secret", "");
2429 basedn = strndup(d, p - d);
2430 lp_set_cmdline("torture:ldap_basedn", basedn);
2432 /* retrieve the secret */
2435 lp_set_cmdline("torture:ldap_secret", "");
2439 lp_set_cmdline("torture:ldap_secret", secret);
2441 printf ("%s - %s - %s\n", userdn, basedn, secret);
2445 static void usage(poptContext pc)
2450 poptPrintUsage(pc, stdout, 0);
2453 printf("The binding format is:\n\n");
2455 printf(" TRANSPORT:host[flags]\n\n");
2457 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2459 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2460 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2461 printf(" string.\n\n");
2463 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2464 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2465 printf(" will be auto-determined.\n\n");
2467 printf(" other recognised flags are:\n\n");
2469 printf(" sign : enable ntlmssp signing\n");
2470 printf(" seal : enable ntlmssp sealing\n");
2471 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2472 printf(" validate: enable the NDR validator\n");
2473 printf(" print: enable debugging of the packets\n");
2474 printf(" bigendian: use bigendian RPC\n");
2475 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2477 printf(" For example, these all connect to the samr pipe:\n\n");
2479 printf(" ncacn_np:myserver\n");
2480 printf(" ncacn_np:myserver[samr]\n");
2481 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2482 printf(" ncacn_np:myserver[/pipe/samr]\n");
2483 printf(" ncacn_np:myserver[samr,sign,print]\n");
2484 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2485 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2486 printf(" ncacn_np:\n");
2487 printf(" ncacn_np:[/pipe/samr]\n\n");
2489 printf(" ncacn_ip_tcp:myserver\n");
2490 printf(" ncacn_ip_tcp:myserver[1024]\n");
2491 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2493 printf("The unc format is:\n\n");
2495 printf(" //server/share\n\n");
2497 printf("tests are:");
2498 for (i=0;torture_ops[i].name;i++) {
2499 if ((i%perline)==0) {
2502 printf("%s ", torture_ops[i].name);
2506 printf("default test is ALL\n");
2511 static BOOL is_binding_string(const char *binding_string)
2513 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2514 struct dcerpc_binding *binding_struct;
2517 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2519 talloc_free(mem_ctx);
2520 return NT_STATUS_IS_OK(status);
2523 static void max_runtime_handler(int sig)
2525 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2529 /****************************************************************************
2531 ****************************************************************************/
2532 int main(int argc,char *argv[])
2536 BOOL correct = True;
2541 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,OPT_DANGEROUS};
2542 struct poptOption long_options[] = {
2544 {"smb-ports", 'p', POPT_ARG_STRING, NULL, 0, "SMB ports", NULL},
2545 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2546 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2547 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2548 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2549 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2550 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2551 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2552 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2553 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2554 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2555 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2556 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2557 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2558 "set maximum time for smbtorture to live", "seconds"},
2560 POPT_COMMON_CONNECTION
2561 POPT_COMMON_CREDENTIALS
2566 #ifdef HAVE_SETBUFFER
2567 setbuffer(stdout, NULL, 0);
2570 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2571 POPT_CONTEXT_KEEP_FIRST);
2573 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2575 while((opt = poptGetNextOpt(pc)) != -1) {
2578 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2581 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2584 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2587 parse_dns(poptGetOptArg(pc));
2590 lp_set_cmdline("torture:dangerous", "Yes");
2593 d_printf("Invalid option %s: %s\n",
2594 poptBadOption(pc, 0), poptStrerror(opt));
2601 /* this will only work if nobody else uses alarm(),
2602 which means it won't work for some tests, but we
2603 can't use the event context method we use for smbd
2604 as so many tests create their own event
2605 context. This will at least catch most cases. */
2606 signal(SIGALRM, max_runtime_handler);
2610 smbtorture_init_subsystems;
2613 if (torture_seed == 0) {
2614 torture_seed = time(NULL);
2616 printf("Using seed %d\n", torture_seed);
2617 srandom(torture_seed);
2619 argv_new = discard_const_p(char *, poptGetArgs(pc));
2622 for (i=0; i<argc; i++) {
2623 if (argv_new[i] == NULL) {
2634 for(p = argv_new[1]; *p; p++) {
2639 /* see if its a RPC transport specifier */
2640 if (is_binding_string(argv_new[1])) {
2641 lp_set_cmdline("torture:binding", argv_new[1]);
2643 char *binding = NULL;
2644 const char *host = NULL, *share = NULL;
2646 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
2647 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
2651 lp_set_cmdline("torture:host", host);
2652 lp_set_cmdline("torture:share", share);
2653 asprintf(&binding, "ncacn_np:%s", host);
2654 lp_set_cmdline("torture:binding", binding);
2657 if (argc_new == 0) {
2658 printf("You must specify a test to run, or 'ALL'\n");
2660 for (i=2;i<argc_new;i++) {
2661 if (!run_test(argv_new[i])) {