2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-2003
5 Copyright (C) Jelmer Vernooij 2006
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 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"
28 #include "libcli/raw/ioctl.h"
29 #include "libcli/libcli.h"
30 #include "lib/ldb/include/ldb.h"
31 #include "lib/events/events.h"
32 #include "libcli/resolve/resolve.h"
33 #include "auth/credentials/credentials.h"
34 #include "librpc/rpc/dcerpc_table.h"
35 #include "libcli/ldap/ldap_client.h"
37 #include "torture/basic/proto.h"
38 #include "torture/raw/proto.h"
39 #include "torture/smb2/proto.h"
40 #include "torture/rap/proto.h"
41 #include "torture/auth/proto.h"
42 #include "torture/local/proto.h"
43 #include "torture/nbench/proto.h"
44 #include "torture/ldap/proto.h"
45 #include "torture/com/proto.h"
46 #include "torture/nbt/proto.h"
47 #include "torture/libnet/proto.h"
48 #include "torture/torture.h"
50 #include "dlinklist.h"
53 int torture_numops=10;
54 int torture_entries=1000;
55 int torture_failures=1;
57 static int procnum; /* records process count number when forking */
58 static struct smbcli_state *current_cli;
59 static BOOL use_oplocks;
60 static BOOL use_level_II_oplocks;
61 #define MAX_COLS 80 /* FIXME: Determine this at run-time */
63 BOOL torture_showall = False;
65 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
67 static struct smbcli_state *open_nbt_connection(void)
69 struct nbt_name called, calling;
70 struct smbcli_state *cli;
71 const char *host = lp_parm_string(-1, "torture", "host");
73 make_nbt_name_client(&calling, lp_netbios_name());
75 nbt_choose_called_name(NULL, &called, host, NBT_NAME_SERVER);
77 cli = smbcli_state_init(NULL);
79 printf("Failed initialize smbcli_struct to connect with %s\n", host);
83 if (!smbcli_socket_connect(cli, host)) {
84 printf("Failed to connect with %s\n", host);
88 if (!smbcli_transport_establish(cli, &calling, &called)) {
89 printf("%s rejected the session\n",host);
100 BOOL torture_open_connection_share(TALLOC_CTX *mem_ctx,
101 struct smbcli_state **c,
102 const char *hostname,
103 const char *sharename,
104 struct event_context *ev)
108 status = smbcli_full_connection(mem_ctx, c, hostname,
110 cmdline_credentials, ev);
111 if (!NT_STATUS_IS_OK(status)) {
112 printf("Failed to open connection - %s\n", nt_errstr(status));
116 (*c)->transport->options.use_oplocks = use_oplocks;
117 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
122 BOOL torture_open_connection(struct smbcli_state **c)
124 const char *host = lp_parm_string(-1, "torture", "host");
125 const char *share = lp_parm_string(-1, "torture", "share");
127 return torture_open_connection_share(NULL, c, host, share, NULL);
132 BOOL torture_close_connection(struct smbcli_state *c)
136 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
137 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
145 /* check if the server produced the expected error code */
146 BOOL check_error(const char *location, struct smbcli_state *c,
147 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
151 status = smbcli_nt_error(c->tree);
152 if (NT_STATUS_IS_DOS(status)) {
154 class = NT_STATUS_DOS_CLASS(status);
155 num = NT_STATUS_DOS_CODE(status);
156 if (eclass != class || ecode != num) {
157 printf("unexpected error code %s\n", nt_errstr(status));
158 printf(" expected %s or %s (at %s)\n",
159 nt_errstr(NT_STATUS_DOS(eclass, ecode)),
160 nt_errstr(nterr), location);
164 if (!NT_STATUS_EQUAL(nterr, status)) {
165 printf("unexpected error code %s\n", nt_errstr(status));
166 printf(" expected %s (at %s)\n", nt_errstr(nterr), location);
175 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
177 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
178 if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
184 static BOOL rw_torture(struct smbcli_state *c)
186 const char *lockfname = "\\torture.lck";
190 pid_t pid2, pid = getpid();
195 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
198 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
200 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
205 for (i=0;i<torture_numops;i++) {
206 uint_t n = (uint_t)random()%10;
208 printf("%d\r", i); fflush(stdout);
210 asprintf(&fname, "\\torture.%u", n);
212 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
216 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
218 printf("open failed (%s)\n", smbcli_errstr(c->tree));
223 if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
224 printf("write failed (%s)\n", smbcli_errstr(c->tree));
229 if (smbcli_write(c->tree, fnum, 0, buf,
230 sizeof(pid)+(j*sizeof(buf)),
231 sizeof(buf)) != sizeof(buf)) {
232 printf("write failed (%s)\n", smbcli_errstr(c->tree));
239 if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
240 printf("read failed (%s)\n", smbcli_errstr(c->tree));
245 printf("data corruption!\n");
249 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
250 printf("close failed (%s)\n", smbcli_errstr(c->tree));
254 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
255 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
259 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
260 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
266 smbcli_close(c->tree, fnum2);
267 smbcli_unlink(c->tree, lockfname);
274 static BOOL run_torture(struct smbcli_state *cli, int dummy)
278 ret = rw_torture(cli);
280 if (!torture_close_connection(cli)) {
288 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
290 const char *lockfname = "\\torture2.lck";
295 uint8_t buf_rd[131072];
297 ssize_t bytes_read, bytes_written;
299 if (smbcli_deltree(c1->tree, lockfname) == -1) {
300 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
303 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
306 printf("first open read/write of %s failed (%s)\n",
307 lockfname, smbcli_errstr(c1->tree));
310 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
313 printf("second open read-only of %s failed (%s)\n",
314 lockfname, smbcli_errstr(c2->tree));
315 smbcli_close(c1->tree, fnum1);
319 printf("Checking data integrity over %d ops\n", torture_numops);
321 for (i=0;i<torture_numops;i++)
323 size_t buf_size = ((uint_t)random()%(sizeof(buf)-1))+ 1;
325 printf("%d\r", i); fflush(stdout);
328 generate_random_buffer(buf, buf_size);
330 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
331 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
332 printf("wrote %d, expected %d\n", (int)bytes_written, (int)buf_size);
337 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
338 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
339 printf("read %d, expected %d\n", (int)bytes_read, (int)buf_size);
344 if (memcmp(buf_rd, buf, buf_size) != 0)
346 printf("read/write compare failed\n");
352 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
353 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
356 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
357 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
361 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
362 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
369 #define BOOLSTR(b) ((b) ? "Yes" : "No")
371 static BOOL run_readwritetest(void)
373 struct smbcli_state *cli1, *cli2;
374 BOOL test1, test2 = True;
376 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
380 printf("starting readwritetest\n");
382 test1 = rw_torture2(cli1, cli2);
383 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
386 test2 = rw_torture2(cli1, cli1);
387 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
390 if (!torture_close_connection(cli1)) {
394 if (!torture_close_connection(cli2)) {
398 return (test1 && test2);
402 this checks to see if a secondary tconx can use open files from an
405 static BOOL run_tcon_test(void)
407 struct smbcli_state *cli;
408 const char *fname = "\\tcontest.tmp";
410 uint16_t cnum1, cnum2, cnum3;
411 uint16_t vuid1, vuid2;
414 struct smbcli_tree *tree1;
415 const char *host = lp_parm_string(-1, "torture", "host");
416 const char *share = lp_parm_string(-1, "torture", "share");
417 const char *password = lp_parm_string(-1, "torture", "password");
419 if (!torture_open_connection(&cli)) {
423 printf("starting tcontest\n");
425 if (smbcli_deltree(cli->tree, fname) == -1) {
426 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
429 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
431 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
435 cnum1 = cli->tree->tid;
436 vuid1 = cli->session->vuid;
438 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
439 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
440 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
444 tree1 = cli->tree; /* save old tree connection */
445 if (NT_STATUS_IS_ERR(smbcli_tconX(cli, share, "?????", password))) {
446 printf("%s refused 2nd tree connect (%s)\n", host,
447 smbcli_errstr(cli->tree));
452 cnum2 = cli->tree->tid;
453 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
454 vuid2 = cli->session->vuid + 1;
456 /* try a write with the wrong tid */
457 cli->tree->tid = cnum2;
459 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
460 printf("* server allows write with wrong TID\n");
463 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
467 /* try a write with an invalid tid */
468 cli->tree->tid = cnum3;
470 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
471 printf("* server allows write with invalid TID\n");
474 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
477 /* try a write with an invalid vuid */
478 cli->session->vuid = vuid2;
479 cli->tree->tid = cnum1;
481 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
482 printf("* server allows write with invalid VUID\n");
485 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
488 cli->session->vuid = vuid1;
489 cli->tree->tid = cnum1;
491 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
492 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
496 cli->tree->tid = cnum2;
498 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
499 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
503 cli->tree = tree1; /* restore initial tree */
504 cli->tree->tid = cnum1;
506 smbcli_unlink(tree1, fname);
508 if (!torture_close_connection(cli)) {
517 static BOOL tcon_devtest(struct smbcli_state *cli,
518 const char *myshare, const char *devtype,
519 NTSTATUS expected_error)
523 const char *password = lp_parm_string(-1, "torture", "password");
525 status = NT_STATUS_IS_OK(smbcli_tconX(cli, myshare, devtype,
528 printf("Trying share %s with devtype %s\n", myshare, devtype);
530 if (NT_STATUS_IS_OK(expected_error)) {
534 printf("tconX to share %s with type %s "
535 "should have succeeded but failed\n",
542 printf("tconx to share %s with type %s "
543 "should have failed but succeeded\n",
547 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
551 printf("Returned unexpected error\n");
560 checks for correct tconX support
562 static BOOL run_tcon_devtype_test(void)
564 struct smbcli_state *cli1 = NULL;
567 const char *host = lp_parm_string(-1, "torture", "host");
568 const char *share = lp_parm_string(-1, "torture", "share");
570 status = smbcli_full_connection(NULL,
573 cmdline_credentials, NULL);
575 if (!NT_STATUS_IS_OK(status)) {
576 printf("could not open connection\n");
580 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
583 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
586 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
589 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
592 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
595 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
598 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
601 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
604 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
607 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
613 printf("Passed tcondevtest\n");
620 test whether fnums and tids open on one VC are available on another (a major
623 static BOOL run_fdpasstest(void)
625 struct smbcli_state *cli1, *cli2;
626 const char *fname = "\\fdpass.tst";
630 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
634 printf("starting fdpasstest\n");
636 smbcli_unlink(cli1->tree, fname);
638 printf("Opening a file on connection 1\n");
640 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
642 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
646 printf("writing to file on connection 1\n");
648 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
649 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
653 oldtid = cli2->tree->tid;
654 cli2->session->vuid = cli1->session->vuid;
655 cli2->tree->tid = cli1->tree->tid;
656 cli2->session->pid = cli1->session->pid;
658 printf("reading from file on connection 2\n");
660 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
661 printf("read succeeded! nasty security hole [%s]\n",
666 smbcli_close(cli1->tree, fnum1);
667 smbcli_unlink(cli1->tree, fname);
669 cli2->tree->tid = oldtid;
671 torture_close_connection(cli1);
672 torture_close_connection(cli2);
674 printf("finished fdpasstest\n");
680 test the timing of deferred open requests
682 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
684 const char *fname = "\\defer_open_test.dat";
690 printf("failed to connect\n");
694 printf("Testing deferred open requests.\n");
701 tv = timeval_current();
702 fnum = smbcli_nt_create_full(cli->tree, fname, 0,
704 FILE_ATTRIBUTE_NORMAL,
705 NTCREATEX_SHARE_ACCESS_NONE,
706 NTCREATEX_DISP_OPEN_IF, 0, 0);
710 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
711 double e = timeval_elapsed(&tv);
712 if (e < 0.5 || e > 1.5) {
713 fprintf(stderr,"Timing incorrect %.2f violation\n",
717 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
720 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
724 printf("pid %u open %d\n", getpid(), i);
728 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
729 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
735 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
736 /* All until the last unlink will fail with sharing violation. */
737 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
738 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
743 printf("deferred test finished\n");
744 if (!torture_close_connection(cli)) {
751 test how many open files this server supports on the one socket
753 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
755 #define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
757 int fnums[0x11000], i;
758 int retries=4, maxfid;
762 printf("failed to connect\n");
766 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
767 printf("Failed to deltree \\maxfid - %s\n",
768 smbcli_errstr(cli->tree));
771 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
772 printf("Failed to mkdir \\maxfid, error=%s\n",
773 smbcli_errstr(cli->tree));
777 printf("Testing maximum number of open files\n");
779 for (i=0; i<0x11000; i++) {
781 asprintf(&fname, "\\maxfid\\fid%d", i/1000);
782 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
783 printf("Failed to mkdir %s, error=%s\n",
784 fname, smbcli_errstr(cli->tree));
789 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
790 if ((fnums[i] = smbcli_open(cli->tree, fname,
791 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
793 printf("open of %s failed (%s)\n",
794 fname, smbcli_errstr(cli->tree));
795 printf("maximum fnum is %d\n", i);
806 printf("cleaning up\n");
807 for (i=0;i<maxfid/2;i++) {
808 asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
809 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
810 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
812 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
813 printf("unlink of %s failed (%s)\n",
814 fname, smbcli_errstr(cli->tree));
819 asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
820 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
821 printf("Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
823 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
824 printf("unlink of %s failed (%s)\n",
825 fname, smbcli_errstr(cli->tree));
830 printf("%6d %6d\r", i, maxfid-i);
834 if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
835 printf("Failed to deltree \\maxfid - %s\n",
836 smbcli_errstr(cli->tree));
840 printf("maxfid test finished\n");
841 if (!torture_close_connection(cli)) {
845 #undef MAXFID_TEMPLATE
848 /* send smb negprot commands, not reading the response */
849 static BOOL run_negprot_nowait(void)
852 struct smbcli_state *cli, *cli2;
855 printf("starting negprot nowait test\n");
857 cli = open_nbt_connection();
862 printf("Filling send buffer\n");
864 for (i=0;i<100;i++) {
865 struct smbcli_request *req;
866 req = smb_raw_negotiate_send(cli->transport, PROTOCOL_NT1);
867 event_loop_once(cli->transport->socket->event.ctx);
868 if (req->state == SMBCLI_REQUEST_ERROR) {
870 printf("Failed to fill pipe packet[%d] - %s (ignored)\n", i+1, nt_errstr(req->status));
873 printf("Failed to fill pipe - %s \n", nt_errstr(req->status));
874 torture_close_connection(cli);
880 printf("Opening secondary connection\n");
881 if (!torture_open_connection(&cli2)) {
882 printf("Failed to open secondary connection\n");
886 if (!torture_close_connection(cli2)) {
887 printf("Failed to close secondary connection\n");
891 torture_close_connection(cli);
893 printf("finished negprot nowait test\n");
900 This checks how the getatr calls works
902 static BOOL run_attrtest(void)
904 struct smbcli_state *cli;
907 const char *fname = "\\attrib123456789.tst";
910 printf("starting attrib test\n");
912 if (!torture_open_connection(&cli)) {
916 smbcli_unlink(cli->tree, fname);
917 fnum = smbcli_open(cli->tree, fname,
918 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
919 smbcli_close(cli->tree, fnum);
921 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
922 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
926 printf("New file time is %s", ctime(&t));
928 if (abs(t - time(NULL)) > 60*60*24*10) {
929 printf("ERROR: SMBgetatr bug. time is %s",
935 t2 = t-60*60*24; /* 1 day ago */
937 printf("Setting file time to %s", ctime(&t2));
939 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
940 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
944 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
945 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
949 printf("Retrieved file time as %s", ctime(&t));
952 printf("ERROR: getatr/setatr bug. times are\n%s",
954 printf("%s", ctime(&t2));
958 smbcli_unlink(cli->tree, fname);
960 if (!torture_close_connection(cli)) {
964 printf("attrib test finished\n");
971 This checks a couple of trans2 calls
973 static BOOL run_trans2test(void)
975 struct smbcli_state *cli;
978 time_t c_time, a_time, m_time, w_time, m_time2;
979 const char *fname = "\\trans2.tst";
980 const char *dname = "\\trans2";
981 const char *fname2 = "\\trans2\\trans2.tst";
985 printf("starting trans2 test\n");
987 if (!torture_open_connection(&cli)) {
991 smbcli_unlink(cli->tree, fname);
993 printf("Testing qfileinfo\n");
995 fnum = smbcli_open(cli->tree, fname,
996 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
997 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
999 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
1003 printf("Testing NAME_INFO\n");
1005 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
1006 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
1010 if (!pname || strcmp(pname, fname)) {
1011 printf("qfilename gave different name? [%s] [%s]\n",
1016 smbcli_close(cli->tree, fnum);
1017 smbcli_unlink(cli->tree, fname);
1019 fnum = smbcli_open(cli->tree, fname,
1020 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1022 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1025 smbcli_close(cli->tree, fnum);
1027 printf("Checking for sticky create times\n");
1029 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1030 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
1033 if (c_time != m_time) {
1034 printf("create time=%s", ctime(&c_time));
1035 printf("modify time=%s", ctime(&m_time));
1036 printf("This system appears to have sticky create times\n");
1038 if (a_time % (60*60) == 0) {
1039 printf("access time=%s", ctime(&a_time));
1040 printf("This system appears to set a midnight access time\n");
1044 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1045 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1051 smbcli_unlink(cli->tree, fname);
1052 fnum = smbcli_open(cli->tree, fname,
1053 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1054 smbcli_close(cli->tree, fnum);
1055 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1056 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1059 if (w_time < 60*60*24*2) {
1060 printf("write time=%s", ctime(&w_time));
1061 printf("This system appears to set a initial 0 write time\n");
1066 smbcli_unlink(cli->tree, fname);
1069 /* check if the server updates the directory modification time
1070 when creating a new file */
1071 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
1072 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
1076 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
1077 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1081 fnum = smbcli_open(cli->tree, fname2,
1082 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1083 smbcli_write(cli->tree, fnum, 0, &fnum, 0, sizeof(fnum));
1084 smbcli_close(cli->tree, fnum);
1085 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
1086 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
1089 if (m_time2 == m_time) {
1090 printf("This system does not update directory modification times\n");
1094 smbcli_unlink(cli->tree, fname2);
1095 smbcli_rmdir(cli->tree, dname);
1097 if (!torture_close_connection(cli)) {
1101 printf("trans2 test finished\n");
1108 /* FIRST_DESIRED_ACCESS 0xf019f */
1109 #define FIRST_DESIRED_ACCESS SEC_FILE_READ_DATA|SEC_FILE_WRITE_DATA|SEC_FILE_APPEND_DATA|\
1110 SEC_FILE_READ_EA| /* 0xf */ \
1111 SEC_FILE_WRITE_EA|SEC_FILE_READ_ATTRIBUTE| /* 0x90 */ \
1112 SEC_FILE_WRITE_ATTRIBUTE| /* 0x100 */ \
1113 SEC_STD_DELETE|SEC_STD_READ_CONTROL|\
1114 SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER /* 0xf0000 */
1115 /* SECOND_DESIRED_ACCESS 0xe0080 */
1116 #define SECOND_DESIRED_ACCESS SEC_FILE_READ_ATTRIBUTE| /* 0x80 */ \
1117 SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|\
1118 SEC_STD_WRITE_OWNER /* 0xe0000 */
1121 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTE| /* 0x80 */ \
1122 READ_CONTROL|WRITE_DAC|\
1123 SEC_FILE_READ_DATA|\
1128 Test ntcreate calls made by xcopy
1130 static BOOL run_xcopy(void)
1132 struct smbcli_state *cli1;
1133 const char *fname = "\\test.txt";
1134 BOOL correct = True;
1137 printf("starting xcopy test\n");
1139 if (!torture_open_connection(&cli1)) {
1143 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
1144 FIRST_DESIRED_ACCESS,
1145 FILE_ATTRIBUTE_ARCHIVE,
1146 NTCREATEX_SHARE_ACCESS_NONE,
1147 NTCREATEX_DISP_OVERWRITE_IF,
1151 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
1155 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
1156 SECOND_DESIRED_ACCESS, 0,
1157 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
1160 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
1164 if (!torture_close_connection(cli1)) {
1173 see how many RPC pipes we can open at once
1175 static BOOL run_pipe_number(void)
1177 struct smbcli_state *cli1;
1178 const char *pipe_name = "\\WKSSVC";
1182 printf("starting pipenumber test\n");
1183 if (!torture_open_connection(&cli1)) {
1188 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1189 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1192 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
1196 printf("%d\r", num_pipes);
1200 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
1201 torture_close_connection(cli1);
1209 open N connections to the server and just hold them open
1210 used for testing performance when there are N idle users
1213 static BOOL torture_holdcon(void)
1216 struct smbcli_state **cli;
1219 printf("Opening %d connections\n", torture_numops);
1221 cli = malloc_array_p(struct smbcli_state *, torture_numops);
1223 for (i=0;i<torture_numops;i++) {
1224 if (!torture_open_connection(&cli[i])) {
1227 printf("opened %d connections\r", i);
1231 printf("\nStarting pings\n");
1234 for (i=0;i<torture_numops;i++) {
1237 status = smbcli_chkpath(cli[i]->tree, "\\");
1238 if (!NT_STATUS_IS_OK(status)) {
1239 printf("Connection %d is dead\n", i);
1247 if (num_dead == torture_numops) {
1248 printf("All connections dead - finishing\n");
1260 Try with a wrong vuid and check error message.
1263 static BOOL run_vuidtest(void)
1265 struct smbcli_state *cli;
1266 const char *fname = "\\vuid.tst";
1269 time_t c_time, a_time, m_time;
1270 BOOL correct = True;
1275 printf("starting vuid test\n");
1277 if (!torture_open_connection(&cli)) {
1281 smbcli_unlink(cli->tree, fname);
1283 fnum = smbcli_open(cli->tree, fname,
1284 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1286 orig_vuid = cli->session->vuid;
1288 cli->session->vuid += 1234;
1290 printf("Testing qfileinfo with wrong vuid\n");
1292 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
1293 &size, &c_time, &a_time,
1294 &m_time, NULL, NULL))) {
1295 printf("ERROR: qfileinfo passed with wrong vuid\n");
1299 if (!NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1300 NT_STATUS_DOS(ERRSRV, ERRbaduid)) &&
1301 !NT_STATUS_EQUAL(cli->transport->error.e.nt_status,
1302 NT_STATUS_INVALID_HANDLE)) {
1303 printf("ERROR: qfileinfo should have returned DOS error "
1304 "ERRSRV:ERRbaduid\n but returned %s\n",
1305 smbcli_errstr(cli->tree));
1309 cli->session->vuid -= 1234;
1311 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1312 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
1316 smbcli_unlink(cli->tree, fname);
1318 if (!torture_close_connection(cli)) {
1322 printf("vuid test finished\n");
1328 Test open mode returns on read-only files.
1330 static BOOL run_opentest(void)
1332 static struct smbcli_state *cli1;
1333 static struct smbcli_state *cli2;
1334 const char *fname = "\\readonly.file";
1335 char *control_char_fname;
1339 BOOL correct = True;
1344 printf("starting open test\n");
1346 if (!torture_open_connection(&cli1)) {
1350 asprintf(&control_char_fname, "\\readonly.afile");
1351 for (i = 1; i <= 0x1f; i++) {
1352 control_char_fname[10] = i;
1353 fnum1 = smbcli_nt_create_full(cli1->tree, control_char_fname, 0, SEC_FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
1354 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1356 if (!check_error(__location__, cli1, ERRDOS, ERRinvalidname,
1357 NT_STATUS_OBJECT_NAME_INVALID)) {
1358 printf("Error code should be NT_STATUS_OBJECT_NAME_INVALID, was %s for file with %d char\n",
1359 smbcli_errstr(cli1->tree), i);
1364 smbcli_close(cli1->tree, fnum1);
1366 smbcli_setatr(cli1->tree, control_char_fname, 0, 0);
1367 smbcli_unlink(cli1->tree, control_char_fname);
1369 free(control_char_fname);
1372 printf("Create file with control char names passed.\n");
1374 smbcli_setatr(cli1->tree, fname, 0, 0);
1375 smbcli_unlink(cli1->tree, fname);
1377 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1379 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1383 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1384 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1388 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
1389 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
1390 CHECK_MAX_FAILURES(error_test1);
1394 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1396 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1397 CHECK_MAX_FAILURES(error_test1);
1401 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
1402 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1404 if (check_error(__location__, cli1, ERRDOS, ERRnoaccess,
1405 NT_STATUS_ACCESS_DENIED)) {
1406 printf("correct error code ERRDOS/ERRnoaccess returned\n");
1409 printf("finished open test 1\n");
1411 smbcli_close(cli1->tree, fnum1);
1413 /* Now try not readonly and ensure ERRbadshare is returned. */
1415 smbcli_setatr(cli1->tree, fname, 0, 0);
1417 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
1419 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1423 /* This will fail - but the error should be ERRshare. */
1424 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
1426 if (check_error(__location__, cli1, ERRDOS, ERRbadshare,
1427 NT_STATUS_SHARING_VIOLATION)) {
1428 printf("correct error code ERRDOS/ERRbadshare returned\n");
1431 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1432 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1436 smbcli_unlink(cli1->tree, fname);
1438 printf("finished open test 2\n");
1440 /* Test truncate open disposition on file opened for read. */
1442 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1444 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1448 /* write 20 bytes. */
1450 memset(buf, '\0', 20);
1452 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1453 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1457 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1458 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1462 /* Ensure size == 20. */
1463 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1464 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1465 CHECK_MAX_FAILURES(error_test3);
1470 printf("(3) file size != 20\n");
1471 CHECK_MAX_FAILURES(error_test3);
1475 /* Now test if we can truncate a file opened for readonly. */
1477 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
1479 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1480 CHECK_MAX_FAILURES(error_test3);
1484 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1485 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
1489 /* Ensure size == 0. */
1490 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1491 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1492 CHECK_MAX_FAILURES(error_test3);
1497 printf("(3) file size != 0\n");
1498 CHECK_MAX_FAILURES(error_test3);
1501 printf("finished open test 3\n");
1503 smbcli_unlink(cli1->tree, fname);
1506 printf("testing ctemp\n");
1507 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
1509 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
1510 CHECK_MAX_FAILURES(error_test4);
1513 printf("ctemp gave path %s\n", tmp_path);
1514 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1515 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1517 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
1518 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
1521 /* Test the non-io opens... */
1523 if (!torture_open_connection(&cli2)) {
1527 smbcli_setatr(cli2->tree, fname, 0, 0);
1528 smbcli_unlink(cli2->tree, fname);
1530 printf("TEST #1 testing 2 non-io opens (no delete)\n");
1532 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1533 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1536 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1537 CHECK_MAX_FAILURES(error_test10);
1541 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1542 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1544 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1545 CHECK_MAX_FAILURES(error_test10);
1549 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1550 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1553 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1554 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1558 printf("non-io open test #1 passed.\n");
1560 smbcli_unlink(cli1->tree, fname);
1562 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
1564 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1565 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1568 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1569 CHECK_MAX_FAILURES(error_test20);
1573 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1574 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1577 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1578 CHECK_MAX_FAILURES(error_test20);
1582 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1583 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1586 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1587 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1591 printf("non-io open test #2 passed.\n");
1593 smbcli_unlink(cli1->tree, fname);
1595 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
1597 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1598 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1601 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1602 CHECK_MAX_FAILURES(error_test30);
1606 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1607 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1610 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1611 CHECK_MAX_FAILURES(error_test30);
1615 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1616 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1619 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1620 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1624 printf("non-io open test #3 passed.\n");
1626 smbcli_unlink(cli1->tree, fname);
1628 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
1630 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1631 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1634 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1635 CHECK_MAX_FAILURES(error_test40);
1639 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1640 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1643 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1644 CHECK_MAX_FAILURES(error_test40);
1648 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1650 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1651 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1655 printf("non-io open test #4 passed.\n");
1657 smbcli_unlink(cli1->tree, fname);
1659 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
1661 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1662 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1665 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1666 CHECK_MAX_FAILURES(error_test50);
1670 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1671 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1674 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1675 CHECK_MAX_FAILURES(error_test50);
1679 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1680 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1684 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1685 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1689 printf("non-io open test #5 passed.\n");
1691 printf("TEST #6 testing 1 non-io open, one io open\n");
1693 smbcli_unlink(cli1->tree, fname);
1695 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
1696 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
1699 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1700 CHECK_MAX_FAILURES(error_test60);
1704 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1705 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
1708 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1709 CHECK_MAX_FAILURES(error_test60);
1713 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1714 printf("test 6 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 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1723 printf("non-io open test #6 passed.\n");
1725 printf("TEST #7 testing 1 non-io open, one io open with delete\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 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1734 CHECK_MAX_FAILURES(error_test70);
1738 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SEC_STD_DELETE|SEC_FILE_READ_ATTRIBUTE, FILE_ATTRIBUTE_NORMAL,
1739 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
1742 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1743 CHECK_MAX_FAILURES(error_test70);
1747 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
1749 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1750 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1754 printf("non-io open test #7 passed.\n");
1758 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
1760 smbcli_unlink(cli1->tree, fname);
1762 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
1764 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1768 /* write 20 bytes. */
1770 memset(buf, '\0', 20);
1772 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
1773 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
1777 /* Ensure size == 20. */
1778 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1779 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
1780 CHECK_MAX_FAILURES(error_test80);
1785 printf("(8) file size != 20\n");
1786 CHECK_MAX_FAILURES(error_test80);
1790 /* Get an exclusive lock on the open file. */
1791 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
1792 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
1793 CHECK_MAX_FAILURES(error_test80);
1797 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1799 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1803 /* Ensure size == 0. */
1804 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
1805 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
1806 CHECK_MAX_FAILURES(error_test80);
1811 printf("(8) file size != 0\n");
1812 CHECK_MAX_FAILURES(error_test80);
1816 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1817 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1821 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
1822 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1828 printf("open test #8 passed.\n");
1830 smbcli_unlink(cli1->tree, fname);
1832 if (!torture_close_connection(cli1)) {
1835 if (!torture_close_connection(cli2)) {
1844 sees what IOCTLs are supported
1846 BOOL torture_ioctl_test(void)
1848 struct smbcli_state *cli;
1849 uint16_t device, function;
1851 const char *fname = "\\ioctl.dat";
1853 union smb_ioctl parms;
1854 TALLOC_CTX *mem_ctx;
1856 if (!torture_open_connection(&cli)) {
1860 mem_ctx = talloc_init("ioctl_test");
1862 printf("starting ioctl test\n");
1864 smbcli_unlink(cli->tree, fname);
1866 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1868 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1872 parms.ioctl.level = RAW_IOCTL_IOCTL;
1873 parms.ioctl.in.file.fnum = fnum;
1874 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
1875 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1876 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
1878 for (device=0;device<0x100;device++) {
1879 printf("testing device=0x%x\n", device);
1880 for (function=0;function<0x100;function++) {
1881 parms.ioctl.in.request = (device << 16) | function;
1882 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
1884 if (NT_STATUS_IS_OK(status)) {
1885 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
1886 device, function, (int)parms.ioctl.out.blob.length);
1891 if (!torture_close_connection(cli)) {
1900 tries variants of chkpath
1902 BOOL torture_chkpath_test(void)
1904 struct smbcli_state *cli;
1908 if (!torture_open_connection(&cli)) {
1912 printf("starting chkpath test\n");
1914 printf("Testing valid and invalid paths\n");
1916 /* cleanup from an old run */
1917 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1918 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1919 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1921 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
1922 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
1926 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
1927 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
1931 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1933 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
1936 smbcli_close(cli->tree, fnum);
1938 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
1939 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
1943 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
1944 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
1948 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
1949 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1950 NT_STATUS_NOT_A_DIRECTORY);
1952 printf("* chkpath on a file should fail\n");
1956 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
1957 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1958 NT_STATUS_OBJECT_NAME_NOT_FOUND);
1960 printf("* chkpath on a non existent file should fail\n");
1964 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
1965 ret = check_error(__location__, cli, ERRDOS, ERRbadpath,
1966 NT_STATUS_OBJECT_PATH_NOT_FOUND);
1968 printf("* chkpath on a non existent component should fail\n");
1972 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
1973 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
1974 smbcli_rmdir(cli->tree, "\\chkpath.dir");
1976 if (!torture_close_connection(cli)) {
1984 static void sigcont(int sig)
1988 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
1991 volatile pid_t *child_status;
1992 volatile BOOL *child_status_out;
1995 double start_time_limit = 10 + (torture_nprocs * 1.5);
1996 char **unc_list = NULL;
1998 int num_unc_names = 0;
2005 signal(SIGCONT, sigcont);
2007 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
2008 if (!child_status) {
2009 printf("Failed to setup shared memory\n");
2013 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
2014 if (!child_status_out) {
2015 printf("Failed to setup result status shared memory\n");
2019 p = lp_parm_string(-1, "torture", "unclist");
2021 unc_list = file_lines_load(p, &num_unc_names, NULL);
2022 if (!unc_list || num_unc_names <= 0) {
2023 printf("Failed to load unc names list from '%s'\n", p);
2028 for (i = 0; i < torture_nprocs; i++) {
2029 child_status[i] = 0;
2030 child_status_out[i] = True;
2033 tv = timeval_current();
2035 for (i=0;i<torture_nprocs;i++) {
2039 char *hostname=NULL, *sharename;
2041 pid_t mypid = getpid();
2042 srandom(((int)mypid) ^ ((int)time(NULL)));
2044 asprintf(&myname, "CLIENT%d", i);
2045 lp_set_cmdline("netbios name", myname);
2050 if (!smbcli_parse_unc(unc_list[i % num_unc_names],
2051 NULL, &hostname, &sharename)) {
2052 printf("Failed to parse UNC name %s\n",
2053 unc_list[i % num_unc_names]);
2060 if (torture_open_connection_share(NULL,
2067 } else if (torture_open_connection(¤t_cli)) {
2071 printf("pid %d failed to start\n", (int)getpid());
2077 child_status[i] = getpid();
2081 if (child_status[i]) {
2082 printf("Child %d failed to start!\n", i);
2083 child_status_out[i] = 1;
2087 child_status_out[i] = fn(current_cli, i);
2094 for (i=0;i<torture_nprocs;i++) {
2095 if (child_status[i]) synccount++;
2097 if (synccount == torture_nprocs) break;
2099 } while (timeval_elapsed(&tv) < start_time_limit);
2101 if (synccount != torture_nprocs) {
2102 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
2104 return timeval_elapsed(&tv);
2107 printf("Starting %d clients\n", torture_nprocs);
2109 /* start the client load */
2110 tv = timeval_current();
2111 for (i=0;i<torture_nprocs;i++) {
2112 child_status[i] = 0;
2115 printf("%d clients started\n", torture_nprocs);
2119 for (i=0;i<torture_nprocs;i++) {
2121 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
2122 if (ret == -1 || WEXITSTATUS(status) != 0) {
2129 for (i=0;i<torture_nprocs;i++) {
2130 if (!child_status_out[i]) {
2134 return timeval_elapsed(&tv);
2137 #define FLAG_MULTIPROC 1
2142 BOOL (*multi_fn)(struct smbcli_state *, int );
2143 } builtin_torture_ops[] = {
2145 {"BASE-FDPASS", run_fdpasstest, 0},
2146 {"BASE-LOCK1", torture_locktest1, 0},
2147 {"BASE-LOCK2", torture_locktest2, 0},
2148 {"BASE-LOCK3", torture_locktest3, 0},
2149 {"BASE-LOCK4", torture_locktest4, 0},
2150 {"BASE-LOCK5", torture_locktest5, 0},
2151 {"BASE-LOCK6", torture_locktest6, 0},
2152 {"BASE-LOCK7", torture_locktest7, 0},
2153 {"BASE-UNLINK", torture_unlinktest, 0},
2154 {"BASE-ATTR", run_attrtest, 0},
2155 {"BASE-TRANS2", run_trans2test, 0},
2156 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
2157 {"BASE-DIR1", torture_dirtest1, 0},
2158 {"BASE-DIR2", torture_dirtest2, 0},
2159 {"BASE-DENY1", torture_denytest1, 0},
2160 {"BASE-DENY2", torture_denytest2, 0},
2161 {"BASE-DENY3", torture_denytest3, 0},
2162 {"BASE-DENYDOS", torture_denydos_sharing, 0},
2163 {"BASE-NTDENY1", NULL, torture_ntdenytest1},
2164 {"BASE-NTDENY2", torture_ntdenytest2, 0},
2165 {"BASE-TCON", run_tcon_test, 0},
2166 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
2167 {"BASE-VUID", run_vuidtest, 0},
2168 {"BASE-RW1", run_readwritetest, 0},
2169 {"BASE-OPEN", run_opentest, 0},
2170 {"BASE-DEFER_OPEN", NULL, run_deferopen},
2171 {"BASE-XCOPY", run_xcopy, 0},
2172 {"BASE-RENAME", torture_test_rename, 0},
2173 {"BASE-DELETE", torture_test_delete, 0},
2174 {"BASE-PROPERTIES", torture_test_properties, 0},
2175 {"BASE-MANGLE", torture_mangle, 0},
2176 {"BASE-OPENATTR", torture_openattrtest, 0},
2177 {"BASE-CHARSET", torture_charset, 0},
2178 {"BASE-CHKPATH", torture_chkpath_test, 0},
2179 {"BASE-SECLEAK", torture_sec_leak, 0},
2180 {"BASE-DISCONNECT", torture_disconnect, 0},
2181 {"BASE-DELAYWRITE", torture_delay_write, 0},
2183 /* benchmarking tests */
2184 {"BENCH-HOLDCON", torture_holdcon, 0},
2185 {"BENCH-NBENCH", torture_nbench, 0},
2186 {"BENCH-TORTURE", NULL, run_torture},
2187 {"BENCH-NBT", torture_bench_nbt, 0},
2188 {"BENCH-WINS", torture_bench_wins, 0},
2189 {"BENCH-CLDAP", torture_bench_cldap, 0},
2192 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
2193 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
2194 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
2195 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
2196 {"RAW-SEARCH", torture_raw_search, 0},
2197 {"RAW-CLOSE", torture_raw_close, 0},
2198 {"RAW-OPEN", torture_raw_open, 0},
2199 {"RAW-MKDIR", torture_raw_mkdir, 0},
2200 {"RAW-OPLOCK", torture_raw_oplock, 0},
2201 {"RAW-NOTIFY", torture_raw_notify, 0},
2202 {"RAW-MUX", torture_raw_mux, 0},
2203 {"RAW-IOCTL", torture_raw_ioctl, 0},
2204 {"RAW-CHKPATH", torture_raw_chkpath, 0},
2205 {"RAW-UNLINK", torture_raw_unlink, 0},
2206 {"RAW-READ", torture_raw_read, 0},
2207 {"RAW-WRITE", torture_raw_write, 0},
2208 {"RAW-LOCK", torture_raw_lock, 0},
2209 {"RAW-CONTEXT", torture_raw_context, 0},
2210 {"RAW-RENAME", torture_raw_rename, 0},
2211 {"RAW-SEEK", torture_raw_seek, 0},
2212 {"RAW-EAS", torture_raw_eas, 0},
2213 {"RAW-EAMAX", torture_max_eas, 0},
2214 {"RAW-STREAMS", torture_raw_streams, 0},
2215 {"RAW-ACLS", torture_raw_acls, 0},
2216 {"RAW-RAP", torture_raw_rap, 0},
2217 {"RAW-COMPOSITE", torture_raw_composite, 0},
2220 {"SMB2-CONNECT", torture_smb2_connect, 0},
2221 {"SMB2-SCAN", torture_smb2_scan, 0},
2222 {"SMB2-SCANGETINFO", torture_smb2_getinfo_scan, 0},
2223 {"SMB2-SCANSETINFO", torture_smb2_setinfo_scan, 0},
2224 {"SMB2-SCANFIND", torture_smb2_find_scan, 0},
2225 {"SMB2-GETINFO", torture_smb2_getinfo, 0},
2226 {"SMB2-SETINFO", torture_smb2_setinfo, 0},
2227 {"SMB2-FIND", torture_smb2_find, 0},
2229 /* protocol scanners */
2230 {"SCAN-TRANS2", torture_trans2_scan, 0},
2231 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
2232 {"SCAN-ALIASES", torture_trans2_aliases, 0},
2233 {"SCAN-SMB", torture_smb_scan, 0},
2234 {"SCAN-MAXFID", NULL, run_maxfidtest},
2235 {"SCAN-UTABLE", torture_utable, 0},
2236 {"SCAN-CASETABLE", torture_casetable, 0},
2237 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
2238 {"SCAN-IOCTL", torture_ioctl_test, 0},
2239 {"SCAN-RAP", torture_rap_scan, 0},
2241 /* local (no server) testers */
2242 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
2243 {"LOCAL-ICONV", torture_local_iconv, 0},
2244 {"LOCAL-TALLOC", torture_local_talloc, 0},
2245 {"LOCAL-MESSAGING", torture_local_messaging, 0},
2246 {"LOCAL-IRPC", torture_local_irpc, 0},
2247 {"LOCAL-BINDING", torture_local_binding_string, 0},
2248 {"LOCAL-STRLIST", torture_local_util_strlist, 0},
2249 {"LOCAL-FILE", torture_local_util_file, 0},
2250 {"LOCAL-IDTREE", torture_local_idtree, 0},
2251 {"LOCAL-SOCKET", torture_local_socket, 0},
2252 {"LOCAL-PAC", torture_pac, 0},
2253 {"LOCAL-REGISTRY", torture_registry, 0},
2254 {"LOCAL-RESOLVE", torture_local_resolve, 0},
2255 {"LOCAL-SDDL", torture_local_sddl, 0},
2256 {"LOCAL-NDR", torture_local_ndr, 0},
2259 {"LDAP-BASIC", torture_ldap_basic, 0},
2260 {"LDAP-CLDAP", torture_cldap, 0},
2263 {"NBT-REGISTER", torture_nbt_register, 0},
2264 {"NBT-WINS", torture_nbt_wins, 0},
2265 {"NBT-DGRAM", torture_nbt_dgram, 0},
2266 {"NBT-BROWSE", torture_nbt_browse, 0},
2267 {"NBT-WINSREPLICATION-SIMPLE", torture_nbt_winsreplication_simple, 0},
2268 {"NBT-WINSREPLICATION-REPLICA", torture_nbt_winsreplication_replica, 0},
2269 {"NBT-WINSREPLICATION-OWNED", torture_nbt_winsreplication_owned, 0},
2272 {"NET-USERINFO", torture_userinfo, 0},
2273 {"NET-USERADD", torture_useradd, 0},
2274 {"NET-USERDEL", torture_userdel, 0},
2275 {"NET-USERMOD", torture_usermod, 0},
2276 {"NET-DOMOPEN", torture_domainopen, 0},
2277 {"NET-API-LOOKUP", torture_lookup, 0},
2278 {"NET-API-LOOKUPHOST", torture_lookup_host, 0},
2279 {"NET-API-LOOKUPPDC", torture_lookup_pdc, 0},
2280 {"NET-API-CREATEUSER", torture_createuser, 0},
2281 {"NET-API-RPCCONNECT", torture_rpc_connect, 0},
2282 {"NET-API-LISTSHARES", torture_listshares, 0},
2283 {"NET-API-DELSHARE", torture_delshare, 0},
2287 static void register_builtin_ops(void)
2290 for (i = 0; builtin_torture_ops[i].name; i++) {
2291 register_torture_op(builtin_torture_ops[i].name,
2292 builtin_torture_ops[i].fn,
2293 builtin_torture_ops[i].multi_fn);
2298 static struct torture_op {
2301 BOOL (*multi_fn)(struct smbcli_state *, int );
2302 struct torture_op *prev, *next;
2303 }* torture_ops = NULL;;
2305 static struct torture_op *find_torture_op(const char *name)
2307 struct torture_op *o;
2308 for (o = torture_ops; o; o = o->next) {
2309 if (strcmp(name, o->name) == 0)
2316 NTSTATUS register_torture_op(const char *name, BOOL (*fn)(void), BOOL (*multi_fn)(struct smbcli_state *, int ))
2318 struct torture_op *op;
2320 /* Check for duplicates */
2321 if (find_torture_op(name) != NULL) {
2322 DEBUG(0,("There already is a torture op registered with the name %s!\n", name));
2323 return NT_STATUS_OBJECT_NAME_COLLISION;
2326 op = talloc(talloc_autofree_context(), struct torture_op);
2328 op->name = talloc_strdup(op, name);
2330 op->multi_fn = multi_fn;
2332 DLIST_ADD(torture_ops, op);
2334 return NT_STATUS_OK;
2337 /****************************************************************************
2338 run a specified test or "ALL"
2339 ****************************************************************************/
2340 static BOOL run_test(const char *name)
2343 struct torture_op *o;
2344 BOOL matched = False;
2346 if (strequal(name,"ALL")) {
2347 for (o = torture_ops; o; o = o->next) {
2348 if (!run_test(o->name)) {
2355 for (o = torture_ops; o; o = o->next) {
2356 if (gen_fnmatch(name, o->name) == 0) {
2360 printf("Running %s\n", o->name);
2362 BOOL result = False;
2363 t = torture_create_procs(o->multi_fn,
2367 printf("TEST %s FAILED!\n", o->name);
2371 struct timeval tv = timeval_current();
2374 printf("TEST %s FAILED!\n", o->name);
2376 t = timeval_elapsed(&tv);
2378 printf("%s took %g secs\n\n", o->name, t);
2383 printf("Unknown torture operation '%s'\n", name);
2390 static void parse_dns(const char *dns)
2392 char *userdn, *basedn, *secret;
2395 /* retrievieng the userdn */
2396 p = strchr_m(dns, '#');
2398 lp_set_cmdline("torture:ldap_userdn", "");
2399 lp_set_cmdline("torture:ldap_basedn", "");
2400 lp_set_cmdline("torture:ldap_secret", "");
2403 userdn = strndup(dns, p - dns);
2404 lp_set_cmdline("torture:ldap_userdn", userdn);
2406 /* retrieve the basedn */
2408 p = strchr_m(d, '#');
2410 lp_set_cmdline("torture:ldap_basedn", "");
2411 lp_set_cmdline("torture:ldap_secret", "");
2414 basedn = strndup(d, p - d);
2415 lp_set_cmdline("torture:ldap_basedn", basedn);
2417 /* retrieve the secret */
2420 lp_set_cmdline("torture:ldap_secret", "");
2424 lp_set_cmdline("torture:ldap_secret", secret);
2426 printf ("%s - %s - %s\n", userdn, basedn, secret);
2430 static void usage(poptContext pc)
2432 struct torture_op *o;
2435 poptPrintUsage(pc, stdout, 0);
2438 printf("The binding format is:\n\n");
2440 printf(" TRANSPORT:host[flags]\n\n");
2442 printf(" where TRANSPORT is either ncacn_np for SMB or ncacn_ip_tcp for RPC/TCP\n\n");
2444 printf(" 'host' is an IP or hostname or netbios name. If the binding string\n");
2445 printf(" identifies the server side of an endpoint, 'host' may be an empty\n");
2446 printf(" string.\n\n");
2448 printf(" 'flags' can include a SMB pipe name if using the ncacn_np transport or\n");
2449 printf(" a TCP port number if using the ncacn_ip_tcp transport, otherwise they\n");
2450 printf(" will be auto-determined.\n\n");
2452 printf(" other recognised flags are:\n\n");
2454 printf(" sign : enable ntlmssp signing\n");
2455 printf(" seal : enable ntlmssp sealing\n");
2456 printf(" connect : enable rpc connect level auth (auth, but no sign or seal)\n");
2457 printf(" validate: enable the NDR validator\n");
2458 printf(" print: enable debugging of the packets\n");
2459 printf(" bigendian: use bigendian RPC\n");
2460 printf(" padcheck: check reply data for non-zero pad bytes\n\n");
2462 printf(" For example, these all connect to the samr pipe:\n\n");
2464 printf(" ncacn_np:myserver\n");
2465 printf(" ncacn_np:myserver[samr]\n");
2466 printf(" ncacn_np:myserver[\\pipe\\samr]\n");
2467 printf(" ncacn_np:myserver[/pipe/samr]\n");
2468 printf(" ncacn_np:myserver[samr,sign,print]\n");
2469 printf(" ncacn_np:myserver[\\pipe\\samr,sign,seal,bigendian]\n");
2470 printf(" ncacn_np:myserver[/pipe/samr,seal,validate]\n");
2471 printf(" ncacn_np:\n");
2472 printf(" ncacn_np:[/pipe/samr]\n\n");
2474 printf(" ncacn_ip_tcp:myserver\n");
2475 printf(" ncacn_ip_tcp:myserver[1024]\n");
2476 printf(" ncacn_ip_tcp:myserver[1024,sign,seal]\n\n");
2478 printf("The unc format is:\n\n");
2480 printf(" //server/share\n\n");
2482 printf("tests are:\n");
2485 for (o = torture_ops; o; o = o->next) {
2486 if (i + strlen(o->name) >= MAX_COLS) {
2490 i+=printf("%s ", o->name);
2494 printf("default test is ALL\n");
2499 static BOOL is_binding_string(const char *binding_string)
2501 TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
2502 struct dcerpc_binding *binding_struct;
2505 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);
2507 talloc_free(mem_ctx);
2508 return NT_STATUS_IS_OK(status);
2511 static void max_runtime_handler(int sig)
2513 DEBUG(0,("maximum runtime exceeded for smbtorture - terminating\n"));
2517 /****************************************************************************
2519 ****************************************************************************/
2520 int main(int argc,char *argv[])
2524 BOOL correct = True;
2529 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,
2530 OPT_DANGEROUS,OPT_SMB_PORTS};
2531 init_module_fn static_init[] = STATIC_smbtorture_MODULES;
2532 init_module_fn *shared_init = load_samba_modules(NULL, "torture");
2534 struct poptOption long_options[] = {
2536 {"smb-ports", 'p', POPT_ARG_STRING, NULL, OPT_SMB_PORTS, "SMB ports", NULL},
2537 {"seed", 0, POPT_ARG_INT, &torture_seed, 0, "seed", NULL},
2538 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
2539 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
2540 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
2541 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
2542 {"show-all", 0, POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
2543 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
2544 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
2545 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
2546 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
2547 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
2548 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
2549 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, 0,
2550 "set maximum time for smbtorture to live", "seconds"},
2552 POPT_COMMON_CONNECTION
2553 POPT_COMMON_CREDENTIALS
2558 #ifdef HAVE_SETBUFFER
2559 setbuffer(stdout, NULL, 0);
2562 register_builtin_ops();
2564 run_init_functions(static_init);
2565 run_init_functions(shared_init);
2567 talloc_free(shared_init);
2569 /* we are never interested in SIGPIPE */
2570 BlockSignals(True,SIGPIPE);
2572 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
2573 POPT_CONTEXT_KEEP_FIRST);
2575 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
2577 while((opt = poptGetNextOpt(pc)) != -1) {
2580 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
2583 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
2586 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
2589 parse_dns(poptGetOptArg(pc));
2592 lp_set_cmdline("torture:dangerous", "Yes");
2595 lp_set_cmdline("smb ports", poptGetOptArg(pc));
2598 d_printf("Invalid option %s: %s\n",
2599 poptBadOption(pc, 0), poptStrerror(opt));
2606 /* this will only work if nobody else uses alarm(),
2607 which means it won't work for some tests, but we
2608 can't use the event context method we use for smbd
2609 as so many tests create their own event
2610 context. This will at least catch most cases. */
2611 signal(SIGALRM, max_runtime_handler);
2619 dcerpc_table_init();
2621 if (torture_seed == 0) {
2622 torture_seed = time(NULL);
2624 printf("Using seed %d\n", torture_seed);
2625 srandom(torture_seed);
2627 argv_new = discard_const_p(char *, poptGetArgs(pc));
2630 for (i=0; i<argc; i++) {
2631 if (argv_new[i] == NULL) {
2642 for(p = argv_new[1]; *p; p++) {
2647 /* see if its a RPC transport specifier */
2648 if (is_binding_string(argv_new[1])) {
2649 lp_set_cmdline("torture:binding", argv_new[1]);
2651 char *binding = NULL;
2652 char *host = NULL, *share = NULL;
2654 if (!smbcli_parse_unc(argv_new[1], NULL, &host, &share)) {
2655 d_printf("Invalid option: %s is not a valid torture target (share or binding string)\n\n", argv_new[1]);
2659 lp_set_cmdline("torture:host", host);
2660 lp_set_cmdline("torture:share", share);
2661 asprintf(&binding, "ncacn_np:%s", host);
2662 lp_set_cmdline("torture:binding", binding);
2665 if (argc_new == 0) {
2666 printf("You must specify a test to run, or 'ALL'\n");
2668 for (i=2;i<argc_new;i++) {
2669 if (!run_test(argv_new[i])) {