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"
32 int torture_numops=10;
33 int torture_entries=1000;
34 int torture_failures=1;
36 static int procnum; /* records process count number when forking */
37 static struct smbcli_state *current_cli;
38 static BOOL use_oplocks;
39 static BOOL use_level_II_oplocks;
41 BOOL torture_showall = False;
43 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
45 static struct smbcli_state *open_nbt_connection(void)
47 struct nbt_name called, calling;
48 struct smbcli_state *cli;
49 const char *host = lp_parm_string(-1, "torture", "host");
51 make_nbt_name_client(&calling, lp_netbios_name());
53 nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
55 cli = smbcli_state_init(NULL);
57 printf("Failed initialize smbcli_struct to connect with %s\n", host);
61 if (!smbcli_socket_connect(cli, host)) {
62 printf("Failed to connect with %s\n", host);
66 if (!smbcli_transport_establish(cli, &calling, &called)) {
67 printf("%s rejected the session\n",host);
78 BOOL torture_open_connection_share(TALLOC_CTX *mem_ctx,
79 struct smbcli_state **c,
81 const char *sharename,
82 struct event_context *ev)
86 status = smbcli_full_connection(mem_ctx, c, hostname,
88 cmdline_credentials, ev);
89 if (!NT_STATUS_IS_OK(status)) {
90 printf("Failed to open connection - %s\n", nt_errstr(status));
94 (*c)->transport->options.use_oplocks = use_oplocks;
95 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
100 BOOL torture_open_connection(struct smbcli_state **c)
102 const char *host = lp_parm_string(-1, "torture", "host");
103 const char *share = lp_parm_string(-1, "torture", "share");
105 return torture_open_connection_share(NULL, c, host, share, NULL);
110 BOOL torture_close_connection(struct smbcli_state *c)
114 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
115 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
122 /* open a rpc connection to the chosen binding string */
123 NTSTATUS torture_rpc_connection(TALLOC_CTX *parent_ctx,
124 struct dcerpc_pipe **p,
125 const struct dcerpc_interface_table *table)
128 const char *binding = lp_parm_string(-1, "torture", "binding");
131 printf("You must specify a ncacn binding string\n");
132 return NT_STATUS_INVALID_PARAMETER;
135 status = dcerpc_pipe_connect(parent_ctx,
137 cmdline_credentials, NULL);
142 /* open a rpc connection to a specific transport */
143 NTSTATUS torture_rpc_connection_transport(TALLOC_CTX *parent_ctx,
144 struct dcerpc_pipe **p,
145 const struct dcerpc_interface_table *table,
146 enum dcerpc_transport_t transport)
149 const char *binding = lp_parm_string(-1, "torture", "binding");
150 struct dcerpc_binding *b;
151 TALLOC_CTX *mem_ctx = talloc_named(parent_ctx, 0, "torture_rpc_connection_smb");
154 printf("You must specify a ncacn binding string\n");
155 talloc_free(mem_ctx);
156 return NT_STATUS_INVALID_PARAMETER;
159 status = dcerpc_parse_binding(mem_ctx, binding, &b);
160 if (!NT_STATUS_IS_OK(status)) {
161 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
162 talloc_free(mem_ctx);
166 b->transport = transport;
168 status = dcerpc_pipe_connect_b(mem_ctx, p, b, table,
169 cmdline_credentials, NULL);
171 if (NT_STATUS_IS_OK(status)) {
172 *p = talloc_reference(parent_ctx, *p);
176 talloc_free(mem_ctx);
180 /* check if the server produced the expected error code */
181 BOOL check_error(const char *location, struct smbcli_state *c,
182 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
186 status = smbcli_nt_error(c->tree);
187 if (NT_STATUS_IS_DOS(status)) {
189 class = NT_STATUS_DOS_CLASS(status);
190 num = NT_STATUS_DOS_CODE(status);
191 if (eclass != class || ecode != num) {
192 printf("unexpected error code %s\n", nt_errstr(status));
193 printf(" expected %s or %s (at %s)\n",
194 nt_errstr(NT_STATUS_DOS(eclass, ecode)),
195 nt_errstr(nterr), location);
199 if (!NT_STATUS_EQUAL(nterr, status)) {
200 printf("unexpected error code %s\n", nt_errstr(status));
201 printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
210 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
212 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
213 if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
219 static BOOL rw_torture(struct smbcli_state *c)
221 const char *lockfname = "\\torture.lck";
225 pid_t pid2, pid = getpid();
230 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
233 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
235 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
240 for (i=0;i<torture_numops;i++) {
241 uint_t n = (uint_t)random()%10;
243 printf("%d\r", i); fflush(stdout);
245 asprintf(&fname, "\\torture.%u", n);
247 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
251 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
253 printf("open failed (%s)\n", smbcli_errstr(c->tree));
258 if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
259 printf("write failed (%s)\n", smbcli_errstr(c->tree));
264 if (smbcli_write(c->tree, fnum, 0, buf,
265 sizeof(pid)+(j*sizeof(buf)),
266 sizeof(buf)) != sizeof(buf)) {
267 printf("write failed (%s)\n", smbcli_errstr(c->tree));
274 if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
275 printf("read failed (%s)\n", smbcli_errstr(c->tree));
280 printf("data corruption!\n");
284 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
285 printf("close failed (%s)\n", smbcli_errstr(c->tree));
289 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
290 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
294 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
295 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
301 smbcli_close(c->tree, fnum2);
302 smbcli_unlink(c->tree, lockfname);
309 static BOOL run_torture(struct smbcli_state *cli, int dummy)
313 ret = rw_torture(cli);
315 if (!torture_close_connection(cli)) {
323 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
325 const char *lockfname = "\\torture2.lck";
330 uint8_t buf_rd[131072];
332 ssize_t bytes_read, bytes_written;
334 if (smbcli_deltree(c1->tree, lockfname) == -1) {
335 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
338 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
341 printf("first open read/write of %s failed (%s)\n",
342 lockfname, smbcli_errstr(c1->tree));
345 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
348 printf("second open read-only of %s failed (%s)\n",
349 lockfname, smbcli_errstr(c2->tree));
350 smbcli_close(c1->tree, fnum1);
354 printf("Checking data integrity over %d ops\n", torture_numops);
356 for (i=0;i<torture_numops;i++)
358 size_t buf_size = ((uint_t)random()%(sizeof(buf)-1))+ 1;
360 printf("%d\r", i); fflush(stdout);
363 generate_random_buffer(buf, buf_size);
365 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
366 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
367 printf("wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
372 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
373 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
374 printf("read %d, expected %d\n", (int)bytes_read, (int)buf_size);
379 if (memcmp(buf_rd, buf, buf_size) != 0)
381 printf("read/write compare failed\n");
387 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
388 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
391 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
392 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
396 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
397 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
404 #define BOOLSTR(b) ((b) ? "Yes" : "No")
406 static BOOL run_readwritetest(void)
408 struct smbcli_state *cli1, *cli2;
409 BOOL test1, test2 = True;
411 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
415 printf("starting readwritetest\n");
417 test1 = rw_torture2(cli1, cli2);
418 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
421 test2 = rw_torture2(cli1, cli1);
422 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
425 if (!torture_close_connection(cli1)) {
429 if (!torture_close_connection(cli2)) {
433 return (test1 && test2);
437 this checks to see if a secondary tconx can use open files from an
440 static BOOL run_tcon_test(void)
442 struct smbcli_state *cli;
443 const char *fname = "\\tcontest.tmp";
445 uint16_t cnum1, cnum2, cnum3;
446 uint16_t vuid1, vuid2;
449 struct smbcli_tree *tree1;
450 const char *host = lp_parm_string(-1, "torture", "host");
451 const char *share = lp_parm_string(-1, "torture", "share");
452 const char *password = lp_parm_string(-1, "torture", "password");
454 if (!torture_open_connection(&cli)) {
458 printf("starting tcontest\n");
460 if (smbcli_deltree(cli->tree, fname) == -1) {
461 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
464 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
466 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
470 cnum1 = cli->tree->tid;
471 vuid1 = cli->session->vuid;
473 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
474 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
475 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
479 tree1 = cli->tree; /* save old tree connection */
480 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
481 printf("%s refused 2nd tree connect (%s)\n", host,
482 smbcli_errstr(cli->tree));
487 cnum2 = cli->tree->tid;
488 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
489 vuid2 = cli->session->vuid + 1;
491 /* try a write with the wrong tid */
492 cli->tree->tid = cnum2;
494 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
495 printf("* server allows write with wrong TID\n");
498 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
502 /* try a write with an invalid tid */
503 cli->tree->tid = cnum3;
505 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
506 printf("* server allows write with invalid TID\n");
509 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
512 /* try a write with an invalid vuid */
513 cli->session->vuid = vuid2;
514 cli->tree->tid = cnum1;
516 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
517 printf("* server allows write with invalid VUID\n");
520 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
523 cli->session->vuid = vuid1;
524 cli->tree->tid = cnum1;
526 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
527 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
531 cli->tree->tid = cnum2;
533 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
534 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
538 cli->tree = tree1; /* restore initial tree */
539 cli->tree->tid = cnum1;
541 smbcli_unlink(tree1, fname);
543 if (!torture_close_connection(cli)) {
552 static BOOL tcon_devtest(struct smbcli_state *cli,
553 const char *myshare, const char *devtype,
554 NTSTATUS expected_error)
558 const char *password = lp_parm_string(-1, "torture", "password");
560 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
563 printf("Trying share %s with devtype %s\n", myshare, devtype);
565 if (NT_STATUS_IS_OK(expected_error)) {
569 printf("tconX to share %s with type %s "
570 "should have succeeded but failed\n",
577 printf("tconx to share %s with type %s "
578 "should have failed but succeeded\n",
582 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
586 printf("Returned unexpected error\n");
595 checks for correct tconX support
597 static BOOL run_tcon_devtype_test(void)
599 struct smbcli_state *cli1 = NULL;
602 const char *host = lp_parm_string(-1, "torture", "host");
603 const char *share = lp_parm_string(-1, "torture", "share");
605 status = smbcli_full_connection(NULL,
608 cmdline_credentials, NULL);
610 if (!NT_STATUS_IS_OK(status)) {
611 printf("could not open connection\n");
615 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
618 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
621 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
624 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
627 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
630 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
633 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
636 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
639 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
642 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
648 printf("Passed tcondevtest\n");
655 test whether fnums and tids open on one VC are available on another (a major
658 static BOOL run_fdpasstest(void)
660 struct smbcli_state *cli1, *cli2;
661 const char *fname = "\\fdpass.tst";
665 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
669 printf("starting fdpasstest\n");
671 smbcli_unlink(cli1->tree, fname);
673 printf("Opening a file on connection 1\n");
675 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
677 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
681 printf("writing to file on connection 1\n");
683 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
684 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
688 oldtid = cli2->tree->tid;
689 cli2->session->vuid = cli1->session->vuid;
690 cli2->tree->tid = cli1->tree->tid;
691 cli2->session->pid = cli1->session->pid;
693 printf("reading from file on connection 2\n");
695 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
696 printf("read succeeded! nasty security hole [%s]\n",
701 smbcli_close(cli1->tree, fnum1);
702 smbcli_unlink(cli1->tree, fname);
704 cli2->tree->tid = oldtid;
706 torture_close_connection(cli1);
707 torture_close_connection(cli2);
709 printf("finished fdpasstest\n");
715 test the timing of deferred open requests
717 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
719 const char *fname = "\\defer_open_test.dat";
725 printf("failed to connect\n");
729 printf("Testing deferred open requests.\n");
736 tv = timeval_current();
737 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
739 FILE_ATTRIBUTE_NORMAL,
740 NTCREATEX_SHARE_ACCESS_NONE,
741 NTCREATEX_DISP_OPEN_IF, 0, 0);
745 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
746 double e = timeval_elapsed(&tv);
747 if (e < 0.5 || e > 1.5) {
748 fprintf(stderr,"Timing incorrect %.2f violation\n",
752 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
755 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
759 printf("pid %u open %d\n", getpid(), i);
763 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
764 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
770 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
771 /* All until the last unlink will fail with sharing violation. */
772 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
773 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
778 printf("deferred test finished\n");
779 if (!torture_close_connection(cli)) {
786 test how many open files this server supports on the one socket
788 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
790 #define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
792 int fnums[0x11000], i;
793 int retries=4, maxfid;
797 printf("failed to connect\n");
801 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
802 printf("Failed to deltree \\maxfid - %s\n",
803 smbcli_errstr(cli->tree));
806 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
807 printf("Failed to mkdir \\maxfid, error=%s\n",
808 smbcli_errstr(cli->tree));
812 printf("Testing maximum number of open files\n");
814 for (i=0; i<0x11000; i++) {
816 asprintf(&fname, "\\maxfid\\fid%d", i/1000);
817 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
818 printf("Failed to mkdir %s, error=%s\n",
819 fname, smbcli_errstr(cli->tree));
824 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
825 if ((fnums[i] = smbcli_open(cli->tree, fname,
826 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
828 printf("open of %s failed (%s)\n",
829 fname, smbcli_errstr(cli->tree));
830 printf("maximum fnum is %d\n", i);
841 printf("cleaning up\n");
842 for (i=0;i<maxfid/2;i++) {
843 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
844 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
845 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
847 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
848 printf("unlink of %s failed (%s)\n",
849 fname, smbcli_errstr(cli->tree));
854 asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
855 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
856 printf("Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
858 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
859 printf("unlink of %s failed (%s)\n",
860 fname, smbcli_errstr(cli->tree));
865 printf("%6d %6d\r", i, maxfid-i);
869 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
870 printf("Failed to deltree \\maxfid - %s\n",
871 smbcli_errstr(cli->tree));
875 printf("maxfid test finished\n");
876 if (!torture_close_connection(cli)) {
880 #undef MAXFID_TEMPLATE
883 /* send smb negprot commands, not reading the response */
884 static BOOL run_negprot_nowait(void)
887 struct smbcli_state *cli, *cli2;
890 printf("starting negprot nowait test\n");
892 cli = open_nbt_connection();
897 printf("Filling send buffer\n");
899 for (i=0;i<1000;i++) {
900 struct smbcli_request *req;
901 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
902 smbcli_transport_process(cli->transport);
903 if (req->state == SMBCLI_REQUEST_ERROR) {
904 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
905 torture_close_connection(cli);
910 printf("Opening secondary connection\n");
911 if (!torture_open_connection(&cli2)) {
915 if (!torture_close_connection(cli)) {
919 if (!torture_close_connection(cli2)) {
923 printf("finished negprot nowait test\n");
930 This checks how the getatr calls works
932 static BOOL run_attrtest(void)
934 struct smbcli_state *cli;
937 const char *fname = "\\attrib123456789.tst";
940 printf("starting attrib test\n");
942 if (!torture_open_connection(&cli)) {
946 smbcli_unlink(cli->tree, fname);
947 fnum = smbcli_open(cli->tree, fname,
948 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
949 smbcli_close(cli->tree, fnum);
951 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
952 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
956 printf("New file time is %s", ctime(&t));
958 if (abs(t - time(NULL)) > 60*60*24*10) {
959 printf("ERROR: SMBgetatr bug. time is %s",
965 t2 = t-60*60*24; /* 1 day ago */
967 printf("Setting file time to %s", ctime(&t2));
969 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
970 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
974 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
975 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
979 printf("Retrieved file time as %s", ctime(&t));
982 printf("ERROR: getatr/setatr bug. times are\n%s",
984 printf("%s", ctime(&t2));
988 smbcli_unlink(cli->tree, fname);
990 if (!torture_close_connection(cli)) {
994 printf("attrib test finished\n");
1001 This checks a couple of trans2 calls
1003 static BOOL run_trans2test(void)
1005 struct smbcli_state *cli;
1008 time_t c_time, a_time, m_time, w_time, m_time2;
1009 const char *fname = "\\trans2.tst";
1010 const char *dname = "\\trans2";
1011 const char *fname2 = "\\trans2\\trans2.tst";
1013 BOOL correct = True;
1015 printf("starting trans2 test\n");
1017 if (!torture_open_connection(&cli)) {
1021 smbcli_unlink(cli->tree, fname);
1023 printf("Testing qfileinfo\n");
1025 fnum = smbcli_open(cli->tree, fname,
1026 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1027 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
1029 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
1033 printf("Testing NAME_INFO\n");
1035 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
1036 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
1040 if (!pname || strcmp(pname, fname)) {
1041 printf("qfilename gave different name? [%s] [%s]\n",
1046 smbcli_close(cli->tree, fnum);
1047 smbcli_unlink(cli->tree, fname);
1049 fnum = smbcli_open(cli->tree, fname,
1050 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1052 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1055 smbcli_close(cli->tree, fnum);
1057 printf("Checking for sticky create times\n");
1059 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1060 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
1063 if (c_time != m_time) {
1064 printf("create time=%s", ctime(&c_time));
1065 printf("modify time=%s", ctime(&m_time));
1066 printf("This system appears to have sticky create times\n");
1068 if (a_time % (60*60) == 0) {
1069 printf("access time=%s", ctime(&a_time));
1070 printf("This system appears to set a midnight access time\n");
1074 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1075 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1081 smbcli_unlink(cli->tree, fname);
1082 fnum = smbcli_open(cli->tree, fname,
1083 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1084 smbcli_close(cli->tree, fnum);
1085 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1086 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1089 if (w_time < 60*60*24*2) {
1090 printf("write time=%s", ctime(&w_time));
1091 printf("This system appears to set a initial 0 write time\n");
1096 smbcli_unlink(cli->tree, fname);
1099 /* check if the server updates the directory modification time
1100 when creating a new file */
1101 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1102 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
1106 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1107 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1111 fnum = smbcli_open(cli->tree, fname2,
1112 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1113 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
1114 smbcli_close(cli->tree, fnum);
1115 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
1116 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1119 if (m_time2 == m_time) {
1120 printf("This system does not update directory modification times\n");
1124 smbcli_unlink(cli->tree, fname2);
1125 smbcli_rmdir(cli->tree, dname);
1127 if (!torture_close_connection(cli)) {
1131 printf("trans2 test finished\n");
1138 /* FIRST_DESIRED_ACCESS 0xf019f */
1139 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1140 SEC_FILE_READ_EA| /* 0xf */ \
1141 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1142 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1143 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1144 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1145 /* SECOND_DESIRED_ACCESS 0xe0080 */
1146 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1147 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1148 SEC_STD_WRITE_OWNER /* 0xe0000 */
1151 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1152 READ_CONTROL|WRITE_DAC|\
1153 SEC_FILE_READ_DATA|\
1158 Test ntcreate calls made by xcopy
1160 static BOOL run_xcopy(void)
1162 struct smbcli_state *cli1;
1163 const char *fname = "\\test.txt";
1164 BOOL correct = True;
1167 printf("starting xcopy test\n");
1169 if (!torture_open_connection(&cli1)) {
1173 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1174 FIRST_DESIRED_ACCESS,
1175 FILE_ATTRIBUTE_ARCHIVE,
1176 NTCREATEX_SHARE_ACCESS_NONE,
1177 NTCREATEX_DISP_OVERWRITE_IF,
1181 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
1185 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1186 SECOND_DESIRED_ACCESS, 0,
1187 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1190 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
1194 if (!torture_close_connection(cli1)) {
1203 see how many RPC pipes we can open at once
1205 static BOOL run_pipe_number(void)
1207 struct smbcli_state *cli1;
1208 const char *pipe_name = "\\WKSSVC";
1212 printf("starting pipenumber test\n");
1213 if (!torture_open_connection(&cli1)) {
1218 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1219 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1222 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
1226 printf("%d\r", num_pipes);
1230 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
1231 torture_close_connection(cli1);
1239 open N connections to the server and just hold them open
1240 used for testing performance when there are N idle users
1243 static BOOL torture_holdcon(void)
1246 struct smbcli_state **cli;
1249 printf("Opening %d connections\n", torture_numops);
1251 cli = malloc_array_p(struct smbcli_state *, torture_numops);
1253 for (i=0;i<torture_numops;i++) {
1254 if (!torture_open_connection(&cli[i])) {
1257 printf("opened %d connections\r", i);
1261 printf("\nStarting pings\n");
1264 for (i=0;i<torture_numops;i++) {
1267 status = smbcli_chkpath(cli[i]->tree, "\\");
1268 if (!NT_STATUS_IS_OK(status)) {
1269 printf("Connection %d is dead\n", i);
1277 if (num_dead == torture_numops) {
1278 printf("All connections dead - finishing\n");
1290 Try with a wrong vuid and check error message.
1293 static BOOL run_vuidtest(void)
1295 struct smbcli_state *cli;
1296 const char *fname = "\\vuid.tst";
1299 time_t c_time, a_time, m_time;
1300 BOOL correct = True;
1305 printf("starting vuid test\n");
1307 if (!torture_open_connection(&cli)) {
1311 smbcli_unlink(cli->tree, fname);
1313 fnum = smbcli_open(cli->tree, fname,
1314 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1316 orig_vuid = cli->session->vuid;
1318 cli->session->vuid += 1234;
1320 printf("Testing qfileinfo with wrong vuid\n");
1322 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
1323 &size, &c_time, &a_time,
1324 &m_time, NULL, NULL))) {
1325 printf("ERROR: qfileinfo passed with wrong vuid\n");
1329 if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1330 NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
1331 !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1332 NT_STATUS_INVALID_HANDLE)) {
1333 printf("ERROR: qfileinfo should have returned DOS error "
1334 "ERRSRV:ERRbaduid\n but returned %s\n",
1335 smbcli_errstr(cli->tree));
1339 cli->session->vuid -= 1234;
1341 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1342 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
1346 smbcli_unlink(cli->tree, fname);
1348 if (!torture_close_connection(cli)) {
1352 printf("vuid test finished\n");
1358 Test open mode returns on read-only files.
1360 static BOOL run_opentest(void)
1362 static struct smbcli_state *cli1;
1363 static struct smbcli_state *cli2;
1364 const char *fname = "\\readonly.file";
1365 char *control_char_fname;
1369 BOOL correct = True;
1374 printf("starting open test\n");
1376 if (!torture_open_connection(&cli1)) {
1380 asprintf(&control_char_fname, "\\readonly.afile");
1381 for (i = 1; i <= 0x1f; i++) {
1382 control_char_fname[10] = i;
1383 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
1384 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1386 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
1387 NT_STATUS_OBJECT_NAME_INVALID)) {
1388 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
1389 smbcli_errstr(cli1->tree), i);
1394 smbcli_close(cli1->tree, fnum1);
1396 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
1397 smbcli_unlink(cli1->tree, control_char_fname);
1399 free(control_char_fname);
1402 printf("Create file with control char names passed.\n");
1404 smbcli_setatr(cli1->tree, fname, 0, 0);
1405 smbcli_unlink(cli1->tree, fname);
1407 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1409 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1413 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1414 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1418 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
1419 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
1420 CHECK_MAX_FAILURES(error_test1);
1424 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1426 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1427 CHECK_MAX_FAILURES(error_test1);
1431 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
1432 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1434 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
1435 NT_STATUS_ACCESS_DENIED)) {
1436 printf("correct error code ERRDOS/ERRnoaccess returned\n");
1439 printf("finished open test 1\n");
1441 smbcli_close(cli1->tree, fnum1);
1443 /* Now try not readonly and ensure ERRbadshare is returned. */
1445 smbcli_setatr(cli1->tree, fname, 0, 0);
1447 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1449 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1453 /* This will fail - but the error should be ERRshare. */
1454 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1456 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
1457 NT_STATUS_SHARING_VIOLATION)) {
1458 printf("correct error code ERRDOS/ERRbadshare returned\n");
1461 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1462 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1466 smbcli_unlink(cli1->tree, fname);
1468 printf("finished open test 2\n");
1470 /* Test truncate open disposition on file opened for read. */
1472 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1474 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1478 /* write 20 bytes. */
1480 memset(buf, '\0', 20);
1482 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1483 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1487 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1488 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1492 /* Ensure size == 20. */
1493 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1494 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1495 CHECK_MAX_FAILURES(error_test3);
1500 printf("(3) file size != 20\n");
1501 CHECK_MAX_FAILURES(error_test3);
1505 /* Now test if we can truncate a file opened for readonly. */
1507 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
1509 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1510 CHECK_MAX_FAILURES(error_test3);
1514 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1515 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1519 /* Ensure size == 0. */
1520 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1521 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1522 CHECK_MAX_FAILURES(error_test3);
1527 printf("(3) file size != 0\n");
1528 CHECK_MAX_FAILURES(error_test3);
1531 printf("finished open test 3\n");
1533 smbcli_unlink(cli1->tree, fname);
1536 printf("testing ctemp\n");
1537 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
1539 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1540 CHECK_MAX_FAILURES(error_test4);
1543 printf("ctemp gave path %s\n", tmp_path);
1544 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1545 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1547 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1548 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1551 /* Test the non-io opens... */
1553 if (!torture_open_connection(&cli2)) {
1557 smbcli_setatr(cli2->tree, fname, 0, 0);
1558 smbcli_unlink(cli2->tree, fname);
1560 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1562 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1563 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1566 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1567 CHECK_MAX_FAILURES(error_test10);
1571 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1572 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1574 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1575 CHECK_MAX_FAILURES(error_test10);
1579 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1580 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1583 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1584 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1588 printf("non-io open test #1 passed.\n");
1590 smbcli_unlink(cli1->tree, fname);
1592 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1594 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1595 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1598 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1599 CHECK_MAX_FAILURES(error_test20);
1603 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1604 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1607 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1608 CHECK_MAX_FAILURES(error_test20);
1612 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1613 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1616 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1617 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1621 printf("non-io open test #2 passed.\n");
1623 smbcli_unlink(cli1->tree, fname);
1625 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1627 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1628 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1631 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1632 CHECK_MAX_FAILURES(error_test30);
1636 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1637 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1640 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1641 CHECK_MAX_FAILURES(error_test30);
1645 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1646 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1649 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1650 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1654 printf("non-io open test #3 passed.\n");
1656 smbcli_unlink(cli1->tree, fname);
1658 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1660 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1661 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1664 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1665 CHECK_MAX_FAILURES(error_test40);
1669 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1670 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1673 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1674 CHECK_MAX_FAILURES(error_test40);
1678 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1680 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1681 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1685 printf("non-io open test #4 passed.\n");
1687 smbcli_unlink(cli1->tree, fname);
1689 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1691 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1692 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1695 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1696 CHECK_MAX_FAILURES(error_test50);
1700 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1701 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1704 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1705 CHECK_MAX_FAILURES(error_test50);
1709 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1710 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1714 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1715 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1719 printf("non-io open test #5 passed.\n");
1721 printf("TEST #6 testing 1 non-io open, one io open\n");
1723 smbcli_unlink(cli1->tree, fname);
1725 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1726 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1729 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1730 CHECK_MAX_FAILURES(error_test60);
1734 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1735 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1738 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1739 CHECK_MAX_FAILURES(error_test60);
1743 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1744 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1748 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1749 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1753 printf("non-io open test #6 passed.\n");
1755 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
1757 smbcli_unlink(cli1->tree, fname);
1759 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1760 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1763 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1764 CHECK_MAX_FAILURES(error_test70);
1768 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1769 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1772 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1773 CHECK_MAX_FAILURES(error_test70);
1777 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1779 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1780 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1784 printf("non-io open test #7 passed.\n");
1788 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1790 smbcli_unlink(cli1->tree, fname);
1792 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1794 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1798 /* write 20 bytes. */
1800 memset(buf, '\0', 20);
1802 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1803 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1807 /* Ensure size == 20. */
1808 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1809 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1810 CHECK_MAX_FAILURES(error_test80);
1815 printf("(8) file size != 20\n");
1816 CHECK_MAX_FAILURES(error_test80);
1820 /* Get an exclusive lock on the open file. */
1821 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1822 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1823 CHECK_MAX_FAILURES(error_test80);
1827 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1829 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1833 /* Ensure size == 0. */
1834 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1835 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1836 CHECK_MAX_FAILURES(error_test80);
1841 printf("(8) file size != 0\n");
1842 CHECK_MAX_FAILURES(error_test80);
1846 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1847 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1851 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1852 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1858 printf("open test #8 passed.\n");
1860 smbcli_unlink(cli1->tree, fname);
1862 if (!torture_close_connection(cli1)) {
1865 if (!torture_close_connection(cli2)) {
1874 sees what IOCTLs are supported
1876 BOOL torture_ioctl_test(void)
1878 struct smbcli_state *cli;
1879 uint16_t device, function;
1881 const char *fname = "\\ioctl.dat";
1883 union smb_ioctl parms;
1884 TALLOC_CTX *mem_ctx;
1886 if (!torture_open_connection(&cli)) {
1890 mem_ctx = talloc_init("ioctl_test");
1892 printf("starting ioctl test\n");
1894 smbcli_unlink(cli->tree, fname);
1896 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1898 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1902 parms.ioctl.level = RAW_IOCTL_IOCTL;
1903 parms.ioctl.in.fnum = fnum;
1904 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
1905 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1906 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
1908 for (device=0;device<0x100;device++) {
1909 printf("testing device=0x%x\n", device);
1910 for (function=0;function<0x100;function++) {
1911 parms.ioctl.in.request = (device << 16) | function;
1912 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1914 if (NT_STATUS_IS_OK(status)) {
1915 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
1916 device, function, (int)parms.ioctl.out.blob.length);
1921 if (!torture_close_connection(cli)) {
1930 tries variants of chkpath
1932 BOOL torture_chkpath_test(void)
1934 struct smbcli_state *cli;
1938 if (!torture_open_connection(&cli)) {
1942 printf("starting chkpath test\n");
1944 printf("Testing valid and invalid paths\n");
1946 /* cleanup from an old run */
1947 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1948 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1949 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1951 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1952 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1956 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1957 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1961 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1963 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
1966 smbcli_close(cli->tree, fnum);
1968 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1969 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1973 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1974 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1978 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1979 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1980 NT_STATUS_NOT_A_DIRECTORY);
1982 printf("* chkpath on a file should fail\n");
1986 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
1987 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1988 NT_STATUS_OBJECT_NAME_NOT_FOUND);
1990 printf("* chkpath on a non existent file should fail\n");
1994 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
1995 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1996 NT_STATUS_OBJECT_PATH_NOT_FOUND);
1998 printf("* chkpath on a non existent component should fail\n");
2002 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
2003 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
2004 smbcli_rmdir(cli->tree, "\\chkpath.dir");
2006 if (!torture_close_connection(cli)) {
2014 static void sigcont(int sig)
2018 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
2021 volatile pid_t *child_status;
2022 volatile BOOL *child_status_out;
2025 double start_time_limit = 10 + (torture_nprocs * 1.5);
2026 char **unc_list = NULL;
2028 int num_unc_names = 0;
2035 signal(SIGCONT, sigcont);
2037 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
2038 if (!child_status) {
2039 printf("Failed to setup shared memory\n");
2043 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
2044 if (!child_status_out) {
2045 printf("Failed to setup result status shared memory\n");
2049 p = lp_parm_string(-1, "torture", "unclist");
2051 unc_list = file_lines_load(p, &num_unc_names, NULL);
2052 if (!unc_list || num_unc_names <= 0) {
2053 printf("Failed to load unc names list from '%s'\n", p);
2058 for (i = 0; i < torture_nprocs; i++) {
2059 child_status[i] = 0;
2060 child_status_out[i] = True;
2063 tv = timeval_current();
2065 for (i=0;i<torture_nprocs;i++) {
2069 const char *hostname=NULL, *sharename;
2071 pid_t mypid = getpid();
2072 srandom(((int)mypid) ^ ((int)time(NULL)));
2074 asprintf(&myname, "CLIENT%d", i);
2075 lp_set_cmdline("netbios name", myname);
2080 if (!smbcli_parse_unc(unc_list[i % num_unc_names],
2081 NULL, &hostname, &sharename)) {
2082 printf("Failed to parse UNC name %s\n",
2083 unc_list[i % num_unc_names]);
2090 if (torture_open_connection_share(NULL,
2097 } else if (torture_open_connection(¤t_cli)) {
2101 printf("pid %d failed to start\n", (int)getpid());
2107 child_status[i] = getpid();
2111 if (child_status[i]) {
2112 printf("Child %d failed to start!\n", i);
2113 child_status_out[i] = 1;
2117 child_status_out[i] = fn(current_cli, i);
2124 for (i=0;i<torture_nprocs;i++) {
2125 if (child_status[i]) synccount++;
2127 if (synccount == torture_nprocs) break;
2129 } while (timeval_elapsed(&tv) < start_time_limit);
2131 if (synccount != torture_nprocs) {
2132 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
2134 return timeval_elapsed(&tv);
2137 printf("Starting %d clients\n", torture_nprocs);
2139 /* start the client load */
2140 tv = timeval_current();
2141 for (i=0;i<torture_nprocs;i++) {
2142 child_status[i] = 0;
2145 printf("%d clients started\n", torture_nprocs);
2149 for (i=0;i<torture_nprocs;i++) {
2151 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
2152 if (ret == -1 || WEXITSTATUS(status) != 0) {
2159 for (i=0;i<torture_nprocs;i++) {
2160 if (!child_status_out[i]) {
2164 return timeval_elapsed(&tv);
2167 #define FLAG_MULTIPROC 1
2172 BOOL (*multi_fn)(struct smbcli_state *, int );
2175 {"BASE-FDPASS", run_fdpasstest, 0},
2176 {"BASE-LOCK1", torture_locktest1, 0},
2177 {"BASE-LOCK2", torture_locktest2, 0},
2178 {"BASE-LOCK3", torture_locktest3, 0},
2179 {"BASE-LOCK4", torture_locktest4, 0},
2180 {"BASE-LOCK5", torture_locktest5, 0},
2181 {"BASE-LOCK6", torture_locktest6, 0},
2182 {"BASE-LOCK7", torture_locktest7, 0},
2183 {"BASE-UNLINK", torture_unlinktest, 0},
2184 {"BASE-ATTR", run_attrtest, 0},
2185 {"BASE-TRANS2", run_trans2test, 0},
2186 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
2187 {"BASE-DIR1", torture_dirtest1, 0},
2188 {"BASE-DIR2", torture_dirtest2, 0},
2189 {"BASE-DENY1", torture_denytest1, 0},
2190 {"BASE-DENY2", torture_denytest2, 0},
2191 {"BASE-DENY3", torture_denytest3, 0},
2192 {"BASE-DENYDOS", torture_denydos_sharing, 0},
2193 {"BASE-NTDENY1", NULL, torture_ntdenytest1},
2194 {"BASE-NTDENY2", torture_ntdenytest2, 0},
2195 {"BASE-TCON", run_tcon_test, 0},
2196 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
2197 {"BASE-VUID", run_vuidtest, 0},
2198 {"BASE-RW1", run_readwritetest, 0},
2199 {"BASE-OPEN", run_opentest, 0},
2200 {"BASE-DEFER_OPEN", NULL, run_deferopen},
2201 {"BASE-XCOPY", run_xcopy, 0},
2202 {"BASE-RENAME", torture_test_rename, 0},
2203 {"BASE-DELETE", torture_test_delete, 0},
2204 {"BASE-PROPERTIES", torture_test_properties, 0},
2205 {"BASE-MANGLE", torture_mangle, 0},
2206 {"BASE-OPENATTR", torture_openattrtest, 0},
2207 {"BASE-CHARSET", torture_charset, 0},
2208 {"BASE-CHKPATH", torture_chkpath_test, 0},
2209 {"BASE-SECLEAK", torture_sec_leak, 0},
2210 {"BASE-DISCONNECT", torture_disconnect, 0},
2211 {"BASE-DELAYWRITE", torture_delay_write, 0},
2213 /* benchmarking tests */
2214 {"BENCH-HOLDCON", torture_holdcon, 0},
2215 {"BENCH-NBENCH", torture_nbench, 0},
2216 {"BENCH-TORTURE", NULL, run_torture},
2217 {"BENCH-NBT", torture_bench_nbt, 0},
2218 {"BENCH-WINS", torture_bench_wins, 0},
2219 {"BENCH-RPC", torture_bench_rpc, 0},
2220 {"BENCH-CLDAP", torture_bench_cldap, 0},
2223 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
2224 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
2225 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
2226 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
2227 {"RAW-SEARCH", torture_raw_search, 0},
2228 {"RAW-CLOSE", torture_raw_close, 0},
2229 {"RAW-OPEN", torture_raw_open, 0},
2230 {"RAW-MKDIR", torture_raw_mkdir, 0},
2231 {"RAW-OPLOCK", torture_raw_oplock, 0},
2232 {"RAW-NOTIFY", torture_raw_notify, 0},
2233 {"RAW-MUX", torture_raw_mux, 0},
2234 {"RAW-IOCTL", torture_raw_ioctl, 0},
2235 {"RAW-CHKPATH", torture_raw_chkpath, 0},
2236 {"RAW-UNLINK", torture_raw_unlink, 0},
2237 {"RAW-READ", torture_raw_read, 0},
2238 {"RAW-WRITE", torture_raw_write, 0},
2239 {"RAW-LOCK", torture_raw_lock, 0},
2240 {"RAW-CONTEXT", torture_raw_context, 0},
2241 {"RAW-RENAME", torture_raw_rename, 0},
2242 {"RAW-SEEK", torture_raw_seek, 0},
2243 {"RAW-EAS", torture_raw_eas, 0},
2244 {"RAW-EAMAX", torture_max_eas, 0},
2245 {"RAW-STREAMS", torture_raw_streams, 0},
2246 {"RAW-ACLS", torture_raw_acls, 0},
2247 {"RAW-RAP", torture_raw_rap, 0},
2248 {"RAW-COMPOSITE", torture_raw_composite, 0},
2249 {"RAW-PIPE-ECHO", torture_np_echo, 0 },
2252 {"SMB2-CONNECT", torture_smb2_connect, 0},
2253 {"SMB2-SCAN", torture_smb2_scan, 0},
2254 {"SMB2-SCANGETINFO", torture_smb2_getinfo_scan, 0},
2255 {"SMB2-SCANSETINFO", torture_smb2_setinfo_scan, 0},
2256 {"SMB2-SCANFIND", torture_smb2_find_scan, 0},
2257 {"SMB2-GETINFO", torture_smb2_getinfo, 0},
2258 {"SMB2-SETINFO", torture_smb2_setinfo, 0},
2259 {"SMB2-FIND", torture_smb2_find, 0},
2261 /* protocol scanners */
2262 {"SCAN-TRANS2", torture_trans2_scan, 0},
2263 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2264 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2265 {"SCAN-SMB", torture_smb_scan, 0},
2266 {"SCAN-MAXFID", NULL, run_maxfidtest},
2267 {"SCAN-UTABLE", torture_utable, 0},
2268 {"SCAN-CASETABLE", torture_casetable, 0},
2269 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2270 {"SCAN-IOCTL", torture_ioctl_test, 0},
2271 {"SCAN-RAP", torture_rap_scan, 0},
2274 {"RPC-LSA", torture_rpc_lsa, 0},
2275 {"RPC-LSALOOKUP", torture_rpc_lsa_lookup, 0},
2276 {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
2277 {"RPC-ECHO", torture_rpc_echo, 0},
2278 {"RPC-DFS", torture_rpc_dfs, 0},
2279 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2280 {"RPC-SAMR", torture_rpc_samr, 0},
2281 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2282 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2283 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2284 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2285 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2286 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2287 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2288 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2289 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2290 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2291 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2292 {"RPC-WINREG", torture_rpc_winreg, 0},
2293 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2294 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2295 {"RPC-REMACT", torture_rpc_remact, 0},
2296 {"RPC-MGMT", torture_rpc_mgmt, 0},
2297 {"RPC-SCANNER", torture_rpc_scanner, 0},
2298 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2299 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2300 {"RPC-MULTIBIND", torture_multi_bind, 0},
2301 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2302 {"RPC-CRACKNAMES", torture_rpc_drsuapi_cracknames, 0},
2303 {"RPC-ROT", torture_rpc_rot, 0},
2304 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2305 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2306 {"RPC-JOIN", torture_rpc_join, 0},
2307 {"RPC-DSSYNC", torture_rpc_dssync, 0},
2309 /* local (no server) testers */
2310 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2311 {"LOCAL-ICONV", torture_local_iconv, 0},
2312 {"LOCAL-TALLOC", torture_local_talloc, 0},
2313 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2314 {"LOCAL-IRPC", torture_local_irpc, 0},
2315 {"LOCAL-BINDING", torture_local_binding_string, 0},
2316 {"LOCAL-STRLIST", torture_local_util_strlist, 0},
2317 {"LOCAL-FILE", torture_local_util_file, 0},
2318 {"LOCAL-IDTREE", torture_local_idtree, 0},
2319 {"LOCAL-SOCKET", torture_local_socket, 0},
2320 {"LOCAL-PAC", torture_pac, 0},
2321 {"LOCAL-REGISTRY", torture_registry, 0},
2322 {"LOCAL-RESOLVE", torture_local_resolve, 0},
2323 {"LOCAL-SDDL", torture_local_sddl, 0},
2324 {"LOCAL-NDR", torture_local_ndr, 0},
2326 /* COM (Component Object Model) testers */
2327 {"COM-SIMPLE", torture_com_simple, 0 },
2330 {"LDAP-BASIC", torture_ldap_basic, 0},
2331 {"LDAP-CLDAP", torture_cldap, 0},
2334 {"NBT-REGISTER", torture_nbt_register, 0},
2335 {"NBT-WINS", torture_nbt_wins, 0},
2336 {"NBT-DGRAM", torture_nbt_dgram, 0},
2337 {"NBT-WINSREPLICATION", torture_nbt_winsreplication, 0},
2338 {"NBT-BROWSE", torture_nbt_browse, 0},
2341 {"NET-USERINFO", torture_userinfo, 0},
2342 {"NET-USERADD", torture_useradd, 0},
2343 {"NET-USERDEL", torture_userdel, 0},
2344 {"NET-USERMOD", torture_usermod, 0},
2345 {"NET-DOMOPEN", torture_domainopen, 0},
2346 {"NET-API-LOOKUP", torture_lookup, 0},
2347 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2348 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2349 {"NET-API-CREATEUSER", torture_createuser, 0},
2350 {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
2351 {"NET-API-LISTSHARES", torture_listshares, 0},
2352 {"NET-API-DELSHARE", torture_delshare, 0},
2358 /****************************************************************************
2359 run a specified test or "ALL"
2360 ****************************************************************************/
2361 static BOOL run_test(const char *name)
2365 BOOL matched = False;
2367 if (strequal(name,"ALL")) {
2368 for (i=0;torture_ops[i].name;i++) {
2369 if (!run_test(torture_ops[i].name)) {
2376 for (i=0;torture_ops[i].name;i++) {
2377 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
2381 printf("Running %s\n", torture_ops[i].name);
2382 if (torture_ops[i].multi_fn) {
2383 BOOL result = False;
2384 t = torture_create_procs(torture_ops[i].multi_fn,
2388 printf("TEST %s FAILED!\n", torture_ops[i].name);
2392 struct timeval tv = timeval_current();
2393 if (!torture_ops[i].fn()) {
2395 printf("TEST %s FAILED!\n", torture_ops[i].name);
2397 t = timeval_elapsed(&tv);
2399 printf("%s took %g secs\n\n", torture_ops[i].name, t);
2404 printf("Unknown torture operation '%s'\n", name);
2411 static void parse_dns(const char *dns)
2413 char *userdn, *basedn, *secret;
2416 /* retrievieng the userdn */
2417 p = strchr_m(dns, '#');
2419 lp_set_cmdline("torture:ldap_userdn", "");
2420 lp_set_cmdline("torture:ldap_basedn", "");
2421 lp_set_cmdline("torture:ldap_secret", "");
2424 userdn = strndup(dns, p - dns);
2425 lp_set_cmdline("torture:ldap_userdn", userdn);
2427 /* retrieve the basedn */
2429 p = strchr_m(d, '#');
2431 lp_set_cmdline("torture:ldap_basedn", "");
2432 lp_set_cmdline("torture:ldap_secret", "");
2435 basedn = strndup(d, p - d);
2436 lp_set_cmdline("torture:ldap_basedn", basedn);
2438 /* retrieve the secret */
2441 lp_set_cmdline("torture:ldap_secret", "");
2445 lp_set_cmdline("torture:ldap_secret", secret);
2447 printf ("%s - %s - %s\n", userdn, basedn, secret);
2451 static void usage(poptContext pc)
2456 poptPrintUsage(pc, stdout, 0);
2459 printf("The binding format is:\n\n");
2461 printf(" TRANSPORT:host[flags]\n\n");
2463 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2465 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2466 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2467 printf(" string.\n\n");
2469 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2470 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2471 printf(" will be auto-determined.\n\n");
2473 printf(" other recognised flags are:\n\n");
2475 printf(" sign : enable ntlmssp signing\n");
2476 printf(" seal : enable ntlmssp sealing\n");
2477 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2478 printf(" validate: enable the NDR validator\n");
2479 printf(" print: enable debugging of the packets\n");
2480 printf(" bigendian: use bigendian RPC\n");
2481 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2483 printf(" For example, these all connect to the samr pipe:\n\n");
2485 printf(" ncacn_np:myserver\n");
2486 printf(" ncacn_np:myserver[samr]\n");
2487 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2488 printf(" ncacn_np:myserver[/pipe/samr]\n");
2489 printf(" ncacn_np:myserver[samr,sign,print]\n");
2490 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2491 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2492 printf(" ncacn_np:\n");
2493 printf(" ncacn_np:[/pipe/samr]\n\n");
2495 printf(" ncacn_ip_tcp:myserver\n");
2496 printf(" ncacn_ip_tcp:myserver[1024]\n");
2497 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2499 printf("The unc format is:\n\n");
2501 printf(" //server/share\n\n");
2503 printf("tests are:");
2504 for (i=0;torture_ops[i].name;i++) {
2505 if ((i%perline)==0) {
2508 printf("%s ", torture_ops[i].name);
2512 printf("default test is ALL\n");
2517 static BOOL is_binding_string(const char *binding_string)
2519 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2520 struct dcerpc_binding *binding_struct;
2523 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2525 talloc_free(mem_ctx);
2526 return NT_STATUS_IS_OK(status);
2529 static void max_runtime_handler(int sig)
2531 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2535 /****************************************************************************
2537 ****************************************************************************/
2538 int main(int argc,char *argv[])
2542 BOOL correct = True;
2547 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,OPT_DANGEROUS};
2548 struct poptOption long_options[] = {
2550 {"smb-ports", 'p', POPT_ARG_STRING, NULL, 0, "SMB ports", NULL},
2551 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2552 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2553 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2554 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2555 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2556 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2557 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2558 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2559 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2560 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2561 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2562 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2563 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2564 "set maximum time for smbtorture to live", "seconds"},
2566 POPT_COMMON_CONNECTION
2567 POPT_COMMON_CREDENTIALS
2572 #ifdef HAVE_SETBUFFER
2573 setbuffer(stdout, NULL, 0);
2576 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2577 POPT_CONTEXT_KEEP_FIRST);
2579 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2581 while((opt = poptGetNextOpt(pc)) != -1) {
2584 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2587 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2590 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2593 parse_dns(poptGetOptArg(pc));
2596 lp_set_cmdline("torture:dangerous", "Yes");
2599 d_printf("Invalid option %s: %s\n",
2600 poptBadOption(pc, 0), poptStrerror(opt));
2607 /* this will only work if nobody else uses alarm(),
2608 which means it won't work for some tests, but we
2609 can't use the event context method we use for smbd
2610 as so many tests create their own event
2611 context. This will at least catch most cases. */
2612 signal(SIGALRM, max_runtime_handler);
2618 dcerpc_table_init();
2620 if (torture_seed == 0) {
2621 torture_seed = time(NULL);
2623 printf("Using seed %d\n", torture_seed);
2624 srandom(torture_seed);
2626 argv_new = discard_const_p(char *, poptGetArgs(pc));
2629 for (i=0; i<argc; i++) {
2630 if (argv_new[i] == NULL) {
2641 for(p = argv_new[1]; *p; p++) {
2646 /* see if its a RPC transport specifier */
2647 if (is_binding_string(argv_new[1])) {
2648 lp_set_cmdline("torture:binding", argv_new[1]);
2650 char *binding = NULL;
2651 const char *host = NULL, *share = NULL;
2653 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
2654 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
2658 lp_set_cmdline("torture:host", host);
2659 lp_set_cmdline("torture:share", share);
2660 asprintf(&binding, "ncacn_np:%s", host);
2661 lp_set_cmdline("torture:binding", binding);
2664 if (argc_new == 0) {
2665 printf("You must specify a test to run, or 'ALL'\n");
2667 for (i=2;i<argc_new;i++) {
2668 if (!run_test(argv_new[i])) {