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 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 unsigned n = (unsigned)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 unsigned 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 = ((unsigned)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 uchar 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 = ((unsigned)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;
559 unsigned lock_timeout;
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 (unsigned int)(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 cnum1, cnum2, cnum3;
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
1763 static BOOL run_maxfidtest(struct cli_state *cli, int dummy)
1765 const char *template = "\\maxfid.%d.%d";
1767 int fnums[0x11000], i;
1769 BOOL correct = True;
1772 printf("failed to connect\n");
1776 printf("Testing maximum number of open files\n");
1778 for (i=0; i<0x11000; i++) {
1779 asprintf(&fname, template, i,(int)getpid());
1780 if ((fnums[i] = cli_open(cli->tree, fname,
1781 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1783 printf("open of %s failed (%s)\n",
1784 fname, cli_errstr(cli->tree));
1785 printf("maximum fnum is %d\n", i);
1794 printf("cleaning up\n");
1796 asprintf(&fname, template, i,(int)getpid());
1797 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnums[i]))) {
1798 printf("Close of fnum %d failed - %s\n", fnums[i], cli_errstr(cli->tree));
1800 if (NT_STATUS_IS_ERR(cli_unlink(cli->tree, fname))) {
1801 printf("unlink of %s failed (%s)\n",
1802 fname, cli_errstr(cli->tree));
1810 printf("maxfid test finished\n");
1811 if (!torture_close_connection(cli)) {
1817 /* send smb negprot commands, not reading the response */
1818 static BOOL run_negprot_nowait(int dummy)
1821 struct cli_state *cli;
1822 BOOL correct = True;
1824 printf("starting negprot nowait test\n");
1826 cli = open_nbt_connection();
1831 printf("Establishing protocol negotiations - connect with another client\n");
1833 for (i=0;i<50000;i++) {
1834 smb_negprot_send(cli->transport, PROTOCOL_NT1);
1837 if (!torture_close_connection(cli)) {
1841 printf("finished negprot nowait test\n");
1848 This checks how the getatr calls works
1850 static BOOL run_attrtest(int dummy)
1852 struct cli_state *cli;
1855 const char *fname = "\\attrib123456789.tst";
1856 BOOL correct = True;
1858 printf("starting attrib test\n");
1860 if (!torture_open_connection(&cli)) {
1864 cli_unlink(cli->tree, fname);
1865 fnum = cli_open(cli->tree, fname,
1866 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1867 cli_close(cli->tree, fnum);
1869 if (NT_STATUS_IS_ERR(cli_getatr(cli->tree, fname, NULL, NULL, &t))) {
1870 printf("getatr failed (%s)\n", cli_errstr(cli->tree));
1874 printf("New file time is %s", ctime(&t));
1876 if (abs(t - time(NULL)) > 60*60*24*10) {
1877 printf("ERROR: SMBgetatr bug. time is %s",
1883 t2 = t-60*60*24; /* 1 day ago */
1885 printf("Setting file time to %s", ctime(&t2));
1887 if (NT_STATUS_IS_ERR(cli_setatr(cli->tree, fname, 0, t2))) {
1888 printf("setatr failed (%s)\n", cli_errstr(cli->tree));
1892 if (NT_STATUS_IS_ERR(cli_getatr(cli->tree, fname, NULL, NULL, &t))) {
1893 printf("getatr failed (%s)\n", cli_errstr(cli->tree));
1897 printf("Retrieved file time as %s", ctime(&t));
1900 printf("ERROR: getatr/setatr bug. times are\n%s",
1902 printf("%s", ctime(&t2));
1906 cli_unlink(cli->tree, fname);
1908 if (!torture_close_connection(cli)) {
1912 printf("attrib test finished\n");
1919 This checks a couple of trans2 calls
1921 static BOOL run_trans2test(int dummy)
1923 struct cli_state *cli;
1926 time_t c_time, a_time, m_time, w_time, m_time2;
1927 const char *fname = "\\trans2.tst";
1928 const char *dname = "\\trans2";
1929 const char *fname2 = "\\trans2\\trans2.tst";
1931 BOOL correct = True;
1933 printf("starting trans2 test\n");
1935 if (!torture_open_connection(&cli)) {
1939 cli_unlink(cli->tree, fname);
1941 printf("Testing qfileinfo\n");
1943 fnum = cli_open(cli->tree, fname,
1944 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1945 if (NT_STATUS_IS_ERR(cli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
1947 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli->tree));
1951 printf("Testing NAME_INFO\n");
1953 if (NT_STATUS_IS_ERR(cli_qfilename(cli->tree, fnum, &pname))) {
1954 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli->tree));
1958 if (!pname || strcmp(pname, fname)) {
1959 printf("qfilename gave different name? [%s] [%s]\n",
1964 cli_close(cli->tree, fnum);
1965 cli_unlink(cli->tree, fname);
1967 fnum = cli_open(cli->tree, fname,
1968 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1970 printf("open of %s failed (%s)\n", fname, cli_errstr(cli->tree));
1973 cli_close(cli->tree, fnum);
1975 printf("Checking for sticky create times\n");
1977 if (NT_STATUS_IS_ERR(cli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
1978 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli->tree));
1981 if (c_time != m_time) {
1982 printf("create time=%s", ctime(&c_time));
1983 printf("modify time=%s", ctime(&m_time));
1984 printf("This system appears to have sticky create times\n");
1986 if (a_time % (60*60) == 0) {
1987 printf("access time=%s", ctime(&a_time));
1988 printf("This system appears to set a midnight access time\n");
1992 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1993 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1999 cli_unlink(cli->tree, fname);
2000 fnum = cli_open(cli->tree, fname,
2001 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2002 cli_close(cli->tree, fnum);
2003 if (NT_STATUS_IS_ERR(cli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2004 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli->tree));
2007 if (w_time < 60*60*24*2) {
2008 printf("write time=%s", ctime(&w_time));
2009 printf("This system appears to set a initial 0 write time\n");
2014 cli_unlink(cli->tree, fname);
2017 /* check if the server updates the directory modification time
2018 when creating a new file */
2019 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, dname))) {
2020 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli->tree));
2024 if (NT_STATUS_IS_ERR(cli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2025 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli->tree));
2029 fnum = cli_open(cli->tree, fname2,
2030 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2031 cli_write(cli->tree, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2032 cli_close(cli->tree, fnum);
2033 if (NT_STATUS_IS_ERR(cli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
2034 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli->tree));
2037 if (m_time2 == m_time) {
2038 printf("This system does not update directory modification times\n");
2042 cli_unlink(cli->tree, fname2);
2043 cli_rmdir(cli->tree, dname);
2045 if (!torture_close_connection(cli)) {
2049 printf("trans2 test finished\n");
2055 Test delete on close semantics.
2057 static BOOL run_deletetest(int dummy)
2059 struct cli_state *cli1;
2060 struct cli_state *cli2 = NULL;
2061 const char *fname = "\\delete.file";
2064 BOOL correct = True;
2066 printf("starting delete test\n");
2068 if (!torture_open_connection(&cli1)) {
2072 /* Test 1 - this should delete the file on close. */
2074 cli_setatr(cli1->tree, fname, 0, 0);
2075 cli_unlink(cli1->tree, fname);
2077 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2078 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF,
2079 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2082 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2087 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2088 printf("[1] close failed (%s)\n", cli_errstr(cli1->tree));
2093 fnum1 = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
2095 printf("[1] open of %s succeeded (should fail)\n", fname);
2100 printf("first delete on close test succeeded.\n");
2102 /* Test 2 - this should delete the file on close. */
2104 cli_setatr(cli1->tree, fname, 0, 0);
2105 cli_unlink(cli1->tree, fname);
2107 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
2108 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
2109 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2112 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2117 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2118 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1->tree));
2123 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2124 printf("[2] close failed (%s)\n", cli_errstr(cli1->tree));
2129 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2131 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2132 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2133 printf("[2] close failed (%s)\n", cli_errstr(cli1->tree));
2137 cli_unlink(cli1->tree, fname);
2139 printf("second delete on close test succeeded.\n");
2142 cli_setatr(cli1->tree, fname, 0, 0);
2143 cli_unlink(cli1->tree, fname);
2145 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2146 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2149 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2154 /* This should fail with a sharing violation - open for delete is only compatible
2155 with SHARE_DELETE. */
2157 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2158 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2159 NTCREATEX_DISP_OPEN, 0, 0);
2162 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2167 /* This should succeed. */
2169 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2170 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN, 0, 0);
2173 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2178 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2179 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1->tree));
2184 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2185 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1->tree));
2190 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum2))) {
2191 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1->tree));
2196 /* This should fail - file should no longer be there. */
2198 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2200 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2201 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2202 printf("[3] close failed (%s)\n", cli_errstr(cli1->tree));
2204 cli_unlink(cli1->tree, fname);
2208 printf("third delete on close test succeeded.\n");
2211 cli_setatr(cli1->tree, fname, 0, 0);
2212 cli_unlink(cli1->tree, fname);
2214 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
2215 SA_RIGHT_FILE_READ_DATA |
2216 SA_RIGHT_FILE_WRITE_DATA |
2217 STD_RIGHT_DELETE_ACCESS,
2218 FILE_ATTRIBUTE_NORMAL,
2219 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2220 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2223 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2228 /* This should succeed. */
2229 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2230 FILE_ATTRIBUTE_NORMAL,
2231 NTCREATEX_SHARE_ACCESS_READ |
2232 NTCREATEX_SHARE_ACCESS_WRITE |
2233 NTCREATEX_SHARE_ACCESS_DELETE,
2234 NTCREATEX_DISP_OPEN, 0, 0);
2236 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2241 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum2))) {
2242 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1->tree));
2247 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2248 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1->tree));
2253 /* This should fail - no more opens once delete on close set. */
2254 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2255 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2256 NTCREATEX_DISP_OPEN, 0, 0);
2258 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2262 printf("fourth delete on close test succeeded.\n");
2264 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2265 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2271 cli_setatr(cli1->tree, fname, 0, 0);
2272 cli_unlink(cli1->tree, fname);
2274 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
2276 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2281 /* This should fail - only allowed on NT opens with DELETE access. */
2283 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2284 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2289 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2290 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2295 printf("fifth delete on close test succeeded.\n");
2298 cli_setatr(cli1->tree, fname, 0, 0);
2299 cli_unlink(cli1->tree, fname);
2301 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
2302 SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA,
2303 FILE_ATTRIBUTE_NORMAL,
2304 NTCREATEX_SHARE_ACCESS_READ |
2305 NTCREATEX_SHARE_ACCESS_WRITE |
2306 NTCREATEX_SHARE_ACCESS_DELETE,
2307 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2310 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2315 /* This should fail - only allowed on NT opens with DELETE access. */
2317 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2318 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2323 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2324 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2329 printf("sixth delete on close test succeeded.\n");
2332 cli_setatr(cli1->tree, fname, 0, 0);
2333 cli_unlink(cli1->tree, fname);
2335 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
2336 SA_RIGHT_FILE_READ_DATA |
2337 SA_RIGHT_FILE_WRITE_DATA |
2338 STD_RIGHT_DELETE_ACCESS,
2339 FILE_ATTRIBUTE_NORMAL, 0, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2342 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2347 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2348 printf("[7] setting delete_on_close on file failed !\n");
2353 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, False))) {
2354 printf("[7] unsetting delete_on_close on file failed !\n");
2359 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2360 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2365 /* This next open should succeed - we reset the flag. */
2367 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2369 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2374 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2375 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2380 printf("seventh delete on close test succeeded.\n");
2383 cli_setatr(cli1->tree, fname, 0, 0);
2384 cli_unlink(cli1->tree, fname);
2386 if (!torture_open_connection(&cli2)) {
2387 printf("[8] failed to open second connection.\n");
2392 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2393 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2394 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2397 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2402 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2403 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2404 NTCREATEX_DISP_OPEN, 0, 0);
2407 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2412 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2413 printf("[8] setting delete_on_close on file failed !\n");
2418 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2419 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1->tree));
2424 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
2425 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2->tree));
2430 /* This should fail.. */
2431 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2433 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2437 printf("eighth delete on close test succeeded.\n");
2439 /* This should fail - we need to set DELETE_ACCESS. */
2440 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
2441 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2444 printf("[9] open of %s succeeded should have failed!\n", fname);
2449 printf("ninth delete on close test succeeded.\n");
2451 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2452 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2454 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2459 /* This should delete the file. */
2460 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2461 printf("[10] close failed (%s)\n", cli_errstr(cli1->tree));
2466 /* This should fail.. */
2467 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2469 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2473 printf("tenth delete on close test succeeded.\n");
2474 printf("finished delete test\n");
2477 /* FIXME: This will crash if we aborted before cli2 got
2478 * intialized, because these functions don't handle
2479 * uninitialized connections. */
2481 cli_close(cli1->tree, fnum1);
2482 cli_close(cli1->tree, fnum2);
2483 cli_setatr(cli1->tree, fname, 0, 0);
2484 cli_unlink(cli1->tree, fname);
2486 if (!torture_close_connection(cli1)) {
2489 if (!torture_close_connection(cli2)) {
2497 print out server properties
2499 static BOOL run_properties(int dummy)
2501 struct cli_state *cli;
2502 BOOL correct = True;
2504 printf("starting properties test\n");
2508 if (!torture_open_connection(&cli)) {
2512 d_printf("Capabilities 0x%08x\n", cli->transport->negotiate.capabilities);
2514 if (!torture_close_connection(cli)) {
2523 /* FIRST_DESIRED_ACCESS 0xf019f */
2524 #define FIRST_DESIRED_ACCESS SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_APPEND_DATA|\
2525 SA_RIGHT_FILE_READ_EA| /* 0xf */ \
2526 SA_RIGHT_FILE_WRITE_EA|SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x90 */ \
2527 SA_RIGHT_FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
2528 STD_RIGHT_DELETE_ACCESS|STD_RIGHT_READ_CONTROL_ACCESS|\
2529 STD_RIGHT_WRITE_DAC_ACCESS|STD_RIGHT_WRITE_OWNER_ACCESS /* 0xf0000 */
2530 /* SECOND_DESIRED_ACCESS 0xe0080 */
2531 #define SECOND_DESIRED_ACCESS SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x80 */ \
2532 STD_RIGHT_READ_CONTROL_ACCESS|STD_RIGHT_WRITE_DAC_ACCESS|\
2533 STD_RIGHT_WRITE_OWNER_ACCESS /* 0xe0000 */
2536 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
2537 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2538 SA_RIGHT_FILE_READ_DATA|\
2539 WRITE_OWNER_ACCESS /* */
2543 Test ntcreate calls made by xcopy
2545 static BOOL run_xcopy(int dummy)
2547 struct cli_state *cli1;
2548 const char *fname = "\\test.txt";
2549 BOOL correct = True;
2552 printf("starting xcopy test\n");
2554 if (!torture_open_connection(&cli1)) {
2558 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
2559 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2560 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF,
2564 printf("First open failed - %s\n", cli_errstr(cli1->tree));
2568 fnum2 = cli_nt_create_full(cli1->tree, fname, 0,
2569 SECOND_DESIRED_ACCESS, 0,
2570 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
2573 printf("second open failed - %s\n", cli_errstr(cli1->tree));
2577 if (!torture_close_connection(cli1)) {
2585 Test rename on files open with share delete and no share delete.
2587 static BOOL run_rename(int dummy)
2589 struct cli_state *cli1;
2590 const char *fname = "\\test.txt";
2591 const char *fname1 = "\\test1.txt";
2592 BOOL correct = True;
2595 printf("starting rename test\n");
2597 if (!torture_open_connection(&cli1)) {
2601 cli_unlink(cli1->tree, fname);
2602 cli_unlink(cli1->tree, fname1);
2603 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2604 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2607 printf("First open failed - %s\n", cli_errstr(cli1->tree));
2611 if (NT_STATUS_IS_ERR(cli_rename(cli1->tree, fname, fname1))) {
2612 printf("First rename failed (this is correct) - %s\n", cli_errstr(cli1->tree));
2614 printf("First rename succeeded - this should have failed !\n");
2618 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2619 printf("close - 1 failed (%s)\n", cli_errstr(cli1->tree));
2623 cli_unlink(cli1->tree, fname);
2624 cli_unlink(cli1->tree, fname1);
2625 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2627 NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2629 NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2633 printf("Second open failed - %s\n", cli_errstr(cli1->tree));
2637 if (NT_STATUS_IS_ERR(cli_rename(cli1->tree, fname, fname1))) {
2638 printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(cli1->tree));
2641 printf("Second rename succeeded\n");
2644 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2645 printf("close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2649 cli_unlink(cli1->tree, fname);
2650 cli_unlink(cli1->tree, fname1);
2652 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2653 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2656 printf("Third open failed - %s\n", cli_errstr(cli1->tree));
2665 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2666 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2669 printf("Fourth open failed - %s\n", cli_errstr(cli1->tree));
2672 if (!cli_nt_delete_on_close(cli1->tree, fnum2, True)) {
2673 printf("[8] setting delete_on_close on file failed !\n");
2677 if (!cli_close(cli1->tree, fnum2)) {
2678 printf("close - 4 failed (%s)\n", cli_errstr(cli1->tree));
2684 if (NT_STATUS_IS_ERR(cli_rename(cli1->tree, fname, fname1))) {
2685 printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(cli1->tree));
2688 printf("Third rename succeeded\n");
2691 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2692 printf("close - 3 failed (%s)\n", cli_errstr(cli1->tree));
2696 cli_unlink(cli1->tree, fname);
2697 cli_unlink(cli1->tree, fname1);
2699 if (!torture_close_connection(cli1)) {
2706 static BOOL run_pipe_number(int dummy)
2708 struct cli_state *cli1;
2709 const char *pipe_name = "\\WKSSVC";
2713 printf("starting pipenumber test\n");
2714 if (!torture_open_connection(&cli1)) {
2719 fnum = cli_nt_create_full(cli1->tree, pipe_name, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
2720 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
2723 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1->tree));
2729 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
2730 torture_close_connection(cli1);
2738 open N connections to the server and just hold them open
2739 used for testing performance when there are N idle users
2742 static BOOL torture_holdcon(int dummy)
2745 struct cli_state **cli;
2748 printf("Opening %d connections\n", torture_numops);
2750 cli = malloc(sizeof(struct cli_state *) * torture_numops);
2752 for (i=0;i<torture_numops;i++) {
2753 if (!torture_open_connection(&cli[i])) {
2756 printf("opened %d connections\r", i);
2760 printf("\nStarting pings\n");
2763 for (i=0;i<torture_numops;i++) {
2766 status = cli_chkpath(cli[i]->tree, "\\");
2767 if (!NT_STATUS_IS_OK(status)) {
2768 printf("Connection %d is dead\n", i);
2776 if (num_dead == torture_numops) {
2777 printf("All connections dead - finishing\n");
2789 Try with a wrong vuid and check error message.
2792 static BOOL run_vuidtest(int dummy)
2794 struct cli_state *cli;
2795 const char *fname = "\\vuid.tst";
2798 time_t c_time, a_time, m_time, w_time, m_time2;
2799 BOOL correct = True;
2804 printf("starting vuid test\n");
2806 if (!torture_open_connection(&cli)) {
2810 cli_unlink(cli->tree, fname);
2812 fnum = cli_open(cli->tree, fname,
2813 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2815 orig_vuid = cli->session->vuid;
2817 cli->session->vuid += 1234;
2819 printf("Testing qfileinfo with wrong vuid\n");
2821 if (NT_STATUS_IS_OK(result = cli_qfileinfo(cli->tree, fnum, NULL,
2822 &size, &c_time, &a_time,
2823 &m_time, NULL, NULL))) {
2824 printf("ERROR: qfileinfo passed with wrong vuid\n");
2828 if ( (cli->transport->error.etype != ETYPE_DOS) ||
2829 (cli->transport->error.e.dos.eclass != ERRSRV) ||
2830 (cli->transport->error.e.dos.ecode != ERRbaduid) ) {
2831 printf("ERROR: qfileinfo should have returned DOS error "
2832 "ERRSRV:ERRbaduid\n but returned %s\n",
2833 cli_errstr(cli->tree));
2837 cli->session->vuid -= 1234;
2839 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum))) {
2840 printf("close failed (%s)\n", cli_errstr(cli->tree));
2844 cli_unlink(cli->tree, fname);
2846 if (!torture_close_connection(cli)) {
2850 printf("vuid test finished\n");
2856 Test open mode returns on read-only files.
2858 static BOOL run_opentest(int dummy)
2860 static struct cli_state *cli1;
2861 static struct cli_state *cli2;
2862 const char *fname = "\\readonly.file";
2866 BOOL correct = True;
2870 printf("starting open test\n");
2872 if (!torture_open_connection(&cli1)) {
2876 cli_setatr(cli1->tree, fname, 0, 0);
2877 cli_unlink(cli1->tree, fname);
2879 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2881 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2885 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2886 printf("close2 failed (%s)\n", cli_errstr(cli1->tree));
2890 if (NT_STATUS_IS_ERR(cli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
2891 printf("cli_setatr failed (%s)\n", cli_errstr(cli1->tree));
2892 CHECK_MAX_FAILURES(error_test1);
2896 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
2898 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2899 CHECK_MAX_FAILURES(error_test1);
2903 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
2904 fnum2 = cli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
2906 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
2907 NT_STATUS_ACCESS_DENIED)) {
2908 printf("correct error code ERRDOS/ERRnoaccess returned\n");
2911 printf("finished open test 1\n");
2913 cli_close(cli1->tree, fnum1);
2915 /* Now try not readonly and ensure ERRbadshare is returned. */
2917 cli_setatr(cli1->tree, fname, 0, 0);
2919 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
2921 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2925 /* This will fail - but the error should be ERRshare. */
2926 fnum2 = cli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
2928 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
2929 NT_STATUS_SHARING_VIOLATION)) {
2930 printf("correct error code ERRDOS/ERRbadshare returned\n");
2933 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2934 printf("close2 failed (%s)\n", cli_errstr(cli1->tree));
2938 cli_unlink(cli1->tree, fname);
2940 printf("finished open test 2\n");
2942 /* Test truncate open disposition on file opened for read. */
2944 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2946 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2950 /* write 20 bytes. */
2952 memset(buf, '\0', 20);
2954 if (cli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
2955 printf("write failed (%s)\n", cli_errstr(cli1->tree));
2959 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2960 printf("(3) close1 failed (%s)\n", cli_errstr(cli1->tree));
2964 /* Ensure size == 20. */
2965 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
2966 printf("(3) getatr failed (%s)\n", cli_errstr(cli1->tree));
2967 CHECK_MAX_FAILURES(error_test3);
2972 printf("(3) file size != 20\n");
2973 CHECK_MAX_FAILURES(error_test3);
2977 /* Now test if we can truncate a file opened for readonly. */
2979 fnum1 = cli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
2981 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2982 CHECK_MAX_FAILURES(error_test3);
2986 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2987 printf("close2 failed (%s)\n", cli_errstr(cli1->tree));
2991 /* Ensure size == 0. */
2992 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
2993 printf("(3) getatr failed (%s)\n", cli_errstr(cli1->tree));
2994 CHECK_MAX_FAILURES(error_test3);
2999 printf("(3) file size != 0\n");
3000 CHECK_MAX_FAILURES(error_test3);
3003 printf("finished open test 3\n");
3005 cli_unlink(cli1->tree, fname);
3008 printf("testing ctemp\n");
3009 fnum1 = cli_ctemp(cli1->tree, "\\", &tmp_path);
3011 printf("ctemp failed (%s)\n", cli_errstr(cli1->tree));
3012 CHECK_MAX_FAILURES(error_test4);
3015 printf("ctemp gave path %s\n", tmp_path);
3016 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3017 printf("close of temp failed (%s)\n", cli_errstr(cli1->tree));
3019 if (NT_STATUS_IS_ERR(cli_unlink(cli1->tree, tmp_path))) {
3020 printf("unlink of temp failed (%s)\n", cli_errstr(cli1->tree));
3023 /* Test the non-io opens... */
3025 if (!torture_open_connection(&cli2)) {
3029 cli_setatr(cli2->tree, fname, 0, 0);
3030 cli_unlink(cli2->tree, fname);
3032 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3034 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3035 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3038 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3039 CHECK_MAX_FAILURES(error_test10);
3043 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3044 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3046 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3047 CHECK_MAX_FAILURES(error_test10);
3051 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3052 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3055 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3056 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3060 printf("non-io open test #1 passed.\n");
3062 cli_unlink(cli1->tree, fname);
3064 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3066 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3067 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3070 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3071 CHECK_MAX_FAILURES(error_test20);
3075 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3076 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3079 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3080 CHECK_MAX_FAILURES(error_test20);
3084 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3085 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3088 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3089 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3093 printf("non-io open test #2 passed.\n");
3095 cli_unlink(cli1->tree, fname);
3097 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3099 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3100 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3103 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3104 CHECK_MAX_FAILURES(error_test30);
3108 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3109 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3112 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3113 CHECK_MAX_FAILURES(error_test30);
3117 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3118 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3121 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3122 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3126 printf("non-io open test #3 passed.\n");
3128 cli_unlink(cli1->tree, fname);
3130 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3132 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3133 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3136 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3137 CHECK_MAX_FAILURES(error_test40);
3141 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3142 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3145 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2->tree));
3146 CHECK_MAX_FAILURES(error_test40);
3150 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2->tree), "sharing violation");
3152 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3153 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3157 printf("non-io open test #4 passed.\n");
3159 cli_unlink(cli1->tree, fname);
3161 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3163 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3164 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3167 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3168 CHECK_MAX_FAILURES(error_test50);
3172 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3173 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3176 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3177 CHECK_MAX_FAILURES(error_test50);
3181 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3182 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3186 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3187 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3191 printf("non-io open test #5 passed.\n");
3193 printf("TEST #6 testing 1 non-io open, one io open\n");
3195 cli_unlink(cli1->tree, fname);
3197 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3198 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3201 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3202 CHECK_MAX_FAILURES(error_test60);
3206 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3207 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
3210 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3211 CHECK_MAX_FAILURES(error_test60);
3215 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3216 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3220 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3221 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3225 printf("non-io open test #6 passed.\n");
3227 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3229 cli_unlink(cli1->tree, fname);
3231 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3232 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3235 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3236 CHECK_MAX_FAILURES(error_test70);
3240 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3241 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3244 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2->tree));
3245 CHECK_MAX_FAILURES(error_test70);
3249 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2->tree), "sharing violation");
3251 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3252 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3256 printf("non-io open test #7 passed.\n");
3260 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
3262 cli_unlink(cli1->tree, fname);
3264 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3266 printf("(8) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3270 /* write 20 bytes. */
3272 memset(buf, '\0', 20);
3274 if (cli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
3275 printf("(8) write failed (%s)\n", cli_errstr(cli1->tree));
3279 /* Ensure size == 20. */
3280 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3281 printf("(8) getatr (1) failed (%s)\n", cli_errstr(cli1->tree));
3282 CHECK_MAX_FAILURES(error_test80);
3287 printf("(8) file size != 20\n");
3288 CHECK_MAX_FAILURES(error_test80);
3292 /* Get an exclusive lock on the open file. */
3293 if (NT_STATUS_IS_ERR(cli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
3294 printf("(8) lock1 failed (%s)\n", cli_errstr(cli1->tree));
3295 CHECK_MAX_FAILURES(error_test80);
3299 fnum2 = cli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
3301 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, cli_errstr(cli1->tree));
3305 /* Ensure size == 0. */
3306 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3307 printf("(8) getatr (2) failed (%s)\n", cli_errstr(cli1->tree));
3308 CHECK_MAX_FAILURES(error_test80);
3313 printf("(8) file size != 0\n");
3314 CHECK_MAX_FAILURES(error_test80);
3318 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3319 printf("(8) close1 failed (%s)\n", cli_errstr(cli1->tree));
3323 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum2))) {
3324 printf("(8) close1 failed (%s)\n", cli_errstr(cli1->tree));
3330 printf("open test #8 passed.\n");
3332 cli_unlink(cli1->tree, fname);
3334 if (!torture_close_connection(cli1)) {
3337 if (!torture_close_connection(cli2)) {
3345 static uint32_t open_attrs_table[] = {
3346 FILE_ATTRIBUTE_NORMAL,
3347 FILE_ATTRIBUTE_ARCHIVE,
3348 FILE_ATTRIBUTE_READONLY,
3349 FILE_ATTRIBUTE_HIDDEN,
3350 FILE_ATTRIBUTE_SYSTEM,
3352 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
3353 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
3354 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
3355 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3356 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3357 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3359 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3360 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3361 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3362 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
3365 struct trunc_open_results {
3368 uint32_t trunc_attr;
3369 uint32_t result_attr;
3372 static struct trunc_open_results attr_results[] = {
3373 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3374 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3375 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3376 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3377 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3378 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3379 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3380 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3381 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3382 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3383 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3384 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
3385 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3386 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3387 { 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 },
3388 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3389 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3390 { 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 },
3391 { 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 },
3392 { 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 },
3393 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3394 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3395 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3396 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3397 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3398 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
3401 static BOOL run_openattrtest(int dummy)
3403 struct cli_state *cli1;
3404 const char *fname = "\\openattr.file";
3406 BOOL correct = True;
3408 unsigned int i, j, k, l;
3411 printf("starting open attr test\n");
3413 if (!torture_open_connection(&cli1)) {
3417 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
3418 cli_setatr(cli1->tree, fname, 0, 0);
3419 cli_unlink(cli1->tree, fname);
3420 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_WRITE_DATA, open_attrs_table[i],
3421 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3424 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1->tree));
3428 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3429 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1->tree));
3433 for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
3434 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
3435 SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
3436 open_attrs_table[j],
3437 NTCREATEX_SHARE_ACCESS_NONE,
3438 NTCREATEX_DISP_OVERWRITE, 0, 0);
3441 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3442 if (attr_results[l].num == k) {
3443 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
3444 k, open_attrs_table[i],
3445 open_attrs_table[j],
3446 fname, NT_STATUS_V(cli_nt_error(cli1->tree)), cli_errstr(cli1->tree));
3448 CHECK_MAX_FAILURES(error_exit);
3451 if (NT_STATUS_V(cli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
3452 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
3453 k, open_attrs_table[i], open_attrs_table[j],
3454 cli_errstr(cli1->tree));
3456 CHECK_MAX_FAILURES(error_exit);
3459 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
3465 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3466 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1->tree));
3470 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, &attr, NULL, NULL))) {
3471 printf("getatr(2) failed (%s)\n", cli_errstr(cli1->tree));
3476 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
3477 k, open_attrs_table[i], open_attrs_table[j], attr );
3480 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3481 if (attr_results[l].num == k) {
3482 if (attr != attr_results[l].result_attr ||
3483 open_attrs_table[i] != attr_results[l].init_attr ||
3484 open_attrs_table[j] != attr_results[l].trunc_attr) {
3485 printf("[%d] getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
3486 k, open_attrs_table[i],
3487 open_attrs_table[j],
3489 attr_results[l].result_attr);
3491 CHECK_MAX_FAILURES(error_exit);
3500 cli_setatr(cli1->tree, fname, 0, 0);
3501 cli_unlink(cli1->tree, fname);
3503 printf("open attr test %s.\n", correct ? "passed" : "failed");
3505 if (!torture_close_connection(cli1)) {
3511 static void list_fn(file_info *finfo, const char *name, void *state)
3517 test directory listing speed
3519 static BOOL run_dirtest(int dummy)
3522 struct cli_state *cli;
3525 BOOL correct = True;
3527 printf("starting directory test\n");
3529 if (!torture_open_connection(&cli)) {
3533 printf("Creating %d random filenames\n", torture_numops);
3536 for (i=0;i<torture_numops;i++) {
3538 asprintf(&fname, "\\%x", (int)random());
3539 fnum = cli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3541 fprintf(stderr,"Failed to open %s\n", fname);
3544 cli_close(cli->tree, fnum);
3550 printf("Matched %d\n", cli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3551 printf("Matched %d\n", cli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3552 printf("Matched %d\n", cli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3554 printf("dirtest core %g seconds\n", end_timer() - t1);
3557 for (i=0;i<torture_numops;i++) {
3559 asprintf(&fname, "\\%x", (int)random());
3560 cli_unlink(cli->tree, fname);
3564 if (!torture_close_connection(cli)) {
3568 printf("finished dirtest\n");
3573 static void del_fn(file_info *finfo, const char *mask, void *state)
3575 struct cli_state *pcli = (struct cli_state *)state;
3577 asprintf(&fname, "\\LISTDIR\\%s", finfo->name);
3579 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
3582 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
3583 if (NT_STATUS_IS_ERR(cli_rmdir(pcli->tree, fname)))
3584 printf("del_fn: failed to rmdir %s, error=%s\n", fname, cli_errstr(pcli->tree) );
3586 if (NT_STATUS_IS_ERR(cli_unlink(pcli->tree, fname)))
3587 printf("del_fn: failed to unlink %s, error=%s\n", fname, cli_errstr(pcli->tree) );
3594 sees what IOCTLs are supported
3596 BOOL torture_ioctl_test(int dummy)
3598 struct cli_state *cli;
3599 uint16 device, function;
3601 const char *fname = "\\ioctl.dat";
3603 union smb_ioctl parms;
3604 TALLOC_CTX *mem_ctx;
3606 if (!torture_open_connection(&cli)) {
3610 mem_ctx = talloc_init("ioctl_test");
3612 printf("starting ioctl test\n");
3614 cli_unlink(cli->tree, fname);
3616 fnum = cli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3618 printf("open of %s failed (%s)\n", fname, cli_errstr(cli->tree));
3622 parms.ioctl.level = RAW_IOCTL_IOCTL;
3623 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
3624 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3625 printf("ioctl job info: %s\n", cli_errstr(cli->tree));
3627 for (device=0;device<0x100;device++) {
3628 printf("testing device=0x%x\n", device);
3629 for (function=0;function<0x100;function++) {
3630 parms.ioctl.in.request = (device << 16) | function;
3631 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3633 if (NT_STATUS_IS_OK(status)) {
3634 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
3635 device, function, parms.ioctl.out.blob.length);
3640 if (!torture_close_connection(cli)) {
3649 tries variants of chkpath
3651 BOOL torture_chkpath_test(int dummy)
3653 struct cli_state *cli;
3657 if (!torture_open_connection(&cli)) {
3661 printf("starting chkpath test\n");
3663 printf("Testing valid and invalid paths\n");
3665 /* cleanup from an old run */
3666 cli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3667 cli_unlink(cli->tree, "\\chkpath.dir\\*");
3668 cli_rmdir(cli->tree, "\\chkpath.dir");
3670 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, "\\chkpath.dir"))) {
3671 printf("mkdir1 failed : %s\n", cli_errstr(cli->tree));
3675 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
3676 printf("mkdir2 failed : %s\n", cli_errstr(cli->tree));
3680 fnum = cli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3682 printf("open1 failed (%s)\n", cli_errstr(cli->tree));
3685 cli_close(cli->tree, fnum);
3687 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir"))) {
3688 printf("chkpath1 failed: %s\n", cli_errstr(cli->tree));
3692 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
3693 printf("chkpath2 failed: %s\n", cli_errstr(cli->tree));
3697 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
3698 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3699 NT_STATUS_NOT_A_DIRECTORY);
3701 printf("* chkpath on a file should fail\n");
3705 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
3706 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
3707 NT_STATUS_OBJECT_NAME_NOT_FOUND);
3709 printf("* chkpath on a non existent file should fail\n");
3713 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
3714 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3715 NT_STATUS_OBJECT_PATH_NOT_FOUND);
3717 printf("* chkpath on a non existent component should fail\n");
3721 cli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3722 cli_unlink(cli->tree, "\\chkpath.dir\\*");
3723 cli_rmdir(cli->tree, "\\chkpath.dir");
3725 if (!torture_close_connection(cli)) {
3732 static BOOL run_dirtest1(int dummy)
3735 struct cli_state *cli;
3737 BOOL correct = True;
3739 printf("starting directory test\n");
3741 if (!torture_open_connection(&cli)) {
3745 cli_list(cli->tree, "\\LISTDIR\\*", 0, del_fn, cli);
3746 cli_list(cli->tree, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
3747 if (cli_deltree(cli->tree, "\\LISTDIR") == -1) {
3748 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", cli_errstr(cli->tree));
3751 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, "\\LISTDIR"))) {
3752 fprintf(stderr,"Failed to mkdir %s, error=%s\n", "\\LISTDIR", cli_errstr(cli->tree));
3756 printf("Creating %d files\n", torture_entries);
3758 /* Create torture_entries files and torture_entries directories. */
3759 for (i=0;i<torture_entries;i++) {
3761 asprintf(&fname, "\\LISTDIR\\f%d", i);
3762 fnum = cli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3763 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3765 fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli->tree));
3769 cli_close(cli->tree, fnum);
3771 for (i=0;i<torture_entries;i++) {
3773 asprintf(&fname, "\\LISTDIR\\d%d", i);
3774 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, fname))) {
3775 fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli->tree));
3781 /* Now ensure that doing an old list sees both files and directories. */
3782 num_seen = cli_list_old(cli->tree, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3783 printf("num_seen = %d\n", num_seen );
3784 /* We should see (torture_entries) each of files & directories + . and .. */
3785 if (num_seen != (2*torture_entries)+2) {
3787 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3788 (2*torture_entries)+2, num_seen);
3792 /* Ensure if we have the "must have" bits we only see the
3795 num_seen = cli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3796 printf("num_seen = %d\n", num_seen );
3797 if (num_seen != torture_entries+2) {
3799 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3800 torture_entries+2, num_seen);
3803 num_seen = cli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3804 printf("num_seen = %d\n", num_seen );
3805 if (num_seen != torture_entries) {
3807 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3808 torture_entries, num_seen);
3811 /* Delete everything. */
3812 cli_list(cli->tree, "\\LISTDIR\\*", 0, del_fn, cli);
3813 cli_list(cli->tree, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
3814 cli_rmdir(cli->tree, "\\LISTDIR");
3817 printf("Matched %d\n", cli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3818 printf("Matched %d\n", cli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3819 printf("Matched %d\n", cli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3822 if (!torture_close_connection(cli)) {
3826 printf("finished dirtest1\n");
3833 simple test harness for playing with deny modes
3835 static BOOL run_deny3test(int dummy)
3837 struct cli_state *cli1, *cli2;
3841 printf("starting deny3 test\n");
3843 printf("Testing simple deny modes\n");
3845 if (!torture_open_connection(&cli1)) {
3848 if (!torture_open_connection(&cli2)) {
3852 fname = "\\deny_dos1.dat";
3854 cli_unlink(cli1->tree, fname);
3855 fnum1 = cli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3856 fnum2 = cli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3857 if (fnum1 != -1) cli_close(cli1->tree, fnum1);
3858 if (fnum2 != -1) cli_close(cli1->tree, fnum2);
3859 cli_unlink(cli1->tree, fname);
3860 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3863 fname = "\\deny_dos2.dat";
3865 cli_unlink(cli1->tree, fname);
3866 fnum1 = cli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3867 fnum2 = cli_open(cli2->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3868 if (fnum1 != -1) cli_close(cli1->tree, fnum1);
3869 if (fnum2 != -1) cli_close(cli2->tree, fnum2);
3870 cli_unlink(cli1->tree, fname);
3871 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3874 torture_close_connection(cli1);
3875 torture_close_connection(cli2);
3881 parse a //server/share type UNC name
3883 static BOOL parse_unc(const char *unc_name, char **hostname, char **sharename)
3887 if (strncmp(unc_name, "//", 2)) {
3891 *hostname = strdup(&unc_name[2]);
3892 p = strchr_m(&(*hostname)[2],'/');
3897 *sharename = strdup(p+1);
3904 static void sigcont(void)
3908 double torture_create_procs(BOOL (*fn)(struct cli_state *, int), BOOL *result)
3911 volatile pid_t *child_status;
3912 volatile BOOL *child_status_out;
3915 double start_time_limit = 10 + (torture_nprocs * 1.5);
3916 char **unc_list = NULL;
3918 int num_unc_names = 0;
3922 signal(SIGCONT, sigcont);
3924 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
3925 if (!child_status) {
3926 printf("Failed to setup shared memory\n");
3930 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
3931 if (!child_status_out) {
3932 printf("Failed to setup result status shared memory\n");
3936 p = lp_parm_string(-1, "torture", "unclist");
3938 unc_list = file_lines_load(p, &num_unc_names);
3939 if (!unc_list || num_unc_names <= 0) {
3940 printf("Failed to load unc names list from %s\n", p);
3945 for (i = 0; i < torture_nprocs; i++) {
3946 child_status[i] = 0;
3947 child_status_out[i] = True;
3952 for (i=0;i<torture_nprocs;i++) {
3956 char *hostname=NULL, *sharename;
3958 pid_t mypid = getpid();
3959 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
3961 asprintf(&myname, "CLIENT%d", i);
3962 lp_set_cmdline("netbios name", myname);
3967 if (!parse_unc(unc_list[i % num_unc_names],
3968 &hostname, &sharename)) {
3969 printf("Failed to parse UNC name %s\n",
3970 unc_list[i % num_unc_names]);
3977 if (torture_open_connection_share(¤t_cli,
3982 } else if (torture_open_connection(¤t_cli)) {
3986 printf("pid %d failed to start\n", (int)getpid());
3992 child_status[i] = getpid();
3996 if (child_status[i]) {
3997 printf("Child %d failed to start!\n", i);
3998 child_status_out[i] = 1;
4002 child_status_out[i] = fn(current_cli, i);
4009 for (i=0;i<torture_nprocs;i++) {
4010 if (child_status[i]) synccount++;
4012 if (synccount == torture_nprocs) break;
4014 } while (end_timer() < start_time_limit);
4016 if (synccount != torture_nprocs) {
4017 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
4022 printf("Starting %d clients\n", torture_nprocs);
4024 /* start the client load */
4026 for (i=0;i<torture_nprocs;i++) {
4027 child_status[i] = 0;
4031 printf("%d clients started\n", torture_nprocs);
4033 for (i=0;i<torture_nprocs;i++) {
4035 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
4036 if (ret == -1 || WEXITSTATUS(status) != 0) {
4043 for (i=0;i<torture_nprocs;i++) {
4044 if (!child_status_out[i]) {
4051 #define FLAG_MULTIPROC 1
4058 {"FDPASS", run_fdpasstest, 0},
4059 {"LOCK1", run_locktest1, 0},
4060 {"LOCK2", run_locktest2, 0},
4061 {"LOCK3", run_locktest3, 0},
4062 {"LOCK4", run_locktest4, 0},
4063 {"LOCK5", run_locktest5, 0},
4064 {"LOCK6", run_locktest6, 0},
4065 {"LOCK7", run_locktest7, 0},
4066 {"UNLINK", run_unlinktest, 0},
4067 {"ATTR", run_attrtest, 0},
4068 {"TRANS2", run_trans2test, 0},
4069 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
4070 {"TORTURE",run_torture, FLAG_MULTIPROC},
4071 {"NEGNOWAIT", run_negprot_nowait, 0},
4072 {"NBENCH", torture_nbench, 0},
4073 {"DIR", run_dirtest, 0},
4074 {"DIR1", run_dirtest1, 0},
4075 {"DENY1", torture_denytest1, 0},
4076 {"DENY2", torture_denytest2, 0},
4077 {"TCON", run_tcon_test, 0},
4078 {"TCONDEV", run_tcon_devtype_test, 0},
4079 {"VUID", run_vuidtest, 0},
4081 {"DFSBASIC", torture_dfs_basic, 0},
4082 {"DFSRENAME", torture_dfs_rename, 0},
4083 {"DFSRANDOM", torture_dfs_random, 0},
4085 {"RW1", run_readwritetest, 0},
4086 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
4087 {"OPEN", run_opentest, 0},
4088 {"DENY3", run_deny3test, 0},
4090 {"OPENATTR", run_openattrtest, 0},
4092 {"XCOPY", run_xcopy, 0},
4093 {"RENAME", run_rename, 0},
4094 {"DELETE", run_deletetest, 0},
4095 {"PROPERTIES", run_properties, 0},
4096 {"MANGLE", torture_mangle, 0},
4097 {"UTABLE", torture_utable, 0},
4098 {"CASETABLE", torture_casetable, 0},
4099 {"CHARSET", torture_charset, 0},
4100 {"PIPE_NUMBER", run_pipe_number, 0},
4101 {"IOCTL", torture_ioctl_test, 0},
4102 {"CHKPATH", torture_chkpath_test, 0},
4103 {"HOLDCON", torture_holdcon, 0},
4104 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
4105 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
4106 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
4107 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
4108 {"RAW-SEARCH", torture_raw_search, 0},
4109 {"RAW-CLOSE", torture_raw_close, 0},
4110 {"RAW-OPEN", torture_raw_open, 0},
4111 {"RAW-MKDIR", torture_raw_mkdir, 0},
4112 {"RAW-OPLOCK", torture_raw_oplock, 0},
4113 {"RAW-NOTIFY", torture_raw_notify, 0},
4114 {"RAW-MUX", torture_raw_mux, 0},
4115 {"RAW-IOCTL", torture_raw_ioctl, 0},
4116 {"RAW-CHKPATH", torture_raw_chkpath, 0},
4117 {"RAW-UNLINK", torture_raw_unlink, 0},
4118 {"RAW-READ", torture_raw_read, 0},
4119 {"RAW-WRITE", torture_raw_write, 0},
4120 {"RAW-LOCK", torture_raw_lock, 0},
4121 {"RAW-CONTEXT", torture_raw_context, 0},
4122 {"RAW-RENAME", torture_raw_rename, 0},
4123 {"RAW-SEEK", torture_raw_seek, 0},
4124 {"SCAN-TRANS2", torture_trans2_scan, 0},
4125 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
4126 {"SCAN-ALIASES", torture_trans2_aliases, 0},
4127 {"SCAN-SMB", torture_smb_scan, 0},
4128 {"RPC-LSA", torture_rpc_lsa, 0},
4129 {"RPC-ECHO", torture_rpc_echo, 0},
4130 {"RPC-DFS", torture_rpc_dfs, 0},
4131 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
4132 {"RPC-SAMR", torture_rpc_samr, 0},
4133 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
4134 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
4135 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
4136 {"RPC-ATSVC", torture_rpc_atsvc, 0},
4137 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
4138 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
4139 {"RPC-WINREG", torture_rpc_winreg, 0},
4140 {"RPC-MGMT", torture_rpc_mgmt, 0},
4141 {"RPC-SCANNER", torture_rpc_scanner, 0},
4142 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
4143 /* {"NTLMSSP-SELFCHECK", torture_ntlmssp_self_check, 0},*/
4148 /****************************************************************************
4149 run a specified test or "ALL"
4150 ****************************************************************************/
4151 static BOOL run_test(const char *name)
4155 BOOL matched = False;
4157 if (strequal(name,"ALL")) {
4158 for (i=0;torture_ops[i].name;i++) {
4159 if (!run_test(torture_ops[i].name)) {
4166 for (i=0;torture_ops[i].name;i++) {
4167 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
4170 printf("Running %s\n", torture_ops[i].name);
4171 if (torture_ops[i].flags & FLAG_MULTIPROC) {
4173 t = torture_create_procs(torture_ops[i].fn, &result);
4176 printf("TEST %s FAILED!\n", torture_ops[i].name);
4181 if (!torture_ops[i].fn(0)) {
4183 printf("TEST %s FAILED!\n", torture_ops[i].name);
4187 printf("%s took %g secs\n\n", torture_ops[i].name, t);
4192 printf("Unknown torture operation '%s'\n", name);
4200 parse a username%password
4202 static void parse_user(const char *user)
4204 char *username, *password = NULL, *p;
4206 username = strdup(user);
4207 p = strchr_m(username,'%');
4210 password = strdup(p+1);
4213 lp_set_cmdline("torture:username", username);
4216 lp_set_cmdline("torture:password", password);
4219 if (!lp_parm_string(-1,"torture","password")) {
4220 password = getpass("password:");
4222 lp_set_cmdline("torture:password", password);
4226 static void usage(void)
4230 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
4232 printf("\t-d debuglevel\n");
4233 printf("\t-U user%%pass\n");
4234 printf("\t-k use kerberos\n");
4235 printf("\t-N numprocs\n");
4236 printf("\t-n my_netbios_name\n");
4237 printf("\t-W workgroup\n");
4238 printf("\t-o num_operations\n");
4239 printf("\t-e num files(entries)\n");
4240 printf("\t-O socket_options\n");
4241 printf("\t-m maximum protocol\n");
4242 printf("\t-L use oplocks\n");
4243 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
4244 printf("\t-t timelimit specify NBENCH time limit (seconds)\n");
4245 printf("\t-C filename specifies file with list of UNCs for connections\n");
4246 printf("\t-A showall\n");
4247 printf("\t-p port\n");
4248 printf("\t-s seed\n");
4249 printf("\t-f max failures\n");
4250 printf("\t-b bypass I/O (NBENCH)\n");
4251 printf("\t-X enable dangerous tests\n");
4254 printf("tests are:");
4255 for (i=0;torture_ops[i].name;i++) {
4256 printf(" %s", torture_ops[i].name);
4260 printf("default test is ALL\n");
4265 /****************************************************************************
4267 ****************************************************************************/
4268 int main(int argc,char *argv[])
4272 BOOL correct = True;
4273 char *host, *share, *username;
4275 setup_logging("smbtorture", DEBUG_STDOUT);
4277 #ifdef HAVE_SETBUFFER
4278 setbuffer(stdout, NULL, 0);
4281 lp_load(dyn_CONFIGFILE,True,False,False);
4288 for(p = argv[1]; *p; p++)
4293 /* see if its a RPC transport specifier */
4294 if (strncmp(argv[1], "ncacn_", 6) == 0) {
4295 lp_set_cmdline("torture:binding", argv[1]);
4297 char *binding = NULL;
4299 if (!parse_unc(argv[1], &host, &share)) {
4303 lp_set_cmdline("torture:host", host);
4304 lp_set_cmdline("torture:share", share);
4305 lp_set_cmdline("torture:password", "");
4306 asprintf(&binding, "ncacn_np:%s", host);
4307 lp_set_cmdline("torture:binding", binding);
4310 if (getenv("LOGNAME")) {
4311 username = strdup(getenv("LOGNAME"));
4313 lp_set_cmdline("torture:username", username);
4319 srandom(time(NULL));
4321 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:e:m:Ld:Ac:ks:f:s:t:C:X")) != EOF) {
4324 lp_set_cmdline("smb ports", optarg);
4327 lp_set_cmdline("workgroup", optarg);
4330 lp_set_cmdline("protocol", optarg);
4333 lp_set_cmdline("netbios name", optarg);
4336 lp_set_cmdline("debug level", optarg);
4337 setup_logging(NULL, DEBUG_STDOUT);
4340 lp_set_cmdline("socket options", optarg);
4343 srandom(atoi(optarg));
4346 torture_nprocs = atoi(optarg);
4349 torture_numops = atoi(optarg);
4352 torture_entries = atoi(optarg);
4358 torture_showall = True;
4361 lp_set_cmdline("torture:loadfile", optarg);
4364 lp_set_cmdline("torture:unclist", optarg);
4367 lp_set_cmdline("torture:timelimit", optarg);
4371 use_kerberos = True;
4373 d_printf("No kerberos support compiled in\n");
4381 torture_failures = atoi(optarg);
4385 lp_set_cmdline("torture:dangerous", "1");
4389 printf("Unknown option %c (%d)\n", (char)opt, opt);
4394 if (!lp_parm_string(-1,"torture","password")) {
4395 lp_set_cmdline("torture:password", "");
4398 if (argc == optind) {
4399 printf("You must specify a test to run, or 'ALL'\n");
4401 for (i=optind;i<argc;i++) {
4402 if (!run_test(argv[i])) {