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.
24 int torture_numops=100;
25 int torture_entries=1000;
26 int torture_failures=1;
27 static int procnum; /* records process count number when forking */
28 static struct smbcli_state *current_cli;
29 static BOOL use_oplocks;
30 static BOOL use_level_II_oplocks;
31 static BOOL use_kerberos;
33 BOOL torture_showall = False;
35 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
37 static struct smbcli_state *open_nbt_connection(void)
39 struct nmb_name called, calling;
40 struct smbcli_state *cli;
41 const char *host = lp_parm_string(-1, "torture", "host");
43 make_nmb_name(&calling, lp_netbios_name(), 0x0);
44 choose_called_name(&called, host, 0x20);
46 cli = smbcli_state_init();
48 printf("Failed initialize smbcli_struct to connect with %s\n", host);
52 if (!smbcli_socket_connect(cli, host)) {
53 printf("Failed to connect with %s\n", host);
57 cli->transport->socket->timeout = 120000; /* set a really long timeout (2 minutes) */
59 if (!smbcli_transport_establish(cli, &calling, &called)) {
61 * Well, that failed, try *SMBSERVER ...
62 * However, we must reconnect as well ...
64 if (!smbcli_socket_connect(cli, host)) {
65 printf("Failed to connect with %s\n", host);
69 make_nmb_name(&called, "*SMBSERVER", 0x20);
70 if (!smbcli_transport_establish(cli, &calling, &called)) {
71 printf("%s rejected the session\n",host);
72 printf("We tried with a called name of %s & %s\n",
82 BOOL torture_open_connection_share(struct smbcli_state **c,
84 const char *sharename)
89 const char *username = lp_parm_string(-1, "torture", "username");
90 const char *userdomain = lp_parm_string(-1, "torture", "userdomain");
91 const char *password = lp_parm_string(-1, "torture", "password");
94 flags |= SMBCLI_FULL_CONNECTION_USE_KERBEROS;
96 status = smbcli_full_connection(c, lp_netbios_name(),
99 username, username[0]?userdomain:"",
100 password, flags, &retry);
101 if (!NT_STATUS_IS_OK(status)) {
102 printf("Failed to open connection - %s\n", nt_errstr(status));
106 (*c)->transport->options.use_oplocks = use_oplocks;
107 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
108 (*c)->transport->socket->timeout = 120000;
113 BOOL torture_open_connection(struct smbcli_state **c)
115 const char *host = lp_parm_string(-1, "torture", "host");
116 const char *share = lp_parm_string(-1, "torture", "share");
118 return torture_open_connection_share(c, host, share);
123 BOOL torture_close_connection(struct smbcli_state *c)
126 DEBUG(9,("torture_close_connection: smbcli_state@%p\n", c));
128 if (NT_STATUS_IS_ERR(smbcli_tdis(c))) {
129 printf("tdis failed (%s)\n", smbcli_errstr(c->tree));
132 DEBUG(9,("torture_close_connection: call smbcli_shutdown\n"));
134 DEBUG(9,("torture_close_connection: exit\n"));
139 /* open a rpc connection to the chosen binding string */
140 NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p,
141 const char *pipe_name,
142 const char *pipe_uuid,
143 uint32_t pipe_version)
146 const char *binding = lp_parm_string(-1, "torture", "binding");
149 printf("You must specify a ncacn binding string\n");
150 return NT_STATUS_INVALID_PARAMETER;
153 status = dcerpc_pipe_connect(p, binding, pipe_uuid, pipe_version,
154 lp_parm_string(-1, "torture", "userdomain"),
155 lp_parm_string(-1, "torture", "username"),
156 lp_parm_string(-1, "torture", "password"));
161 /* open a rpc connection to a specific transport */
162 NTSTATUS torture_rpc_connection_transport(struct dcerpc_pipe **p,
163 const char *pipe_name,
164 const char *pipe_uuid,
165 uint32_t pipe_version,
166 enum dcerpc_transport_t transport)
169 const char *binding = lp_parm_string(-1, "torture", "binding");
170 struct dcerpc_binding b;
171 TALLOC_CTX *mem_ctx = talloc_init("torture_rpc_connection_smb");
174 printf("You must specify a ncacn binding string\n");
175 return NT_STATUS_INVALID_PARAMETER;
178 status = dcerpc_parse_binding(mem_ctx, binding, &b);
179 if (!NT_STATUS_IS_OK(status)) {
180 DEBUG(0,("Failed to parse dcerpc binding '%s'\n", binding));
181 talloc_destroy(mem_ctx);
185 b.transport = transport;
187 status = dcerpc_pipe_connect_b(p, &b, pipe_uuid, pipe_version,
188 lp_parm_string(-1, "torture", "userdomain"),
189 lp_parm_string(-1, "torture", "username"),
190 lp_parm_string(-1, "torture", "password"));
195 /* close a rpc connection to a named pipe */
196 NTSTATUS torture_rpc_close(struct dcerpc_pipe *p)
198 dcerpc_pipe_close(p);
203 /* check if the server produced the expected error code */
204 static BOOL check_error(int line, struct smbcli_state *c,
205 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
207 if (smbcli_is_dos_error(c->tree)) {
211 /* Check DOS error */
213 smbcli_dos_error(c, &class, &num);
215 if (eclass != class || ecode != num) {
216 printf("unexpected error code class=%d code=%d\n",
217 (int)class, (int)num);
218 printf(" expected %d/%d %s (line=%d)\n",
219 (int)eclass, (int)ecode, nt_errstr(nterr), line);
228 status = smbcli_nt_error(c->tree);
230 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
231 printf("unexpected error code %s\n", nt_errstr(status));
232 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
241 static BOOL wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
243 while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
244 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
250 static BOOL rw_torture(struct smbcli_state *c)
252 const char *lockfname = "\\torture.lck";
256 pid_t pid2, pid = getpid();
261 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
264 fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
266 printf("open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
271 for (i=0;i<torture_numops;i++) {
272 uint_t n = (uint_t)sys_random()%10;
274 printf("%d\r", i); fflush(stdout);
276 asprintf(&fname, "\\torture.%u", n);
278 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
282 fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
284 printf("open failed (%s)\n", smbcli_errstr(c->tree));
289 if (smbcli_write(c->tree, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
290 printf("write failed (%s)\n", smbcli_errstr(c->tree));
295 if (smbcli_write(c->tree, fnum, 0, (char *)buf,
296 sizeof(pid)+(j*sizeof(buf)),
297 sizeof(buf)) != sizeof(buf)) {
298 printf("write failed (%s)\n", smbcli_errstr(c->tree));
305 if (smbcli_read(c->tree, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
306 printf("read failed (%s)\n", smbcli_errstr(c->tree));
311 printf("data corruption!\n");
315 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
316 printf("close failed (%s)\n", smbcli_errstr(c->tree));
320 if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
321 printf("unlink failed (%s)\n", smbcli_errstr(c->tree));
325 if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
326 printf("unlock failed (%s)\n", smbcli_errstr(c->tree));
332 smbcli_close(c->tree, fnum2);
333 smbcli_unlink(c->tree, lockfname);
340 static BOOL run_torture(struct smbcli_state *cli, int dummy)
344 ret = rw_torture(cli);
346 if (!torture_close_connection(cli)) {
353 static BOOL rw_torture3(struct smbcli_state *c, const char *lockfname)
360 uint_t countprev = 0;
365 for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
367 SIVAL(buf, i, sys_random());
372 fnum = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
375 printf("first open read/write of %s failed (%s)\n",
376 lockfname, smbcli_errstr(c->tree));
382 for (i = 0; i < 500 && fnum == -1; i++)
384 fnum = smbcli_open(c->tree, lockfname, O_RDONLY,
389 printf("second open read-only of %s failed (%s)\n",
390 lockfname, smbcli_errstr(c->tree));
396 for (count = 0; count < sizeof(buf); count += sent)
398 if (count >= countprev) {
399 printf("%d %8d\r", i, count);
402 countprev += (sizeof(buf) / 20);
407 sent = ((uint_t)sys_random()%(20))+ 1;
408 if (sent > sizeof(buf) - count)
410 sent = sizeof(buf) - count;
413 if (smbcli_write(c->tree, fnum, 0, buf+count, count, (size_t)sent) != sent) {
414 printf("write failed (%s)\n", smbcli_errstr(c->tree));
420 sent = smbcli_read(c->tree, fnum, buf_rd+count, count,
424 printf("read failed offset:%d size:%d (%s)\n",
425 count, sizeof(buf)-count,
426 smbcli_errstr(c->tree));
432 if (memcmp(buf_rd+count, buf+count, sent) != 0)
434 printf("read/write compare failed\n");
435 printf("offset: %d req %d recvd %d\n",
436 count, sizeof(buf)-count, sent);
445 if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
446 printf("close failed (%s)\n", smbcli_errstr(c->tree));
453 static BOOL rw_torture2(struct smbcli_state *c1, struct smbcli_state *c2)
455 const char *lockfname = "\\torture2.lck";
460 uint8_t buf_rd[131072];
462 ssize_t bytes_read, bytes_written;
464 if (smbcli_deltree(c1->tree, lockfname) == -1) {
465 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
468 fnum1 = smbcli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
471 printf("first open read/write of %s failed (%s)\n",
472 lockfname, smbcli_errstr(c1->tree));
475 fnum2 = smbcli_open(c2->tree, lockfname, O_RDONLY,
478 printf("second open read-only of %s failed (%s)\n",
479 lockfname, smbcli_errstr(c2->tree));
480 smbcli_close(c1->tree, fnum1);
484 printf("Checking data integrity over %d ops\n", torture_numops);
486 for (i=0;i<torture_numops;i++)
488 size_t buf_size = ((uint_t)sys_random()%(sizeof(buf)-1))+ 1;
490 printf("%d\r", i); fflush(stdout);
493 generate_random_buffer(buf, buf_size);
495 if ((bytes_written = smbcli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
496 printf("write failed (%s)\n", smbcli_errstr(c1->tree));
497 printf("wrote %d, expected %d\n", bytes_written, buf_size);
502 if ((bytes_read = smbcli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
503 printf("read failed (%s)\n", smbcli_errstr(c2->tree));
504 printf("read %d, expected %d\n", bytes_read, buf_size);
509 if (memcmp(buf_rd, buf, buf_size) != 0)
511 printf("read/write compare failed\n");
517 if (NT_STATUS_IS_ERR(smbcli_close(c2->tree, fnum2))) {
518 printf("close failed (%s)\n", smbcli_errstr(c2->tree));
521 if (NT_STATUS_IS_ERR(smbcli_close(c1->tree, fnum1))) {
522 printf("close failed (%s)\n", smbcli_errstr(c1->tree));
526 if (NT_STATUS_IS_ERR(smbcli_unlink(c1->tree, lockfname))) {
527 printf("unlink failed (%s)\n", smbcli_errstr(c1->tree));
534 static BOOL run_readwritetest(int dummy)
536 struct smbcli_state *cli1, *cli2;
537 BOOL test1, test2 = True;
539 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
543 printf("starting readwritetest\n");
545 test1 = rw_torture2(cli1, cli2);
546 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
549 test2 = rw_torture2(cli1, cli1);
550 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
553 if (!torture_close_connection(cli1)) {
557 if (!torture_close_connection(cli2)) {
561 return (test1 && test2);
564 static BOOL run_readwritemulti(struct smbcli_state *cli, int dummy)
568 test = rw_torture3(cli, "\\multitest.txt");
570 if (!torture_close_connection(cli)) {
579 This test checks for two things:
581 1) correct support for retaining locks over a close (ie. the server
582 must not use posix semantics)
583 2) support for lock timeouts
585 static BOOL run_locktest1(int dummy)
587 struct smbcli_state *cli1, *cli2;
588 const char *fname = "\\lockt1.lck";
589 int fnum1, fnum2, fnum3;
593 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
597 printf("starting locktest1\n");
599 smbcli_unlink(cli1->tree, fname);
601 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
603 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
606 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
608 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
611 fnum3 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
613 printf("open3 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
617 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
618 printf("lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
623 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
624 printf("lock2 succeeded! This is a locking bug\n");
627 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
628 NT_STATUS_LOCK_NOT_GRANTED)) return False;
632 lock_timeout = (6 + (random() % 20));
633 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
635 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK))) {
636 printf("lock3 succeeded! This is a locking bug\n");
639 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
640 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
645 printf("error: This server appears not to support timed lock requests\n");
647 printf("server slept for %u seconds for a %u second timeout\n",
648 (uint_t)(t2-t1), lock_timeout);
650 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
651 printf("close1 failed (%s)\n", smbcli_errstr(cli1->tree));
655 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
656 printf("lock4 succeeded! This is a locking bug\n");
659 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
660 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
663 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
664 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
668 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum3))) {
669 printf("close3 failed (%s)\n", smbcli_errstr(cli2->tree));
673 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, fname))) {
674 printf("unlink failed (%s)\n", smbcli_errstr(cli1->tree));
679 if (!torture_close_connection(cli1)) {
683 if (!torture_close_connection(cli2)) {
687 printf("Passed locktest1\n");
692 this checks to see if a secondary tconx can use open files from an
695 static BOOL run_tcon_test(int dummy)
697 struct smbcli_state *cli;
698 const char *fname = "\\tcontest.tmp";
700 uint16_t cnum1, cnum2, cnum3;
701 uint16_t vuid1, vuid2;
704 struct smbcli_tree *tree1;
705 const char *host = lp_parm_string(-1, "torture", "host");
706 const char *share = lp_parm_string(-1, "torture", "share");
707 const char *password = lp_parm_string(-1, "torture", "password");
709 if (!torture_open_connection(&cli)) {
713 printf("starting tcontest\n");
715 if (smbcli_deltree(cli->tree, fname) == -1) {
716 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
719 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
721 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
725 cnum1 = cli->tree->tid;
726 vuid1 = cli->session->vuid;
728 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
729 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
730 printf("initial write failed (%s)\n", smbcli_errstr(cli->tree));
734 tree1 = cli->tree; /* save old tree connection */
735 if (NT_STATUS_IS_ERR(smbcli_send_tconX(cli, share, "?????", password))) {
736 printf("%s refused 2nd tree connect (%s)\n", host,
737 smbcli_errstr(cli->tree));
738 smbcli_shutdown(cli);
742 cnum2 = cli->tree->tid;
743 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
744 vuid2 = cli->session->vuid + 1;
746 /* try a write with the wrong tid */
747 cli->tree->tid = cnum2;
749 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
750 printf("* server allows write with wrong TID\n");
753 printf("server fails write with wrong TID : %s\n", smbcli_errstr(cli->tree));
757 /* try a write with an invalid tid */
758 cli->tree->tid = cnum3;
760 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
761 printf("* server allows write with invalid TID\n");
764 printf("server fails write with invalid TID : %s\n", smbcli_errstr(cli->tree));
767 /* try a write with an invalid vuid */
768 cli->session->vuid = vuid2;
769 cli->tree->tid = cnum1;
771 if (smbcli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
772 printf("* server allows write with invalid VUID\n");
775 printf("server fails write with invalid VUID : %s\n", smbcli_errstr(cli->tree));
778 cli->session->vuid = vuid1;
779 cli->tree->tid = cnum1;
781 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
782 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
786 cli->tree->tid = cnum2;
788 if (NT_STATUS_IS_ERR(smbcli_tdis(cli))) {
789 printf("secondary tdis failed (%s)\n", smbcli_errstr(cli->tree));
793 cli->tree = tree1; /* restore initial tree */
794 cli->tree->tid = cnum1;
796 if (!torture_close_connection(cli)) {
805 static BOOL tcon_devtest(struct smbcli_state *cli,
806 const char *myshare, const char *devtype,
807 NTSTATUS expected_error)
811 const char *password = lp_parm_string(-1, "torture", "password");
813 status = NT_STATUS_IS_OK(smbcli_send_tconX(cli, myshare, devtype,
816 printf("Trying share %s with devtype %s\n", myshare, devtype);
818 if (NT_STATUS_IS_OK(expected_error)) {
822 printf("tconX to share %s with type %s "
823 "should have succeeded but failed\n",
830 printf("tconx to share %s with type %s "
831 "should have failed but succeeded\n",
835 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),
839 printf("Returned unexpected error\n");
848 checks for correct tconX support
850 static BOOL run_tcon_devtype_test(int dummy)
852 struct smbcli_state *cli1 = NULL;
857 const char *host = lp_parm_string(-1, "torture", "host");
858 const char *share = lp_parm_string(-1, "torture", "share");
859 const char *username = lp_parm_string(-1, "torture", "username");
860 const char *userdomain = lp_parm_string(-1, "torture", "userdomain");
861 const char *password = lp_parm_string(-1, "torture", "password");
863 status = smbcli_full_connection(&cli1, lp_netbios_name(),
866 username, userdomain,
867 password, flags, &retry);
869 if (!NT_STATUS_IS_OK(status)) {
870 printf("could not open connection\n");
874 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
877 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
880 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
883 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
886 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
889 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
892 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
895 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
898 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
901 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
904 smbcli_shutdown(cli1);
907 printf("Passed tcondevtest\n");
914 This test checks that
916 1) the server supports multiple locking contexts on the one SMB
917 connection, distinguished by PID.
919 2) the server correctly fails overlapping locks made by the same PID (this
920 goes against POSIX behaviour, which is why it is tricky to implement)
922 3) the server denies unlock requests by an incorrect client PID
924 static BOOL run_locktest2(int dummy)
926 struct smbcli_state *cli;
927 const char *fname = "\\lockt2.lck";
928 int fnum1, fnum2, fnum3;
931 if (!torture_open_connection(&cli)) {
935 printf("starting locktest2\n");
937 smbcli_unlink(cli->tree, fname);
939 printf("Testing pid context\n");
941 cli->session->pid = 1;
943 fnum1 = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
945 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
949 fnum2 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
951 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
955 cli->session->pid = 2;
957 fnum3 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE);
959 printf("open3 of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
963 cli->session->pid = 1;
965 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
966 printf("lock1 failed (%s)\n", smbcli_errstr(cli->tree));
970 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
971 printf("WRITE lock1 succeeded! This is a locking bug\n");
974 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
975 NT_STATUS_LOCK_NOT_GRANTED)) return False;
978 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, WRITE_LOCK))) {
979 printf("WRITE lock2 succeeded! This is a locking bug\n");
982 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
983 NT_STATUS_LOCK_NOT_GRANTED)) return False;
986 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum2, 0, 4, 0, READ_LOCK))) {
987 printf("READ lock2 succeeded! This is a locking bug\n");
990 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
991 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
994 if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum1, 100, 4, 0, WRITE_LOCK))) {
995 printf("lock at 100 failed (%s)\n", smbcli_errstr(cli->tree));
998 cli->session->pid = 2;
1000 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 100, 4))) {
1001 printf("unlock at 100 succeeded! This is a locking bug\n");
1005 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 4))) {
1006 printf("unlock1 succeeded! This is a locking bug\n");
1009 if (!check_error(__LINE__, cli,
1011 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1014 if (NT_STATUS_IS_OK(smbcli_unlock(cli->tree, fnum1, 0, 8))) {
1015 printf("unlock2 succeeded! This is a locking bug\n");
1018 if (!check_error(__LINE__, cli,
1020 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1023 if (NT_STATUS_IS_OK(smbcli_lock(cli->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
1024 printf("lock3 succeeded! This is a locking bug\n");
1027 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1030 cli->session->pid = 1;
1032 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum1))) {
1033 printf("close1 failed (%s)\n", smbcli_errstr(cli->tree));
1037 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum2))) {
1038 printf("close2 failed (%s)\n", smbcli_errstr(cli->tree));
1042 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum3))) {
1043 printf("close3 failed (%s)\n", smbcli_errstr(cli->tree));
1047 if (!torture_close_connection(cli)) {
1051 printf("locktest2 finished\n");
1058 This test checks that
1060 1) the server supports the full offset range in lock requests
1062 static BOOL run_locktest3(int dummy)
1064 struct smbcli_state *cli1, *cli2;
1065 const char *fname = "\\lockt3.lck";
1066 int fnum1, fnum2, i;
1068 BOOL correct = True;
1070 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1072 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1076 printf("starting locktest3\n");
1078 printf("Testing 32 bit offset ranges\n");
1080 smbcli_unlink(cli1->tree, fname);
1082 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1084 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1087 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1089 printf("open2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
1093 printf("Establishing %d locks\n", torture_numops);
1095 for (offset=i=0;i<torture_numops;i++) {
1097 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
1098 printf("lock1 %d failed (%s)\n",
1100 smbcli_errstr(cli1->tree));
1104 if (NT_STATUS_IS_ERR(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
1105 printf("lock2 %d failed (%s)\n",
1107 smbcli_errstr(cli1->tree));
1112 printf("Testing %d locks\n", torture_numops);
1114 for (offset=i=0;i<torture_numops;i++) {
1117 if (NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-2, 1, 0, WRITE_LOCK))) {
1118 printf("error: lock1 %d succeeded!\n", i);
1122 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-1, 1, 0, WRITE_LOCK))) {
1123 printf("error: lock2 %d succeeded!\n", i);
1127 if (NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
1128 printf("error: lock3 %d succeeded!\n", i);
1132 if (NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
1133 printf("error: lock4 %d succeeded!\n", i);
1138 printf("Removing %d locks\n", torture_numops);
1140 for (offset=i=0;i<torture_numops;i++) {
1143 if (NT_STATUS_IS_ERR(smbcli_unlock(cli1->tree, fnum1, offset-1, 1))) {
1144 printf("unlock1 %d failed (%s)\n",
1146 smbcli_errstr(cli1->tree));
1150 if (NT_STATUS_IS_ERR(smbcli_unlock(cli2->tree, fnum2, offset-2, 1))) {
1151 printf("unlock2 %d failed (%s)\n",
1153 smbcli_errstr(cli1->tree));
1158 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
1159 printf("close1 failed (%s)\n", smbcli_errstr(cli1->tree));
1163 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
1164 printf("close2 failed (%s)\n", smbcli_errstr(cli2->tree));
1168 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, fname))) {
1169 printf("unlink failed (%s)\n", smbcli_errstr(cli1->tree));
1173 if (!torture_close_connection(cli1)) {
1177 if (!torture_close_connection(cli2)) {
1181 printf("finished locktest3\n");
1186 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1187 printf("** "); correct = False; \
1191 looks at overlapping locks
1193 static BOOL run_locktest4(int dummy)
1195 struct smbcli_state *cli1, *cli2;
1196 const char *fname = "\\lockt4.lck";
1197 int fnum1, fnum2, f;
1200 BOOL correct = True;
1202 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1206 printf("starting locktest4\n");
1208 smbcli_unlink(cli1->tree, fname);
1210 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1211 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1213 memset(buf, 0, sizeof(buf));
1215 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1216 printf("Failed to create file\n");
1221 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1222 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 2, 4, 0, WRITE_LOCK));
1223 EXPECTED(ret, False);
1224 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1226 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 10, 4, 0, READ_LOCK)) &&
1227 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 12, 4, 0, READ_LOCK));
1228 EXPECTED(ret, True);
1229 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1231 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1232 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 22, 4, 0, WRITE_LOCK));
1233 EXPECTED(ret, False);
1234 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1236 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 30, 4, 0, READ_LOCK)) &&
1237 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 32, 4, 0, READ_LOCK));
1238 EXPECTED(ret, True);
1239 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1241 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1242 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 42, 4, 0, WRITE_LOCK)));
1243 EXPECTED(ret, False);
1244 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1246 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 50, 4, 0, READ_LOCK))) &&
1247 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 52, 4, 0, READ_LOCK)));
1248 EXPECTED(ret, True);
1249 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1251 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK)) &&
1252 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK));
1253 EXPECTED(ret, True);
1254 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1256 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1257 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK));
1258 EXPECTED(ret, False);
1259 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1261 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, READ_LOCK)) &&
1262 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 80, 4, 0, WRITE_LOCK));
1263 EXPECTED(ret, False);
1264 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1266 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, WRITE_LOCK)) &&
1267 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 90, 4, 0, READ_LOCK));
1268 EXPECTED(ret, True);
1269 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1271 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, WRITE_LOCK))) &&
1272 NT_STATUS_IS_OK((cli1->session->pid = 2, smbcli_lock(cli1->tree, fnum1, 100, 4, 0, READ_LOCK)));
1273 EXPECTED(ret, False);
1274 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1276 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 110, 4, 0, READ_LOCK)) &&
1277 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 112, 4, 0, READ_LOCK)) &&
1278 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 110, 6));
1279 EXPECTED(ret, False);
1280 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1283 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 120, 4, 0, WRITE_LOCK)) &&
1284 (smbcli_read(cli2->tree, fnum2, buf, 120, 4) == 4);
1285 EXPECTED(ret, False);
1286 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1288 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK)) &&
1289 (smbcli_write(cli2->tree, fnum2, 0, buf, 130, 4) == 4);
1290 EXPECTED(ret, False);
1291 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1294 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
1295 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
1296 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4)) &&
1297 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 140, 4));
1298 EXPECTED(ret, True);
1299 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1302 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, WRITE_LOCK)) &&
1303 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 150, 4, 0, READ_LOCK)) &&
1304 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4)) &&
1305 (smbcli_read(cli2->tree, fnum2, buf, 150, 4) == 4) &&
1306 !(smbcli_write(cli2->tree, fnum2, 0, buf, 150, 4) == 4) &&
1307 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 150, 4));
1308 EXPECTED(ret, True);
1309 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1311 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 160, 4, 0, READ_LOCK)) &&
1312 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 160, 4)) &&
1313 (smbcli_write(cli2->tree, fnum2, 0, buf, 160, 4) == 4) &&
1314 (smbcli_read(cli2->tree, fnum2, buf, 160, 4) == 4);
1315 EXPECTED(ret, True);
1316 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1318 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 170, 4, 0, WRITE_LOCK)) &&
1319 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 170, 4)) &&
1320 (smbcli_write(cli2->tree, fnum2, 0, buf, 170, 4) == 4) &&
1321 (smbcli_read(cli2->tree, fnum2, buf, 170, 4) == 4);
1322 EXPECTED(ret, True);
1323 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1325 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, WRITE_LOCK)) &&
1326 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 190, 4, 0, READ_LOCK)) &&
1327 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 190, 4)) &&
1328 !(smbcli_write(cli2->tree, fnum2, 0, buf, 190, 4) == 4) &&
1329 (smbcli_read(cli2->tree, fnum2, buf, 190, 4) == 4);
1330 EXPECTED(ret, True);
1331 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1333 smbcli_close(cli1->tree, fnum1);
1334 smbcli_close(cli2->tree, fnum2);
1335 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1336 f = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1337 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
1338 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, f, 0, 1, 0, READ_LOCK)) &&
1339 NT_STATUS_IS_OK(smbcli_close(cli1->tree, fnum1)) &&
1340 ((fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE)) != -1) &&
1341 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
1342 smbcli_close(cli1->tree, f);
1343 smbcli_close(cli1->tree, fnum1);
1344 EXPECTED(ret, True);
1345 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1348 smbcli_close(cli1->tree, fnum1);
1349 smbcli_close(cli2->tree, fnum2);
1350 smbcli_unlink(cli1->tree, fname);
1351 torture_close_connection(cli1);
1352 torture_close_connection(cli2);
1354 printf("finished locktest4\n");
1359 looks at lock upgrade/downgrade.
1361 static BOOL run_locktest5(int dummy)
1363 struct smbcli_state *cli1, *cli2;
1364 const char *fname = "\\lockt5.lck";
1365 int fnum1, fnum2, fnum3;
1368 BOOL correct = True;
1370 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1374 printf("starting locktest5\n");
1376 smbcli_unlink(cli1->tree, fname);
1378 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1379 fnum2 = smbcli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1380 fnum3 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1382 memset(buf, 0, sizeof(buf));
1384 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1385 printf("Failed to create file\n");
1390 /* Check for NT bug... */
1391 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
1392 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 1, 0, READ_LOCK));
1393 smbcli_close(cli1->tree, fnum1);
1394 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1395 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
1396 EXPECTED(ret, True);
1397 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1398 smbcli_close(cli1->tree, fnum1);
1399 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1400 smbcli_unlock(cli1->tree, fnum3, 0, 1);
1402 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1403 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 1, 1, 0, READ_LOCK));
1404 EXPECTED(ret, True);
1405 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1407 ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
1408 EXPECTED(ret, False);
1410 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1412 /* Unlock the process 2 lock. */
1413 smbcli_unlock(cli2->tree, fnum2, 0, 4);
1415 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum3, 0, 4, 0, READ_LOCK));
1416 EXPECTED(ret, False);
1418 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1420 /* Unlock the process 1 fnum3 lock. */
1421 smbcli_unlock(cli1->tree, fnum3, 0, 4);
1423 /* Stack 2 more locks here. */
1424 ret = NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK)) &&
1425 NT_STATUS_IS_OK(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK));
1427 EXPECTED(ret, True);
1428 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1430 /* Unlock the first process lock, then check this was the WRITE lock that was
1433 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
1434 NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
1436 EXPECTED(ret, True);
1437 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1439 /* Unlock the process 2 lock. */
1440 smbcli_unlock(cli2->tree, fnum2, 0, 4);
1442 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1444 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 1, 1)) &&
1445 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4)) &&
1446 NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
1448 EXPECTED(ret, True);
1449 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1451 /* Ensure the next unlock fails. */
1452 ret = NT_STATUS_IS_OK(smbcli_unlock(cli1->tree, fnum1, 0, 4));
1453 EXPECTED(ret, False);
1454 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1456 /* Ensure connection 2 can get a write lock. */
1457 ret = NT_STATUS_IS_OK(smbcli_lock(cli2->tree, fnum2, 0, 4, 0, WRITE_LOCK));
1458 EXPECTED(ret, True);
1460 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1464 smbcli_close(cli1->tree, fnum1);
1465 smbcli_close(cli2->tree, fnum2);
1466 smbcli_unlink(cli1->tree, fname);
1467 if (!torture_close_connection(cli1)) {
1470 if (!torture_close_connection(cli2)) {
1474 printf("finished locktest5\n");
1480 tries the unusual lockingX locktype bits
1482 static BOOL run_locktest6(int dummy)
1484 struct smbcli_state *cli;
1485 const char *fname[1] = { "\\lock6.txt" };
1490 if (!torture_open_connection(&cli)) {
1494 printf("starting locktest6\n");
1497 printf("Testing %s\n", fname[i]);
1499 smbcli_unlink(cli->tree, fname[i]);
1501 fnum = smbcli_open(cli->tree, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1502 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1503 smbcli_close(cli->tree, fnum);
1504 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1506 fnum = smbcli_open(cli->tree, fname[i], O_RDWR, DENY_NONE);
1507 status = smbcli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1508 smbcli_close(cli->tree, fnum);
1509 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1511 smbcli_unlink(cli->tree, fname[i]);
1514 torture_close_connection(cli);
1516 printf("finished locktest6\n");
1520 static BOOL run_locktest7(int dummy)
1522 struct smbcli_state *cli1;
1523 const char *fname = "\\lockt7.lck";
1528 BOOL correct = False;
1530 if (!torture_open_connection(&cli1)) {
1534 printf("starting locktest7\n");
1536 smbcli_unlink(cli1->tree, fname);
1538 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1540 memset(buf, 0, sizeof(buf));
1542 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1543 printf("Failed to create file\n");
1547 cli1->session->pid = 1;
1549 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK))) {
1550 printf("Unable to apply read lock on range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1553 printf("pid1 successfully locked range 130:4 for READ\n");
1556 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1557 printf("pid1 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1560 printf("pid1 successfully read the range 130:4\n");
1563 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1564 printf("pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1565 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1566 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1570 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1574 cli1->session->pid = 2;
1576 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1577 printf("pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1579 printf("pid2 successfully read the range 130:4\n");
1582 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1583 printf("pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1584 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1585 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1589 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1593 cli1->session->pid = 1;
1594 smbcli_unlock(cli1->tree, fnum1, 130, 4);
1596 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 130, 4, 0, WRITE_LOCK))) {
1597 printf("Unable to apply write lock on range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1600 printf("pid1 successfully locked range 130:4 for WRITE\n");
1603 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1604 printf("pid1 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1607 printf("pid1 successfully read the range 130:4\n");
1610 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1611 printf("pid1 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1614 printf("pid1 successfully wrote to the range 130:4\n");
1617 cli1->session->pid = 2;
1619 if (smbcli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1620 printf("pid2 unable to read the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1621 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1622 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1626 printf("pid2 successfully read the range 130:4 (should be denied)\n");
1630 if (smbcli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1631 printf("pid2 unable to write to the range 130:4, error was %s\n", smbcli_errstr(cli1->tree));
1632 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1633 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1637 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1641 printf("Testing truncate of locked file.\n");
1643 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1646 printf("Unable to truncate locked file.\n");
1650 printf("Truncated locked file.\n");
1653 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &size, NULL))) {
1654 printf("getatr failed (%s)\n", smbcli_errstr(cli1->tree));
1660 printf("Unable to truncate locked file. Size was %u\n", size);
1665 cli1->session->pid = 1;
1667 smbcli_unlock(cli1->tree, fnum1, 130, 4);
1671 smbcli_close(cli1->tree, fnum1);
1672 smbcli_close(cli1->tree, fnum2);
1673 smbcli_unlink(cli1->tree, fname);
1674 torture_close_connection(cli1);
1676 printf("finished locktest7\n");
1681 test whether fnums and tids open on one VC are available on another (a major
1684 static BOOL run_fdpasstest(int dummy)
1686 struct smbcli_state *cli1, *cli2;
1687 const char *fname = "\\fdpass.tst";
1691 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1695 printf("starting fdpasstest\n");
1697 smbcli_unlink(cli1->tree, fname);
1699 printf("Opening a file on connection 1\n");
1701 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1703 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
1707 printf("writing to file on connection 1\n");
1709 if (smbcli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
1710 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
1714 oldtid = cli2->tree->tid;
1715 cli2->session->vuid = cli1->session->vuid;
1716 cli2->tree->tid = cli1->tree->tid;
1717 cli2->session->pid = cli1->session->pid;
1719 printf("reading from file on connection 2\n");
1721 if (smbcli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
1722 printf("read succeeded! nasty security hole [%s]\n",
1727 smbcli_close(cli1->tree, fnum1);
1728 smbcli_unlink(cli1->tree, fname);
1730 cli2->tree->tid = oldtid;
1732 torture_close_connection(cli1);
1733 torture_close_connection(cli2);
1735 printf("finished fdpasstest\n");
1741 This test checks that
1743 1) the server does not allow an unlink on a file that is open
1745 static BOOL run_unlinktest(int dummy)
1747 struct smbcli_state *cli;
1748 const char *fname = "\\unlink.tst";
1750 BOOL correct = True;
1752 if (!torture_open_connection(&cli)) {
1756 printf("starting unlink test\n");
1758 smbcli_unlink(cli->tree, fname);
1760 cli->session->pid = 1;
1762 printf("Opening a file\n");
1764 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1766 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1770 printf("Unlinking a open file\n");
1772 if (NT_STATUS_IS_OK(smbcli_unlink(cli->tree, fname))) {
1773 printf("error: server allowed unlink on an open file\n");
1776 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
1777 NT_STATUS_SHARING_VIOLATION);
1780 smbcli_close(cli->tree, fnum);
1781 smbcli_unlink(cli->tree, fname);
1783 if (!torture_close_connection(cli)) {
1787 printf("unlink test finished\n");
1794 test the timing of deferred open requests
1796 static BOOL run_deferopen(struct smbcli_state *cli, int dummy)
1798 const char *fname = "\\defer_open_test.dat";
1801 BOOL correct = True;
1804 printf("failed to connect\n");
1808 printf("Testing deferred open requests.\n");
1814 struct timeval tv_start, tv_end;
1815 GetTimeOfDay(&tv_start);
1816 fnum = smbcli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
1817 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
1818 NTCREATEX_DISP_OPEN_IF, 0, 0);
1822 GetTimeOfDay(&tv_end);
1823 if (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
1824 /* Sharing violation errors need to be 1 second apart. */
1825 int64_t tdif = usec_time_diff(&tv_end, &tv_start);
1826 if (tdif < 500000 || tdif > 1500000) {
1827 fprintf(stderr,"Timing incorrect %lld.%lld for share violation\n",
1828 tdif / (int64_t)1000000,
1829 tdif % (int64_t)1000000);
1832 } while (NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
1835 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
1839 printf("pid %u open %d\n", getpid(), i);
1843 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
1844 fprintf(stderr,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree));
1850 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
1851 /* All until the last unlink will fail with sharing violation. */
1852 if (!NT_STATUS_EQUAL(smbcli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
1853 printf("unlink of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
1858 printf("deferred test finished\n");
1859 if (!torture_close_connection(cli)) {
1866 test how many open files this server supports on the one socket
1868 static BOOL run_maxfidtest(struct smbcli_state *cli, int dummy)
1870 #define MAXFID_TEMPLATE "\\maxfid.%d.%d"
1872 int fnums[0x11000], i;
1874 BOOL correct = True;
1877 printf("failed to connect\n");
1881 printf("Testing maximum number of open files\n");
1883 for (i=0; i<0x11000; i++) {
1884 asprintf(&fname, MAXFID_TEMPLATE, i,(int)getpid());
1885 if ((fnums[i] = smbcli_open(cli->tree, fname,
1886 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1888 printf("open of %s failed (%s)\n",
1889 fname, smbcli_errstr(cli->tree));
1890 printf("maximum fnum is %d\n", i);
1899 printf("cleaning up\n");
1901 asprintf(&fname, MAXFID_TEMPLATE, i,(int)getpid());
1902 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
1903 printf("Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
1905 if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
1906 printf("unlink of %s failed (%s)\n",
1907 fname, smbcli_errstr(cli->tree));
1915 printf("maxfid test finished\n");
1916 if (!torture_close_connection(cli)) {
1920 #undef MAXFID_TEMPLATE
1923 /* send smb negprot commands, not reading the response */
1924 static BOOL run_negprot_nowait(int dummy)
1927 struct smbcli_state *cli, *cli2;
1928 BOOL correct = True;
1930 printf("starting negprot nowait test\n");
1932 cli = open_nbt_connection();
1937 printf("Filling send buffer\n");
1939 for (i=0;i<10000;i++) {
1940 struct smbcli_request *req;
1941 time_t t1 = time(NULL);
1942 req = smb_negprot_send(cli->transport, PROTOCOL_NT1);
1943 while (req->state == SMBCLI_REQUEST_SEND && time(NULL) < t1+5) {
1944 smbcli_transport_process(cli->transport);
1946 if (req->state == SMBCLI_REQUEST_ERROR) {
1947 printf("Failed to fill pipe - %s\n", nt_errstr(req->status));
1948 torture_close_connection(cli);
1951 if (req->state == SMBCLI_REQUEST_SEND) {
1957 printf("send buffer failed to fill\n");
1958 if (!torture_close_connection(cli)) {
1964 printf("send buffer filled after %d requests\n", i);
1966 printf("Opening secondary connection\n");
1967 if (!torture_open_connection(&cli2)) {
1971 if (!torture_close_connection(cli)) {
1975 if (!torture_close_connection(cli2)) {
1979 printf("finished negprot nowait test\n");
1986 This checks how the getatr calls works
1988 static BOOL run_attrtest(int dummy)
1990 struct smbcli_state *cli;
1993 const char *fname = "\\attrib123456789.tst";
1994 BOOL correct = True;
1996 printf("starting attrib test\n");
1998 if (!torture_open_connection(&cli)) {
2002 smbcli_unlink(cli->tree, fname);
2003 fnum = smbcli_open(cli->tree, fname,
2004 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2005 smbcli_close(cli->tree, fnum);
2007 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
2008 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
2012 printf("New file time is %s", ctime(&t));
2014 if (abs(t - time(NULL)) > 60*60*24*10) {
2015 printf("ERROR: SMBgetatr bug. time is %s",
2021 t2 = t-60*60*24; /* 1 day ago */
2023 printf("Setting file time to %s", ctime(&t2));
2025 if (NT_STATUS_IS_ERR(smbcli_setatr(cli->tree, fname, 0, t2))) {
2026 printf("setatr failed (%s)\n", smbcli_errstr(cli->tree));
2030 if (NT_STATUS_IS_ERR(smbcli_getatr(cli->tree, fname, NULL, NULL, &t))) {
2031 printf("getatr failed (%s)\n", smbcli_errstr(cli->tree));
2035 printf("Retrieved file time as %s", ctime(&t));
2038 printf("ERROR: getatr/setatr bug. times are\n%s",
2040 printf("%s", ctime(&t2));
2044 smbcli_unlink(cli->tree, fname);
2046 if (!torture_close_connection(cli)) {
2050 printf("attrib test finished\n");
2057 This checks a couple of trans2 calls
2059 static BOOL run_trans2test(int dummy)
2061 struct smbcli_state *cli;
2064 time_t c_time, a_time, m_time, w_time, m_time2;
2065 const char *fname = "\\trans2.tst";
2066 const char *dname = "\\trans2";
2067 const char *fname2 = "\\trans2\\trans2.tst";
2069 BOOL correct = True;
2071 printf("starting trans2 test\n");
2073 if (!torture_open_connection(&cli)) {
2077 smbcli_unlink(cli->tree, fname);
2079 printf("Testing qfileinfo\n");
2081 fnum = smbcli_open(cli->tree, fname,
2082 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2083 if (NT_STATUS_IS_ERR(smbcli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
2085 printf("ERROR: qfileinfo failed (%s)\n", smbcli_errstr(cli->tree));
2089 printf("Testing NAME_INFO\n");
2091 if (NT_STATUS_IS_ERR(smbcli_qfilename(cli->tree, fnum, &pname))) {
2092 printf("ERROR: qfilename failed (%s)\n", smbcli_errstr(cli->tree));
2096 if (!pname || strcmp(pname, fname)) {
2097 printf("qfilename gave different name? [%s] [%s]\n",
2102 smbcli_close(cli->tree, fnum);
2103 smbcli_unlink(cli->tree, fname);
2105 fnum = smbcli_open(cli->tree, fname,
2106 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2108 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
2111 smbcli_close(cli->tree, fnum);
2113 printf("Checking for sticky create times\n");
2115 if (NT_STATUS_IS_ERR(smbcli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
2116 printf("ERROR: qpathinfo failed (%s)\n", smbcli_errstr(cli->tree));
2119 if (c_time != m_time) {
2120 printf("create time=%s", ctime(&c_time));
2121 printf("modify time=%s", ctime(&m_time));
2122 printf("This system appears to have sticky create times\n");
2124 if (a_time % (60*60) == 0) {
2125 printf("access time=%s", ctime(&a_time));
2126 printf("This system appears to set a midnight access time\n");
2130 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2131 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2137 smbcli_unlink(cli->tree, fname);
2138 fnum = smbcli_open(cli->tree, fname,
2139 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2140 smbcli_close(cli->tree, fnum);
2141 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2142 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
2145 if (w_time < 60*60*24*2) {
2146 printf("write time=%s", ctime(&w_time));
2147 printf("This system appears to set a initial 0 write time\n");
2152 smbcli_unlink(cli->tree, fname);
2155 /* check if the server updates the directory modification time
2156 when creating a new file */
2157 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, dname))) {
2158 printf("ERROR: mkdir failed (%s)\n", smbcli_errstr(cli->tree));
2162 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2163 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
2167 fnum = smbcli_open(cli->tree, fname2,
2168 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2169 smbcli_write(cli->tree, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2170 smbcli_close(cli->tree, fnum);
2171 if (NT_STATUS_IS_ERR(smbcli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
2172 printf("ERROR: qpathinfo2 failed (%s)\n", smbcli_errstr(cli->tree));
2175 if (m_time2 == m_time) {
2176 printf("This system does not update directory modification times\n");
2180 smbcli_unlink(cli->tree, fname2);
2181 smbcli_rmdir(cli->tree, dname);
2183 if (!torture_close_connection(cli)) {
2187 printf("trans2 test finished\n");
2193 Test delete on close semantics.
2195 static BOOL run_deletetest(int dummy)
2197 struct smbcli_state *cli1;
2198 struct smbcli_state *cli2 = NULL;
2199 const char *fname = "\\delete.file";
2202 BOOL correct = True;
2204 printf("starting delete test\n");
2206 if (!torture_open_connection(&cli1)) {
2210 /* Test 1 - this should delete the file on close. */
2212 smbcli_setatr(cli1->tree, fname, 0, 0);
2213 smbcli_unlink(cli1->tree, fname);
2215 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2216 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF,
2217 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2220 printf("[1] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2225 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2226 printf("[1] close failed (%s)\n", smbcli_errstr(cli1->tree));
2231 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
2233 printf("[1] open of %s succeeded (should fail)\n", fname);
2238 printf("first delete on close test succeeded.\n");
2240 /* Test 2 - this should delete the file on close. */
2242 smbcli_setatr(cli1->tree, fname, 0, 0);
2243 smbcli_unlink(cli1->tree, fname);
2245 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
2246 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
2247 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2250 printf("[2] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2255 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2256 printf("[2] setting delete_on_close failed (%s)\n", smbcli_errstr(cli1->tree));
2261 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2262 printf("[2] close failed (%s)\n", smbcli_errstr(cli1->tree));
2267 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2269 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2270 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2271 printf("[2] close failed (%s)\n", smbcli_errstr(cli1->tree));
2275 smbcli_unlink(cli1->tree, fname);
2277 printf("second delete on close test succeeded.\n");
2280 smbcli_setatr(cli1->tree, fname, 0, 0);
2281 smbcli_unlink(cli1->tree, fname);
2283 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2284 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2287 printf("[3] open - 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2292 /* This should fail with a sharing violation - open for delete is only compatible
2293 with SHARE_DELETE. */
2295 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2296 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2297 NTCREATEX_DISP_OPEN, 0, 0);
2300 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2305 /* This should succeed. */
2307 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2308 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN, 0, 0);
2311 printf("[3] open - 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2316 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2317 printf("[3] setting delete_on_close failed (%s)\n", smbcli_errstr(cli1->tree));
2322 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2323 printf("[3] close 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2328 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
2329 printf("[3] close 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2334 /* This should fail - file should no longer be there. */
2336 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2338 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2339 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2340 printf("[3] close failed (%s)\n", smbcli_errstr(cli1->tree));
2342 smbcli_unlink(cli1->tree, fname);
2346 printf("third delete on close test succeeded.\n");
2349 smbcli_setatr(cli1->tree, fname, 0, 0);
2350 smbcli_unlink(cli1->tree, fname);
2352 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2353 SA_RIGHT_FILE_READ_DATA |
2354 SA_RIGHT_FILE_WRITE_DATA |
2355 STD_RIGHT_DELETE_ACCESS,
2356 FILE_ATTRIBUTE_NORMAL,
2357 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2358 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2361 printf("[4] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2366 /* This should succeed. */
2367 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2368 FILE_ATTRIBUTE_NORMAL,
2369 NTCREATEX_SHARE_ACCESS_READ |
2370 NTCREATEX_SHARE_ACCESS_WRITE |
2371 NTCREATEX_SHARE_ACCESS_DELETE,
2372 NTCREATEX_DISP_OPEN, 0, 0);
2374 printf("[4] open - 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2379 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
2380 printf("[4] close - 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2385 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2386 printf("[4] setting delete_on_close failed (%s)\n", smbcli_errstr(cli1->tree));
2391 /* This should fail - no more opens once delete on close set. */
2392 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2393 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2394 NTCREATEX_DISP_OPEN, 0, 0);
2396 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2400 printf("fourth delete on close test succeeded.\n");
2402 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2403 printf("[4] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2409 smbcli_setatr(cli1->tree, fname, 0, 0);
2410 smbcli_unlink(cli1->tree, fname);
2412 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
2414 printf("[5] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2419 /* This should fail - only allowed on NT opens with DELETE access. */
2421 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2422 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2427 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2428 printf("[5] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2433 printf("fifth delete on close test succeeded.\n");
2436 smbcli_setatr(cli1->tree, fname, 0, 0);
2437 smbcli_unlink(cli1->tree, fname);
2439 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2440 SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA,
2441 FILE_ATTRIBUTE_NORMAL,
2442 NTCREATEX_SHARE_ACCESS_READ |
2443 NTCREATEX_SHARE_ACCESS_WRITE |
2444 NTCREATEX_SHARE_ACCESS_DELETE,
2445 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2448 printf("[6] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2453 /* This should fail - only allowed on NT opens with DELETE access. */
2455 if (NT_STATUS_IS_OK(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2456 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2461 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2462 printf("[6] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2467 printf("sixth delete on close test succeeded.\n");
2470 smbcli_setatr(cli1->tree, fname, 0, 0);
2471 smbcli_unlink(cli1->tree, fname);
2473 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2474 SA_RIGHT_FILE_READ_DATA |
2475 SA_RIGHT_FILE_WRITE_DATA |
2476 STD_RIGHT_DELETE_ACCESS,
2477 FILE_ATTRIBUTE_NORMAL, 0, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2480 printf("[7] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2485 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2486 printf("[7] setting delete_on_close on file failed !\n");
2491 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, False))) {
2492 printf("[7] unsetting delete_on_close on file failed !\n");
2497 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2498 printf("[7] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2503 /* This next open should succeed - we reset the flag. */
2505 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2507 printf("[5] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2512 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2513 printf("[7] close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2518 printf("seventh delete on close test succeeded.\n");
2521 smbcli_setatr(cli1->tree, fname, 0, 0);
2522 smbcli_unlink(cli1->tree, fname);
2524 if (!torture_open_connection(&cli2)) {
2525 printf("[8] failed to open second connection.\n");
2530 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2531 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2532 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2535 printf("[8] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2540 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2541 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2542 NTCREATEX_DISP_OPEN, 0, 0);
2545 printf("[8] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2550 if (NT_STATUS_IS_ERR(smbcli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2551 printf("[8] setting delete_on_close on file failed !\n");
2556 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2557 printf("[8] close - 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2562 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
2563 printf("[8] close - 2 failed (%s)\n", smbcli_errstr(cli2->tree));
2568 /* This should fail.. */
2569 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2571 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2575 printf("eighth delete on close test succeeded.\n");
2577 /* This should fail - we need to set DELETE_ACCESS. */
2578 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
2579 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2582 printf("[9] open of %s succeeded should have failed!\n", fname);
2587 printf("ninth delete on close test succeeded.\n");
2589 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2590 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2592 printf("[10] open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
2597 /* This should delete the file. */
2598 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2599 printf("[10] close failed (%s)\n", smbcli_errstr(cli1->tree));
2604 /* This should fail.. */
2605 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2607 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2611 printf("tenth delete on close test succeeded.\n");
2612 printf("finished delete test\n");
2615 /* FIXME: This will crash if we aborted before cli2 got
2616 * intialized, because these functions don't handle
2617 * uninitialized connections. */
2619 smbcli_close(cli1->tree, fnum1);
2620 smbcli_close(cli1->tree, fnum2);
2621 smbcli_setatr(cli1->tree, fname, 0, 0);
2622 smbcli_unlink(cli1->tree, fname);
2624 if (!torture_close_connection(cli1)) {
2627 if (!torture_close_connection(cli2)) {
2635 print out server properties
2637 static BOOL run_properties(int dummy)
2639 struct smbcli_state *cli;
2640 BOOL correct = True;
2642 printf("starting properties test\n");
2646 if (!torture_open_connection(&cli)) {
2650 d_printf("Capabilities 0x%08x\n", cli->transport->negotiate.capabilities);
2652 if (!torture_close_connection(cli)) {
2661 /* FIRST_DESIRED_ACCESS 0xf019f */
2662 #define FIRST_DESIRED_ACCESS SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_APPEND_DATA|\
2663 SA_RIGHT_FILE_READ_EA| /* 0xf */ \
2664 SA_RIGHT_FILE_WRITE_EA|SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x90 */ \
2665 SA_RIGHT_FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
2666 STD_RIGHT_DELETE_ACCESS|STD_RIGHT_READ_CONTROL_ACCESS|\
2667 STD_RIGHT_WRITE_DAC_ACCESS|STD_RIGHT_WRITE_OWNER_ACCESS /* 0xf0000 */
2668 /* SECOND_DESIRED_ACCESS 0xe0080 */
2669 #define SECOND_DESIRED_ACCESS SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x80 */ \
2670 STD_RIGHT_READ_CONTROL_ACCESS|STD_RIGHT_WRITE_DAC_ACCESS|\
2671 STD_RIGHT_WRITE_OWNER_ACCESS /* 0xe0000 */
2674 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
2675 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2676 SA_RIGHT_FILE_READ_DATA|\
2677 WRITE_OWNER_ACCESS /* */
2681 Test ntcreate calls made by xcopy
2683 static BOOL run_xcopy(int dummy)
2685 struct smbcli_state *cli1;
2686 const char *fname = "\\test.txt";
2687 BOOL correct = True;
2690 printf("starting xcopy test\n");
2692 if (!torture_open_connection(&cli1)) {
2696 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
2697 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2698 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF,
2702 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
2706 fnum2 = smbcli_nt_create_full(cli1->tree, fname, 0,
2707 SECOND_DESIRED_ACCESS, 0,
2708 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
2711 printf("second open failed - %s\n", smbcli_errstr(cli1->tree));
2715 if (!torture_close_connection(cli1)) {
2723 Test rename on files open with share delete and no share delete.
2725 static BOOL run_rename(int dummy)
2727 struct smbcli_state *cli1;
2728 const char *fname = "\\test.txt";
2729 const char *fname1 = "\\test1.txt";
2730 BOOL correct = True;
2733 printf("starting rename test\n");
2735 if (!torture_open_connection(&cli1)) {
2739 smbcli_unlink(cli1->tree, fname);
2740 smbcli_unlink(cli1->tree, fname1);
2741 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2742 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2745 printf("First open failed - %s\n", smbcli_errstr(cli1->tree));
2749 if (NT_STATUS_IS_ERR(smbcli_rename(cli1->tree, fname, fname1))) {
2750 printf("First rename failed (this is correct) - %s\n", smbcli_errstr(cli1->tree));
2752 printf("First rename succeeded - this should have failed !\n");
2756 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2757 printf("close - 1 failed (%s)\n", smbcli_errstr(cli1->tree));
2761 smbcli_unlink(cli1->tree, fname);
2762 smbcli_unlink(cli1->tree, fname1);
2763 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2764 NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2767 printf("Second open failed - %s\n", smbcli_errstr(cli1->tree));
2771 if (NT_STATUS_IS_ERR(smbcli_rename(cli1->tree, fname, fname1))) {
2772 printf("Second rename failed - this should have succeeded - %s\n", smbcli_errstr(cli1->tree));
2775 printf("Second rename succeeded\n");
2778 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2779 printf("close - 2 failed (%s)\n", smbcli_errstr(cli1->tree));
2783 smbcli_unlink(cli1->tree, fname);
2784 smbcli_unlink(cli1->tree, fname1);
2786 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2787 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2790 printf("Third open failed - %s\n", smbcli_errstr(cli1->tree));
2795 if (NT_STATUS_IS_ERR(smbcli_rename(cli1->tree, fname, fname1))) {
2796 printf("Third rename failed - this should have succeeded - %s\n", smbcli_errstr(cli1->tree));
2799 printf("Third rename succeeded\n");
2802 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
2803 printf("close - 3 failed (%s)\n", smbcli_errstr(cli1->tree));
2807 smbcli_unlink(cli1->tree, fname);
2808 smbcli_unlink(cli1->tree, fname1);
2810 if (!torture_close_connection(cli1)) {
2819 see how many RPC pipes we can open at once
2821 static BOOL run_pipe_number(int dummy)
2823 struct smbcli_state *cli1;
2824 const char *pipe_name = "\\WKSSVC";
2828 printf("starting pipenumber test\n");
2829 if (!torture_open_connection(&cli1)) {
2834 fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
2835 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
2838 printf("Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
2842 printf("%d\r", num_pipes);
2846 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
2847 torture_close_connection(cli1);
2855 open N connections to the server and just hold them open
2856 used for testing performance when there are N idle users
2859 static BOOL torture_holdcon(int dummy)
2862 struct smbcli_state **cli;
2865 printf("Opening %d connections\n", torture_numops);
2867 cli = malloc(sizeof(struct smbcli_state *) * torture_numops);
2869 for (i=0;i<torture_numops;i++) {
2870 if (!torture_open_connection(&cli[i])) {
2873 printf("opened %d connections\r", i);
2877 printf("\nStarting pings\n");
2880 for (i=0;i<torture_numops;i++) {
2883 status = smbcli_chkpath(cli[i]->tree, "\\");
2884 if (!NT_STATUS_IS_OK(status)) {
2885 printf("Connection %d is dead\n", i);
2893 if (num_dead == torture_numops) {
2894 printf("All connections dead - finishing\n");
2906 Try with a wrong vuid and check error message.
2909 static BOOL run_vuidtest(int dummy)
2911 struct smbcli_state *cli;
2912 const char *fname = "\\vuid.tst";
2915 time_t c_time, a_time, m_time;
2916 BOOL correct = True;
2921 printf("starting vuid test\n");
2923 if (!torture_open_connection(&cli)) {
2927 smbcli_unlink(cli->tree, fname);
2929 fnum = smbcli_open(cli->tree, fname,
2930 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2932 orig_vuid = cli->session->vuid;
2934 cli->session->vuid += 1234;
2936 printf("Testing qfileinfo with wrong vuid\n");
2938 if (NT_STATUS_IS_OK(result = smbcli_qfileinfo(cli->tree, fnum, NULL,
2939 &size, &c_time, &a_time,
2940 &m_time, NULL, NULL))) {
2941 printf("ERROR: qfileinfo passed with wrong vuid\n");
2945 if ( (cli->transport->error.etype != ETYPE_DOS) ||
2946 (cli->transport->error.e.dos.eclass != ERRSRV) ||
2947 (cli->transport->error.e.dos.ecode != ERRbaduid) ) {
2948 printf("ERROR: qfileinfo should have returned DOS error "
2949 "ERRSRV:ERRbaduid\n but returned %s\n",
2950 smbcli_errstr(cli->tree));
2954 cli->session->vuid -= 1234;
2956 if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) {
2957 printf("close failed (%s)\n", smbcli_errstr(cli->tree));
2961 smbcli_unlink(cli->tree, fname);
2963 if (!torture_close_connection(cli)) {
2967 printf("vuid test finished\n");
2973 Test open mode returns on read-only files.
2975 static BOOL run_opentest(int dummy)
2977 static struct smbcli_state *cli1;
2978 static struct smbcli_state *cli2;
2979 const char *fname = "\\readonly.file";
2983 BOOL correct = True;
2987 printf("starting open test\n");
2989 if (!torture_open_connection(&cli1)) {
2993 smbcli_setatr(cli1->tree, fname, 0, 0);
2994 smbcli_unlink(cli1->tree, fname);
2996 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2998 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3002 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3003 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
3007 if (NT_STATUS_IS_ERR(smbcli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
3008 printf("smbcli_setatr failed (%s)\n", smbcli_errstr(cli1->tree));
3009 CHECK_MAX_FAILURES(error_test1);
3013 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
3015 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3016 CHECK_MAX_FAILURES(error_test1);
3020 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3021 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
3023 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
3024 NT_STATUS_ACCESS_DENIED)) {
3025 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3028 printf("finished open test 1\n");
3030 smbcli_close(cli1->tree, fnum1);
3032 /* Now try not readonly and ensure ERRbadshare is returned. */
3034 smbcli_setatr(cli1->tree, fname, 0, 0);
3036 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
3038 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3042 /* This will fail - but the error should be ERRshare. */
3043 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
3045 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3046 NT_STATUS_SHARING_VIOLATION)) {
3047 printf("correct error code ERRDOS/ERRbadshare returned\n");
3050 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3051 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
3055 smbcli_unlink(cli1->tree, fname);
3057 printf("finished open test 2\n");
3059 /* Test truncate open disposition on file opened for read. */
3061 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3063 printf("(3) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3067 /* write 20 bytes. */
3069 memset(buf, '\0', 20);
3071 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
3072 printf("write failed (%s)\n", smbcli_errstr(cli1->tree));
3076 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3077 printf("(3) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
3081 /* Ensure size == 20. */
3082 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3083 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
3084 CHECK_MAX_FAILURES(error_test3);
3089 printf("(3) file size != 20\n");
3090 CHECK_MAX_FAILURES(error_test3);
3094 /* Now test if we can truncate a file opened for readonly. */
3096 fnum1 = smbcli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3098 printf("(3) open (2) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3099 CHECK_MAX_FAILURES(error_test3);
3103 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3104 printf("close2 failed (%s)\n", smbcli_errstr(cli1->tree));
3108 /* Ensure size == 0. */
3109 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3110 printf("(3) getatr failed (%s)\n", smbcli_errstr(cli1->tree));
3111 CHECK_MAX_FAILURES(error_test3);
3116 printf("(3) file size != 0\n");
3117 CHECK_MAX_FAILURES(error_test3);
3120 printf("finished open test 3\n");
3122 smbcli_unlink(cli1->tree, fname);
3125 printf("testing ctemp\n");
3126 fnum1 = smbcli_ctemp(cli1->tree, "\\", &tmp_path);
3128 printf("ctemp failed (%s)\n", smbcli_errstr(cli1->tree));
3129 CHECK_MAX_FAILURES(error_test4);
3132 printf("ctemp gave path %s\n", tmp_path);
3133 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3134 printf("close of temp failed (%s)\n", smbcli_errstr(cli1->tree));
3136 if (NT_STATUS_IS_ERR(smbcli_unlink(cli1->tree, tmp_path))) {
3137 printf("unlink of temp failed (%s)\n", smbcli_errstr(cli1->tree));
3140 /* Test the non-io opens... */
3142 if (!torture_open_connection(&cli2)) {
3146 smbcli_setatr(cli2->tree, fname, 0, 0);
3147 smbcli_unlink(cli2->tree, fname);
3149 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3151 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3152 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3155 printf("test 1 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3156 CHECK_MAX_FAILURES(error_test10);
3160 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3161 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3163 printf("test 1 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3164 CHECK_MAX_FAILURES(error_test10);
3168 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3169 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3172 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3173 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3177 printf("non-io open test #1 passed.\n");
3179 smbcli_unlink(cli1->tree, fname);
3181 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3183 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3184 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3187 printf("test 2 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3188 CHECK_MAX_FAILURES(error_test20);
3192 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3193 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3196 printf("test 2 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3197 CHECK_MAX_FAILURES(error_test20);
3201 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3202 printf("test 1 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3205 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3206 printf("test 1 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3210 printf("non-io open test #2 passed.\n");
3212 smbcli_unlink(cli1->tree, fname);
3214 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3216 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3217 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3220 printf("test 3 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3221 CHECK_MAX_FAILURES(error_test30);
3225 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3226 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3229 printf("test 3 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3230 CHECK_MAX_FAILURES(error_test30);
3234 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3235 printf("test 3 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3238 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3239 printf("test 3 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3243 printf("non-io open test #3 passed.\n");
3245 smbcli_unlink(cli1->tree, fname);
3247 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3249 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3250 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3253 printf("test 4 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3254 CHECK_MAX_FAILURES(error_test40);
3258 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3259 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3262 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3263 CHECK_MAX_FAILURES(error_test40);
3267 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
3269 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3270 printf("test 4 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3274 printf("non-io open test #4 passed.\n");
3276 smbcli_unlink(cli1->tree, fname);
3278 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3280 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3281 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3284 printf("test 5 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3285 CHECK_MAX_FAILURES(error_test50);
3289 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3290 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3293 printf("test 5 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3294 CHECK_MAX_FAILURES(error_test50);
3298 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3299 printf("test 5 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3303 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3304 printf("test 5 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3308 printf("non-io open test #5 passed.\n");
3310 printf("TEST #6 testing 1 non-io open, one io open\n");
3312 smbcli_unlink(cli1->tree, fname);
3314 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3315 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3318 printf("test 6 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3319 CHECK_MAX_FAILURES(error_test60);
3323 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3324 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
3327 printf("test 6 open 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3328 CHECK_MAX_FAILURES(error_test60);
3332 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3333 printf("test 6 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3337 if (NT_STATUS_IS_ERR(smbcli_close(cli2->tree, fnum2))) {
3338 printf("test 6 close 2 of %s failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3342 printf("non-io open test #6 passed.\n");
3344 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3346 smbcli_unlink(cli1->tree, fname);
3348 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3349 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3352 printf("test 7 open 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3353 CHECK_MAX_FAILURES(error_test70);
3357 fnum2 = smbcli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3358 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3361 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, smbcli_errstr(cli2->tree));
3362 CHECK_MAX_FAILURES(error_test70);
3366 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, smbcli_errstr(cli2->tree), "sharing violation");
3368 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3369 printf("test 7 close 1 of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3373 printf("non-io open test #7 passed.\n");
3377 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
3379 smbcli_unlink(cli1->tree, fname);
3381 fnum1 = smbcli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3383 printf("(8) open (1) of %s failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3387 /* write 20 bytes. */
3389 memset(buf, '\0', 20);
3391 if (smbcli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
3392 printf("(8) write failed (%s)\n", smbcli_errstr(cli1->tree));
3396 /* Ensure size == 20. */
3397 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3398 printf("(8) getatr (1) failed (%s)\n", smbcli_errstr(cli1->tree));
3399 CHECK_MAX_FAILURES(error_test80);
3404 printf("(8) file size != 20\n");
3405 CHECK_MAX_FAILURES(error_test80);
3409 /* Get an exclusive lock on the open file. */
3410 if (NT_STATUS_IS_ERR(smbcli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
3411 printf("(8) lock1 failed (%s)\n", smbcli_errstr(cli1->tree));
3412 CHECK_MAX_FAILURES(error_test80);
3416 fnum2 = smbcli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
3418 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, smbcli_errstr(cli1->tree));
3422 /* Ensure size == 0. */
3423 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3424 printf("(8) getatr (2) failed (%s)\n", smbcli_errstr(cli1->tree));
3425 CHECK_MAX_FAILURES(error_test80);
3430 printf("(8) file size != 0\n");
3431 CHECK_MAX_FAILURES(error_test80);
3435 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3436 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
3440 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum2))) {
3441 printf("(8) close1 failed (%s)\n", smbcli_errstr(cli1->tree));
3447 printf("open test #8 passed.\n");
3449 smbcli_unlink(cli1->tree, fname);
3451 if (!torture_close_connection(cli1)) {
3454 if (!torture_close_connection(cli2)) {
3462 static uint32_t open_attrs_table[] = {
3463 FILE_ATTRIBUTE_NORMAL,
3464 FILE_ATTRIBUTE_ARCHIVE,
3465 FILE_ATTRIBUTE_READONLY,
3466 FILE_ATTRIBUTE_HIDDEN,
3467 FILE_ATTRIBUTE_SYSTEM,
3469 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
3470 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
3471 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
3472 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3473 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3474 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3476 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3477 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3478 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3479 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
3482 struct trunc_open_results {
3485 uint32_t trunc_attr;
3486 uint32_t result_attr;
3489 static struct trunc_open_results attr_results[] = {
3490 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3491 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3492 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3493 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3494 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3495 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3496 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3497 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3498 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3499 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3500 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3501 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
3502 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3503 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3504 { 104, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3505 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3506 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3507 { 121, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
3508 { 170, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN },
3509 { 173, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM },
3510 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3511 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3512 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3513 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3514 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3515 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
3518 static BOOL run_openattrtest(int dummy)
3520 struct smbcli_state *cli1;
3521 const char *fname = "\\openattr.file";
3523 BOOL correct = True;
3528 printf("starting open attr test\n");
3530 if (!torture_open_connection(&cli1)) {
3534 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
3535 smbcli_setatr(cli1->tree, fname, 0, 0);
3536 smbcli_unlink(cli1->tree, fname);
3537 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_WRITE_DATA, open_attrs_table[i],
3538 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3541 printf("open %d (1) of %s failed (%s)\n", i, fname, smbcli_errstr(cli1->tree));
3545 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3546 printf("close %d (1) of %s failed (%s)\n", i, fname, smbcli_errstr(cli1->tree));
3550 for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
3551 fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0,
3552 SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
3553 open_attrs_table[j],
3554 NTCREATEX_SHARE_ACCESS_NONE,
3555 NTCREATEX_DISP_OVERWRITE, 0, 0);
3558 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3559 if (attr_results[l].num == k) {
3560 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
3561 k, open_attrs_table[i],
3562 open_attrs_table[j],
3563 fname, NT_STATUS_V(smbcli_nt_error(cli1->tree)), smbcli_errstr(cli1->tree));
3565 CHECK_MAX_FAILURES(error_exit);
3568 if (NT_STATUS_V(smbcli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
3569 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
3570 k, open_attrs_table[i], open_attrs_table[j],
3571 smbcli_errstr(cli1->tree));
3573 CHECK_MAX_FAILURES(error_exit);
3576 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
3582 if (NT_STATUS_IS_ERR(smbcli_close(cli1->tree, fnum1))) {
3583 printf("close %d (2) of %s failed (%s)\n", j, fname, smbcli_errstr(cli1->tree));
3587 if (NT_STATUS_IS_ERR(smbcli_getatr(cli1->tree, fname, &attr, NULL, NULL))) {
3588 printf("getatr(2) failed (%s)\n", smbcli_errstr(cli1->tree));
3593 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
3594 k, open_attrs_table[i], open_attrs_table[j], attr );
3597 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3598 if (attr_results[l].num == k) {
3599 if (attr != attr_results[l].result_attr ||
3600 open_attrs_table[i] != attr_results[l].init_attr ||
3601 open_attrs_table[j] != attr_results[l].trunc_attr) {
3602 printf("[%d] getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
3603 k, open_attrs_table[i],
3604 open_attrs_table[j],
3606 attr_results[l].result_attr);
3608 CHECK_MAX_FAILURES(error_exit);
3617 smbcli_setatr(cli1->tree, fname, 0, 0);
3618 smbcli_unlink(cli1->tree, fname);
3620 printf("open attr test %s.\n", correct ? "passed" : "failed");
3622 if (!torture_close_connection(cli1)) {
3628 static void list_fn(file_info *finfo, const char *name, void *state)
3634 test directory listing speed
3636 static BOOL run_dirtest(int dummy)
3639 struct smbcli_state *cli;
3642 BOOL correct = True;
3644 printf("starting directory test\n");
3646 if (!torture_open_connection(&cli)) {
3650 printf("Creating %d random filenames\n", torture_numops);
3653 for (i=0;i<torture_numops;i++) {
3655 asprintf(&fname, "\\%x", (int)random());
3656 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3658 fprintf(stderr,"Failed to open %s\n", fname);
3661 smbcli_close(cli->tree, fnum);
3667 printf("Matched %d\n", smbcli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3668 printf("Matched %d\n", smbcli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3669 printf("Matched %d\n", smbcli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3671 printf("dirtest core %g seconds\n", end_timer() - t1);
3674 for (i=0;i<torture_numops;i++) {
3676 asprintf(&fname, "\\%x", (int)random());
3677 smbcli_unlink(cli->tree, fname);
3681 if (!torture_close_connection(cli)) {
3685 printf("finished dirtest\n");
3691 sees what IOCTLs are supported
3693 BOOL torture_ioctl_test(int dummy)
3695 struct smbcli_state *cli;
3696 uint16_t device, function;
3698 const char *fname = "\\ioctl.dat";
3700 union smb_ioctl parms;
3701 TALLOC_CTX *mem_ctx;
3703 if (!torture_open_connection(&cli)) {
3707 mem_ctx = talloc_init("ioctl_test");
3709 printf("starting ioctl test\n");
3711 smbcli_unlink(cli->tree, fname);
3713 fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3715 printf("open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
3719 parms.ioctl.level = RAW_IOCTL_IOCTL;
3720 parms.ioctl.in.fnum = fnum;
3721 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
3722 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3723 printf("ioctl job info: %s\n", smbcli_errstr(cli->tree));
3725 for (device=0;device<0x100;device++) {
3726 printf("testing device=0x%x\n", device);
3727 for (function=0;function<0x100;function++) {
3728 parms.ioctl.in.request = (device << 16) | function;
3729 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3731 if (NT_STATUS_IS_OK(status)) {
3732 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
3733 device, function, parms.ioctl.out.blob.length);
3738 if (!torture_close_connection(cli)) {
3747 tries variants of chkpath
3749 BOOL torture_chkpath_test(int dummy)
3751 struct smbcli_state *cli;
3755 if (!torture_open_connection(&cli)) {
3759 printf("starting chkpath test\n");
3761 printf("Testing valid and invalid paths\n");
3763 /* cleanup from an old run */
3764 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3765 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
3766 smbcli_rmdir(cli->tree, "\\chkpath.dir");
3768 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir"))) {
3769 printf("mkdir1 failed : %s\n", smbcli_errstr(cli->tree));
3773 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
3774 printf("mkdir2 failed : %s\n", smbcli_errstr(cli->tree));
3778 fnum = smbcli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3780 printf("open1 failed (%s)\n", smbcli_errstr(cli->tree));
3783 smbcli_close(cli->tree, fnum);
3785 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir"))) {
3786 printf("chkpath1 failed: %s\n", smbcli_errstr(cli->tree));
3790 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
3791 printf("chkpath2 failed: %s\n", smbcli_errstr(cli->tree));
3795 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
3796 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3797 NT_STATUS_NOT_A_DIRECTORY);
3799 printf("* chkpath on a file should fail\n");
3803 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
3804 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
3805 NT_STATUS_OBJECT_NAME_NOT_FOUND);
3807 printf("* chkpath on a non existent file should fail\n");
3811 if (NT_STATUS_IS_ERR(smbcli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
3812 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3813 NT_STATUS_OBJECT_PATH_NOT_FOUND);
3815 printf("* chkpath on a non existent component should fail\n");
3819 smbcli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3820 smbcli_unlink(cli->tree, "\\chkpath.dir\\*");
3821 smbcli_rmdir(cli->tree, "\\chkpath.dir");
3823 if (!torture_close_connection(cli)) {
3830 static BOOL run_dirtest1(int dummy)
3833 struct smbcli_state *cli;
3835 BOOL correct = True;
3837 printf("starting directory test\n");
3839 if (!torture_open_connection(&cli)) {
3843 if (smbcli_deltree(cli->tree, "\\LISTDIR") == -1) {
3844 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", smbcli_errstr(cli->tree));
3847 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\LISTDIR"))) {
3848 fprintf(stderr,"Failed to mkdir %s, error=%s\n", "\\LISTDIR", smbcli_errstr(cli->tree));
3852 printf("Creating %d files\n", torture_entries);
3854 /* Create torture_entries files and torture_entries directories. */
3855 for (i=0;i<torture_entries;i++) {
3857 asprintf(&fname, "\\LISTDIR\\f%d", i);
3858 fnum = smbcli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3859 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3861 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
3865 smbcli_close(cli->tree, fnum);
3867 for (i=0;i<torture_entries;i++) {
3869 asprintf(&fname, "\\LISTDIR\\d%d", i);
3870 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
3871 fprintf(stderr,"Failed to open %s, error=%s\n", fname, smbcli_errstr(cli->tree));
3877 /* Now ensure that doing an old list sees both files and directories. */
3878 num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3879 printf("num_seen = %d\n", num_seen );
3880 /* We should see (torture_entries) each of files & directories + . and .. */
3881 if (num_seen != (2*torture_entries)+2) {
3883 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3884 (2*torture_entries)+2, num_seen);
3888 /* Ensure if we have the "must have" bits we only see the
3891 num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3892 printf("num_seen = %d\n", num_seen );
3893 if (num_seen != torture_entries+2) {
3895 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3896 torture_entries+2, num_seen);
3899 num_seen = smbcli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3900 printf("num_seen = %d\n", num_seen );
3901 if (num_seen != torture_entries) {
3903 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3904 torture_entries, num_seen);
3907 /* Delete everything. */
3908 if (smbcli_deltree(cli->tree, "\\LISTDIR") == -1) {
3909 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", smbcli_errstr(cli->tree));
3914 printf("Matched %d\n", smbcli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3915 printf("Matched %d\n", smbcli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3916 printf("Matched %d\n", smbcli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3919 if (!torture_close_connection(cli)) {
3923 printf("finished dirtest1\n");
3930 simple test harness for playing with deny modes
3932 static BOOL run_deny3test(int dummy)
3934 struct smbcli_state *cli1, *cli2;
3938 printf("starting deny3 test\n");
3940 printf("Testing simple deny modes\n");
3942 if (!torture_open_connection(&cli1)) {
3945 if (!torture_open_connection(&cli2)) {
3949 fname = "\\deny_dos1.dat";
3951 smbcli_unlink(cli1->tree, fname);
3952 fnum1 = smbcli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3953 fnum2 = smbcli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3954 if (fnum1 != -1) smbcli_close(cli1->tree, fnum1);
3955 if (fnum2 != -1) smbcli_close(cli1->tree, fnum2);
3956 smbcli_unlink(cli1->tree, fname);
3957 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3960 fname = "\\deny_dos2.dat";
3962 smbcli_unlink(cli1->tree, fname);
3963 fnum1 = smbcli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3964 fnum2 = smbcli_open(cli2->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3965 if (fnum1 != -1) smbcli_close(cli1->tree, fnum1);
3966 if (fnum2 != -1) smbcli_close(cli2->tree, fnum2);
3967 smbcli_unlink(cli1->tree, fname);
3968 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3971 torture_close_connection(cli1);
3972 torture_close_connection(cli2);
3978 parse a //server/share type UNC name
3980 static BOOL parse_unc(const char *unc_name, char **hostname, char **sharename)
3984 if (strncmp(unc_name, "//", 2)) {
3988 *hostname = strdup(&unc_name[2]);
3989 p = strchr_m(&(*hostname)[2],'/');
3994 *sharename = strdup(p+1);
4001 static void sigcont(void)
4005 double torture_create_procs(BOOL (*fn)(struct smbcli_state *, int), BOOL *result)
4008 volatile pid_t *child_status;
4009 volatile BOOL *child_status_out;
4012 double start_time_limit = 10 + (torture_nprocs * 1.5);
4013 char **unc_list = NULL;
4015 int num_unc_names = 0;
4019 signal(SIGCONT, sigcont);
4021 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
4022 if (!child_status) {
4023 printf("Failed to setup shared memory\n");
4027 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
4028 if (!child_status_out) {
4029 printf("Failed to setup result status shared memory\n");
4033 p = lp_parm_string(-1, "torture", "unclist");
4035 unc_list = file_lines_load(p, &num_unc_names);
4036 if (!unc_list || num_unc_names <= 0) {
4037 printf("Failed to load unc names list from '%s'\n", p);
4042 for (i = 0; i < torture_nprocs; i++) {
4043 child_status[i] = 0;
4044 child_status_out[i] = True;
4049 for (i=0;i<torture_nprocs;i++) {
4053 char *hostname=NULL, *sharename;
4055 pid_t mypid = getpid();
4056 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
4058 asprintf(&myname, "CLIENT%d", i);
4059 lp_set_cmdline("netbios name", myname);
4064 if (!parse_unc(unc_list[i % num_unc_names],
4065 &hostname, &sharename)) {
4066 printf("Failed to parse UNC name %s\n",
4067 unc_list[i % num_unc_names]);
4074 if (torture_open_connection_share(¤t_cli,
4079 } else if (torture_open_connection(¤t_cli)) {
4083 printf("pid %d failed to start\n", (int)getpid());
4089 child_status[i] = getpid();
4093 if (child_status[i]) {
4094 printf("Child %d failed to start!\n", i);
4095 child_status_out[i] = 1;
4099 child_status_out[i] = fn(current_cli, i);
4106 for (i=0;i<torture_nprocs;i++) {
4107 if (child_status[i]) synccount++;
4109 if (synccount == torture_nprocs) break;
4111 } while (end_timer() < start_time_limit);
4113 if (synccount != torture_nprocs) {
4114 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
4119 printf("Starting %d clients\n", torture_nprocs);
4121 /* start the client load */
4123 for (i=0;i<torture_nprocs;i++) {
4124 child_status[i] = 0;
4128 printf("%d clients started\n", torture_nprocs);
4130 for (i=0;i<torture_nprocs;i++) {
4132 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
4133 if (ret == -1 || WEXITSTATUS(status) != 0) {
4140 for (i=0;i<torture_nprocs;i++) {
4141 if (!child_status_out[i]) {
4148 #define FLAG_MULTIPROC 1
4156 {"BASE-FDPASS", run_fdpasstest, 0},
4157 {"BASE-LOCK1", run_locktest1, 0},
4158 {"BASE-LOCK2", run_locktest2, 0},
4159 {"BASE-LOCK3", run_locktest3, 0},
4160 {"BASE-LOCK4", run_locktest4, 0},
4161 {"BASE-LOCK5", run_locktest5, 0},
4162 {"BASE-LOCK6", run_locktest6, 0},
4163 {"BASE-LOCK7", run_locktest7, 0},
4164 {"BASE-UNLINK", run_unlinktest, 0},
4165 {"BASE-ATTR", run_attrtest, 0},
4166 {"BASE-TRANS2", run_trans2test, 0},
4167 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
4168 {"BASE-DIR", run_dirtest, 0},
4169 {"BASE-DIR1", run_dirtest1, 0},
4170 {"BASE-DENY1", torture_denytest1, 0},
4171 {"BASE-DENY2", torture_denytest2, 0},
4172 {"BASE-TCON", run_tcon_test, 0},
4173 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
4174 {"BASE-VUID", run_vuidtest, 0},
4175 {"BASE-RW1", run_readwritetest, 0},
4176 {"BASE-RW2", run_readwritemulti, FLAG_MULTIPROC},
4177 {"BASE-OPEN", run_opentest, 0},
4178 {"BASE-DENY3", run_deny3test, 0},
4179 {"BASE-DEFER_OPEN", run_deferopen, FLAG_MULTIPROC},
4180 {"BASE-XCOPY", run_xcopy, 0},
4181 {"BASE-RENAME", run_rename, 0},
4182 {"BASE-DELETE", run_deletetest, 0},
4183 {"BASE-PROPERTIES", run_properties, 0},
4184 {"BASE-MANGLE", torture_mangle, 0},
4185 {"BASE-OPENATTR", run_openattrtest, 0},
4186 {"BASE-CHARSET", torture_charset, 0},
4187 {"BASE-CHKPATH", torture_chkpath_test, 0},
4189 /* benchmarking tests */
4190 {"BENCH-HOLDCON", torture_holdcon, 0},
4191 {"BENCH-NBENCH", torture_nbench, 0},
4192 {"BENCH-TORTURE",run_torture, FLAG_MULTIPROC},
4195 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
4196 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
4197 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
4198 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
4199 {"RAW-SEARCH", torture_raw_search, 0},
4200 {"RAW-CLOSE", torture_raw_close, 0},
4201 {"RAW-OPEN", torture_raw_open, 0},
4202 {"RAW-MKDIR", torture_raw_mkdir, 0},
4203 {"RAW-OPLOCK", torture_raw_oplock, 0},
4204 {"RAW-NOTIFY", torture_raw_notify, 0},
4205 {"RAW-MUX", torture_raw_mux, 0},
4206 {"RAW-IOCTL", torture_raw_ioctl, 0},
4207 {"RAW-CHKPATH", torture_raw_chkpath, 0},
4208 {"RAW-UNLINK", torture_raw_unlink, 0},
4209 {"RAW-READ", torture_raw_read, 0},
4210 {"RAW-WRITE", torture_raw_write, 0},
4211 {"RAW-LOCK", torture_raw_lock, 0},
4212 {"RAW-CONTEXT", torture_raw_context, 0},
4213 {"RAW-RENAME", torture_raw_rename, 0},
4214 {"RAW-SEEK", torture_raw_seek, 0},
4215 {"RAW-RAP", torture_raw_rap, 0},
4217 /* protocol scanners */
4218 {"SCAN-TRANS2", torture_trans2_scan, 0},
4219 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
4220 {"SCAN-ALIASES", torture_trans2_aliases, 0},
4221 {"SCAN-SMB", torture_smb_scan, 0},
4222 {"SCAN-MAXFID", run_maxfidtest, FLAG_MULTIPROC},
4223 {"SCAN-UTABLE", torture_utable, 0},
4224 {"SCAN-CASETABLE", torture_casetable, 0},
4225 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
4226 {"SCAN-IOCTL", torture_ioctl_test, 0},
4229 {"RPC-LSA", torture_rpc_lsa, 0},
4230 {"RPC-ECHO", torture_rpc_echo, 0},
4231 {"RPC-DFS", torture_rpc_dfs, 0},
4232 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
4233 {"RPC-SAMR", torture_rpc_samr, 0},
4234 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
4235 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
4236 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
4237 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
4238 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
4239 {"RPC-ATSVC", torture_rpc_atsvc, 0},
4240 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
4241 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
4242 {"RPC-WINREG", torture_rpc_winreg, 0},
4243 {"RPC-MGMT", torture_rpc_mgmt, 0},
4244 {"RPC-SCANNER", torture_rpc_scanner, 0},
4245 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
4246 {"RPC-MULTIBIND", torture_multi_bind, 0},
4247 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
4249 /* local (no server) testers */
4250 {"LOCAL-NTLMSSP", torture_ntlmssp_self_check, 0},
4251 {"LOCAL-ICONV", torture_local_iconv, 0},
4254 {"LDAP-BASIC", torture_ldap_basic, 0},
4260 /****************************************************************************
4261 run a specified test or "ALL"
4262 ****************************************************************************/
4263 static BOOL run_test(const char *name)
4267 BOOL matched = False;
4269 if (strequal(name,"ALL")) {
4270 for (i=0;torture_ops[i].name;i++) {
4271 if (!run_test(torture_ops[i].name)) {
4278 for (i=0;torture_ops[i].name;i++) {
4279 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
4282 printf("Running %s\n", torture_ops[i].name);
4283 if (torture_ops[i].flags & FLAG_MULTIPROC) {
4285 t = torture_create_procs(torture_ops[i].fn, &result);
4288 printf("TEST %s FAILED!\n", torture_ops[i].name);
4293 if (!torture_ops[i].fn(0)) {
4295 printf("TEST %s FAILED!\n", torture_ops[i].name);
4299 printf("%s took %g secs\n\n", torture_ops[i].name, t);
4304 printf("Unknown torture operation '%s'\n", name);
4311 static void parse_dns(const char *dns)
4313 char *userdn, *basedn, *secret;
4316 /* retrievieng the userdn */
4317 p = strchr_m(dns, '#');
4319 lp_set_cmdline("torture:ldap_userdn", "");
4320 lp_set_cmdline("torture:ldap_basedn", "");
4321 lp_set_cmdline("torture:ldap_secret", "");
4324 userdn = strndup(dns, p - dns);
4325 lp_set_cmdline("torture:ldap_userdn", userdn);
4327 /* retrieve the basedn */
4329 p = strchr_m(d, '#');
4331 lp_set_cmdline("torture:ldap_basedn", "");
4332 lp_set_cmdline("torture:ldap_secret", "");
4335 basedn = strndup(d, p - d);
4336 lp_set_cmdline("torture:ldap_basedn", basedn);
4338 /* retrieve the secret */
4341 lp_set_cmdline("torture:ldap_secret", "");
4345 lp_set_cmdline("torture:ldap_secret", secret);
4347 printf ("%s - %s - %s\n", userdn, basedn, secret);
4351 static void usage(poptContext pc)
4356 poptPrintUsage(pc, stdout, 0);
4359 printf("tests are:");
4360 for (i=0;torture_ops[i].name;i++) {
4361 if ((i%perline)==0) {
4364 printf("%s ", torture_ops[i].name);
4368 printf("default test is ALL\n");
4373 /****************************************************************************
4375 ****************************************************************************/
4376 int main(int argc,char *argv[])
4380 BOOL correct = True;
4384 enum {OPT_LOADFILE=1000,OPT_UNCLIST,OPT_TIMELIMIT,OPT_DNS,OPT_DANGEROUS};
4385 struct poptOption long_options[] = {
4387 {"smb-ports", 'p', POPT_ARG_STRING, NULL, 0, "SMB ports", NULL},
4388 {"seed", 0, POPT_ARG_STRING, NULL, 0, "seed", NULL},
4389 {"num-progs", 0, POPT_ARG_INT, &torture_nprocs, 0, "num progs", NULL},
4390 {"num-ops", 0, POPT_ARG_INT, &torture_numops, 0, "num ops", NULL},
4391 {"entries", 0, POPT_ARG_INT, &torture_entries, 0, "entries", NULL},
4392 {"use-oplocks", 'L', POPT_ARG_NONE, &use_oplocks, 0, "use oplocks", NULL},
4393 {"show-all", 'A', POPT_ARG_NONE, &torture_showall, 0, "show all", NULL},
4394 {"loadfile", 0, POPT_ARG_STRING, NULL, OPT_LOADFILE, "loadfile", NULL},
4395 {"unclist", 0, POPT_ARG_STRING, NULL, OPT_UNCLIST, "unclist", NULL},
4396 {"timelimit", 't', POPT_ARG_STRING, NULL, OPT_TIMELIMIT, "timelimit", NULL},
4397 {"failures", 'f', POPT_ARG_INT, &torture_failures, 0, "failures", NULL},
4398 {"parse-dns", 'D', POPT_ARG_STRING, NULL, OPT_DNS, "parse-dns", NULL},
4399 {"dangerous", 'X', POPT_ARG_NONE, NULL, OPT_DANGEROUS, "dangerous", NULL},
4401 POPT_COMMON_CONNECTION
4402 POPT_COMMON_CREDENTIALS
4407 setup_logging("smbtorture", DEBUG_STDOUT);
4409 #ifdef HAVE_SETBUFFER
4410 setbuffer(stdout, NULL, 0);
4413 pc = poptGetContext("smbtorture", argc, (const char **) argv, long_options,
4414 POPT_CONTEXT_KEEP_FIRST);
4416 poptSetOtherOptionHelp(pc, "<binding>|<unc> TEST1 TEST2 ...");
4418 while((opt = poptGetNextOpt(pc)) != -1) {
4421 lp_set_cmdline("torture:loadfile", poptGetOptArg(pc));
4424 lp_set_cmdline("torture:unclist", poptGetOptArg(pc));
4427 lp_set_cmdline("torture:timelimit", poptGetOptArg(pc));
4430 parse_dns(poptGetOptArg(pc));
4433 lp_set_cmdline("torture:dangerous", "1");
4436 d_printf("Invalid option %s: %s\n",
4437 poptBadOption(pc, 0), poptStrerror(opt));
4443 lp_load(dyn_CONFIGFILE,True,False,False);
4445 srandom(time(NULL));
4447 argv_new = (const char **)poptGetArgs(pc);
4450 for (i=0; i<argc; i++) {
4451 if (argv_new[i] == NULL) {
4462 for(p = argv_new[1]; *p; p++) {
4467 /* see if its a RPC transport specifier */
4468 if (strncmp(argv_new[1], "ncacn_", 6) == 0) {
4469 lp_set_cmdline("torture:binding", argv_new[1]);
4471 char *binding = NULL;
4472 char *host = NULL, *share = NULL;
4474 if (!parse_unc(argv_new[1], &host, &share)) {
4478 lp_set_cmdline("torture:host", host);
4479 lp_set_cmdline("torture:share", share);
4480 asprintf(&binding, "ncacn_np:%s", host);
4481 lp_set_cmdline("torture:binding", binding);
4484 if (!lp_parm_string(-1,"torture","username")) {
4485 lp_set_cmdline("torture:username", cmdline_get_username());
4487 if (!lp_parm_string(-1,"torture","userdomain")) {
4489 * backward compatibility
4490 * maybe we should remove this to make this consistent
4491 * for all cmdline tools
4494 if (strequal(lp_netbios_name(),cmdline_get_userdomain())) {
4495 cmdline_set_userdomain(lp_workgroup());
4497 lp_set_cmdline("torture:userdomain", cmdline_get_userdomain());
4499 if (!lp_parm_string(-1,"torture","password")) {
4500 lp_set_cmdline("torture:password", cmdline_get_userpassword());
4503 if (argc_new == 0) {
4504 printf("You must specify a test to run, or 'ALL'\n");
4506 for (i=2;i<argc_new;i++) {
4507 if (!run_test(argv_new[i])) {