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.
23 #include "lib/cmdline/popt_common.h"
24 #include "libcli/raw/libcliraw.h"
25 #include "system/time.h"
26 #include "system/wait.h"
27 #include "system/filesys.h"
29 #include "librpc/gen_ndr/ndr_security.h"
30 #include "smb_build.h"
31 #include "libcli/nbt/libnbt.h"
34 int torture_numops=10;
35 int torture_entries=1000;
36 int torture_failures=1;
38 static int procnum; /* records process count number when forking */
39 static struct smbcli_state *current_cli;
40 static BOOL use_oplocks;
41 static BOOL use_level_II_oplocks;
43 BOOL torture_showall = False;
45 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
47 static struct smbcli_state *open_nbt_connection(void)
49 struct nbt_name called, calling;
50 struct smbcli_state *cli;
51 const char *host = lp_parm_string(-1, "torture", "host");
53 make_nbt_name_client(&calling, lp_netbios_name());
55 nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
57 cli = smbcli_state_init(NULL);
59 printf("Failed initialize smbcli_struct to connect with %s\n", host);
63 if (!smbcli_socket_connect(cli, host)) {
64 printf("Failed to connect with %s\n", host);
68 if (!smbcli_transport_establish(cli, &calling, &called)) {
69 printf("%s rejected the session\n",host);
80 BOOL torture_open_connection_share(TALLOC_CTX *mem_ctx,
81 struct smbcli_state **c,
83 const char *sharename,
84 struct event_context *ev)
88 status = smbcli_full_connection(mem_ctx, c, hostname,
90 cmdline_credentials, ev);
91 if (!NT_STATUS_IS_OK(status)) {
92 printf("Failed to open connection - %s\n", nt_errstr(status));
96 (*c)->transport->options.use_oplocks = use_oplocks;
97 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
102 BOOL torture_open_connection(struct smbcli_state **c)
104 const char *host = lp_parm_string(-1, "torture", "host");
105 const char *share = lp_parm_string(-1, "torture", "share");
107 return torture_open_connection_share(NULL, c, host, share, NULL);
112 BOOL torture_close_connection(struct smbcli_state *c)
116 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
117 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
124 /* open a rpc connection to the chosen binding string */
125 NTSTATUS torture_rpc_connection(TALLOC_CTX *parent_ctx,
126 struct dcerpc_pipe **p,
127 const struct dcerpc_interface_table *table)
130 const char *binding = lp_parm_string(-1, "torture", "binding");
133 printf("You must specify a ncacn binding string\n");
134 return NT_STATUS_INVALID_PARAMETER;
137 status = dcerpc_pipe_connect(parent_ctx,
139 cmdline_credentials, NULL);
144 /* open a rpc connection to a specific transport */
145 NTSTATUS torture_rpc_connection_transport(TALLOC_CTX *parent_ctx,
146 struct dcerpc_pipe **p,
147 const struct dcerpc_interface_table *table,
148 enum dcerpc_transport_t transport)
151 const char *binding = lp_parm_string(-1, "torture", "binding");
152 struct dcerpc_binding *b;
153 TALLOC_CTX *mem_ctx = talloc_named(parent_ctx, 0, "torture_rpc_connection_smb");
156 printf("You must specify a ncacn binding string\n");
157 talloc_free(mem_ctx);
158 return NT_STATUS_INVALID_PARAMETER;
161 status = dcerpc_parse_binding(mem_ctx, binding, &b);
162 if (!NT_STATUS_IS_OK(status)) {
163 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
164 talloc_free(mem_ctx);
168 b->transport = transport;
170 status = dcerpc_pipe_connect_b(mem_ctx, p, b, table,
171 cmdline_credentials, NULL);
173 if (NT_STATUS_IS_OK(status)) {
174 *p = talloc_reference(parent_ctx, *p);
178 talloc_free(mem_ctx);
182 /* check if the server produced the expected error code */
183 BOOL check_error(const char *location, struct smbcli_state *c,
184 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
188 status = smbcli_nt_error(c->tree);
189 if (NT_STATUS_IS_DOS(status)) {
191 class = NT_STATUS_DOS_CLASS(status);
192 num = NT_STATUS_DOS_CODE(status);
193 if (eclass != class || ecode != num) {
194 printf("unexpected error code %s\n", nt_errstr(status));
195 printf(" expected %s or %s (at %s)\n",
196 nt_errstr(NT_STATUS_DOS(eclass, ecode)),
197 nt_errstr(nterr), location);
201 if (!NT_STATUS_EQUAL(nterr, status)) {
202 printf("unexpected error code %s\n", nt_errstr(status));
203 printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
212 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
214 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
215 if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
221 static BOOL rw_torture(struct smbcli_state *c)
223 const char *lockfname = "\\torture.lck";
227 pid_t pid2, pid = getpid();
232 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
235 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
237 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
242 for (i=0;i<torture_numops;i++) {
243 uint_t n = (uint_t)random()%10;
245 printf("%d\r", i); fflush(stdout);
247 asprintf(&fname, "\\torture.%u", n);
249 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
253 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
255 printf("open failed (%s)\n", smbcli_errstr(c->tree));
260 if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
261 printf("write failed (%s)\n", smbcli_errstr(c->tree));
266 if (smbcli_write(c->tree, fnum, 0, buf,
267 sizeof(pid)+(j*sizeof(buf)),
268 sizeof(buf)) != sizeof(buf)) {
269 printf("write failed (%s)\n", smbcli_errstr(c->tree));
276 if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
277 printf("read failed (%s)\n", smbcli_errstr(c->tree));
282 printf("data corruption!\n");
286 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
287 printf("close failed (%s)\n", smbcli_errstr(c->tree));
291 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
292 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
296 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
297 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
303 smbcli_close(c->tree, fnum2);
304 smbcli_unlink(c->tree, lockfname);
311 static BOOL run_torture(struct smbcli_state *cli, int dummy)
315 ret = rw_torture(cli);
317 if (!torture_close_connection(cli)) {
325 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
327 const char *lockfname = "\\torture2.lck";
332 uint8_t buf_rd[131072];
334 ssize_t bytes_read, bytes_written;
336 if (smbcli_deltree(c1->tree, lockfname) == -1) {
337 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
340 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
343 printf("first open read/write of %s failed (%s)\n",
344 lockfname, smbcli_errstr(c1->tree));
347 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
350 printf("second open read-only of %s failed (%s)\n",
351 lockfname, smbcli_errstr(c2->tree));
352 smbcli_close(c1->tree, fnum1);
356 printf("Checking data integrity over %d ops\n", torture_numops);
358 for (i=0;i<torture_numops;i++)
360 size_t buf_size = ((uint_t)random()%(sizeof(buf)-1))+ 1;
362 printf("%d\r", i); fflush(stdout);
365 generate_random_buffer(buf, buf_size);
367 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
368 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
369 printf("wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
374 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
375 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
376 printf("read %d, expected %d\n", (int)bytes_read, (int)buf_size);
381 if (memcmp(buf_rd, buf, buf_size) != 0)
383 printf("read/write compare failed\n");
389 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
390 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
393 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
394 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
398 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
399 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
406 #define BOOLSTR(b) ((b) ? "Yes" : "No")
408 static BOOL run_readwritetest(void)
410 struct smbcli_state *cli1, *cli2;
411 BOOL test1, test2 = True;
413 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
417 printf("starting readwritetest\n");
419 test1 = rw_torture2(cli1, cli2);
420 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
423 test2 = rw_torture2(cli1, cli1);
424 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
427 if (!torture_close_connection(cli1)) {
431 if (!torture_close_connection(cli2)) {
435 return (test1 && test2);
439 this checks to see if a secondary tconx can use open files from an
442 static BOOL run_tcon_test(void)
444 struct smbcli_state *cli;
445 const char *fname = "\\tcontest.tmp";
447 uint16_t cnum1, cnum2, cnum3;
448 uint16_t vuid1, vuid2;
451 struct smbcli_tree *tree1;
452 const char *host = lp_parm_string(-1, "torture", "host");
453 const char *share = lp_parm_string(-1, "torture", "share");
454 const char *password = lp_parm_string(-1, "torture", "password");
456 if (!torture_open_connection(&cli)) {
460 printf("starting tcontest\n");
462 if (smbcli_deltree(cli->tree, fname) == -1) {
463 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
466 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
468 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
472 cnum1 = cli->tree->tid;
473 vuid1 = cli->session->vuid;
475 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
476 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
477 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
481 tree1 = cli->tree; /* save old tree connection */
482 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
483 printf("%s refused 2nd tree connect (%s)\n", host,
484 smbcli_errstr(cli->tree));
489 cnum2 = cli->tree->tid;
490 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
491 vuid2 = cli->session->vuid + 1;
493 /* try a write with the wrong tid */
494 cli->tree->tid = cnum2;
496 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
497 printf("* server allows write with wrong TID\n");
500 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
504 /* try a write with an invalid tid */
505 cli->tree->tid = cnum3;
507 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
508 printf("* server allows write with invalid TID\n");
511 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
514 /* try a write with an invalid vuid */
515 cli->session->vuid = vuid2;
516 cli->tree->tid = cnum1;
518 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
519 printf("* server allows write with invalid VUID\n");
522 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
525 cli->session->vuid = vuid1;
526 cli->tree->tid = cnum1;
528 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
529 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
533 cli->tree->tid = cnum2;
535 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
536 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
540 cli->tree = tree1; /* restore initial tree */
541 cli->tree->tid = cnum1;
543 smbcli_unlink(tree1, fname);
545 if (!torture_close_connection(cli)) {
554 static BOOL tcon_devtest(struct smbcli_state *cli,
555 const char *myshare, const char *devtype,
556 NTSTATUS expected_error)
560 const char *password = lp_parm_string(-1, "torture", "password");
562 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
565 printf("Trying share %s with devtype %s\n", myshare, devtype);
567 if (NT_STATUS_IS_OK(expected_error)) {
571 printf("tconX to share %s with type %s "
572 "should have succeeded but failed\n",
579 printf("tconx to share %s with type %s "
580 "should have failed but succeeded\n",
584 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
588 printf("Returned unexpected error\n");
597 checks for correct tconX support
599 static BOOL run_tcon_devtype_test(void)
601 struct smbcli_state *cli1 = NULL;
604 const char *host = lp_parm_string(-1, "torture", "host");
605 const char *share = lp_parm_string(-1, "torture", "share");
607 status = smbcli_full_connection(NULL,
610 cmdline_credentials, NULL);
612 if (!NT_STATUS_IS_OK(status)) {
613 printf("could not open connection\n");
617 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
620 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
623 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
626 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
629 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
632 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
635 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
638 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
641 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
644 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
650 printf("Passed tcondevtest\n");
657 test whether fnums and tids open on one VC are available on another (a major
660 static BOOL run_fdpasstest(void)
662 struct smbcli_state *cli1, *cli2;
663 const char *fname = "\\fdpass.tst";
667 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
671 printf("starting fdpasstest\n");
673 smbcli_unlink(cli1->tree, fname);
675 printf("Opening a file on connection 1\n");
677 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
679 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
683 printf("writing to file on connection 1\n");
685 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
686 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
690 oldtid = cli2->tree->tid;
691 cli2->session->vuid = cli1->session->vuid;
692 cli2->tree->tid = cli1->tree->tid;
693 cli2->session->pid = cli1->session->pid;
695 printf("reading from file on connection 2\n");
697 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
698 printf("read succeeded! nasty security hole [%s]\n",
703 smbcli_close(cli1->tree, fnum1);
704 smbcli_unlink(cli1->tree, fname);
706 cli2->tree->tid = oldtid;
708 torture_close_connection(cli1);
709 torture_close_connection(cli2);
711 printf("finished fdpasstest\n");
717 test the timing of deferred open requests
719 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
721 const char *fname = "\\defer_open_test.dat";
727 printf("failed to connect\n");
731 printf("Testing deferred open requests.\n");
738 tv = timeval_current();
739 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
741 FILE_ATTRIBUTE_NORMAL,
742 NTCREATEX_SHARE_ACCESS_NONE,
743 NTCREATEX_DISP_OPEN_IF, 0, 0);
747 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
748 double e = timeval_elapsed(&tv);
749 if (e < 0.5 || e > 1.5) {
750 fprintf(stderr,"Timing incorrect %.2f violation\n",
754 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
757 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
761 printf("pid %u open %d\n", getpid(), i);
765 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
766 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
772 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
773 /* All until the last unlink will fail with sharing violation. */
774 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
775 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
780 printf("deferred test finished\n");
781 if (!torture_close_connection(cli)) {
788 test how many open files this server supports on the one socket
790 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
792 #define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
794 int fnums[0x11000], i;
795 int retries=4, maxfid;
799 printf("failed to connect\n");
803 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
804 printf("Failed to deltree \\maxfid - %s\n",
805 smbcli_errstr(cli->tree));
808 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
809 printf("Failed to mkdir \\maxfid, error=%s\n",
810 smbcli_errstr(cli->tree));
814 printf("Testing maximum number of open files\n");
816 for (i=0; i<0x11000; i++) {
818 asprintf(&fname, "\\maxfid\\fid%d", i/1000);
819 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
820 printf("Failed to mkdir %s, error=%s\n",
821 fname, smbcli_errstr(cli->tree));
826 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
827 if ((fnums[i] = smbcli_open(cli->tree, fname,
828 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
830 printf("open of %s failed (%s)\n",
831 fname, smbcli_errstr(cli->tree));
832 printf("maximum fnum is %d\n", i);
843 printf("cleaning up\n");
844 for (i=0;i<maxfid/2;i++) {
845 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
846 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
847 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
849 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
850 printf("unlink of %s failed (%s)\n",
851 fname, smbcli_errstr(cli->tree));
856 asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
857 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
858 printf("Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
860 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
861 printf("unlink of %s failed (%s)\n",
862 fname, smbcli_errstr(cli->tree));
867 printf("%6d %6d\r", i, maxfid-i);
871 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
872 printf("Failed to deltree \\maxfid - %s\n",
873 smbcli_errstr(cli->tree));
877 printf("maxfid test finished\n");
878 if (!torture_close_connection(cli)) {
882 #undef MAXFID_TEMPLATE
885 /* send smb negprot commands, not reading the response */
886 static BOOL run_negprot_nowait(void)
889 struct smbcli_state *cli, *cli2;
892 printf("starting negprot nowait test\n");
894 cli = open_nbt_connection();
899 printf("Filling send buffer\n");
901 for (i=0;i<1000;i++) {
902 struct smbcli_request *req;
903 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
904 smbcli_transport_process(cli->transport);
905 if (req->state == SMBCLI_REQUEST_ERROR) {
906 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
907 torture_close_connection(cli);
912 printf("Opening secondary connection\n");
913 if (!torture_open_connection(&cli2)) {
917 if (!torture_close_connection(cli)) {
921 if (!torture_close_connection(cli2)) {
925 printf("finished negprot nowait test\n");
932 This checks how the getatr calls works
934 static BOOL run_attrtest(void)
936 struct smbcli_state *cli;
939 const char *fname = "\\attrib123456789.tst";
942 printf("starting attrib test\n");
944 if (!torture_open_connection(&cli)) {
948 smbcli_unlink(cli->tree, fname);
949 fnum = smbcli_open(cli->tree, fname,
950 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
951 smbcli_close(cli->tree, fnum);
953 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
954 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
958 printf("New file time is %s", ctime(&t));
960 if (abs(t - time(NULL)) > 60*60*24*10) {
961 printf("ERROR: SMBgetatr bug. time is %s",
967 t2 = t-60*60*24; /* 1 day ago */
969 printf("Setting file time to %s", ctime(&t2));
971 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
972 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
976 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
977 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
981 printf("Retrieved file time as %s", ctime(&t));
984 printf("ERROR: getatr/setatr bug. times are\n%s",
986 printf("%s", ctime(&t2));
990 smbcli_unlink(cli->tree, fname);
992 if (!torture_close_connection(cli)) {
996 printf("attrib test finished\n");
1003 This checks a couple of trans2 calls
1005 static BOOL run_trans2test(void)
1007 struct smbcli_state *cli;
1010 time_t c_time, a_time, m_time, w_time, m_time2;
1011 const char *fname = "\\trans2.tst";
1012 const char *dname = "\\trans2";
1013 const char *fname2 = "\\trans2\\trans2.tst";
1015 BOOL correct = True;
1017 printf("starting trans2 test\n");
1019 if (!torture_open_connection(&cli)) {
1023 smbcli_unlink(cli->tree, fname);
1025 printf("Testing qfileinfo\n");
1027 fnum = smbcli_open(cli->tree, fname,
1028 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1029 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
1031 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
1035 printf("Testing NAME_INFO\n");
1037 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
1038 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
1042 if (!pname || strcmp(pname, fname)) {
1043 printf("qfilename gave different name? [%s] [%s]\n",
1048 smbcli_close(cli->tree, fnum);
1049 smbcli_unlink(cli->tree, fname);
1051 fnum = smbcli_open(cli->tree, fname,
1052 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1054 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1057 smbcli_close(cli->tree, fnum);
1059 printf("Checking for sticky create times\n");
1061 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1062 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
1065 if (c_time != m_time) {
1066 printf("create time=%s", ctime(&c_time));
1067 printf("modify time=%s", ctime(&m_time));
1068 printf("This system appears to have sticky create times\n");
1070 if (a_time % (60*60) == 0) {
1071 printf("access time=%s", ctime(&a_time));
1072 printf("This system appears to set a midnight access time\n");
1076 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1077 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1083 smbcli_unlink(cli->tree, fname);
1084 fnum = smbcli_open(cli->tree, fname,
1085 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1086 smbcli_close(cli->tree, fnum);
1087 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1088 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1091 if (w_time < 60*60*24*2) {
1092 printf("write time=%s", ctime(&w_time));
1093 printf("This system appears to set a initial 0 write time\n");
1098 smbcli_unlink(cli->tree, fname);
1101 /* check if the server updates the directory modification time
1102 when creating a new file */
1103 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1104 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
1108 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1109 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1113 fnum = smbcli_open(cli->tree, fname2,
1114 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1115 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
1116 smbcli_close(cli->tree, fnum);
1117 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
1118 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1121 if (m_time2 == m_time) {
1122 printf("This system does not update directory modification times\n");
1126 smbcli_unlink(cli->tree, fname2);
1127 smbcli_rmdir(cli->tree, dname);
1129 if (!torture_close_connection(cli)) {
1133 printf("trans2 test finished\n");
1140 /* FIRST_DESIRED_ACCESS 0xf019f */
1141 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1142 SEC_FILE_READ_EA| /* 0xf */ \
1143 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1144 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1145 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1146 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1147 /* SECOND_DESIRED_ACCESS 0xe0080 */
1148 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1149 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1150 SEC_STD_WRITE_OWNER /* 0xe0000 */
1153 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1154 READ_CONTROL|WRITE_DAC|\
1155 SEC_FILE_READ_DATA|\
1160 Test ntcreate calls made by xcopy
1162 static BOOL run_xcopy(void)
1164 struct smbcli_state *cli1;
1165 const char *fname = "\\test.txt";
1166 BOOL correct = True;
1169 printf("starting xcopy test\n");
1171 if (!torture_open_connection(&cli1)) {
1175 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1176 FIRST_DESIRED_ACCESS,
1177 FILE_ATTRIBUTE_ARCHIVE,
1178 NTCREATEX_SHARE_ACCESS_NONE,
1179 NTCREATEX_DISP_OVERWRITE_IF,
1183 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
1187 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1188 SECOND_DESIRED_ACCESS, 0,
1189 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1192 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
1196 if (!torture_close_connection(cli1)) {
1205 see how many RPC pipes we can open at once
1207 static BOOL run_pipe_number(void)
1209 struct smbcli_state *cli1;
1210 const char *pipe_name = "\\WKSSVC";
1214 printf("starting pipenumber test\n");
1215 if (!torture_open_connection(&cli1)) {
1220 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1221 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1224 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
1228 printf("%d\r", num_pipes);
1232 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
1233 torture_close_connection(cli1);
1241 open N connections to the server and just hold them open
1242 used for testing performance when there are N idle users
1245 static BOOL torture_holdcon(void)
1248 struct smbcli_state **cli;
1251 printf("Opening %d connections\n", torture_numops);
1253 cli = malloc_array_p(struct smbcli_state *, torture_numops);
1255 for (i=0;i<torture_numops;i++) {
1256 if (!torture_open_connection(&cli[i])) {
1259 printf("opened %d connections\r", i);
1263 printf("\nStarting pings\n");
1266 for (i=0;i<torture_numops;i++) {
1269 status = smbcli_chkpath(cli[i]->tree, "\\");
1270 if (!NT_STATUS_IS_OK(status)) {
1271 printf("Connection %d is dead\n", i);
1279 if (num_dead == torture_numops) {
1280 printf("All connections dead - finishing\n");
1292 Try with a wrong vuid and check error message.
1295 static BOOL run_vuidtest(void)
1297 struct smbcli_state *cli;
1298 const char *fname = "\\vuid.tst";
1301 time_t c_time, a_time, m_time;
1302 BOOL correct = True;
1307 printf("starting vuid test\n");
1309 if (!torture_open_connection(&cli)) {
1313 smbcli_unlink(cli->tree, fname);
1315 fnum = smbcli_open(cli->tree, fname,
1316 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1318 orig_vuid = cli->session->vuid;
1320 cli->session->vuid += 1234;
1322 printf("Testing qfileinfo with wrong vuid\n");
1324 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
1325 &size, &c_time, &a_time,
1326 &m_time, NULL, NULL))) {
1327 printf("ERROR: qfileinfo passed with wrong vuid\n");
1331 if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1332 NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
1333 !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1334 NT_STATUS_INVALID_HANDLE)) {
1335 printf("ERROR: qfileinfo should have returned DOS error "
1336 "ERRSRV:ERRbaduid\n but returned %s\n",
1337 smbcli_errstr(cli->tree));
1341 cli->session->vuid -= 1234;
1343 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1344 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
1348 smbcli_unlink(cli->tree, fname);
1350 if (!torture_close_connection(cli)) {
1354 printf("vuid test finished\n");
1360 Test open mode returns on read-only files.
1362 static BOOL run_opentest(void)
1364 static struct smbcli_state *cli1;
1365 static struct smbcli_state *cli2;
1366 const char *fname = "\\readonly.file";
1367 char *control_char_fname;
1371 BOOL correct = True;
1376 printf("starting open test\n");
1378 if (!torture_open_connection(&cli1)) {
1382 asprintf(&control_char_fname, "\\readonly.afile");
1383 for (i = 1; i <= 0x1f; i++) {
1384 control_char_fname[10] = i;
1385 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
1386 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1388 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
1389 NT_STATUS_OBJECT_NAME_INVALID)) {
1390 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
1391 smbcli_errstr(cli1->tree), i);
1396 smbcli_close(cli1->tree, fnum1);
1398 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
1399 smbcli_unlink(cli1->tree, control_char_fname);
1401 free(control_char_fname);
1404 printf("Create file with control char names passed.\n");
1406 smbcli_setatr(cli1->tree, fname, 0, 0);
1407 smbcli_unlink(cli1->tree, fname);
1409 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1411 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1415 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1416 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1420 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
1421 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
1422 CHECK_MAX_FAILURES(error_test1);
1426 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1428 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1429 CHECK_MAX_FAILURES(error_test1);
1433 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
1434 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1436 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
1437 NT_STATUS_ACCESS_DENIED)) {
1438 printf("correct error code ERRDOS/ERRnoaccess returned\n");
1441 printf("finished open test 1\n");
1443 smbcli_close(cli1->tree, fnum1);
1445 /* Now try not readonly and ensure ERRbadshare is returned. */
1447 smbcli_setatr(cli1->tree, fname, 0, 0);
1449 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1451 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1455 /* This will fail - but the error should be ERRshare. */
1456 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1458 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
1459 NT_STATUS_SHARING_VIOLATION)) {
1460 printf("correct error code ERRDOS/ERRbadshare returned\n");
1463 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1464 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1468 smbcli_unlink(cli1->tree, fname);
1470 printf("finished open test 2\n");
1472 /* Test truncate open disposition on file opened for read. */
1474 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1476 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1480 /* write 20 bytes. */
1482 memset(buf, '\0', 20);
1484 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1485 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1489 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1490 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1494 /* Ensure size == 20. */
1495 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1496 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1497 CHECK_MAX_FAILURES(error_test3);
1502 printf("(3) file size != 20\n");
1503 CHECK_MAX_FAILURES(error_test3);
1507 /* Now test if we can truncate a file opened for readonly. */
1509 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
1511 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1512 CHECK_MAX_FAILURES(error_test3);
1516 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1517 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1521 /* Ensure size == 0. */
1522 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1523 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1524 CHECK_MAX_FAILURES(error_test3);
1529 printf("(3) file size != 0\n");
1530 CHECK_MAX_FAILURES(error_test3);
1533 printf("finished open test 3\n");
1535 smbcli_unlink(cli1->tree, fname);
1538 printf("testing ctemp\n");
1539 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
1541 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1542 CHECK_MAX_FAILURES(error_test4);
1545 printf("ctemp gave path %s\n", tmp_path);
1546 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1547 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1549 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1550 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1553 /* Test the non-io opens... */
1555 if (!torture_open_connection(&cli2)) {
1559 smbcli_setatr(cli2->tree, fname, 0, 0);
1560 smbcli_unlink(cli2->tree, fname);
1562 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1564 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1565 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1568 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1569 CHECK_MAX_FAILURES(error_test10);
1573 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1574 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1576 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1577 CHECK_MAX_FAILURES(error_test10);
1581 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1582 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1585 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1586 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1590 printf("non-io open test #1 passed.\n");
1592 smbcli_unlink(cli1->tree, fname);
1594 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1596 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1597 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1600 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1601 CHECK_MAX_FAILURES(error_test20);
1605 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1606 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1609 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1610 CHECK_MAX_FAILURES(error_test20);
1614 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1615 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1618 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1619 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1623 printf("non-io open test #2 passed.\n");
1625 smbcli_unlink(cli1->tree, fname);
1627 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1629 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1630 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1633 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1634 CHECK_MAX_FAILURES(error_test30);
1638 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1639 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1642 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1643 CHECK_MAX_FAILURES(error_test30);
1647 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1648 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1651 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1652 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1656 printf("non-io open test #3 passed.\n");
1658 smbcli_unlink(cli1->tree, fname);
1660 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1662 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1663 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1666 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1667 CHECK_MAX_FAILURES(error_test40);
1671 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1672 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1675 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1676 CHECK_MAX_FAILURES(error_test40);
1680 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1682 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1683 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1687 printf("non-io open test #4 passed.\n");
1689 smbcli_unlink(cli1->tree, fname);
1691 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1693 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1694 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1697 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1698 CHECK_MAX_FAILURES(error_test50);
1702 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1703 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1706 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1707 CHECK_MAX_FAILURES(error_test50);
1711 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1712 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1716 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1717 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1721 printf("non-io open test #5 passed.\n");
1723 printf("TEST #6 testing 1 non-io open, one io open\n");
1725 smbcli_unlink(cli1->tree, fname);
1727 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1728 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1731 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1732 CHECK_MAX_FAILURES(error_test60);
1736 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1737 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1740 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1741 CHECK_MAX_FAILURES(error_test60);
1745 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1746 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1750 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1751 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1755 printf("non-io open test #6 passed.\n");
1757 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
1759 smbcli_unlink(cli1->tree, fname);
1761 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1762 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1765 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1766 CHECK_MAX_FAILURES(error_test70);
1770 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1771 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1774 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1775 CHECK_MAX_FAILURES(error_test70);
1779 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1781 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1782 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1786 printf("non-io open test #7 passed.\n");
1790 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1792 smbcli_unlink(cli1->tree, fname);
1794 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1796 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1800 /* write 20 bytes. */
1802 memset(buf, '\0', 20);
1804 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1805 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1809 /* Ensure size == 20. */
1810 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1811 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1812 CHECK_MAX_FAILURES(error_test80);
1817 printf("(8) file size != 20\n");
1818 CHECK_MAX_FAILURES(error_test80);
1822 /* Get an exclusive lock on the open file. */
1823 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1824 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1825 CHECK_MAX_FAILURES(error_test80);
1829 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1831 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1835 /* Ensure size == 0. */
1836 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1837 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1838 CHECK_MAX_FAILURES(error_test80);
1843 printf("(8) file size != 0\n");
1844 CHECK_MAX_FAILURES(error_test80);
1848 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1849 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1853 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1854 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1860 printf("open test #8 passed.\n");
1862 smbcli_unlink(cli1->tree, fname);
1864 if (!torture_close_connection(cli1)) {
1867 if (!torture_close_connection(cli2)) {
1876 sees what IOCTLs are supported
1878 BOOL torture_ioctl_test(void)
1880 struct smbcli_state *cli;
1881 uint16_t device, function;
1883 const char *fname = "\\ioctl.dat";
1885 union smb_ioctl parms;
1886 TALLOC_CTX *mem_ctx;
1888 if (!torture_open_connection(&cli)) {
1892 mem_ctx = talloc_init("ioctl_test");
1894 printf("starting ioctl test\n");
1896 smbcli_unlink(cli->tree, fname);
1898 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1900 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1904 parms.ioctl.level = RAW_IOCTL_IOCTL;
1905 parms.ioctl.in.fnum = fnum;
1906 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
1907 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1908 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
1910 for (device=0;device<0x100;device++) {
1911 printf("testing device=0x%x\n", device);
1912 for (function=0;function<0x100;function++) {
1913 parms.ioctl.in.request = (device << 16) | function;
1914 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1916 if (NT_STATUS_IS_OK(status)) {
1917 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
1918 device, function, (int)parms.ioctl.out.blob.length);
1923 if (!torture_close_connection(cli)) {
1932 tries variants of chkpath
1934 BOOL torture_chkpath_test(void)
1936 struct smbcli_state *cli;
1940 if (!torture_open_connection(&cli)) {
1944 printf("starting chkpath test\n");
1946 printf("Testing valid and invalid paths\n");
1948 /* cleanup from an old run */
1949 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1950 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1951 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1953 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1954 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1958 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1959 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1963 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1965 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
1968 smbcli_close(cli->tree, fnum);
1970 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1971 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1975 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1976 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1980 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1981 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1982 NT_STATUS_NOT_A_DIRECTORY);
1984 printf("* chkpath on a file should fail\n");
1988 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
1989 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1990 NT_STATUS_OBJECT_NAME_NOT_FOUND);
1992 printf("* chkpath on a non existent file should fail\n");
1996 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
1997 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1998 NT_STATUS_OBJECT_PATH_NOT_FOUND);
2000 printf("* chkpath on a non existent component should fail\n");
2004 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
2005 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
2006 smbcli_rmdir(cli->tree, "\\chkpath.dir");
2008 if (!torture_close_connection(cli)) {
2016 static void sigcont(int sig)
2020 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
2023 volatile pid_t *child_status;
2024 volatile BOOL *child_status_out;
2027 double start_time_limit = 10 + (torture_nprocs * 1.5);
2028 char **unc_list = NULL;
2030 int num_unc_names = 0;
2037 signal(SIGCONT, sigcont);
2039 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
2040 if (!child_status) {
2041 printf("Failed to setup shared memory\n");
2045 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
2046 if (!child_status_out) {
2047 printf("Failed to setup result status shared memory\n");
2051 p = lp_parm_string(-1, "torture", "unclist");
2053 unc_list = file_lines_load(p, &num_unc_names, NULL);
2054 if (!unc_list || num_unc_names <= 0) {
2055 printf("Failed to load unc names list from '%s'\n", p);
2060 for (i = 0; i < torture_nprocs; i++) {
2061 child_status[i] = 0;
2062 child_status_out[i] = True;
2065 tv = timeval_current();
2067 for (i=0;i<torture_nprocs;i++) {
2071 const char *hostname=NULL, *sharename;
2073 pid_t mypid = getpid();
2074 srandom(((int)mypid) ^ ((int)time(NULL)));
2076 asprintf(&myname, "CLIENT%d", i);
2077 lp_set_cmdline("netbios name", myname);
2082 if (!smbcli_parse_unc(unc_list[i % num_unc_names],
2083 NULL, &hostname, &sharename)) {
2084 printf("Failed to parse UNC name %s\n",
2085 unc_list[i % num_unc_names]);
2092 if (torture_open_connection_share(NULL,
2099 } else if (torture_open_connection(¤t_cli)) {
2103 printf("pid %d failed to start\n", (int)getpid());
2109 child_status[i] = getpid();
2113 if (child_status[i]) {
2114 printf("Child %d failed to start!\n", i);
2115 child_status_out[i] = 1;
2119 child_status_out[i] = fn(current_cli, i);
2126 for (i=0;i<torture_nprocs;i++) {
2127 if (child_status[i]) synccount++;
2129 if (synccount == torture_nprocs) break;
2131 } while (timeval_elapsed(&tv) < start_time_limit);
2133 if (synccount != torture_nprocs) {
2134 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
2136 return timeval_elapsed(&tv);
2139 printf("Starting %d clients\n", torture_nprocs);
2141 /* start the client load */
2142 tv = timeval_current();
2143 for (i=0;i<torture_nprocs;i++) {
2144 child_status[i] = 0;
2147 printf("%d clients started\n", torture_nprocs);
2151 for (i=0;i<torture_nprocs;i++) {
2153 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
2154 if (ret == -1 || WEXITSTATUS(status) != 0) {
2161 for (i=0;i<torture_nprocs;i++) {
2162 if (!child_status_out[i]) {
2166 return timeval_elapsed(&tv);
2169 #define FLAG_MULTIPROC 1
2174 BOOL (*multi_fn)(struct smbcli_state *, int );
2177 {"BASE-FDPASS", run_fdpasstest, 0},
2178 {"BASE-LOCK1", torture_locktest1, 0},
2179 {"BASE-LOCK2", torture_locktest2, 0},
2180 {"BASE-LOCK3", torture_locktest3, 0},
2181 {"BASE-LOCK4", torture_locktest4, 0},
2182 {"BASE-LOCK5", torture_locktest5, 0},
2183 {"BASE-LOCK6", torture_locktest6, 0},
2184 {"BASE-LOCK7", torture_locktest7, 0},
2185 {"BASE-UNLINK", torture_unlinktest, 0},
2186 {"BASE-ATTR", run_attrtest, 0},
2187 {"BASE-TRANS2", run_trans2test, 0},
2188 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
2189 {"BASE-DIR1", torture_dirtest1, 0},
2190 {"BASE-DIR2", torture_dirtest2, 0},
2191 {"BASE-DENY1", torture_denytest1, 0},
2192 {"BASE-DENY2", torture_denytest2, 0},
2193 {"BASE-DENY3", torture_denytest3, 0},
2194 {"BASE-DENYDOS", torture_denydos_sharing, 0},
2195 {"BASE-NTDENY1", NULL, torture_ntdenytest1},
2196 {"BASE-NTDENY2", torture_ntdenytest2, 0},
2197 {"BASE-TCON", run_tcon_test, 0},
2198 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
2199 {"BASE-VUID", run_vuidtest, 0},
2200 {"BASE-RW1", run_readwritetest, 0},
2201 {"BASE-OPEN", run_opentest, 0},
2202 {"BASE-DEFER_OPEN", NULL, run_deferopen},
2203 {"BASE-XCOPY", run_xcopy, 0},
2204 {"BASE-RENAME", torture_test_rename, 0},
2205 {"BASE-DELETE", torture_test_delete, 0},
2206 {"BASE-PROPERTIES", torture_test_properties, 0},
2207 {"BASE-MANGLE", torture_mangle, 0},
2208 {"BASE-OPENATTR", torture_openattrtest, 0},
2209 {"BASE-CHARSET", torture_charset, 0},
2210 {"BASE-CHKPATH", torture_chkpath_test, 0},
2211 {"BASE-SECLEAK", torture_sec_leak, 0},
2212 {"BASE-DISCONNECT", torture_disconnect, 0},
2213 {"BASE-DELAYWRITE", torture_delay_write, 0},
2215 /* benchmarking tests */
2216 {"BENCH-HOLDCON", torture_holdcon, 0},
2217 {"BENCH-NBENCH", torture_nbench, 0},
2218 {"BENCH-TORTURE", NULL, run_torture},
2219 {"BENCH-NBT", torture_bench_nbt, 0},
2220 {"BENCH-WINS", torture_bench_wins, 0},
2221 {"BENCH-RPC", torture_bench_rpc, 0},
2222 {"BENCH-CLDAP", torture_bench_cldap, 0},
2225 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
2226 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
2227 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
2228 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
2229 {"RAW-SEARCH", torture_raw_search, 0},
2230 {"RAW-CLOSE", torture_raw_close, 0},
2231 {"RAW-OPEN", torture_raw_open, 0},
2232 {"RAW-MKDIR", torture_raw_mkdir, 0},
2233 {"RAW-OPLOCK", torture_raw_oplock, 0},
2234 {"RAW-NOTIFY", torture_raw_notify, 0},
2235 {"RAW-MUX", torture_raw_mux, 0},
2236 {"RAW-IOCTL", torture_raw_ioctl, 0},
2237 {"RAW-CHKPATH", torture_raw_chkpath, 0},
2238 {"RAW-UNLINK", torture_raw_unlink, 0},
2239 {"RAW-READ", torture_raw_read, 0},
2240 {"RAW-WRITE", torture_raw_write, 0},
2241 {"RAW-LOCK", torture_raw_lock, 0},
2242 {"RAW-CONTEXT", torture_raw_context, 0},
2243 {"RAW-RENAME", torture_raw_rename, 0},
2244 {"RAW-SEEK", torture_raw_seek, 0},
2245 {"RAW-EAS", torture_raw_eas, 0},
2246 {"RAW-EAMAX", torture_max_eas, 0},
2247 {"RAW-STREAMS", torture_raw_streams, 0},
2248 {"RAW-ACLS", torture_raw_acls, 0},
2249 {"RAW-RAP", torture_raw_rap, 0},
2250 {"RAW-COMPOSITE", torture_raw_composite, 0},
2253 {"SMB2-CONNECT", torture_smb2_connect, 0},
2254 {"SMB2-SCAN", torture_smb2_scan, 0},
2255 {"SMB2-SCANGETINFO", torture_smb2_getinfo_scan, 0},
2256 {"SMB2-SCANSETINFO", torture_smb2_setinfo_scan, 0},
2257 {"SMB2-SCANFIND", torture_smb2_find_scan, 0},
2258 {"SMB2-GETINFO", torture_smb2_getinfo, 0},
2259 {"SMB2-SETINFO", torture_smb2_setinfo, 0},
2260 {"SMB2-FIND", torture_smb2_find, 0},
2262 /* protocol scanners */
2263 {"SCAN-TRANS2", torture_trans2_scan, 0},
2264 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2265 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2266 {"SCAN-SMB", torture_smb_scan, 0},
2267 {"SCAN-MAXFID", NULL, run_maxfidtest},
2268 {"SCAN-UTABLE", torture_utable, 0},
2269 {"SCAN-CASETABLE", torture_casetable, 0},
2270 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2271 {"SCAN-IOCTL", torture_ioctl_test, 0},
2272 {"SCAN-RAP", torture_rap_scan, 0},
2275 {"RPC-LSA", torture_rpc_lsa, 0},
2276 {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
2277 {"RPC-ECHO", torture_rpc_echo, 0},
2278 {"RPC-DFS", torture_rpc_dfs, 0},
2279 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2280 {"RPC-SAMR", torture_rpc_samr, 0},
2281 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2282 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2283 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2284 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2285 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2286 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2287 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2288 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2289 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2290 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2291 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2292 {"RPC-WINREG", torture_rpc_winreg, 0},
2293 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2294 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2295 {"RPC-REMACT", torture_rpc_remact, 0},
2296 {"RPC-MGMT", torture_rpc_mgmt, 0},
2297 {"RPC-SCANNER", torture_rpc_scanner, 0},
2298 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2299 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2300 {"RPC-MULTIBIND", torture_multi_bind, 0},
2301 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2302 {"RPC-CRACKNAMES", torture_rpc_drsuapi_cracknames, 0},
2303 {"RPC-ROT", torture_rpc_rot, 0},
2304 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2305 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2306 {"RPC-JOIN", torture_rpc_join, 0},
2307 {"RPC-DSSYNC", torture_rpc_dssync, 0},
2308 {"RPC-NDR", torture_rpc_ndr, 0},
2310 /* local (no server) testers */
2311 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2312 {"LOCAL-ICONV", torture_local_iconv, 0},
2313 {"LOCAL-TALLOC", torture_local_talloc, 0},
2314 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2315 {"LOCAL-IRPC", torture_local_irpc, 0},
2316 {"LOCAL-BINDING", torture_local_binding_string, 0},
2317 {"LOCAL-STRLIST", torture_local_util_strlist, 0},
2318 {"LOCAL-FILE", torture_local_util_file, 0},
2319 {"LOCAL-IDTREE", torture_local_idtree, 0},
2320 {"LOCAL-SOCKET", torture_local_socket, 0},
2321 {"LOCAL-PAC", torture_pac, 0},
2322 {"LOCAL-REGISTRY", torture_registry, 0},
2323 {"LOCAL-RESOLVE", torture_local_resolve, 0},
2324 {"LOCAL-SDDL", torture_local_sddl, 0},
2326 /* COM (Component Object Model) testers */
2327 {"COM-SIMPLE", torture_com_simple, 0 },
2330 {"LDAP-BASIC", torture_ldap_basic, 0},
2331 {"LDAP-CLDAP", torture_cldap, 0},
2334 {"NBT-REGISTER", torture_nbt_register, 0},
2335 {"NBT-WINS", torture_nbt_wins, 0},
2336 {"NBT-DGRAM", torture_nbt_dgram, 0},
2337 {"NBT-WINSREPLICATION", torture_nbt_winsreplication, 0},
2340 {"NET-USERINFO", torture_userinfo, 0},
2341 {"NET-USERADD", torture_useradd, 0},
2342 {"NET-USERDEL", torture_userdel, 0},
2343 {"NET-USERMOD", torture_usermod, 0},
2344 {"NET-DOMOPEN", torture_domainopen, 0},
2345 {"NET-API-LOOKUP", torture_lookup, 0},
2346 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2347 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2348 {"NET-API-CREATEUSER", torture_createuser, 0},
2349 {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
2350 {"NET-API-LISTSHARES", torture_listshares, 0},
2351 {"NET-API-DELSHARE", torture_delshare, 0},
2357 /****************************************************************************
2358 run a specified test or "ALL"
2359 ****************************************************************************/
2360 static BOOL run_test(const char *name)
2364 BOOL matched = False;
2366 if (strequal(name,"ALL")) {
2367 for (i=0;torture_ops[i].name;i++) {
2368 if (!run_test(torture_ops[i].name)) {
2375 for (i=0;torture_ops[i].name;i++) {
2376 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
2380 printf("Running %s\n", torture_ops[i].name);
2381 if (torture_ops[i].multi_fn) {
2382 BOOL result = False;
2383 t = torture_create_procs(torture_ops[i].multi_fn,
2387 printf("TEST %s FAILED!\n", torture_ops[i].name);
2391 struct timeval tv = timeval_current();
2392 if (!torture_ops[i].fn()) {
2394 printf("TEST %s FAILED!\n", torture_ops[i].name);
2396 t = timeval_elapsed(&tv);
2398 printf("%s took %g secs\n\n", torture_ops[i].name, t);
2403 printf("Unknown torture operation '%s'\n", name);
2410 static void parse_dns(const char *dns)
2412 char *userdn, *basedn, *secret;
2415 /* retrievieng the userdn */
2416 p = strchr_m(dns, '#');
2418 lp_set_cmdline("torture:ldap_userdn", "");
2419 lp_set_cmdline("torture:ldap_basedn", "");
2420 lp_set_cmdline("torture:ldap_secret", "");
2423 userdn = strndup(dns, p - dns);
2424 lp_set_cmdline("torture:ldap_userdn", userdn);
2426 /* retrieve the basedn */
2428 p = strchr_m(d, '#');
2430 lp_set_cmdline("torture:ldap_basedn", "");
2431 lp_set_cmdline("torture:ldap_secret", "");
2434 basedn = strndup(d, p - d);
2435 lp_set_cmdline("torture:ldap_basedn", basedn);
2437 /* retrieve the secret */
2440 lp_set_cmdline("torture:ldap_secret", "");
2444 lp_set_cmdline("torture:ldap_secret", secret);
2446 printf ("%s - %s - %s\n", userdn, basedn, secret);
2450 static void usage(poptContext pc)
2455 poptPrintUsage(pc, stdout, 0);
2458 printf("The binding format is:\n\n");
2460 printf(" TRANSPORT:host[flags]\n\n");
2462 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2464 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2465 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2466 printf(" string.\n\n");
2468 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2469 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2470 printf(" will be auto-determined.\n\n");
2472 printf(" other recognised flags are:\n\n");
2474 printf(" sign : enable ntlmssp signing\n");
2475 printf(" seal : enable ntlmssp sealing\n");
2476 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2477 printf(" validate: enable the NDR validator\n");
2478 printf(" print: enable debugging of the packets\n");
2479 printf(" bigendian: use bigendian RPC\n");
2480 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2482 printf(" For example, these all connect to the samr pipe:\n\n");
2484 printf(" ncacn_np:myserver\n");
2485 printf(" ncacn_np:myserver[samr]\n");
2486 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2487 printf(" ncacn_np:myserver[/pipe/samr]\n");
2488 printf(" ncacn_np:myserver[samr,sign,print]\n");
2489 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2490 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2491 printf(" ncacn_np:\n");
2492 printf(" ncacn_np:[/pipe/samr]\n\n");
2494 printf(" ncacn_ip_tcp:myserver\n");
2495 printf(" ncacn_ip_tcp:myserver[1024]\n");
2496 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2498 printf("The unc format is:\n\n");
2500 printf(" //server/share\n\n");
2502 printf("tests are:");
2503 for (i=0;torture_ops[i].name;i++) {
2504 if ((i%perline)==0) {
2507 printf("%s ", torture_ops[i].name);
2511 printf("default test is ALL\n");
2516 static BOOL is_binding_string(const char *binding_string)
2518 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2519 struct dcerpc_binding *binding_struct;
2522 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2524 talloc_free(mem_ctx);
2525 return NT_STATUS_IS_OK(status);
2528 static void max_runtime_handler(int sig)
2530 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2534 /****************************************************************************
2536 ****************************************************************************/
2537 int main(int argc,char *argv[])
2541 BOOL correct = True;
2546 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,OPT_DANGEROUS};
2547 struct poptOption long_options[] = {
2549 {"smb-ports", 'p', POPT_ARG_STRING, NULL, 0, "SMB ports", NULL},
2550 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2551 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2552 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2553 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2554 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2555 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2556 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2557 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2558 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2559 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2560 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2561 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2562 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2563 "set maximum time for smbtorture to live", "seconds"},
2565 POPT_COMMON_CONNECTION
2566 POPT_COMMON_CREDENTIALS
2571 #ifdef HAVE_SETBUFFER
2572 setbuffer(stdout, NULL, 0);
2575 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2576 POPT_CONTEXT_KEEP_FIRST);
2578 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2580 while((opt = poptGetNextOpt(pc)) != -1) {
2583 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2586 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2589 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2592 parse_dns(poptGetOptArg(pc));
2595 lp_set_cmdline("torture:dangerous", "Yes");
2598 d_printf("Invalid option %s: %s\n",
2599 poptBadOption(pc, 0), poptStrerror(opt));
2606 /* this will only work if nobody else uses alarm(),
2607 which means it won't work for some tests, but we
2608 can't use the event context method we use for smbd
2609 as so many tests create their own event
2610 context. This will at least catch most cases. */
2611 signal(SIGALRM, max_runtime_handler);
2615 smbtorture_init_subsystems;
2618 if (torture_seed == 0) {
2619 torture_seed = time(NULL);
2621 printf("Using seed %d\n", torture_seed);
2622 srandom(torture_seed);
2624 argv_new = discard_const_p(char *, poptGetArgs(pc));
2627 for (i=0; i<argc; i++) {
2628 if (argv_new[i] == NULL) {
2639 for(p = argv_new[1]; *p; p++) {
2644 /* see if its a RPC transport specifier */
2645 if (is_binding_string(argv_new[1])) {
2646 lp_set_cmdline("torture:binding", argv_new[1]);
2648 char *binding = NULL;
2649 const char *host = NULL, *share = NULL;
2651 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
2652 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
2656 lp_set_cmdline("torture:host", host);
2657 lp_set_cmdline("torture:share", share);
2658 asprintf(&binding, "ncacn_np:%s", host);
2659 lp_set_cmdline("torture:binding", binding);
2662 if (argc_new == 0) {
2663 printf("You must specify a test to run, or 'ALL'\n");
2665 for (i=2;i<argc_new;i++) {
2666 if (!run_test(argv_new[i])) {