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"
33 #include "auth/credentials/credentials.h"
35 #include "torture/basic/proto.h"
36 #include "torture/raw/proto.h"
37 #include "torture/smb2/proto.h"
38 #include "torture/rpc/proto.h"
39 #include "torture/rap/proto.h"
40 #include "torture/auth/proto.h"
41 #include "torture/local/proto.h"
42 #include "torture/nbench/proto.h"
43 #include "torture/ldap/proto.h"
44 #include "torture/com/proto.h"
45 #include "torture/nbt/proto.h"
46 #include "torture/libnet/proto.h"
47 #include "torture/torture.h"
49 #include "dlinklist.h"
52 int torture_numops=10;
53 int torture_entries=1000;
54 int torture_failures=1;
56 static int procnum; /* records process count number when forking */
57 static struct smbcli_state *current_cli;
58 static BOOL use_oplocks;
59 static BOOL use_level_II_oplocks;
60 #define MAX_COLS 80 /* FIXME: Determine this at run-time */
62 BOOL torture_showall = False;
64 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
66 static struct smbcli_state *open_nbt_connection(void)
68 struct nbt_name called, calling;
69 struct smbcli_state *cli;
70 const char *host = lp_parm_string(-1, "torture", "host");
72 make_nbt_name_client(&calling, lp_netbios_name());
74 nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
76 cli = smbcli_state_init(NULL);
78 printf("Failed initialize smbcli_struct to connect with %s\n", host);
82 if (!smbcli_socket_connect(cli, host)) {
83 printf("Failed to connect with %s\n", host);
87 if (!smbcli_transport_establish(cli, &calling, &called)) {
88 printf("%s rejected the session\n",host);
99 BOOL torture_open_connection_share(TALLOC_CTX *mem_ctx,
100 struct smbcli_state **c,
101 const char *hostname,
102 const char *sharename,
103 struct event_context *ev)
107 status = smbcli_full_connection(mem_ctx, c, hostname,
109 cmdline_credentials, ev);
110 if (!NT_STATUS_IS_OK(status)) {
111 printf("Failed to open connection - %s\n", nt_errstr(status));
115 (*c)->transport->options.use_oplocks = use_oplocks;
116 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
121 BOOL torture_open_connection(struct smbcli_state **c)
123 const char *host = lp_parm_string(-1, "torture", "host");
124 const char *share = lp_parm_string(-1, "torture", "share");
126 return torture_open_connection_share(NULL, c, host, share, NULL);
131 BOOL torture_close_connection(struct smbcli_state *c)
135 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
136 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
143 /* open a rpc connection to the chosen binding string */
144 NTSTATUS torture_rpc_connection(TALLOC_CTX *parent_ctx,
145 struct dcerpc_pipe **p,
146 const struct dcerpc_interface_table *table)
149 const char *binding = lp_parm_string(-1, "torture", "binding");
152 printf("You must specify a ncacn binding string\n");
153 return NT_STATUS_INVALID_PARAMETER;
156 status = dcerpc_pipe_connect(parent_ctx,
158 cmdline_credentials, NULL);
163 /* open a rpc connection to a specific transport */
164 NTSTATUS torture_rpc_connection_transport(TALLOC_CTX *parent_ctx,
165 struct dcerpc_pipe **p,
166 const struct dcerpc_interface_table *table,
167 enum dcerpc_transport_t transport)
170 const char *binding = lp_parm_string(-1, "torture", "binding");
171 struct dcerpc_binding *b;
172 TALLOC_CTX *mem_ctx = talloc_named(parent_ctx, 0, "torture_rpc_connection_smb");
175 printf("You must specify a ncacn binding string\n");
176 talloc_free(mem_ctx);
177 return NT_STATUS_INVALID_PARAMETER;
180 status = dcerpc_parse_binding(mem_ctx, binding, &b);
181 if (!NT_STATUS_IS_OK(status)) {
182 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
183 talloc_free(mem_ctx);
187 b->transport = transport;
189 status = dcerpc_pipe_connect_b(mem_ctx, p, b, table,
190 cmdline_credentials, NULL);
192 if (NT_STATUS_IS_OK(status)) {
193 *p = talloc_reference(parent_ctx, *p);
197 talloc_free(mem_ctx);
201 /* check if the server produced the expected error code */
202 BOOL check_error(const char *location, struct smbcli_state *c,
203 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
207 status = smbcli_nt_error(c->tree);
208 if (NT_STATUS_IS_DOS(status)) {
210 class = NT_STATUS_DOS_CLASS(status);
211 num = NT_STATUS_DOS_CODE(status);
212 if (eclass != class || ecode != num) {
213 printf("unexpected error code %s\n", nt_errstr(status));
214 printf(" expected %s or %s (at %s)\n",
215 nt_errstr(NT_STATUS_DOS(eclass, ecode)),
216 nt_errstr(nterr), location);
220 if (!NT_STATUS_EQUAL(nterr, status)) {
221 printf("unexpected error code %s\n", nt_errstr(status));
222 printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
231 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
233 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
234 if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
240 static BOOL rw_torture(struct smbcli_state *c)
242 const char *lockfname = "\\torture.lck";
246 pid_t pid2, pid = getpid();
251 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
254 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
256 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
261 for (i=0;i<torture_numops;i++) {
262 uint_t n = (uint_t)random()%10;
264 printf("%d\r", i); fflush(stdout);
266 asprintf(&fname, "\\torture.%u", n);
268 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
272 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
274 printf("open failed (%s)\n", smbcli_errstr(c->tree));
279 if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
280 printf("write failed (%s)\n", smbcli_errstr(c->tree));
285 if (smbcli_write(c->tree, fnum, 0, buf,
286 sizeof(pid)+(j*sizeof(buf)),
287 sizeof(buf)) != sizeof(buf)) {
288 printf("write failed (%s)\n", smbcli_errstr(c->tree));
295 if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
296 printf("read failed (%s)\n", smbcli_errstr(c->tree));
301 printf("data corruption!\n");
305 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
306 printf("close failed (%s)\n", smbcli_errstr(c->tree));
310 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
311 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
315 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
316 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
322 smbcli_close(c->tree, fnum2);
323 smbcli_unlink(c->tree, lockfname);
330 static BOOL run_torture(struct smbcli_state *cli, int dummy)
334 ret = rw_torture(cli);
336 if (!torture_close_connection(cli)) {
344 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
346 const char *lockfname = "\\torture2.lck";
351 uint8_t buf_rd[131072];
353 ssize_t bytes_read, bytes_written;
355 if (smbcli_deltree(c1->tree, lockfname) == -1) {
356 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
359 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
362 printf("first open read/write of %s failed (%s)\n",
363 lockfname, smbcli_errstr(c1->tree));
366 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
369 printf("second open read-only of %s failed (%s)\n",
370 lockfname, smbcli_errstr(c2->tree));
371 smbcli_close(c1->tree, fnum1);
375 printf("Checking data integrity over %d ops\n", torture_numops);
377 for (i=0;i<torture_numops;i++)
379 size_t buf_size = ((uint_t)random()%(sizeof(buf)-1))+ 1;
381 printf("%d\r", i); fflush(stdout);
384 generate_random_buffer(buf, buf_size);
386 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
387 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
388 printf("wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
393 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
394 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
395 printf("read %d, expected %d\n", (int)bytes_read, (int)buf_size);
400 if (memcmp(buf_rd, buf, buf_size) != 0)
402 printf("read/write compare failed\n");
408 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
409 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
412 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
413 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
417 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
418 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
425 #define BOOLSTR(b) ((b) ? "Yes" : "No")
427 static BOOL run_readwritetest(void)
429 struct smbcli_state *cli1, *cli2;
430 BOOL test1, test2 = True;
432 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
436 printf("starting readwritetest\n");
438 test1 = rw_torture2(cli1, cli2);
439 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
442 test2 = rw_torture2(cli1, cli1);
443 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
446 if (!torture_close_connection(cli1)) {
450 if (!torture_close_connection(cli2)) {
454 return (test1 && test2);
458 this checks to see if a secondary tconx can use open files from an
461 static BOOL run_tcon_test(void)
463 struct smbcli_state *cli;
464 const char *fname = "\\tcontest.tmp";
466 uint16_t cnum1, cnum2, cnum3;
467 uint16_t vuid1, vuid2;
470 struct smbcli_tree *tree1;
471 const char *host = lp_parm_string(-1, "torture", "host");
472 const char *share = lp_parm_string(-1, "torture", "share");
473 const char *password = lp_parm_string(-1, "torture", "password");
475 if (!torture_open_connection(&cli)) {
479 printf("starting tcontest\n");
481 if (smbcli_deltree(cli->tree, fname) == -1) {
482 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
485 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
487 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
491 cnum1 = cli->tree->tid;
492 vuid1 = cli->session->vuid;
494 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
495 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
496 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
500 tree1 = cli->tree; /* save old tree connection */
501 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
502 printf("%s refused 2nd tree connect (%s)\n", host,
503 smbcli_errstr(cli->tree));
508 cnum2 = cli->tree->tid;
509 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
510 vuid2 = cli->session->vuid + 1;
512 /* try a write with the wrong tid */
513 cli->tree->tid = cnum2;
515 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
516 printf("* server allows write with wrong TID\n");
519 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
523 /* try a write with an invalid tid */
524 cli->tree->tid = cnum3;
526 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
527 printf("* server allows write with invalid TID\n");
530 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
533 /* try a write with an invalid vuid */
534 cli->session->vuid = vuid2;
535 cli->tree->tid = cnum1;
537 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
538 printf("* server allows write with invalid VUID\n");
541 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
544 cli->session->vuid = vuid1;
545 cli->tree->tid = cnum1;
547 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
548 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
552 cli->tree->tid = cnum2;
554 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
555 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
559 cli->tree = tree1; /* restore initial tree */
560 cli->tree->tid = cnum1;
562 smbcli_unlink(tree1, fname);
564 if (!torture_close_connection(cli)) {
573 static BOOL tcon_devtest(struct smbcli_state *cli,
574 const char *myshare, const char *devtype,
575 NTSTATUS expected_error)
579 const char *password = lp_parm_string(-1, "torture", "password");
581 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
584 printf("Trying share %s with devtype %s\n", myshare, devtype);
586 if (NT_STATUS_IS_OK(expected_error)) {
590 printf("tconX to share %s with type %s "
591 "should have succeeded but failed\n",
598 printf("tconx to share %s with type %s "
599 "should have failed but succeeded\n",
603 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
607 printf("Returned unexpected error\n");
616 checks for correct tconX support
618 static BOOL run_tcon_devtype_test(void)
620 struct smbcli_state *cli1 = NULL;
623 const char *host = lp_parm_string(-1, "torture", "host");
624 const char *share = lp_parm_string(-1, "torture", "share");
626 status = smbcli_full_connection(NULL,
629 cmdline_credentials, NULL);
631 if (!NT_STATUS_IS_OK(status)) {
632 printf("could not open connection\n");
636 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
639 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
642 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
645 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
648 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
651 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
654 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
657 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
660 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
663 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
669 printf("Passed tcondevtest\n");
676 test whether fnums and tids open on one VC are available on another (a major
679 static BOOL run_fdpasstest(void)
681 struct smbcli_state *cli1, *cli2;
682 const char *fname = "\\fdpass.tst";
686 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
690 printf("starting fdpasstest\n");
692 smbcli_unlink(cli1->tree, fname);
694 printf("Opening a file on connection 1\n");
696 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
698 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
702 printf("writing to file on connection 1\n");
704 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
705 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
709 oldtid = cli2->tree->tid;
710 cli2->session->vuid = cli1->session->vuid;
711 cli2->tree->tid = cli1->tree->tid;
712 cli2->session->pid = cli1->session->pid;
714 printf("reading from file on connection 2\n");
716 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
717 printf("read succeeded! nasty security hole [%s]\n",
722 smbcli_close(cli1->tree, fnum1);
723 smbcli_unlink(cli1->tree, fname);
725 cli2->tree->tid = oldtid;
727 torture_close_connection(cli1);
728 torture_close_connection(cli2);
730 printf("finished fdpasstest\n");
736 test the timing of deferred open requests
738 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
740 const char *fname = "\\defer_open_test.dat";
746 printf("failed to connect\n");
750 printf("Testing deferred open requests.\n");
757 tv = timeval_current();
758 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
760 FILE_ATTRIBUTE_NORMAL,
761 NTCREATEX_SHARE_ACCESS_NONE,
762 NTCREATEX_DISP_OPEN_IF, 0, 0);
766 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
767 double e = timeval_elapsed(&tv);
768 if (e < 0.5 || e > 1.5) {
769 fprintf(stderr,"Timing incorrect %.2f violation\n",
773 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
776 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
780 printf("pid %u open %d\n", getpid(), i);
784 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
785 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
791 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
792 /* All until the last unlink will fail with sharing violation. */
793 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
794 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
799 printf("deferred test finished\n");
800 if (!torture_close_connection(cli)) {
807 test how many open files this server supports on the one socket
809 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
811 #define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
813 int fnums[0x11000], i;
814 int retries=4, maxfid;
818 printf("failed to connect\n");
822 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
823 printf("Failed to deltree \\maxfid - %s\n",
824 smbcli_errstr(cli->tree));
827 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
828 printf("Failed to mkdir \\maxfid, error=%s\n",
829 smbcli_errstr(cli->tree));
833 printf("Testing maximum number of open files\n");
835 for (i=0; i<0x11000; i++) {
837 asprintf(&fname, "\\maxfid\\fid%d", i/1000);
838 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
839 printf("Failed to mkdir %s, error=%s\n",
840 fname, smbcli_errstr(cli->tree));
845 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
846 if ((fnums[i] = smbcli_open(cli->tree, fname,
847 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
849 printf("open of %s failed (%s)\n",
850 fname, smbcli_errstr(cli->tree));
851 printf("maximum fnum is %d\n", i);
862 printf("cleaning up\n");
863 for (i=0;i<maxfid/2;i++) {
864 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
865 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
866 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
868 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
869 printf("unlink of %s failed (%s)\n",
870 fname, smbcli_errstr(cli->tree));
875 asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
876 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
877 printf("Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
879 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
880 printf("unlink of %s failed (%s)\n",
881 fname, smbcli_errstr(cli->tree));
886 printf("%6d %6d\r", i, maxfid-i);
890 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
891 printf("Failed to deltree \\maxfid - %s\n",
892 smbcli_errstr(cli->tree));
896 printf("maxfid test finished\n");
897 if (!torture_close_connection(cli)) {
901 #undef MAXFID_TEMPLATE
904 /* send smb negprot commands, not reading the response */
905 static BOOL run_negprot_nowait(void)
908 struct smbcli_state *cli, *cli2;
911 printf("starting negprot nowait test\n");
913 cli = open_nbt_connection();
918 printf("Filling send buffer\n");
920 for (i=0;i<100;i++) {
921 struct smbcli_request *req;
922 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
923 event_loop_once(cli->transport->socket->event.ctx);
924 if (req->state == SMBCLI_REQUEST_ERROR) {
926 printf("Failed to fill pipe packet[%d] - %s (ignored)\n", i+1, nt_errstr(req->status));
929 printf("Failed to fill pipe - %s \n", nt_errstr(req->status));
930 torture_close_connection(cli);
936 printf("Opening secondary connection\n");
937 if (!torture_open_connection(&cli2)) {
938 printf("Failed to open secondary connection\n");
942 if (!torture_close_connection(cli2)) {
943 printf("Failed to close secondary connection\n");
947 torture_close_connection(cli);
949 printf("finished negprot nowait test\n");
956 This checks how the getatr calls works
958 static BOOL run_attrtest(void)
960 struct smbcli_state *cli;
963 const char *fname = "\\attrib123456789.tst";
966 printf("starting attrib test\n");
968 if (!torture_open_connection(&cli)) {
972 smbcli_unlink(cli->tree, fname);
973 fnum = smbcli_open(cli->tree, fname,
974 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
975 smbcli_close(cli->tree, fnum);
977 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
978 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
982 printf("New file time is %s", ctime(&t));
984 if (abs(t - time(NULL)) > 60*60*24*10) {
985 printf("ERROR: SMBgetatr bug. time is %s",
991 t2 = t-60*60*24; /* 1 day ago */
993 printf("Setting file time to %s", ctime(&t2));
995 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
996 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
1000 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
1001 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
1005 printf("Retrieved file time as %s", ctime(&t));
1008 printf("ERROR: getatr/setatr bug. times are\n%s",
1010 printf("%s", ctime(&t2));
1014 smbcli_unlink(cli->tree, fname);
1016 if (!torture_close_connection(cli)) {
1020 printf("attrib test finished\n");
1027 This checks a couple of trans2 calls
1029 static BOOL run_trans2test(void)
1031 struct smbcli_state *cli;
1034 time_t c_time, a_time, m_time, w_time, m_time2;
1035 const char *fname = "\\trans2.tst";
1036 const char *dname = "\\trans2";
1037 const char *fname2 = "\\trans2\\trans2.tst";
1039 BOOL correct = True;
1041 printf("starting trans2 test\n");
1043 if (!torture_open_connection(&cli)) {
1047 smbcli_unlink(cli->tree, fname);
1049 printf("Testing qfileinfo\n");
1051 fnum = smbcli_open(cli->tree, fname,
1052 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1053 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
1055 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
1059 printf("Testing NAME_INFO\n");
1061 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
1062 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
1066 if (!pname || strcmp(pname, fname)) {
1067 printf("qfilename gave different name? [%s] [%s]\n",
1072 smbcli_close(cli->tree, fnum);
1073 smbcli_unlink(cli->tree, fname);
1075 fnum = smbcli_open(cli->tree, fname,
1076 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1078 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1081 smbcli_close(cli->tree, fnum);
1083 printf("Checking for sticky create times\n");
1085 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1086 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
1089 if (c_time != m_time) {
1090 printf("create time=%s", ctime(&c_time));
1091 printf("modify time=%s", ctime(&m_time));
1092 printf("This system appears to have sticky create times\n");
1094 if (a_time % (60*60) == 0) {
1095 printf("access time=%s", ctime(&a_time));
1096 printf("This system appears to set a midnight access time\n");
1100 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1101 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1107 smbcli_unlink(cli->tree, fname);
1108 fnum = smbcli_open(cli->tree, fname,
1109 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1110 smbcli_close(cli->tree, fnum);
1111 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1112 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1115 if (w_time < 60*60*24*2) {
1116 printf("write time=%s", ctime(&w_time));
1117 printf("This system appears to set a initial 0 write time\n");
1122 smbcli_unlink(cli->tree, fname);
1125 /* check if the server updates the directory modification time
1126 when creating a new file */
1127 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1128 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
1132 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1133 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1137 fnum = smbcli_open(cli->tree, fname2,
1138 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1139 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
1140 smbcli_close(cli->tree, fnum);
1141 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
1142 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1145 if (m_time2 == m_time) {
1146 printf("This system does not update directory modification times\n");
1150 smbcli_unlink(cli->tree, fname2);
1151 smbcli_rmdir(cli->tree, dname);
1153 if (!torture_close_connection(cli)) {
1157 printf("trans2 test finished\n");
1164 /* FIRST_DESIRED_ACCESS 0xf019f */
1165 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1166 SEC_FILE_READ_EA| /* 0xf */ \
1167 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1168 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1169 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1170 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1171 /* SECOND_DESIRED_ACCESS 0xe0080 */
1172 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1173 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1174 SEC_STD_WRITE_OWNER /* 0xe0000 */
1177 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1178 READ_CONTROL|WRITE_DAC|\
1179 SEC_FILE_READ_DATA|\
1184 Test ntcreate calls made by xcopy
1186 static BOOL run_xcopy(void)
1188 struct smbcli_state *cli1;
1189 const char *fname = "\\test.txt";
1190 BOOL correct = True;
1193 printf("starting xcopy test\n");
1195 if (!torture_open_connection(&cli1)) {
1199 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1200 FIRST_DESIRED_ACCESS,
1201 FILE_ATTRIBUTE_ARCHIVE,
1202 NTCREATEX_SHARE_ACCESS_NONE,
1203 NTCREATEX_DISP_OVERWRITE_IF,
1207 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
1211 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1212 SECOND_DESIRED_ACCESS, 0,
1213 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1216 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
1220 if (!torture_close_connection(cli1)) {
1229 see how many RPC pipes we can open at once
1231 static BOOL run_pipe_number(void)
1233 struct smbcli_state *cli1;
1234 const char *pipe_name = "\\WKSSVC";
1238 printf("starting pipenumber test\n");
1239 if (!torture_open_connection(&cli1)) {
1244 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1245 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1248 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
1252 printf("%d\r", num_pipes);
1256 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
1257 torture_close_connection(cli1);
1265 open N connections to the server and just hold them open
1266 used for testing performance when there are N idle users
1269 static BOOL torture_holdcon(void)
1272 struct smbcli_state **cli;
1275 printf("Opening %d connections\n", torture_numops);
1277 cli = malloc_array_p(struct smbcli_state *, torture_numops);
1279 for (i=0;i<torture_numops;i++) {
1280 if (!torture_open_connection(&cli[i])) {
1283 printf("opened %d connections\r", i);
1287 printf("\nStarting pings\n");
1290 for (i=0;i<torture_numops;i++) {
1293 status = smbcli_chkpath(cli[i]->tree, "\\");
1294 if (!NT_STATUS_IS_OK(status)) {
1295 printf("Connection %d is dead\n", i);
1303 if (num_dead == torture_numops) {
1304 printf("All connections dead - finishing\n");
1316 Try with a wrong vuid and check error message.
1319 static BOOL run_vuidtest(void)
1321 struct smbcli_state *cli;
1322 const char *fname = "\\vuid.tst";
1325 time_t c_time, a_time, m_time;
1326 BOOL correct = True;
1331 printf("starting vuid test\n");
1333 if (!torture_open_connection(&cli)) {
1337 smbcli_unlink(cli->tree, fname);
1339 fnum = smbcli_open(cli->tree, fname,
1340 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1342 orig_vuid = cli->session->vuid;
1344 cli->session->vuid += 1234;
1346 printf("Testing qfileinfo with wrong vuid\n");
1348 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
1349 &size, &c_time, &a_time,
1350 &m_time, NULL, NULL))) {
1351 printf("ERROR: qfileinfo passed with wrong vuid\n");
1355 if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1356 NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
1357 !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1358 NT_STATUS_INVALID_HANDLE)) {
1359 printf("ERROR: qfileinfo should have returned DOS error "
1360 "ERRSRV:ERRbaduid\n but returned %s\n",
1361 smbcli_errstr(cli->tree));
1365 cli->session->vuid -= 1234;
1367 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1368 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
1372 smbcli_unlink(cli->tree, fname);
1374 if (!torture_close_connection(cli)) {
1378 printf("vuid test finished\n");
1384 Test open mode returns on read-only files.
1386 static BOOL run_opentest(void)
1388 static struct smbcli_state *cli1;
1389 static struct smbcli_state *cli2;
1390 const char *fname = "\\readonly.file";
1391 char *control_char_fname;
1395 BOOL correct = True;
1400 printf("starting open test\n");
1402 if (!torture_open_connection(&cli1)) {
1406 asprintf(&control_char_fname, "\\readonly.afile");
1407 for (i = 1; i <= 0x1f; i++) {
1408 control_char_fname[10] = i;
1409 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
1410 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1412 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
1413 NT_STATUS_OBJECT_NAME_INVALID)) {
1414 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
1415 smbcli_errstr(cli1->tree), i);
1420 smbcli_close(cli1->tree, fnum1);
1422 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
1423 smbcli_unlink(cli1->tree, control_char_fname);
1425 free(control_char_fname);
1428 printf("Create file with control char names passed.\n");
1430 smbcli_setatr(cli1->tree, fname, 0, 0);
1431 smbcli_unlink(cli1->tree, fname);
1433 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1435 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1439 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1440 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1444 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
1445 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
1446 CHECK_MAX_FAILURES(error_test1);
1450 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1452 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1453 CHECK_MAX_FAILURES(error_test1);
1457 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
1458 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1460 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
1461 NT_STATUS_ACCESS_DENIED)) {
1462 printf("correct error code ERRDOS/ERRnoaccess returned\n");
1465 printf("finished open test 1\n");
1467 smbcli_close(cli1->tree, fnum1);
1469 /* Now try not readonly and ensure ERRbadshare is returned. */
1471 smbcli_setatr(cli1->tree, fname, 0, 0);
1473 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1475 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1479 /* This will fail - but the error should be ERRshare. */
1480 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1482 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
1483 NT_STATUS_SHARING_VIOLATION)) {
1484 printf("correct error code ERRDOS/ERRbadshare returned\n");
1487 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1488 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1492 smbcli_unlink(cli1->tree, fname);
1494 printf("finished open test 2\n");
1496 /* Test truncate open disposition on file opened for read. */
1498 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1500 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1504 /* write 20 bytes. */
1506 memset(buf, '\0', 20);
1508 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1509 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1513 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1514 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1518 /* Ensure size == 20. */
1519 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1520 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1521 CHECK_MAX_FAILURES(error_test3);
1526 printf("(3) file size != 20\n");
1527 CHECK_MAX_FAILURES(error_test3);
1531 /* Now test if we can truncate a file opened for readonly. */
1533 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
1535 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1536 CHECK_MAX_FAILURES(error_test3);
1540 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1541 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1545 /* Ensure size == 0. */
1546 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1547 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1548 CHECK_MAX_FAILURES(error_test3);
1553 printf("(3) file size != 0\n");
1554 CHECK_MAX_FAILURES(error_test3);
1557 printf("finished open test 3\n");
1559 smbcli_unlink(cli1->tree, fname);
1562 printf("testing ctemp\n");
1563 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
1565 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1566 CHECK_MAX_FAILURES(error_test4);
1569 printf("ctemp gave path %s\n", tmp_path);
1570 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1571 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1573 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1574 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1577 /* Test the non-io opens... */
1579 if (!torture_open_connection(&cli2)) {
1583 smbcli_setatr(cli2->tree, fname, 0, 0);
1584 smbcli_unlink(cli2->tree, fname);
1586 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1588 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1589 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1592 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1593 CHECK_MAX_FAILURES(error_test10);
1597 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1598 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1600 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1601 CHECK_MAX_FAILURES(error_test10);
1605 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1606 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1609 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1610 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1614 printf("non-io open test #1 passed.\n");
1616 smbcli_unlink(cli1->tree, fname);
1618 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1620 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1621 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1624 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1625 CHECK_MAX_FAILURES(error_test20);
1629 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1630 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1633 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1634 CHECK_MAX_FAILURES(error_test20);
1638 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1639 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1642 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1643 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1647 printf("non-io open test #2 passed.\n");
1649 smbcli_unlink(cli1->tree, fname);
1651 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1653 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1654 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1657 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1658 CHECK_MAX_FAILURES(error_test30);
1662 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1663 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1666 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1667 CHECK_MAX_FAILURES(error_test30);
1671 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1672 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1675 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1676 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1680 printf("non-io open test #3 passed.\n");
1682 smbcli_unlink(cli1->tree, fname);
1684 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1686 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1687 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1690 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1691 CHECK_MAX_FAILURES(error_test40);
1695 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1696 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1699 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1700 CHECK_MAX_FAILURES(error_test40);
1704 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1706 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1707 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1711 printf("non-io open test #4 passed.\n");
1713 smbcli_unlink(cli1->tree, fname);
1715 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1717 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1718 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1721 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1722 CHECK_MAX_FAILURES(error_test50);
1726 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1727 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1730 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1731 CHECK_MAX_FAILURES(error_test50);
1735 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1736 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1740 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1741 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1745 printf("non-io open test #5 passed.\n");
1747 printf("TEST #6 testing 1 non-io open, one io open\n");
1749 smbcli_unlink(cli1->tree, fname);
1751 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1752 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1755 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1756 CHECK_MAX_FAILURES(error_test60);
1760 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1761 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1764 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1765 CHECK_MAX_FAILURES(error_test60);
1769 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1770 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1774 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1775 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1779 printf("non-io open test #6 passed.\n");
1781 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
1783 smbcli_unlink(cli1->tree, fname);
1785 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1786 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1789 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1790 CHECK_MAX_FAILURES(error_test70);
1794 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1795 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1798 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1799 CHECK_MAX_FAILURES(error_test70);
1803 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1805 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1806 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1810 printf("non-io open test #7 passed.\n");
1814 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1816 smbcli_unlink(cli1->tree, fname);
1818 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1820 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1824 /* write 20 bytes. */
1826 memset(buf, '\0', 20);
1828 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1829 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1833 /* Ensure size == 20. */
1834 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1835 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1836 CHECK_MAX_FAILURES(error_test80);
1841 printf("(8) file size != 20\n");
1842 CHECK_MAX_FAILURES(error_test80);
1846 /* Get an exclusive lock on the open file. */
1847 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1848 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1849 CHECK_MAX_FAILURES(error_test80);
1853 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1855 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1859 /* Ensure size == 0. */
1860 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1861 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1862 CHECK_MAX_FAILURES(error_test80);
1867 printf("(8) file size != 0\n");
1868 CHECK_MAX_FAILURES(error_test80);
1872 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1873 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1877 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1878 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1884 printf("open test #8 passed.\n");
1886 smbcli_unlink(cli1->tree, fname);
1888 if (!torture_close_connection(cli1)) {
1891 if (!torture_close_connection(cli2)) {
1900 sees what IOCTLs are supported
1902 BOOL torture_ioctl_test(void)
1904 struct smbcli_state *cli;
1905 uint16_t device, function;
1907 const char *fname = "\\ioctl.dat";
1909 union smb_ioctl parms;
1910 TALLOC_CTX *mem_ctx;
1912 if (!torture_open_connection(&cli)) {
1916 mem_ctx = talloc_init("ioctl_test");
1918 printf("starting ioctl test\n");
1920 smbcli_unlink(cli->tree, fname);
1922 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1924 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1928 parms.ioctl.level = RAW_IOCTL_IOCTL;
1929 parms.ioctl.in.file.fnum = fnum;
1930 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
1931 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1932 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
1934 for (device=0;device<0x100;device++) {
1935 printf("testing device=0x%x\n", device);
1936 for (function=0;function<0x100;function++) {
1937 parms.ioctl.in.request = (device << 16) | function;
1938 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1940 if (NT_STATUS_IS_OK(status)) {
1941 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
1942 device, function, (int)parms.ioctl.out.blob.length);
1947 if (!torture_close_connection(cli)) {
1956 tries variants of chkpath
1958 BOOL torture_chkpath_test(void)
1960 struct smbcli_state *cli;
1964 if (!torture_open_connection(&cli)) {
1968 printf("starting chkpath test\n");
1970 printf("Testing valid and invalid paths\n");
1972 /* cleanup from an old run */
1973 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1974 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1975 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1977 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1978 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1982 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1983 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1987 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1989 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
1992 smbcli_close(cli->tree, fnum);
1994 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1995 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1999 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
2000 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
2004 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
2005 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2006 NT_STATUS_NOT_A_DIRECTORY);
2008 printf("* chkpath on a file should fail\n");
2012 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
2013 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2014 NT_STATUS_OBJECT_NAME_NOT_FOUND);
2016 printf("* chkpath on a non existent file should fail\n");
2020 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
2021 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2022 NT_STATUS_OBJECT_PATH_NOT_FOUND);
2024 printf("* chkpath on a non existent component should fail\n");
2028 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
2029 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
2030 smbcli_rmdir(cli->tree, "\\chkpath.dir");
2032 if (!torture_close_connection(cli)) {
2040 static void sigcont(int sig)
2044 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
2047 volatile pid_t *child_status;
2048 volatile BOOL *child_status_out;
2051 double start_time_limit = 10 + (torture_nprocs * 1.5);
2052 char **unc_list = NULL;
2054 int num_unc_names = 0;
2061 signal(SIGCONT, sigcont);
2063 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
2064 if (!child_status) {
2065 printf("Failed to setup shared memory\n");
2069 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
2070 if (!child_status_out) {
2071 printf("Failed to setup result status shared memory\n");
2075 p = lp_parm_string(-1, "torture", "unclist");
2077 unc_list = file_lines_load(p, &num_unc_names, NULL);
2078 if (!unc_list || num_unc_names <= 0) {
2079 printf("Failed to load unc names list from '%s'\n", p);
2084 for (i = 0; i < torture_nprocs; i++) {
2085 child_status[i] = 0;
2086 child_status_out[i] = True;
2089 tv = timeval_current();
2091 for (i=0;i<torture_nprocs;i++) {
2095 const char *hostname=NULL, *sharename;
2097 pid_t mypid = getpid();
2098 srandom(((int)mypid) ^ ((int)time(NULL)));
2100 asprintf(&myname, "CLIENT%d", i);
2101 lp_set_cmdline("netbios name", myname);
2106 if (!smbcli_parse_unc(unc_list[i % num_unc_names],
2107 NULL, &hostname, &sharename)) {
2108 printf("Failed to parse UNC name %s\n",
2109 unc_list[i % num_unc_names]);
2116 if (torture_open_connection_share(NULL,
2123 } else if (torture_open_connection(¤t_cli)) {
2127 printf("pid %d failed to start\n", (int)getpid());
2133 child_status[i] = getpid();
2137 if (child_status[i]) {
2138 printf("Child %d failed to start!\n", i);
2139 child_status_out[i] = 1;
2143 child_status_out[i] = fn(current_cli, i);
2150 for (i=0;i<torture_nprocs;i++) {
2151 if (child_status[i]) synccount++;
2153 if (synccount == torture_nprocs) break;
2155 } while (timeval_elapsed(&tv) < start_time_limit);
2157 if (synccount != torture_nprocs) {
2158 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
2160 return timeval_elapsed(&tv);
2163 printf("Starting %d clients\n", torture_nprocs);
2165 /* start the client load */
2166 tv = timeval_current();
2167 for (i=0;i<torture_nprocs;i++) {
2168 child_status[i] = 0;
2171 printf("%d clients started\n", torture_nprocs);
2175 for (i=0;i<torture_nprocs;i++) {
2177 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
2178 if (ret == -1 || WEXITSTATUS(status) != 0) {
2185 for (i=0;i<torture_nprocs;i++) {
2186 if (!child_status_out[i]) {
2190 return timeval_elapsed(&tv);
2193 #define FLAG_MULTIPROC 1
2198 BOOL (*multi_fn)(struct smbcli_state *, int );
2199 } builtin_torture_ops[] = {
2201 {"BASE-FDPASS", run_fdpasstest, 0},
2202 {"BASE-LOCK1", torture_locktest1, 0},
2203 {"BASE-LOCK2", torture_locktest2, 0},
2204 {"BASE-LOCK3", torture_locktest3, 0},
2205 {"BASE-LOCK4", torture_locktest4, 0},
2206 {"BASE-LOCK5", torture_locktest5, 0},
2207 {"BASE-LOCK6", torture_locktest6, 0},
2208 {"BASE-LOCK7", torture_locktest7, 0},
2209 {"BASE-UNLINK", torture_unlinktest, 0},
2210 {"BASE-ATTR", run_attrtest, 0},
2211 {"BASE-TRANS2", run_trans2test, 0},
2212 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
2213 {"BASE-DIR1", torture_dirtest1, 0},
2214 {"BASE-DIR2", torture_dirtest2, 0},
2215 {"BASE-DENY1", torture_denytest1, 0},
2216 {"BASE-DENY2", torture_denytest2, 0},
2217 {"BASE-DENY3", torture_denytest3, 0},
2218 {"BASE-DENYDOS", torture_denydos_sharing, 0},
2219 {"BASE-NTDENY1", NULL, torture_ntdenytest1},
2220 {"BASE-NTDENY2", torture_ntdenytest2, 0},
2221 {"BASE-TCON", run_tcon_test, 0},
2222 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
2223 {"BASE-VUID", run_vuidtest, 0},
2224 {"BASE-RW1", run_readwritetest, 0},
2225 {"BASE-OPEN", run_opentest, 0},
2226 {"BASE-DEFER_OPEN", NULL, run_deferopen},
2227 {"BASE-XCOPY", run_xcopy, 0},
2228 {"BASE-RENAME", torture_test_rename, 0},
2229 {"BASE-DELETE", torture_test_delete, 0},
2230 {"BASE-PROPERTIES", torture_test_properties, 0},
2231 {"BASE-MANGLE", torture_mangle, 0},
2232 {"BASE-OPENATTR", torture_openattrtest, 0},
2233 {"BASE-CHARSET", torture_charset, 0},
2234 {"BASE-CHKPATH", torture_chkpath_test, 0},
2235 {"BASE-SECLEAK", torture_sec_leak, 0},
2236 {"BASE-DISCONNECT", torture_disconnect, 0},
2237 {"BASE-DELAYWRITE", torture_delay_write, 0},
2239 /* benchmarking tests */
2240 {"BENCH-HOLDCON", torture_holdcon, 0},
2241 {"BENCH-NBENCH", torture_nbench, 0},
2242 {"BENCH-TORTURE", NULL, run_torture},
2243 {"BENCH-NBT", torture_bench_nbt, 0},
2244 {"BENCH-WINS", torture_bench_wins, 0},
2245 {"BENCH-RPC", torture_bench_rpc, 0},
2246 {"BENCH-CLDAP", torture_bench_cldap, 0},
2249 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
2250 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
2251 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
2252 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
2253 {"RAW-SEARCH", torture_raw_search, 0},
2254 {"RAW-CLOSE", torture_raw_close, 0},
2255 {"RAW-OPEN", torture_raw_open, 0},
2256 {"RAW-MKDIR", torture_raw_mkdir, 0},
2257 {"RAW-OPLOCK", torture_raw_oplock, 0},
2258 {"RAW-NOTIFY", torture_raw_notify, 0},
2259 {"RAW-MUX", torture_raw_mux, 0},
2260 {"RAW-IOCTL", torture_raw_ioctl, 0},
2261 {"RAW-CHKPATH", torture_raw_chkpath, 0},
2262 {"RAW-UNLINK", torture_raw_unlink, 0},
2263 {"RAW-READ", torture_raw_read, 0},
2264 {"RAW-WRITE", torture_raw_write, 0},
2265 {"RAW-LOCK", torture_raw_lock, 0},
2266 {"RAW-CONTEXT", torture_raw_context, 0},
2267 {"RAW-RENAME", torture_raw_rename, 0},
2268 {"RAW-SEEK", torture_raw_seek, 0},
2269 {"RAW-EAS", torture_raw_eas, 0},
2270 {"RAW-EAMAX", torture_max_eas, 0},
2271 {"RAW-STREAMS", torture_raw_streams, 0},
2272 {"RAW-ACLS", torture_raw_acls, 0},
2273 {"RAW-RAP", torture_raw_rap, 0},
2274 {"RAW-COMPOSITE", torture_raw_composite, 0},
2277 {"SMB2-CONNECT", torture_smb2_connect, 0},
2278 {"SMB2-SCAN", torture_smb2_scan, 0},
2279 {"SMB2-SCANGETINFO", torture_smb2_getinfo_scan, 0},
2280 {"SMB2-SCANSETINFO", torture_smb2_setinfo_scan, 0},
2281 {"SMB2-SCANFIND", torture_smb2_find_scan, 0},
2282 {"SMB2-GETINFO", torture_smb2_getinfo, 0},
2283 {"SMB2-SETINFO", torture_smb2_setinfo, 0},
2284 {"SMB2-FIND", torture_smb2_find, 0},
2286 /* protocol scanners */
2287 {"SCAN-TRANS2", torture_trans2_scan, 0},
2288 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2289 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2290 {"SCAN-SMB", torture_smb_scan, 0},
2291 {"SCAN-MAXFID", NULL, run_maxfidtest},
2292 {"SCAN-UTABLE", torture_utable, 0},
2293 {"SCAN-CASETABLE", torture_casetable, 0},
2294 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2295 {"SCAN-IOCTL", torture_ioctl_test, 0},
2296 {"SCAN-RAP", torture_rap_scan, 0},
2299 {"RPC-LSA", torture_rpc_lsa, 0},
2300 {"RPC-LSALOOKUP", torture_rpc_lsa_lookup, 0},
2301 {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
2302 {"RPC-ECHO", torture_rpc_echo, 0},
2303 {"RPC-DFS", torture_rpc_dfs, 0},
2304 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2305 {"RPC-SAMR", torture_rpc_samr, 0},
2306 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2307 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2308 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2309 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2310 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2311 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2312 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2313 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2314 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2315 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2316 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2317 {"RPC-WINREG", torture_rpc_winreg, 0},
2318 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2319 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2320 {"RPC-REMACT", torture_rpc_remact, 0},
2321 {"RPC-MGMT", torture_rpc_mgmt, 0},
2322 {"RPC-SCANNER", torture_rpc_scanner, 0},
2323 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2324 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2325 {"RPC-MULTIBIND", torture_multi_bind, 0},
2326 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2327 {"RPC-CRACKNAMES", torture_rpc_drsuapi_cracknames, 0},
2328 {"RPC-ROT", torture_rpc_rot, 0},
2329 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2330 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2331 {"RPC-JOIN", torture_rpc_join, 0},
2332 {"RPC-DSSYNC", torture_rpc_dssync, 0},
2334 /* local (no server) testers */
2335 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2336 {"LOCAL-ICONV", torture_local_iconv, 0},
2337 {"LOCAL-TALLOC", torture_local_talloc, 0},
2338 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2339 {"LOCAL-IRPC", torture_local_irpc, 0},
2340 {"LOCAL-BINDING", torture_local_binding_string, 0},
2341 {"LOCAL-STRLIST", torture_local_util_strlist, 0},
2342 {"LOCAL-FILE", torture_local_util_file, 0},
2343 {"LOCAL-IDTREE", torture_local_idtree, 0},
2344 {"LOCAL-SOCKET", torture_local_socket, 0},
2345 {"LOCAL-PAC", torture_pac, 0},
2346 {"LOCAL-REGISTRY", torture_registry, 0},
2347 {"LOCAL-RESOLVE", torture_local_resolve, 0},
2348 {"LOCAL-SDDL", torture_local_sddl, 0},
2349 {"LOCAL-NDR", torture_local_ndr, 0},
2352 {"LDAP-BASIC", torture_ldap_basic, 0},
2353 {"LDAP-CLDAP", torture_cldap, 0},
2356 {"NBT-REGISTER", torture_nbt_register, 0},
2357 {"NBT-WINS", torture_nbt_wins, 0},
2358 {"NBT-DGRAM", torture_nbt_dgram, 0},
2359 {"NBT-BROWSE", torture_nbt_browse, 0},
2360 {"NBT-WINSREPLICATION-SIMPLE", torture_nbt_winsreplication_simple, 0},
2361 {"NBT-WINSREPLICATION-REPLICA", torture_nbt_winsreplication_replica, 0},
2362 {"NBT-WINSREPLICATION-OWNED", torture_nbt_winsreplication_owned, 0},
2365 {"NET-USERINFO", torture_userinfo, 0},
2366 {"NET-USERADD", torture_useradd, 0},
2367 {"NET-USERDEL", torture_userdel, 0},
2368 {"NET-USERMOD", torture_usermod, 0},
2369 {"NET-DOMOPEN", torture_domainopen, 0},
2370 {"NET-API-LOOKUP", torture_lookup, 0},
2371 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2372 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2373 {"NET-API-CREATEUSER", torture_createuser, 0},
2374 {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
2375 {"NET-API-LISTSHARES", torture_listshares, 0},
2376 {"NET-API-DELSHARE", torture_delshare, 0},
2380 static void register_builtin_ops(void)
2383 for (i = 0; builtin_torture_ops[i].name; i++) {
2384 register_torture_op(builtin_torture_ops[i].name,
2385 builtin_torture_ops[i].fn,
2386 builtin_torture_ops[i].multi_fn);
2391 static struct torture_op {
2394 BOOL (*multi_fn)(struct smbcli_state *, int );
2395 struct torture_op *prev, *next;
2396 }* torture_ops = NULL;;
2398 static struct torture_op *find_torture_op(const char *name)
2400 struct torture_op *o;
2401 for (o = torture_ops; o; o = o->next) {
2402 if (strcmp(name, o->name) == 0)
2409 NTSTATUS register_torture_op(const char *name, BOOL (*fn)(void), BOOL (*multi_fn)(struct smbcli_state *, int ))
2411 struct torture_op *op;
2413 /* Check for duplicates */
2414 if (find_torture_op(name) != NULL) {
2415 DEBUG(0,("There already is a torture op registered with the name %s!\n", name));
2416 return NT_STATUS_OBJECT_NAME_COLLISION;
2419 op = talloc(talloc_autofree_context(), struct torture_op);
2421 op->name = talloc_strdup(op, name);
2423 op->multi_fn = multi_fn;
2425 DLIST_ADD(torture_ops, op);
2427 return NT_STATUS_OK;
2430 /****************************************************************************
2431 run a specified test or "ALL"
2432 ****************************************************************************/
2433 static BOOL run_test(const char *name)
2436 struct torture_op *o;
2437 BOOL matched = False;
2439 if (strequal(name,"ALL")) {
2440 for (o = torture_ops; o; o = o->next) {
2441 if (!run_test(o->name)) {
2448 for (o = torture_ops; o; o = o->next) {
2449 if (gen_fnmatch(name, o->name) == 0) {
2453 printf("Running %s\n", o->name);
2455 BOOL result = False;
2456 t = torture_create_procs(o->multi_fn,
2460 printf("TEST %s FAILED!\n", o->name);
2464 struct timeval tv = timeval_current();
2467 printf("TEST %s FAILED!\n", o->name);
2469 t = timeval_elapsed(&tv);
2471 printf("%s took %g secs\n\n", o->name, t);
2476 printf("Unknown torture operation '%s'\n", name);
2483 static void parse_dns(const char *dns)
2485 char *userdn, *basedn, *secret;
2488 /* retrievieng the userdn */
2489 p = strchr_m(dns, '#');
2491 lp_set_cmdline("torture:ldap_userdn", "");
2492 lp_set_cmdline("torture:ldap_basedn", "");
2493 lp_set_cmdline("torture:ldap_secret", "");
2496 userdn = strndup(dns, p - dns);
2497 lp_set_cmdline("torture:ldap_userdn", userdn);
2499 /* retrieve the basedn */
2501 p = strchr_m(d, '#');
2503 lp_set_cmdline("torture:ldap_basedn", "");
2504 lp_set_cmdline("torture:ldap_secret", "");
2507 basedn = strndup(d, p - d);
2508 lp_set_cmdline("torture:ldap_basedn", basedn);
2510 /* retrieve the secret */
2513 lp_set_cmdline("torture:ldap_secret", "");
2517 lp_set_cmdline("torture:ldap_secret", secret);
2519 printf ("%s - %s - %s\n", userdn, basedn, secret);
2523 static void usage(poptContext pc)
2525 struct torture_op *o;
2528 poptPrintUsage(pc, stdout, 0);
2531 printf("The binding format is:\n\n");
2533 printf(" TRANSPORT:host[flags]\n\n");
2535 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2537 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2538 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2539 printf(" string.\n\n");
2541 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2542 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2543 printf(" will be auto-determined.\n\n");
2545 printf(" other recognised flags are:\n\n");
2547 printf(" sign : enable ntlmssp signing\n");
2548 printf(" seal : enable ntlmssp sealing\n");
2549 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2550 printf(" validate: enable the NDR validator\n");
2551 printf(" print: enable debugging of the packets\n");
2552 printf(" bigendian: use bigendian RPC\n");
2553 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2555 printf(" For example, these all connect to the samr pipe:\n\n");
2557 printf(" ncacn_np:myserver\n");
2558 printf(" ncacn_np:myserver[samr]\n");
2559 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2560 printf(" ncacn_np:myserver[/pipe/samr]\n");
2561 printf(" ncacn_np:myserver[samr,sign,print]\n");
2562 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2563 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2564 printf(" ncacn_np:\n");
2565 printf(" ncacn_np:[/pipe/samr]\n\n");
2567 printf(" ncacn_ip_tcp:myserver\n");
2568 printf(" ncacn_ip_tcp:myserver[1024]\n");
2569 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2571 printf("The unc format is:\n\n");
2573 printf(" //server/share\n\n");
2575 printf("tests are:\n");
2578 for (o = torture_ops; o; o = o->next) {
2579 if (i + strlen(o->name) >= MAX_COLS) {
2583 i+=printf("%s ", o->name);
2587 printf("default test is ALL\n");
2592 static BOOL is_binding_string(const char *binding_string)
2594 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2595 struct dcerpc_binding *binding_struct;
2598 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2600 talloc_free(mem_ctx);
2601 return NT_STATUS_IS_OK(status);
2604 static void max_runtime_handler(int sig)
2606 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2610 /****************************************************************************
2612 ****************************************************************************/
2613 int main(int argc,char *argv[])
2617 BOOL correct = True;
2622 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,
2623 OPT_DANGEROUS,OPT_SMB_PORTS};
2624 init_module_fn static_init[] = STATIC_smbtorture_MODULES;
2625 init_module_fn *shared_init = load_samba_modules(NULL, "torture");
2627 struct poptOption long_options[] = {
2629 {"smb-ports", 'p', POPT_ARG_STRING, NULL, OPT_SMB_PORTS, "SMB ports", NULL},
2630 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2631 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2632 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2633 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2634 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2635 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2636 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2637 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2638 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2639 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2640 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2641 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2642 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2643 "set maximum time for smbtorture to live", "seconds"},
2645 POPT_COMMON_CONNECTION
2646 POPT_COMMON_CREDENTIALS
2651 #ifdef HAVE_SETBUFFER
2652 setbuffer(stdout, NULL, 0);
2655 register_builtin_ops();
2657 run_init_functions(static_init);
2658 run_init_functions(shared_init);
2660 talloc_free(shared_init);
2662 /* we are never interested in SIGPIPE */
2663 BlockSignals(True,SIGPIPE);
2665 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2666 POPT_CONTEXT_KEEP_FIRST);
2668 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2670 while((opt = poptGetNextOpt(pc)) != -1) {
2673 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2676 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2679 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2682 parse_dns(poptGetOptArg(pc));
2685 lp_set_cmdline("torture:dangerous", "Yes");
2688 lp_set_cmdline("smb ports", poptGetOptArg(pc));
2691 d_printf("Invalid option %s: %s\n",
2692 poptBadOption(pc, 0), poptStrerror(opt));
2699 /* this will only work if nobody else uses alarm(),
2700 which means it won't work for some tests, but we
2701 can't use the event context method we use for smbd
2702 as so many tests create their own event
2703 context. This will at least catch most cases. */
2704 signal(SIGALRM, max_runtime_handler);
2712 dcerpc_table_init();
2714 if (torture_seed == 0) {
2715 torture_seed = time(NULL);
2717 printf("Using seed %d\n", torture_seed);
2718 srandom(torture_seed);
2720 argv_new = discard_const_p(char *, poptGetArgs(pc));
2723 for (i=0; i<argc; i++) {
2724 if (argv_new[i] == NULL) {
2735 for(p = argv_new[1]; *p; p++) {
2740 /* see if its a RPC transport specifier */
2741 if (is_binding_string(argv_new[1])) {
2742 lp_set_cmdline("torture:binding", argv_new[1]);
2744 char *binding = NULL;
2745 const char *host = NULL, *share = NULL;
2747 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
2748 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
2752 lp_set_cmdline("torture:host", host);
2753 lp_set_cmdline("torture:share", share);
2754 asprintf(&binding, "ncacn_np:%s", host);
2755 lp_set_cmdline("torture:binding", binding);
2758 if (argc_new == 0) {
2759 printf("You must specify a test to run, or 'ALL'\n");
2761 for (i=2;i<argc_new;i++) {
2762 if (!run_test(argv_new[i])) {