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 "libcli/libcli.h"
29 #include "librpc/rpc/dcerpc_table.h"
31 #include "torture/basic/proto.h"
32 #include "torture/raw/proto.h"
33 #include "torture/smb2/proto.h"
34 #include "torture/rpc/proto.h"
35 #include "torture/rap/proto.h"
36 #include "torture/auth/proto.h"
37 #include "torture/local/proto.h"
38 #include "torture/nbench/proto.h"
39 #include "torture/ldap/proto.h"
40 #include "torture/com/proto.h"
41 #include "torture/nbt/proto.h"
42 #include "torture/libnet/proto.h"
45 int torture_numops=10;
46 int torture_entries=1000;
47 int torture_failures=1;
49 static int procnum; /* records process count number when forking */
50 static struct smbcli_state *current_cli;
51 static BOOL use_oplocks;
52 static BOOL use_level_II_oplocks;
54 BOOL torture_showall = False;
56 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
58 static struct smbcli_state *open_nbt_connection(void)
60 struct nbt_name called, calling;
61 struct smbcli_state *cli;
62 const char *host = lp_parm_string(-1, "torture", "host");
64 make_nbt_name_client(&calling, lp_netbios_name());
66 nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
68 cli = smbcli_state_init(NULL);
70 printf("Failed initialize smbcli_struct to connect with %s\n", host);
74 if (!smbcli_socket_connect(cli, host)) {
75 printf("Failed to connect with %s\n", host);
79 if (!smbcli_transport_establish(cli, &calling, &called)) {
80 printf("%s rejected the session\n",host);
91 BOOL torture_open_connection_share(TALLOC_CTX *mem_ctx,
92 struct smbcli_state **c,
94 const char *sharename,
95 struct event_context *ev)
99 status = smbcli_full_connection(mem_ctx, c, hostname,
101 cmdline_credentials, ev);
102 if (!NT_STATUS_IS_OK(status)) {
103 printf("Failed to open connection - %s\n", nt_errstr(status));
107 (*c)->transport->options.use_oplocks = use_oplocks;
108 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
113 BOOL torture_open_connection(struct smbcli_state **c)
115 const char *host = lp_parm_string(-1, "torture", "host");
116 const char *share = lp_parm_string(-1, "torture", "share");
118 return torture_open_connection_share(NULL, c, host, share, NULL);
123 BOOL torture_close_connection(struct smbcli_state *c)
127 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
128 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
135 /* open a rpc connection to the chosen binding string */
136 NTSTATUS torture_rpc_connection(TALLOC_CTX *parent_ctx,
137 struct dcerpc_pipe **p,
138 const struct dcerpc_interface_table *table)
141 const char *binding = lp_parm_string(-1, "torture", "binding");
144 printf("You must specify a ncacn binding string\n");
145 return NT_STATUS_INVALID_PARAMETER;
148 status = dcerpc_pipe_connect(parent_ctx,
150 cmdline_credentials, NULL);
155 /* open a rpc connection to a specific transport */
156 NTSTATUS torture_rpc_connection_transport(TALLOC_CTX *parent_ctx,
157 struct dcerpc_pipe **p,
158 const struct dcerpc_interface_table *table,
159 enum dcerpc_transport_t transport)
162 const char *binding = lp_parm_string(-1, "torture", "binding");
163 struct dcerpc_binding *b;
164 TALLOC_CTX *mem_ctx = talloc_named(parent_ctx, 0, "torture_rpc_connection_smb");
167 printf("You must specify a ncacn binding string\n");
168 talloc_free(mem_ctx);
169 return NT_STATUS_INVALID_PARAMETER;
172 status = dcerpc_parse_binding(mem_ctx, binding, &b);
173 if (!NT_STATUS_IS_OK(status)) {
174 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
175 talloc_free(mem_ctx);
179 b->transport = transport;
181 status = dcerpc_pipe_connect_b(mem_ctx, p, b, table,
182 cmdline_credentials, NULL);
184 if (NT_STATUS_IS_OK(status)) {
185 *p = talloc_reference(parent_ctx, *p);
189 talloc_free(mem_ctx);
193 /* check if the server produced the expected error code */
194 BOOL check_error(const char *location, struct smbcli_state *c,
195 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
199 status = smbcli_nt_error(c->tree);
200 if (NT_STATUS_IS_DOS(status)) {
202 class = NT_STATUS_DOS_CLASS(status);
203 num = NT_STATUS_DOS_CODE(status);
204 if (eclass != class || ecode != num) {
205 printf("unexpected error code %s\n", nt_errstr(status));
206 printf(" expected %s or %s (at %s)\n",
207 nt_errstr(NT_STATUS_DOS(eclass, ecode)),
208 nt_errstr(nterr), location);
212 if (!NT_STATUS_EQUAL(nterr, status)) {
213 printf("unexpected error code %s\n", nt_errstr(status));
214 printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
223 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
225 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
226 if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
232 static BOOL rw_torture(struct smbcli_state *c)
234 const char *lockfname = "\\torture.lck";
238 pid_t pid2, pid = getpid();
243 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
246 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
248 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
253 for (i=0;i<torture_numops;i++) {
254 uint_t n = (uint_t)random()%10;
256 printf("%d\r", i); fflush(stdout);
258 asprintf(&fname, "\\torture.%u", n);
260 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
264 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
266 printf("open failed (%s)\n", smbcli_errstr(c->tree));
271 if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
272 printf("write failed (%s)\n", smbcli_errstr(c->tree));
277 if (smbcli_write(c->tree, fnum, 0, buf,
278 sizeof(pid)+(j*sizeof(buf)),
279 sizeof(buf)) != sizeof(buf)) {
280 printf("write failed (%s)\n", smbcli_errstr(c->tree));
287 if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
288 printf("read failed (%s)\n", smbcli_errstr(c->tree));
293 printf("data corruption!\n");
297 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
298 printf("close failed (%s)\n", smbcli_errstr(c->tree));
302 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
303 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
307 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
308 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
314 smbcli_close(c->tree, fnum2);
315 smbcli_unlink(c->tree, lockfname);
322 static BOOL run_torture(struct smbcli_state *cli, int dummy)
326 ret = rw_torture(cli);
328 if (!torture_close_connection(cli)) {
336 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
338 const char *lockfname = "\\torture2.lck";
343 uint8_t buf_rd[131072];
345 ssize_t bytes_read, bytes_written;
347 if (smbcli_deltree(c1->tree, lockfname) == -1) {
348 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
351 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
354 printf("first open read/write of %s failed (%s)\n",
355 lockfname, smbcli_errstr(c1->tree));
358 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
361 printf("second open read-only of %s failed (%s)\n",
362 lockfname, smbcli_errstr(c2->tree));
363 smbcli_close(c1->tree, fnum1);
367 printf("Checking data integrity over %d ops\n", torture_numops);
369 for (i=0;i<torture_numops;i++)
371 size_t buf_size = ((uint_t)random()%(sizeof(buf)-1))+ 1;
373 printf("%d\r", i); fflush(stdout);
376 generate_random_buffer(buf, buf_size);
378 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
379 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
380 printf("wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
385 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
386 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
387 printf("read %d, expected %d\n", (int)bytes_read, (int)buf_size);
392 if (memcmp(buf_rd, buf, buf_size) != 0)
394 printf("read/write compare failed\n");
400 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
401 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
404 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
405 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
409 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
410 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
417 #define BOOLSTR(b) ((b) ? "Yes" : "No")
419 static BOOL run_readwritetest(void)
421 struct smbcli_state *cli1, *cli2;
422 BOOL test1, test2 = True;
424 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
428 printf("starting readwritetest\n");
430 test1 = rw_torture2(cli1, cli2);
431 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
434 test2 = rw_torture2(cli1, cli1);
435 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
438 if (!torture_close_connection(cli1)) {
442 if (!torture_close_connection(cli2)) {
446 return (test1 && test2);
450 this checks to see if a secondary tconx can use open files from an
453 static BOOL run_tcon_test(void)
455 struct smbcli_state *cli;
456 const char *fname = "\\tcontest.tmp";
458 uint16_t cnum1, cnum2, cnum3;
459 uint16_t vuid1, vuid2;
462 struct smbcli_tree *tree1;
463 const char *host = lp_parm_string(-1, "torture", "host");
464 const char *share = lp_parm_string(-1, "torture", "share");
465 const char *password = lp_parm_string(-1, "torture", "password");
467 if (!torture_open_connection(&cli)) {
471 printf("starting tcontest\n");
473 if (smbcli_deltree(cli->tree, fname) == -1) {
474 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
477 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
479 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
483 cnum1 = cli->tree->tid;
484 vuid1 = cli->session->vuid;
486 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
487 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
488 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
492 tree1 = cli->tree; /* save old tree connection */
493 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
494 printf("%s refused 2nd tree connect (%s)\n", host,
495 smbcli_errstr(cli->tree));
500 cnum2 = cli->tree->tid;
501 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
502 vuid2 = cli->session->vuid + 1;
504 /* try a write with the wrong tid */
505 cli->tree->tid = cnum2;
507 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
508 printf("* server allows write with wrong TID\n");
511 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
515 /* try a write with an invalid tid */
516 cli->tree->tid = cnum3;
518 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
519 printf("* server allows write with invalid TID\n");
522 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
525 /* try a write with an invalid vuid */
526 cli->session->vuid = vuid2;
527 cli->tree->tid = cnum1;
529 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
530 printf("* server allows write with invalid VUID\n");
533 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
536 cli->session->vuid = vuid1;
537 cli->tree->tid = cnum1;
539 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
540 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
544 cli->tree->tid = cnum2;
546 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
547 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
551 cli->tree = tree1; /* restore initial tree */
552 cli->tree->tid = cnum1;
554 smbcli_unlink(tree1, fname);
556 if (!torture_close_connection(cli)) {
565 static BOOL tcon_devtest(struct smbcli_state *cli,
566 const char *myshare, const char *devtype,
567 NTSTATUS expected_error)
571 const char *password = lp_parm_string(-1, "torture", "password");
573 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
576 printf("Trying share %s with devtype %s\n", myshare, devtype);
578 if (NT_STATUS_IS_OK(expected_error)) {
582 printf("tconX to share %s with type %s "
583 "should have succeeded but failed\n",
590 printf("tconx to share %s with type %s "
591 "should have failed but succeeded\n",
595 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
599 printf("Returned unexpected error\n");
608 checks for correct tconX support
610 static BOOL run_tcon_devtype_test(void)
612 struct smbcli_state *cli1 = NULL;
615 const char *host = lp_parm_string(-1, "torture", "host");
616 const char *share = lp_parm_string(-1, "torture", "share");
618 status = smbcli_full_connection(NULL,
621 cmdline_credentials, NULL);
623 if (!NT_STATUS_IS_OK(status)) {
624 printf("could not open connection\n");
628 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
631 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
634 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
637 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
640 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
643 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
646 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
649 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
652 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
655 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
661 printf("Passed tcondevtest\n");
668 test whether fnums and tids open on one VC are available on another (a major
671 static BOOL run_fdpasstest(void)
673 struct smbcli_state *cli1, *cli2;
674 const char *fname = "\\fdpass.tst";
678 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
682 printf("starting fdpasstest\n");
684 smbcli_unlink(cli1->tree, fname);
686 printf("Opening a file on connection 1\n");
688 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
690 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
694 printf("writing to file on connection 1\n");
696 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
697 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
701 oldtid = cli2->tree->tid;
702 cli2->session->vuid = cli1->session->vuid;
703 cli2->tree->tid = cli1->tree->tid;
704 cli2->session->pid = cli1->session->pid;
706 printf("reading from file on connection 2\n");
708 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
709 printf("read succeeded! nasty security hole [%s]\n",
714 smbcli_close(cli1->tree, fnum1);
715 smbcli_unlink(cli1->tree, fname);
717 cli2->tree->tid = oldtid;
719 torture_close_connection(cli1);
720 torture_close_connection(cli2);
722 printf("finished fdpasstest\n");
728 test the timing of deferred open requests
730 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
732 const char *fname = "\\defer_open_test.dat";
738 printf("failed to connect\n");
742 printf("Testing deferred open requests.\n");
749 tv = timeval_current();
750 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
752 FILE_ATTRIBUTE_NORMAL,
753 NTCREATEX_SHARE_ACCESS_NONE,
754 NTCREATEX_DISP_OPEN_IF, 0, 0);
758 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
759 double e = timeval_elapsed(&tv);
760 if (e < 0.5 || e > 1.5) {
761 fprintf(stderr,"Timing incorrect %.2f violation\n",
765 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
768 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
772 printf("pid %u open %d\n", getpid(), i);
776 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
777 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
783 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
784 /* All until the last unlink will fail with sharing violation. */
785 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
786 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
791 printf("deferred test finished\n");
792 if (!torture_close_connection(cli)) {
799 test how many open files this server supports on the one socket
801 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
803 #define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
805 int fnums[0x11000], i;
806 int retries=4, maxfid;
810 printf("failed to connect\n");
814 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
815 printf("Failed to deltree \\maxfid - %s\n",
816 smbcli_errstr(cli->tree));
819 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
820 printf("Failed to mkdir \\maxfid, error=%s\n",
821 smbcli_errstr(cli->tree));
825 printf("Testing maximum number of open files\n");
827 for (i=0; i<0x11000; i++) {
829 asprintf(&fname, "\\maxfid\\fid%d", i/1000);
830 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
831 printf("Failed to mkdir %s, error=%s\n",
832 fname, smbcli_errstr(cli->tree));
837 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
838 if ((fnums[i] = smbcli_open(cli->tree, fname,
839 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
841 printf("open of %s failed (%s)\n",
842 fname, smbcli_errstr(cli->tree));
843 printf("maximum fnum is %d\n", i);
854 printf("cleaning up\n");
855 for (i=0;i<maxfid/2;i++) {
856 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
857 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
858 printf("Close of fnum %d failed - %s\n", fnums[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 asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
868 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
869 printf("Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
871 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
872 printf("unlink of %s failed (%s)\n",
873 fname, smbcli_errstr(cli->tree));
878 printf("%6d %6d\r", i, maxfid-i);
882 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
883 printf("Failed to deltree \\maxfid - %s\n",
884 smbcli_errstr(cli->tree));
888 printf("maxfid test finished\n");
889 if (!torture_close_connection(cli)) {
893 #undef MAXFID_TEMPLATE
896 /* send smb negprot commands, not reading the response */
897 static BOOL run_negprot_nowait(void)
900 struct smbcli_state *cli, *cli2;
903 printf("starting negprot nowait test\n");
905 cli = open_nbt_connection();
910 printf("Filling send buffer\n");
912 for (i=0;i<1000;i++) {
913 struct smbcli_request *req;
914 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
915 smbcli_transport_process(cli->transport);
916 if (req->state == SMBCLI_REQUEST_ERROR) {
917 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
918 torture_close_connection(cli);
923 printf("Opening secondary connection\n");
924 if (!torture_open_connection(&cli2)) {
928 if (!torture_close_connection(cli)) {
932 if (!torture_close_connection(cli2)) {
936 printf("finished negprot nowait test\n");
943 This checks how the getatr calls works
945 static BOOL run_attrtest(void)
947 struct smbcli_state *cli;
950 const char *fname = "\\attrib123456789.tst";
953 printf("starting attrib test\n");
955 if (!torture_open_connection(&cli)) {
959 smbcli_unlink(cli->tree, fname);
960 fnum = smbcli_open(cli->tree, fname,
961 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
962 smbcli_close(cli->tree, fnum);
964 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
965 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
969 printf("New file time is %s", ctime(&t));
971 if (abs(t - time(NULL)) > 60*60*24*10) {
972 printf("ERROR: SMBgetatr bug. time is %s",
978 t2 = t-60*60*24; /* 1 day ago */
980 printf("Setting file time to %s", ctime(&t2));
982 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
983 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
987 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
988 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
992 printf("Retrieved file time as %s", ctime(&t));
995 printf("ERROR: getatr/setatr bug. times are\n%s",
997 printf("%s", ctime(&t2));
1001 smbcli_unlink(cli->tree, fname);
1003 if (!torture_close_connection(cli)) {
1007 printf("attrib test finished\n");
1014 This checks a couple of trans2 calls
1016 static BOOL run_trans2test(void)
1018 struct smbcli_state *cli;
1021 time_t c_time, a_time, m_time, w_time, m_time2;
1022 const char *fname = "\\trans2.tst";
1023 const char *dname = "\\trans2";
1024 const char *fname2 = "\\trans2\\trans2.tst";
1026 BOOL correct = True;
1028 printf("starting trans2 test\n");
1030 if (!torture_open_connection(&cli)) {
1034 smbcli_unlink(cli->tree, fname);
1036 printf("Testing qfileinfo\n");
1038 fnum = smbcli_open(cli->tree, fname,
1039 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1040 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
1042 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
1046 printf("Testing NAME_INFO\n");
1048 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
1049 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
1053 if (!pname || strcmp(pname, fname)) {
1054 printf("qfilename gave different name? [%s] [%s]\n",
1059 smbcli_close(cli->tree, fnum);
1060 smbcli_unlink(cli->tree, fname);
1062 fnum = smbcli_open(cli->tree, fname,
1063 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1065 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1068 smbcli_close(cli->tree, fnum);
1070 printf("Checking for sticky create times\n");
1072 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1073 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
1076 if (c_time != m_time) {
1077 printf("create time=%s", ctime(&c_time));
1078 printf("modify time=%s", ctime(&m_time));
1079 printf("This system appears to have sticky create times\n");
1081 if (a_time % (60*60) == 0) {
1082 printf("access time=%s", ctime(&a_time));
1083 printf("This system appears to set a midnight access time\n");
1087 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1088 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1094 smbcli_unlink(cli->tree, fname);
1095 fnum = smbcli_open(cli->tree, fname,
1096 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1097 smbcli_close(cli->tree, fnum);
1098 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1099 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1102 if (w_time < 60*60*24*2) {
1103 printf("write time=%s", ctime(&w_time));
1104 printf("This system appears to set a initial 0 write time\n");
1109 smbcli_unlink(cli->tree, fname);
1112 /* check if the server updates the directory modification time
1113 when creating a new file */
1114 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1115 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
1119 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1120 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1124 fnum = smbcli_open(cli->tree, fname2,
1125 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1126 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
1127 smbcli_close(cli->tree, fnum);
1128 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
1129 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1132 if (m_time2 == m_time) {
1133 printf("This system does not update directory modification times\n");
1137 smbcli_unlink(cli->tree, fname2);
1138 smbcli_rmdir(cli->tree, dname);
1140 if (!torture_close_connection(cli)) {
1144 printf("trans2 test finished\n");
1151 /* FIRST_DESIRED_ACCESS 0xf019f */
1152 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1153 SEC_FILE_READ_EA| /* 0xf */ \
1154 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1155 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1156 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1157 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1158 /* SECOND_DESIRED_ACCESS 0xe0080 */
1159 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1160 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1161 SEC_STD_WRITE_OWNER /* 0xe0000 */
1164 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1165 READ_CONTROL|WRITE_DAC|\
1166 SEC_FILE_READ_DATA|\
1171 Test ntcreate calls made by xcopy
1173 static BOOL run_xcopy(void)
1175 struct smbcli_state *cli1;
1176 const char *fname = "\\test.txt";
1177 BOOL correct = True;
1180 printf("starting xcopy test\n");
1182 if (!torture_open_connection(&cli1)) {
1186 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1187 FIRST_DESIRED_ACCESS,
1188 FILE_ATTRIBUTE_ARCHIVE,
1189 NTCREATEX_SHARE_ACCESS_NONE,
1190 NTCREATEX_DISP_OVERWRITE_IF,
1194 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
1198 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1199 SECOND_DESIRED_ACCESS, 0,
1200 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1203 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
1207 if (!torture_close_connection(cli1)) {
1216 see how many RPC pipes we can open at once
1218 static BOOL run_pipe_number(void)
1220 struct smbcli_state *cli1;
1221 const char *pipe_name = "\\WKSSVC";
1225 printf("starting pipenumber test\n");
1226 if (!torture_open_connection(&cli1)) {
1231 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1232 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1235 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
1239 printf("%d\r", num_pipes);
1243 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
1244 torture_close_connection(cli1);
1252 open N connections to the server and just hold them open
1253 used for testing performance when there are N idle users
1256 static BOOL torture_holdcon(void)
1259 struct smbcli_state **cli;
1262 printf("Opening %d connections\n", torture_numops);
1264 cli = malloc_array_p(struct smbcli_state *, torture_numops);
1266 for (i=0;i<torture_numops;i++) {
1267 if (!torture_open_connection(&cli[i])) {
1270 printf("opened %d connections\r", i);
1274 printf("\nStarting pings\n");
1277 for (i=0;i<torture_numops;i++) {
1280 status = smbcli_chkpath(cli[i]->tree, "\\");
1281 if (!NT_STATUS_IS_OK(status)) {
1282 printf("Connection %d is dead\n", i);
1290 if (num_dead == torture_numops) {
1291 printf("All connections dead - finishing\n");
1303 Try with a wrong vuid and check error message.
1306 static BOOL run_vuidtest(void)
1308 struct smbcli_state *cli;
1309 const char *fname = "\\vuid.tst";
1312 time_t c_time, a_time, m_time;
1313 BOOL correct = True;
1318 printf("starting vuid test\n");
1320 if (!torture_open_connection(&cli)) {
1324 smbcli_unlink(cli->tree, fname);
1326 fnum = smbcli_open(cli->tree, fname,
1327 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1329 orig_vuid = cli->session->vuid;
1331 cli->session->vuid += 1234;
1333 printf("Testing qfileinfo with wrong vuid\n");
1335 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
1336 &size, &c_time, &a_time,
1337 &m_time, NULL, NULL))) {
1338 printf("ERROR: qfileinfo passed with wrong vuid\n");
1342 if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1343 NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
1344 !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1345 NT_STATUS_INVALID_HANDLE)) {
1346 printf("ERROR: qfileinfo should have returned DOS error "
1347 "ERRSRV:ERRbaduid\n but returned %s\n",
1348 smbcli_errstr(cli->tree));
1352 cli->session->vuid -= 1234;
1354 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1355 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
1359 smbcli_unlink(cli->tree, fname);
1361 if (!torture_close_connection(cli)) {
1365 printf("vuid test finished\n");
1371 Test open mode returns on read-only files.
1373 static BOOL run_opentest(void)
1375 static struct smbcli_state *cli1;
1376 static struct smbcli_state *cli2;
1377 const char *fname = "\\readonly.file";
1378 char *control_char_fname;
1382 BOOL correct = True;
1387 printf("starting open test\n");
1389 if (!torture_open_connection(&cli1)) {
1393 asprintf(&control_char_fname, "\\readonly.afile");
1394 for (i = 1; i <= 0x1f; i++) {
1395 control_char_fname[10] = i;
1396 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
1397 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1399 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
1400 NT_STATUS_OBJECT_NAME_INVALID)) {
1401 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
1402 smbcli_errstr(cli1->tree), i);
1407 smbcli_close(cli1->tree, fnum1);
1409 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
1410 smbcli_unlink(cli1->tree, control_char_fname);
1412 free(control_char_fname);
1415 printf("Create file with control char names passed.\n");
1417 smbcli_setatr(cli1->tree, fname, 0, 0);
1418 smbcli_unlink(cli1->tree, fname);
1420 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1422 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1426 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1427 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1431 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
1432 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
1433 CHECK_MAX_FAILURES(error_test1);
1437 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1439 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1440 CHECK_MAX_FAILURES(error_test1);
1444 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
1445 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1447 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
1448 NT_STATUS_ACCESS_DENIED)) {
1449 printf("correct error code ERRDOS/ERRnoaccess returned\n");
1452 printf("finished open test 1\n");
1454 smbcli_close(cli1->tree, fnum1);
1456 /* Now try not readonly and ensure ERRbadshare is returned. */
1458 smbcli_setatr(cli1->tree, fname, 0, 0);
1460 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1462 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1466 /* This will fail - but the error should be ERRshare. */
1467 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1469 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
1470 NT_STATUS_SHARING_VIOLATION)) {
1471 printf("correct error code ERRDOS/ERRbadshare returned\n");
1474 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1475 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1479 smbcli_unlink(cli1->tree, fname);
1481 printf("finished open test 2\n");
1483 /* Test truncate open disposition on file opened for read. */
1485 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1487 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1491 /* write 20 bytes. */
1493 memset(buf, '\0', 20);
1495 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1496 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1500 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1501 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1505 /* Ensure size == 20. */
1506 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1507 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1508 CHECK_MAX_FAILURES(error_test3);
1513 printf("(3) file size != 20\n");
1514 CHECK_MAX_FAILURES(error_test3);
1518 /* Now test if we can truncate a file opened for readonly. */
1520 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
1522 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1523 CHECK_MAX_FAILURES(error_test3);
1527 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1528 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1532 /* Ensure size == 0. */
1533 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1534 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1535 CHECK_MAX_FAILURES(error_test3);
1540 printf("(3) file size != 0\n");
1541 CHECK_MAX_FAILURES(error_test3);
1544 printf("finished open test 3\n");
1546 smbcli_unlink(cli1->tree, fname);
1549 printf("testing ctemp\n");
1550 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
1552 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1553 CHECK_MAX_FAILURES(error_test4);
1556 printf("ctemp gave path %s\n", tmp_path);
1557 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1558 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1560 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1561 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1564 /* Test the non-io opens... */
1566 if (!torture_open_connection(&cli2)) {
1570 smbcli_setatr(cli2->tree, fname, 0, 0);
1571 smbcli_unlink(cli2->tree, fname);
1573 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1575 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1576 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1579 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1580 CHECK_MAX_FAILURES(error_test10);
1584 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1585 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1587 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1588 CHECK_MAX_FAILURES(error_test10);
1592 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1593 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1596 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1597 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1601 printf("non-io open test #1 passed.\n");
1603 smbcli_unlink(cli1->tree, fname);
1605 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1607 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1608 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1611 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1612 CHECK_MAX_FAILURES(error_test20);
1616 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1617 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1620 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1621 CHECK_MAX_FAILURES(error_test20);
1625 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1626 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1629 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1630 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1634 printf("non-io open test #2 passed.\n");
1636 smbcli_unlink(cli1->tree, fname);
1638 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1640 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1641 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1644 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1645 CHECK_MAX_FAILURES(error_test30);
1649 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1650 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1653 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1654 CHECK_MAX_FAILURES(error_test30);
1658 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1659 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1662 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1663 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1667 printf("non-io open test #3 passed.\n");
1669 smbcli_unlink(cli1->tree, fname);
1671 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1673 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1674 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1677 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1678 CHECK_MAX_FAILURES(error_test40);
1682 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1683 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1686 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1687 CHECK_MAX_FAILURES(error_test40);
1691 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1693 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1694 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1698 printf("non-io open test #4 passed.\n");
1700 smbcli_unlink(cli1->tree, fname);
1702 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1704 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1705 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1708 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1709 CHECK_MAX_FAILURES(error_test50);
1713 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1714 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1717 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1718 CHECK_MAX_FAILURES(error_test50);
1722 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1723 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1727 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1728 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1732 printf("non-io open test #5 passed.\n");
1734 printf("TEST #6 testing 1 non-io open, one io open\n");
1736 smbcli_unlink(cli1->tree, fname);
1738 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1739 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1742 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1743 CHECK_MAX_FAILURES(error_test60);
1747 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1748 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1751 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1752 CHECK_MAX_FAILURES(error_test60);
1756 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1757 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1761 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1762 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1766 printf("non-io open test #6 passed.\n");
1768 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
1770 smbcli_unlink(cli1->tree, fname);
1772 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1773 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1776 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1777 CHECK_MAX_FAILURES(error_test70);
1781 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1782 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1785 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1786 CHECK_MAX_FAILURES(error_test70);
1790 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1792 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1793 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1797 printf("non-io open test #7 passed.\n");
1801 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1803 smbcli_unlink(cli1->tree, fname);
1805 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1807 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1811 /* write 20 bytes. */
1813 memset(buf, '\0', 20);
1815 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1816 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1820 /* Ensure size == 20. */
1821 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1822 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1823 CHECK_MAX_FAILURES(error_test80);
1828 printf("(8) file size != 20\n");
1829 CHECK_MAX_FAILURES(error_test80);
1833 /* Get an exclusive lock on the open file. */
1834 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1835 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1836 CHECK_MAX_FAILURES(error_test80);
1840 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1842 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1846 /* Ensure size == 0. */
1847 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1848 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1849 CHECK_MAX_FAILURES(error_test80);
1854 printf("(8) file size != 0\n");
1855 CHECK_MAX_FAILURES(error_test80);
1859 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1860 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1864 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1865 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1871 printf("open test #8 passed.\n");
1873 smbcli_unlink(cli1->tree, fname);
1875 if (!torture_close_connection(cli1)) {
1878 if (!torture_close_connection(cli2)) {
1887 sees what IOCTLs are supported
1889 BOOL torture_ioctl_test(void)
1891 struct smbcli_state *cli;
1892 uint16_t device, function;
1894 const char *fname = "\\ioctl.dat";
1896 union smb_ioctl parms;
1897 TALLOC_CTX *mem_ctx;
1899 if (!torture_open_connection(&cli)) {
1903 mem_ctx = talloc_init("ioctl_test");
1905 printf("starting ioctl test\n");
1907 smbcli_unlink(cli->tree, fname);
1909 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1911 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1915 parms.ioctl.level = RAW_IOCTL_IOCTL;
1916 parms.ioctl.in.fnum = fnum;
1917 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
1918 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1919 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
1921 for (device=0;device<0x100;device++) {
1922 printf("testing device=0x%x\n", device);
1923 for (function=0;function<0x100;function++) {
1924 parms.ioctl.in.request = (device << 16) | function;
1925 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1927 if (NT_STATUS_IS_OK(status)) {
1928 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
1929 device, function, (int)parms.ioctl.out.blob.length);
1934 if (!torture_close_connection(cli)) {
1943 tries variants of chkpath
1945 BOOL torture_chkpath_test(void)
1947 struct smbcli_state *cli;
1951 if (!torture_open_connection(&cli)) {
1955 printf("starting chkpath test\n");
1957 printf("Testing valid and invalid paths\n");
1959 /* cleanup from an old run */
1960 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1961 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1962 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1964 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1965 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1969 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1970 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1974 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1976 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
1979 smbcli_close(cli->tree, fnum);
1981 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1982 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1986 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1987 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1991 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1992 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1993 NT_STATUS_NOT_A_DIRECTORY);
1995 printf("* chkpath on a file should fail\n");
1999 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
2000 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2001 NT_STATUS_OBJECT_NAME_NOT_FOUND);
2003 printf("* chkpath on a non existent file should fail\n");
2007 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
2008 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2009 NT_STATUS_OBJECT_PATH_NOT_FOUND);
2011 printf("* chkpath on a non existent component should fail\n");
2015 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
2016 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
2017 smbcli_rmdir(cli->tree, "\\chkpath.dir");
2019 if (!torture_close_connection(cli)) {
2027 static void sigcont(int sig)
2031 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
2034 volatile pid_t *child_status;
2035 volatile BOOL *child_status_out;
2038 double start_time_limit = 10 + (torture_nprocs * 1.5);
2039 char **unc_list = NULL;
2041 int num_unc_names = 0;
2048 signal(SIGCONT, sigcont);
2050 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
2051 if (!child_status) {
2052 printf("Failed to setup shared memory\n");
2056 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
2057 if (!child_status_out) {
2058 printf("Failed to setup result status shared memory\n");
2062 p = lp_parm_string(-1, "torture", "unclist");
2064 unc_list = file_lines_load(p, &num_unc_names, NULL);
2065 if (!unc_list || num_unc_names <= 0) {
2066 printf("Failed to load unc names list from '%s'\n", p);
2071 for (i = 0; i < torture_nprocs; i++) {
2072 child_status[i] = 0;
2073 child_status_out[i] = True;
2076 tv = timeval_current();
2078 for (i=0;i<torture_nprocs;i++) {
2082 const char *hostname=NULL, *sharename;
2084 pid_t mypid = getpid();
2085 srandom(((int)mypid) ^ ((int)time(NULL)));
2087 asprintf(&myname, "CLIENT%d", i);
2088 lp_set_cmdline("netbios name", myname);
2093 if (!smbcli_parse_unc(unc_list[i % num_unc_names],
2094 NULL, &hostname, &sharename)) {
2095 printf("Failed to parse UNC name %s\n",
2096 unc_list[i % num_unc_names]);
2103 if (torture_open_connection_share(NULL,
2110 } else if (torture_open_connection(¤t_cli)) {
2114 printf("pid %d failed to start\n", (int)getpid());
2120 child_status[i] = getpid();
2124 if (child_status[i]) {
2125 printf("Child %d failed to start!\n", i);
2126 child_status_out[i] = 1;
2130 child_status_out[i] = fn(current_cli, i);
2137 for (i=0;i<torture_nprocs;i++) {
2138 if (child_status[i]) synccount++;
2140 if (synccount == torture_nprocs) break;
2142 } while (timeval_elapsed(&tv) < start_time_limit);
2144 if (synccount != torture_nprocs) {
2145 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
2147 return timeval_elapsed(&tv);
2150 printf("Starting %d clients\n", torture_nprocs);
2152 /* start the client load */
2153 tv = timeval_current();
2154 for (i=0;i<torture_nprocs;i++) {
2155 child_status[i] = 0;
2158 printf("%d clients started\n", torture_nprocs);
2162 for (i=0;i<torture_nprocs;i++) {
2164 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
2165 if (ret == -1 || WEXITSTATUS(status) != 0) {
2172 for (i=0;i<torture_nprocs;i++) {
2173 if (!child_status_out[i]) {
2177 return timeval_elapsed(&tv);
2180 #define FLAG_MULTIPROC 1
2185 BOOL (*multi_fn)(struct smbcli_state *, int );
2188 {"BASE-FDPASS", run_fdpasstest, 0},
2189 {"BASE-LOCK1", torture_locktest1, 0},
2190 {"BASE-LOCK2", torture_locktest2, 0},
2191 {"BASE-LOCK3", torture_locktest3, 0},
2192 {"BASE-LOCK4", torture_locktest4, 0},
2193 {"BASE-LOCK5", torture_locktest5, 0},
2194 {"BASE-LOCK6", torture_locktest6, 0},
2195 {"BASE-LOCK7", torture_locktest7, 0},
2196 {"BASE-UNLINK", torture_unlinktest, 0},
2197 {"BASE-ATTR", run_attrtest, 0},
2198 {"BASE-TRANS2", run_trans2test, 0},
2199 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
2200 {"BASE-DIR1", torture_dirtest1, 0},
2201 {"BASE-DIR2", torture_dirtest2, 0},
2202 {"BASE-DENY1", torture_denytest1, 0},
2203 {"BASE-DENY2", torture_denytest2, 0},
2204 {"BASE-DENY3", torture_denytest3, 0},
2205 {"BASE-DENYDOS", torture_denydos_sharing, 0},
2206 {"BASE-NTDENY1", NULL, torture_ntdenytest1},
2207 {"BASE-NTDENY2", torture_ntdenytest2, 0},
2208 {"BASE-TCON", run_tcon_test, 0},
2209 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
2210 {"BASE-VUID", run_vuidtest, 0},
2211 {"BASE-RW1", run_readwritetest, 0},
2212 {"BASE-OPEN", run_opentest, 0},
2213 {"BASE-DEFER_OPEN", NULL, run_deferopen},
2214 {"BASE-XCOPY", run_xcopy, 0},
2215 {"BASE-RENAME", torture_test_rename, 0},
2216 {"BASE-DELETE", torture_test_delete, 0},
2217 {"BASE-PROPERTIES", torture_test_properties, 0},
2218 {"BASE-MANGLE", torture_mangle, 0},
2219 {"BASE-OPENATTR", torture_openattrtest, 0},
2220 {"BASE-CHARSET", torture_charset, 0},
2221 {"BASE-CHKPATH", torture_chkpath_test, 0},
2222 {"BASE-SECLEAK", torture_sec_leak, 0},
2223 {"BASE-DISCONNECT", torture_disconnect, 0},
2224 {"BASE-DELAYWRITE", torture_delay_write, 0},
2226 /* benchmarking tests */
2227 {"BENCH-HOLDCON", torture_holdcon, 0},
2228 {"BENCH-NBENCH", torture_nbench, 0},
2229 {"BENCH-TORTURE", NULL, run_torture},
2230 {"BENCH-NBT", torture_bench_nbt, 0},
2231 {"BENCH-WINS", torture_bench_wins, 0},
2232 {"BENCH-RPC", torture_bench_rpc, 0},
2233 {"BENCH-CLDAP", torture_bench_cldap, 0},
2236 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
2237 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
2238 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
2239 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
2240 {"RAW-SEARCH", torture_raw_search, 0},
2241 {"RAW-CLOSE", torture_raw_close, 0},
2242 {"RAW-OPEN", torture_raw_open, 0},
2243 {"RAW-MKDIR", torture_raw_mkdir, 0},
2244 {"RAW-OPLOCK", torture_raw_oplock, 0},
2245 {"RAW-NOTIFY", torture_raw_notify, 0},
2246 {"RAW-MUX", torture_raw_mux, 0},
2247 {"RAW-IOCTL", torture_raw_ioctl, 0},
2248 {"RAW-CHKPATH", torture_raw_chkpath, 0},
2249 {"RAW-UNLINK", torture_raw_unlink, 0},
2250 {"RAW-READ", torture_raw_read, 0},
2251 {"RAW-WRITE", torture_raw_write, 0},
2252 {"RAW-LOCK", torture_raw_lock, 0},
2253 {"RAW-CONTEXT", torture_raw_context, 0},
2254 {"RAW-RENAME", torture_raw_rename, 0},
2255 {"RAW-SEEK", torture_raw_seek, 0},
2256 {"RAW-EAS", torture_raw_eas, 0},
2257 {"RAW-EAMAX", torture_max_eas, 0},
2258 {"RAW-STREAMS", torture_raw_streams, 0},
2259 {"RAW-ACLS", torture_raw_acls, 0},
2260 {"RAW-RAP", torture_raw_rap, 0},
2261 {"RAW-COMPOSITE", torture_raw_composite, 0},
2264 {"SMB2-CONNECT", torture_smb2_connect, 0},
2265 {"SMB2-SCAN", torture_smb2_scan, 0},
2266 {"SMB2-SCANGETINFO", torture_smb2_getinfo_scan, 0},
2267 {"SMB2-SCANSETINFO", torture_smb2_setinfo_scan, 0},
2268 {"SMB2-SCANFIND", torture_smb2_find_scan, 0},
2269 {"SMB2-GETINFO", torture_smb2_getinfo, 0},
2270 {"SMB2-SETINFO", torture_smb2_setinfo, 0},
2271 {"SMB2-FIND", torture_smb2_find, 0},
2273 /* protocol scanners */
2274 {"SCAN-TRANS2", torture_trans2_scan, 0},
2275 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2276 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2277 {"SCAN-SMB", torture_smb_scan, 0},
2278 {"SCAN-MAXFID", NULL, run_maxfidtest},
2279 {"SCAN-UTABLE", torture_utable, 0},
2280 {"SCAN-CASETABLE", torture_casetable, 0},
2281 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2282 {"SCAN-IOCTL", torture_ioctl_test, 0},
2283 {"SCAN-RAP", torture_rap_scan, 0},
2286 {"RPC-LSA", torture_rpc_lsa, 0},
2287 {"RPC-LSALOOKUP", torture_rpc_lsa_lookup, 0},
2288 {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
2289 {"RPC-ECHO", torture_rpc_echo, 0},
2290 {"RPC-DFS", torture_rpc_dfs, 0},
2291 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2292 {"RPC-SAMR", torture_rpc_samr, 0},
2293 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2294 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2295 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2296 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2297 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2298 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2299 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2300 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2301 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2302 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2303 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2304 {"RPC-WINREG", torture_rpc_winreg, 0},
2305 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2306 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2307 {"RPC-REMACT", torture_rpc_remact, 0},
2308 {"RPC-MGMT", torture_rpc_mgmt, 0},
2309 {"RPC-SCANNER", torture_rpc_scanner, 0},
2310 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2311 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2312 {"RPC-MULTIBIND", torture_multi_bind, 0},
2313 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2314 {"RPC-CRACKNAMES", torture_rpc_drsuapi_cracknames, 0},
2315 {"RPC-ROT", torture_rpc_rot, 0},
2316 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2317 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2318 {"RPC-JOIN", torture_rpc_join, 0},
2319 {"RPC-DSSYNC", torture_rpc_dssync, 0},
2321 /* local (no server) testers */
2322 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2323 {"LOCAL-ICONV", torture_local_iconv, 0},
2324 {"LOCAL-TALLOC", torture_local_talloc, 0},
2325 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2326 {"LOCAL-IRPC", torture_local_irpc, 0},
2327 {"LOCAL-BINDING", torture_local_binding_string, 0},
2328 {"LOCAL-STRLIST", torture_local_util_strlist, 0},
2329 {"LOCAL-FILE", torture_local_util_file, 0},
2330 {"LOCAL-IDTREE", torture_local_idtree, 0},
2331 {"LOCAL-SOCKET", torture_local_socket, 0},
2332 {"LOCAL-PAC", torture_pac, 0},
2333 {"LOCAL-REGISTRY", torture_registry, 0},
2334 {"LOCAL-RESOLVE", torture_local_resolve, 0},
2335 {"LOCAL-SDDL", torture_local_sddl, 0},
2336 {"LOCAL-NDR", torture_local_ndr, 0},
2338 /* COM (Component Object Model) testers */
2339 {"COM-SIMPLE", torture_com_simple, 0 },
2342 {"LDAP-BASIC", torture_ldap_basic, 0},
2343 {"LDAP-CLDAP", torture_cldap, 0},
2346 {"NBT-REGISTER", torture_nbt_register, 0},
2347 {"NBT-WINS", torture_nbt_wins, 0},
2348 {"NBT-DGRAM", torture_nbt_dgram, 0},
2349 {"NBT-BROWSE", torture_nbt_browse, 0},
2350 {"NBT-WINSREPLICATION-SIMPLE", torture_nbt_winsreplication_simple, 0},
2351 {"NBT-WINSREPLICATION-REPLICA", torture_nbt_winsreplication_replica, 0},
2352 {"NBT-WINSREPLICATION-OWNED", torture_nbt_winsreplication_owned, 0},
2355 {"NET-USERINFO", torture_userinfo, 0},
2356 {"NET-USERADD", torture_useradd, 0},
2357 {"NET-USERDEL", torture_userdel, 0},
2358 {"NET-USERMOD", torture_usermod, 0},
2359 {"NET-DOMOPEN", torture_domainopen, 0},
2360 {"NET-API-LOOKUP", torture_lookup, 0},
2361 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2362 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2363 {"NET-API-CREATEUSER", torture_createuser, 0},
2364 {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
2365 {"NET-API-LISTSHARES", torture_listshares, 0},
2366 {"NET-API-DELSHARE", torture_delshare, 0},
2372 /****************************************************************************
2373 run a specified test or "ALL"
2374 ****************************************************************************/
2375 static BOOL run_test(const char *name)
2379 BOOL matched = False;
2381 if (strequal(name,"ALL")) {
2382 for (i=0;torture_ops[i].name;i++) {
2383 if (!run_test(torture_ops[i].name)) {
2390 for (i=0;torture_ops[i].name;i++) {
2391 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
2395 printf("Running %s\n", torture_ops[i].name);
2396 if (torture_ops[i].multi_fn) {
2397 BOOL result = False;
2398 t = torture_create_procs(torture_ops[i].multi_fn,
2402 printf("TEST %s FAILED!\n", torture_ops[i].name);
2406 struct timeval tv = timeval_current();
2407 if (!torture_ops[i].fn()) {
2409 printf("TEST %s FAILED!\n", torture_ops[i].name);
2411 t = timeval_elapsed(&tv);
2413 printf("%s took %g secs\n\n", torture_ops[i].name, t);
2418 printf("Unknown torture operation '%s'\n", name);
2425 static void parse_dns(const char *dns)
2427 char *userdn, *basedn, *secret;
2430 /* retrievieng the userdn */
2431 p = strchr_m(dns, '#');
2433 lp_set_cmdline("torture:ldap_userdn", "");
2434 lp_set_cmdline("torture:ldap_basedn", "");
2435 lp_set_cmdline("torture:ldap_secret", "");
2438 userdn = strndup(dns, p - dns);
2439 lp_set_cmdline("torture:ldap_userdn", userdn);
2441 /* retrieve the basedn */
2443 p = strchr_m(d, '#');
2445 lp_set_cmdline("torture:ldap_basedn", "");
2446 lp_set_cmdline("torture:ldap_secret", "");
2449 basedn = strndup(d, p - d);
2450 lp_set_cmdline("torture:ldap_basedn", basedn);
2452 /* retrieve the secret */
2455 lp_set_cmdline("torture:ldap_secret", "");
2459 lp_set_cmdline("torture:ldap_secret", secret);
2461 printf ("%s - %s - %s\n", userdn, basedn, secret);
2465 static void usage(poptContext pc)
2470 poptPrintUsage(pc, stdout, 0);
2473 printf("The binding format is:\n\n");
2475 printf(" TRANSPORT:host[flags]\n\n");
2477 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2479 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2480 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2481 printf(" string.\n\n");
2483 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2484 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2485 printf(" will be auto-determined.\n\n");
2487 printf(" other recognised flags are:\n\n");
2489 printf(" sign : enable ntlmssp signing\n");
2490 printf(" seal : enable ntlmssp sealing\n");
2491 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2492 printf(" validate: enable the NDR validator\n");
2493 printf(" print: enable debugging of the packets\n");
2494 printf(" bigendian: use bigendian RPC\n");
2495 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2497 printf(" For example, these all connect to the samr pipe:\n\n");
2499 printf(" ncacn_np:myserver\n");
2500 printf(" ncacn_np:myserver[samr]\n");
2501 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2502 printf(" ncacn_np:myserver[/pipe/samr]\n");
2503 printf(" ncacn_np:myserver[samr,sign,print]\n");
2504 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2505 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2506 printf(" ncacn_np:\n");
2507 printf(" ncacn_np:[/pipe/samr]\n\n");
2509 printf(" ncacn_ip_tcp:myserver\n");
2510 printf(" ncacn_ip_tcp:myserver[1024]\n");
2511 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2513 printf("The unc format is:\n\n");
2515 printf(" //server/share\n\n");
2517 printf("tests are:");
2518 for (i=0;torture_ops[i].name;i++) {
2519 if ((i%perline)==0) {
2522 printf("%s ", torture_ops[i].name);
2526 printf("default test is ALL\n");
2531 static BOOL is_binding_string(const char *binding_string)
2533 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2534 struct dcerpc_binding *binding_struct;
2537 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2539 talloc_free(mem_ctx);
2540 return NT_STATUS_IS_OK(status);
2543 static void max_runtime_handler(int sig)
2545 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2549 /****************************************************************************
2551 ****************************************************************************/
2552 int main(int argc,char *argv[])
2556 BOOL correct = True;
2561 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,
2562 OPT_DANGEROUS,OPT_SMB_PORTS};
2564 struct poptOption long_options[] = {
2566 {"smb-ports", 'p', POPT_ARG_STRING, NULL, OPT_SMB_PORTS, "SMB ports", NULL},
2567 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2568 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2569 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2570 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2571 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2572 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2573 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2574 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2575 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2576 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2577 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2578 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2579 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2580 "set maximum time for smbtorture to live", "seconds"},
2582 POPT_COMMON_CONNECTION
2583 POPT_COMMON_CREDENTIALS
2588 #ifdef HAVE_SETBUFFER
2589 setbuffer(stdout, NULL, 0);
2592 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2593 POPT_CONTEXT_KEEP_FIRST);
2595 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2597 while((opt = poptGetNextOpt(pc)) != -1) {
2600 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2603 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2606 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2609 parse_dns(poptGetOptArg(pc));
2612 lp_set_cmdline("torture:dangerous", "Yes");
2615 lp_set_cmdline("smb ports", poptGetOptArg(pc));
2618 d_printf("Invalid option %s: %s\n",
2619 poptBadOption(pc, 0), poptStrerror(opt));
2626 /* this will only work if nobody else uses alarm(),
2627 which means it won't work for some tests, but we
2628 can't use the event context method we use for smbd
2629 as so many tests create their own event
2630 context. This will at least catch most cases. */
2631 signal(SIGALRM, max_runtime_handler);
2637 dcerpc_table_init();
2639 if (torture_seed == 0) {
2640 torture_seed = time(NULL);
2642 printf("Using seed %d\n", torture_seed);
2643 srandom(torture_seed);
2645 argv_new = discard_const_p(char *, poptGetArgs(pc));
2648 for (i=0; i<argc; i++) {
2649 if (argv_new[i] == NULL) {
2660 for(p = argv_new[1]; *p; p++) {
2665 /* see if its a RPC transport specifier */
2666 if (is_binding_string(argv_new[1])) {
2667 lp_set_cmdline("torture:binding", argv_new[1]);
2669 char *binding = NULL;
2670 const char *host = NULL, *share = NULL;
2672 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
2673 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
2677 lp_set_cmdline("torture:host", host);
2678 lp_set_cmdline("torture:share", share);
2679 asprintf(&binding, "ncacn_np:%s", host);
2680 lp_set_cmdline("torture:binding", binding);
2683 if (argc_new == 0) {
2684 printf("You must specify a test to run, or 'ALL'\n");
2686 for (i=2;i<argc_new;i++) {
2687 if (!run_test(argv_new[i])) {