2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "dynconfig.h"
24 #include "lib/cmdline/popt_common.h"
25 #include "libcli/raw/libcliraw.h"
26 #include "system/time.h"
27 #include "system/wait.h"
28 #include "system/filesys.h"
30 #include "librpc/gen_ndr/ndr_security.h"
33 int torture_numops=100;
34 int torture_entries=1000;
35 int torture_failures=1;
37 static int procnum; /* records process count number when forking */
38 static struct smbcli_state *current_cli;
39 static BOOL use_oplocks;
40 static BOOL use_level_II_oplocks;
42 BOOL torture_showall = False;
44 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
46 static struct smbcli_state *open_nbt_connection(void)
48 struct nbt_name called, calling;
49 struct smbcli_state *cli;
50 const char *host = lp_parm_string(-1, "torture", "host");
52 make_nbt_name_client(&calling, lp_netbios_name());
54 nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
56 cli = smbcli_state_init(NULL);
58 printf("Failed initialize smbcli_struct to connect with %s\n", host);
62 if (!smbcli_socket_connect(cli, host)) {
63 printf("Failed to connect with %s\n", host);
67 if (!smbcli_transport_establish(cli, &calling, &called)) {
68 printf("%s rejected the session\n",host);
76 BOOL torture_open_connection_share(struct smbcli_state **c,
78 const char *sharename)
82 status = smbcli_full_connection(NULL,
86 if (!NT_STATUS_IS_OK(status)) {
87 printf("Failed to open connection - %s\n", nt_errstr(status));
91 (*c)->transport->options.use_oplocks = use_oplocks;
92 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
97 BOOL torture_open_connection(struct smbcli_state **c)
99 const char *host = lp_parm_string(-1, "torture", "host");
100 const char *share = lp_parm_string(-1, "torture", "share");
102 return torture_open_connection_share(c, host, share);
107 BOOL torture_close_connection(struct smbcli_state *c)
111 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
112 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
119 /* open a rpc connection to the chosen binding string */
120 NTSTATUS torture_rpc_connection(TALLOC_CTX *parent_ctx,
121 struct dcerpc_pipe **p,
122 const char *pipe_name,
123 const char *pipe_uuid,
124 uint32_t pipe_version)
127 const char *binding = lp_parm_string(-1, "torture", "binding");
130 printf("You must specify a ncacn binding string\n");
131 return NT_STATUS_INVALID_PARAMETER;
134 status = dcerpc_pipe_connect(parent_ctx,
135 p, binding, pipe_uuid, pipe_version,
136 cmdline_credentials);
141 /* open a rpc connection to a specific transport */
142 NTSTATUS torture_rpc_connection_transport(TALLOC_CTX *parent_ctx,
143 struct dcerpc_pipe **p,
144 const char *pipe_name,
145 const char *pipe_uuid,
146 uint32_t pipe_version,
147 enum dcerpc_transport_t transport)
150 const char *binding = lp_parm_string(-1, "torture", "binding");
151 struct dcerpc_binding *b;
152 TALLOC_CTX *mem_ctx = talloc_named(parent_ctx, 0, "torture_rpc_connection_smb");
155 printf("You must specify a ncacn binding string\n");
156 talloc_free(mem_ctx);
157 return NT_STATUS_INVALID_PARAMETER;
160 status = dcerpc_parse_binding(mem_ctx, binding, &b);
161 if (!NT_STATUS_IS_OK(status)) {
162 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
163 talloc_free(mem_ctx);
167 b->transport = transport;
169 status = dcerpc_pipe_connect_b(mem_ctx, p, b, pipe_uuid, pipe_version,
170 cmdline_credentials);
172 if (NT_STATUS_IS_OK(status)) {
173 *p = talloc_reference(parent_ctx, *p);
177 talloc_free(mem_ctx);
181 /* check if the server produced the expected error code */
182 BOOL check_error(const char *location, struct smbcli_state *c,
183 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
185 if (smbcli_is_dos_error(c->tree)) {
189 /* Check DOS error */
191 smbcli_dos_error(c, &class, &num);
193 if (eclass != class || ecode != num) {
194 printf("unexpected error code class=%d code=%d\n",
195 (int)class, (int)num);
196 printf(" expected %d/%d %s (at %s)\n",
197 (int)eclass, (int)ecode, nt_errstr(nterr), location);
206 status = smbcli_nt_error(c->tree);
208 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
209 printf("unexpected error code %s\n", nt_errstr(status));
210 printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
219 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
221 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
222 if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
228 static BOOL rw_torture(struct smbcli_state *c)
230 const char *lockfname = "\\torture.lck";
234 pid_t pid2, pid = getpid();
239 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
242 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
244 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
249 for (i=0;i<torture_numops;i++) {
250 uint_t n = (uint_t)random()%10;
252 printf("%d\r", i); fflush(stdout);
254 asprintf(&fname, "\\torture.%u", n);
256 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
260 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
262 printf("open failed (%s)\n", smbcli_errstr(c->tree));
267 if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
268 printf("write failed (%s)\n", smbcli_errstr(c->tree));
273 if (smbcli_write(c->tree, fnum, 0, buf,
274 sizeof(pid)+(j*sizeof(buf)),
275 sizeof(buf)) != sizeof(buf)) {
276 printf("write failed (%s)\n", smbcli_errstr(c->tree));
283 if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
284 printf("read failed (%s)\n", smbcli_errstr(c->tree));
289 printf("data corruption!\n");
293 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
294 printf("close failed (%s)\n", smbcli_errstr(c->tree));
298 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
299 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
303 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
304 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
310 smbcli_close(c->tree, fnum2);
311 smbcli_unlink(c->tree, lockfname);
318 static BOOL run_torture(struct smbcli_state *cli, int dummy)
322 ret = rw_torture(cli);
324 if (!torture_close_connection(cli)) {
332 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
334 const char *lockfname = "\\torture2.lck";
339 uint8_t buf_rd[131072];
341 ssize_t bytes_read, bytes_written;
343 if (smbcli_deltree(c1->tree, lockfname) == -1) {
344 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
347 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
350 printf("first open read/write of %s failed (%s)\n",
351 lockfname, smbcli_errstr(c1->tree));
354 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
357 printf("second open read-only of %s failed (%s)\n",
358 lockfname, smbcli_errstr(c2->tree));
359 smbcli_close(c1->tree, fnum1);
363 printf("Checking data integrity over %d ops\n", torture_numops);
365 for (i=0;i<torture_numops;i++)
367 size_t buf_size = ((uint_t)random()%(sizeof(buf)-1))+ 1;
369 printf("%d\r", i); fflush(stdout);
372 generate_random_buffer(buf, buf_size);
374 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
375 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
376 printf("wrote %d, expected %d\n", bytes_written, buf_size);
381 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
382 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
383 printf("read %d, expected %d\n", bytes_read, buf_size);
388 if (memcmp(buf_rd, buf, buf_size) != 0)
390 printf("read/write compare failed\n");
396 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
397 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
400 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
401 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
405 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
406 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
413 #define BOOLSTR(b) ((b) ? "Yes" : "No")
415 static BOOL run_readwritetest(void)
417 struct smbcli_state *cli1, *cli2;
418 BOOL test1, test2 = True;
420 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
424 printf("starting readwritetest\n");
426 test1 = rw_torture2(cli1, cli2);
427 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
430 test2 = rw_torture2(cli1, cli1);
431 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
434 if (!torture_close_connection(cli1)) {
438 if (!torture_close_connection(cli2)) {
442 return (test1 && test2);
446 this checks to see if a secondary tconx can use open files from an
449 static BOOL run_tcon_test(void)
451 struct smbcli_state *cli;
452 const char *fname = "\\tcontest.tmp";
454 uint16_t cnum1, cnum2, cnum3;
455 uint16_t vuid1, vuid2;
458 struct smbcli_tree *tree1;
459 const char *host = lp_parm_string(-1, "torture", "host");
460 const char *share = lp_parm_string(-1, "torture", "share");
461 const char *password = lp_parm_string(-1, "torture", "password");
463 if (!torture_open_connection(&cli)) {
467 printf("starting tcontest\n");
469 if (smbcli_deltree(cli->tree, fname) == -1) {
470 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
473 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
475 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
479 cnum1 = cli->tree->tid;
480 vuid1 = cli->session->vuid;
482 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
483 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
484 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
488 tree1 = cli->tree; /* save old tree connection */
489 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
490 printf("%s refused 2nd tree connect (%s)\n", host,
491 smbcli_errstr(cli->tree));
492 smbcli_shutdown(cli);
496 cnum2 = cli->tree->tid;
497 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
498 vuid2 = cli->session->vuid + 1;
500 /* try a write with the wrong tid */
501 cli->tree->tid = cnum2;
503 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
504 printf("* server allows write with wrong TID\n");
507 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
511 /* try a write with an invalid tid */
512 cli->tree->tid = cnum3;
514 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
515 printf("* server allows write with invalid TID\n");
518 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
521 /* try a write with an invalid vuid */
522 cli->session->vuid = vuid2;
523 cli->tree->tid = cnum1;
525 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
526 printf("* server allows write with invalid VUID\n");
529 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
532 cli->session->vuid = vuid1;
533 cli->tree->tid = cnum1;
535 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
536 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
540 cli->tree->tid = cnum2;
542 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
543 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
547 cli->tree = tree1; /* restore initial tree */
548 cli->tree->tid = cnum1;
550 if (!torture_close_connection(cli)) {
559 static BOOL tcon_devtest(struct smbcli_state *cli,
560 const char *myshare, const char *devtype,
561 NTSTATUS expected_error)
565 const char *password = lp_parm_string(-1, "torture", "password");
567 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
570 printf("Trying share %s with devtype %s\n", myshare, devtype);
572 if (NT_STATUS_IS_OK(expected_error)) {
576 printf("tconX to share %s with type %s "
577 "should have succeeded but failed\n",
584 printf("tconx to share %s with type %s "
585 "should have failed but succeeded\n",
589 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
593 printf("Returned unexpected error\n");
602 checks for correct tconX support
604 static BOOL run_tcon_devtype_test(void)
606 struct smbcli_state *cli1 = NULL;
609 const char *host = lp_parm_string(-1, "torture", "host");
610 const char *share = lp_parm_string(-1, "torture", "share");
612 status = smbcli_full_connection(NULL,
615 cmdline_credentials);
617 if (!NT_STATUS_IS_OK(status)) {
618 printf("could not open connection\n");
622 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
625 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
628 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
631 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
634 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
637 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
640 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
643 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
646 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
649 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
652 smbcli_shutdown(cli1);
655 printf("Passed tcondevtest\n");
662 test whether fnums and tids open on one VC are available on another (a major
665 static BOOL run_fdpasstest(void)
667 struct smbcli_state *cli1, *cli2;
668 const char *fname = "\\fdpass.tst";
672 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
676 printf("starting fdpasstest\n");
678 smbcli_unlink(cli1->tree, fname);
680 printf("Opening a file on connection 1\n");
682 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
684 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
688 printf("writing to file on connection 1\n");
690 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
691 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
695 oldtid = cli2->tree->tid;
696 cli2->session->vuid = cli1->session->vuid;
697 cli2->tree->tid = cli1->tree->tid;
698 cli2->session->pid = cli1->session->pid;
700 printf("reading from file on connection 2\n");
702 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
703 printf("read succeeded! nasty security hole [%s]\n",
708 smbcli_close(cli1->tree, fnum1);
709 smbcli_unlink(cli1->tree, fname);
711 cli2->tree->tid = oldtid;
713 torture_close_connection(cli1);
714 torture_close_connection(cli2);
716 printf("finished fdpasstest\n");
722 test the timing of deferred open requests
724 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
726 const char *fname = "\\defer_open_test.dat";
732 printf("failed to connect\n");
736 printf("Testing deferred open requests.\n");
743 tv = timeval_current();
744 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
746 FILE_ATTRIBUTE_NORMAL,
747 NTCREATEX_SHARE_ACCESS_NONE,
748 NTCREATEX_DISP_OPEN_IF, 0, 0);
752 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
753 double e = timeval_elapsed(&tv);
754 if (e < 0.5 || e > 1.5) {
755 fprintf(stderr,"Timing incorrect %.2f violation\n",
759 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
762 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
766 printf("pid %u open %d\n", getpid(), i);
770 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
771 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
777 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
778 /* All until the last unlink will fail with sharing violation. */
779 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
780 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
785 printf("deferred test finished\n");
786 if (!torture_close_connection(cli)) {
793 test how many open files this server supports on the one socket
795 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
797 #define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
799 int fnums[0x11000], i;
800 int retries=4, maxfid;
804 printf("failed to connect\n");
808 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
809 printf("Failed to deltree \\maxfid - %s\n",
810 smbcli_errstr(cli->tree));
813 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
814 printf("Failed to mkdir \\maxfid, error=%s\n",
815 smbcli_errstr(cli->tree));
819 printf("Testing maximum number of open files\n");
821 for (i=0; i<0x11000; i++) {
823 asprintf(&fname, "\\maxfid\\fid%d", i/1000);
824 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
825 printf("Failed to mkdir %s, error=%s\n",
826 fname, smbcli_errstr(cli->tree));
831 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
832 if ((fnums[i] = smbcli_open(cli->tree, fname,
833 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
835 printf("open of %s failed (%s)\n",
836 fname, smbcli_errstr(cli->tree));
837 printf("maximum fnum is %d\n", i);
848 printf("cleaning up\n");
849 for (i=0;i<maxfid/2;i++) {
850 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
851 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
852 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
854 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
855 printf("unlink of %s failed (%s)\n",
856 fname, smbcli_errstr(cli->tree));
861 asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
862 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
863 printf("Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
865 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
866 printf("unlink of %s failed (%s)\n",
867 fname, smbcli_errstr(cli->tree));
872 printf("%6d %6d\r", i, maxfid-i);
876 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
877 printf("Failed to deltree \\maxfid - %s\n",
878 smbcli_errstr(cli->tree));
882 printf("maxfid test finished\n");
883 if (!torture_close_connection(cli)) {
887 #undef MAXFID_TEMPLATE
890 /* send smb negprot commands, not reading the response */
891 static BOOL run_negprot_nowait(void)
894 struct smbcli_state *cli, *cli2;
897 printf("starting negprot nowait test\n");
899 cli = open_nbt_connection();
904 printf("Filling send buffer\n");
906 for (i=0;i<10000;i++) {
907 struct smbcli_request *req;
908 time_t t1 = time(NULL);
909 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
910 while (req->state == SMBCLI_REQUEST_SEND && time(NULL) < t1+5) {
911 smbcli_transport_process(cli->transport);
913 if (req->state == SMBCLI_REQUEST_ERROR) {
914 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
915 torture_close_connection(cli);
918 if (req->state == SMBCLI_REQUEST_SEND) {
924 printf("send buffer failed to fill\n");
925 if (!torture_close_connection(cli)) {
931 printf("send buffer filled after %d requests\n", i);
933 printf("Opening secondary connection\n");
934 if (!torture_open_connection(&cli2)) {
938 if (!torture_close_connection(cli)) {
942 if (!torture_close_connection(cli2)) {
946 printf("finished negprot nowait test\n");
953 This checks how the getatr calls works
955 static BOOL run_attrtest(void)
957 struct smbcli_state *cli;
960 const char *fname = "\\attrib123456789.tst";
963 printf("starting attrib test\n");
965 if (!torture_open_connection(&cli)) {
969 smbcli_unlink(cli->tree, fname);
970 fnum = smbcli_open(cli->tree, fname,
971 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
972 smbcli_close(cli->tree, fnum);
974 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
975 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
979 printf("New file time is %s", ctime(&t));
981 if (abs(t - time(NULL)) > 60*60*24*10) {
982 printf("ERROR: SMBgetatr bug. time is %s",
988 t2 = t-60*60*24; /* 1 day ago */
990 printf("Setting file time to %s", ctime(&t2));
992 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
993 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
997 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
998 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
1002 printf("Retrieved file time as %s", ctime(&t));
1005 printf("ERROR: getatr/setatr bug. times are\n%s",
1007 printf("%s", ctime(&t2));
1011 smbcli_unlink(cli->tree, fname);
1013 if (!torture_close_connection(cli)) {
1017 printf("attrib test finished\n");
1024 This checks a couple of trans2 calls
1026 static BOOL run_trans2test(void)
1028 struct smbcli_state *cli;
1031 time_t c_time, a_time, m_time, w_time, m_time2;
1032 const char *fname = "\\trans2.tst";
1033 const char *dname = "\\trans2";
1034 const char *fname2 = "\\trans2\\trans2.tst";
1036 BOOL correct = True;
1038 printf("starting trans2 test\n");
1040 if (!torture_open_connection(&cli)) {
1044 smbcli_unlink(cli->tree, fname);
1046 printf("Testing qfileinfo\n");
1048 fnum = smbcli_open(cli->tree, fname,
1049 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1050 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
1052 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
1056 printf("Testing NAME_INFO\n");
1058 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
1059 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
1063 if (!pname || strcmp(pname, fname)) {
1064 printf("qfilename gave different name? [%s] [%s]\n",
1069 smbcli_close(cli->tree, fnum);
1070 smbcli_unlink(cli->tree, fname);
1072 fnum = smbcli_open(cli->tree, fname,
1073 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1075 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1078 smbcli_close(cli->tree, fnum);
1080 printf("Checking for sticky create times\n");
1082 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1083 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
1086 if (c_time != m_time) {
1087 printf("create time=%s", ctime(&c_time));
1088 printf("modify time=%s", ctime(&m_time));
1089 printf("This system appears to have sticky create times\n");
1091 if (a_time % (60*60) == 0) {
1092 printf("access time=%s", ctime(&a_time));
1093 printf("This system appears to set a midnight access time\n");
1097 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1098 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1104 smbcli_unlink(cli->tree, fname);
1105 fnum = smbcli_open(cli->tree, fname,
1106 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1107 smbcli_close(cli->tree, fnum);
1108 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1109 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1112 if (w_time < 60*60*24*2) {
1113 printf("write time=%s", ctime(&w_time));
1114 printf("This system appears to set a initial 0 write time\n");
1119 smbcli_unlink(cli->tree, fname);
1122 /* check if the server updates the directory modification time
1123 when creating a new file */
1124 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1125 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
1129 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1130 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1134 fnum = smbcli_open(cli->tree, fname2,
1135 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1136 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
1137 smbcli_close(cli->tree, fnum);
1138 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
1139 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1142 if (m_time2 == m_time) {
1143 printf("This system does not update directory modification times\n");
1147 smbcli_unlink(cli->tree, fname2);
1148 smbcli_rmdir(cli->tree, dname);
1150 if (!torture_close_connection(cli)) {
1154 printf("trans2 test finished\n");
1161 /* FIRST_DESIRED_ACCESS 0xf019f */
1162 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1163 SEC_FILE_READ_EA| /* 0xf */ \
1164 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1165 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1166 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1167 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1168 /* SECOND_DESIRED_ACCESS 0xe0080 */
1169 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1170 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1171 SEC_STD_WRITE_OWNER /* 0xe0000 */
1174 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1175 READ_CONTROL|WRITE_DAC|\
1176 SEC_FILE_READ_DATA|\
1181 Test ntcreate calls made by xcopy
1183 static BOOL run_xcopy(void)
1185 struct smbcli_state *cli1;
1186 const char *fname = "\\test.txt";
1187 BOOL correct = True;
1190 printf("starting xcopy test\n");
1192 if (!torture_open_connection(&cli1)) {
1196 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1197 FIRST_DESIRED_ACCESS,
1198 FILE_ATTRIBUTE_ARCHIVE,
1199 NTCREATEX_SHARE_ACCESS_NONE,
1200 NTCREATEX_DISP_OVERWRITE_IF,
1204 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
1208 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1209 SECOND_DESIRED_ACCESS, 0,
1210 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1213 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
1217 if (!torture_close_connection(cli1)) {
1226 see how many RPC pipes we can open at once
1228 static BOOL run_pipe_number(void)
1230 struct smbcli_state *cli1;
1231 const char *pipe_name = "\\WKSSVC";
1235 printf("starting pipenumber test\n");
1236 if (!torture_open_connection(&cli1)) {
1241 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1242 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1245 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
1249 printf("%d\r", num_pipes);
1253 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
1254 torture_close_connection(cli1);
1262 open N connections to the server and just hold them open
1263 used for testing performance when there are N idle users
1266 static BOOL torture_holdcon(void)
1269 struct smbcli_state **cli;
1272 printf("Opening %d connections\n", torture_numops);
1274 cli = malloc_array_p(struct smbcli_state *, torture_numops);
1276 for (i=0;i<torture_numops;i++) {
1277 if (!torture_open_connection(&cli[i])) {
1280 printf("opened %d connections\r", i);
1284 printf("\nStarting pings\n");
1287 for (i=0;i<torture_numops;i++) {
1290 status = smbcli_chkpath(cli[i]->tree, "\\");
1291 if (!NT_STATUS_IS_OK(status)) {
1292 printf("Connection %d is dead\n", i);
1300 if (num_dead == torture_numops) {
1301 printf("All connections dead - finishing\n");
1313 Try with a wrong vuid and check error message.
1316 static BOOL run_vuidtest(void)
1318 struct smbcli_state *cli;
1319 const char *fname = "\\vuid.tst";
1322 time_t c_time, a_time, m_time;
1323 BOOL correct = True;
1328 printf("starting vuid test\n");
1330 if (!torture_open_connection(&cli)) {
1334 smbcli_unlink(cli->tree, fname);
1336 fnum = smbcli_open(cli->tree, fname,
1337 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1339 orig_vuid = cli->session->vuid;
1341 cli->session->vuid += 1234;
1343 printf("Testing qfileinfo with wrong vuid\n");
1345 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
1346 &size, &c_time, &a_time,
1347 &m_time, NULL, NULL))) {
1348 printf("ERROR: qfileinfo passed with wrong vuid\n");
1352 if ( (cli->transport->error.etype != ETYPE_DOS) ||
1353 (cli->transport->error.e.dos.eclass != ERRSRV) ||
1354 (cli->transport->error.e.dos.ecode != ERRbaduid) ) {
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, 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, ERRbadfile,
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);
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(¤t_cli,
2117 } else if (torture_open_connection(¤t_cli)) {
2121 printf("pid %d failed to start\n", (int)getpid());
2127 child_status[i] = getpid();
2131 if (child_status[i]) {
2132 printf("Child %d failed to start!\n", i);
2133 child_status_out[i] = 1;
2137 child_status_out[i] = fn(current_cli, i);
2144 for (i=0;i<torture_nprocs;i++) {
2145 if (child_status[i]) synccount++;
2147 if (synccount == torture_nprocs) break;
2149 } while (timeval_elapsed(&tv) < start_time_limit);
2151 if (synccount != torture_nprocs) {
2152 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
2154 return timeval_elapsed(&tv);
2157 printf("Starting %d clients\n", torture_nprocs);
2159 /* start the client load */
2160 tv = timeval_current();
2161 for (i=0;i<torture_nprocs;i++) {
2162 child_status[i] = 0;
2165 printf("%d clients started\n", torture_nprocs);
2169 for (i=0;i<torture_nprocs;i++) {
2171 while ((ret=sys_waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
2172 if (ret == -1 || WEXITSTATUS(status) != 0) {
2179 for (i=0;i<torture_nprocs;i++) {
2180 if (!child_status_out[i]) {
2184 return timeval_elapsed(&tv);
2187 #define FLAG_MULTIPROC 1
2192 BOOL (*multi_fn)(struct smbcli_state *, int );
2195 {"BASE-FDPASS", run_fdpasstest, 0},
2196 {"BASE-LOCK1", torture_locktest1, 0},
2197 {"BASE-LOCK2", torture_locktest2, 0},
2198 {"BASE-LOCK3", torture_locktest3, 0},
2199 {"BASE-LOCK4", torture_locktest4, 0},
2200 {"BASE-LOCK5", torture_locktest5, 0},
2201 {"BASE-LOCK6", torture_locktest6, 0},
2202 {"BASE-LOCK7", torture_locktest7, 0},
2203 {"BASE-UNLINK", torture_unlinktest, 0},
2204 {"BASE-ATTR", run_attrtest, 0},
2205 {"BASE-TRANS2", run_trans2test, 0},
2206 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
2207 {"BASE-DIR1", torture_dirtest1, 0},
2208 {"BASE-DIR2", torture_dirtest2, 0},
2209 {"BASE-DENY1", torture_denytest1, 0},
2210 {"BASE-DENY2", torture_denytest2, 0},
2211 {"BASE-DENY3", torture_denytest3, 0},
2212 {"BASE-DENYDOS", torture_denydos_sharing, 0},
2213 {"BASE-NTDENY1", NULL, torture_ntdenytest1},
2214 {"BASE-NTDENY2", torture_ntdenytest2, 0},
2215 {"BASE-TCON", run_tcon_test, 0},
2216 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
2217 {"BASE-VUID", run_vuidtest, 0},
2218 {"BASE-RW1", run_readwritetest, 0},
2219 {"BASE-OPEN", run_opentest, 0},
2220 {"BASE-DEFER_OPEN", NULL, run_deferopen},
2221 {"BASE-XCOPY", run_xcopy, 0},
2222 {"BASE-RENAME", torture_test_rename, 0},
2223 {"BASE-DELETE", torture_test_delete, 0},
2224 {"BASE-PROPERTIES", torture_test_properties, 0},
2225 {"BASE-MANGLE", torture_mangle, 0},
2226 {"BASE-OPENATTR", torture_openattrtest, 0},
2227 {"BASE-CHARSET", torture_charset, 0},
2228 {"BASE-CHKPATH", torture_chkpath_test, 0},
2229 {"BASE-SECLEAK", torture_sec_leak, 0},
2230 {"BASE-DISCONNECT", torture_disconnect, 0},
2231 {"BASE-DELAYWRITE", torture_delay_write, 0},
2233 /* benchmarking tests */
2234 {"BENCH-HOLDCON", torture_holdcon, 0},
2235 {"BENCH-NBENCH", torture_nbench, 0},
2236 {"BENCH-TORTURE", NULL, run_torture},
2237 {"BENCH-NBT", torture_bench_nbt, 0},
2238 {"BENCH-WINS", torture_bench_wins, 0},
2239 {"BENCH-RPC", torture_bench_rpc, 0},
2240 {"BENCH-CLDAP", torture_bench_cldap, 0},
2243 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
2244 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
2245 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
2246 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
2247 {"RAW-SEARCH", torture_raw_search, 0},
2248 {"RAW-CLOSE", torture_raw_close, 0},
2249 {"RAW-OPEN", torture_raw_open, 0},
2250 {"RAW-MKDIR", torture_raw_mkdir, 0},
2251 {"RAW-OPLOCK", torture_raw_oplock, 0},
2252 {"RAW-NOTIFY", torture_raw_notify, 0},
2253 {"RAW-MUX", torture_raw_mux, 0},
2254 {"RAW-IOCTL", torture_raw_ioctl, 0},
2255 {"RAW-CHKPATH", torture_raw_chkpath, 0},
2256 {"RAW-UNLINK", torture_raw_unlink, 0},
2257 {"RAW-READ", torture_raw_read, 0},
2258 {"RAW-WRITE", torture_raw_write, 0},
2259 {"RAW-LOCK", torture_raw_lock, 0},
2260 {"RAW-CONTEXT", torture_raw_context, 0},
2261 {"RAW-RENAME", torture_raw_rename, 0},
2262 {"RAW-SEEK", torture_raw_seek, 0},
2263 {"RAW-EAS", torture_raw_eas, 0},
2264 {"RAW-STREAMS", torture_raw_streams, 0},
2265 {"RAW-ACLS", torture_raw_acls, 0},
2266 {"RAW-RAP", torture_raw_rap, 0},
2267 {"RAW-COMPOSITE", torture_raw_composite, 0},
2269 /* protocol scanners */
2270 {"SCAN-TRANS2", torture_trans2_scan, 0},
2271 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2272 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2273 {"SCAN-SMB", torture_smb_scan, 0},
2274 {"SCAN-MAXFID", NULL, run_maxfidtest},
2275 {"SCAN-UTABLE", torture_utable, 0},
2276 {"SCAN-CASETABLE", torture_casetable, 0},
2277 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2278 {"SCAN-IOCTL", torture_ioctl_test, 0},
2279 {"SCAN-RAP", torture_rap_scan, 0},
2282 {"RPC-LSA", torture_rpc_lsa, 0},
2283 {"RPC-ECHO", torture_rpc_echo, 0},
2284 {"RPC-DFS", torture_rpc_dfs, 0},
2285 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2286 {"RPC-SAMR", torture_rpc_samr, 0},
2287 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2288 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2289 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2290 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2291 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2292 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2293 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2294 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2295 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2296 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2297 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2298 {"RPC-WINREG", torture_rpc_winreg, 0},
2299 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2300 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2301 {"RPC-REMACT", torture_rpc_remact, 0},
2302 {"RPC-MGMT", torture_rpc_mgmt, 0},
2303 {"RPC-SCANNER", torture_rpc_scanner, 0},
2304 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2305 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2306 {"RPC-MULTIBIND", torture_multi_bind, 0},
2307 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2308 {"RPC-LOGIN", torture_rpc_login, 0},
2309 {"RPC-ROT", torture_rpc_rot, 0},
2310 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2311 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2313 /* local (no server) testers */
2314 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2315 {"LOCAL-ICONV", torture_local_iconv, 0},
2316 {"LOCAL-TALLOC", torture_local_talloc, 0},
2317 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2318 {"LOCAL-IRPC", torture_local_irpc, 0},
2319 {"LOCAL-BINDING", torture_local_binding_string, 0},
2320 {"LOCAL-IDTREE", torture_local_idtree, 0},
2321 {"LOCAL-SOCKET", torture_local_socket, 0},
2323 /* COM (Component Object Model) testers */
2324 {"COM-SIMPLE", torture_com_simple, 0 },
2327 {"LDAP-BASIC", torture_ldap_basic, 0},
2328 {"LDAP-CLDAP", torture_cldap, 0},
2331 {"NBT-REGISTER", torture_nbt_register, 0},
2332 {"NBT-WINS", torture_nbt_wins, 0},
2333 {"NBT-WINSREPLICATION", torture_nbt_winsreplication, 0},
2334 {"NBT-DGRAM", torture_nbt_dgram, 0},
2337 {"NET-USERINFO", torture_userinfo, 0},
2338 {"NET-USERADD", torture_useradd, 0},
2339 {"NET-USERDEL", torture_userdel, 0},
2340 {"NET-DOMOPEN", torture_domainopen, 0},
2341 {"NET-API-CREATEUSER", torture_createuser, 0},
2347 /****************************************************************************
2348 run a specified test or "ALL"
2349 ****************************************************************************/
2350 static BOOL run_test(const char *name)
2354 BOOL matched = False;
2356 if (strequal(name,"ALL")) {
2357 for (i=0;torture_ops[i].name;i++) {
2358 if (!run_test(torture_ops[i].name)) {
2365 for (i=0;torture_ops[i].name;i++) {
2366 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
2370 printf("Running %s\n", torture_ops[i].name);
2371 if (torture_ops[i].multi_fn) {
2372 BOOL result = False;
2373 t = torture_create_procs(torture_ops[i].multi_fn,
2377 printf("TEST %s FAILED!\n", torture_ops[i].name);
2381 struct timeval tv = timeval_current();
2382 if (!torture_ops[i].fn()) {
2384 printf("TEST %s FAILED!\n", torture_ops[i].name);
2386 t = timeval_elapsed(&tv);
2388 printf("%s took %g secs\n\n", torture_ops[i].name, t);
2393 printf("Unknown torture operation '%s'\n", name);
2400 static void parse_dns(const char *dns)
2402 char *userdn, *basedn, *secret;
2405 /* retrievieng the userdn */
2406 p = strchr_m(dns, '#');
2408 lp_set_cmdline("torture:ldap_userdn", "");
2409 lp_set_cmdline("torture:ldap_basedn", "");
2410 lp_set_cmdline("torture:ldap_secret", "");
2413 userdn = strndup(dns, p - dns);
2414 lp_set_cmdline("torture:ldap_userdn", userdn);
2416 /* retrieve the basedn */
2418 p = strchr_m(d, '#');
2420 lp_set_cmdline("torture:ldap_basedn", "");
2421 lp_set_cmdline("torture:ldap_secret", "");
2424 basedn = strndup(d, p - d);
2425 lp_set_cmdline("torture:ldap_basedn", basedn);
2427 /* retrieve the secret */
2430 lp_set_cmdline("torture:ldap_secret", "");
2434 lp_set_cmdline("torture:ldap_secret", secret);
2436 printf ("%s - %s - %s\n", userdn, basedn, secret);
2440 static void usage(poptContext pc)
2445 poptPrintUsage(pc, stdout, 0);
2448 printf("The binding format is:\n\n");
2450 printf(" TRANSPORT:host[flags]\n\n");
2452 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2454 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2455 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2456 printf(" string.\n\n");
2458 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2459 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2460 printf(" will be auto-determined.\n\n");
2462 printf(" other recognised flags are:\n\n");
2464 printf(" sign : enable ntlmssp signing\n");
2465 printf(" seal : enable ntlmssp sealing\n");
2466 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2467 printf(" validate: enable the NDR validator\n");
2468 printf(" print: enable debugging of the packets\n");
2469 printf(" bigendian: use bigendian RPC\n");
2470 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2472 printf(" For example, these all connect to the samr pipe:\n\n");
2474 printf(" ncacn_np:myserver\n");
2475 printf(" ncacn_np:myserver[samr]\n");
2476 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2477 printf(" ncacn_np:myserver[/pipe/samr]\n");
2478 printf(" ncacn_np:myserver[samr,sign,print]\n");
2479 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2480 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2481 printf(" ncacn_np:\n");
2482 printf(" ncacn_np:[/pipe/samr]\n\n");
2484 printf(" ncacn_ip_tcp:myserver\n");
2485 printf(" ncacn_ip_tcp:myserver[1024]\n");
2486 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2488 printf("The unc format is:\n\n");
2490 printf(" //server/share\n\n");
2492 printf("tests are:");
2493 for (i=0;torture_ops[i].name;i++) {
2494 if ((i%perline)==0) {
2497 printf("%s ", torture_ops[i].name);
2501 printf("default test is ALL\n");
2506 static BOOL is_binding_string(const char *binding_string)
2508 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2509 struct dcerpc_binding *binding_struct;
2512 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2514 talloc_free(mem_ctx);
2515 return NT_STATUS_IS_OK(status);
2518 static void max_runtime_handler(int sig)
2520 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2524 /****************************************************************************
2526 ****************************************************************************/
2527 int main(int argc,char *argv[])
2531 BOOL correct = True;
2536 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,OPT_DANGEROUS};
2537 struct poptOption long_options[] = {
2539 {"smb-ports", 'p', POPT_ARG_STRING, NULL, 0, "SMB ports", NULL},
2540 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2541 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2542 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2543 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2544 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2545 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2546 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2547 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2548 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2549 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2550 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2551 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2552 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2553 "set maximum time for smbtorture to live", "seconds"},
2555 POPT_COMMON_CONNECTION
2556 POPT_COMMON_CREDENTIALS
2561 setup_logging("smbtorture", DEBUG_STDOUT);
2563 #ifdef HAVE_SETBUFFER
2564 setbuffer(stdout, NULL, 0);
2567 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2568 POPT_CONTEXT_KEEP_FIRST);
2570 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2572 while((opt = poptGetNextOpt(pc)) != -1) {
2575 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2578 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2581 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2584 parse_dns(poptGetOptArg(pc));
2587 lp_set_cmdline("torture:dangerous", "Yes");
2590 d_printf("Invalid option %s: %s\n",
2591 poptBadOption(pc, 0), poptStrerror(opt));
2598 /* this will only work if nobody else uses alarm(),
2599 which means it won't work for some tests, but we
2600 can't use the event context method we use for smbd
2601 as so many tests create their own event
2602 context. This will at least catch most cases. */
2603 signal(SIGALRM, max_runtime_handler);
2607 lp_load(dyn_CONFIGFILE,True,False,False);
2610 smbtorture_init_subsystems;
2613 if (torture_seed == 0) {
2614 torture_seed = time(NULL);
2616 printf("Using seed %d\n", torture_seed);
2617 srandom(torture_seed);
2619 argv_new = discard_const_p(char *, poptGetArgs(pc));
2622 for (i=0; i<argc; i++) {
2623 if (argv_new[i] == NULL) {
2634 for(p = argv_new[1]; *p; p++) {
2639 /* see if its a RPC transport specifier */
2640 if (is_binding_string(argv_new[1])) {
2641 lp_set_cmdline("torture:binding", argv_new[1]);
2643 char *binding = NULL;
2644 const char *host = NULL, *share = NULL;
2646 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
2647 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
2651 lp_set_cmdline("torture:host", host);
2652 lp_set_cmdline("torture:share", share);
2653 asprintf(&binding, "ncacn_np:%s", host);
2654 lp_set_cmdline("torture:binding", binding);
2657 if (argc_new == 0) {
2658 printf("You must specify a test to run, or 'ALL'\n");
2660 for (i=2;i<argc_new;i++) {
2661 if (!run_test(argv_new[i])) {