2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "lib/cmdline/popt_common.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "system/time.h"
25 #include "system/wait.h"
26 #include "system/filesys.h"
27 #include "libcli/raw/ioctl.h"
28 #include "libcli/libcli.h"
29 #include "lib/ldb/include/ldb.h"
30 #include "librpc/rpc/dcerpc_table.h"
31 #include "lib/events/events.h"
33 #include "torture/basic/proto.h"
34 #include "torture/raw/proto.h"
35 #include "torture/smb2/proto.h"
36 #include "torture/rpc/proto.h"
37 #include "torture/rap/proto.h"
38 #include "torture/auth/proto.h"
39 #include "torture/local/proto.h"
40 #include "torture/nbench/proto.h"
41 #include "torture/ldap/proto.h"
42 #include "torture/com/proto.h"
43 #include "torture/nbt/proto.h"
44 #include "torture/libnet/proto.h"
45 #include "torture/torture.h"
48 int torture_numops=10;
49 int torture_entries=1000;
50 int torture_failures=1;
52 static int procnum; /* records process count number when forking */
53 static struct smbcli_state *current_cli;
54 static BOOL use_oplocks;
55 static BOOL use_level_II_oplocks;
57 BOOL torture_showall = False;
59 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
61 static struct smbcli_state *open_nbt_connection(void)
63 struct nbt_name called, calling;
64 struct smbcli_state *cli;
65 const char *host = lp_parm_string(-1, "torture", "host");
67 make_nbt_name_client(&calling, lp_netbios_name());
69 nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
71 cli = smbcli_state_init(NULL);
73 printf("Failed initialize smbcli_struct to connect with %s\n", host);
77 if (!smbcli_socket_connect(cli, host)) {
78 printf("Failed to connect with %s\n", host);
82 if (!smbcli_transport_establish(cli, &calling, &called)) {
83 printf("%s rejected the session\n",host);
94 BOOL torture_open_connection_share(TALLOC_CTX *mem_ctx,
95 struct smbcli_state **c,
97 const char *sharename,
98 struct event_context *ev)
102 status = smbcli_full_connection(mem_ctx, c, hostname,
104 cmdline_credentials, ev);
105 if (!NT_STATUS_IS_OK(status)) {
106 printf("Failed to open connection - %s\n", nt_errstr(status));
110 (*c)->transport->options.use_oplocks = use_oplocks;
111 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
116 BOOL torture_open_connection(struct smbcli_state **c)
118 const char *host = lp_parm_string(-1, "torture", "host");
119 const char *share = lp_parm_string(-1, "torture", "share");
121 return torture_open_connection_share(NULL, c, host, share, NULL);
126 BOOL torture_close_connection(struct smbcli_state *c)
130 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
131 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
138 /* open a rpc connection to the chosen binding string */
139 NTSTATUS torture_rpc_connection(TALLOC_CTX *parent_ctx,
140 struct dcerpc_pipe **p,
141 const struct dcerpc_interface_table *table)
144 const char *binding = lp_parm_string(-1, "torture", "binding");
147 printf("You must specify a ncacn binding string\n");
148 return NT_STATUS_INVALID_PARAMETER;
151 status = dcerpc_pipe_connect(parent_ctx,
153 cmdline_credentials, NULL);
158 /* open a rpc connection to a specific transport */
159 NTSTATUS torture_rpc_connection_transport(TALLOC_CTX *parent_ctx,
160 struct dcerpc_pipe **p,
161 const struct dcerpc_interface_table *table,
162 enum dcerpc_transport_t transport)
165 const char *binding = lp_parm_string(-1, "torture", "binding");
166 struct dcerpc_binding *b;
167 TALLOC_CTX *mem_ctx = talloc_named(parent_ctx, 0, "torture_rpc_connection_smb");
170 printf("You must specify a ncacn binding string\n");
171 talloc_free(mem_ctx);
172 return NT_STATUS_INVALID_PARAMETER;
175 status = dcerpc_parse_binding(mem_ctx, binding, &b);
176 if (!NT_STATUS_IS_OK(status)) {
177 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
178 talloc_free(mem_ctx);
182 b->transport = transport;
184 status = dcerpc_pipe_connect_b(mem_ctx, p, b, table,
185 cmdline_credentials, NULL);
187 if (NT_STATUS_IS_OK(status)) {
188 *p = talloc_reference(parent_ctx, *p);
192 talloc_free(mem_ctx);
196 /* check if the server produced the expected error code */
197 BOOL check_error(const char *location, struct smbcli_state *c,
198 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
202 status = smbcli_nt_error(c->tree);
203 if (NT_STATUS_IS_DOS(status)) {
205 class = NT_STATUS_DOS_CLASS(status);
206 num = NT_STATUS_DOS_CODE(status);
207 if (eclass != class || ecode != num) {
208 printf("unexpected error code %s\n", nt_errstr(status));
209 printf(" expected %s or %s (at %s)\n",
210 nt_errstr(NT_STATUS_DOS(eclass, ecode)),
211 nt_errstr(nterr), location);
215 if (!NT_STATUS_EQUAL(nterr, status)) {
216 printf("unexpected error code %s\n", nt_errstr(status));
217 printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
226 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
228 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
229 if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
235 static BOOL rw_torture(struct smbcli_state *c)
237 const char *lockfname = "\\torture.lck";
241 pid_t pid2, pid = getpid();
246 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
249 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
251 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
256 for (i=0;i<torture_numops;i++) {
257 uint_t n = (uint_t)random()%10;
259 printf("%d\r", i); fflush(stdout);
261 asprintf(&fname, "\\torture.%u", n);
263 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
267 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
269 printf("open failed (%s)\n", smbcli_errstr(c->tree));
274 if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
275 printf("write failed (%s)\n", smbcli_errstr(c->tree));
280 if (smbcli_write(c->tree, fnum, 0, buf,
281 sizeof(pid)+(j*sizeof(buf)),
282 sizeof(buf)) != sizeof(buf)) {
283 printf("write failed (%s)\n", smbcli_errstr(c->tree));
290 if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
291 printf("read failed (%s)\n", smbcli_errstr(c->tree));
296 printf("data corruption!\n");
300 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
301 printf("close failed (%s)\n", smbcli_errstr(c->tree));
305 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
306 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
310 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
311 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
317 smbcli_close(c->tree, fnum2);
318 smbcli_unlink(c->tree, lockfname);
325 static BOOL run_torture(struct smbcli_state *cli, int dummy)
329 ret = rw_torture(cli);
331 if (!torture_close_connection(cli)) {
339 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
341 const char *lockfname = "\\torture2.lck";
346 uint8_t buf_rd[131072];
348 ssize_t bytes_read, bytes_written;
350 if (smbcli_deltree(c1->tree, lockfname) == -1) {
351 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
354 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
357 printf("first open read/write of %s failed (%s)\n",
358 lockfname, smbcli_errstr(c1->tree));
361 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
364 printf("second open read-only of %s failed (%s)\n",
365 lockfname, smbcli_errstr(c2->tree));
366 smbcli_close(c1->tree, fnum1);
370 printf("Checking data integrity over %d ops\n", torture_numops);
372 for (i=0;i<torture_numops;i++)
374 size_t buf_size = ((uint_t)random()%(sizeof(buf)-1))+ 1;
376 printf("%d\r", i); fflush(stdout);
379 generate_random_buffer(buf, buf_size);
381 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
382 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
383 printf("wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
388 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
389 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
390 printf("read %d, expected %d\n", (int)bytes_read, (int)buf_size);
395 if (memcmp(buf_rd, buf, buf_size) != 0)
397 printf("read/write compare failed\n");
403 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
404 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
407 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
408 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
412 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
413 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
420 #define BOOLSTR(b) ((b) ? "Yes" : "No")
422 static BOOL run_readwritetest(void)
424 struct smbcli_state *cli1, *cli2;
425 BOOL test1, test2 = True;
427 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
431 printf("starting readwritetest\n");
433 test1 = rw_torture2(cli1, cli2);
434 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
437 test2 = rw_torture2(cli1, cli1);
438 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
441 if (!torture_close_connection(cli1)) {
445 if (!torture_close_connection(cli2)) {
449 return (test1 && test2);
453 this checks to see if a secondary tconx can use open files from an
456 static BOOL run_tcon_test(void)
458 struct smbcli_state *cli;
459 const char *fname = "\\tcontest.tmp";
461 uint16_t cnum1, cnum2, cnum3;
462 uint16_t vuid1, vuid2;
465 struct smbcli_tree *tree1;
466 const char *host = lp_parm_string(-1, "torture", "host");
467 const char *share = lp_parm_string(-1, "torture", "share");
468 const char *password = lp_parm_string(-1, "torture", "password");
470 if (!torture_open_connection(&cli)) {
474 printf("starting tcontest\n");
476 if (smbcli_deltree(cli->tree, fname) == -1) {
477 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
480 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
482 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
486 cnum1 = cli->tree->tid;
487 vuid1 = cli->session->vuid;
489 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
490 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
491 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
495 tree1 = cli->tree; /* save old tree connection */
496 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
497 printf("%s refused 2nd tree connect (%s)\n", host,
498 smbcli_errstr(cli->tree));
503 cnum2 = cli->tree->tid;
504 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
505 vuid2 = cli->session->vuid + 1;
507 /* try a write with the wrong tid */
508 cli->tree->tid = cnum2;
510 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
511 printf("* server allows write with wrong TID\n");
514 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
518 /* try a write with an invalid tid */
519 cli->tree->tid = cnum3;
521 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
522 printf("* server allows write with invalid TID\n");
525 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
528 /* try a write with an invalid vuid */
529 cli->session->vuid = vuid2;
530 cli->tree->tid = cnum1;
532 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
533 printf("* server allows write with invalid VUID\n");
536 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
539 cli->session->vuid = vuid1;
540 cli->tree->tid = cnum1;
542 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
543 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
547 cli->tree->tid = cnum2;
549 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
550 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
554 cli->tree = tree1; /* restore initial tree */
555 cli->tree->tid = cnum1;
557 smbcli_unlink(tree1, fname);
559 if (!torture_close_connection(cli)) {
568 static BOOL tcon_devtest(struct smbcli_state *cli,
569 const char *myshare, const char *devtype,
570 NTSTATUS expected_error)
574 const char *password = lp_parm_string(-1, "torture", "password");
576 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
579 printf("Trying share %s with devtype %s\n", myshare, devtype);
581 if (NT_STATUS_IS_OK(expected_error)) {
585 printf("tconX to share %s with type %s "
586 "should have succeeded but failed\n",
593 printf("tconx to share %s with type %s "
594 "should have failed but succeeded\n",
598 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
602 printf("Returned unexpected error\n");
611 checks for correct tconX support
613 static BOOL run_tcon_devtype_test(void)
615 struct smbcli_state *cli1 = NULL;
618 const char *host = lp_parm_string(-1, "torture", "host");
619 const char *share = lp_parm_string(-1, "torture", "share");
621 status = smbcli_full_connection(NULL,
624 cmdline_credentials, NULL);
626 if (!NT_STATUS_IS_OK(status)) {
627 printf("could not open connection\n");
631 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
634 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
637 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
640 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
643 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
646 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
649 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
652 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
655 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
658 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
664 printf("Passed tcondevtest\n");
671 test whether fnums and tids open on one VC are available on another (a major
674 static BOOL run_fdpasstest(void)
676 struct smbcli_state *cli1, *cli2;
677 const char *fname = "\\fdpass.tst";
681 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
685 printf("starting fdpasstest\n");
687 smbcli_unlink(cli1->tree, fname);
689 printf("Opening a file on connection 1\n");
691 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
693 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
697 printf("writing to file on connection 1\n");
699 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
700 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
704 oldtid = cli2->tree->tid;
705 cli2->session->vuid = cli1->session->vuid;
706 cli2->tree->tid = cli1->tree->tid;
707 cli2->session->pid = cli1->session->pid;
709 printf("reading from file on connection 2\n");
711 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
712 printf("read succeeded! nasty security hole [%s]\n",
717 smbcli_close(cli1->tree, fnum1);
718 smbcli_unlink(cli1->tree, fname);
720 cli2->tree->tid = oldtid;
722 torture_close_connection(cli1);
723 torture_close_connection(cli2);
725 printf("finished fdpasstest\n");
731 test the timing of deferred open requests
733 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
735 const char *fname = "\\defer_open_test.dat";
741 printf("failed to connect\n");
745 printf("Testing deferred open requests.\n");
752 tv = timeval_current();
753 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
755 FILE_ATTRIBUTE_NORMAL,
756 NTCREATEX_SHARE_ACCESS_NONE,
757 NTCREATEX_DISP_OPEN_IF, 0, 0);
761 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
762 double e = timeval_elapsed(&tv);
763 if (e < 0.5 || e > 1.5) {
764 fprintf(stderr,"Timing incorrect %.2f violation\n",
768 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
771 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
775 printf("pid %u open %d\n", getpid(), i);
779 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
780 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
786 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
787 /* All until the last unlink will fail with sharing violation. */
788 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
789 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
794 printf("deferred test finished\n");
795 if (!torture_close_connection(cli)) {
802 test how many open files this server supports on the one socket
804 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
806 #define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
808 int fnums[0x11000], i;
809 int retries=4, maxfid;
813 printf("failed to connect\n");
817 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
818 printf("Failed to deltree \\maxfid - %s\n",
819 smbcli_errstr(cli->tree));
822 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
823 printf("Failed to mkdir \\maxfid, error=%s\n",
824 smbcli_errstr(cli->tree));
828 printf("Testing maximum number of open files\n");
830 for (i=0; i<0x11000; i++) {
832 asprintf(&fname, "\\maxfid\\fid%d", i/1000);
833 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
834 printf("Failed to mkdir %s, error=%s\n",
835 fname, smbcli_errstr(cli->tree));
840 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
841 if ((fnums[i] = smbcli_open(cli->tree, fname,
842 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
844 printf("open of %s failed (%s)\n",
845 fname, smbcli_errstr(cli->tree));
846 printf("maximum fnum is %d\n", i);
857 printf("cleaning up\n");
858 for (i=0;i<maxfid/2;i++) {
859 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
860 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
861 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
863 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
864 printf("unlink of %s failed (%s)\n",
865 fname, smbcli_errstr(cli->tree));
870 asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
871 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
872 printf("Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
874 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
875 printf("unlink of %s failed (%s)\n",
876 fname, smbcli_errstr(cli->tree));
881 printf("%6d %6d\r", i, maxfid-i);
885 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
886 printf("Failed to deltree \\maxfid - %s\n",
887 smbcli_errstr(cli->tree));
891 printf("maxfid test finished\n");
892 if (!torture_close_connection(cli)) {
896 #undef MAXFID_TEMPLATE
899 /* send smb negprot commands, not reading the response */
900 static BOOL run_negprot_nowait(void)
903 struct smbcli_state *cli, *cli2;
906 printf("starting negprot nowait test\n");
908 cli = open_nbt_connection();
913 printf("Filling send buffer\n");
915 for (i=0;i<100;i++) {
916 struct smbcli_request *req;
917 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
918 event_loop_once(cli->transport->socket->event.ctx);
919 if (req->state == SMBCLI_REQUEST_ERROR) {
920 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
921 torture_close_connection(cli);
926 printf("Opening secondary connection\n");
927 if (!torture_open_connection(&cli2)) {
931 if (!torture_close_connection(cli)) {
935 if (!torture_close_connection(cli2)) {
939 printf("finished negprot nowait test\n");
946 This checks how the getatr calls works
948 static BOOL run_attrtest(void)
950 struct smbcli_state *cli;
953 const char *fname = "\\attrib123456789.tst";
956 printf("starting attrib test\n");
958 if (!torture_open_connection(&cli)) {
962 smbcli_unlink(cli->tree, fname);
963 fnum = smbcli_open(cli->tree, fname,
964 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
965 smbcli_close(cli->tree, fnum);
967 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
968 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
972 printf("New file time is %s", ctime(&t));
974 if (abs(t - time(NULL)) > 60*60*24*10) {
975 printf("ERROR: SMBgetatr bug. time is %s",
981 t2 = t-60*60*24; /* 1 day ago */
983 printf("Setting file time to %s", ctime(&t2));
985 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
986 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
990 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
991 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
995 printf("Retrieved file time as %s", ctime(&t));
998 printf("ERROR: getatr/setatr bug. times are\n%s",
1000 printf("%s", ctime(&t2));
1004 smbcli_unlink(cli->tree, fname);
1006 if (!torture_close_connection(cli)) {
1010 printf("attrib test finished\n");
1017 This checks a couple of trans2 calls
1019 static BOOL run_trans2test(void)
1021 struct smbcli_state *cli;
1024 time_t c_time, a_time, m_time, w_time, m_time2;
1025 const char *fname = "\\trans2.tst";
1026 const char *dname = "\\trans2";
1027 const char *fname2 = "\\trans2\\trans2.tst";
1029 BOOL correct = True;
1031 printf("starting trans2 test\n");
1033 if (!torture_open_connection(&cli)) {
1037 smbcli_unlink(cli->tree, fname);
1039 printf("Testing qfileinfo\n");
1041 fnum = smbcli_open(cli->tree, fname,
1042 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1043 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
1045 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
1049 printf("Testing NAME_INFO\n");
1051 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
1052 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
1056 if (!pname || strcmp(pname, fname)) {
1057 printf("qfilename gave different name? [%s] [%s]\n",
1062 smbcli_close(cli->tree, fnum);
1063 smbcli_unlink(cli->tree, fname);
1065 fnum = smbcli_open(cli->tree, fname,
1066 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1068 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1071 smbcli_close(cli->tree, fnum);
1073 printf("Checking for sticky create times\n");
1075 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1076 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
1079 if (c_time != m_time) {
1080 printf("create time=%s", ctime(&c_time));
1081 printf("modify time=%s", ctime(&m_time));
1082 printf("This system appears to have sticky create times\n");
1084 if (a_time % (60*60) == 0) {
1085 printf("access time=%s", ctime(&a_time));
1086 printf("This system appears to set a midnight access time\n");
1090 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1091 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1097 smbcli_unlink(cli->tree, fname);
1098 fnum = smbcli_open(cli->tree, fname,
1099 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1100 smbcli_close(cli->tree, fnum);
1101 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1102 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1105 if (w_time < 60*60*24*2) {
1106 printf("write time=%s", ctime(&w_time));
1107 printf("This system appears to set a initial 0 write time\n");
1112 smbcli_unlink(cli->tree, fname);
1115 /* check if the server updates the directory modification time
1116 when creating a new file */
1117 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1118 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
1122 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1123 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1127 fnum = smbcli_open(cli->tree, fname2,
1128 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1129 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
1130 smbcli_close(cli->tree, fnum);
1131 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
1132 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1135 if (m_time2 == m_time) {
1136 printf("This system does not update directory modification times\n");
1140 smbcli_unlink(cli->tree, fname2);
1141 smbcli_rmdir(cli->tree, dname);
1143 if (!torture_close_connection(cli)) {
1147 printf("trans2 test finished\n");
1154 /* FIRST_DESIRED_ACCESS 0xf019f */
1155 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1156 SEC_FILE_READ_EA| /* 0xf */ \
1157 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1158 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1159 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1160 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1161 /* SECOND_DESIRED_ACCESS 0xe0080 */
1162 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1163 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1164 SEC_STD_WRITE_OWNER /* 0xe0000 */
1167 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1168 READ_CONTROL|WRITE_DAC|\
1169 SEC_FILE_READ_DATA|\
1174 Test ntcreate calls made by xcopy
1176 static BOOL run_xcopy(void)
1178 struct smbcli_state *cli1;
1179 const char *fname = "\\test.txt";
1180 BOOL correct = True;
1183 printf("starting xcopy test\n");
1185 if (!torture_open_connection(&cli1)) {
1189 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1190 FIRST_DESIRED_ACCESS,
1191 FILE_ATTRIBUTE_ARCHIVE,
1192 NTCREATEX_SHARE_ACCESS_NONE,
1193 NTCREATEX_DISP_OVERWRITE_IF,
1197 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
1201 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1202 SECOND_DESIRED_ACCESS, 0,
1203 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1206 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
1210 if (!torture_close_connection(cli1)) {
1219 see how many RPC pipes we can open at once
1221 static BOOL run_pipe_number(void)
1223 struct smbcli_state *cli1;
1224 const char *pipe_name = "\\WKSSVC";
1228 printf("starting pipenumber test\n");
1229 if (!torture_open_connection(&cli1)) {
1234 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1235 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1238 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
1242 printf("%d\r", num_pipes);
1246 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
1247 torture_close_connection(cli1);
1255 open N connections to the server and just hold them open
1256 used for testing performance when there are N idle users
1259 static BOOL torture_holdcon(void)
1262 struct smbcli_state **cli;
1265 printf("Opening %d connections\n", torture_numops);
1267 cli = malloc_array_p(struct smbcli_state *, torture_numops);
1269 for (i=0;i<torture_numops;i++) {
1270 if (!torture_open_connection(&cli[i])) {
1273 printf("opened %d connections\r", i);
1277 printf("\nStarting pings\n");
1280 for (i=0;i<torture_numops;i++) {
1283 status = smbcli_chkpath(cli[i]->tree, "\\");
1284 if (!NT_STATUS_IS_OK(status)) {
1285 printf("Connection %d is dead\n", i);
1293 if (num_dead == torture_numops) {
1294 printf("All connections dead - finishing\n");
1306 Try with a wrong vuid and check error message.
1309 static BOOL run_vuidtest(void)
1311 struct smbcli_state *cli;
1312 const char *fname = "\\vuid.tst";
1315 time_t c_time, a_time, m_time;
1316 BOOL correct = True;
1321 printf("starting vuid test\n");
1323 if (!torture_open_connection(&cli)) {
1327 smbcli_unlink(cli->tree, fname);
1329 fnum = smbcli_open(cli->tree, fname,
1330 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1332 orig_vuid = cli->session->vuid;
1334 cli->session->vuid += 1234;
1336 printf("Testing qfileinfo with wrong vuid\n");
1338 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
1339 &size, &c_time, &a_time,
1340 &m_time, NULL, NULL))) {
1341 printf("ERROR: qfileinfo passed with wrong vuid\n");
1345 if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1346 NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
1347 !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1348 NT_STATUS_INVALID_HANDLE)) {
1349 printf("ERROR: qfileinfo should have returned DOS error "
1350 "ERRSRV:ERRbaduid\n but returned %s\n",
1351 smbcli_errstr(cli->tree));
1355 cli->session->vuid -= 1234;
1357 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1358 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
1362 smbcli_unlink(cli->tree, fname);
1364 if (!torture_close_connection(cli)) {
1368 printf("vuid test finished\n");
1374 Test open mode returns on read-only files.
1376 static BOOL run_opentest(void)
1378 static struct smbcli_state *cli1;
1379 static struct smbcli_state *cli2;
1380 const char *fname = "\\readonly.file";
1381 char *control_char_fname;
1385 BOOL correct = True;
1390 printf("starting open test\n");
1392 if (!torture_open_connection(&cli1)) {
1396 asprintf(&control_char_fname, "\\readonly.afile");
1397 for (i = 1; i <= 0x1f; i++) {
1398 control_char_fname[10] = i;
1399 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
1400 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1402 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
1403 NT_STATUS_OBJECT_NAME_INVALID)) {
1404 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
1405 smbcli_errstr(cli1->tree), i);
1410 smbcli_close(cli1->tree, fnum1);
1412 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
1413 smbcli_unlink(cli1->tree, control_char_fname);
1415 free(control_char_fname);
1418 printf("Create file with control char names passed.\n");
1420 smbcli_setatr(cli1->tree, fname, 0, 0);
1421 smbcli_unlink(cli1->tree, fname);
1423 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1425 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1429 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1430 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1434 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
1435 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
1436 CHECK_MAX_FAILURES(error_test1);
1440 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1442 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1443 CHECK_MAX_FAILURES(error_test1);
1447 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
1448 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1450 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
1451 NT_STATUS_ACCESS_DENIED)) {
1452 printf("correct error code ERRDOS/ERRnoaccess returned\n");
1455 printf("finished open test 1\n");
1457 smbcli_close(cli1->tree, fnum1);
1459 /* Now try not readonly and ensure ERRbadshare is returned. */
1461 smbcli_setatr(cli1->tree, fname, 0, 0);
1463 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1465 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1469 /* This will fail - but the error should be ERRshare. */
1470 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1472 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
1473 NT_STATUS_SHARING_VIOLATION)) {
1474 printf("correct error code ERRDOS/ERRbadshare returned\n");
1477 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1478 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1482 smbcli_unlink(cli1->tree, fname);
1484 printf("finished open test 2\n");
1486 /* Test truncate open disposition on file opened for read. */
1488 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1490 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1494 /* write 20 bytes. */
1496 memset(buf, '\0', 20);
1498 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1499 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1503 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1504 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1508 /* Ensure size == 20. */
1509 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1510 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1511 CHECK_MAX_FAILURES(error_test3);
1516 printf("(3) file size != 20\n");
1517 CHECK_MAX_FAILURES(error_test3);
1521 /* Now test if we can truncate a file opened for readonly. */
1523 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
1525 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1526 CHECK_MAX_FAILURES(error_test3);
1530 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1531 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1535 /* Ensure size == 0. */
1536 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1537 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1538 CHECK_MAX_FAILURES(error_test3);
1543 printf("(3) file size != 0\n");
1544 CHECK_MAX_FAILURES(error_test3);
1547 printf("finished open test 3\n");
1549 smbcli_unlink(cli1->tree, fname);
1552 printf("testing ctemp\n");
1553 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
1555 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1556 CHECK_MAX_FAILURES(error_test4);
1559 printf("ctemp gave path %s\n", tmp_path);
1560 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1561 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1563 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1564 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1567 /* Test the non-io opens... */
1569 if (!torture_open_connection(&cli2)) {
1573 smbcli_setatr(cli2->tree, fname, 0, 0);
1574 smbcli_unlink(cli2->tree, fname);
1576 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1578 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1579 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1582 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1583 CHECK_MAX_FAILURES(error_test10);
1587 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1588 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1590 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1591 CHECK_MAX_FAILURES(error_test10);
1595 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1596 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1599 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1600 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1604 printf("non-io open test #1 passed.\n");
1606 smbcli_unlink(cli1->tree, fname);
1608 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1610 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1611 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1614 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1615 CHECK_MAX_FAILURES(error_test20);
1619 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1620 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1623 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1624 CHECK_MAX_FAILURES(error_test20);
1628 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1629 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1632 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1633 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1637 printf("non-io open test #2 passed.\n");
1639 smbcli_unlink(cli1->tree, fname);
1641 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1643 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1644 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1647 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1648 CHECK_MAX_FAILURES(error_test30);
1652 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1653 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1656 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1657 CHECK_MAX_FAILURES(error_test30);
1661 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1662 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1665 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1666 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1670 printf("non-io open test #3 passed.\n");
1672 smbcli_unlink(cli1->tree, fname);
1674 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1676 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1677 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1680 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1681 CHECK_MAX_FAILURES(error_test40);
1685 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1686 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1689 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1690 CHECK_MAX_FAILURES(error_test40);
1694 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1696 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1697 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1701 printf("non-io open test #4 passed.\n");
1703 smbcli_unlink(cli1->tree, fname);
1705 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1707 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1708 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1711 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1712 CHECK_MAX_FAILURES(error_test50);
1716 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1717 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1720 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1721 CHECK_MAX_FAILURES(error_test50);
1725 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1726 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1730 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1731 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1735 printf("non-io open test #5 passed.\n");
1737 printf("TEST #6 testing 1 non-io open, one io open\n");
1739 smbcli_unlink(cli1->tree, fname);
1741 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1742 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1745 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1746 CHECK_MAX_FAILURES(error_test60);
1750 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1751 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1754 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1755 CHECK_MAX_FAILURES(error_test60);
1759 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1760 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1764 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1765 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1769 printf("non-io open test #6 passed.\n");
1771 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
1773 smbcli_unlink(cli1->tree, fname);
1775 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1776 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1779 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1780 CHECK_MAX_FAILURES(error_test70);
1784 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1785 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1788 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1789 CHECK_MAX_FAILURES(error_test70);
1793 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1795 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1796 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1800 printf("non-io open test #7 passed.\n");
1804 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1806 smbcli_unlink(cli1->tree, fname);
1808 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1810 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1814 /* write 20 bytes. */
1816 memset(buf, '\0', 20);
1818 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1819 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1823 /* Ensure size == 20. */
1824 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1825 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1826 CHECK_MAX_FAILURES(error_test80);
1831 printf("(8) file size != 20\n");
1832 CHECK_MAX_FAILURES(error_test80);
1836 /* Get an exclusive lock on the open file. */
1837 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1838 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1839 CHECK_MAX_FAILURES(error_test80);
1843 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1845 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1849 /* Ensure size == 0. */
1850 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1851 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1852 CHECK_MAX_FAILURES(error_test80);
1857 printf("(8) file size != 0\n");
1858 CHECK_MAX_FAILURES(error_test80);
1862 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1863 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1867 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1868 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1874 printf("open test #8 passed.\n");
1876 smbcli_unlink(cli1->tree, fname);
1878 if (!torture_close_connection(cli1)) {
1881 if (!torture_close_connection(cli2)) {
1890 sees what IOCTLs are supported
1892 BOOL torture_ioctl_test(void)
1894 struct smbcli_state *cli;
1895 uint16_t device, function;
1897 const char *fname = "\\ioctl.dat";
1899 union smb_ioctl parms;
1900 TALLOC_CTX *mem_ctx;
1902 if (!torture_open_connection(&cli)) {
1906 mem_ctx = talloc_init("ioctl_test");
1908 printf("starting ioctl test\n");
1910 smbcli_unlink(cli->tree, fname);
1912 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1914 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1918 parms.ioctl.level = RAW_IOCTL_IOCTL;
1919 parms.ioctl.in.fnum = fnum;
1920 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
1921 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1922 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
1924 for (device=0;device<0x100;device++) {
1925 printf("testing device=0x%x\n", device);
1926 for (function=0;function<0x100;function++) {
1927 parms.ioctl.in.request = (device << 16) | function;
1928 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1930 if (NT_STATUS_IS_OK(status)) {
1931 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
1932 device, function, (int)parms.ioctl.out.blob.length);
1937 if (!torture_close_connection(cli)) {
1946 tries variants of chkpath
1948 BOOL torture_chkpath_test(void)
1950 struct smbcli_state *cli;
1954 if (!torture_open_connection(&cli)) {
1958 printf("starting chkpath test\n");
1960 printf("Testing valid and invalid paths\n");
1962 /* cleanup from an old run */
1963 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1964 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1965 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1967 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1968 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1972 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1973 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1977 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1979 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
1982 smbcli_close(cli->tree, fnum);
1984 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1985 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1989 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1990 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1994 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1995 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1996 NT_STATUS_NOT_A_DIRECTORY);
1998 printf("* chkpath on a file should fail\n");
2002 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
2003 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2004 NT_STATUS_OBJECT_NAME_NOT_FOUND);
2006 printf("* chkpath on a non existent file should fail\n");
2010 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
2011 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2012 NT_STATUS_OBJECT_PATH_NOT_FOUND);
2014 printf("* chkpath on a non existent component should fail\n");
2018 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
2019 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
2020 smbcli_rmdir(cli->tree, "\\chkpath.dir");
2022 if (!torture_close_connection(cli)) {
2030 static void sigcont(int sig)
2034 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
2037 volatile pid_t *child_status;
2038 volatile BOOL *child_status_out;
2041 double start_time_limit = 10 + (torture_nprocs * 1.5);
2042 char **unc_list = NULL;
2044 int num_unc_names = 0;
2051 signal(SIGCONT, sigcont);
2053 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
2054 if (!child_status) {
2055 printf("Failed to setup shared memory\n");
2059 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
2060 if (!child_status_out) {
2061 printf("Failed to setup result status shared memory\n");
2065 p = lp_parm_string(-1, "torture", "unclist");
2067 unc_list = file_lines_load(p, &num_unc_names, NULL);
2068 if (!unc_list || num_unc_names <= 0) {
2069 printf("Failed to load unc names list from '%s'\n", p);
2074 for (i = 0; i < torture_nprocs; i++) {
2075 child_status[i] = 0;
2076 child_status_out[i] = True;
2079 tv = timeval_current();
2081 for (i=0;i<torture_nprocs;i++) {
2085 const char *hostname=NULL, *sharename;
2087 pid_t mypid = getpid();
2088 srandom(((int)mypid) ^ ((int)time(NULL)));
2090 asprintf(&myname, "CLIENT%d", i);
2091 lp_set_cmdline("netbios name", myname);
2096 if (!smbcli_parse_unc(unc_list[i % num_unc_names],
2097 NULL, &hostname, &sharename)) {
2098 printf("Failed to parse UNC name %s\n",
2099 unc_list[i % num_unc_names]);
2106 if (torture_open_connection_share(NULL,
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=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},
2267 {"SMB2-CONNECT", torture_smb2_connect, 0},
2268 {"SMB2-SCAN", torture_smb2_scan, 0},
2269 {"SMB2-SCANGETINFO", torture_smb2_getinfo_scan, 0},
2270 {"SMB2-SCANSETINFO", torture_smb2_setinfo_scan, 0},
2271 {"SMB2-SCANFIND", torture_smb2_find_scan, 0},
2272 {"SMB2-GETINFO", torture_smb2_getinfo, 0},
2273 {"SMB2-SETINFO", torture_smb2_setinfo, 0},
2274 {"SMB2-FIND", torture_smb2_find, 0},
2276 /* protocol scanners */
2277 {"SCAN-TRANS2", torture_trans2_scan, 0},
2278 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2279 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2280 {"SCAN-SMB", torture_smb_scan, 0},
2281 {"SCAN-MAXFID", NULL, run_maxfidtest},
2282 {"SCAN-UTABLE", torture_utable, 0},
2283 {"SCAN-CASETABLE", torture_casetable, 0},
2284 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2285 {"SCAN-IOCTL", torture_ioctl_test, 0},
2286 {"SCAN-RAP", torture_rap_scan, 0},
2289 {"RPC-LSA", torture_rpc_lsa, 0},
2290 {"RPC-LSALOOKUP", torture_rpc_lsa_lookup, 0},
2291 {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
2292 {"RPC-ECHO", torture_rpc_echo, 0},
2293 {"RPC-DFS", torture_rpc_dfs, 0},
2294 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2295 {"RPC-SAMR", torture_rpc_samr, 0},
2296 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2297 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2298 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2299 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2300 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2301 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2302 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2303 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2304 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2305 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2306 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2307 {"RPC-WINREG", torture_rpc_winreg, 0},
2308 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2309 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2310 {"RPC-REMACT", torture_rpc_remact, 0},
2311 {"RPC-MGMT", torture_rpc_mgmt, 0},
2312 {"RPC-SCANNER", torture_rpc_scanner, 0},
2313 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2314 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2315 {"RPC-MULTIBIND", torture_multi_bind, 0},
2316 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2317 {"RPC-CRACKNAMES", torture_rpc_drsuapi_cracknames, 0},
2318 {"RPC-ROT", torture_rpc_rot, 0},
2319 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2320 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2321 {"RPC-JOIN", torture_rpc_join, 0},
2322 {"RPC-DSSYNC", torture_rpc_dssync, 0},
2324 /* local (no server) testers */
2325 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2326 {"LOCAL-ICONV", torture_local_iconv, 0},
2327 {"LOCAL-TALLOC", torture_local_talloc, 0},
2328 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2329 {"LOCAL-IRPC", torture_local_irpc, 0},
2330 {"LOCAL-BINDING", torture_local_binding_string, 0},
2331 {"LOCAL-STRLIST", torture_local_util_strlist, 0},
2332 {"LOCAL-FILE", torture_local_util_file, 0},
2333 {"LOCAL-IDTREE", torture_local_idtree, 0},
2334 {"LOCAL-SOCKET", torture_local_socket, 0},
2335 {"LOCAL-PAC", torture_pac, 0},
2336 {"LOCAL-REGISTRY", torture_registry, 0},
2337 {"LOCAL-RESOLVE", torture_local_resolve, 0},
2338 {"LOCAL-SDDL", torture_local_sddl, 0},
2339 {"LOCAL-NDR", torture_local_ndr, 0},
2341 /* COM (Component Object Model) testers */
2342 {"COM-SIMPLE", torture_com_simple, 0 },
2345 {"LDAP-BASIC", torture_ldap_basic, 0},
2346 {"LDAP-CLDAP", torture_cldap, 0},
2349 {"NBT-REGISTER", torture_nbt_register, 0},
2350 {"NBT-WINS", torture_nbt_wins, 0},
2351 {"NBT-DGRAM", torture_nbt_dgram, 0},
2352 {"NBT-BROWSE", torture_nbt_browse, 0},
2353 {"NBT-WINSREPLICATION-SIMPLE", torture_nbt_winsreplication_simple, 0},
2354 {"NBT-WINSREPLICATION-REPLICA", torture_nbt_winsreplication_replica, 0},
2355 {"NBT-WINSREPLICATION-OWNED", torture_nbt_winsreplication_owned, 0},
2358 {"NET-USERINFO", torture_userinfo, 0},
2359 {"NET-USERADD", torture_useradd, 0},
2360 {"NET-USERDEL", torture_userdel, 0},
2361 {"NET-USERMOD", torture_usermod, 0},
2362 {"NET-DOMOPEN", torture_domainopen, 0},
2363 {"NET-API-LOOKUP", torture_lookup, 0},
2364 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2365 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2366 {"NET-API-CREATEUSER", torture_createuser, 0},
2367 {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
2368 {"NET-API-LISTSHARES", torture_listshares, 0},
2369 {"NET-API-DELSHARE", torture_delshare, 0},
2375 /****************************************************************************
2376 run a specified test or "ALL"
2377 ****************************************************************************/
2378 static BOOL run_test(const char *name)
2382 BOOL matched = False;
2384 if (strequal(name,"ALL")) {
2385 for (i=0;torture_ops[i].name;i++) {
2386 if (!run_test(torture_ops[i].name)) {
2393 for (i=0;torture_ops[i].name;i++) {
2394 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
2398 printf("Running %s\n", torture_ops[i].name);
2399 if (torture_ops[i].multi_fn) {
2400 BOOL result = False;
2401 t = torture_create_procs(torture_ops[i].multi_fn,
2405 printf("TEST %s FAILED!\n", torture_ops[i].name);
2409 struct timeval tv = timeval_current();
2410 if (!torture_ops[i].fn()) {
2412 printf("TEST %s FAILED!\n", torture_ops[i].name);
2414 t = timeval_elapsed(&tv);
2416 printf("%s took %g secs\n\n", torture_ops[i].name, t);
2421 printf("Unknown torture operation '%s'\n", name);
2428 static void parse_dns(const char *dns)
2430 char *userdn, *basedn, *secret;
2433 /* retrievieng the userdn */
2434 p = strchr_m(dns, '#');
2436 lp_set_cmdline("torture:ldap_userdn", "");
2437 lp_set_cmdline("torture:ldap_basedn", "");
2438 lp_set_cmdline("torture:ldap_secret", "");
2441 userdn = strndup(dns, p - dns);
2442 lp_set_cmdline("torture:ldap_userdn", userdn);
2444 /* retrieve the basedn */
2446 p = strchr_m(d, '#');
2448 lp_set_cmdline("torture:ldap_basedn", "");
2449 lp_set_cmdline("torture:ldap_secret", "");
2452 basedn = strndup(d, p - d);
2453 lp_set_cmdline("torture:ldap_basedn", basedn);
2455 /* retrieve the secret */
2458 lp_set_cmdline("torture:ldap_secret", "");
2462 lp_set_cmdline("torture:ldap_secret", secret);
2464 printf ("%s - %s - %s\n", userdn, basedn, secret);
2468 static void usage(poptContext pc)
2473 poptPrintUsage(pc, stdout, 0);
2476 printf("The binding format is:\n\n");
2478 printf(" TRANSPORT:host[flags]\n\n");
2480 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2482 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2483 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2484 printf(" string.\n\n");
2486 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2487 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2488 printf(" will be auto-determined.\n\n");
2490 printf(" other recognised flags are:\n\n");
2492 printf(" sign : enable ntlmssp signing\n");
2493 printf(" seal : enable ntlmssp sealing\n");
2494 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2495 printf(" validate: enable the NDR validator\n");
2496 printf(" print: enable debugging of the packets\n");
2497 printf(" bigendian: use bigendian RPC\n");
2498 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2500 printf(" For example, these all connect to the samr pipe:\n\n");
2502 printf(" ncacn_np:myserver\n");
2503 printf(" ncacn_np:myserver[samr]\n");
2504 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2505 printf(" ncacn_np:myserver[/pipe/samr]\n");
2506 printf(" ncacn_np:myserver[samr,sign,print]\n");
2507 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2508 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2509 printf(" ncacn_np:\n");
2510 printf(" ncacn_np:[/pipe/samr]\n\n");
2512 printf(" ncacn_ip_tcp:myserver\n");
2513 printf(" ncacn_ip_tcp:myserver[1024]\n");
2514 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2516 printf("The unc format is:\n\n");
2518 printf(" //server/share\n\n");
2520 printf("tests are:");
2521 for (i=0;torture_ops[i].name;i++) {
2522 if ((i%perline)==0) {
2525 printf("%s ", torture_ops[i].name);
2529 printf("default test is ALL\n");
2534 static BOOL is_binding_string(const char *binding_string)
2536 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2537 struct dcerpc_binding *binding_struct;
2540 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2542 talloc_free(mem_ctx);
2543 return NT_STATUS_IS_OK(status);
2546 static void max_runtime_handler(int sig)
2548 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2552 /****************************************************************************
2554 ****************************************************************************/
2555 int main(int argc,char *argv[])
2559 BOOL correct = True;
2564 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,
2565 OPT_DANGEROUS,OPT_SMB_PORTS};
2567 struct poptOption long_options[] = {
2569 {"smb-ports", 'p', POPT_ARG_STRING, NULL, OPT_SMB_PORTS, "SMB ports", NULL},
2570 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2571 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2572 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2573 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2574 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2575 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2576 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2577 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2578 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2579 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2580 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2581 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2582 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2583 "set maximum time for smbtorture to live", "seconds"},
2585 POPT_COMMON_CONNECTION
2586 POPT_COMMON_CREDENTIALS
2591 #ifdef HAVE_SETBUFFER
2592 setbuffer(stdout, NULL, 0);
2595 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2596 POPT_CONTEXT_KEEP_FIRST);
2598 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2600 while((opt = poptGetNextOpt(pc)) != -1) {
2603 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2606 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2609 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2612 parse_dns(poptGetOptArg(pc));
2615 lp_set_cmdline("torture:dangerous", "Yes");
2618 lp_set_cmdline("smb ports", poptGetOptArg(pc));
2621 d_printf("Invalid option %s: %s\n",
2622 poptBadOption(pc, 0), poptStrerror(opt));
2629 /* this will only work if nobody else uses alarm(),
2630 which means it won't work for some tests, but we
2631 can't use the event context method we use for smbd
2632 as so many tests create their own event
2633 context. This will at least catch most cases. */
2634 signal(SIGALRM, max_runtime_handler);
2642 dcerpc_table_init();
2644 if (torture_seed == 0) {
2645 torture_seed = time(NULL);
2647 printf("Using seed %d\n", torture_seed);
2648 srandom(torture_seed);
2650 argv_new = discard_const_p(char *, poptGetArgs(pc));
2653 for (i=0; i<argc; i++) {
2654 if (argv_new[i] == NULL) {
2665 for(p = argv_new[1]; *p; p++) {
2670 /* see if its a RPC transport specifier */
2671 if (is_binding_string(argv_new[1])) {
2672 lp_set_cmdline("torture:binding", argv_new[1]);
2674 char *binding = NULL;
2675 const char *host = NULL, *share = NULL;
2677 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
2678 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
2682 lp_set_cmdline("torture:host", host);
2683 lp_set_cmdline("torture:share", share);
2684 asprintf(&binding, "ncacn_np:%s", host);
2685 lp_set_cmdline("torture:binding", binding);
2688 if (argc_new == 0) {
2689 printf("You must specify a test to run, or 'ALL'\n");
2691 for (i=2;i<argc_new;i++) {
2692 if (!run_test(argv_new[i])) {