2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "lib/cmdline/popt_common.h"
23 #include "libcli/raw/libcliraw.h"
24 #include "system/time.h"
25 #include "system/wait.h"
26 #include "system/filesys.h"
28 #include "smb_build.h"
31 int torture_numops=10;
32 int torture_entries=1000;
33 int torture_failures=1;
35 static int procnum; /* records process count number when forking */
36 static struct smbcli_state *current_cli;
37 static BOOL use_oplocks;
38 static BOOL use_level_II_oplocks;
40 BOOL torture_showall = False;
42 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
44 static struct smbcli_state *open_nbt_connection(void)
46 struct nbt_name called, calling;
47 struct smbcli_state *cli;
48 const char *host = lp_parm_string(-1, "torture", "host");
50 make_nbt_name_client(&calling, lp_netbios_name());
52 nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
54 cli = smbcli_state_init(NULL);
56 printf("Failed initialize smbcli_struct to connect with %s\n", host);
60 if (!smbcli_socket_connect(cli, host)) {
61 printf("Failed to connect with %s\n", host);
65 if (!smbcli_transport_establish(cli, &calling, &called)) {
66 printf("%s rejected the session\n",host);
77 BOOL torture_open_connection_share(TALLOC_CTX *mem_ctx,
78 struct smbcli_state **c,
80 const char *sharename,
81 struct event_context *ev)
85 status = smbcli_full_connection(mem_ctx, c, hostname,
87 cmdline_credentials, ev);
88 if (!NT_STATUS_IS_OK(status)) {
89 printf("Failed to open connection - %s\n", nt_errstr(status));
93 (*c)->transport->options.use_oplocks = use_oplocks;
94 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
99 BOOL torture_open_connection(struct smbcli_state **c)
101 const char *host = lp_parm_string(-1, "torture", "host");
102 const char *share = lp_parm_string(-1, "torture", "share");
104 return torture_open_connection_share(NULL, c, host, share, NULL);
109 BOOL torture_close_connection(struct smbcli_state *c)
113 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
114 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
121 /* open a rpc connection to the chosen binding string */
122 NTSTATUS torture_rpc_connection(TALLOC_CTX *parent_ctx,
123 struct dcerpc_pipe **p,
124 const struct dcerpc_interface_table *table)
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,
136 cmdline_credentials, NULL);
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 struct dcerpc_interface_table *table,
145 enum dcerpc_transport_t transport)
148 const char *binding = lp_parm_string(-1, "torture", "binding");
149 struct dcerpc_binding *b;
150 TALLOC_CTX *mem_ctx = talloc_named(parent_ctx, 0, "torture_rpc_connection_smb");
153 printf("You must specify a ncacn binding string\n");
154 talloc_free(mem_ctx);
155 return NT_STATUS_INVALID_PARAMETER;
158 status = dcerpc_parse_binding(mem_ctx, binding, &b);
159 if (!NT_STATUS_IS_OK(status)) {
160 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
161 talloc_free(mem_ctx);
165 b->transport = transport;
167 status = dcerpc_pipe_connect_b(mem_ctx, p, b, table,
168 cmdline_credentials, NULL);
170 if (NT_STATUS_IS_OK(status)) {
171 *p = talloc_reference(parent_ctx, *p);
175 talloc_free(mem_ctx);
179 /* check if the server produced the expected error code */
180 BOOL check_error(const char *location, struct smbcli_state *c,
181 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
185 status = smbcli_nt_error(c->tree);
186 if (NT_STATUS_IS_DOS(status)) {
188 class = NT_STATUS_DOS_CLASS(status);
189 num = NT_STATUS_DOS_CODE(status);
190 if (eclass != class || ecode != num) {
191 printf("unexpected error code %s\n", nt_errstr(status));
192 printf(" expected %s or %s (at %s)\n",
193 nt_errstr(NT_STATUS_DOS(eclass, ecode)),
194 nt_errstr(nterr), location);
198 if (!NT_STATUS_EQUAL(nterr, status)) {
199 printf("unexpected error code %s\n", nt_errstr(status));
200 printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
209 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
211 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
212 if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
218 static BOOL rw_torture(struct smbcli_state *c)
220 const char *lockfname = "\\torture.lck";
224 pid_t pid2, pid = getpid();
229 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
232 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
234 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
239 for (i=0;i<torture_numops;i++) {
240 uint_t n = (uint_t)random()%10;
242 printf("%d\r", i); fflush(stdout);
244 asprintf(&fname, "\\torture.%u", n);
246 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
250 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
252 printf("open failed (%s)\n", smbcli_errstr(c->tree));
257 if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
258 printf("write failed (%s)\n", smbcli_errstr(c->tree));
263 if (smbcli_write(c->tree, fnum, 0, buf,
264 sizeof(pid)+(j*sizeof(buf)),
265 sizeof(buf)) != sizeof(buf)) {
266 printf("write failed (%s)\n", smbcli_errstr(c->tree));
273 if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
274 printf("read failed (%s)\n", smbcli_errstr(c->tree));
279 printf("data corruption!\n");
283 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
284 printf("close failed (%s)\n", smbcli_errstr(c->tree));
288 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
289 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
293 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
294 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
300 smbcli_close(c->tree, fnum2);
301 smbcli_unlink(c->tree, lockfname);
308 static BOOL run_torture(struct smbcli_state *cli, int dummy)
312 ret = rw_torture(cli);
314 if (!torture_close_connection(cli)) {
322 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
324 const char *lockfname = "\\torture2.lck";
329 uint8_t buf_rd[131072];
331 ssize_t bytes_read, bytes_written;
333 if (smbcli_deltree(c1->tree, lockfname) == -1) {
334 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
337 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
340 printf("first open read/write of %s failed (%s)\n",
341 lockfname, smbcli_errstr(c1->tree));
344 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
347 printf("second open read-only of %s failed (%s)\n",
348 lockfname, smbcli_errstr(c2->tree));
349 smbcli_close(c1->tree, fnum1);
353 printf("Checking data integrity over %d ops\n", torture_numops);
355 for (i=0;i<torture_numops;i++)
357 size_t buf_size = ((uint_t)random()%(sizeof(buf)-1))+ 1;
359 printf("%d\r", i); fflush(stdout);
362 generate_random_buffer(buf, buf_size);
364 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
365 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
366 printf("wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
371 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
372 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
373 printf("read %d, expected %d\n", (int)bytes_read, (int)buf_size);
378 if (memcmp(buf_rd, buf, buf_size) != 0)
380 printf("read/write compare failed\n");
386 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
387 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
390 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
391 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
395 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
396 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
403 #define BOOLSTR(b) ((b) ? "Yes" : "No")
405 static BOOL run_readwritetest(void)
407 struct smbcli_state *cli1, *cli2;
408 BOOL test1, test2 = True;
410 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
414 printf("starting readwritetest\n");
416 test1 = rw_torture2(cli1, cli2);
417 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
420 test2 = rw_torture2(cli1, cli1);
421 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
424 if (!torture_close_connection(cli1)) {
428 if (!torture_close_connection(cli2)) {
432 return (test1 && test2);
436 this checks to see if a secondary tconx can use open files from an
439 static BOOL run_tcon_test(void)
441 struct smbcli_state *cli;
442 const char *fname = "\\tcontest.tmp";
444 uint16_t cnum1, cnum2, cnum3;
445 uint16_t vuid1, vuid2;
448 struct smbcli_tree *tree1;
449 const char *host = lp_parm_string(-1, "torture", "host");
450 const char *share = lp_parm_string(-1, "torture", "share");
451 const char *password = lp_parm_string(-1, "torture", "password");
453 if (!torture_open_connection(&cli)) {
457 printf("starting tcontest\n");
459 if (smbcli_deltree(cli->tree, fname) == -1) {
460 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
463 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
465 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
469 cnum1 = cli->tree->tid;
470 vuid1 = cli->session->vuid;
472 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
473 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
474 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
478 tree1 = cli->tree; /* save old tree connection */
479 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
480 printf("%s refused 2nd tree connect (%s)\n", host,
481 smbcli_errstr(cli->tree));
486 cnum2 = cli->tree->tid;
487 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
488 vuid2 = cli->session->vuid + 1;
490 /* try a write with the wrong tid */
491 cli->tree->tid = cnum2;
493 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
494 printf("* server allows write with wrong TID\n");
497 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
501 /* try a write with an invalid tid */
502 cli->tree->tid = cnum3;
504 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
505 printf("* server allows write with invalid TID\n");
508 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
511 /* try a write with an invalid vuid */
512 cli->session->vuid = vuid2;
513 cli->tree->tid = cnum1;
515 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
516 printf("* server allows write with invalid VUID\n");
519 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
522 cli->session->vuid = vuid1;
523 cli->tree->tid = cnum1;
525 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
526 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
530 cli->tree->tid = cnum2;
532 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
533 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
537 cli->tree = tree1; /* restore initial tree */
538 cli->tree->tid = cnum1;
540 smbcli_unlink(tree1, fname);
542 if (!torture_close_connection(cli)) {
551 static BOOL tcon_devtest(struct smbcli_state *cli,
552 const char *myshare, const char *devtype,
553 NTSTATUS expected_error)
557 const char *password = lp_parm_string(-1, "torture", "password");
559 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
562 printf("Trying share %s with devtype %s\n", myshare, devtype);
564 if (NT_STATUS_IS_OK(expected_error)) {
568 printf("tconX to share %s with type %s "
569 "should have succeeded but failed\n",
576 printf("tconx to share %s with type %s "
577 "should have failed but succeeded\n",
581 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
585 printf("Returned unexpected error\n");
594 checks for correct tconX support
596 static BOOL run_tcon_devtype_test(void)
598 struct smbcli_state *cli1 = NULL;
601 const char *host = lp_parm_string(-1, "torture", "host");
602 const char *share = lp_parm_string(-1, "torture", "share");
604 status = smbcli_full_connection(NULL,
607 cmdline_credentials, NULL);
609 if (!NT_STATUS_IS_OK(status)) {
610 printf("could not open connection\n");
614 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
617 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
620 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
623 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
626 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
629 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
632 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
635 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
638 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
641 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
647 printf("Passed tcondevtest\n");
654 test whether fnums and tids open on one VC are available on another (a major
657 static BOOL run_fdpasstest(void)
659 struct smbcli_state *cli1, *cli2;
660 const char *fname = "\\fdpass.tst";
664 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
668 printf("starting fdpasstest\n");
670 smbcli_unlink(cli1->tree, fname);
672 printf("Opening a file on connection 1\n");
674 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
676 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
680 printf("writing to file on connection 1\n");
682 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
683 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
687 oldtid = cli2->tree->tid;
688 cli2->session->vuid = cli1->session->vuid;
689 cli2->tree->tid = cli1->tree->tid;
690 cli2->session->pid = cli1->session->pid;
692 printf("reading from file on connection 2\n");
694 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
695 printf("read succeeded! nasty security hole [%s]\n",
700 smbcli_close(cli1->tree, fnum1);
701 smbcli_unlink(cli1->tree, fname);
703 cli2->tree->tid = oldtid;
705 torture_close_connection(cli1);
706 torture_close_connection(cli2);
708 printf("finished fdpasstest\n");
714 test the timing of deferred open requests
716 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
718 const char *fname = "\\defer_open_test.dat";
724 printf("failed to connect\n");
728 printf("Testing deferred open requests.\n");
735 tv = timeval_current();
736 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
738 FILE_ATTRIBUTE_NORMAL,
739 NTCREATEX_SHARE_ACCESS_NONE,
740 NTCREATEX_DISP_OPEN_IF, 0, 0);
744 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
745 double e = timeval_elapsed(&tv);
746 if (e < 0.5 || e > 1.5) {
747 fprintf(stderr,"Timing incorrect %.2f violation\n",
751 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
754 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
758 printf("pid %u open %d\n", getpid(), i);
762 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
763 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
769 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
770 /* All until the last unlink will fail with sharing violation. */
771 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
772 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
777 printf("deferred test finished\n");
778 if (!torture_close_connection(cli)) {
785 test how many open files this server supports on the one socket
787 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
789 #define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
791 int fnums[0x11000], i;
792 int retries=4, maxfid;
796 printf("failed to connect\n");
800 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
801 printf("Failed to deltree \\maxfid - %s\n",
802 smbcli_errstr(cli->tree));
805 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
806 printf("Failed to mkdir \\maxfid, error=%s\n",
807 smbcli_errstr(cli->tree));
811 printf("Testing maximum number of open files\n");
813 for (i=0; i<0x11000; i++) {
815 asprintf(&fname, "\\maxfid\\fid%d", i/1000);
816 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
817 printf("Failed to mkdir %s, error=%s\n",
818 fname, smbcli_errstr(cli->tree));
823 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
824 if ((fnums[i] = smbcli_open(cli->tree, fname,
825 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
827 printf("open of %s failed (%s)\n",
828 fname, smbcli_errstr(cli->tree));
829 printf("maximum fnum is %d\n", i);
840 printf("cleaning up\n");
841 for (i=0;i<maxfid/2;i++) {
842 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
843 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
844 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
846 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
847 printf("unlink of %s failed (%s)\n",
848 fname, smbcli_errstr(cli->tree));
853 asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
854 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
855 printf("Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
857 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
858 printf("unlink of %s failed (%s)\n",
859 fname, smbcli_errstr(cli->tree));
864 printf("%6d %6d\r", i, maxfid-i);
868 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
869 printf("Failed to deltree \\maxfid - %s\n",
870 smbcli_errstr(cli->tree));
874 printf("maxfid test finished\n");
875 if (!torture_close_connection(cli)) {
879 #undef MAXFID_TEMPLATE
882 /* send smb negprot commands, not reading the response */
883 static BOOL run_negprot_nowait(void)
886 struct smbcli_state *cli, *cli2;
889 printf("starting negprot nowait test\n");
891 cli = open_nbt_connection();
896 printf("Filling send buffer\n");
898 for (i=0;i<1000;i++) {
899 struct smbcli_request *req;
900 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
901 smbcli_transport_process(cli->transport);
902 if (req->state == SMBCLI_REQUEST_ERROR) {
903 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
904 torture_close_connection(cli);
909 printf("Opening secondary connection\n");
910 if (!torture_open_connection(&cli2)) {
914 if (!torture_close_connection(cli)) {
918 if (!torture_close_connection(cli2)) {
922 printf("finished negprot nowait test\n");
929 This checks how the getatr calls works
931 static BOOL run_attrtest(void)
933 struct smbcli_state *cli;
936 const char *fname = "\\attrib123456789.tst";
939 printf("starting attrib test\n");
941 if (!torture_open_connection(&cli)) {
945 smbcli_unlink(cli->tree, fname);
946 fnum = smbcli_open(cli->tree, fname,
947 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
948 smbcli_close(cli->tree, fnum);
950 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
951 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
955 printf("New file time is %s", ctime(&t));
957 if (abs(t - time(NULL)) > 60*60*24*10) {
958 printf("ERROR: SMBgetatr bug. time is %s",
964 t2 = t-60*60*24; /* 1 day ago */
966 printf("Setting file time to %s", ctime(&t2));
968 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
969 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
973 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
974 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
978 printf("Retrieved file time as %s", ctime(&t));
981 printf("ERROR: getatr/setatr bug. times are\n%s",
983 printf("%s", ctime(&t2));
987 smbcli_unlink(cli->tree, fname);
989 if (!torture_close_connection(cli)) {
993 printf("attrib test finished\n");
1000 This checks a couple of trans2 calls
1002 static BOOL run_trans2test(void)
1004 struct smbcli_state *cli;
1007 time_t c_time, a_time, m_time, w_time, m_time2;
1008 const char *fname = "\\trans2.tst";
1009 const char *dname = "\\trans2";
1010 const char *fname2 = "\\trans2\\trans2.tst";
1012 BOOL correct = True;
1014 printf("starting trans2 test\n");
1016 if (!torture_open_connection(&cli)) {
1020 smbcli_unlink(cli->tree, fname);
1022 printf("Testing qfileinfo\n");
1024 fnum = smbcli_open(cli->tree, fname,
1025 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1026 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
1028 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
1032 printf("Testing NAME_INFO\n");
1034 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
1035 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
1039 if (!pname || strcmp(pname, fname)) {
1040 printf("qfilename gave different name? [%s] [%s]\n",
1045 smbcli_close(cli->tree, fnum);
1046 smbcli_unlink(cli->tree, fname);
1048 fnum = smbcli_open(cli->tree, fname,
1049 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1051 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1054 smbcli_close(cli->tree, fnum);
1056 printf("Checking for sticky create times\n");
1058 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1059 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
1062 if (c_time != m_time) {
1063 printf("create time=%s", ctime(&c_time));
1064 printf("modify time=%s", ctime(&m_time));
1065 printf("This system appears to have sticky create times\n");
1067 if (a_time % (60*60) == 0) {
1068 printf("access time=%s", ctime(&a_time));
1069 printf("This system appears to set a midnight access time\n");
1073 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1074 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1080 smbcli_unlink(cli->tree, fname);
1081 fnum = smbcli_open(cli->tree, fname,
1082 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1083 smbcli_close(cli->tree, fnum);
1084 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1085 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1088 if (w_time < 60*60*24*2) {
1089 printf("write time=%s", ctime(&w_time));
1090 printf("This system appears to set a initial 0 write time\n");
1095 smbcli_unlink(cli->tree, fname);
1098 /* check if the server updates the directory modification time
1099 when creating a new file */
1100 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1101 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
1105 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1106 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1110 fnum = smbcli_open(cli->tree, fname2,
1111 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1112 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
1113 smbcli_close(cli->tree, fnum);
1114 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
1115 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1118 if (m_time2 == m_time) {
1119 printf("This system does not update directory modification times\n");
1123 smbcli_unlink(cli->tree, fname2);
1124 smbcli_rmdir(cli->tree, dname);
1126 if (!torture_close_connection(cli)) {
1130 printf("trans2 test finished\n");
1137 /* FIRST_DESIRED_ACCESS 0xf019f */
1138 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1139 SEC_FILE_READ_EA| /* 0xf */ \
1140 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1141 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1142 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1143 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1144 /* SECOND_DESIRED_ACCESS 0xe0080 */
1145 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1146 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1147 SEC_STD_WRITE_OWNER /* 0xe0000 */
1150 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1151 READ_CONTROL|WRITE_DAC|\
1152 SEC_FILE_READ_DATA|\
1157 Test ntcreate calls made by xcopy
1159 static BOOL run_xcopy(void)
1161 struct smbcli_state *cli1;
1162 const char *fname = "\\test.txt";
1163 BOOL correct = True;
1166 printf("starting xcopy test\n");
1168 if (!torture_open_connection(&cli1)) {
1172 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1173 FIRST_DESIRED_ACCESS,
1174 FILE_ATTRIBUTE_ARCHIVE,
1175 NTCREATEX_SHARE_ACCESS_NONE,
1176 NTCREATEX_DISP_OVERWRITE_IF,
1180 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
1184 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1185 SECOND_DESIRED_ACCESS, 0,
1186 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1189 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
1193 if (!torture_close_connection(cli1)) {
1202 see how many RPC pipes we can open at once
1204 static BOOL run_pipe_number(void)
1206 struct smbcli_state *cli1;
1207 const char *pipe_name = "\\WKSSVC";
1211 printf("starting pipenumber test\n");
1212 if (!torture_open_connection(&cli1)) {
1217 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1218 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1221 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
1225 printf("%d\r", num_pipes);
1229 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
1230 torture_close_connection(cli1);
1238 open N connections to the server and just hold them open
1239 used for testing performance when there are N idle users
1242 static BOOL torture_holdcon(void)
1245 struct smbcli_state **cli;
1248 printf("Opening %d connections\n", torture_numops);
1250 cli = malloc_array_p(struct smbcli_state *, torture_numops);
1252 for (i=0;i<torture_numops;i++) {
1253 if (!torture_open_connection(&cli[i])) {
1256 printf("opened %d connections\r", i);
1260 printf("\nStarting pings\n");
1263 for (i=0;i<torture_numops;i++) {
1266 status = smbcli_chkpath(cli[i]->tree, "\\");
1267 if (!NT_STATUS_IS_OK(status)) {
1268 printf("Connection %d is dead\n", i);
1276 if (num_dead == torture_numops) {
1277 printf("All connections dead - finishing\n");
1289 Try with a wrong vuid and check error message.
1292 static BOOL run_vuidtest(void)
1294 struct smbcli_state *cli;
1295 const char *fname = "\\vuid.tst";
1298 time_t c_time, a_time, m_time;
1299 BOOL correct = True;
1304 printf("starting vuid test\n");
1306 if (!torture_open_connection(&cli)) {
1310 smbcli_unlink(cli->tree, fname);
1312 fnum = smbcli_open(cli->tree, fname,
1313 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1315 orig_vuid = cli->session->vuid;
1317 cli->session->vuid += 1234;
1319 printf("Testing qfileinfo with wrong vuid\n");
1321 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
1322 &size, &c_time, &a_time,
1323 &m_time, NULL, NULL))) {
1324 printf("ERROR: qfileinfo passed with wrong vuid\n");
1328 if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1329 NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
1330 !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1331 NT_STATUS_INVALID_HANDLE)) {
1332 printf("ERROR: qfileinfo should have returned DOS error "
1333 "ERRSRV:ERRbaduid\n but returned %s\n",
1334 smbcli_errstr(cli->tree));
1338 cli->session->vuid -= 1234;
1340 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1341 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
1345 smbcli_unlink(cli->tree, fname);
1347 if (!torture_close_connection(cli)) {
1351 printf("vuid test finished\n");
1357 Test open mode returns on read-only files.
1359 static BOOL run_opentest(void)
1361 static struct smbcli_state *cli1;
1362 static struct smbcli_state *cli2;
1363 const char *fname = "\\readonly.file";
1364 char *control_char_fname;
1368 BOOL correct = True;
1373 printf("starting open test\n");
1375 if (!torture_open_connection(&cli1)) {
1379 asprintf(&control_char_fname, "\\readonly.afile");
1380 for (i = 1; i <= 0x1f; i++) {
1381 control_char_fname[10] = i;
1382 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
1383 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1385 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
1386 NT_STATUS_OBJECT_NAME_INVALID)) {
1387 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
1388 smbcli_errstr(cli1->tree), i);
1393 smbcli_close(cli1->tree, fnum1);
1395 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
1396 smbcli_unlink(cli1->tree, control_char_fname);
1398 free(control_char_fname);
1401 printf("Create file with control char names passed.\n");
1403 smbcli_setatr(cli1->tree, fname, 0, 0);
1404 smbcli_unlink(cli1->tree, fname);
1406 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1408 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1412 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1413 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1417 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
1418 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
1419 CHECK_MAX_FAILURES(error_test1);
1423 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1425 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1426 CHECK_MAX_FAILURES(error_test1);
1430 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
1431 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1433 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
1434 NT_STATUS_ACCESS_DENIED)) {
1435 printf("correct error code ERRDOS/ERRnoaccess returned\n");
1438 printf("finished open test 1\n");
1440 smbcli_close(cli1->tree, fnum1);
1442 /* Now try not readonly and ensure ERRbadshare is returned. */
1444 smbcli_setatr(cli1->tree, fname, 0, 0);
1446 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1448 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1452 /* This will fail - but the error should be ERRshare. */
1453 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1455 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
1456 NT_STATUS_SHARING_VIOLATION)) {
1457 printf("correct error code ERRDOS/ERRbadshare returned\n");
1460 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1461 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1465 smbcli_unlink(cli1->tree, fname);
1467 printf("finished open test 2\n");
1469 /* Test truncate open disposition on file opened for read. */
1471 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1473 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1477 /* write 20 bytes. */
1479 memset(buf, '\0', 20);
1481 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1482 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1486 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1487 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1491 /* Ensure size == 20. */
1492 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1493 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1494 CHECK_MAX_FAILURES(error_test3);
1499 printf("(3) file size != 20\n");
1500 CHECK_MAX_FAILURES(error_test3);
1504 /* Now test if we can truncate a file opened for readonly. */
1506 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
1508 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1509 CHECK_MAX_FAILURES(error_test3);
1513 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1514 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1518 /* Ensure size == 0. */
1519 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1520 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1521 CHECK_MAX_FAILURES(error_test3);
1526 printf("(3) file size != 0\n");
1527 CHECK_MAX_FAILURES(error_test3);
1530 printf("finished open test 3\n");
1532 smbcli_unlink(cli1->tree, fname);
1535 printf("testing ctemp\n");
1536 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
1538 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1539 CHECK_MAX_FAILURES(error_test4);
1542 printf("ctemp gave path %s\n", tmp_path);
1543 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1544 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1546 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1547 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1550 /* Test the non-io opens... */
1552 if (!torture_open_connection(&cli2)) {
1556 smbcli_setatr(cli2->tree, fname, 0, 0);
1557 smbcli_unlink(cli2->tree, fname);
1559 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1561 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1562 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1565 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1566 CHECK_MAX_FAILURES(error_test10);
1570 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1571 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1573 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1574 CHECK_MAX_FAILURES(error_test10);
1578 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1579 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1582 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1583 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1587 printf("non-io open test #1 passed.\n");
1589 smbcli_unlink(cli1->tree, fname);
1591 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1593 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1594 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1597 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1598 CHECK_MAX_FAILURES(error_test20);
1602 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1603 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1606 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1607 CHECK_MAX_FAILURES(error_test20);
1611 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1612 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1615 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1616 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1620 printf("non-io open test #2 passed.\n");
1622 smbcli_unlink(cli1->tree, fname);
1624 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1626 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1627 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1630 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1631 CHECK_MAX_FAILURES(error_test30);
1635 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1636 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1639 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1640 CHECK_MAX_FAILURES(error_test30);
1644 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1645 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1648 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1649 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1653 printf("non-io open test #3 passed.\n");
1655 smbcli_unlink(cli1->tree, fname);
1657 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1659 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1660 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1663 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1664 CHECK_MAX_FAILURES(error_test40);
1668 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1669 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1672 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1673 CHECK_MAX_FAILURES(error_test40);
1677 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1679 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1680 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1684 printf("non-io open test #4 passed.\n");
1686 smbcli_unlink(cli1->tree, fname);
1688 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1690 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1691 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1694 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1695 CHECK_MAX_FAILURES(error_test50);
1699 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1700 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1703 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1704 CHECK_MAX_FAILURES(error_test50);
1708 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1709 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1713 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1714 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1718 printf("non-io open test #5 passed.\n");
1720 printf("TEST #6 testing 1 non-io open, one io open\n");
1722 smbcli_unlink(cli1->tree, fname);
1724 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1725 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1728 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1729 CHECK_MAX_FAILURES(error_test60);
1733 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1734 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1737 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1738 CHECK_MAX_FAILURES(error_test60);
1742 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1743 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1747 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1748 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1752 printf("non-io open test #6 passed.\n");
1754 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
1756 smbcli_unlink(cli1->tree, fname);
1758 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1759 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1762 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1763 CHECK_MAX_FAILURES(error_test70);
1767 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1768 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1771 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1772 CHECK_MAX_FAILURES(error_test70);
1776 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1778 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1779 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1783 printf("non-io open test #7 passed.\n");
1787 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1789 smbcli_unlink(cli1->tree, fname);
1791 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1793 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1797 /* write 20 bytes. */
1799 memset(buf, '\0', 20);
1801 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1802 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1806 /* Ensure size == 20. */
1807 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1808 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1809 CHECK_MAX_FAILURES(error_test80);
1814 printf("(8) file size != 20\n");
1815 CHECK_MAX_FAILURES(error_test80);
1819 /* Get an exclusive lock on the open file. */
1820 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1821 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1822 CHECK_MAX_FAILURES(error_test80);
1826 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1828 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1832 /* Ensure size == 0. */
1833 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1834 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1835 CHECK_MAX_FAILURES(error_test80);
1840 printf("(8) file size != 0\n");
1841 CHECK_MAX_FAILURES(error_test80);
1845 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1846 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1850 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1851 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1857 printf("open test #8 passed.\n");
1859 smbcli_unlink(cli1->tree, fname);
1861 if (!torture_close_connection(cli1)) {
1864 if (!torture_close_connection(cli2)) {
1873 sees what IOCTLs are supported
1875 BOOL torture_ioctl_test(void)
1877 struct smbcli_state *cli;
1878 uint16_t device, function;
1880 const char *fname = "\\ioctl.dat";
1882 union smb_ioctl parms;
1883 TALLOC_CTX *mem_ctx;
1885 if (!torture_open_connection(&cli)) {
1889 mem_ctx = talloc_init("ioctl_test");
1891 printf("starting ioctl test\n");
1893 smbcli_unlink(cli->tree, fname);
1895 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1897 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1901 parms.ioctl.level = RAW_IOCTL_IOCTL;
1902 parms.ioctl.in.fnum = fnum;
1903 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
1904 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1905 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
1907 for (device=0;device<0x100;device++) {
1908 printf("testing device=0x%x\n", device);
1909 for (function=0;function<0x100;function++) {
1910 parms.ioctl.in.request = (device << 16) | function;
1911 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1913 if (NT_STATUS_IS_OK(status)) {
1914 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
1915 device, function, (int)parms.ioctl.out.blob.length);
1920 if (!torture_close_connection(cli)) {
1929 tries variants of chkpath
1931 BOOL torture_chkpath_test(void)
1933 struct smbcli_state *cli;
1937 if (!torture_open_connection(&cli)) {
1941 printf("starting chkpath test\n");
1943 printf("Testing valid and invalid paths\n");
1945 /* cleanup from an old run */
1946 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1947 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1948 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1950 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1951 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1955 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1956 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1960 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1962 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
1965 smbcli_close(cli->tree, fnum);
1967 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1968 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1972 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1973 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1977 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1978 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1979 NT_STATUS_NOT_A_DIRECTORY);
1981 printf("* chkpath on a file should fail\n");
1985 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
1986 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1987 NT_STATUS_OBJECT_NAME_NOT_FOUND);
1989 printf("* chkpath on a non existent file should fail\n");
1993 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
1994 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1995 NT_STATUS_OBJECT_PATH_NOT_FOUND);
1997 printf("* chkpath on a non existent component should fail\n");
2001 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
2002 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
2003 smbcli_rmdir(cli->tree, "\\chkpath.dir");
2005 if (!torture_close_connection(cli)) {
2013 static void sigcont(int sig)
2017 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
2020 volatile pid_t *child_status;
2021 volatile BOOL *child_status_out;
2024 double start_time_limit = 10 + (torture_nprocs * 1.5);
2025 char **unc_list = NULL;
2027 int num_unc_names = 0;
2034 signal(SIGCONT, sigcont);
2036 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
2037 if (!child_status) {
2038 printf("Failed to setup shared memory\n");
2042 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
2043 if (!child_status_out) {
2044 printf("Failed to setup result status shared memory\n");
2048 p = lp_parm_string(-1, "torture", "unclist");
2050 unc_list = file_lines_load(p, &num_unc_names, NULL);
2051 if (!unc_list || num_unc_names <= 0) {
2052 printf("Failed to load unc names list from '%s'\n", p);
2057 for (i = 0; i < torture_nprocs; i++) {
2058 child_status[i] = 0;
2059 child_status_out[i] = True;
2062 tv = timeval_current();
2064 for (i=0;i<torture_nprocs;i++) {
2068 const char *hostname=NULL, *sharename;
2070 pid_t mypid = getpid();
2071 srandom(((int)mypid) ^ ((int)time(NULL)));
2073 asprintf(&myname, "CLIENT%d", i);
2074 lp_set_cmdline("netbios name", myname);
2079 if (!smbcli_parse_unc(unc_list[i % num_unc_names],
2080 NULL, &hostname, &sharename)) {
2081 printf("Failed to parse UNC name %s\n",
2082 unc_list[i % num_unc_names]);
2089 if (torture_open_connection_share(NULL,
2096 } else if (torture_open_connection(¤t_cli)) {
2100 printf("pid %d failed to start\n", (int)getpid());
2106 child_status[i] = getpid();
2110 if (child_status[i]) {
2111 printf("Child %d failed to start!\n", i);
2112 child_status_out[i] = 1;
2116 child_status_out[i] = fn(current_cli, i);
2123 for (i=0;i<torture_nprocs;i++) {
2124 if (child_status[i]) synccount++;
2126 if (synccount == torture_nprocs) break;
2128 } while (timeval_elapsed(&tv) < start_time_limit);
2130 if (synccount != torture_nprocs) {
2131 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
2133 return timeval_elapsed(&tv);
2136 printf("Starting %d clients\n", torture_nprocs);
2138 /* start the client load */
2139 tv = timeval_current();
2140 for (i=0;i<torture_nprocs;i++) {
2141 child_status[i] = 0;
2144 printf("%d clients started\n", torture_nprocs);
2148 for (i=0;i<torture_nprocs;i++) {
2150 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
2151 if (ret == -1 || WEXITSTATUS(status) != 0) {
2158 for (i=0;i<torture_nprocs;i++) {
2159 if (!child_status_out[i]) {
2163 return timeval_elapsed(&tv);
2166 #define FLAG_MULTIPROC 1
2171 BOOL (*multi_fn)(struct smbcli_state *, int );
2174 {"BASE-FDPASS", run_fdpasstest, 0},
2175 {"BASE-LOCK1", torture_locktest1, 0},
2176 {"BASE-LOCK2", torture_locktest2, 0},
2177 {"BASE-LOCK3", torture_locktest3, 0},
2178 {"BASE-LOCK4", torture_locktest4, 0},
2179 {"BASE-LOCK5", torture_locktest5, 0},
2180 {"BASE-LOCK6", torture_locktest6, 0},
2181 {"BASE-LOCK7", torture_locktest7, 0},
2182 {"BASE-UNLINK", torture_unlinktest, 0},
2183 {"BASE-ATTR", run_attrtest, 0},
2184 {"BASE-TRANS2", run_trans2test, 0},
2185 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
2186 {"BASE-DIR1", torture_dirtest1, 0},
2187 {"BASE-DIR2", torture_dirtest2, 0},
2188 {"BASE-DENY1", torture_denytest1, 0},
2189 {"BASE-DENY2", torture_denytest2, 0},
2190 {"BASE-DENY3", torture_denytest3, 0},
2191 {"BASE-DENYDOS", torture_denydos_sharing, 0},
2192 {"BASE-NTDENY1", NULL, torture_ntdenytest1},
2193 {"BASE-NTDENY2", torture_ntdenytest2, 0},
2194 {"BASE-TCON", run_tcon_test, 0},
2195 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
2196 {"BASE-VUID", run_vuidtest, 0},
2197 {"BASE-RW1", run_readwritetest, 0},
2198 {"BASE-OPEN", run_opentest, 0},
2199 {"BASE-DEFER_OPEN", NULL, run_deferopen},
2200 {"BASE-XCOPY", run_xcopy, 0},
2201 {"BASE-RENAME", torture_test_rename, 0},
2202 {"BASE-DELETE", torture_test_delete, 0},
2203 {"BASE-PROPERTIES", torture_test_properties, 0},
2204 {"BASE-MANGLE", torture_mangle, 0},
2205 {"BASE-OPENATTR", torture_openattrtest, 0},
2206 {"BASE-CHARSET", torture_charset, 0},
2207 {"BASE-CHKPATH", torture_chkpath_test, 0},
2208 {"BASE-SECLEAK", torture_sec_leak, 0},
2209 {"BASE-DISCONNECT", torture_disconnect, 0},
2210 {"BASE-DELAYWRITE", torture_delay_write, 0},
2212 /* benchmarking tests */
2213 {"BENCH-HOLDCON", torture_holdcon, 0},
2214 {"BENCH-NBENCH", torture_nbench, 0},
2215 {"BENCH-TORTURE", NULL, run_torture},
2216 {"BENCH-NBT", torture_bench_nbt, 0},
2217 {"BENCH-WINS", torture_bench_wins, 0},
2218 {"BENCH-RPC", torture_bench_rpc, 0},
2219 {"BENCH-CLDAP", torture_bench_cldap, 0},
2222 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
2223 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
2224 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
2225 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
2226 {"RAW-SEARCH", torture_raw_search, 0},
2227 {"RAW-CLOSE", torture_raw_close, 0},
2228 {"RAW-OPEN", torture_raw_open, 0},
2229 {"RAW-MKDIR", torture_raw_mkdir, 0},
2230 {"RAW-OPLOCK", torture_raw_oplock, 0},
2231 {"RAW-NOTIFY", torture_raw_notify, 0},
2232 {"RAW-MUX", torture_raw_mux, 0},
2233 {"RAW-IOCTL", torture_raw_ioctl, 0},
2234 {"RAW-CHKPATH", torture_raw_chkpath, 0},
2235 {"RAW-UNLINK", torture_raw_unlink, 0},
2236 {"RAW-READ", torture_raw_read, 0},
2237 {"RAW-WRITE", torture_raw_write, 0},
2238 {"RAW-LOCK", torture_raw_lock, 0},
2239 {"RAW-CONTEXT", torture_raw_context, 0},
2240 {"RAW-RENAME", torture_raw_rename, 0},
2241 {"RAW-SEEK", torture_raw_seek, 0},
2242 {"RAW-EAS", torture_raw_eas, 0},
2243 {"RAW-EAMAX", torture_max_eas, 0},
2244 {"RAW-STREAMS", torture_raw_streams, 0},
2245 {"RAW-ACLS", torture_raw_acls, 0},
2246 {"RAW-RAP", torture_raw_rap, 0},
2247 {"RAW-COMPOSITE", torture_raw_composite, 0},
2250 {"SMB2-CONNECT", torture_smb2_connect, 0},
2251 {"SMB2-SCAN", torture_smb2_scan, 0},
2252 {"SMB2-SCANGETINFO", torture_smb2_getinfo_scan, 0},
2253 {"SMB2-SCANSETINFO", torture_smb2_setinfo_scan, 0},
2254 {"SMB2-SCANFIND", torture_smb2_find_scan, 0},
2255 {"SMB2-GETINFO", torture_smb2_getinfo, 0},
2256 {"SMB2-SETINFO", torture_smb2_setinfo, 0},
2257 {"SMB2-FIND", torture_smb2_find, 0},
2259 /* protocol scanners */
2260 {"SCAN-TRANS2", torture_trans2_scan, 0},
2261 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2262 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2263 {"SCAN-SMB", torture_smb_scan, 0},
2264 {"SCAN-MAXFID", NULL, run_maxfidtest},
2265 {"SCAN-UTABLE", torture_utable, 0},
2266 {"SCAN-CASETABLE", torture_casetable, 0},
2267 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2268 {"SCAN-IOCTL", torture_ioctl_test, 0},
2269 {"SCAN-RAP", torture_rap_scan, 0},
2272 {"RPC-LSA", torture_rpc_lsa, 0},
2273 {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
2274 {"RPC-ECHO", torture_rpc_echo, 0},
2275 {"RPC-DFS", torture_rpc_dfs, 0},
2276 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2277 {"RPC-SAMR", torture_rpc_samr, 0},
2278 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2279 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2280 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2281 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2282 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2283 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2284 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2285 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2286 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2287 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2288 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2289 {"RPC-WINREG", torture_rpc_winreg, 0},
2290 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2291 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2292 {"RPC-REMACT", torture_rpc_remact, 0},
2293 {"RPC-MGMT", torture_rpc_mgmt, 0},
2294 {"RPC-SCANNER", torture_rpc_scanner, 0},
2295 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2296 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2297 {"RPC-MULTIBIND", torture_multi_bind, 0},
2298 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2299 {"RPC-CRACKNAMES", torture_rpc_drsuapi_cracknames, 0},
2300 {"RPC-ROT", torture_rpc_rot, 0},
2301 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2302 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2303 {"RPC-JOIN", torture_rpc_join, 0},
2304 {"RPC-DSSYNC", torture_rpc_dssync, 0},
2306 /* local (no server) testers */
2307 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2308 {"LOCAL-ICONV", torture_local_iconv, 0},
2309 {"LOCAL-TALLOC", torture_local_talloc, 0},
2310 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2311 {"LOCAL-IRPC", torture_local_irpc, 0},
2312 {"LOCAL-BINDING", torture_local_binding_string, 0},
2313 {"LOCAL-STRLIST", torture_local_util_strlist, 0},
2314 {"LOCAL-FILE", torture_local_util_file, 0},
2315 {"LOCAL-IDTREE", torture_local_idtree, 0},
2316 {"LOCAL-SOCKET", torture_local_socket, 0},
2317 {"LOCAL-PAC", torture_pac, 0},
2318 {"LOCAL-REGISTRY", torture_registry, 0},
2319 {"LOCAL-RESOLVE", torture_local_resolve, 0},
2320 {"LOCAL-SDDL", torture_local_sddl, 0},
2321 {"LOCAL-NDR", torture_local_ndr, 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-DGRAM", torture_nbt_dgram, 0},
2334 {"NBT-WINSREPLICATION", torture_nbt_winsreplication, 0},
2337 {"NET-USERINFO", torture_userinfo, 0},
2338 {"NET-USERADD", torture_useradd, 0},
2339 {"NET-USERDEL", torture_userdel, 0},
2340 {"NET-USERMOD", torture_usermod, 0},
2341 {"NET-DOMOPEN", torture_domainopen, 0},
2342 {"NET-API-LOOKUP", torture_lookup, 0},
2343 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2344 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2345 {"NET-API-CREATEUSER", torture_createuser, 0},
2346 {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
2347 {"NET-API-LISTSHARES", torture_listshares, 0},
2348 {"NET-API-DELSHARE", torture_delshare, 0},
2354 /****************************************************************************
2355 run a specified test or "ALL"
2356 ****************************************************************************/
2357 static BOOL run_test(const char *name)
2361 BOOL matched = False;
2363 if (strequal(name,"ALL")) {
2364 for (i=0;torture_ops[i].name;i++) {
2365 if (!run_test(torture_ops[i].name)) {
2372 for (i=0;torture_ops[i].name;i++) {
2373 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
2377 printf("Running %s\n", torture_ops[i].name);
2378 if (torture_ops[i].multi_fn) {
2379 BOOL result = False;
2380 t = torture_create_procs(torture_ops[i].multi_fn,
2384 printf("TEST %s FAILED!\n", torture_ops[i].name);
2388 struct timeval tv = timeval_current();
2389 if (!torture_ops[i].fn()) {
2391 printf("TEST %s FAILED!\n", torture_ops[i].name);
2393 t = timeval_elapsed(&tv);
2395 printf("%s took %g secs\n\n", torture_ops[i].name, t);
2400 printf("Unknown torture operation '%s'\n", name);
2407 static void parse_dns(const char *dns)
2409 char *userdn, *basedn, *secret;
2412 /* retrievieng the userdn */
2413 p = strchr_m(dns, '#');
2415 lp_set_cmdline("torture:ldap_userdn", "");
2416 lp_set_cmdline("torture:ldap_basedn", "");
2417 lp_set_cmdline("torture:ldap_secret", "");
2420 userdn = strndup(dns, p - dns);
2421 lp_set_cmdline("torture:ldap_userdn", userdn);
2423 /* retrieve the basedn */
2425 p = strchr_m(d, '#');
2427 lp_set_cmdline("torture:ldap_basedn", "");
2428 lp_set_cmdline("torture:ldap_secret", "");
2431 basedn = strndup(d, p - d);
2432 lp_set_cmdline("torture:ldap_basedn", basedn);
2434 /* retrieve the secret */
2437 lp_set_cmdline("torture:ldap_secret", "");
2441 lp_set_cmdline("torture:ldap_secret", secret);
2443 printf ("%s - %s - %s\n", userdn, basedn, secret);
2447 static void usage(poptContext pc)
2452 poptPrintUsage(pc, stdout, 0);
2455 printf("The binding format is:\n\n");
2457 printf(" TRANSPORT:host[flags]\n\n");
2459 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2461 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2462 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2463 printf(" string.\n\n");
2465 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2466 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2467 printf(" will be auto-determined.\n\n");
2469 printf(" other recognised flags are:\n\n");
2471 printf(" sign : enable ntlmssp signing\n");
2472 printf(" seal : enable ntlmssp sealing\n");
2473 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2474 printf(" validate: enable the NDR validator\n");
2475 printf(" print: enable debugging of the packets\n");
2476 printf(" bigendian: use bigendian RPC\n");
2477 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2479 printf(" For example, these all connect to the samr pipe:\n\n");
2481 printf(" ncacn_np:myserver\n");
2482 printf(" ncacn_np:myserver[samr]\n");
2483 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2484 printf(" ncacn_np:myserver[/pipe/samr]\n");
2485 printf(" ncacn_np:myserver[samr,sign,print]\n");
2486 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2487 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2488 printf(" ncacn_np:\n");
2489 printf(" ncacn_np:[/pipe/samr]\n\n");
2491 printf(" ncacn_ip_tcp:myserver\n");
2492 printf(" ncacn_ip_tcp:myserver[1024]\n");
2493 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2495 printf("The unc format is:\n\n");
2497 printf(" //server/share\n\n");
2499 printf("tests are:");
2500 for (i=0;torture_ops[i].name;i++) {
2501 if ((i%perline)==0) {
2504 printf("%s ", torture_ops[i].name);
2508 printf("default test is ALL\n");
2513 static BOOL is_binding_string(const char *binding_string)
2515 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2516 struct dcerpc_binding *binding_struct;
2519 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2521 talloc_free(mem_ctx);
2522 return NT_STATUS_IS_OK(status);
2525 static void max_runtime_handler(int sig)
2527 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2531 /****************************************************************************
2533 ****************************************************************************/
2534 int main(int argc,char *argv[])
2538 BOOL correct = True;
2543 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,OPT_DANGEROUS};
2544 struct poptOption long_options[] = {
2546 {"smb-ports", 'p', POPT_ARG_STRING, NULL, 0, "SMB ports", NULL},
2547 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2548 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2549 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2550 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2551 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2552 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2553 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2554 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2555 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2556 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2557 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2558 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2559 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2560 "set maximum time for smbtorture to live", "seconds"},
2562 POPT_COMMON_CONNECTION
2563 POPT_COMMON_CREDENTIALS
2568 #ifdef HAVE_SETBUFFER
2569 setbuffer(stdout, NULL, 0);
2572 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2573 POPT_CONTEXT_KEEP_FIRST);
2575 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2577 while((opt = poptGetNextOpt(pc)) != -1) {
2580 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2583 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2586 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2589 parse_dns(poptGetOptArg(pc));
2592 lp_set_cmdline("torture:dangerous", "Yes");
2595 d_printf("Invalid option %s: %s\n",
2596 poptBadOption(pc, 0), poptStrerror(opt));
2603 /* this will only work if nobody else uses alarm(),
2604 which means it won't work for some tests, but we
2605 can't use the event context method we use for smbd
2606 as so many tests create their own event
2607 context. This will at least catch most cases. */
2608 signal(SIGALRM, max_runtime_handler);
2612 smbtorture_init_subsystems;
2614 dcerpc_table_init();
2616 if (torture_seed == 0) {
2617 torture_seed = time(NULL);
2619 printf("Using seed %d\n", torture_seed);
2620 srandom(torture_seed);
2622 argv_new = discard_const_p(char *, poptGetArgs(pc));
2625 for (i=0; i<argc; i++) {
2626 if (argv_new[i] == NULL) {
2637 for(p = argv_new[1]; *p; p++) {
2642 /* see if its a RPC transport specifier */
2643 if (is_binding_string(argv_new[1])) {
2644 lp_set_cmdline("torture:binding", argv_new[1]);
2646 char *binding = NULL;
2647 const char *host = NULL, *share = NULL;
2649 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
2650 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
2654 lp_set_cmdline("torture:host", host);
2655 lp_set_cmdline("torture:share", share);
2656 asprintf(&binding, "ncacn_np:%s", host);
2657 lp_set_cmdline("torture:binding", binding);
2660 if (argc_new == 0) {
2661 printf("You must specify a test to run, or 'ALL'\n");
2663 for (i=2;i<argc_new;i++) {
2664 if (!run_test(argv_new[i])) {