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 class=%d code=%d\n",
197 (int)class, (int)num);
198 printf(" expected %d/%d %s (at %s)\n",
199 (int)eclass, (int)ecode, 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 printf("ERROR: qfileinfo should have returned DOS error "
1352 "ERRSRV:ERRbaduid\n but returned %s\n",
1353 smbcli_errstr(cli->tree));
1357 cli->session->vuid -= 1234;
1359 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1360 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
1364 smbcli_unlink(cli->tree, fname);
1366 if (!torture_close_connection(cli)) {
1370 printf("vuid test finished\n");
1376 Test open mode returns on read-only files.
1378 static BOOL run_opentest(void)
1380 static struct smbcli_state *cli1;
1381 static struct smbcli_state *cli2;
1382 const char *fname = "\\readonly.file";
1383 char *control_char_fname;
1387 BOOL correct = True;
1392 printf("starting open test\n");
1394 if (!torture_open_connection(&cli1)) {
1398 asprintf(&control_char_fname, "\\readonly.afile");
1399 for (i = 1; i <= 0x1f; i++) {
1400 control_char_fname[10] = i;
1401 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
1402 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1404 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
1405 NT_STATUS_OBJECT_NAME_INVALID)) {
1406 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
1407 smbcli_errstr(cli1->tree), i);
1412 smbcli_close(cli1->tree, fnum1);
1414 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
1415 smbcli_unlink(cli1->tree, control_char_fname);
1417 free(control_char_fname);
1420 printf("Create file with control char names passed.\n");
1422 smbcli_setatr(cli1->tree, fname, 0, 0);
1423 smbcli_unlink(cli1->tree, fname);
1425 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1427 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1431 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1432 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1436 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
1437 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
1438 CHECK_MAX_FAILURES(error_test1);
1442 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1444 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1445 CHECK_MAX_FAILURES(error_test1);
1449 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
1450 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1452 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
1453 NT_STATUS_ACCESS_DENIED)) {
1454 printf("correct error code ERRDOS/ERRnoaccess returned\n");
1457 printf("finished open test 1\n");
1459 smbcli_close(cli1->tree, fnum1);
1461 /* Now try not readonly and ensure ERRbadshare is returned. */
1463 smbcli_setatr(cli1->tree, fname, 0, 0);
1465 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1467 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1471 /* This will fail - but the error should be ERRshare. */
1472 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1474 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
1475 NT_STATUS_SHARING_VIOLATION)) {
1476 printf("correct error code ERRDOS/ERRbadshare returned\n");
1479 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1480 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1484 smbcli_unlink(cli1->tree, fname);
1486 printf("finished open test 2\n");
1488 /* Test truncate open disposition on file opened for read. */
1490 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1492 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1496 /* write 20 bytes. */
1498 memset(buf, '\0', 20);
1500 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1501 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1505 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1506 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1510 /* Ensure size == 20. */
1511 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1512 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1513 CHECK_MAX_FAILURES(error_test3);
1518 printf("(3) file size != 20\n");
1519 CHECK_MAX_FAILURES(error_test3);
1523 /* Now test if we can truncate a file opened for readonly. */
1525 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
1527 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1528 CHECK_MAX_FAILURES(error_test3);
1532 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1533 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1537 /* Ensure size == 0. */
1538 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1539 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1540 CHECK_MAX_FAILURES(error_test3);
1545 printf("(3) file size != 0\n");
1546 CHECK_MAX_FAILURES(error_test3);
1549 printf("finished open test 3\n");
1551 smbcli_unlink(cli1->tree, fname);
1554 printf("testing ctemp\n");
1555 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
1557 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1558 CHECK_MAX_FAILURES(error_test4);
1561 printf("ctemp gave path %s\n", tmp_path);
1562 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1563 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1565 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1566 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1569 /* Test the non-io opens... */
1571 if (!torture_open_connection(&cli2)) {
1575 smbcli_setatr(cli2->tree, fname, 0, 0);
1576 smbcli_unlink(cli2->tree, fname);
1578 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1580 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1581 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1584 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1585 CHECK_MAX_FAILURES(error_test10);
1589 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1590 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1592 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1593 CHECK_MAX_FAILURES(error_test10);
1597 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1598 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1601 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1602 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1606 printf("non-io open test #1 passed.\n");
1608 smbcli_unlink(cli1->tree, fname);
1610 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1612 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1613 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1616 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1617 CHECK_MAX_FAILURES(error_test20);
1621 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1622 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1625 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1626 CHECK_MAX_FAILURES(error_test20);
1630 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1631 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1634 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1635 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1639 printf("non-io open test #2 passed.\n");
1641 smbcli_unlink(cli1->tree, fname);
1643 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1645 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1646 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1649 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1650 CHECK_MAX_FAILURES(error_test30);
1654 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1655 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1658 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1659 CHECK_MAX_FAILURES(error_test30);
1663 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1664 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1667 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1668 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1672 printf("non-io open test #3 passed.\n");
1674 smbcli_unlink(cli1->tree, fname);
1676 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1678 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1679 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1682 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1683 CHECK_MAX_FAILURES(error_test40);
1687 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1688 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1691 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1692 CHECK_MAX_FAILURES(error_test40);
1696 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1698 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1699 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1703 printf("non-io open test #4 passed.\n");
1705 smbcli_unlink(cli1->tree, fname);
1707 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1709 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1710 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1713 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1714 CHECK_MAX_FAILURES(error_test50);
1718 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1719 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1722 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1723 CHECK_MAX_FAILURES(error_test50);
1727 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1728 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1732 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1733 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1737 printf("non-io open test #5 passed.\n");
1739 printf("TEST #6 testing 1 non-io open, one io open\n");
1741 smbcli_unlink(cli1->tree, fname);
1743 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1744 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1747 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1748 CHECK_MAX_FAILURES(error_test60);
1752 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1753 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1756 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1757 CHECK_MAX_FAILURES(error_test60);
1761 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1762 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1766 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1767 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1771 printf("non-io open test #6 passed.\n");
1773 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
1775 smbcli_unlink(cli1->tree, fname);
1777 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1778 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1781 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1782 CHECK_MAX_FAILURES(error_test70);
1786 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1787 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1790 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1791 CHECK_MAX_FAILURES(error_test70);
1795 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1797 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1798 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1802 printf("non-io open test #7 passed.\n");
1806 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1808 smbcli_unlink(cli1->tree, fname);
1810 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1812 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1816 /* write 20 bytes. */
1818 memset(buf, '\0', 20);
1820 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1821 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1825 /* Ensure size == 20. */
1826 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1827 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1828 CHECK_MAX_FAILURES(error_test80);
1833 printf("(8) file size != 20\n");
1834 CHECK_MAX_FAILURES(error_test80);
1838 /* Get an exclusive lock on the open file. */
1839 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1840 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1841 CHECK_MAX_FAILURES(error_test80);
1845 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1847 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1851 /* Ensure size == 0. */
1852 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1853 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1854 CHECK_MAX_FAILURES(error_test80);
1859 printf("(8) file size != 0\n");
1860 CHECK_MAX_FAILURES(error_test80);
1864 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1865 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1869 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1870 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1876 printf("open test #8 passed.\n");
1878 smbcli_unlink(cli1->tree, fname);
1880 if (!torture_close_connection(cli1)) {
1883 if (!torture_close_connection(cli2)) {
1892 sees what IOCTLs are supported
1894 BOOL torture_ioctl_test(void)
1896 struct smbcli_state *cli;
1897 uint16_t device, function;
1899 const char *fname = "\\ioctl.dat";
1901 union smb_ioctl parms;
1902 TALLOC_CTX *mem_ctx;
1904 if (!torture_open_connection(&cli)) {
1908 mem_ctx = talloc_init("ioctl_test");
1910 printf("starting ioctl test\n");
1912 smbcli_unlink(cli->tree, fname);
1914 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1916 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1920 parms.ioctl.level = RAW_IOCTL_IOCTL;
1921 parms.ioctl.in.fnum = fnum;
1922 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
1923 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1924 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
1926 for (device=0;device<0x100;device++) {
1927 printf("testing device=0x%x\n", device);
1928 for (function=0;function<0x100;function++) {
1929 parms.ioctl.in.request = (device << 16) | function;
1930 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1932 if (NT_STATUS_IS_OK(status)) {
1933 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
1934 device, function, parms.ioctl.out.blob.length);
1939 if (!torture_close_connection(cli)) {
1948 tries variants of chkpath
1950 BOOL torture_chkpath_test(void)
1952 struct smbcli_state *cli;
1956 if (!torture_open_connection(&cli)) {
1960 printf("starting chkpath test\n");
1962 printf("Testing valid and invalid paths\n");
1964 /* cleanup from an old run */
1965 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1966 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1967 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1969 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1970 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1974 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1975 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1979 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1981 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
1984 smbcli_close(cli->tree, fnum);
1986 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1987 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1991 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1992 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1996 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1997 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1998 NT_STATUS_NOT_A_DIRECTORY);
2000 printf("* chkpath on a file should fail\n");
2004 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
2005 ret = check_error(__location__, cli, ERRDOS, ERRbadfile,
2006 NT_STATUS_OBJECT_NAME_NOT_FOUND);
2008 printf("* chkpath on a non existent file should fail\n");
2012 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
2013 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2014 NT_STATUS_OBJECT_PATH_NOT_FOUND);
2016 printf("* chkpath on a non existent component should fail\n");
2020 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
2021 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
2022 smbcli_rmdir(cli->tree, "\\chkpath.dir");
2024 if (!torture_close_connection(cli)) {
2032 static void sigcont(int sig)
2036 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
2039 volatile pid_t *child_status;
2040 volatile BOOL *child_status_out;
2043 double start_time_limit = 10 + (torture_nprocs * 1.5);
2044 char **unc_list = NULL;
2046 int num_unc_names = 0;
2053 signal(SIGCONT, sigcont);
2055 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
2056 if (!child_status) {
2057 printf("Failed to setup shared memory\n");
2061 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
2062 if (!child_status_out) {
2063 printf("Failed to setup result status shared memory\n");
2067 p = lp_parm_string(-1, "torture", "unclist");
2069 unc_list = file_lines_load(p, &num_unc_names);
2070 if (!unc_list || num_unc_names <= 0) {
2071 printf("Failed to load unc names list from '%s'\n", p);
2076 for (i = 0; i < torture_nprocs; i++) {
2077 child_status[i] = 0;
2078 child_status_out[i] = True;
2081 tv = timeval_current();
2083 for (i=0;i<torture_nprocs;i++) {
2087 const char *hostname=NULL, *sharename;
2089 pid_t mypid = getpid();
2090 srandom(((int)mypid) ^ ((int)time(NULL)));
2092 asprintf(&myname, "CLIENT%d", i);
2093 lp_set_cmdline("netbios name", myname);
2098 if (!smbcli_parse_unc(unc_list[i % num_unc_names],
2099 NULL, &hostname, &sharename)) {
2100 printf("Failed to parse UNC name %s\n",
2101 unc_list[i % num_unc_names]);
2108 if (torture_open_connection_share(¤t_cli,
2113 } else if (torture_open_connection(¤t_cli)) {
2117 printf("pid %d failed to start\n", (int)getpid());
2123 child_status[i] = getpid();
2127 if (child_status[i]) {
2128 printf("Child %d failed to start!\n", i);
2129 child_status_out[i] = 1;
2133 child_status_out[i] = fn(current_cli, i);
2140 for (i=0;i<torture_nprocs;i++) {
2141 if (child_status[i]) synccount++;
2143 if (synccount == torture_nprocs) break;
2145 } while (timeval_elapsed(&tv) < start_time_limit);
2147 if (synccount != torture_nprocs) {
2148 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
2150 return timeval_elapsed(&tv);
2153 printf("Starting %d clients\n", torture_nprocs);
2155 /* start the client load */
2156 tv = timeval_current();
2157 for (i=0;i<torture_nprocs;i++) {
2158 child_status[i] = 0;
2161 printf("%d clients started\n", torture_nprocs);
2165 for (i=0;i<torture_nprocs;i++) {
2167 while ((ret=sys_waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
2168 if (ret == -1 || WEXITSTATUS(status) != 0) {
2175 for (i=0;i<torture_nprocs;i++) {
2176 if (!child_status_out[i]) {
2180 return timeval_elapsed(&tv);
2183 #define FLAG_MULTIPROC 1
2188 BOOL (*multi_fn)(struct smbcli_state *, int );
2191 {"BASE-FDPASS", run_fdpasstest, 0},
2192 {"BASE-LOCK1", torture_locktest1, 0},
2193 {"BASE-LOCK2", torture_locktest2, 0},
2194 {"BASE-LOCK3", torture_locktest3, 0},
2195 {"BASE-LOCK4", torture_locktest4, 0},
2196 {"BASE-LOCK5", torture_locktest5, 0},
2197 {"BASE-LOCK6", torture_locktest6, 0},
2198 {"BASE-LOCK7", torture_locktest7, 0},
2199 {"BASE-UNLINK", torture_unlinktest, 0},
2200 {"BASE-ATTR", run_attrtest, 0},
2201 {"BASE-TRANS2", run_trans2test, 0},
2202 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
2203 {"BASE-DIR1", torture_dirtest1, 0},
2204 {"BASE-DIR2", torture_dirtest2, 0},
2205 {"BASE-DENY1", torture_denytest1, 0},
2206 {"BASE-DENY2", torture_denytest2, 0},
2207 {"BASE-DENY3", torture_denytest3, 0},
2208 {"BASE-DENYDOS", torture_denydos_sharing, 0},
2209 {"BASE-NTDENY1", NULL, torture_ntdenytest1},
2210 {"BASE-NTDENY2", torture_ntdenytest2, 0},
2211 {"BASE-TCON", run_tcon_test, 0},
2212 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
2213 {"BASE-VUID", run_vuidtest, 0},
2214 {"BASE-RW1", run_readwritetest, 0},
2215 {"BASE-OPEN", run_opentest, 0},
2216 {"BASE-DEFER_OPEN", NULL, run_deferopen},
2217 {"BASE-XCOPY", run_xcopy, 0},
2218 {"BASE-RENAME", torture_test_rename, 0},
2219 {"BASE-DELETE", torture_test_delete, 0},
2220 {"BASE-PROPERTIES", torture_test_properties, 0},
2221 {"BASE-MANGLE", torture_mangle, 0},
2222 {"BASE-OPENATTR", torture_openattrtest, 0},
2223 {"BASE-CHARSET", torture_charset, 0},
2224 {"BASE-CHKPATH", torture_chkpath_test, 0},
2225 {"BASE-SECLEAK", torture_sec_leak, 0},
2226 {"BASE-DISCONNECT", torture_disconnect, 0},
2227 {"BASE-DELAYWRITE", torture_delay_write, 0},
2229 /* benchmarking tests */
2230 {"BENCH-HOLDCON", torture_holdcon, 0},
2231 {"BENCH-NBENCH", torture_nbench, 0},
2232 {"BENCH-TORTURE", NULL, run_torture},
2233 {"BENCH-NBT", torture_bench_nbt, 0},
2234 {"BENCH-WINS", torture_bench_wins, 0},
2235 {"BENCH-RPC", torture_bench_rpc, 0},
2236 {"BENCH-CLDAP", torture_bench_cldap, 0},
2239 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
2240 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
2241 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
2242 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
2243 {"RAW-SEARCH", torture_raw_search, 0},
2244 {"RAW-CLOSE", torture_raw_close, 0},
2245 {"RAW-OPEN", torture_raw_open, 0},
2246 {"RAW-MKDIR", torture_raw_mkdir, 0},
2247 {"RAW-OPLOCK", torture_raw_oplock, 0},
2248 {"RAW-NOTIFY", torture_raw_notify, 0},
2249 {"RAW-MUX", torture_raw_mux, 0},
2250 {"RAW-IOCTL", torture_raw_ioctl, 0},
2251 {"RAW-CHKPATH", torture_raw_chkpath, 0},
2252 {"RAW-UNLINK", torture_raw_unlink, 0},
2253 {"RAW-READ", torture_raw_read, 0},
2254 {"RAW-WRITE", torture_raw_write, 0},
2255 {"RAW-LOCK", torture_raw_lock, 0},
2256 {"RAW-CONTEXT", torture_raw_context, 0},
2257 {"RAW-RENAME", torture_raw_rename, 0},
2258 {"RAW-SEEK", torture_raw_seek, 0},
2259 {"RAW-EAS", torture_raw_eas, 0},
2260 {"RAW-EAMAX", torture_max_eas, 0},
2261 {"RAW-STREAMS", torture_raw_streams, 0},
2262 {"RAW-ACLS", torture_raw_acls, 0},
2263 {"RAW-RAP", torture_raw_rap, 0},
2264 {"RAW-COMPOSITE", torture_raw_composite, 0},
2266 /* protocol scanners */
2267 {"SCAN-TRANS2", torture_trans2_scan, 0},
2268 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2269 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2270 {"SCAN-SMB", torture_smb_scan, 0},
2271 {"SCAN-MAXFID", NULL, run_maxfidtest},
2272 {"SCAN-UTABLE", torture_utable, 0},
2273 {"SCAN-CASETABLE", torture_casetable, 0},
2274 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2275 {"SCAN-IOCTL", torture_ioctl_test, 0},
2276 {"SCAN-RAP", torture_rap_scan, 0},
2279 {"RPC-LSA", torture_rpc_lsa, 0},
2280 {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
2281 {"RPC-ECHO", torture_rpc_echo, 0},
2282 {"RPC-DFS", torture_rpc_dfs, 0},
2283 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2284 {"RPC-SAMR", torture_rpc_samr, 0},
2285 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2286 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2287 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2288 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2289 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2290 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2291 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2292 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2293 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2294 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2295 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2296 {"RPC-WINREG", torture_rpc_winreg, 0},
2297 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2298 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2299 {"RPC-REMACT", torture_rpc_remact, 0},
2300 {"RPC-MGMT", torture_rpc_mgmt, 0},
2301 {"RPC-SCANNER", torture_rpc_scanner, 0},
2302 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2303 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2304 {"RPC-MULTIBIND", torture_multi_bind, 0},
2305 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2306 {"RPC-LOGIN", torture_rpc_login, 0},
2307 {"RPC-ROT", torture_rpc_rot, 0},
2308 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2309 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2311 /* local (no server) testers */
2312 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2313 {"LOCAL-ICONV", torture_local_iconv, 0},
2314 {"LOCAL-TALLOC", torture_local_talloc, 0},
2315 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2316 {"LOCAL-IRPC", torture_local_irpc, 0},
2317 {"LOCAL-BINDING", torture_local_binding_string, 0},
2318 {"LOCAL-IDTREE", torture_local_idtree, 0},
2319 {"LOCAL-SOCKET", torture_local_socket, 0},
2320 {"LOCAL-PAC", torture_pac, 0},
2322 /* COM (Component Object Model) testers */
2323 {"COM-SIMPLE", torture_com_simple, 0 },
2326 {"LDAP-BASIC", torture_ldap_basic, 0},
2327 {"LDAP-CLDAP", torture_cldap, 0},
2330 {"NBT-REGISTER", torture_nbt_register, 0},
2331 {"NBT-WINS", torture_nbt_wins, 0},
2332 {"NBT-WINSREPLICATION", torture_nbt_winsreplication, 0},
2333 {"NBT-DGRAM", torture_nbt_dgram, 0},
2336 {"NET-USERINFO", torture_userinfo, 0},
2337 {"NET-USERADD", torture_useradd, 0},
2338 {"NET-USERDEL", torture_userdel, 0},
2339 {"NET-DOMOPEN", torture_domainopen, 0},
2340 {"NET-API-LOOKUP", torture_lookup, 0},
2341 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2342 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2343 {"NET-API-CREATEUSER", torture_createuser, 0},
2344 {"NET-API-RPCCONNECT", torture_rpc_connect, 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])) {