2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-2003
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "lib/cmdline/popt_common.h"
24 #include "libcli/raw/libcliraw.h"
25 #include "system/time.h"
26 #include "system/wait.h"
27 #include "system/filesys.h"
29 #include "librpc/gen_ndr/ndr_security.h"
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 char *pipe_name,
126 const char *pipe_uuid,
127 uint32_t pipe_version)
130 const char *binding = lp_parm_string(-1, "torture", "binding");
133 printf("You must specify a ncacn binding string\n");
134 return NT_STATUS_INVALID_PARAMETER;
137 status = dcerpc_pipe_connect(parent_ctx,
138 p, binding, pipe_uuid, pipe_version,
139 cmdline_credentials, NULL);
144 /* open a rpc connection to a specific transport */
145 NTSTATUS torture_rpc_connection_transport(TALLOC_CTX *parent_ctx,
146 struct dcerpc_pipe **p,
147 const char *pipe_name,
148 const char *pipe_uuid,
149 uint32_t pipe_version,
150 enum dcerpc_transport_t transport)
153 const char *binding = lp_parm_string(-1, "torture", "binding");
154 struct dcerpc_binding *b;
155 TALLOC_CTX *mem_ctx = talloc_named(parent_ctx, 0, "torture_rpc_connection_smb");
158 printf("You must specify a ncacn binding string\n");
159 talloc_free(mem_ctx);
160 return NT_STATUS_INVALID_PARAMETER;
163 status = dcerpc_parse_binding(mem_ctx, binding, &b);
164 if (!NT_STATUS_IS_OK(status)) {
165 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
166 talloc_free(mem_ctx);
170 b->transport = transport;
172 status = dcerpc_pipe_connect_b(mem_ctx, p, b, pipe_uuid, pipe_version,
173 cmdline_credentials, NULL);
175 if (NT_STATUS_IS_OK(status)) {
176 *p = talloc_reference(parent_ctx, *p);
180 talloc_free(mem_ctx);
184 /* check if the server produced the expected error code */
185 BOOL check_error(const char *location, struct smbcli_state *c,
186 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
190 status = smbcli_nt_error(c->tree);
191 if (NT_STATUS_IS_DOS(status)) {
193 class = NT_STATUS_DOS_CLASS(status);
194 num = NT_STATUS_DOS_CODE(status);
195 if (eclass != class || ecode != num) {
196 printf("unexpected error code %s\n", nt_errstr(status));
197 printf(" expected %s or %s (at %s)\n",
198 nt_errstr(NT_STATUS_DOS(eclass, ecode)),
199 nt_errstr(nterr), location);
203 if (!NT_STATUS_EQUAL(nterr, status)) {
204 printf("unexpected error code %s\n", nt_errstr(status));
205 printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
214 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
216 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
217 if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
223 static BOOL rw_torture(struct smbcli_state *c)
225 const char *lockfname = "\\torture.lck";
229 pid_t pid2, pid = getpid();
234 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
237 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
239 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
244 for (i=0;i<torture_numops;i++) {
245 uint_t n = (uint_t)random()%10;
247 printf("%d\r", i); fflush(stdout);
249 asprintf(&fname, "\\torture.%u", n);
251 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
255 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
257 printf("open failed (%s)\n", smbcli_errstr(c->tree));
262 if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
263 printf("write failed (%s)\n", smbcli_errstr(c->tree));
268 if (smbcli_write(c->tree, fnum, 0, buf,
269 sizeof(pid)+(j*sizeof(buf)),
270 sizeof(buf)) != sizeof(buf)) {
271 printf("write failed (%s)\n", smbcli_errstr(c->tree));
278 if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
279 printf("read failed (%s)\n", smbcli_errstr(c->tree));
284 printf("data corruption!\n");
288 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
289 printf("close failed (%s)\n", smbcli_errstr(c->tree));
293 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
294 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
298 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
299 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
305 smbcli_close(c->tree, fnum2);
306 smbcli_unlink(c->tree, lockfname);
313 static BOOL run_torture(struct smbcli_state *cli, int dummy)
317 ret = rw_torture(cli);
319 if (!torture_close_connection(cli)) {
327 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
329 const char *lockfname = "\\torture2.lck";
334 uint8_t buf_rd[131072];
336 ssize_t bytes_read, bytes_written;
338 if (smbcli_deltree(c1->tree, lockfname) == -1) {
339 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
342 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
345 printf("first open read/write of %s failed (%s)\n",
346 lockfname, smbcli_errstr(c1->tree));
349 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
352 printf("second open read-only of %s failed (%s)\n",
353 lockfname, smbcli_errstr(c2->tree));
354 smbcli_close(c1->tree, fnum1);
358 printf("Checking data integrity over %d ops\n", torture_numops);
360 for (i=0;i<torture_numops;i++)
362 size_t buf_size = ((uint_t)random()%(sizeof(buf)-1))+ 1;
364 printf("%d\r", i); fflush(stdout);
367 generate_random_buffer(buf, buf_size);
369 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
370 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
371 printf("wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
376 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
377 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
378 printf("read %d, expected %d\n", (int)bytes_read, (int)buf_size);
383 if (memcmp(buf_rd, buf, buf_size) != 0)
385 printf("read/write compare failed\n");
391 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
392 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
395 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
396 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
400 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
401 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
408 #define BOOLSTR(b) ((b) ? "Yes" : "No")
410 static BOOL run_readwritetest(void)
412 struct smbcli_state *cli1, *cli2;
413 BOOL test1, test2 = True;
415 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
419 printf("starting readwritetest\n");
421 test1 = rw_torture2(cli1, cli2);
422 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
425 test2 = rw_torture2(cli1, cli1);
426 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
429 if (!torture_close_connection(cli1)) {
433 if (!torture_close_connection(cli2)) {
437 return (test1 && test2);
441 this checks to see if a secondary tconx can use open files from an
444 static BOOL run_tcon_test(void)
446 struct smbcli_state *cli;
447 const char *fname = "\\tcontest.tmp";
449 uint16_t cnum1, cnum2, cnum3;
450 uint16_t vuid1, vuid2;
453 struct smbcli_tree *tree1;
454 const char *host = lp_parm_string(-1, "torture", "host");
455 const char *share = lp_parm_string(-1, "torture", "share");
456 const char *password = lp_parm_string(-1, "torture", "password");
458 if (!torture_open_connection(&cli)) {
462 printf("starting tcontest\n");
464 if (smbcli_deltree(cli->tree, fname) == -1) {
465 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
468 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
470 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
474 cnum1 = cli->tree->tid;
475 vuid1 = cli->session->vuid;
477 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
478 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
479 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
483 tree1 = cli->tree; /* save old tree connection */
484 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
485 printf("%s refused 2nd tree connect (%s)\n", host,
486 smbcli_errstr(cli->tree));
491 cnum2 = cli->tree->tid;
492 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
493 vuid2 = cli->session->vuid + 1;
495 /* try a write with the wrong tid */
496 cli->tree->tid = cnum2;
498 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
499 printf("* server allows write with wrong TID\n");
502 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
506 /* try a write with an invalid tid */
507 cli->tree->tid = cnum3;
509 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
510 printf("* server allows write with invalid TID\n");
513 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
516 /* try a write with an invalid vuid */
517 cli->session->vuid = vuid2;
518 cli->tree->tid = cnum1;
520 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
521 printf("* server allows write with invalid VUID\n");
524 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
527 cli->session->vuid = vuid1;
528 cli->tree->tid = cnum1;
530 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
531 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
535 cli->tree->tid = cnum2;
537 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
538 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
542 cli->tree = tree1; /* restore initial tree */
543 cli->tree->tid = cnum1;
545 smbcli_unlink(tree1, fname);
547 if (!torture_close_connection(cli)) {
556 static BOOL tcon_devtest(struct smbcli_state *cli,
557 const char *myshare, const char *devtype,
558 NTSTATUS expected_error)
562 const char *password = lp_parm_string(-1, "torture", "password");
564 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
567 printf("Trying share %s with devtype %s\n", myshare, devtype);
569 if (NT_STATUS_IS_OK(expected_error)) {
573 printf("tconX to share %s with type %s "
574 "should have succeeded but failed\n",
581 printf("tconx to share %s with type %s "
582 "should have failed but succeeded\n",
586 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
590 printf("Returned unexpected error\n");
599 checks for correct tconX support
601 static BOOL run_tcon_devtype_test(void)
603 struct smbcli_state *cli1 = NULL;
606 const char *host = lp_parm_string(-1, "torture", "host");
607 const char *share = lp_parm_string(-1, "torture", "share");
609 status = smbcli_full_connection(NULL,
612 cmdline_credentials, NULL);
614 if (!NT_STATUS_IS_OK(status)) {
615 printf("could not open connection\n");
619 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
622 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
625 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
628 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
631 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
634 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
637 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
640 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
643 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
646 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
652 printf("Passed tcondevtest\n");
659 test whether fnums and tids open on one VC are available on another (a major
662 static BOOL run_fdpasstest(void)
664 struct smbcli_state *cli1, *cli2;
665 const char *fname = "\\fdpass.tst";
669 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
673 printf("starting fdpasstest\n");
675 smbcli_unlink(cli1->tree, fname);
677 printf("Opening a file on connection 1\n");
679 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
681 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
685 printf("writing to file on connection 1\n");
687 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
688 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
692 oldtid = cli2->tree->tid;
693 cli2->session->vuid = cli1->session->vuid;
694 cli2->tree->tid = cli1->tree->tid;
695 cli2->session->pid = cli1->session->pid;
697 printf("reading from file on connection 2\n");
699 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
700 printf("read succeeded! nasty security hole [%s]\n",
705 smbcli_close(cli1->tree, fnum1);
706 smbcli_unlink(cli1->tree, fname);
708 cli2->tree->tid = oldtid;
710 torture_close_connection(cli1);
711 torture_close_connection(cli2);
713 printf("finished fdpasstest\n");
719 test the timing of deferred open requests
721 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
723 const char *fname = "\\defer_open_test.dat";
729 printf("failed to connect\n");
733 printf("Testing deferred open requests.\n");
740 tv = timeval_current();
741 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
743 FILE_ATTRIBUTE_NORMAL,
744 NTCREATEX_SHARE_ACCESS_NONE,
745 NTCREATEX_DISP_OPEN_IF, 0, 0);
749 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
750 double e = timeval_elapsed(&tv);
751 if (e < 0.5 || e > 1.5) {
752 fprintf(stderr,"Timing incorrect %.2f violation\n",
756 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
759 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
763 printf("pid %u open %d\n", getpid(), i);
767 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
768 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
774 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
775 /* All until the last unlink will fail with sharing violation. */
776 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
777 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
782 printf("deferred test finished\n");
783 if (!torture_close_connection(cli)) {
790 test how many open files this server supports on the one socket
792 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
794 #define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
796 int fnums[0x11000], i;
797 int retries=4, maxfid;
801 printf("failed to connect\n");
805 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
806 printf("Failed to deltree \\maxfid - %s\n",
807 smbcli_errstr(cli->tree));
810 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
811 printf("Failed to mkdir \\maxfid, error=%s\n",
812 smbcli_errstr(cli->tree));
816 printf("Testing maximum number of open files\n");
818 for (i=0; i<0x11000; i++) {
820 asprintf(&fname, "\\maxfid\\fid%d", i/1000);
821 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
822 printf("Failed to mkdir %s, error=%s\n",
823 fname, smbcli_errstr(cli->tree));
828 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
829 if ((fnums[i] = smbcli_open(cli->tree, fname,
830 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
832 printf("open of %s failed (%s)\n",
833 fname, smbcli_errstr(cli->tree));
834 printf("maximum fnum is %d\n", i);
845 printf("cleaning up\n");
846 for (i=0;i<maxfid/2;i++) {
847 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
848 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
849 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
851 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
852 printf("unlink of %s failed (%s)\n",
853 fname, smbcli_errstr(cli->tree));
858 asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
859 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
860 printf("Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
862 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
863 printf("unlink of %s failed (%s)\n",
864 fname, smbcli_errstr(cli->tree));
869 printf("%6d %6d\r", i, maxfid-i);
873 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
874 printf("Failed to deltree \\maxfid - %s\n",
875 smbcli_errstr(cli->tree));
879 printf("maxfid test finished\n");
880 if (!torture_close_connection(cli)) {
884 #undef MAXFID_TEMPLATE
887 /* send smb negprot commands, not reading the response */
888 static BOOL run_negprot_nowait(void)
891 struct smbcli_state *cli, *cli2;
894 printf("starting negprot nowait test\n");
896 cli = open_nbt_connection();
901 printf("Filling send buffer\n");
903 for (i=0;i<1000;i++) {
904 struct smbcli_request *req;
905 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
906 smbcli_transport_process(cli->transport);
907 if (req->state == SMBCLI_REQUEST_ERROR) {
908 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
909 torture_close_connection(cli);
914 printf("Opening secondary connection\n");
915 if (!torture_open_connection(&cli2)) {
919 if (!torture_close_connection(cli)) {
923 if (!torture_close_connection(cli2)) {
927 printf("finished negprot nowait test\n");
934 This checks how the getatr calls works
936 static BOOL run_attrtest(void)
938 struct smbcli_state *cli;
941 const char *fname = "\\attrib123456789.tst";
944 printf("starting attrib test\n");
946 if (!torture_open_connection(&cli)) {
950 smbcli_unlink(cli->tree, fname);
951 fnum = smbcli_open(cli->tree, fname,
952 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
953 smbcli_close(cli->tree, fnum);
955 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
956 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
960 printf("New file time is %s", ctime(&t));
962 if (abs(t - time(NULL)) > 60*60*24*10) {
963 printf("ERROR: SMBgetatr bug. time is %s",
969 t2 = t-60*60*24; /* 1 day ago */
971 printf("Setting file time to %s", ctime(&t2));
973 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
974 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
978 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
979 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
983 printf("Retrieved file time as %s", ctime(&t));
986 printf("ERROR: getatr/setatr bug. times are\n%s",
988 printf("%s", ctime(&t2));
992 smbcli_unlink(cli->tree, fname);
994 if (!torture_close_connection(cli)) {
998 printf("attrib test finished\n");
1005 This checks a couple of trans2 calls
1007 static BOOL run_trans2test(void)
1009 struct smbcli_state *cli;
1012 time_t c_time, a_time, m_time, w_time, m_time2;
1013 const char *fname = "\\trans2.tst";
1014 const char *dname = "\\trans2";
1015 const char *fname2 = "\\trans2\\trans2.tst";
1017 BOOL correct = True;
1019 printf("starting trans2 test\n");
1021 if (!torture_open_connection(&cli)) {
1025 smbcli_unlink(cli->tree, fname);
1027 printf("Testing qfileinfo\n");
1029 fnum = smbcli_open(cli->tree, fname,
1030 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1031 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
1033 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
1037 printf("Testing NAME_INFO\n");
1039 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
1040 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
1044 if (!pname || strcmp(pname, fname)) {
1045 printf("qfilename gave different name? [%s] [%s]\n",
1050 smbcli_close(cli->tree, fnum);
1051 smbcli_unlink(cli->tree, fname);
1053 fnum = smbcli_open(cli->tree, fname,
1054 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1056 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1059 smbcli_close(cli->tree, fnum);
1061 printf("Checking for sticky create times\n");
1063 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1064 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
1067 if (c_time != m_time) {
1068 printf("create time=%s", ctime(&c_time));
1069 printf("modify time=%s", ctime(&m_time));
1070 printf("This system appears to have sticky create times\n");
1072 if (a_time % (60*60) == 0) {
1073 printf("access time=%s", ctime(&a_time));
1074 printf("This system appears to set a midnight access time\n");
1078 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1079 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1085 smbcli_unlink(cli->tree, fname);
1086 fnum = smbcli_open(cli->tree, fname,
1087 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1088 smbcli_close(cli->tree, fnum);
1089 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1090 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1093 if (w_time < 60*60*24*2) {
1094 printf("write time=%s", ctime(&w_time));
1095 printf("This system appears to set a initial 0 write time\n");
1100 smbcli_unlink(cli->tree, fname);
1103 /* check if the server updates the directory modification time
1104 when creating a new file */
1105 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1106 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
1110 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1111 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1115 fnum = smbcli_open(cli->tree, fname2,
1116 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1117 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
1118 smbcli_close(cli->tree, fnum);
1119 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
1120 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1123 if (m_time2 == m_time) {
1124 printf("This system does not update directory modification times\n");
1128 smbcli_unlink(cli->tree, fname2);
1129 smbcli_rmdir(cli->tree, dname);
1131 if (!torture_close_connection(cli)) {
1135 printf("trans2 test finished\n");
1142 /* FIRST_DESIRED_ACCESS 0xf019f */
1143 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1144 SEC_FILE_READ_EA| /* 0xf */ \
1145 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1146 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1147 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1148 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1149 /* SECOND_DESIRED_ACCESS 0xe0080 */
1150 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1151 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1152 SEC_STD_WRITE_OWNER /* 0xe0000 */
1155 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1156 READ_CONTROL|WRITE_DAC|\
1157 SEC_FILE_READ_DATA|\
1162 Test ntcreate calls made by xcopy
1164 static BOOL run_xcopy(void)
1166 struct smbcli_state *cli1;
1167 const char *fname = "\\test.txt";
1168 BOOL correct = True;
1171 printf("starting xcopy test\n");
1173 if (!torture_open_connection(&cli1)) {
1177 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1178 FIRST_DESIRED_ACCESS,
1179 FILE_ATTRIBUTE_ARCHIVE,
1180 NTCREATEX_SHARE_ACCESS_NONE,
1181 NTCREATEX_DISP_OVERWRITE_IF,
1185 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
1189 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1190 SECOND_DESIRED_ACCESS, 0,
1191 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1194 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
1198 if (!torture_close_connection(cli1)) {
1207 see how many RPC pipes we can open at once
1209 static BOOL run_pipe_number(void)
1211 struct smbcli_state *cli1;
1212 const char *pipe_name = "\\WKSSVC";
1216 printf("starting pipenumber test\n");
1217 if (!torture_open_connection(&cli1)) {
1222 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1223 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1226 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
1230 printf("%d\r", num_pipes);
1234 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
1235 torture_close_connection(cli1);
1243 open N connections to the server and just hold them open
1244 used for testing performance when there are N idle users
1247 static BOOL torture_holdcon(void)
1250 struct smbcli_state **cli;
1253 printf("Opening %d connections\n", torture_numops);
1255 cli = malloc_array_p(struct smbcli_state *, torture_numops);
1257 for (i=0;i<torture_numops;i++) {
1258 if (!torture_open_connection(&cli[i])) {
1261 printf("opened %d connections\r", i);
1265 printf("\nStarting pings\n");
1268 for (i=0;i<torture_numops;i++) {
1271 status = smbcli_chkpath(cli[i]->tree, "\\");
1272 if (!NT_STATUS_IS_OK(status)) {
1273 printf("Connection %d is dead\n", i);
1281 if (num_dead == torture_numops) {
1282 printf("All connections dead - finishing\n");
1294 Try with a wrong vuid and check error message.
1297 static BOOL run_vuidtest(void)
1299 struct smbcli_state *cli;
1300 const char *fname = "\\vuid.tst";
1303 time_t c_time, a_time, m_time;
1304 BOOL correct = True;
1309 printf("starting vuid test\n");
1311 if (!torture_open_connection(&cli)) {
1315 smbcli_unlink(cli->tree, fname);
1317 fnum = smbcli_open(cli->tree, fname,
1318 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1320 orig_vuid = cli->session->vuid;
1322 cli->session->vuid += 1234;
1324 printf("Testing qfileinfo with wrong vuid\n");
1326 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
1327 &size, &c_time, &a_time,
1328 &m_time, NULL, NULL))) {
1329 printf("ERROR: qfileinfo passed with wrong vuid\n");
1333 if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1334 NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
1335 !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1336 NT_STATUS_INVALID_HANDLE)) {
1337 printf("ERROR: qfileinfo should have returned DOS error "
1338 "ERRSRV:ERRbaduid\n but returned %s\n",
1339 smbcli_errstr(cli->tree));
1343 cli->session->vuid -= 1234;
1345 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1346 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
1350 smbcli_unlink(cli->tree, fname);
1352 if (!torture_close_connection(cli)) {
1356 printf("vuid test finished\n");
1362 Test open mode returns on read-only files.
1364 static BOOL run_opentest(void)
1366 static struct smbcli_state *cli1;
1367 static struct smbcli_state *cli2;
1368 const char *fname = "\\readonly.file";
1369 char *control_char_fname;
1373 BOOL correct = True;
1378 printf("starting open test\n");
1380 if (!torture_open_connection(&cli1)) {
1384 asprintf(&control_char_fname, "\\readonly.afile");
1385 for (i = 1; i <= 0x1f; i++) {
1386 control_char_fname[10] = i;
1387 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
1388 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1390 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
1391 NT_STATUS_OBJECT_NAME_INVALID)) {
1392 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
1393 smbcli_errstr(cli1->tree), i);
1398 smbcli_close(cli1->tree, fnum1);
1400 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
1401 smbcli_unlink(cli1->tree, control_char_fname);
1403 free(control_char_fname);
1406 printf("Create file with control char names passed.\n");
1408 smbcli_setatr(cli1->tree, fname, 0, 0);
1409 smbcli_unlink(cli1->tree, fname);
1411 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1413 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1417 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1418 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1422 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
1423 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
1424 CHECK_MAX_FAILURES(error_test1);
1428 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1430 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1431 CHECK_MAX_FAILURES(error_test1);
1435 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
1436 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1438 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
1439 NT_STATUS_ACCESS_DENIED)) {
1440 printf("correct error code ERRDOS/ERRnoaccess returned\n");
1443 printf("finished open test 1\n");
1445 smbcli_close(cli1->tree, fnum1);
1447 /* Now try not readonly and ensure ERRbadshare is returned. */
1449 smbcli_setatr(cli1->tree, fname, 0, 0);
1451 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1453 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1457 /* This will fail - but the error should be ERRshare. */
1458 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1460 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
1461 NT_STATUS_SHARING_VIOLATION)) {
1462 printf("correct error code ERRDOS/ERRbadshare returned\n");
1465 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1466 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1470 smbcli_unlink(cli1->tree, fname);
1472 printf("finished open test 2\n");
1474 /* Test truncate open disposition on file opened for read. */
1476 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1478 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1482 /* write 20 bytes. */
1484 memset(buf, '\0', 20);
1486 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1487 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1491 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1492 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1496 /* Ensure size == 20. */
1497 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1498 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1499 CHECK_MAX_FAILURES(error_test3);
1504 printf("(3) file size != 20\n");
1505 CHECK_MAX_FAILURES(error_test3);
1509 /* Now test if we can truncate a file opened for readonly. */
1511 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
1513 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1514 CHECK_MAX_FAILURES(error_test3);
1518 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1519 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1523 /* Ensure size == 0. */
1524 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1525 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1526 CHECK_MAX_FAILURES(error_test3);
1531 printf("(3) file size != 0\n");
1532 CHECK_MAX_FAILURES(error_test3);
1535 printf("finished open test 3\n");
1537 smbcli_unlink(cli1->tree, fname);
1540 printf("testing ctemp\n");
1541 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
1543 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1544 CHECK_MAX_FAILURES(error_test4);
1547 printf("ctemp gave path %s\n", tmp_path);
1548 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1549 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1551 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1552 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1555 /* Test the non-io opens... */
1557 if (!torture_open_connection(&cli2)) {
1561 smbcli_setatr(cli2->tree, fname, 0, 0);
1562 smbcli_unlink(cli2->tree, fname);
1564 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1566 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1567 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1570 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1571 CHECK_MAX_FAILURES(error_test10);
1575 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1576 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1578 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1579 CHECK_MAX_FAILURES(error_test10);
1583 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1584 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1587 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1588 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1592 printf("non-io open test #1 passed.\n");
1594 smbcli_unlink(cli1->tree, fname);
1596 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1598 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1599 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1602 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1603 CHECK_MAX_FAILURES(error_test20);
1607 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1608 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1611 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1612 CHECK_MAX_FAILURES(error_test20);
1616 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1617 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1620 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1621 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1625 printf("non-io open test #2 passed.\n");
1627 smbcli_unlink(cli1->tree, fname);
1629 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1631 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1632 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1635 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1636 CHECK_MAX_FAILURES(error_test30);
1640 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1641 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1644 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1645 CHECK_MAX_FAILURES(error_test30);
1649 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1650 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1653 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1654 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1658 printf("non-io open test #3 passed.\n");
1660 smbcli_unlink(cli1->tree, fname);
1662 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1664 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1665 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1668 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1669 CHECK_MAX_FAILURES(error_test40);
1673 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1674 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1677 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1678 CHECK_MAX_FAILURES(error_test40);
1682 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1684 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1685 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1689 printf("non-io open test #4 passed.\n");
1691 smbcli_unlink(cli1->tree, fname);
1693 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1695 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1696 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1699 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1700 CHECK_MAX_FAILURES(error_test50);
1704 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1705 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1708 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1709 CHECK_MAX_FAILURES(error_test50);
1713 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1714 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1718 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1719 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1723 printf("non-io open test #5 passed.\n");
1725 printf("TEST #6 testing 1 non-io open, one io open\n");
1727 smbcli_unlink(cli1->tree, fname);
1729 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1730 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1733 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1734 CHECK_MAX_FAILURES(error_test60);
1738 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1739 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1742 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1743 CHECK_MAX_FAILURES(error_test60);
1747 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1748 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1752 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1753 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1757 printf("non-io open test #6 passed.\n");
1759 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
1761 smbcli_unlink(cli1->tree, fname);
1763 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1764 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1767 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1768 CHECK_MAX_FAILURES(error_test70);
1772 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1773 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1776 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1777 CHECK_MAX_FAILURES(error_test70);
1781 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1783 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1784 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1788 printf("non-io open test #7 passed.\n");
1792 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1794 smbcli_unlink(cli1->tree, fname);
1796 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1798 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1802 /* write 20 bytes. */
1804 memset(buf, '\0', 20);
1806 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1807 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1811 /* Ensure size == 20. */
1812 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1813 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1814 CHECK_MAX_FAILURES(error_test80);
1819 printf("(8) file size != 20\n");
1820 CHECK_MAX_FAILURES(error_test80);
1824 /* Get an exclusive lock on the open file. */
1825 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1826 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1827 CHECK_MAX_FAILURES(error_test80);
1831 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1833 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1837 /* Ensure size == 0. */
1838 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1839 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1840 CHECK_MAX_FAILURES(error_test80);
1845 printf("(8) file size != 0\n");
1846 CHECK_MAX_FAILURES(error_test80);
1850 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1851 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1855 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1856 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1862 printf("open test #8 passed.\n");
1864 smbcli_unlink(cli1->tree, fname);
1866 if (!torture_close_connection(cli1)) {
1869 if (!torture_close_connection(cli2)) {
1878 sees what IOCTLs are supported
1880 BOOL torture_ioctl_test(void)
1882 struct smbcli_state *cli;
1883 uint16_t device, function;
1885 const char *fname = "\\ioctl.dat";
1887 union smb_ioctl parms;
1888 TALLOC_CTX *mem_ctx;
1890 if (!torture_open_connection(&cli)) {
1894 mem_ctx = talloc_init("ioctl_test");
1896 printf("starting ioctl test\n");
1898 smbcli_unlink(cli->tree, fname);
1900 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1902 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1906 parms.ioctl.level = RAW_IOCTL_IOCTL;
1907 parms.ioctl.in.fnum = fnum;
1908 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
1909 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1910 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
1912 for (device=0;device<0x100;device++) {
1913 printf("testing device=0x%x\n", device);
1914 for (function=0;function<0x100;function++) {
1915 parms.ioctl.in.request = (device << 16) | function;
1916 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1918 if (NT_STATUS_IS_OK(status)) {
1919 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
1920 device, function, (int)parms.ioctl.out.blob.length);
1925 if (!torture_close_connection(cli)) {
1934 tries variants of chkpath
1936 BOOL torture_chkpath_test(void)
1938 struct smbcli_state *cli;
1942 if (!torture_open_connection(&cli)) {
1946 printf("starting chkpath test\n");
1948 printf("Testing valid and invalid paths\n");
1950 /* cleanup from an old run */
1951 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1952 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1953 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1955 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1956 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1960 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1961 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1965 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1967 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
1970 smbcli_close(cli->tree, fnum);
1972 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1973 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1977 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1978 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1982 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1983 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1984 NT_STATUS_NOT_A_DIRECTORY);
1986 printf("* chkpath on a file should fail\n");
1990 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
1991 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1992 NT_STATUS_OBJECT_NAME_NOT_FOUND);
1994 printf("* chkpath on a non existent file should fail\n");
1998 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
1999 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
2000 NT_STATUS_OBJECT_PATH_NOT_FOUND);
2002 printf("* chkpath on a non existent component should fail\n");
2006 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
2007 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
2008 smbcli_rmdir(cli->tree, "\\chkpath.dir");
2010 if (!torture_close_connection(cli)) {
2018 static void sigcont(int sig)
2022 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
2025 volatile pid_t *child_status;
2026 volatile BOOL *child_status_out;
2029 double start_time_limit = 10 + (torture_nprocs * 1.5);
2030 char **unc_list = NULL;
2032 int num_unc_names = 0;
2039 signal(SIGCONT, sigcont);
2041 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
2042 if (!child_status) {
2043 printf("Failed to setup shared memory\n");
2047 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
2048 if (!child_status_out) {
2049 printf("Failed to setup result status shared memory\n");
2053 p = lp_parm_string(-1, "torture", "unclist");
2055 unc_list = file_lines_load(p, &num_unc_names, NULL);
2056 if (!unc_list || num_unc_names <= 0) {
2057 printf("Failed to load unc names list from '%s'\n", p);
2062 for (i = 0; i < torture_nprocs; i++) {
2063 child_status[i] = 0;
2064 child_status_out[i] = True;
2067 tv = timeval_current();
2069 for (i=0;i<torture_nprocs;i++) {
2073 const char *hostname=NULL, *sharename;
2075 pid_t mypid = getpid();
2076 srandom(((int)mypid) ^ ((int)time(NULL)));
2078 asprintf(&myname, "CLIENT%d", i);
2079 lp_set_cmdline("netbios name", myname);
2084 if (!smbcli_parse_unc(unc_list[i % num_unc_names],
2085 NULL, &hostname, &sharename)) {
2086 printf("Failed to parse UNC name %s\n",
2087 unc_list[i % num_unc_names]);
2094 if (torture_open_connection_share(NULL,
2101 } else if (torture_open_connection(¤t_cli)) {
2105 printf("pid %d failed to start\n", (int)getpid());
2111 child_status[i] = getpid();
2115 if (child_status[i]) {
2116 printf("Child %d failed to start!\n", i);
2117 child_status_out[i] = 1;
2121 child_status_out[i] = fn(current_cli, i);
2128 for (i=0;i<torture_nprocs;i++) {
2129 if (child_status[i]) synccount++;
2131 if (synccount == torture_nprocs) break;
2133 } while (timeval_elapsed(&tv) < start_time_limit);
2135 if (synccount != torture_nprocs) {
2136 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
2138 return timeval_elapsed(&tv);
2141 printf("Starting %d clients\n", torture_nprocs);
2143 /* start the client load */
2144 tv = timeval_current();
2145 for (i=0;i<torture_nprocs;i++) {
2146 child_status[i] = 0;
2149 printf("%d clients started\n", torture_nprocs);
2153 for (i=0;i<torture_nprocs;i++) {
2155 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
2156 if (ret == -1 || WEXITSTATUS(status) != 0) {
2163 for (i=0;i<torture_nprocs;i++) {
2164 if (!child_status_out[i]) {
2168 return timeval_elapsed(&tv);
2171 #define FLAG_MULTIPROC 1
2176 BOOL (*multi_fn)(struct smbcli_state *, int );
2179 {"BASE-FDPASS", run_fdpasstest, 0},
2180 {"BASE-LOCK1", torture_locktest1, 0},
2181 {"BASE-LOCK2", torture_locktest2, 0},
2182 {"BASE-LOCK3", torture_locktest3, 0},
2183 {"BASE-LOCK4", torture_locktest4, 0},
2184 {"BASE-LOCK5", torture_locktest5, 0},
2185 {"BASE-LOCK6", torture_locktest6, 0},
2186 {"BASE-LOCK7", torture_locktest7, 0},
2187 {"BASE-UNLINK", torture_unlinktest, 0},
2188 {"BASE-ATTR", run_attrtest, 0},
2189 {"BASE-TRANS2", run_trans2test, 0},
2190 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
2191 {"BASE-DIR1", torture_dirtest1, 0},
2192 {"BASE-DIR2", torture_dirtest2, 0},
2193 {"BASE-DENY1", torture_denytest1, 0},
2194 {"BASE-DENY2", torture_denytest2, 0},
2195 {"BASE-DENY3", torture_denytest3, 0},
2196 {"BASE-DENYDOS", torture_denydos_sharing, 0},
2197 {"BASE-NTDENY1", NULL, torture_ntdenytest1},
2198 {"BASE-NTDENY2", torture_ntdenytest2, 0},
2199 {"BASE-TCON", run_tcon_test, 0},
2200 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
2201 {"BASE-VUID", run_vuidtest, 0},
2202 {"BASE-RW1", run_readwritetest, 0},
2203 {"BASE-OPEN", run_opentest, 0},
2204 {"BASE-DEFER_OPEN", NULL, run_deferopen},
2205 {"BASE-XCOPY", run_xcopy, 0},
2206 {"BASE-RENAME", torture_test_rename, 0},
2207 {"BASE-DELETE", torture_test_delete, 0},
2208 {"BASE-PROPERTIES", torture_test_properties, 0},
2209 {"BASE-MANGLE", torture_mangle, 0},
2210 {"BASE-OPENATTR", torture_openattrtest, 0},
2211 {"BASE-CHARSET", torture_charset, 0},
2212 {"BASE-CHKPATH", torture_chkpath_test, 0},
2213 {"BASE-SECLEAK", torture_sec_leak, 0},
2214 {"BASE-DISCONNECT", torture_disconnect, 0},
2215 {"BASE-DELAYWRITE", torture_delay_write, 0},
2217 /* benchmarking tests */
2218 {"BENCH-HOLDCON", torture_holdcon, 0},
2219 {"BENCH-NBENCH", torture_nbench, 0},
2220 {"BENCH-TORTURE", NULL, run_torture},
2221 {"BENCH-NBT", torture_bench_nbt, 0},
2222 {"BENCH-WINS", torture_bench_wins, 0},
2223 {"BENCH-RPC", torture_bench_rpc, 0},
2224 {"BENCH-CLDAP", torture_bench_cldap, 0},
2227 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
2228 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
2229 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
2230 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
2231 {"RAW-SEARCH", torture_raw_search, 0},
2232 {"RAW-CLOSE", torture_raw_close, 0},
2233 {"RAW-OPEN", torture_raw_open, 0},
2234 {"RAW-MKDIR", torture_raw_mkdir, 0},
2235 {"RAW-OPLOCK", torture_raw_oplock, 0},
2236 {"RAW-NOTIFY", torture_raw_notify, 0},
2237 {"RAW-MUX", torture_raw_mux, 0},
2238 {"RAW-IOCTL", torture_raw_ioctl, 0},
2239 {"RAW-CHKPATH", torture_raw_chkpath, 0},
2240 {"RAW-UNLINK", torture_raw_unlink, 0},
2241 {"RAW-READ", torture_raw_read, 0},
2242 {"RAW-WRITE", torture_raw_write, 0},
2243 {"RAW-LOCK", torture_raw_lock, 0},
2244 {"RAW-CONTEXT", torture_raw_context, 0},
2245 {"RAW-RENAME", torture_raw_rename, 0},
2246 {"RAW-SEEK", torture_raw_seek, 0},
2247 {"RAW-EAS", torture_raw_eas, 0},
2248 {"RAW-EAMAX", torture_max_eas, 0},
2249 {"RAW-STREAMS", torture_raw_streams, 0},
2250 {"RAW-ACLS", torture_raw_acls, 0},
2251 {"RAW-RAP", torture_raw_rap, 0},
2252 {"RAW-COMPOSITE", torture_raw_composite, 0},
2255 {"SMB2-CONNECT", torture_smb2_connect, 0},
2256 {"SMB2-SCAN", torture_smb2_scan, 0},
2257 {"SMB2-SCANGETINFO", torture_smb2_getinfo_scan, 0},
2258 {"SMB2-SCANSETINFO", torture_smb2_setinfo_scan, 0},
2259 {"SMB2-SCANFIND", torture_smb2_find_scan, 0},
2260 {"SMB2-GETINFO", torture_smb2_getinfo, 0},
2261 {"SMB2-SETINFO", torture_smb2_setinfo, 0},
2262 {"SMB2-FIND", torture_smb2_find, 0},
2264 /* protocol scanners */
2265 {"SCAN-TRANS2", torture_trans2_scan, 0},
2266 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2267 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2268 {"SCAN-SMB", torture_smb_scan, 0},
2269 {"SCAN-MAXFID", NULL, run_maxfidtest},
2270 {"SCAN-UTABLE", torture_utable, 0},
2271 {"SCAN-CASETABLE", torture_casetable, 0},
2272 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2273 {"SCAN-IOCTL", torture_ioctl_test, 0},
2274 {"SCAN-RAP", torture_rap_scan, 0},
2277 {"RPC-LSA", torture_rpc_lsa, 0},
2278 {"RPC-SECRETS", torture_rpc_lsa_secrets, 0},
2279 {"RPC-ECHO", torture_rpc_echo, 0},
2280 {"RPC-DFS", torture_rpc_dfs, 0},
2281 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
2282 {"RPC-SAMR", torture_rpc_samr, 0},
2283 {"RPC-UNIXINFO", torture_rpc_unixinfo, 0},
2284 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
2285 {"RPC-SAMLOGON", torture_rpc_samlogon, 0},
2286 {"RPC-SAMSYNC", torture_rpc_samsync, 0},
2287 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
2288 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
2289 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
2290 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
2291 {"RPC-ATSVC", torture_rpc_atsvc, 0},
2292 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
2293 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
2294 {"RPC-WINREG", torture_rpc_winreg, 0},
2295 {"RPC-INITSHUTDOWN", torture_rpc_initshutdown, 0},
2296 {"RPC-OXIDRESOLVE", torture_rpc_oxidresolve, 0},
2297 {"RPC-REMACT", torture_rpc_remact, 0},
2298 {"RPC-MGMT", torture_rpc_mgmt, 0},
2299 {"RPC-SCANNER", torture_rpc_scanner, 0},
2300 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
2301 {"RPC-COUNTCALLS", torture_rpc_countcalls, 0},
2302 {"RPC-MULTIBIND", torture_multi_bind, 0},
2303 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
2304 {"RPC-CRACKNAMES", torture_rpc_drsuapi_cracknames, 0},
2305 {"RPC-LOGIN", torture_rpc_login, 0},
2306 {"RPC-ROT", torture_rpc_rot, 0},
2307 {"RPC-DSSETUP", torture_rpc_dssetup, 0},
2308 {"RPC-ALTERCONTEXT", torture_rpc_alter_context, 0},
2309 {"RPC-JOIN", torture_rpc_join, 0},
2310 {"RPC-DSSYNC", torture_rpc_dssync, 0},
2312 /* local (no server) testers */
2313 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2314 {"LOCAL-ICONV", torture_local_iconv, 0},
2315 {"LOCAL-TALLOC", torture_local_talloc, 0},
2316 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2317 {"LOCAL-IRPC", torture_local_irpc, 0},
2318 {"LOCAL-BINDING", torture_local_binding_string, 0},
2319 {"LOCAL-STRLIST", torture_local_util_strlist, 0},
2320 {"LOCAL-FILE", torture_local_util_file, 0},
2321 {"LOCAL-IDTREE", torture_local_idtree, 0},
2322 {"LOCAL-SOCKET", torture_local_socket, 0},
2323 {"LOCAL-PAC", torture_pac, 0},
2324 {"LOCAL-REGISTRY", torture_registry, 0},
2325 {"LOCAL-RESOLVE", torture_local_resolve, 0},
2327 /* COM (Component Object Model) testers */
2328 {"COM-SIMPLE", torture_com_simple, 0 },
2331 {"LDAP-BASIC", torture_ldap_basic, 0},
2332 {"LDAP-CLDAP", torture_cldap, 0},
2335 {"NBT-REGISTER", torture_nbt_register, 0},
2336 {"NBT-WINS", torture_nbt_wins, 0},
2337 {"NBT-DGRAM", torture_nbt_dgram, 0},
2338 {"NBT-WINSREPLICATION-QUICK", torture_nbt_winsreplication_quick, 0},
2339 {"NBT-WINSREPLICATION", torture_nbt_winsreplication, 0},
2342 {"NET-USERINFO", torture_userinfo, 0},
2343 {"NET-USERADD", torture_useradd, 0},
2344 {"NET-USERDEL", torture_userdel, 0},
2345 {"NET-USERMOD", torture_usermod, 0},
2346 {"NET-DOMOPEN", torture_domainopen, 0},
2347 {"NET-API-LOOKUP", torture_lookup, 0},
2348 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2349 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2350 {"NET-API-CREATEUSER", torture_createuser, 0},
2351 {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
2352 {"NET-API-LISTSHARES", torture_listshares, 0},
2353 {"NET-API-DELSHARE", torture_delshare, 0},
2359 /****************************************************************************
2360 run a specified test or "ALL"
2361 ****************************************************************************/
2362 static BOOL run_test(const char *name)
2366 BOOL matched = False;
2368 if (strequal(name,"ALL")) {
2369 for (i=0;torture_ops[i].name;i++) {
2370 if (!run_test(torture_ops[i].name)) {
2377 for (i=0;torture_ops[i].name;i++) {
2378 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
2382 printf("Running %s\n", torture_ops[i].name);
2383 if (torture_ops[i].multi_fn) {
2384 BOOL result = False;
2385 t = torture_create_procs(torture_ops[i].multi_fn,
2389 printf("TEST %s FAILED!\n", torture_ops[i].name);
2393 struct timeval tv = timeval_current();
2394 if (!torture_ops[i].fn()) {
2396 printf("TEST %s FAILED!\n", torture_ops[i].name);
2398 t = timeval_elapsed(&tv);
2400 printf("%s took %g secs\n\n", torture_ops[i].name, t);
2405 printf("Unknown torture operation '%s'\n", name);
2412 static void parse_dns(const char *dns)
2414 char *userdn, *basedn, *secret;
2417 /* retrievieng the userdn */
2418 p = strchr_m(dns, '#');
2420 lp_set_cmdline("torture:ldap_userdn", "");
2421 lp_set_cmdline("torture:ldap_basedn", "");
2422 lp_set_cmdline("torture:ldap_secret", "");
2425 userdn = strndup(dns, p - dns);
2426 lp_set_cmdline("torture:ldap_userdn", userdn);
2428 /* retrieve the basedn */
2430 p = strchr_m(d, '#');
2432 lp_set_cmdline("torture:ldap_basedn", "");
2433 lp_set_cmdline("torture:ldap_secret", "");
2436 basedn = strndup(d, p - d);
2437 lp_set_cmdline("torture:ldap_basedn", basedn);
2439 /* retrieve the secret */
2442 lp_set_cmdline("torture:ldap_secret", "");
2446 lp_set_cmdline("torture:ldap_secret", secret);
2448 printf ("%s - %s - %s\n", userdn, basedn, secret);
2452 static void usage(poptContext pc)
2457 poptPrintUsage(pc, stdout, 0);
2460 printf("The binding format is:\n\n");
2462 printf(" TRANSPORT:host[flags]\n\n");
2464 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2466 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2467 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2468 printf(" string.\n\n");
2470 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2471 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2472 printf(" will be auto-determined.\n\n");
2474 printf(" other recognised flags are:\n\n");
2476 printf(" sign : enable ntlmssp signing\n");
2477 printf(" seal : enable ntlmssp sealing\n");
2478 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2479 printf(" validate: enable the NDR validator\n");
2480 printf(" print: enable debugging of the packets\n");
2481 printf(" bigendian: use bigendian RPC\n");
2482 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2484 printf(" For example, these all connect to the samr pipe:\n\n");
2486 printf(" ncacn_np:myserver\n");
2487 printf(" ncacn_np:myserver[samr]\n");
2488 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2489 printf(" ncacn_np:myserver[/pipe/samr]\n");
2490 printf(" ncacn_np:myserver[samr,sign,print]\n");
2491 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2492 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2493 printf(" ncacn_np:\n");
2494 printf(" ncacn_np:[/pipe/samr]\n\n");
2496 printf(" ncacn_ip_tcp:myserver\n");
2497 printf(" ncacn_ip_tcp:myserver[1024]\n");
2498 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2500 printf("The unc format is:\n\n");
2502 printf(" //server/share\n\n");
2504 printf("tests are:");
2505 for (i=0;torture_ops[i].name;i++) {
2506 if ((i%perline)==0) {
2509 printf("%s ", torture_ops[i].name);
2513 printf("default test is ALL\n");
2518 static BOOL is_binding_string(const char *binding_string)
2520 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2521 struct dcerpc_binding *binding_struct;
2524 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2526 talloc_free(mem_ctx);
2527 return NT_STATUS_IS_OK(status);
2530 static void max_runtime_handler(int sig)
2532 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2536 /****************************************************************************
2538 ****************************************************************************/
2539 int main(int argc,char *argv[])
2543 BOOL correct = True;
2548 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,OPT_DANGEROUS};
2549 struct poptOption long_options[] = {
2551 {"smb-ports", 'p', POPT_ARG_STRING, NULL, 0, "SMB ports", NULL},
2552 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2553 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2554 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2555 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2556 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2557 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2558 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2559 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2560 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2561 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2562 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2563 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2564 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2565 "set maximum time for smbtorture to live", "seconds"},
2567 POPT_COMMON_CONNECTION
2568 POPT_COMMON_CREDENTIALS
2573 #ifdef HAVE_SETBUFFER
2574 setbuffer(stdout, NULL, 0);
2577 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2578 POPT_CONTEXT_KEEP_FIRST);
2580 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2582 while((opt = poptGetNextOpt(pc)) != -1) {
2585 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2588 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2591 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2594 parse_dns(poptGetOptArg(pc));
2597 lp_set_cmdline("torture:dangerous", "Yes");
2600 d_printf("Invalid option %s: %s\n",
2601 poptBadOption(pc, 0), poptStrerror(opt));
2608 /* this will only work if nobody else uses alarm(),
2609 which means it won't work for some tests, but we
2610 can't use the event context method we use for smbd
2611 as so many tests create their own event
2612 context. This will at least catch most cases. */
2613 signal(SIGALRM, max_runtime_handler);
2617 smbtorture_init_subsystems;
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])) {