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"
32 #include "libcli/resolve/resolve.h"
34 #include "torture/basic/proto.h"
35 #include "torture/raw/proto.h"
36 #include "torture/smb2/proto.h"
37 #include "torture/rpc/proto.h"
38 #include "torture/rap/proto.h"
39 #include "torture/auth/proto.h"
40 #include "torture/local/proto.h"
41 #include "torture/nbench/proto.h"
42 #include "torture/ldap/proto.h"
43 #include "torture/com/proto.h"
44 #include "torture/nbt/proto.h"
45 #include "torture/libnet/proto.h"
46 #include "torture/torture.h"
49 int torture_numops=10;
50 int torture_entries=1000;
51 int torture_failures=1;
53 static int procnum; /* records process count number when forking */
54 static struct smbcli_state *current_cli;
55 static BOOL use_oplocks;
56 static BOOL use_level_II_oplocks;
58 BOOL torture_showall = False;
60 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
62 static struct smbcli_state *open_nbt_connection(void)
64 struct nbt_name called, calling;
65 struct smbcli_state *cli;
66 const char *host = lp_parm_string(-1, "torture", "host");
68 make_nbt_name_client(&calling, lp_netbios_name());
70 nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
72 cli = smbcli_state_init(NULL);
74 printf("Failed initialize smbcli_struct to connect with %s\n", host);
78 if (!smbcli_socket_connect(cli, host)) {
79 printf("Failed to connect with %s\n", host);
83 if (!smbcli_transport_establish(cli, &calling, &called)) {
84 printf("%s rejected the session\n",host);
95 BOOL torture_open_connection_share(TALLOC_CTX *mem_ctx,
96 struct smbcli_state **c,
98 const char *sharename,
99 struct event_context *ev)
103 status = smbcli_full_connection(mem_ctx, c, hostname,
105 cmdline_credentials, ev);
106 if (!NT_STATUS_IS_OK(status)) {
107 printf("Failed to open connection - %s\n", nt_errstr(status));
111 (*c)->transport->options.use_oplocks = use_oplocks;
112 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
117 BOOL torture_open_connection(struct smbcli_state **c)
119 const char *host = lp_parm_string(-1, "torture", "host");
120 const char *share = lp_parm_string(-1, "torture", "share");
122 return torture_open_connection_share(NULL, c, host, share, NULL);
127 BOOL torture_close_connection(struct smbcli_state *c)
131 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
132 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
139 /* open a rpc connection to the chosen binding string */
140 NTSTATUS torture_rpc_connection(TALLOC_CTX *parent_ctx,
141 struct dcerpc_pipe **p,
142 const struct dcerpc_interface_table *table)
145 const char *binding = lp_parm_string(-1, "torture", "binding");
148 printf("You must specify a ncacn binding string\n");
149 return NT_STATUS_INVALID_PARAMETER;
152 status = dcerpc_pipe_connect(parent_ctx,
154 cmdline_credentials, NULL);
159 /* open a rpc connection to a specific transport */
160 NTSTATUS torture_rpc_connection_transport(TALLOC_CTX *parent_ctx,
161 struct dcerpc_pipe **p,
162 const struct dcerpc_interface_table *table,
163 enum dcerpc_transport_t transport)
166 const char *binding = lp_parm_string(-1, "torture", "binding");
167 struct dcerpc_binding *b;
168 TALLOC_CTX *mem_ctx = talloc_named(parent_ctx, 0, "torture_rpc_connection_smb");
171 printf("You must specify a ncacn binding string\n");
172 talloc_free(mem_ctx);
173 return NT_STATUS_INVALID_PARAMETER;
176 status = dcerpc_parse_binding(mem_ctx, binding, &b);
177 if (!NT_STATUS_IS_OK(status)) {
178 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
179 talloc_free(mem_ctx);
183 b->transport = transport;
185 status = dcerpc_pipe_connect_b(mem_ctx, p, b, table,
186 cmdline_credentials, NULL);
188 if (NT_STATUS_IS_OK(status)) {
189 *p = talloc_reference(parent_ctx, *p);
193 talloc_free(mem_ctx);
197 /* check if the server produced the expected error code */
198 BOOL check_error(const char *location, struct smbcli_state *c,
199 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
203 status = smbcli_nt_error(c->tree);
204 if (NT_STATUS_IS_DOS(status)) {
206 class = NT_STATUS_DOS_CLASS(status);
207 num = NT_STATUS_DOS_CODE(status);
208 if (eclass != class || ecode != num) {
209 printf("unexpected error code %s\n", nt_errstr(status));
210 printf(" expected %s or %s (at %s)\n",
211 nt_errstr(NT_STATUS_DOS(eclass, ecode)),
212 nt_errstr(nterr), location);
216 if (!NT_STATUS_EQUAL(nterr, status)) {
217 printf("unexpected error code %s\n", nt_errstr(status));
218 printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
227 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
229 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
230 if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
236 static BOOL rw_torture(struct smbcli_state *c)
238 const char *lockfname = "\\torture.lck";
242 pid_t pid2, pid = getpid();
247 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
250 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
252 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
257 for (i=0;i<torture_numops;i++) {
258 uint_t n = (uint_t)random()%10;
260 printf("%d\r", i); fflush(stdout);
262 asprintf(&fname, "\\torture.%u", n);
264 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
268 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
270 printf("open failed (%s)\n", smbcli_errstr(c->tree));
275 if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
276 printf("write failed (%s)\n", smbcli_errstr(c->tree));
281 if (smbcli_write(c->tree, fnum, 0, buf,
282 sizeof(pid)+(j*sizeof(buf)),
283 sizeof(buf)) != sizeof(buf)) {
284 printf("write failed (%s)\n", smbcli_errstr(c->tree));
291 if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
292 printf("read failed (%s)\n", smbcli_errstr(c->tree));
297 printf("data corruption!\n");
301 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
302 printf("close failed (%s)\n", smbcli_errstr(c->tree));
306 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
307 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
311 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
312 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
318 smbcli_close(c->tree, fnum2);
319 smbcli_unlink(c->tree, lockfname);
326 static BOOL run_torture(struct smbcli_state *cli, int dummy)
330 ret = rw_torture(cli);
332 if (!torture_close_connection(cli)) {
340 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
342 const char *lockfname = "\\torture2.lck";
347 uint8_t buf_rd[131072];
349 ssize_t bytes_read, bytes_written;
351 if (smbcli_deltree(c1->tree, lockfname) == -1) {
352 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
355 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
358 printf("first open read/write of %s failed (%s)\n",
359 lockfname, smbcli_errstr(c1->tree));
362 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
365 printf("second open read-only of %s failed (%s)\n",
366 lockfname, smbcli_errstr(c2->tree));
367 smbcli_close(c1->tree, fnum1);
371 printf("Checking data integrity over %d ops\n", torture_numops);
373 for (i=0;i<torture_numops;i++)
375 size_t buf_size = ((uint_t)random()%(sizeof(buf)-1))+ 1;
377 printf("%d\r", i); fflush(stdout);
380 generate_random_buffer(buf, buf_size);
382 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
383 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
384 printf("wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
389 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
390 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
391 printf("read %d, expected %d\n", (int)bytes_read, (int)buf_size);
396 if (memcmp(buf_rd, buf, buf_size) != 0)
398 printf("read/write compare failed\n");
404 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
405 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
408 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
409 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
413 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
414 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
421 #define BOOLSTR(b) ((b) ? "Yes" : "No")
423 static BOOL run_readwritetest(void)
425 struct smbcli_state *cli1, *cli2;
426 BOOL test1, test2 = True;
428 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
432 printf("starting readwritetest\n");
434 test1 = rw_torture2(cli1, cli2);
435 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
438 test2 = rw_torture2(cli1, cli1);
439 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
442 if (!torture_close_connection(cli1)) {
446 if (!torture_close_connection(cli2)) {
450 return (test1 && test2);
454 this checks to see if a secondary tconx can use open files from an
457 static BOOL run_tcon_test(void)
459 struct smbcli_state *cli;
460 const char *fname = "\\tcontest.tmp";
462 uint16_t cnum1, cnum2, cnum3;
463 uint16_t vuid1, vuid2;
466 struct smbcli_tree *tree1;
467 const char *host = lp_parm_string(-1, "torture", "host");
468 const char *share = lp_parm_string(-1, "torture", "share");
469 const char *password = lp_parm_string(-1, "torture", "password");
471 if (!torture_open_connection(&cli)) {
475 printf("starting tcontest\n");
477 if (smbcli_deltree(cli->tree, fname) == -1) {
478 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
481 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
483 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
487 cnum1 = cli->tree->tid;
488 vuid1 = cli->session->vuid;
490 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
491 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
492 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
496 tree1 = cli->tree; /* save old tree connection */
497 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
498 printf("%s refused 2nd tree connect (%s)\n", host,
499 smbcli_errstr(cli->tree));
504 cnum2 = cli->tree->tid;
505 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
506 vuid2 = cli->session->vuid + 1;
508 /* try a write with the wrong tid */
509 cli->tree->tid = cnum2;
511 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
512 printf("* server allows write with wrong TID\n");
515 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
519 /* try a write with an invalid tid */
520 cli->tree->tid = cnum3;
522 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
523 printf("* server allows write with invalid TID\n");
526 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
529 /* try a write with an invalid vuid */
530 cli->session->vuid = vuid2;
531 cli->tree->tid = cnum1;
533 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
534 printf("* server allows write with invalid VUID\n");
537 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
540 cli->session->vuid = vuid1;
541 cli->tree->tid = cnum1;
543 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
544 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
548 cli->tree->tid = cnum2;
550 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
551 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
555 cli->tree = tree1; /* restore initial tree */
556 cli->tree->tid = cnum1;
558 smbcli_unlink(tree1, fname);
560 if (!torture_close_connection(cli)) {
569 static BOOL tcon_devtest(struct smbcli_state *cli,
570 const char *myshare, const char *devtype,
571 NTSTATUS expected_error)
575 const char *password = lp_parm_string(-1, "torture", "password");
577 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
580 printf("Trying share %s with devtype %s\n", myshare, devtype);
582 if (NT_STATUS_IS_OK(expected_error)) {
586 printf("tconX to share %s with type %s "
587 "should have succeeded but failed\n",
594 printf("tconx to share %s with type %s "
595 "should have failed but succeeded\n",
599 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
603 printf("Returned unexpected error\n");
612 checks for correct tconX support
614 static BOOL run_tcon_devtype_test(void)
616 struct smbcli_state *cli1 = NULL;
619 const char *host = lp_parm_string(-1, "torture", "host");
620 const char *share = lp_parm_string(-1, "torture", "share");
622 status = smbcli_full_connection(NULL,
625 cmdline_credentials, NULL);
627 if (!NT_STATUS_IS_OK(status)) {
628 printf("could not open connection\n");
632 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
635 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
638 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
641 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
644 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
647 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
650 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
653 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
656 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
659 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
665 printf("Passed tcondevtest\n");
672 test whether fnums and tids open on one VC are available on another (a major
675 static BOOL run_fdpasstest(void)
677 struct smbcli_state *cli1, *cli2;
678 const char *fname = "\\fdpass.tst";
682 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
686 printf("starting fdpasstest\n");
688 smbcli_unlink(cli1->tree, fname);
690 printf("Opening a file on connection 1\n");
692 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
694 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
698 printf("writing to file on connection 1\n");
700 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
701 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
705 oldtid = cli2->tree->tid;
706 cli2->session->vuid = cli1->session->vuid;
707 cli2->tree->tid = cli1->tree->tid;
708 cli2->session->pid = cli1->session->pid;
710 printf("reading from file on connection 2\n");
712 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
713 printf("read succeeded! nasty security hole [%s]\n",
718 smbcli_close(cli1->tree, fnum1);
719 smbcli_unlink(cli1->tree, fname);
721 cli2->tree->tid = oldtid;
723 torture_close_connection(cli1);
724 torture_close_connection(cli2);
726 printf("finished fdpasstest\n");
732 test the timing of deferred open requests
734 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
736 const char *fname = "\\defer_open_test.dat";
742 printf("failed to connect\n");
746 printf("Testing deferred open requests.\n");
753 tv = timeval_current();
754 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
756 FILE_ATTRIBUTE_NORMAL,
757 NTCREATEX_SHARE_ACCESS_NONE,
758 NTCREATEX_DISP_OPEN_IF, 0, 0);
762 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
763 double e = timeval_elapsed(&tv);
764 if (e < 0.5 || e > 1.5) {
765 fprintf(stderr,"Timing incorrect %.2f violation\n",
769 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
772 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
776 printf("pid %u open %d\n", getpid(), i);
780 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
781 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
787 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
788 /* All until the last unlink will fail with sharing violation. */
789 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
790 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
795 printf("deferred test finished\n");
796 if (!torture_close_connection(cli)) {
803 test how many open files this server supports on the one socket
805 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
807 #define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
809 int fnums[0x11000], i;
810 int retries=4, maxfid;
814 printf("failed to connect\n");
818 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
819 printf("Failed to deltree \\maxfid - %s\n",
820 smbcli_errstr(cli->tree));
823 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
824 printf("Failed to mkdir \\maxfid, error=%s\n",
825 smbcli_errstr(cli->tree));
829 printf("Testing maximum number of open files\n");
831 for (i=0; i<0x11000; i++) {
833 asprintf(&fname, "\\maxfid\\fid%d", i/1000);
834 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
835 printf("Failed to mkdir %s, error=%s\n",
836 fname, smbcli_errstr(cli->tree));
841 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
842 if ((fnums[i] = smbcli_open(cli->tree, fname,
843 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
845 printf("open of %s failed (%s)\n",
846 fname, smbcli_errstr(cli->tree));
847 printf("maximum fnum is %d\n", i);
858 printf("cleaning up\n");
859 for (i=0;i<maxfid/2;i++) {
860 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
861 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
862 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
864 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
865 printf("unlink of %s failed (%s)\n",
866 fname, smbcli_errstr(cli->tree));
871 asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
872 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
873 printf("Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
875 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
876 printf("unlink of %s failed (%s)\n",
877 fname, smbcli_errstr(cli->tree));
882 printf("%6d %6d\r", i, maxfid-i);
886 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
887 printf("Failed to deltree \\maxfid - %s\n",
888 smbcli_errstr(cli->tree));
892 printf("maxfid test finished\n");
893 if (!torture_close_connection(cli)) {
897 #undef MAXFID_TEMPLATE
900 /* send smb negprot commands, not reading the response */
901 static BOOL run_negprot_nowait(void)
904 struct smbcli_state *cli, *cli2;
907 printf("starting negprot nowait test\n");
909 cli = open_nbt_connection();
914 printf("Filling send buffer\n");
916 for (i=0;i<100;i++) {
917 struct smbcli_request *req;
918 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
919 event_loop_once(cli->transport->socket->event.ctx);
920 if (req->state == SMBCLI_REQUEST_ERROR) {
922 printf("Failed to fill pipe packet[%d] - %s (ignored)\n", i+1, nt_errstr(req->status));
925 printf("Failed to fill pipe - %s \n", nt_errstr(req->status));
926 torture_close_connection(cli);
932 printf("Opening secondary connection\n");
933 if (!torture_open_connection(&cli2)) {
934 printf("Failed to open secondary connection\n");
938 if (!torture_close_connection(cli2)) {
939 printf("Failed to close secondary connection\n");
943 torture_close_connection(cli);
945 printf("finished negprot nowait test\n");
952 This checks how the getatr calls works
954 static BOOL run_attrtest(void)
956 struct smbcli_state *cli;
959 const char *fname = "\\attrib123456789.tst";
962 printf("starting attrib test\n");
964 if (!torture_open_connection(&cli)) {
968 smbcli_unlink(cli->tree, fname);
969 fnum = smbcli_open(cli->tree, fname,
970 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
971 smbcli_close(cli->tree, fnum);
973 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
974 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
978 printf("New file time is %s", ctime(&t));
980 if (abs(t - time(NULL)) > 60*60*24*10) {
981 printf("ERROR: SMBgetatr bug. time is %s",
987 t2 = t-60*60*24; /* 1 day ago */
989 printf("Setting file time to %s", ctime(&t2));
991 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
992 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
996 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
997 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
1001 printf("Retrieved file time as %s", ctime(&t));
1004 printf("ERROR: getatr/setatr bug. times are\n%s",
1006 printf("%s", ctime(&t2));
1010 smbcli_unlink(cli->tree, fname);
1012 if (!torture_close_connection(cli)) {
1016 printf("attrib test finished\n");
1023 This checks a couple of trans2 calls
1025 static BOOL run_trans2test(void)
1027 struct smbcli_state *cli;
1030 time_t c_time, a_time, m_time, w_time, m_time2;
1031 const char *fname = "\\trans2.tst";
1032 const char *dname = "\\trans2";
1033 const char *fname2 = "\\trans2\\trans2.tst";
1035 BOOL correct = True;
1037 printf("starting trans2 test\n");
1039 if (!torture_open_connection(&cli)) {
1043 smbcli_unlink(cli->tree, fname);
1045 printf("Testing qfileinfo\n");
1047 fnum = smbcli_open(cli->tree, fname,
1048 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1049 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
1051 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
1055 printf("Testing NAME_INFO\n");
1057 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
1058 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
1062 if (!pname || strcmp(pname, fname)) {
1063 printf("qfilename gave different name? [%s] [%s]\n",
1068 smbcli_close(cli->tree, fnum);
1069 smbcli_unlink(cli->tree, fname);
1071 fnum = smbcli_open(cli->tree, fname,
1072 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1074 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1077 smbcli_close(cli->tree, fnum);
1079 printf("Checking for sticky create times\n");
1081 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1082 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
1085 if (c_time != m_time) {
1086 printf("create time=%s", ctime(&c_time));
1087 printf("modify time=%s", ctime(&m_time));
1088 printf("This system appears to have sticky create times\n");
1090 if (a_time % (60*60) == 0) {
1091 printf("access time=%s", ctime(&a_time));
1092 printf("This system appears to set a midnight access time\n");
1096 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1097 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1103 smbcli_unlink(cli->tree, fname);
1104 fnum = smbcli_open(cli->tree, fname,
1105 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1106 smbcli_close(cli->tree, fnum);
1107 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1108 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1111 if (w_time < 60*60*24*2) {
1112 printf("write time=%s", ctime(&w_time));
1113 printf("This system appears to set a initial 0 write time\n");
1118 smbcli_unlink(cli->tree, fname);
1121 /* check if the server updates the directory modification time
1122 when creating a new file */
1123 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1124 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
1128 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1129 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1133 fnum = smbcli_open(cli->tree, fname2,
1134 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1135 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
1136 smbcli_close(cli->tree, fnum);
1137 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
1138 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1141 if (m_time2 == m_time) {
1142 printf("This system does not update directory modification times\n");
1146 smbcli_unlink(cli->tree, fname2);
1147 smbcli_rmdir(cli->tree, dname);
1149 if (!torture_close_connection(cli)) {
1153 printf("trans2 test finished\n");
1160 /* FIRST_DESIRED_ACCESS 0xf019f */
1161 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1162 SEC_FILE_READ_EA| /* 0xf */ \
1163 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1164 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1165 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1166 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1167 /* SECOND_DESIRED_ACCESS 0xe0080 */
1168 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1169 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1170 SEC_STD_WRITE_OWNER /* 0xe0000 */
1173 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1174 READ_CONTROL|WRITE_DAC|\
1175 SEC_FILE_READ_DATA|\
1180 Test ntcreate calls made by xcopy
1182 static BOOL run_xcopy(void)
1184 struct smbcli_state *cli1;
1185 const char *fname = "\\test.txt";
1186 BOOL correct = True;
1189 printf("starting xcopy test\n");
1191 if (!torture_open_connection(&cli1)) {
1195 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1196 FIRST_DESIRED_ACCESS,
1197 FILE_ATTRIBUTE_ARCHIVE,
1198 NTCREATEX_SHARE_ACCESS_NONE,
1199 NTCREATEX_DISP_OVERWRITE_IF,
1203 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
1207 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1208 SECOND_DESIRED_ACCESS, 0,
1209 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1212 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
1216 if (!torture_close_connection(cli1)) {
1225 see how many RPC pipes we can open at once
1227 static BOOL run_pipe_number(void)
1229 struct smbcli_state *cli1;
1230 const char *pipe_name = "\\WKSSVC";
1234 printf("starting pipenumber test\n");
1235 if (!torture_open_connection(&cli1)) {
1240 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1241 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1244 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
1248 printf("%d\r", num_pipes);
1252 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
1253 torture_close_connection(cli1);
1261 open N connections to the server and just hold them open
1262 used for testing performance when there are N idle users
1265 static BOOL torture_holdcon(void)
1268 struct smbcli_state **cli;
1271 printf("Opening %d connections\n", torture_numops);
1273 cli = malloc_array_p(struct smbcli_state *, torture_numops);
1275 for (i=0;i<torture_numops;i++) {
1276 if (!torture_open_connection(&cli[i])) {
1279 printf("opened %d connections\r", i);
1283 printf("\nStarting pings\n");
1286 for (i=0;i<torture_numops;i++) {
1289 status = smbcli_chkpath(cli[i]->tree, "\\");
1290 if (!NT_STATUS_IS_OK(status)) {
1291 printf("Connection %d is dead\n", i);
1299 if (num_dead == torture_numops) {
1300 printf("All connections dead - finishing\n");
1312 Try with a wrong vuid and check error message.
1315 static BOOL run_vuidtest(void)
1317 struct smbcli_state *cli;
1318 const char *fname = "\\vuid.tst";
1321 time_t c_time, a_time, m_time;
1322 BOOL correct = True;
1327 printf("starting vuid test\n");
1329 if (!torture_open_connection(&cli)) {
1333 smbcli_unlink(cli->tree, fname);
1335 fnum = smbcli_open(cli->tree, fname,
1336 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1338 orig_vuid = cli->session->vuid;
1340 cli->session->vuid += 1234;
1342 printf("Testing qfileinfo with wrong vuid\n");
1344 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
1345 &size, &c_time, &a_time,
1346 &m_time, NULL, NULL))) {
1347 printf("ERROR: qfileinfo passed with wrong vuid\n");
1351 if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1352 NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
1353 !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1354 NT_STATUS_INVALID_HANDLE)) {
1355 printf("ERROR: qfileinfo should have returned DOS error "
1356 "ERRSRV:ERRbaduid\n but returned %s\n",
1357 smbcli_errstr(cli->tree));
1361 cli->session->vuid -= 1234;
1363 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1364 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
1368 smbcli_unlink(cli->tree, fname);
1370 if (!torture_close_connection(cli)) {
1374 printf("vuid test finished\n");
1380 Test open mode returns on read-only files.
1382 static BOOL run_opentest(void)
1384 static struct smbcli_state *cli1;
1385 static struct smbcli_state *cli2;
1386 const char *fname = "\\readonly.file";
1387 char *control_char_fname;
1391 BOOL correct = True;
1396 printf("starting open test\n");
1398 if (!torture_open_connection(&cli1)) {
1402 asprintf(&control_char_fname, "\\readonly.afile");
1403 for (i = 1; i <= 0x1f; i++) {
1404 control_char_fname[10] = i;
1405 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
1406 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1408 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
1409 NT_STATUS_OBJECT_NAME_INVALID)) {
1410 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
1411 smbcli_errstr(cli1->tree), i);
1416 smbcli_close(cli1->tree, fnum1);
1418 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
1419 smbcli_unlink(cli1->tree, control_char_fname);
1421 free(control_char_fname);
1424 printf("Create file with control char names passed.\n");
1426 smbcli_setatr(cli1->tree, fname, 0, 0);
1427 smbcli_unlink(cli1->tree, fname);
1429 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1431 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1435 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1436 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1440 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
1441 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
1442 CHECK_MAX_FAILURES(error_test1);
1446 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1448 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1449 CHECK_MAX_FAILURES(error_test1);
1453 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
1454 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1456 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
1457 NT_STATUS_ACCESS_DENIED)) {
1458 printf("correct error code ERRDOS/ERRnoaccess returned\n");
1461 printf("finished open test 1\n");
1463 smbcli_close(cli1->tree, fnum1);
1465 /* Now try not readonly and ensure ERRbadshare is returned. */
1467 smbcli_setatr(cli1->tree, fname, 0, 0);
1469 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1471 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1475 /* This will fail - but the error should be ERRshare. */
1476 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1478 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
1479 NT_STATUS_SHARING_VIOLATION)) {
1480 printf("correct error code ERRDOS/ERRbadshare returned\n");
1483 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1484 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1488 smbcli_unlink(cli1->tree, fname);
1490 printf("finished open test 2\n");
1492 /* Test truncate open disposition on file opened for read. */
1494 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1496 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1500 /* write 20 bytes. */
1502 memset(buf, '\0', 20);
1504 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1505 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1509 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1510 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1514 /* Ensure size == 20. */
1515 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1516 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1517 CHECK_MAX_FAILURES(error_test3);
1522 printf("(3) file size != 20\n");
1523 CHECK_MAX_FAILURES(error_test3);
1527 /* Now test if we can truncate a file opened for readonly. */
1529 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
1531 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1532 CHECK_MAX_FAILURES(error_test3);
1536 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1537 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1541 /* Ensure size == 0. */
1542 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1543 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1544 CHECK_MAX_FAILURES(error_test3);
1549 printf("(3) file size != 0\n");
1550 CHECK_MAX_FAILURES(error_test3);
1553 printf("finished open test 3\n");
1555 smbcli_unlink(cli1->tree, fname);
1558 printf("testing ctemp\n");
1559 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
1561 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1562 CHECK_MAX_FAILURES(error_test4);
1565 printf("ctemp gave path %s\n", tmp_path);
1566 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1567 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1569 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1570 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1573 /* Test the non-io opens... */
1575 if (!torture_open_connection(&cli2)) {
1579 smbcli_setatr(cli2->tree, fname, 0, 0);
1580 smbcli_unlink(cli2->tree, fname);
1582 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1584 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1585 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1588 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1589 CHECK_MAX_FAILURES(error_test10);
1593 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1594 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1596 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1597 CHECK_MAX_FAILURES(error_test10);
1601 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1602 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1605 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1606 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1610 printf("non-io open test #1 passed.\n");
1612 smbcli_unlink(cli1->tree, fname);
1614 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1616 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1617 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1620 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1621 CHECK_MAX_FAILURES(error_test20);
1625 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1626 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1629 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1630 CHECK_MAX_FAILURES(error_test20);
1634 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1635 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1638 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1639 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1643 printf("non-io open test #2 passed.\n");
1645 smbcli_unlink(cli1->tree, fname);
1647 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1649 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1650 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1653 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1654 CHECK_MAX_FAILURES(error_test30);
1658 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1659 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1662 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1663 CHECK_MAX_FAILURES(error_test30);
1667 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1668 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1671 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1672 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1676 printf("non-io open test #3 passed.\n");
1678 smbcli_unlink(cli1->tree, fname);
1680 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1682 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1683 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1686 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1687 CHECK_MAX_FAILURES(error_test40);
1691 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1692 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1695 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1696 CHECK_MAX_FAILURES(error_test40);
1700 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1702 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1703 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1707 printf("non-io open test #4 passed.\n");
1709 smbcli_unlink(cli1->tree, fname);
1711 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1713 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1714 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1717 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1718 CHECK_MAX_FAILURES(error_test50);
1722 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1723 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1726 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1727 CHECK_MAX_FAILURES(error_test50);
1731 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1732 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1736 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1737 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1741 printf("non-io open test #5 passed.\n");
1743 printf("TEST #6 testing 1 non-io open, one io open\n");
1745 smbcli_unlink(cli1->tree, fname);
1747 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1748 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1751 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1752 CHECK_MAX_FAILURES(error_test60);
1756 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1757 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1760 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1761 CHECK_MAX_FAILURES(error_test60);
1765 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1766 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1770 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1771 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1775 printf("non-io open test #6 passed.\n");
1777 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
1779 smbcli_unlink(cli1->tree, fname);
1781 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1782 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1785 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1786 CHECK_MAX_FAILURES(error_test70);
1790 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1791 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1794 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1795 CHECK_MAX_FAILURES(error_test70);
1799 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1801 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1802 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1806 printf("non-io open test #7 passed.\n");
1810 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1812 smbcli_unlink(cli1->tree, fname);
1814 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1816 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1820 /* write 20 bytes. */
1822 memset(buf, '\0', 20);
1824 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1825 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1829 /* Ensure size == 20. */
1830 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1831 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1832 CHECK_MAX_FAILURES(error_test80);
1837 printf("(8) file size != 20\n");
1838 CHECK_MAX_FAILURES(error_test80);
1842 /* Get an exclusive lock on the open file. */
1843 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1844 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1845 CHECK_MAX_FAILURES(error_test80);
1849 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1851 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1855 /* Ensure size == 0. */
1856 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1857 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1858 CHECK_MAX_FAILURES(error_test80);
1863 printf("(8) file size != 0\n");
1864 CHECK_MAX_FAILURES(error_test80);
1868 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1869 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1873 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1874 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1880 printf("open test #8 passed.\n");
1882 smbcli_unlink(cli1->tree, fname);
1884 if (!torture_close_connection(cli1)) {
1887 if (!torture_close_connection(cli2)) {
1896 sees what IOCTLs are supported
1898 BOOL torture_ioctl_test(void)
1900 struct smbcli_state *cli;
1901 uint16_t device, function;
1903 const char *fname = "\\ioctl.dat";
1905 union smb_ioctl parms;
1906 TALLOC_CTX *mem_ctx;
1908 if (!torture_open_connection(&cli)) {
1912 mem_ctx = talloc_init("ioctl_test");
1914 printf("starting ioctl test\n");
1916 smbcli_unlink(cli->tree, fname);
1918 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1920 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1924 parms.ioctl.level = RAW_IOCTL_IOCTL;
1925 parms.ioctl.in.fnum = fnum;
1926 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
1927 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1928 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
1930 for (device=0;device<0x100;device++) {
1931 printf("testing device=0x%x\n", device);
1932 for (function=0;function<0x100;function++) {
1933 parms.ioctl.in.request = (device << 16) | function;
1934 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1936 if (NT_STATUS_IS_OK(status)) {
1937 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
1938 device, function, (int)parms.ioctl.out.blob.length);
1943 if (!torture_close_connection(cli)) {
1952 tries variants of chkpath
1954 BOOL torture_chkpath_test(void)
1956 struct smbcli_state *cli;
1960 if (!torture_open_connection(&cli)) {
1964 printf("starting chkpath test\n");
1966 printf("Testing valid and invalid paths\n");
1968 /* cleanup from an old run */
1969 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1970 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1971 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1973 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1974 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1978 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1979 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1983 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1985 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
1988 smbcli_close(cli->tree, fnum);
1990 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1991 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1995 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1996 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
2000 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
2001 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2002 NT_STATUS_NOT_A_DIRECTORY);
2004 printf("* chkpath on a file should fail\n");
2008 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
2009 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2010 NT_STATUS_OBJECT_NAME_NOT_FOUND);
2012 printf("* chkpath on a non existent file should fail\n");
2016 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
2017 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2018 NT_STATUS_OBJECT_PATH_NOT_FOUND);
2020 printf("* chkpath on a non existent component should fail\n");
2024 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
2025 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
2026 smbcli_rmdir(cli->tree, "\\chkpath.dir");
2028 if (!torture_close_connection(cli)) {
2036 static void sigcont(int sig)
2040 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
2043 volatile pid_t *child_status;
2044 volatile BOOL *child_status_out;
2047 double start_time_limit = 10 + (torture_nprocs * 1.5);
2048 char **unc_list = NULL;
2050 int num_unc_names = 0;
2057 signal(SIGCONT, sigcont);
2059 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
2060 if (!child_status) {
2061 printf("Failed to setup shared memory\n");
2065 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
2066 if (!child_status_out) {
2067 printf("Failed to setup result status shared memory\n");
2071 p = lp_parm_string(-1, "torture", "unclist");
2073 unc_list = file_lines_load(p, &num_unc_names, NULL);
2074 if (!unc_list || num_unc_names <= 0) {
2075 printf("Failed to load unc names list from '%s'\n", p);
2080 for (i = 0; i < torture_nprocs; i++) {
2081 child_status[i] = 0;
2082 child_status_out[i] = True;
2085 tv = timeval_current();
2087 for (i=0;i<torture_nprocs;i++) {
2091 const char *hostname=NULL, *sharename;
2093 pid_t mypid = getpid();
2094 srandom(((int)mypid) ^ ((int)time(NULL)));
2096 asprintf(&myname, "CLIENT%d", i);
2097 lp_set_cmdline("netbios name", myname);
2102 if (!smbcli_parse_unc(unc_list[i % num_unc_names],
2103 NULL, &hostname, &sharename)) {
2104 printf("Failed to parse UNC name %s\n",
2105 unc_list[i % num_unc_names]);
2112 if (torture_open_connection_share(NULL,
2119 } else if (torture_open_connection(¤t_cli)) {
2123 printf("pid %d failed to start\n", (int)getpid());
2129 child_status[i] = getpid();
2133 if (child_status[i]) {
2134 printf("Child %d failed to start!\n", i);
2135 child_status_out[i] = 1;
2139 child_status_out[i] = fn(current_cli, i);
2146 for (i=0;i<torture_nprocs;i++) {
2147 if (child_status[i]) synccount++;
2149 if (synccount == torture_nprocs) break;
2151 } while (timeval_elapsed(&tv) < start_time_limit);
2153 if (synccount != torture_nprocs) {
2154 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
2156 return timeval_elapsed(&tv);
2159 printf("Starting %d clients\n", torture_nprocs);
2161 /* start the client load */
2162 tv = timeval_current();
2163 for (i=0;i<torture_nprocs;i++) {
2164 child_status[i] = 0;
2167 printf("%d clients started\n", torture_nprocs);
2171 for (i=0;i<torture_nprocs;i++) {
2173 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
2174 if (ret == -1 || WEXITSTATUS(status) != 0) {
2181 for (i=0;i<torture_nprocs;i++) {
2182 if (!child_status_out[i]) {
2186 return timeval_elapsed(&tv);
2189 #define FLAG_MULTIPROC 1
2194 BOOL (*multi_fn)(struct smbcli_state *, int );
2197 {"BASE-FDPASS", run_fdpasstest, 0},
2198 {"BASE-LOCK1", torture_locktest1, 0},
2199 {"BASE-LOCK2", torture_locktest2, 0},
2200 {"BASE-LOCK3", torture_locktest3, 0},
2201 {"BASE-LOCK4", torture_locktest4, 0},
2202 {"BASE-LOCK5", torture_locktest5, 0},
2203 {"BASE-LOCK6", torture_locktest6, 0},
2204 {"BASE-LOCK7", torture_locktest7, 0},
2205 {"BASE-UNLINK", torture_unlinktest, 0},
2206 {"BASE-ATTR", run_attrtest, 0},
2207 {"BASE-TRANS2", run_trans2test, 0},
2208 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
2209 {"BASE-DIR1", torture_dirtest1, 0},
2210 {"BASE-DIR2", torture_dirtest2, 0},
2211 {"BASE-DENY1", torture_denytest1, 0},
2212 {"BASE-DENY2", torture_denytest2, 0},
2213 {"BASE-DENY3", torture_denytest3, 0},
2214 {"BASE-DENYDOS", torture_denydos_sharing, 0},
2215 {"BASE-NTDENY1", NULL, torture_ntdenytest1},
2216 {"BASE-NTDENY2", torture_ntdenytest2, 0},
2217 {"BASE-TCON", run_tcon_test, 0},
2218 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
2219 {"BASE-VUID", run_vuidtest, 0},
2220 {"BASE-RW1", run_readwritetest, 0},
2221 {"BASE-OPEN", run_opentest, 0},
2222 {"BASE-DEFER_OPEN", NULL, run_deferopen},
2223 {"BASE-XCOPY", run_xcopy, 0},
2224 {"BASE-RENAME", torture_test_rename, 0},
2225 {"BASE-DELETE", torture_test_delete, 0},
2226 {"BASE-PROPERTIES", torture_test_properties, 0},
2227 {"BASE-MANGLE", torture_mangle, 0},
2228 {"BASE-OPENATTR", torture_openattrtest, 0},
2229 {"BASE-CHARSET", torture_charset, 0},
2230 {"BASE-CHKPATH", torture_chkpath_test, 0},
2231 {"BASE-SECLEAK", torture_sec_leak, 0},
2232 {"BASE-DISCONNECT", torture_disconnect, 0},
2233 {"BASE-DELAYWRITE", torture_delay_write, 0},
2235 /* benchmarking tests */
2236 {"BENCH-HOLDCON", torture_holdcon, 0},
2237 {"BENCH-NBENCH", torture_nbench, 0},
2238 {"BENCH-TORTURE", NULL, run_torture},
2239 {"BENCH-NBT", torture_bench_nbt, 0},
2240 {"BENCH-WINS", torture_bench_wins, 0},
2241 {"BENCH-RPC", torture_bench_rpc, 0},
2242 {"BENCH-CLDAP", torture_bench_cldap, 0},
2245 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
2246 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
2247 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
2248 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
2249 {"RAW-SEARCH", torture_raw_search, 0},
2250 {"RAW-CLOSE", torture_raw_close, 0},
2251 {"RAW-OPEN", torture_raw_open, 0},
2252 {"RAW-MKDIR", torture_raw_mkdir, 0},
2253 {"RAW-OPLOCK", torture_raw_oplock, 0},
2254 {"RAW-NOTIFY", torture_raw_notify, 0},
2255 {"RAW-MUX", torture_raw_mux, 0},
2256 {"RAW-IOCTL", torture_raw_ioctl, 0},
2257 {"RAW-CHKPATH", torture_raw_chkpath, 0},
2258 {"RAW-UNLINK", torture_raw_unlink, 0},
2259 {"RAW-READ", torture_raw_read, 0},
2260 {"RAW-WRITE", torture_raw_write, 0},
2261 {"RAW-LOCK", torture_raw_lock, 0},
2262 {"RAW-CONTEXT", torture_raw_context, 0},
2263 {"RAW-RENAME", torture_raw_rename, 0},
2264 {"RAW-SEEK", torture_raw_seek, 0},
2265 {"RAW-EAS", torture_raw_eas, 0},
2266 {"RAW-EAMAX", torture_max_eas, 0},
2267 {"RAW-STREAMS", torture_raw_streams, 0},
2268 {"RAW-ACLS", torture_raw_acls, 0},
2269 {"RAW-RAP", torture_raw_rap, 0},
2270 {"RAW-COMPOSITE", torture_raw_composite, 0},
2273 {"SMB2-CONNECT", torture_smb2_connect, 0},
2274 {"SMB2-SCAN", torture_smb2_scan, 0},
2275 {"SMB2-SCANGETINFO", torture_smb2_getinfo_scan, 0},
2276 {"SMB2-SCANSETINFO", torture_smb2_setinfo_scan, 0},
2277 {"SMB2-SCANFIND", torture_smb2_find_scan, 0},
2278 {"SMB2-GETINFO", torture_smb2_getinfo, 0},
2279 {"SMB2-SETINFO", torture_smb2_setinfo, 0},
2280 {"SMB2-FIND", torture_smb2_find, 0},
2282 /* protocol scanners */
2283 {"SCAN-TRANS2", torture_trans2_scan, 0},
2284 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2285 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2286 {"SCAN-SMB", torture_smb_scan, 0},
2287 {"SCAN-MAXFID", NULL, run_maxfidtest},
2288 {"SCAN-UTABLE", torture_utable, 0},
2289 {"SCAN-CASETABLE", torture_casetable, 0},
2290 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2291 {"SCAN-IOCTL", torture_ioctl_test, 0},
2292 {"SCAN-RAP", torture_rap_scan, 0},
2295 {"RPC-LSA", torture_rpc_lsa, 0},
2296 {"RPC-LSALOOKUP", torture_rpc_lsa_lookup, 0},
2297 {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
2298 {"RPC-ECHO", torture_rpc_echo, 0},
2299 {"RPC-DFS", torture_rpc_dfs, 0},
2300 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2301 {"RPC-SAMR", torture_rpc_samr, 0},
2302 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2303 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2304 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2305 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2306 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2307 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2308 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2309 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2310 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2311 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2312 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2313 {"RPC-WINREG", torture_rpc_winreg, 0},
2314 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2315 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2316 {"RPC-REMACT", torture_rpc_remact, 0},
2317 {"RPC-MGMT", torture_rpc_mgmt, 0},
2318 {"RPC-SCANNER", torture_rpc_scanner, 0},
2319 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2320 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2321 {"RPC-MULTIBIND", torture_multi_bind, 0},
2322 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2323 {"RPC-CRACKNAMES", torture_rpc_drsuapi_cracknames, 0},
2324 {"RPC-ROT", torture_rpc_rot, 0},
2325 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2326 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2327 {"RPC-JOIN", torture_rpc_join, 0},
2328 {"RPC-DSSYNC", torture_rpc_dssync, 0},
2330 /* local (no server) testers */
2331 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2332 {"LOCAL-ICONV", torture_local_iconv, 0},
2333 {"LOCAL-TALLOC", torture_local_talloc, 0},
2334 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2335 {"LOCAL-IRPC", torture_local_irpc, 0},
2336 {"LOCAL-BINDING", torture_local_binding_string, 0},
2337 {"LOCAL-STRLIST", torture_local_util_strlist, 0},
2338 {"LOCAL-FILE", torture_local_util_file, 0},
2339 {"LOCAL-IDTREE", torture_local_idtree, 0},
2340 {"LOCAL-SOCKET", torture_local_socket, 0},
2341 {"LOCAL-PAC", torture_pac, 0},
2342 {"LOCAL-REGISTRY", torture_registry, 0},
2343 {"LOCAL-RESOLVE", torture_local_resolve, 0},
2344 {"LOCAL-SDDL", torture_local_sddl, 0},
2345 {"LOCAL-NDR", torture_local_ndr, 0},
2347 /* COM (Component Object Model) testers */
2348 {"COM-SIMPLE", torture_com_simple, 0 },
2351 {"LDAP-BASIC", torture_ldap_basic, 0},
2352 {"LDAP-CLDAP", torture_cldap, 0},
2355 {"NBT-REGISTER", torture_nbt_register, 0},
2356 {"NBT-WINS", torture_nbt_wins, 0},
2357 {"NBT-DGRAM", torture_nbt_dgram, 0},
2358 {"NBT-BROWSE", torture_nbt_browse, 0},
2359 {"NBT-WINSREPLICATION-SIMPLE", torture_nbt_winsreplication_simple, 0},
2360 {"NBT-WINSREPLICATION-REPLICA", torture_nbt_winsreplication_replica, 0},
2361 {"NBT-WINSREPLICATION-OWNED", torture_nbt_winsreplication_owned, 0},
2364 {"NET-USERINFO", torture_userinfo, 0},
2365 {"NET-USERADD", torture_useradd, 0},
2366 {"NET-USERDEL", torture_userdel, 0},
2367 {"NET-USERMOD", torture_usermod, 0},
2368 {"NET-DOMOPEN", torture_domainopen, 0},
2369 {"NET-API-LOOKUP", torture_lookup, 0},
2370 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2371 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2372 {"NET-API-CREATEUSER", torture_createuser, 0},
2373 {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
2374 {"NET-API-LISTSHARES", torture_listshares, 0},
2375 {"NET-API-DELSHARE", torture_delshare, 0},
2381 /****************************************************************************
2382 run a specified test or "ALL"
2383 ****************************************************************************/
2384 static BOOL run_test(const char *name)
2388 BOOL matched = False;
2390 if (strequal(name,"ALL")) {
2391 for (i=0;torture_ops[i].name;i++) {
2392 if (!run_test(torture_ops[i].name)) {
2399 for (i=0;torture_ops[i].name;i++) {
2400 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
2404 printf("Running %s\n", torture_ops[i].name);
2405 if (torture_ops[i].multi_fn) {
2406 BOOL result = False;
2407 t = torture_create_procs(torture_ops[i].multi_fn,
2411 printf("TEST %s FAILED!\n", torture_ops[i].name);
2415 struct timeval tv = timeval_current();
2416 if (!torture_ops[i].fn()) {
2418 printf("TEST %s FAILED!\n", torture_ops[i].name);
2420 t = timeval_elapsed(&tv);
2422 printf("%s took %g secs\n\n", torture_ops[i].name, t);
2427 printf("Unknown torture operation '%s'\n", name);
2434 static void parse_dns(const char *dns)
2436 char *userdn, *basedn, *secret;
2439 /* retrievieng the userdn */
2440 p = strchr_m(dns, '#');
2442 lp_set_cmdline("torture:ldap_userdn", "");
2443 lp_set_cmdline("torture:ldap_basedn", "");
2444 lp_set_cmdline("torture:ldap_secret", "");
2447 userdn = strndup(dns, p - dns);
2448 lp_set_cmdline("torture:ldap_userdn", userdn);
2450 /* retrieve the basedn */
2452 p = strchr_m(d, '#');
2454 lp_set_cmdline("torture:ldap_basedn", "");
2455 lp_set_cmdline("torture:ldap_secret", "");
2458 basedn = strndup(d, p - d);
2459 lp_set_cmdline("torture:ldap_basedn", basedn);
2461 /* retrieve the secret */
2464 lp_set_cmdline("torture:ldap_secret", "");
2468 lp_set_cmdline("torture:ldap_secret", secret);
2470 printf ("%s - %s - %s\n", userdn, basedn, secret);
2474 static void usage(poptContext pc)
2479 poptPrintUsage(pc, stdout, 0);
2482 printf("The binding format is:\n\n");
2484 printf(" TRANSPORT:host[flags]\n\n");
2486 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2488 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2489 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2490 printf(" string.\n\n");
2492 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2493 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2494 printf(" will be auto-determined.\n\n");
2496 printf(" other recognised flags are:\n\n");
2498 printf(" sign : enable ntlmssp signing\n");
2499 printf(" seal : enable ntlmssp sealing\n");
2500 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2501 printf(" validate: enable the NDR validator\n");
2502 printf(" print: enable debugging of the packets\n");
2503 printf(" bigendian: use bigendian RPC\n");
2504 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2506 printf(" For example, these all connect to the samr pipe:\n\n");
2508 printf(" ncacn_np:myserver\n");
2509 printf(" ncacn_np:myserver[samr]\n");
2510 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2511 printf(" ncacn_np:myserver[/pipe/samr]\n");
2512 printf(" ncacn_np:myserver[samr,sign,print]\n");
2513 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2514 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2515 printf(" ncacn_np:\n");
2516 printf(" ncacn_np:[/pipe/samr]\n\n");
2518 printf(" ncacn_ip_tcp:myserver\n");
2519 printf(" ncacn_ip_tcp:myserver[1024]\n");
2520 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2522 printf("The unc format is:\n\n");
2524 printf(" //server/share\n\n");
2526 printf("tests are:");
2527 for (i=0;torture_ops[i].name;i++) {
2528 if ((i%perline)==0) {
2531 printf("%s ", torture_ops[i].name);
2535 printf("default test is ALL\n");
2540 static BOOL is_binding_string(const char *binding_string)
2542 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2543 struct dcerpc_binding *binding_struct;
2546 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2548 talloc_free(mem_ctx);
2549 return NT_STATUS_IS_OK(status);
2552 static void max_runtime_handler(int sig)
2554 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2558 /****************************************************************************
2560 ****************************************************************************/
2561 int main(int argc,char *argv[])
2565 BOOL correct = True;
2570 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,
2571 OPT_DANGEROUS,OPT_SMB_PORTS};
2573 struct poptOption long_options[] = {
2575 {"smb-ports", 'p', POPT_ARG_STRING, NULL, OPT_SMB_PORTS, "SMB ports", NULL},
2576 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2577 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2578 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2579 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2580 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2581 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2582 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2583 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2584 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2585 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2586 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2587 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2588 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2589 "set maximum time for smbtorture to live", "seconds"},
2591 POPT_COMMON_CONNECTION
2592 POPT_COMMON_CREDENTIALS
2597 #ifdef HAVE_SETBUFFER
2598 setbuffer(stdout, NULL, 0);
2601 /* we are never interested in SIGPIPE */
2602 BlockSignals(True,SIGPIPE);
2604 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2605 POPT_CONTEXT_KEEP_FIRST);
2607 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2609 while((opt = poptGetNextOpt(pc)) != -1) {
2612 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2615 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2618 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2621 parse_dns(poptGetOptArg(pc));
2624 lp_set_cmdline("torture:dangerous", "Yes");
2627 lp_set_cmdline("smb ports", poptGetOptArg(pc));
2630 d_printf("Invalid option %s: %s\n",
2631 poptBadOption(pc, 0), poptStrerror(opt));
2638 /* this will only work if nobody else uses alarm(),
2639 which means it won't work for some tests, but we
2640 can't use the event context method we use for smbd
2641 as so many tests create their own event
2642 context. This will at least catch most cases. */
2643 signal(SIGALRM, max_runtime_handler);
2651 dcerpc_table_init();
2653 if (torture_seed == 0) {
2654 torture_seed = time(NULL);
2656 printf("Using seed %d\n", torture_seed);
2657 srandom(torture_seed);
2659 argv_new = discard_const_p(char *, poptGetArgs(pc));
2662 for (i=0; i<argc; i++) {
2663 if (argv_new[i] == NULL) {
2674 for(p = argv_new[1]; *p; p++) {
2679 /* see if its a RPC transport specifier */
2680 if (is_binding_string(argv_new[1])) {
2681 lp_set_cmdline("torture:binding", argv_new[1]);
2683 char *binding = NULL;
2684 const char *host = NULL, *share = NULL;
2686 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
2687 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
2691 lp_set_cmdline("torture:host", host);
2692 lp_set_cmdline("torture:share", share);
2693 asprintf(&binding, "ncacn_np:%s", host);
2694 lp_set_cmdline("torture:binding", binding);
2697 if (argc_new == 0) {
2698 printf("You must specify a test to run, or 'ALL'\n");
2700 for (i=2;i<argc_new;i++) {
2701 if (!run_test(argv_new[i])) {