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 cli_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 cli_state *open_nbt_connection(void)
39 struct nmb_name called, calling;
41 struct cli_state *cli;
42 char *host = lp_parm_string(-1, "torture", "host");
44 make_nmb_name(&calling, lp_netbios_name(), 0x0);
45 make_nmb_name(&called , host, 0x20);
49 cli = cli_state_init();
51 printf("Failed initialize cli_struct to connect with %s\n", host);
55 if (!cli_socket_connect(cli, host, &ip)) {
56 printf("Failed to connect with %s\n", host);
60 cli->transport->socket->timeout = 120000; /* set a really long timeout (2 minutes) */
62 if (!cli_transport_establish(cli, &calling, &called)) {
64 * Well, that failed, try *SMBSERVER ...
65 * However, we must reconnect as well ...
67 if (!cli_socket_connect(cli, host, &ip)) {
68 printf("Failed to connect with %s\n", host);
72 make_nmb_name(&called, "*SMBSERVER", 0x20);
73 if (!cli_transport_establish(cli, &calling, &called)) {
74 printf("%s rejected the session\n",host);
75 printf("We tried with a called name of %s & %s\n",
85 BOOL torture_open_connection_share(struct cli_state **c,
87 const char *sharename)
92 char *username = lp_parm_string(-1, "torture", "username");
93 char *password = lp_parm_string(-1, "torture", "password");
96 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
98 status = cli_full_connection(c, lp_netbios_name(),
101 username, username[0]?lp_workgroup():"",
102 password, flags, &retry);
103 if (!NT_STATUS_IS_OK(status)) {
104 printf("Failed to open connection - %s\n", nt_errstr(status));
108 (*c)->transport->options.use_oplocks = use_oplocks;
109 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
110 (*c)->transport->socket->timeout = 120000;
115 BOOL torture_open_connection(struct cli_state **c)
117 char *host = lp_parm_string(-1, "torture", "host");
118 char *share = lp_parm_string(-1, "torture", "share");
120 return torture_open_connection_share(c, host, share);
125 BOOL torture_close_connection(struct cli_state *c)
128 DEBUG(9,("torture_close_connection: cli_state@%p\n", c));
130 if (NT_STATUS_IS_ERR(cli_tdis(c))) {
131 printf("tdis failed (%s)\n", cli_errstr(c->tree));
134 DEBUG(9,("torture_close_connection: call cli_shutdown\n"));
136 DEBUG(9,("torture_close_connection: exit\n"));
141 /* open a rpc connection to a named pipe */
142 NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p,
143 const char *pipe_name,
144 const char *pipe_uuid,
145 uint32_t pipe_version)
148 char *binding = lp_parm_string(-1, "torture", "binding");
151 printf("You must specify a ncacn binding string\n");
152 return NT_STATUS_INVALID_PARAMETER;
155 status = dcerpc_pipe_connect(p, binding, pipe_uuid, pipe_version,
157 lp_parm_string(-1, "torture", "username"),
158 lp_parm_string(-1, "torture", "password"));
163 /* close a rpc connection to a named pipe */
164 NTSTATUS torture_rpc_close(struct dcerpc_pipe *p)
166 dcerpc_pipe_close(p);
171 /* check if the server produced the expected error code */
172 static BOOL check_error(int line, struct cli_state *c,
173 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
175 if (cli_is_dos_error(c->tree)) {
179 /* Check DOS error */
181 cli_dos_error(c, &class, &num);
183 if (eclass != class || ecode != num) {
184 printf("unexpected error code class=%d code=%d\n",
185 (int)class, (int)num);
186 printf(" expected %d/%d %s (line=%d)\n",
187 (int)eclass, (int)ecode, nt_errstr(nterr), line);
196 status = cli_nt_error(c->tree);
198 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
199 printf("unexpected error code %s\n", nt_errstr(status));
200 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
209 static BOOL wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
211 while (NT_STATUS_IS_ERR(cli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
212 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
218 static BOOL rw_torture(struct cli_state *c)
220 const char *lockfname = "\\torture.lck";
224 pid_t pid2, pid = getpid();
229 fnum2 = cli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
232 fnum2 = cli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
234 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c->tree));
239 for (i=0;i<torture_numops;i++) {
240 uint_t n = (uint_t)sys_random()%10;
242 printf("%d\r", i); fflush(stdout);
244 asprintf(&fname, "\\torture.%u", n);
246 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
250 fnum = cli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
252 printf("open failed (%s)\n", cli_errstr(c->tree));
257 if (cli_write(c->tree, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
258 printf("write failed (%s)\n", cli_errstr(c->tree));
263 if (cli_write(c->tree, fnum, 0, (char *)buf,
264 sizeof(pid)+(j*sizeof(buf)),
265 sizeof(buf)) != sizeof(buf)) {
266 printf("write failed (%s)\n", cli_errstr(c->tree));
273 if (cli_read(c->tree, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
274 printf("read failed (%s)\n", cli_errstr(c->tree));
279 printf("data corruption!\n");
283 if (NT_STATUS_IS_ERR(cli_close(c->tree, fnum))) {
284 printf("close failed (%s)\n", cli_errstr(c->tree));
288 if (NT_STATUS_IS_ERR(cli_unlink(c->tree, fname))) {
289 printf("unlink failed (%s)\n", cli_errstr(c->tree));
293 if (NT_STATUS_IS_ERR(cli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
294 printf("unlock failed (%s)\n", cli_errstr(c->tree));
300 cli_close(c->tree, fnum2);
301 cli_unlink(c->tree, lockfname);
308 static BOOL run_torture(struct cli_state *cli, int dummy)
312 ret = rw_torture(cli);
314 if (!torture_close_connection(cli)) {
321 static BOOL rw_torture3(struct cli_state *c, const char *lockfname)
328 uint_t countprev = 0;
333 for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
335 SIVAL(buf, i, sys_random());
340 fnum = cli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
343 printf("first open read/write of %s failed (%s)\n",
344 lockfname, cli_errstr(c->tree));
350 for (i = 0; i < 500 && fnum == -1; i++)
352 fnum = cli_open(c->tree, lockfname, O_RDONLY,
357 printf("second open read-only of %s failed (%s)\n",
358 lockfname, cli_errstr(c->tree));
364 for (count = 0; count < sizeof(buf); count += sent)
366 if (count >= countprev) {
367 printf("%d %8d\r", i, count);
370 countprev += (sizeof(buf) / 20);
375 sent = ((uint_t)sys_random()%(20))+ 1;
376 if (sent > sizeof(buf) - count)
378 sent = sizeof(buf) - count;
381 if (cli_write(c->tree, fnum, 0, buf+count, count, (size_t)sent) != sent) {
382 printf("write failed (%s)\n", cli_errstr(c->tree));
388 sent = cli_read(c->tree, fnum, buf_rd+count, count,
392 printf("read failed offset:%d size:%d (%s)\n",
393 count, sizeof(buf)-count,
394 cli_errstr(c->tree));
400 if (memcmp(buf_rd+count, buf+count, sent) != 0)
402 printf("read/write compare failed\n");
403 printf("offset: %d req %d recvd %d\n",
404 count, sizeof(buf)-count, sent);
413 if (NT_STATUS_IS_ERR(cli_close(c->tree, fnum))) {
414 printf("close failed (%s)\n", cli_errstr(c->tree));
421 static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
423 const char *lockfname = "\\torture2.lck";
428 uint8_t buf_rd[131072];
430 ssize_t bytes_read, bytes_written;
432 if (cli_deltree(c1->tree, lockfname) == -1) {
433 printf("unlink failed (%s)\n", cli_errstr(c1->tree));
436 fnum1 = cli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
439 printf("first open read/write of %s failed (%s)\n",
440 lockfname, cli_errstr(c1->tree));
443 fnum2 = cli_open(c2->tree, lockfname, O_RDONLY,
446 printf("second open read-only of %s failed (%s)\n",
447 lockfname, cli_errstr(c2->tree));
448 cli_close(c1->tree, fnum1);
452 printf("Checking data integrity over %d ops\n", torture_numops);
454 for (i=0;i<torture_numops;i++)
456 size_t buf_size = ((uint_t)sys_random()%(sizeof(buf)-1))+ 1;
458 printf("%d\r", i); fflush(stdout);
461 generate_random_buffer(buf, buf_size, False);
463 if ((bytes_written = cli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
464 printf("write failed (%s)\n", cli_errstr(c1->tree));
465 printf("wrote %d, expected %d\n", bytes_written, buf_size);
470 if ((bytes_read = cli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
471 printf("read failed (%s)\n", cli_errstr(c2->tree));
472 printf("read %d, expected %d\n", bytes_read, buf_size);
477 if (memcmp(buf_rd, buf, buf_size) != 0)
479 printf("read/write compare failed\n");
485 if (NT_STATUS_IS_ERR(cli_close(c2->tree, fnum2))) {
486 printf("close failed (%s)\n", cli_errstr(c2->tree));
489 if (NT_STATUS_IS_ERR(cli_close(c1->tree, fnum1))) {
490 printf("close failed (%s)\n", cli_errstr(c1->tree));
494 if (NT_STATUS_IS_ERR(cli_unlink(c1->tree, lockfname))) {
495 printf("unlink failed (%s)\n", cli_errstr(c1->tree));
502 static BOOL run_readwritetest(int dummy)
504 struct cli_state *cli1, *cli2;
505 BOOL test1, test2 = True;
507 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
511 printf("starting readwritetest\n");
513 test1 = rw_torture2(cli1, cli2);
514 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
517 test2 = rw_torture2(cli1, cli1);
518 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
521 if (!torture_close_connection(cli1)) {
525 if (!torture_close_connection(cli2)) {
529 return (test1 && test2);
532 static BOOL run_readwritemulti(struct cli_state *cli, int dummy)
536 test = rw_torture3(cli, "\\multitest.txt");
538 if (!torture_close_connection(cli)) {
547 This test checks for two things:
549 1) correct support for retaining locks over a close (ie. the server
550 must not use posix semantics)
551 2) support for lock timeouts
553 static BOOL run_locktest1(int dummy)
555 struct cli_state *cli1, *cli2;
556 const char *fname = "\\lockt1.lck";
557 int fnum1, fnum2, fnum3;
561 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
565 printf("starting locktest1\n");
567 cli_unlink(cli1->tree, fname);
569 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
571 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
574 fnum2 = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
576 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
579 fnum3 = cli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
581 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
585 if (NT_STATUS_IS_ERR(cli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
586 printf("lock1 failed (%s)\n", cli_errstr(cli1->tree));
591 if (NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
592 printf("lock2 succeeded! This is a locking bug\n");
595 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
596 NT_STATUS_LOCK_NOT_GRANTED)) return False;
600 lock_timeout = (6 + (random() % 20));
601 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
603 if (NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK))) {
604 printf("lock3 succeeded! This is a locking bug\n");
607 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
608 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
613 printf("error: This server appears not to support timed lock requests\n");
615 printf("server slept for %u seconds for a %u second timeout\n",
616 (uint_t)(t2-t1), lock_timeout);
618 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum2))) {
619 printf("close1 failed (%s)\n", cli_errstr(cli1->tree));
623 if (NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
624 printf("lock4 succeeded! This is a locking bug\n");
627 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
628 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
631 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
632 printf("close2 failed (%s)\n", cli_errstr(cli1->tree));
636 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum3))) {
637 printf("close3 failed (%s)\n", cli_errstr(cli2->tree));
641 if (NT_STATUS_IS_ERR(cli_unlink(cli1->tree, fname))) {
642 printf("unlink failed (%s)\n", cli_errstr(cli1->tree));
647 if (!torture_close_connection(cli1)) {
651 if (!torture_close_connection(cli2)) {
655 printf("Passed locktest1\n");
660 this checks to see if a secondary tconx can use open files from an
663 static BOOL run_tcon_test(int dummy)
665 struct cli_state *cli;
666 const char *fname = "\\tcontest.tmp";
668 uint16_t cnum1, cnum2, cnum3;
669 uint16_t vuid1, vuid2;
672 struct cli_tree *tree1;
673 char *host = lp_parm_string(-1, "torture", "host");
674 char *share = lp_parm_string(-1, "torture", "share");
675 char *password = lp_parm_string(-1, "torture", "password");
677 if (!torture_open_connection(&cli)) {
681 printf("starting tcontest\n");
683 if (cli_deltree(cli->tree, fname) == -1) {
684 printf("unlink of %s failed (%s)\n", fname, cli_errstr(cli->tree));
687 fnum1 = cli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
689 printf("open of %s failed (%s)\n", fname, cli_errstr(cli->tree));
693 cnum1 = cli->tree->tid;
694 vuid1 = cli->session->vuid;
696 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
697 if (cli_write(cli->tree, fnum1, 0, buf, 130, 4) != 4) {
698 printf("initial write failed (%s)\n", cli_errstr(cli->tree));
702 tree1 = cli->tree; /* save old tree connection */
703 if (NT_STATUS_IS_ERR(cli_send_tconX(cli, share, "?????", password))) {
704 printf("%s refused 2nd tree connect (%s)\n", host,
705 cli_errstr(cli->tree));
710 cnum2 = cli->tree->tid;
711 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
712 vuid2 = cli->session->vuid + 1;
714 /* try a write with the wrong tid */
715 cli->tree->tid = cnum2;
717 if (cli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
718 printf("* server allows write with wrong TID\n");
721 printf("server fails write with wrong TID : %s\n", cli_errstr(cli->tree));
725 /* try a write with an invalid tid */
726 cli->tree->tid = cnum3;
728 if (cli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
729 printf("* server allows write with invalid TID\n");
732 printf("server fails write with invalid TID : %s\n", cli_errstr(cli->tree));
735 /* try a write with an invalid vuid */
736 cli->session->vuid = vuid2;
737 cli->tree->tid = cnum1;
739 if (cli_write(cli->tree, fnum1, 0, buf, 130, 4) == 4) {
740 printf("* server allows write with invalid VUID\n");
743 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli->tree));
746 cli->session->vuid = vuid1;
747 cli->tree->tid = cnum1;
749 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum1))) {
750 printf("close failed (%s)\n", cli_errstr(cli->tree));
754 cli->tree->tid = cnum2;
756 if (NT_STATUS_IS_ERR(cli_tdis(cli))) {
757 printf("secondary tdis failed (%s)\n", cli_errstr(cli->tree));
761 cli->tree = tree1; /* restore initial tree */
762 cli->tree->tid = cnum1;
764 if (!torture_close_connection(cli)) {
773 static BOOL tcon_devtest(struct cli_state *cli,
774 const char *myshare, const char *devtype,
775 NTSTATUS expected_error)
779 char *password = lp_parm_string(-1, "torture", "password");
781 status = NT_STATUS_IS_OK(cli_send_tconX(cli, myshare, devtype,
784 printf("Trying share %s with devtype %s\n", myshare, devtype);
786 if (NT_STATUS_IS_OK(expected_error)) {
790 printf("tconX to share %s with type %s "
791 "should have succeeded but failed\n",
798 printf("tconx to share %s with type %s "
799 "should have failed but succeeded\n",
803 if (NT_STATUS_EQUAL(cli_nt_error(cli->tree),
807 printf("Returned unexpected error\n");
816 checks for correct tconX support
818 static BOOL run_tcon_devtype_test(int dummy)
820 struct cli_state *cli1 = NULL;
825 char *host = lp_parm_string(-1, "torture", "host");
826 char *share = lp_parm_string(-1, "torture", "share");
827 char *username = lp_parm_string(-1, "torture", "username");
828 char *password = lp_parm_string(-1, "torture", "password");
830 status = cli_full_connection(&cli1, lp_netbios_name(),
833 username, lp_workgroup(),
834 password, flags, &retry);
836 if (!NT_STATUS_IS_OK(status)) {
837 printf("could not open connection\n");
841 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
844 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
847 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
850 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
853 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
856 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
859 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
862 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
865 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
868 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
874 printf("Passed tcondevtest\n");
881 This test checks that
883 1) the server supports multiple locking contexts on the one SMB
884 connection, distinguished by PID.
886 2) the server correctly fails overlapping locks made by the same PID (this
887 goes against POSIX behaviour, which is why it is tricky to implement)
889 3) the server denies unlock requests by an incorrect client PID
891 static BOOL run_locktest2(int dummy)
893 struct cli_state *cli;
894 const char *fname = "\\lockt2.lck";
895 int fnum1, fnum2, fnum3;
898 if (!torture_open_connection(&cli)) {
902 printf("starting locktest2\n");
904 cli_unlink(cli->tree, fname);
906 printf("Testing pid context\n");
908 cli->session->pid = 1;
910 fnum1 = cli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
912 printf("open of %s failed (%s)\n", fname, cli_errstr(cli->tree));
916 fnum2 = cli_open(cli->tree, fname, O_RDWR, DENY_NONE);
918 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli->tree));
922 cli->session->pid = 2;
924 fnum3 = cli_open(cli->tree, fname, O_RDWR, DENY_NONE);
926 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli->tree));
930 cli->session->pid = 1;
932 if (NT_STATUS_IS_ERR(cli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
933 printf("lock1 failed (%s)\n", cli_errstr(cli->tree));
937 if (NT_STATUS_IS_OK(cli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
938 printf("WRITE lock1 succeeded! This is a locking bug\n");
941 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
942 NT_STATUS_LOCK_NOT_GRANTED)) return False;
945 if (NT_STATUS_IS_OK(cli_lock(cli->tree, fnum2, 0, 4, 0, WRITE_LOCK))) {
946 printf("WRITE lock2 succeeded! This is a locking bug\n");
949 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
950 NT_STATUS_LOCK_NOT_GRANTED)) return False;
953 if (NT_STATUS_IS_OK(cli_lock(cli->tree, fnum2, 0, 4, 0, READ_LOCK))) {
954 printf("READ lock2 succeeded! This is a locking bug\n");
957 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
958 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
961 if (NT_STATUS_IS_ERR(cli_lock(cli->tree, fnum1, 100, 4, 0, WRITE_LOCK))) {
962 printf("lock at 100 failed (%s)\n", cli_errstr(cli->tree));
965 cli->session->pid = 2;
967 if (NT_STATUS_IS_OK(cli_unlock(cli->tree, fnum1, 100, 4))) {
968 printf("unlock at 100 succeeded! This is a locking bug\n");
972 if (NT_STATUS_IS_OK(cli_unlock(cli->tree, fnum1, 0, 4))) {
973 printf("unlock1 succeeded! This is a locking bug\n");
976 if (!check_error(__LINE__, cli,
978 NT_STATUS_RANGE_NOT_LOCKED)) return False;
981 if (NT_STATUS_IS_OK(cli_unlock(cli->tree, fnum1, 0, 8))) {
982 printf("unlock2 succeeded! This is a locking bug\n");
985 if (!check_error(__LINE__, cli,
987 NT_STATUS_RANGE_NOT_LOCKED)) return False;
990 if (NT_STATUS_IS_OK(cli_lock(cli->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
991 printf("lock3 succeeded! This is a locking bug\n");
994 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
997 cli->session->pid = 1;
999 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum1))) {
1000 printf("close1 failed (%s)\n", cli_errstr(cli->tree));
1004 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum2))) {
1005 printf("close2 failed (%s)\n", cli_errstr(cli->tree));
1009 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum3))) {
1010 printf("close3 failed (%s)\n", cli_errstr(cli->tree));
1014 if (!torture_close_connection(cli)) {
1018 printf("locktest2 finished\n");
1025 This test checks that
1027 1) the server supports the full offset range in lock requests
1029 static BOOL run_locktest3(int dummy)
1031 struct cli_state *cli1, *cli2;
1032 const char *fname = "\\lockt3.lck";
1033 int fnum1, fnum2, i;
1035 BOOL correct = True;
1037 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1039 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1043 printf("starting locktest3\n");
1045 printf("Testing 32 bit offset ranges\n");
1047 cli_unlink(cli1->tree, fname);
1049 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1051 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
1054 fnum2 = cli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1056 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
1060 printf("Establishing %d locks\n", torture_numops);
1062 for (offset=i=0;i<torture_numops;i++) {
1064 if (NT_STATUS_IS_ERR(cli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
1065 printf("lock1 %d failed (%s)\n",
1067 cli_errstr(cli1->tree));
1071 if (NT_STATUS_IS_ERR(cli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
1072 printf("lock2 %d failed (%s)\n",
1074 cli_errstr(cli1->tree));
1079 printf("Testing %d locks\n", torture_numops);
1081 for (offset=i=0;i<torture_numops;i++) {
1084 if (NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, offset-2, 1, 0, WRITE_LOCK))) {
1085 printf("error: lock1 %d succeeded!\n", i);
1089 if (NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum2, offset-1, 1, 0, WRITE_LOCK))) {
1090 printf("error: lock2 %d succeeded!\n", i);
1094 if (NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
1095 printf("error: lock3 %d succeeded!\n", i);
1099 if (NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
1100 printf("error: lock4 %d succeeded!\n", i);
1105 printf("Removing %d locks\n", torture_numops);
1107 for (offset=i=0;i<torture_numops;i++) {
1110 if (NT_STATUS_IS_ERR(cli_unlock(cli1->tree, fnum1, offset-1, 1))) {
1111 printf("unlock1 %d failed (%s)\n",
1113 cli_errstr(cli1->tree));
1117 if (NT_STATUS_IS_ERR(cli_unlock(cli2->tree, fnum2, offset-2, 1))) {
1118 printf("unlock2 %d failed (%s)\n",
1120 cli_errstr(cli1->tree));
1125 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
1126 printf("close1 failed (%s)\n", cli_errstr(cli1->tree));
1130 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
1131 printf("close2 failed (%s)\n", cli_errstr(cli2->tree));
1135 if (NT_STATUS_IS_ERR(cli_unlink(cli1->tree, fname))) {
1136 printf("unlink failed (%s)\n", cli_errstr(cli1->tree));
1140 if (!torture_close_connection(cli1)) {
1144 if (!torture_close_connection(cli2)) {
1148 printf("finished locktest3\n");
1153 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1154 printf("** "); correct = False; \
1158 looks at overlapping locks
1160 static BOOL run_locktest4(int dummy)
1162 struct cli_state *cli1, *cli2;
1163 const char *fname = "\\lockt4.lck";
1164 int fnum1, fnum2, f;
1167 BOOL correct = True;
1169 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1173 printf("starting locktest4\n");
1175 cli_unlink(cli1->tree, fname);
1177 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1178 fnum2 = cli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1180 memset(buf, 0, sizeof(buf));
1182 if (cli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1183 printf("Failed to create file\n");
1188 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1189 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 2, 4, 0, WRITE_LOCK));
1190 EXPECTED(ret, False);
1191 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1193 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 10, 4, 0, READ_LOCK)) &&
1194 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 12, 4, 0, READ_LOCK));
1195 EXPECTED(ret, True);
1196 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1198 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1199 NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum2, 22, 4, 0, WRITE_LOCK));
1200 EXPECTED(ret, False);
1201 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1203 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 30, 4, 0, READ_LOCK)) &&
1204 NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum2, 32, 4, 0, READ_LOCK));
1205 EXPECTED(ret, True);
1206 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1208 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, cli_lock(cli1->tree, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1209 NT_STATUS_IS_OK((cli1->session->pid = 2, cli_lock(cli1->tree, fnum1, 42, 4, 0, WRITE_LOCK)));
1210 EXPECTED(ret, False);
1211 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1213 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, cli_lock(cli1->tree, fnum1, 50, 4, 0, READ_LOCK))) &&
1214 NT_STATUS_IS_OK((cli1->session->pid = 2, cli_lock(cli1->tree, fnum1, 52, 4, 0, READ_LOCK)));
1215 EXPECTED(ret, True);
1216 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1218 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK)) &&
1219 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK));
1220 EXPECTED(ret, True);
1221 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1223 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1224 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK));
1225 EXPECTED(ret, False);
1226 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1228 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 80, 4, 0, READ_LOCK)) &&
1229 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 80, 4, 0, WRITE_LOCK));
1230 EXPECTED(ret, False);
1231 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1233 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 90, 4, 0, WRITE_LOCK)) &&
1234 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 90, 4, 0, READ_LOCK));
1235 EXPECTED(ret, True);
1236 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1238 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, cli_lock(cli1->tree, fnum1, 100, 4, 0, WRITE_LOCK))) &&
1239 NT_STATUS_IS_OK((cli1->session->pid = 2, cli_lock(cli1->tree, fnum1, 100, 4, 0, READ_LOCK)));
1240 EXPECTED(ret, False);
1241 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1243 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 110, 4, 0, READ_LOCK)) &&
1244 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 112, 4, 0, READ_LOCK)) &&
1245 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 110, 6));
1246 EXPECTED(ret, False);
1247 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1250 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 120, 4, 0, WRITE_LOCK)) &&
1251 (cli_read(cli2->tree, fnum2, buf, 120, 4) == 4);
1252 EXPECTED(ret, False);
1253 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1255 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK)) &&
1256 (cli_write(cli2->tree, fnum2, 0, buf, 130, 4) == 4);
1257 EXPECTED(ret, False);
1258 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1261 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
1262 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
1263 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 140, 4)) &&
1264 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 140, 4));
1265 EXPECTED(ret, True);
1266 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1269 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 150, 4, 0, WRITE_LOCK)) &&
1270 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 150, 4, 0, READ_LOCK)) &&
1271 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 150, 4)) &&
1272 (cli_read(cli2->tree, fnum2, buf, 150, 4) == 4) &&
1273 !(cli_write(cli2->tree, fnum2, 0, buf, 150, 4) == 4) &&
1274 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 150, 4));
1275 EXPECTED(ret, True);
1276 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1278 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 160, 4, 0, READ_LOCK)) &&
1279 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 160, 4)) &&
1280 (cli_write(cli2->tree, fnum2, 0, buf, 160, 4) == 4) &&
1281 (cli_read(cli2->tree, fnum2, buf, 160, 4) == 4);
1282 EXPECTED(ret, True);
1283 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1285 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 170, 4, 0, WRITE_LOCK)) &&
1286 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 170, 4)) &&
1287 (cli_write(cli2->tree, fnum2, 0, buf, 170, 4) == 4) &&
1288 (cli_read(cli2->tree, fnum2, buf, 170, 4) == 4);
1289 EXPECTED(ret, True);
1290 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1292 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 190, 4, 0, WRITE_LOCK)) &&
1293 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 190, 4, 0, READ_LOCK)) &&
1294 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 190, 4)) &&
1295 !(cli_write(cli2->tree, fnum2, 0, buf, 190, 4) == 4) &&
1296 (cli_read(cli2->tree, fnum2, buf, 190, 4) == 4);
1297 EXPECTED(ret, True);
1298 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1300 cli_close(cli1->tree, fnum1);
1301 cli_close(cli2->tree, fnum2);
1302 fnum1 = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1303 f = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1304 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
1305 NT_STATUS_IS_OK(cli_lock(cli1->tree, f, 0, 1, 0, READ_LOCK)) &&
1306 NT_STATUS_IS_OK(cli_close(cli1->tree, fnum1)) &&
1307 ((fnum1 = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE)) != -1) &&
1308 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
1309 cli_close(cli1->tree, f);
1310 cli_close(cli1->tree, fnum1);
1311 EXPECTED(ret, True);
1312 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1315 cli_close(cli1->tree, fnum1);
1316 cli_close(cli2->tree, fnum2);
1317 cli_unlink(cli1->tree, fname);
1318 torture_close_connection(cli1);
1319 torture_close_connection(cli2);
1321 printf("finished locktest4\n");
1326 looks at lock upgrade/downgrade.
1328 static BOOL run_locktest5(int dummy)
1330 struct cli_state *cli1, *cli2;
1331 const char *fname = "\\lockt5.lck";
1332 int fnum1, fnum2, fnum3;
1335 BOOL correct = True;
1337 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1341 printf("starting locktest5\n");
1343 cli_unlink(cli1->tree, fname);
1345 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1346 fnum2 = cli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1347 fnum3 = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1349 memset(buf, 0, sizeof(buf));
1351 if (cli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1352 printf("Failed to create file\n");
1357 /* Check for NT bug... */
1358 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
1359 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum3, 0, 1, 0, READ_LOCK));
1360 cli_close(cli1->tree, fnum1);
1361 fnum1 = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1362 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
1363 EXPECTED(ret, True);
1364 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1365 cli_close(cli1->tree, fnum1);
1366 fnum1 = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1367 cli_unlock(cli1->tree, fnum3, 0, 1);
1369 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1370 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 1, 1, 0, READ_LOCK));
1371 EXPECTED(ret, True);
1372 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1374 ret = NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
1375 EXPECTED(ret, False);
1377 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1379 /* Unlock the process 2 lock. */
1380 cli_unlock(cli2->tree, fnum2, 0, 4);
1382 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum3, 0, 4, 0, READ_LOCK));
1383 EXPECTED(ret, False);
1385 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1387 /* Unlock the process 1 fnum3 lock. */
1388 cli_unlock(cli1->tree, fnum3, 0, 4);
1390 /* Stack 2 more locks here. */
1391 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK)) &&
1392 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK));
1394 EXPECTED(ret, True);
1395 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1397 /* Unlock the first process lock, then check this was the WRITE lock that was
1400 ret = NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 0, 4)) &&
1401 NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
1403 EXPECTED(ret, True);
1404 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1406 /* Unlock the process 2 lock. */
1407 cli_unlock(cli2->tree, fnum2, 0, 4);
1409 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1411 ret = NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 1, 1)) &&
1412 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 0, 4)) &&
1413 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 0, 4));
1415 EXPECTED(ret, True);
1416 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1418 /* Ensure the next unlock fails. */
1419 ret = NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 0, 4));
1420 EXPECTED(ret, False);
1421 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1423 /* Ensure connection 2 can get a write lock. */
1424 ret = NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum2, 0, 4, 0, WRITE_LOCK));
1425 EXPECTED(ret, True);
1427 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1431 cli_close(cli1->tree, fnum1);
1432 cli_close(cli2->tree, fnum2);
1433 cli_unlink(cli1->tree, fname);
1434 if (!torture_close_connection(cli1)) {
1437 if (!torture_close_connection(cli2)) {
1441 printf("finished locktest5\n");
1447 tries the unusual lockingX locktype bits
1449 static BOOL run_locktest6(int dummy)
1451 struct cli_state *cli;
1452 const char *fname[1] = { "\\lock6.txt" };
1457 if (!torture_open_connection(&cli)) {
1461 printf("starting locktest6\n");
1464 printf("Testing %s\n", fname[i]);
1466 cli_unlink(cli->tree, fname[i]);
1468 fnum = cli_open(cli->tree, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1469 status = cli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1470 cli_close(cli->tree, fnum);
1471 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1473 fnum = cli_open(cli->tree, fname[i], O_RDWR, DENY_NONE);
1474 status = cli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1475 cli_close(cli->tree, fnum);
1476 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1478 cli_unlink(cli->tree, fname[i]);
1481 torture_close_connection(cli);
1483 printf("finished locktest6\n");
1487 static BOOL run_locktest7(int dummy)
1489 struct cli_state *cli1;
1490 const char *fname = "\\lockt7.lck";
1495 BOOL correct = False;
1497 if (!torture_open_connection(&cli1)) {
1501 printf("starting locktest7\n");
1503 cli_unlink(cli1->tree, fname);
1505 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1507 memset(buf, 0, sizeof(buf));
1509 if (cli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1510 printf("Failed to create file\n");
1514 cli1->session->pid = 1;
1516 if (NT_STATUS_IS_ERR(cli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK))) {
1517 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1->tree));
1520 printf("pid1 successfully locked range 130:4 for READ\n");
1523 if (cli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1524 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1->tree));
1527 printf("pid1 successfully read the range 130:4\n");
1530 if (cli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1531 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1->tree));
1532 if (NT_STATUS_V(cli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1533 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1537 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1541 cli1->session->pid = 2;
1543 if (cli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1544 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1->tree));
1546 printf("pid2 successfully read the range 130:4\n");
1549 if (cli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1550 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1->tree));
1551 if (NT_STATUS_V(cli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1552 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1556 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1560 cli1->session->pid = 1;
1561 cli_unlock(cli1->tree, fnum1, 130, 4);
1563 if (NT_STATUS_IS_ERR(cli_lock(cli1->tree, fnum1, 130, 4, 0, WRITE_LOCK))) {
1564 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1->tree));
1567 printf("pid1 successfully locked range 130:4 for WRITE\n");
1570 if (cli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1571 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1->tree));
1574 printf("pid1 successfully read the range 130:4\n");
1577 if (cli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1578 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1->tree));
1581 printf("pid1 successfully wrote to the range 130:4\n");
1584 cli1->session->pid = 2;
1586 if (cli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1587 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1->tree));
1588 if (NT_STATUS_V(cli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1589 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1593 printf("pid2 successfully read the range 130:4 (should be denied)\n");
1597 if (cli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1598 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1->tree));
1599 if (NT_STATUS_V(cli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1600 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1604 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1608 printf("Testing truncate of locked file.\n");
1610 fnum2 = cli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1613 printf("Unable to truncate locked file.\n");
1617 printf("Truncated locked file.\n");
1620 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &size, NULL))) {
1621 printf("getatr failed (%s)\n", cli_errstr(cli1->tree));
1627 printf("Unable to truncate locked file. Size was %u\n", size);
1632 cli1->session->pid = 1;
1634 cli_unlock(cli1->tree, fnum1, 130, 4);
1638 cli_close(cli1->tree, fnum1);
1639 cli_close(cli1->tree, fnum2);
1640 cli_unlink(cli1->tree, fname);
1641 torture_close_connection(cli1);
1643 printf("finished locktest7\n");
1648 test whether fnums and tids open on one VC are available on another (a major
1651 static BOOL run_fdpasstest(int dummy)
1653 struct cli_state *cli1, *cli2;
1654 const char *fname = "\\fdpass.tst";
1658 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1662 printf("starting fdpasstest\n");
1664 cli_unlink(cli1->tree, fname);
1666 printf("Opening a file on connection 1\n");
1668 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1670 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
1674 printf("writing to file on connection 1\n");
1676 if (cli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
1677 printf("write failed (%s)\n", cli_errstr(cli1->tree));
1681 oldtid = cli2->tree->tid;
1682 cli2->session->vuid = cli1->session->vuid;
1683 cli2->tree->tid = cli1->tree->tid;
1684 cli2->session->pid = cli1->session->pid;
1686 printf("reading from file on connection 2\n");
1688 if (cli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
1689 printf("read succeeded! nasty security hole [%s]\n",
1694 cli_close(cli1->tree, fnum1);
1695 cli_unlink(cli1->tree, fname);
1697 cli2->tree->tid = oldtid;
1699 torture_close_connection(cli1);
1700 torture_close_connection(cli2);
1702 printf("finished fdpasstest\n");
1708 This test checks that
1710 1) the server does not allow an unlink on a file that is open
1712 static BOOL run_unlinktest(int dummy)
1714 struct cli_state *cli;
1715 const char *fname = "\\unlink.tst";
1717 BOOL correct = True;
1719 if (!torture_open_connection(&cli)) {
1723 printf("starting unlink test\n");
1725 cli_unlink(cli->tree, fname);
1727 cli->session->pid = 1;
1729 printf("Opening a file\n");
1731 fnum = cli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1733 printf("open of %s failed (%s)\n", fname, cli_errstr(cli->tree));
1737 printf("Unlinking a open file\n");
1739 if (NT_STATUS_IS_OK(cli_unlink(cli->tree, fname))) {
1740 printf("error: server allowed unlink on an open file\n");
1743 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
1744 NT_STATUS_SHARING_VIOLATION);
1747 cli_close(cli->tree, fnum);
1748 cli_unlink(cli->tree, fname);
1750 if (!torture_close_connection(cli)) {
1754 printf("unlink test finished\n");
1761 test how many open files this server supports on the one socket
1764 static BOOL run_deferopen(struct cli_state *cli, int dummy)
1766 char *fname = "\\defer_open_test.dat";
1769 BOOL correct = True;
1772 printf("failed to connect\n");
1776 printf("Testing deferred open requests.\n");
1781 fnum = cli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
1782 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
1783 NTCREATEX_DISP_OPEN_IF, 0, 0);
1787 } while (NT_STATUS_EQUAL(cli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
1790 fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli->tree));
1794 printf("pid %u open %d\n", getpid(), i);
1798 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum))) {
1799 fprintf(stderr,"Failed to close %s, error=%s\n", fname, cli_errstr(cli->tree));
1805 if (NT_STATUS_IS_ERR(cli_unlink(cli->tree, fname))) {
1806 /* All until the last unlink will fail with sharing violation. */
1807 if (!NT_STATUS_EQUAL(cli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
1808 printf("unlink of %s failed (%s)\n", fname, cli_errstr(cli->tree));
1813 printf("deferred test finished\n");
1814 if (!torture_close_connection(cli)) {
1821 test how many open files this server supports on the one socket
1823 static BOOL run_maxfidtest(struct cli_state *cli, int dummy)
1825 const char *template = "\\maxfid.%d.%d";
1827 int fnums[0x11000], i;
1829 BOOL correct = True;
1832 printf("failed to connect\n");
1836 printf("Testing maximum number of open files\n");
1838 for (i=0; i<0x11000; i++) {
1839 asprintf(&fname, template, i,(int)getpid());
1840 if ((fnums[i] = cli_open(cli->tree, fname,
1841 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1843 printf("open of %s failed (%s)\n",
1844 fname, cli_errstr(cli->tree));
1845 printf("maximum fnum is %d\n", i);
1854 printf("cleaning up\n");
1856 asprintf(&fname, template, i,(int)getpid());
1857 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnums[i]))) {
1858 printf("Close of fnum %d failed - %s\n", fnums[i], cli_errstr(cli->tree));
1860 if (NT_STATUS_IS_ERR(cli_unlink(cli->tree, fname))) {
1861 printf("unlink of %s failed (%s)\n",
1862 fname, cli_errstr(cli->tree));
1870 printf("maxfid test finished\n");
1871 if (!torture_close_connection(cli)) {
1877 /* send smb negprot commands, not reading the response */
1878 static BOOL run_negprot_nowait(int dummy)
1881 struct cli_state *cli;
1882 BOOL correct = True;
1884 printf("starting negprot nowait test\n");
1886 cli = open_nbt_connection();
1891 printf("Establishing protocol negotiations - connect with another client\n");
1893 for (i=0;i<50000;i++) {
1894 smb_negprot_send(cli->transport, PROTOCOL_NT1);
1897 if (!torture_close_connection(cli)) {
1901 printf("finished negprot nowait test\n");
1908 This checks how the getatr calls works
1910 static BOOL run_attrtest(int dummy)
1912 struct cli_state *cli;
1915 const char *fname = "\\attrib123456789.tst";
1916 BOOL correct = True;
1918 printf("starting attrib test\n");
1920 if (!torture_open_connection(&cli)) {
1924 cli_unlink(cli->tree, fname);
1925 fnum = cli_open(cli->tree, fname,
1926 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1927 cli_close(cli->tree, fnum);
1929 if (NT_STATUS_IS_ERR(cli_getatr(cli->tree, fname, NULL, NULL, &t))) {
1930 printf("getatr failed (%s)\n", cli_errstr(cli->tree));
1934 printf("New file time is %s", ctime(&t));
1936 if (abs(t - time(NULL)) > 60*60*24*10) {
1937 printf("ERROR: SMBgetatr bug. time is %s",
1943 t2 = t-60*60*24; /* 1 day ago */
1945 printf("Setting file time to %s", ctime(&t2));
1947 if (NT_STATUS_IS_ERR(cli_setatr(cli->tree, fname, 0, t2))) {
1948 printf("setatr failed (%s)\n", cli_errstr(cli->tree));
1952 if (NT_STATUS_IS_ERR(cli_getatr(cli->tree, fname, NULL, NULL, &t))) {
1953 printf("getatr failed (%s)\n", cli_errstr(cli->tree));
1957 printf("Retrieved file time as %s", ctime(&t));
1960 printf("ERROR: getatr/setatr bug. times are\n%s",
1962 printf("%s", ctime(&t2));
1966 cli_unlink(cli->tree, fname);
1968 if (!torture_close_connection(cli)) {
1972 printf("attrib test finished\n");
1979 This checks a couple of trans2 calls
1981 static BOOL run_trans2test(int dummy)
1983 struct cli_state *cli;
1986 time_t c_time, a_time, m_time, w_time, m_time2;
1987 const char *fname = "\\trans2.tst";
1988 const char *dname = "\\trans2";
1989 const char *fname2 = "\\trans2\\trans2.tst";
1991 BOOL correct = True;
1993 printf("starting trans2 test\n");
1995 if (!torture_open_connection(&cli)) {
1999 cli_unlink(cli->tree, fname);
2001 printf("Testing qfileinfo\n");
2003 fnum = cli_open(cli->tree, fname,
2004 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2005 if (NT_STATUS_IS_ERR(cli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
2007 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli->tree));
2011 printf("Testing NAME_INFO\n");
2013 if (NT_STATUS_IS_ERR(cli_qfilename(cli->tree, fnum, &pname))) {
2014 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli->tree));
2018 if (!pname || strcmp(pname, fname)) {
2019 printf("qfilename gave different name? [%s] [%s]\n",
2024 cli_close(cli->tree, fnum);
2025 cli_unlink(cli->tree, fname);
2027 fnum = cli_open(cli->tree, fname,
2028 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2030 printf("open of %s failed (%s)\n", fname, cli_errstr(cli->tree));
2033 cli_close(cli->tree, fnum);
2035 printf("Checking for sticky create times\n");
2037 if (NT_STATUS_IS_ERR(cli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
2038 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli->tree));
2041 if (c_time != m_time) {
2042 printf("create time=%s", ctime(&c_time));
2043 printf("modify time=%s", ctime(&m_time));
2044 printf("This system appears to have sticky create times\n");
2046 if (a_time % (60*60) == 0) {
2047 printf("access time=%s", ctime(&a_time));
2048 printf("This system appears to set a midnight access time\n");
2052 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2053 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2059 cli_unlink(cli->tree, fname);
2060 fnum = cli_open(cli->tree, fname,
2061 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2062 cli_close(cli->tree, fnum);
2063 if (NT_STATUS_IS_ERR(cli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2064 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli->tree));
2067 if (w_time < 60*60*24*2) {
2068 printf("write time=%s", ctime(&w_time));
2069 printf("This system appears to set a initial 0 write time\n");
2074 cli_unlink(cli->tree, fname);
2077 /* check if the server updates the directory modification time
2078 when creating a new file */
2079 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, dname))) {
2080 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli->tree));
2084 if (NT_STATUS_IS_ERR(cli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2085 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli->tree));
2089 fnum = cli_open(cli->tree, fname2,
2090 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2091 cli_write(cli->tree, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2092 cli_close(cli->tree, fnum);
2093 if (NT_STATUS_IS_ERR(cli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
2094 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli->tree));
2097 if (m_time2 == m_time) {
2098 printf("This system does not update directory modification times\n");
2102 cli_unlink(cli->tree, fname2);
2103 cli_rmdir(cli->tree, dname);
2105 if (!torture_close_connection(cli)) {
2109 printf("trans2 test finished\n");
2115 Test delete on close semantics.
2117 static BOOL run_deletetest(int dummy)
2119 struct cli_state *cli1;
2120 struct cli_state *cli2 = NULL;
2121 const char *fname = "\\delete.file";
2124 BOOL correct = True;
2126 printf("starting delete test\n");
2128 if (!torture_open_connection(&cli1)) {
2132 /* Test 1 - this should delete the file on close. */
2134 cli_setatr(cli1->tree, fname, 0, 0);
2135 cli_unlink(cli1->tree, fname);
2137 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2138 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF,
2139 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2142 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2147 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2148 printf("[1] close failed (%s)\n", cli_errstr(cli1->tree));
2153 fnum1 = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
2155 printf("[1] open of %s succeeded (should fail)\n", fname);
2160 printf("first delete on close test succeeded.\n");
2162 /* Test 2 - this should delete the file on close. */
2164 cli_setatr(cli1->tree, fname, 0, 0);
2165 cli_unlink(cli1->tree, fname);
2167 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
2168 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
2169 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2172 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2177 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2178 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1->tree));
2183 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2184 printf("[2] close failed (%s)\n", cli_errstr(cli1->tree));
2189 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2191 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2192 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2193 printf("[2] close failed (%s)\n", cli_errstr(cli1->tree));
2197 cli_unlink(cli1->tree, fname);
2199 printf("second delete on close test succeeded.\n");
2202 cli_setatr(cli1->tree, fname, 0, 0);
2203 cli_unlink(cli1->tree, fname);
2205 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2206 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2209 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2214 /* This should fail with a sharing violation - open for delete is only compatible
2215 with SHARE_DELETE. */
2217 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2218 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2219 NTCREATEX_DISP_OPEN, 0, 0);
2222 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2227 /* This should succeed. */
2229 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2230 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN, 0, 0);
2233 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2238 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2239 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1->tree));
2244 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2245 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1->tree));
2250 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum2))) {
2251 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1->tree));
2256 /* This should fail - file should no longer be there. */
2258 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2260 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2261 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2262 printf("[3] close failed (%s)\n", cli_errstr(cli1->tree));
2264 cli_unlink(cli1->tree, fname);
2268 printf("third delete on close test succeeded.\n");
2271 cli_setatr(cli1->tree, fname, 0, 0);
2272 cli_unlink(cli1->tree, fname);
2274 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
2275 SA_RIGHT_FILE_READ_DATA |
2276 SA_RIGHT_FILE_WRITE_DATA |
2277 STD_RIGHT_DELETE_ACCESS,
2278 FILE_ATTRIBUTE_NORMAL,
2279 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2280 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2283 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2288 /* This should succeed. */
2289 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2290 FILE_ATTRIBUTE_NORMAL,
2291 NTCREATEX_SHARE_ACCESS_READ |
2292 NTCREATEX_SHARE_ACCESS_WRITE |
2293 NTCREATEX_SHARE_ACCESS_DELETE,
2294 NTCREATEX_DISP_OPEN, 0, 0);
2296 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2301 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum2))) {
2302 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1->tree));
2307 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2308 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1->tree));
2313 /* This should fail - no more opens once delete on close set. */
2314 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2315 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2316 NTCREATEX_DISP_OPEN, 0, 0);
2318 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2322 printf("fourth delete on close test succeeded.\n");
2324 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2325 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2331 cli_setatr(cli1->tree, fname, 0, 0);
2332 cli_unlink(cli1->tree, fname);
2334 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
2336 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2341 /* This should fail - only allowed on NT opens with DELETE access. */
2343 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2344 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2349 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2350 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2355 printf("fifth delete on close test succeeded.\n");
2358 cli_setatr(cli1->tree, fname, 0, 0);
2359 cli_unlink(cli1->tree, fname);
2361 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
2362 SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA,
2363 FILE_ATTRIBUTE_NORMAL,
2364 NTCREATEX_SHARE_ACCESS_READ |
2365 NTCREATEX_SHARE_ACCESS_WRITE |
2366 NTCREATEX_SHARE_ACCESS_DELETE,
2367 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2370 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2375 /* This should fail - only allowed on NT opens with DELETE access. */
2377 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2378 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2383 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2384 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2389 printf("sixth delete on close test succeeded.\n");
2392 cli_setatr(cli1->tree, fname, 0, 0);
2393 cli_unlink(cli1->tree, fname);
2395 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
2396 SA_RIGHT_FILE_READ_DATA |
2397 SA_RIGHT_FILE_WRITE_DATA |
2398 STD_RIGHT_DELETE_ACCESS,
2399 FILE_ATTRIBUTE_NORMAL, 0, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2402 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2407 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2408 printf("[7] setting delete_on_close on file failed !\n");
2413 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, False))) {
2414 printf("[7] unsetting delete_on_close on file failed !\n");
2419 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2420 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2425 /* This next open should succeed - we reset the flag. */
2427 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2429 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2434 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2435 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2440 printf("seventh delete on close test succeeded.\n");
2443 cli_setatr(cli1->tree, fname, 0, 0);
2444 cli_unlink(cli1->tree, fname);
2446 if (!torture_open_connection(&cli2)) {
2447 printf("[8] failed to open second connection.\n");
2452 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2453 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2454 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2457 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2462 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2463 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2464 NTCREATEX_DISP_OPEN, 0, 0);
2467 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2472 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2473 printf("[8] setting delete_on_close on file failed !\n");
2478 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2479 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1->tree));
2484 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
2485 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2->tree));
2490 /* This should fail.. */
2491 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2493 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2497 printf("eighth delete on close test succeeded.\n");
2499 /* This should fail - we need to set DELETE_ACCESS. */
2500 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
2501 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2504 printf("[9] open of %s succeeded should have failed!\n", fname);
2509 printf("ninth delete on close test succeeded.\n");
2511 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2512 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2514 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2519 /* This should delete the file. */
2520 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2521 printf("[10] close failed (%s)\n", cli_errstr(cli1->tree));
2526 /* This should fail.. */
2527 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2529 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2533 printf("tenth delete on close test succeeded.\n");
2534 printf("finished delete test\n");
2537 /* FIXME: This will crash if we aborted before cli2 got
2538 * intialized, because these functions don't handle
2539 * uninitialized connections. */
2541 cli_close(cli1->tree, fnum1);
2542 cli_close(cli1->tree, fnum2);
2543 cli_setatr(cli1->tree, fname, 0, 0);
2544 cli_unlink(cli1->tree, fname);
2546 if (!torture_close_connection(cli1)) {
2549 if (!torture_close_connection(cli2)) {
2557 print out server properties
2559 static BOOL run_properties(int dummy)
2561 struct cli_state *cli;
2562 BOOL correct = True;
2564 printf("starting properties test\n");
2568 if (!torture_open_connection(&cli)) {
2572 d_printf("Capabilities 0x%08x\n", cli->transport->negotiate.capabilities);
2574 if (!torture_close_connection(cli)) {
2583 /* FIRST_DESIRED_ACCESS 0xf019f */
2584 #define FIRST_DESIRED_ACCESS SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_APPEND_DATA|\
2585 SA_RIGHT_FILE_READ_EA| /* 0xf */ \
2586 SA_RIGHT_FILE_WRITE_EA|SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x90 */ \
2587 SA_RIGHT_FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
2588 STD_RIGHT_DELETE_ACCESS|STD_RIGHT_READ_CONTROL_ACCESS|\
2589 STD_RIGHT_WRITE_DAC_ACCESS|STD_RIGHT_WRITE_OWNER_ACCESS /* 0xf0000 */
2590 /* SECOND_DESIRED_ACCESS 0xe0080 */
2591 #define SECOND_DESIRED_ACCESS SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x80 */ \
2592 STD_RIGHT_READ_CONTROL_ACCESS|STD_RIGHT_WRITE_DAC_ACCESS|\
2593 STD_RIGHT_WRITE_OWNER_ACCESS /* 0xe0000 */
2596 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
2597 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2598 SA_RIGHT_FILE_READ_DATA|\
2599 WRITE_OWNER_ACCESS /* */
2603 Test ntcreate calls made by xcopy
2605 static BOOL run_xcopy(int dummy)
2607 struct cli_state *cli1;
2608 const char *fname = "\\test.txt";
2609 BOOL correct = True;
2612 printf("starting xcopy test\n");
2614 if (!torture_open_connection(&cli1)) {
2618 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
2619 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2620 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF,
2624 printf("First open failed - %s\n", cli_errstr(cli1->tree));
2628 fnum2 = cli_nt_create_full(cli1->tree, fname, 0,
2629 SECOND_DESIRED_ACCESS, 0,
2630 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
2633 printf("second open failed - %s\n", cli_errstr(cli1->tree));
2637 if (!torture_close_connection(cli1)) {
2645 Test rename on files open with share delete and no share delete.
2647 static BOOL run_rename(int dummy)
2649 struct cli_state *cli1;
2650 const char *fname = "\\test.txt";
2651 const char *fname1 = "\\test1.txt";
2652 BOOL correct = True;
2655 printf("starting rename test\n");
2657 if (!torture_open_connection(&cli1)) {
2661 cli_unlink(cli1->tree, fname);
2662 cli_unlink(cli1->tree, fname1);
2663 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2664 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2667 printf("First open failed - %s\n", cli_errstr(cli1->tree));
2671 if (NT_STATUS_IS_ERR(cli_rename(cli1->tree, fname, fname1))) {
2672 printf("First rename failed (this is correct) - %s\n", cli_errstr(cli1->tree));
2674 printf("First rename succeeded - this should have failed !\n");
2678 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2679 printf("close - 1 failed (%s)\n", cli_errstr(cli1->tree));
2683 cli_unlink(cli1->tree, fname);
2684 cli_unlink(cli1->tree, fname1);
2685 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2687 NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2689 NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2693 printf("Second open failed - %s\n", cli_errstr(cli1->tree));
2697 if (NT_STATUS_IS_ERR(cli_rename(cli1->tree, fname, fname1))) {
2698 printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(cli1->tree));
2701 printf("Second rename succeeded\n");
2704 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2705 printf("close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2709 cli_unlink(cli1->tree, fname);
2710 cli_unlink(cli1->tree, fname1);
2712 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2713 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2716 printf("Third open failed - %s\n", cli_errstr(cli1->tree));
2725 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2726 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2729 printf("Fourth open failed - %s\n", cli_errstr(cli1->tree));
2732 if (!cli_nt_delete_on_close(cli1->tree, fnum2, True)) {
2733 printf("[8] setting delete_on_close on file failed !\n");
2737 if (!cli_close(cli1->tree, fnum2)) {
2738 printf("close - 4 failed (%s)\n", cli_errstr(cli1->tree));
2744 if (NT_STATUS_IS_ERR(cli_rename(cli1->tree, fname, fname1))) {
2745 printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(cli1->tree));
2748 printf("Third rename succeeded\n");
2751 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2752 printf("close - 3 failed (%s)\n", cli_errstr(cli1->tree));
2756 cli_unlink(cli1->tree, fname);
2757 cli_unlink(cli1->tree, fname1);
2759 if (!torture_close_connection(cli1)) {
2766 static BOOL run_pipe_number(int dummy)
2768 struct cli_state *cli1;
2769 const char *pipe_name = "\\WKSSVC";
2773 printf("starting pipenumber test\n");
2774 if (!torture_open_connection(&cli1)) {
2779 fnum = cli_nt_create_full(cli1->tree, pipe_name, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
2780 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
2783 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1->tree));
2789 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
2790 torture_close_connection(cli1);
2798 open N connections to the server and just hold them open
2799 used for testing performance when there are N idle users
2802 static BOOL torture_holdcon(int dummy)
2805 struct cli_state **cli;
2808 printf("Opening %d connections\n", torture_numops);
2810 cli = malloc(sizeof(struct cli_state *) * torture_numops);
2812 for (i=0;i<torture_numops;i++) {
2813 if (!torture_open_connection(&cli[i])) {
2816 printf("opened %d connections\r", i);
2820 printf("\nStarting pings\n");
2823 for (i=0;i<torture_numops;i++) {
2826 status = cli_chkpath(cli[i]->tree, "\\");
2827 if (!NT_STATUS_IS_OK(status)) {
2828 printf("Connection %d is dead\n", i);
2836 if (num_dead == torture_numops) {
2837 printf("All connections dead - finishing\n");
2849 Try with a wrong vuid and check error message.
2852 static BOOL run_vuidtest(int dummy)
2854 struct cli_state *cli;
2855 const char *fname = "\\vuid.tst";
2858 time_t c_time, a_time, m_time;
2859 BOOL correct = True;
2864 printf("starting vuid test\n");
2866 if (!torture_open_connection(&cli)) {
2870 cli_unlink(cli->tree, fname);
2872 fnum = cli_open(cli->tree, fname,
2873 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2875 orig_vuid = cli->session->vuid;
2877 cli->session->vuid += 1234;
2879 printf("Testing qfileinfo with wrong vuid\n");
2881 if (NT_STATUS_IS_OK(result = cli_qfileinfo(cli->tree, fnum, NULL,
2882 &size, &c_time, &a_time,
2883 &m_time, NULL, NULL))) {
2884 printf("ERROR: qfileinfo passed with wrong vuid\n");
2888 if ( (cli->transport->error.etype != ETYPE_DOS) ||
2889 (cli->transport->error.e.dos.eclass != ERRSRV) ||
2890 (cli->transport->error.e.dos.ecode != ERRbaduid) ) {
2891 printf("ERROR: qfileinfo should have returned DOS error "
2892 "ERRSRV:ERRbaduid\n but returned %s\n",
2893 cli_errstr(cli->tree));
2897 cli->session->vuid -= 1234;
2899 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum))) {
2900 printf("close failed (%s)\n", cli_errstr(cli->tree));
2904 cli_unlink(cli->tree, fname);
2906 if (!torture_close_connection(cli)) {
2910 printf("vuid test finished\n");
2916 Test open mode returns on read-only files.
2918 static BOOL run_opentest(int dummy)
2920 static struct cli_state *cli1;
2921 static struct cli_state *cli2;
2922 const char *fname = "\\readonly.file";
2926 BOOL correct = True;
2930 printf("starting open test\n");
2932 if (!torture_open_connection(&cli1)) {
2936 cli_setatr(cli1->tree, fname, 0, 0);
2937 cli_unlink(cli1->tree, fname);
2939 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2941 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2945 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2946 printf("close2 failed (%s)\n", cli_errstr(cli1->tree));
2950 if (NT_STATUS_IS_ERR(cli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
2951 printf("cli_setatr failed (%s)\n", cli_errstr(cli1->tree));
2952 CHECK_MAX_FAILURES(error_test1);
2956 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
2958 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2959 CHECK_MAX_FAILURES(error_test1);
2963 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
2964 fnum2 = cli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
2966 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
2967 NT_STATUS_ACCESS_DENIED)) {
2968 printf("correct error code ERRDOS/ERRnoaccess returned\n");
2971 printf("finished open test 1\n");
2973 cli_close(cli1->tree, fnum1);
2975 /* Now try not readonly and ensure ERRbadshare is returned. */
2977 cli_setatr(cli1->tree, fname, 0, 0);
2979 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
2981 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2985 /* This will fail - but the error should be ERRshare. */
2986 fnum2 = cli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
2988 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
2989 NT_STATUS_SHARING_VIOLATION)) {
2990 printf("correct error code ERRDOS/ERRbadshare returned\n");
2993 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2994 printf("close2 failed (%s)\n", cli_errstr(cli1->tree));
2998 cli_unlink(cli1->tree, fname);
3000 printf("finished open test 2\n");
3002 /* Test truncate open disposition on file opened for read. */
3004 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3006 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3010 /* write 20 bytes. */
3012 memset(buf, '\0', 20);
3014 if (cli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
3015 printf("write failed (%s)\n", cli_errstr(cli1->tree));
3019 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3020 printf("(3) close1 failed (%s)\n", cli_errstr(cli1->tree));
3024 /* Ensure size == 20. */
3025 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3026 printf("(3) getatr failed (%s)\n", cli_errstr(cli1->tree));
3027 CHECK_MAX_FAILURES(error_test3);
3032 printf("(3) file size != 20\n");
3033 CHECK_MAX_FAILURES(error_test3);
3037 /* Now test if we can truncate a file opened for readonly. */
3039 fnum1 = cli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3041 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3042 CHECK_MAX_FAILURES(error_test3);
3046 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3047 printf("close2 failed (%s)\n", cli_errstr(cli1->tree));
3051 /* Ensure size == 0. */
3052 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3053 printf("(3) getatr failed (%s)\n", cli_errstr(cli1->tree));
3054 CHECK_MAX_FAILURES(error_test3);
3059 printf("(3) file size != 0\n");
3060 CHECK_MAX_FAILURES(error_test3);
3063 printf("finished open test 3\n");
3065 cli_unlink(cli1->tree, fname);
3068 printf("testing ctemp\n");
3069 fnum1 = cli_ctemp(cli1->tree, "\\", &tmp_path);
3071 printf("ctemp failed (%s)\n", cli_errstr(cli1->tree));
3072 CHECK_MAX_FAILURES(error_test4);
3075 printf("ctemp gave path %s\n", tmp_path);
3076 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3077 printf("close of temp failed (%s)\n", cli_errstr(cli1->tree));
3079 if (NT_STATUS_IS_ERR(cli_unlink(cli1->tree, tmp_path))) {
3080 printf("unlink of temp failed (%s)\n", cli_errstr(cli1->tree));
3083 /* Test the non-io opens... */
3085 if (!torture_open_connection(&cli2)) {
3089 cli_setatr(cli2->tree, fname, 0, 0);
3090 cli_unlink(cli2->tree, fname);
3092 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3094 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3095 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3098 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3099 CHECK_MAX_FAILURES(error_test10);
3103 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3104 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3106 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3107 CHECK_MAX_FAILURES(error_test10);
3111 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3112 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3115 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3116 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3120 printf("non-io open test #1 passed.\n");
3122 cli_unlink(cli1->tree, fname);
3124 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3126 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3127 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3130 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3131 CHECK_MAX_FAILURES(error_test20);
3135 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3136 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3139 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3140 CHECK_MAX_FAILURES(error_test20);
3144 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3145 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3148 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3149 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3153 printf("non-io open test #2 passed.\n");
3155 cli_unlink(cli1->tree, fname);
3157 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3159 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3160 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3163 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3164 CHECK_MAX_FAILURES(error_test30);
3168 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3169 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3172 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3173 CHECK_MAX_FAILURES(error_test30);
3177 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3178 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3181 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3182 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3186 printf("non-io open test #3 passed.\n");
3188 cli_unlink(cli1->tree, fname);
3190 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3192 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3193 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3196 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3197 CHECK_MAX_FAILURES(error_test40);
3201 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3202 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3205 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2->tree));
3206 CHECK_MAX_FAILURES(error_test40);
3210 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2->tree), "sharing violation");
3212 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3213 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3217 printf("non-io open test #4 passed.\n");
3219 cli_unlink(cli1->tree, fname);
3221 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3223 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3224 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3227 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3228 CHECK_MAX_FAILURES(error_test50);
3232 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3233 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3236 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3237 CHECK_MAX_FAILURES(error_test50);
3241 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3242 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3246 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3247 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3251 printf("non-io open test #5 passed.\n");
3253 printf("TEST #6 testing 1 non-io open, one io open\n");
3255 cli_unlink(cli1->tree, fname);
3257 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3258 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3261 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3262 CHECK_MAX_FAILURES(error_test60);
3266 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3267 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
3270 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3271 CHECK_MAX_FAILURES(error_test60);
3275 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3276 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3280 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3281 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3285 printf("non-io open test #6 passed.\n");
3287 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3289 cli_unlink(cli1->tree, fname);
3291 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3292 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3295 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3296 CHECK_MAX_FAILURES(error_test70);
3300 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3301 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3304 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2->tree));
3305 CHECK_MAX_FAILURES(error_test70);
3309 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2->tree), "sharing violation");
3311 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3312 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3316 printf("non-io open test #7 passed.\n");
3320 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
3322 cli_unlink(cli1->tree, fname);
3324 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3326 printf("(8) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3330 /* write 20 bytes. */
3332 memset(buf, '\0', 20);
3334 if (cli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
3335 printf("(8) write failed (%s)\n", cli_errstr(cli1->tree));
3339 /* Ensure size == 20. */
3340 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3341 printf("(8) getatr (1) failed (%s)\n", cli_errstr(cli1->tree));
3342 CHECK_MAX_FAILURES(error_test80);
3347 printf("(8) file size != 20\n");
3348 CHECK_MAX_FAILURES(error_test80);
3352 /* Get an exclusive lock on the open file. */
3353 if (NT_STATUS_IS_ERR(cli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
3354 printf("(8) lock1 failed (%s)\n", cli_errstr(cli1->tree));
3355 CHECK_MAX_FAILURES(error_test80);
3359 fnum2 = cli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
3361 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, cli_errstr(cli1->tree));
3365 /* Ensure size == 0. */
3366 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3367 printf("(8) getatr (2) failed (%s)\n", cli_errstr(cli1->tree));
3368 CHECK_MAX_FAILURES(error_test80);
3373 printf("(8) file size != 0\n");
3374 CHECK_MAX_FAILURES(error_test80);
3378 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3379 printf("(8) close1 failed (%s)\n", cli_errstr(cli1->tree));
3383 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum2))) {
3384 printf("(8) close1 failed (%s)\n", cli_errstr(cli1->tree));
3390 printf("open test #8 passed.\n");
3392 cli_unlink(cli1->tree, fname);
3394 if (!torture_close_connection(cli1)) {
3397 if (!torture_close_connection(cli2)) {
3405 static uint32_t open_attrs_table[] = {
3406 FILE_ATTRIBUTE_NORMAL,
3407 FILE_ATTRIBUTE_ARCHIVE,
3408 FILE_ATTRIBUTE_READONLY,
3409 FILE_ATTRIBUTE_HIDDEN,
3410 FILE_ATTRIBUTE_SYSTEM,
3412 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
3413 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
3414 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
3415 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3416 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3417 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3419 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3420 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3421 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3422 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
3425 struct trunc_open_results {
3428 uint32_t trunc_attr;
3429 uint32_t result_attr;
3432 static struct trunc_open_results attr_results[] = {
3433 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3434 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3435 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3436 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3437 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3438 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3439 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3440 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3441 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3442 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3443 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3444 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
3445 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3446 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3447 { 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 },
3448 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3449 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3450 { 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 },
3451 { 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 },
3452 { 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 },
3453 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3454 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3455 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3456 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3457 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3458 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
3461 static BOOL run_openattrtest(int dummy)
3463 struct cli_state *cli1;
3464 const char *fname = "\\openattr.file";
3466 BOOL correct = True;
3471 printf("starting open attr test\n");
3473 if (!torture_open_connection(&cli1)) {
3477 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
3478 cli_setatr(cli1->tree, fname, 0, 0);
3479 cli_unlink(cli1->tree, fname);
3480 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_WRITE_DATA, open_attrs_table[i],
3481 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3484 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1->tree));
3488 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3489 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1->tree));
3493 for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
3494 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
3495 SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
3496 open_attrs_table[j],
3497 NTCREATEX_SHARE_ACCESS_NONE,
3498 NTCREATEX_DISP_OVERWRITE, 0, 0);
3501 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3502 if (attr_results[l].num == k) {
3503 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
3504 k, open_attrs_table[i],
3505 open_attrs_table[j],
3506 fname, NT_STATUS_V(cli_nt_error(cli1->tree)), cli_errstr(cli1->tree));
3508 CHECK_MAX_FAILURES(error_exit);
3511 if (NT_STATUS_V(cli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
3512 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
3513 k, open_attrs_table[i], open_attrs_table[j],
3514 cli_errstr(cli1->tree));
3516 CHECK_MAX_FAILURES(error_exit);
3519 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
3525 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3526 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1->tree));
3530 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, &attr, NULL, NULL))) {
3531 printf("getatr(2) failed (%s)\n", cli_errstr(cli1->tree));
3536 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
3537 k, open_attrs_table[i], open_attrs_table[j], attr );
3540 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3541 if (attr_results[l].num == k) {
3542 if (attr != attr_results[l].result_attr ||
3543 open_attrs_table[i] != attr_results[l].init_attr ||
3544 open_attrs_table[j] != attr_results[l].trunc_attr) {
3545 printf("[%d] getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
3546 k, open_attrs_table[i],
3547 open_attrs_table[j],
3549 attr_results[l].result_attr);
3551 CHECK_MAX_FAILURES(error_exit);
3560 cli_setatr(cli1->tree, fname, 0, 0);
3561 cli_unlink(cli1->tree, fname);
3563 printf("open attr test %s.\n", correct ? "passed" : "failed");
3565 if (!torture_close_connection(cli1)) {
3571 static void list_fn(file_info *finfo, const char *name, void *state)
3577 test directory listing speed
3579 static BOOL run_dirtest(int dummy)
3582 struct cli_state *cli;
3585 BOOL correct = True;
3587 printf("starting directory test\n");
3589 if (!torture_open_connection(&cli)) {
3593 printf("Creating %d random filenames\n", torture_numops);
3596 for (i=0;i<torture_numops;i++) {
3598 asprintf(&fname, "\\%x", (int)random());
3599 fnum = cli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3601 fprintf(stderr,"Failed to open %s\n", fname);
3604 cli_close(cli->tree, fnum);
3610 printf("Matched %d\n", cli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3611 printf("Matched %d\n", cli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3612 printf("Matched %d\n", cli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3614 printf("dirtest core %g seconds\n", end_timer() - t1);
3617 for (i=0;i<torture_numops;i++) {
3619 asprintf(&fname, "\\%x", (int)random());
3620 cli_unlink(cli->tree, fname);
3624 if (!torture_close_connection(cli)) {
3628 printf("finished dirtest\n");
3633 static void del_fn(file_info *finfo, const char *mask, void *state)
3635 struct cli_state *pcli = (struct cli_state *)state;
3637 asprintf(&fname, "\\LISTDIR\\%s", finfo->name);
3639 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
3642 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
3643 if (NT_STATUS_IS_ERR(cli_rmdir(pcli->tree, fname)))
3644 printf("del_fn: failed to rmdir %s, error=%s\n", fname, cli_errstr(pcli->tree) );
3646 if (NT_STATUS_IS_ERR(cli_unlink(pcli->tree, fname)))
3647 printf("del_fn: failed to unlink %s, error=%s\n", fname, cli_errstr(pcli->tree) );
3654 sees what IOCTLs are supported
3656 BOOL torture_ioctl_test(int dummy)
3658 struct cli_state *cli;
3659 uint16_t device, function;
3661 const char *fname = "\\ioctl.dat";
3663 union smb_ioctl parms;
3664 TALLOC_CTX *mem_ctx;
3666 if (!torture_open_connection(&cli)) {
3670 mem_ctx = talloc_init("ioctl_test");
3672 printf("starting ioctl test\n");
3674 cli_unlink(cli->tree, fname);
3676 fnum = cli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3678 printf("open of %s failed (%s)\n", fname, cli_errstr(cli->tree));
3682 parms.ioctl.level = RAW_IOCTL_IOCTL;
3683 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
3684 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3685 printf("ioctl job info: %s\n", cli_errstr(cli->tree));
3687 for (device=0;device<0x100;device++) {
3688 printf("testing device=0x%x\n", device);
3689 for (function=0;function<0x100;function++) {
3690 parms.ioctl.in.request = (device << 16) | function;
3691 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3693 if (NT_STATUS_IS_OK(status)) {
3694 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
3695 device, function, parms.ioctl.out.blob.length);
3700 if (!torture_close_connection(cli)) {
3709 tries variants of chkpath
3711 BOOL torture_chkpath_test(int dummy)
3713 struct cli_state *cli;
3717 if (!torture_open_connection(&cli)) {
3721 printf("starting chkpath test\n");
3723 printf("Testing valid and invalid paths\n");
3725 /* cleanup from an old run */
3726 cli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3727 cli_unlink(cli->tree, "\\chkpath.dir\\*");
3728 cli_rmdir(cli->tree, "\\chkpath.dir");
3730 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, "\\chkpath.dir"))) {
3731 printf("mkdir1 failed : %s\n", cli_errstr(cli->tree));
3735 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
3736 printf("mkdir2 failed : %s\n", cli_errstr(cli->tree));
3740 fnum = cli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3742 printf("open1 failed (%s)\n", cli_errstr(cli->tree));
3745 cli_close(cli->tree, fnum);
3747 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir"))) {
3748 printf("chkpath1 failed: %s\n", cli_errstr(cli->tree));
3752 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
3753 printf("chkpath2 failed: %s\n", cli_errstr(cli->tree));
3757 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
3758 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3759 NT_STATUS_NOT_A_DIRECTORY);
3761 printf("* chkpath on a file should fail\n");
3765 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
3766 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
3767 NT_STATUS_OBJECT_NAME_NOT_FOUND);
3769 printf("* chkpath on a non existent file should fail\n");
3773 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
3774 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3775 NT_STATUS_OBJECT_PATH_NOT_FOUND);
3777 printf("* chkpath on a non existent component should fail\n");
3781 cli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3782 cli_unlink(cli->tree, "\\chkpath.dir\\*");
3783 cli_rmdir(cli->tree, "\\chkpath.dir");
3785 if (!torture_close_connection(cli)) {
3792 static BOOL run_dirtest1(int dummy)
3795 struct cli_state *cli;
3797 BOOL correct = True;
3799 printf("starting directory test\n");
3801 if (!torture_open_connection(&cli)) {
3805 cli_list(cli->tree, "\\LISTDIR\\*", 0, del_fn, cli);
3806 cli_list(cli->tree, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
3807 if (cli_deltree(cli->tree, "\\LISTDIR") == -1) {
3808 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", cli_errstr(cli->tree));
3811 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, "\\LISTDIR"))) {
3812 fprintf(stderr,"Failed to mkdir %s, error=%s\n", "\\LISTDIR", cli_errstr(cli->tree));
3816 printf("Creating %d files\n", torture_entries);
3818 /* Create torture_entries files and torture_entries directories. */
3819 for (i=0;i<torture_entries;i++) {
3821 asprintf(&fname, "\\LISTDIR\\f%d", i);
3822 fnum = cli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3823 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3825 fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli->tree));
3829 cli_close(cli->tree, fnum);
3831 for (i=0;i<torture_entries;i++) {
3833 asprintf(&fname, "\\LISTDIR\\d%d", i);
3834 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, fname))) {
3835 fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli->tree));
3841 /* Now ensure that doing an old list sees both files and directories. */
3842 num_seen = cli_list_old(cli->tree, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3843 printf("num_seen = %d\n", num_seen );
3844 /* We should see (torture_entries) each of files & directories + . and .. */
3845 if (num_seen != (2*torture_entries)+2) {
3847 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3848 (2*torture_entries)+2, num_seen);
3852 /* Ensure if we have the "must have" bits we only see the
3855 num_seen = cli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3856 printf("num_seen = %d\n", num_seen );
3857 if (num_seen != torture_entries+2) {
3859 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3860 torture_entries+2, num_seen);
3863 num_seen = cli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3864 printf("num_seen = %d\n", num_seen );
3865 if (num_seen != torture_entries) {
3867 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3868 torture_entries, num_seen);
3871 /* Delete everything. */
3872 cli_list(cli->tree, "\\LISTDIR\\*", 0, del_fn, cli);
3873 cli_list(cli->tree, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
3874 cli_rmdir(cli->tree, "\\LISTDIR");
3877 printf("Matched %d\n", cli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3878 printf("Matched %d\n", cli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3879 printf("Matched %d\n", cli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3882 if (!torture_close_connection(cli)) {
3886 printf("finished dirtest1\n");
3893 simple test harness for playing with deny modes
3895 static BOOL run_deny3test(int dummy)
3897 struct cli_state *cli1, *cli2;
3901 printf("starting deny3 test\n");
3903 printf("Testing simple deny modes\n");
3905 if (!torture_open_connection(&cli1)) {
3908 if (!torture_open_connection(&cli2)) {
3912 fname = "\\deny_dos1.dat";
3914 cli_unlink(cli1->tree, fname);
3915 fnum1 = cli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3916 fnum2 = cli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3917 if (fnum1 != -1) cli_close(cli1->tree, fnum1);
3918 if (fnum2 != -1) cli_close(cli1->tree, fnum2);
3919 cli_unlink(cli1->tree, fname);
3920 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3923 fname = "\\deny_dos2.dat";
3925 cli_unlink(cli1->tree, fname);
3926 fnum1 = cli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3927 fnum2 = cli_open(cli2->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3928 if (fnum1 != -1) cli_close(cli1->tree, fnum1);
3929 if (fnum2 != -1) cli_close(cli2->tree, fnum2);
3930 cli_unlink(cli1->tree, fname);
3931 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3934 torture_close_connection(cli1);
3935 torture_close_connection(cli2);
3941 parse a //server/share type UNC name
3943 static BOOL parse_unc(const char *unc_name, char **hostname, char **sharename)
3947 if (strncmp(unc_name, "//", 2)) {
3951 *hostname = strdup(&unc_name[2]);
3952 p = strchr_m(&(*hostname)[2],'/');
3957 *sharename = strdup(p+1);
3964 static void sigcont(void)
3968 double torture_create_procs(BOOL (*fn)(struct cli_state *, int), BOOL *result)
3971 volatile pid_t *child_status;
3972 volatile BOOL *child_status_out;
3975 double start_time_limit = 10 + (torture_nprocs * 1.5);
3976 char **unc_list = NULL;
3978 int num_unc_names = 0;
3982 signal(SIGCONT, sigcont);
3984 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
3985 if (!child_status) {
3986 printf("Failed to setup shared memory\n");
3990 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
3991 if (!child_status_out) {
3992 printf("Failed to setup result status shared memory\n");
3996 p = lp_parm_string(-1, "torture", "unclist");
3998 unc_list = file_lines_load(p, &num_unc_names);
3999 if (!unc_list || num_unc_names <= 0) {
4000 printf("Failed to load unc names list from %s\n", p);
4005 for (i = 0; i < torture_nprocs; i++) {
4006 child_status[i] = 0;
4007 child_status_out[i] = True;
4012 for (i=0;i<torture_nprocs;i++) {
4016 char *hostname=NULL, *sharename;
4018 pid_t mypid = getpid();
4019 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
4021 asprintf(&myname, "CLIENT%d", i);
4022 lp_set_cmdline("netbios name", myname);
4027 if (!parse_unc(unc_list[i % num_unc_names],
4028 &hostname, &sharename)) {
4029 printf("Failed to parse UNC name %s\n",
4030 unc_list[i % num_unc_names]);
4037 if (torture_open_connection_share(¤t_cli,
4042 } else if (torture_open_connection(¤t_cli)) {
4046 printf("pid %d failed to start\n", (int)getpid());
4052 child_status[i] = getpid();
4056 if (child_status[i]) {
4057 printf("Child %d failed to start!\n", i);
4058 child_status_out[i] = 1;
4062 child_status_out[i] = fn(current_cli, i);
4069 for (i=0;i<torture_nprocs;i++) {
4070 if (child_status[i]) synccount++;
4072 if (synccount == torture_nprocs) break;
4074 } while (end_timer() < start_time_limit);
4076 if (synccount != torture_nprocs) {
4077 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
4082 printf("Starting %d clients\n", torture_nprocs);
4084 /* start the client load */
4086 for (i=0;i<torture_nprocs;i++) {
4087 child_status[i] = 0;
4091 printf("%d clients started\n", torture_nprocs);
4093 for (i=0;i<torture_nprocs;i++) {
4095 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
4096 if (ret == -1 || WEXITSTATUS(status) != 0) {
4103 for (i=0;i<torture_nprocs;i++) {
4104 if (!child_status_out[i]) {
4111 #define FLAG_MULTIPROC 1
4118 {"FDPASS", run_fdpasstest, 0},
4119 {"LOCK1", run_locktest1, 0},
4120 {"LOCK2", run_locktest2, 0},
4121 {"LOCK3", run_locktest3, 0},
4122 {"LOCK4", run_locktest4, 0},
4123 {"LOCK5", run_locktest5, 0},
4124 {"LOCK6", run_locktest6, 0},
4125 {"LOCK7", run_locktest7, 0},
4126 {"UNLINK", run_unlinktest, 0},
4127 {"ATTR", run_attrtest, 0},
4128 {"TRANS2", run_trans2test, 0},
4129 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
4130 {"TORTURE",run_torture, FLAG_MULTIPROC},
4131 {"NEGNOWAIT", run_negprot_nowait, 0},
4132 {"NBENCH", torture_nbench, 0},
4133 {"DIR", run_dirtest, 0},
4134 {"DIR1", run_dirtest1, 0},
4135 {"DENY1", torture_denytest1, 0},
4136 {"DENY2", torture_denytest2, 0},
4137 {"TCON", run_tcon_test, 0},
4138 {"TCONDEV", run_tcon_devtype_test, 0},
4139 {"VUID", run_vuidtest, 0},
4141 {"DFSBASIC", torture_dfs_basic, 0},
4142 {"DFSRENAME", torture_dfs_rename, 0},
4143 {"DFSRANDOM", torture_dfs_random, 0},
4145 {"RW1", run_readwritetest, 0},
4146 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
4147 {"OPEN", run_opentest, 0},
4148 {"DENY3", run_deny3test, 0},
4150 {"OPENATTR", run_openattrtest, 0},
4152 {"DEFER_OPEN", run_deferopen, FLAG_MULTIPROC},
4153 {"XCOPY", run_xcopy, 0},
4154 {"RENAME", run_rename, 0},
4155 {"DELETE", run_deletetest, 0},
4156 {"PROPERTIES", run_properties, 0},
4157 {"MANGLE", torture_mangle, 0},
4158 {"UTABLE", torture_utable, 0},
4159 {"CASETABLE", torture_casetable, 0},
4160 {"CHARSET", torture_charset, 0},
4161 {"PIPE_NUMBER", run_pipe_number, 0},
4162 {"IOCTL", torture_ioctl_test, 0},
4163 {"CHKPATH", torture_chkpath_test, 0},
4164 {"HOLDCON", torture_holdcon, 0},
4165 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
4166 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
4167 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
4168 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
4169 {"RAW-SEARCH", torture_raw_search, 0},
4170 {"RAW-CLOSE", torture_raw_close, 0},
4171 {"RAW-OPEN", torture_raw_open, 0},
4172 {"RAW-MKDIR", torture_raw_mkdir, 0},
4173 {"RAW-OPLOCK", torture_raw_oplock, 0},
4174 {"RAW-NOTIFY", torture_raw_notify, 0},
4175 {"RAW-MUX", torture_raw_mux, 0},
4176 {"RAW-IOCTL", torture_raw_ioctl, 0},
4177 {"RAW-CHKPATH", torture_raw_chkpath, 0},
4178 {"RAW-UNLINK", torture_raw_unlink, 0},
4179 {"RAW-READ", torture_raw_read, 0},
4180 {"RAW-WRITE", torture_raw_write, 0},
4181 {"RAW-LOCK", torture_raw_lock, 0},
4182 {"RAW-CONTEXT", torture_raw_context, 0},
4183 {"RAW-RENAME", torture_raw_rename, 0},
4184 {"RAW-SEEK", torture_raw_seek, 0},
4185 {"SCAN-TRANS2", torture_trans2_scan, 0},
4186 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
4187 {"SCAN-ALIASES", torture_trans2_aliases, 0},
4188 {"SCAN-SMB", torture_smb_scan, 0},
4189 {"RPC-LSA", torture_rpc_lsa, 0},
4190 {"RPC-ECHO", torture_rpc_echo, 0},
4191 {"RPC-DFS", torture_rpc_dfs, 0},
4192 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
4193 {"RPC-SAMR", torture_rpc_samr, 0},
4194 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
4195 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
4196 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
4197 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
4198 {"RPC-ATSVC", torture_rpc_atsvc, 0},
4199 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
4200 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
4201 {"RPC-WINREG", torture_rpc_winreg, 0},
4202 {"RPC-MGMT", torture_rpc_mgmt, 0},
4203 {"RPC-SCANNER", torture_rpc_scanner, 0},
4204 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
4205 {"NTLMSSP-SELFCHECK", torture_ntlmssp_self_check, 0},
4210 /****************************************************************************
4211 run a specified test or "ALL"
4212 ****************************************************************************/
4213 static BOOL run_test(const char *name)
4217 BOOL matched = False;
4219 if (strequal(name,"ALL")) {
4220 for (i=0;torture_ops[i].name;i++) {
4221 if (!run_test(torture_ops[i].name)) {
4228 for (i=0;torture_ops[i].name;i++) {
4229 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
4232 printf("Running %s\n", torture_ops[i].name);
4233 if (torture_ops[i].flags & FLAG_MULTIPROC) {
4235 t = torture_create_procs(torture_ops[i].fn, &result);
4238 printf("TEST %s FAILED!\n", torture_ops[i].name);
4243 if (!torture_ops[i].fn(0)) {
4245 printf("TEST %s FAILED!\n", torture_ops[i].name);
4249 printf("%s took %g secs\n\n", torture_ops[i].name, t);
4254 printf("Unknown torture operation '%s'\n", name);
4262 parse a username%password
4264 static void parse_user(const char *user)
4266 char *username, *password = NULL, *p;
4268 username = strdup(user);
4269 p = strchr_m(username,'%');
4272 password = strdup(p+1);
4275 lp_set_cmdline("torture:username", username);
4278 lp_set_cmdline("torture:password", password);
4281 if (!lp_parm_string(-1,"torture","password")) {
4282 password = getpass("password:");
4284 lp_set_cmdline("torture:password", password);
4288 static void usage(void)
4292 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
4294 printf("\t-d debuglevel\n");
4295 printf("\t-U user%%pass\n");
4296 printf("\t-k use kerberos\n");
4297 printf("\t-N numprocs\n");
4298 printf("\t-n my_netbios_name\n");
4299 printf("\t-W workgroup\n");
4300 printf("\t-o num_operations\n");
4301 printf("\t-e num files(entries)\n");
4302 printf("\t-O socket_options\n");
4303 printf("\t-m maximum protocol\n");
4304 printf("\t-L use oplocks\n");
4305 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
4306 printf("\t-t timelimit specify NBENCH time limit (seconds)\n");
4307 printf("\t-C filename specifies file with list of UNCs for connections\n");
4308 printf("\t-A showall\n");
4309 printf("\t-p port\n");
4310 printf("\t-s seed\n");
4311 printf("\t-f max failures\n");
4312 printf("\t-X enable dangerous tests\n");
4315 printf("tests are:");
4316 for (i=0;torture_ops[i].name;i++) {
4317 printf(" %s", torture_ops[i].name);
4321 printf("default test is ALL\n");
4326 /****************************************************************************
4328 ****************************************************************************/
4329 int main(int argc,char *argv[])
4333 BOOL correct = True;
4334 char *host, *share, *username;
4336 setup_logging("smbtorture", DEBUG_STDOUT);
4338 #ifdef HAVE_SETBUFFER
4339 setbuffer(stdout, NULL, 0);
4342 lp_load(dyn_CONFIGFILE,True,False,False);
4349 for(p = argv[1]; *p; p++)
4354 /* see if its a RPC transport specifier */
4355 if (strncmp(argv[1], "ncacn_", 6) == 0) {
4356 lp_set_cmdline("torture:binding", argv[1]);
4358 char *binding = NULL;
4360 if (!parse_unc(argv[1], &host, &share)) {
4364 lp_set_cmdline("torture:host", host);
4365 lp_set_cmdline("torture:share", share);
4366 lp_set_cmdline("torture:password", "");
4367 asprintf(&binding, "ncacn_np:%s", host);
4368 lp_set_cmdline("torture:binding", binding);
4371 if (getenv("LOGNAME")) {
4372 username = strdup(getenv("LOGNAME"));
4374 lp_set_cmdline("torture:username", username);
4380 srandom(time(NULL));
4382 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:e:m:Ld:Ac:ks:f:s:t:C:X")) != EOF) {
4385 lp_set_cmdline("smb ports", optarg);
4388 lp_set_cmdline("workgroup", optarg);
4391 lp_set_cmdline("protocol", optarg);
4394 lp_set_cmdline("netbios name", optarg);
4397 lp_set_cmdline("debug level", optarg);
4398 setup_logging(NULL, DEBUG_STDOUT);
4401 lp_set_cmdline("socket options", optarg);
4404 srandom(atoi(optarg));
4407 torture_nprocs = atoi(optarg);
4410 torture_numops = atoi(optarg);
4413 torture_entries = atoi(optarg);
4419 torture_showall = True;
4422 lp_set_cmdline("torture:loadfile", optarg);
4425 lp_set_cmdline("torture:unclist", optarg);
4428 lp_set_cmdline("torture:timelimit", optarg);
4432 use_kerberos = True;
4434 d_printf("No kerberos support compiled in\n");
4442 torture_failures = atoi(optarg);
4446 lp_set_cmdline("torture:dangerous", "1");
4450 printf("Unknown option %c (%d)\n", (char)opt, opt);
4455 if (!lp_parm_string(-1,"torture","password")) {
4456 lp_set_cmdline("torture:password", "");
4459 if (argc == optind) {
4460 printf("You must specify a test to run, or 'ALL'\n");
4462 for (i=optind;i<argc;i++) {
4463 if (!run_test(argv[i])) {