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 const 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 const char *username = lp_parm_string(-1, "torture", "username");
93 const 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 const char *host = lp_parm_string(-1, "torture", "host");
118 const 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 const char *binding = lp_parm_string(-1, "torture", "binding");
151 printf("You must specify a ncacn binding string\n");
152 return NT_STATUS_INVALID_PARAMETER;
155 status = dcerpc_pipe_connect(p, binding, pipe_uuid, pipe_version,
157 lp_parm_string(-1, "torture", "username"),
158 lp_parm_string(-1, "torture", "password"));
163 /* close a rpc connection to a named pipe */
164 NTSTATUS torture_rpc_close(struct dcerpc_pipe *p)
166 dcerpc_pipe_close(p);
171 /* check if the server produced the expected error code */
172 static BOOL check_error(int line, struct cli_state *c,
173 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
175 if (cli_is_dos_error(c->tree)) {
179 /* Check DOS error */
181 cli_dos_error(c, &class, &num);
183 if (eclass != class || ecode != num) {
184 printf("unexpected error code class=%d code=%d\n",
185 (int)class, (int)num);
186 printf(" expected %d/%d %s (line=%d)\n",
187 (int)eclass, (int)ecode, nt_errstr(nterr), line);
196 status = cli_nt_error(c->tree);
198 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
199 printf("unexpected error code %s\n", nt_errstr(status));
200 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
209 static BOOL wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
211 while (NT_STATUS_IS_ERR(cli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
212 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
218 static BOOL rw_torture(struct cli_state *c)
220 const char *lockfname = "\\torture.lck";
224 pid_t pid2, pid = getpid();
229 fnum2 = cli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
232 fnum2 = cli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
234 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c->tree));
239 for (i=0;i<torture_numops;i++) {
240 uint_t n = (uint_t)sys_random()%10;
242 printf("%d\r", i); fflush(stdout);
244 asprintf(&fname, "\\torture.%u", n);
246 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
250 fnum = cli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
252 printf("open failed (%s)\n", cli_errstr(c->tree));
257 if (cli_write(c->tree, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
258 printf("write failed (%s)\n", cli_errstr(c->tree));
263 if (cli_write(c->tree, fnum, 0, (char *)buf,
264 sizeof(pid)+(j*sizeof(buf)),
265 sizeof(buf)) != sizeof(buf)) {
266 printf("write failed (%s)\n", cli_errstr(c->tree));
273 if (cli_read(c->tree, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
274 printf("read failed (%s)\n", cli_errstr(c->tree));
279 printf("data corruption!\n");
283 if (NT_STATUS_IS_ERR(cli_close(c->tree, fnum))) {
284 printf("close failed (%s)\n", cli_errstr(c->tree));
288 if (NT_STATUS_IS_ERR(cli_unlink(c->tree, fname))) {
289 printf("unlink failed (%s)\n", cli_errstr(c->tree));
293 if (NT_STATUS_IS_ERR(cli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
294 printf("unlock failed (%s)\n", cli_errstr(c->tree));
300 cli_close(c->tree, fnum2);
301 cli_unlink(c->tree, lockfname);
308 static BOOL run_torture(struct cli_state *cli, int dummy)
312 ret = rw_torture(cli);
314 if (!torture_close_connection(cli)) {
321 static BOOL rw_torture3(struct cli_state *c, const char *lockfname)
328 uint_t countprev = 0;
333 for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
335 SIVAL(buf, i, sys_random());
340 fnum = cli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
343 printf("first open read/write of %s failed (%s)\n",
344 lockfname, cli_errstr(c->tree));
350 for (i = 0; i < 500 && fnum == -1; i++)
352 fnum = cli_open(c->tree, lockfname, O_RDONLY,
357 printf("second open read-only of %s failed (%s)\n",
358 lockfname, cli_errstr(c->tree));
364 for (count = 0; count < sizeof(buf); count += sent)
366 if (count >= countprev) {
367 printf("%d %8d\r", i, count);
370 countprev += (sizeof(buf) / 20);
375 sent = ((uint_t)sys_random()%(20))+ 1;
376 if (sent > sizeof(buf) - count)
378 sent = sizeof(buf) - count;
381 if (cli_write(c->tree, fnum, 0, buf+count, count, (size_t)sent) != sent) {
382 printf("write failed (%s)\n", cli_errstr(c->tree));
388 sent = cli_read(c->tree, fnum, buf_rd+count, count,
392 printf("read failed offset:%d size:%d (%s)\n",
393 count, sizeof(buf)-count,
394 cli_errstr(c->tree));
400 if (memcmp(buf_rd+count, buf+count, sent) != 0)
402 printf("read/write compare failed\n");
403 printf("offset: %d req %d recvd %d\n",
404 count, sizeof(buf)-count, sent);
413 if (NT_STATUS_IS_ERR(cli_close(c->tree, fnum))) {
414 printf("close failed (%s)\n", cli_errstr(c->tree));
421 static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
423 const char *lockfname = "\\torture2.lck";
428 uint8_t buf_rd[131072];
430 ssize_t bytes_read, bytes_written;
432 if (cli_deltree(c1->tree, lockfname) == -1) {
433 printf("unlink failed (%s)\n", cli_errstr(c1->tree));
436 fnum1 = cli_open(c1->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
439 printf("first open read/write of %s failed (%s)\n",
440 lockfname, cli_errstr(c1->tree));
443 fnum2 = cli_open(c2->tree, lockfname, O_RDONLY,
446 printf("second open read-only of %s failed (%s)\n",
447 lockfname, cli_errstr(c2->tree));
448 cli_close(c1->tree, fnum1);
452 printf("Checking data integrity over %d ops\n", torture_numops);
454 for (i=0;i<torture_numops;i++)
456 size_t buf_size = ((uint_t)sys_random()%(sizeof(buf)-1))+ 1;
458 printf("%d\r", i); fflush(stdout);
461 generate_random_buffer(buf, buf_size, False);
463 if ((bytes_written = cli_write(c1->tree, fnum1, 0, buf, 0, buf_size)) != buf_size) {
464 printf("write failed (%s)\n", cli_errstr(c1->tree));
465 printf("wrote %d, expected %d\n", bytes_written, buf_size);
470 if ((bytes_read = cli_read(c2->tree, fnum2, buf_rd, 0, buf_size)) != buf_size) {
471 printf("read failed (%s)\n", cli_errstr(c2->tree));
472 printf("read %d, expected %d\n", bytes_read, buf_size);
477 if (memcmp(buf_rd, buf, buf_size) != 0)
479 printf("read/write compare failed\n");
485 if (NT_STATUS_IS_ERR(cli_close(c2->tree, fnum2))) {
486 printf("close failed (%s)\n", cli_errstr(c2->tree));
489 if (NT_STATUS_IS_ERR(cli_close(c1->tree, fnum1))) {
490 printf("close failed (%s)\n", cli_errstr(c1->tree));
494 if (NT_STATUS_IS_ERR(cli_unlink(c1->tree, lockfname))) {
495 printf("unlink failed (%s)\n", cli_errstr(c1->tree));
502 static BOOL run_readwritetest(int dummy)
504 struct cli_state *cli1, *cli2;
505 BOOL test1, test2 = True;
507 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
511 printf("starting readwritetest\n");
513 test1 = rw_torture2(cli1, cli2);
514 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
517 test2 = rw_torture2(cli1, cli1);
518 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
521 if (!torture_close_connection(cli1)) {
525 if (!torture_close_connection(cli2)) {
529 return (test1 && test2);
532 static BOOL run_readwritemulti(struct cli_state *cli, int dummy)
536 test = rw_torture3(cli, "\\multitest.txt");
538 if (!torture_close_connection(cli)) {
547 This test checks for two things:
549 1) correct support for retaining locks over a close (ie. the server
550 must not use posix semantics)
551 2) support for lock timeouts
553 static BOOL run_locktest1(int dummy)
555 struct cli_state *cli1, *cli2;
556 const char *fname = "\\lockt1.lck";
557 int fnum1, fnum2, fnum3;
561 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
565 printf("starting locktest1\n");
567 cli_unlink(cli1->tree, fname);
569 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
571 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
574 fnum2 = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
576 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
579 fnum3 = cli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
581 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
585 if (NT_STATUS_IS_ERR(cli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
586 printf("lock1 failed (%s)\n", cli_errstr(cli1->tree));
591 if (NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
592 printf("lock2 succeeded! This is a locking bug\n");
595 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
596 NT_STATUS_LOCK_NOT_GRANTED)) return False;
600 lock_timeout = (6 + (random() % 20));
601 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
603 if (NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK))) {
604 printf("lock3 succeeded! This is a locking bug\n");
607 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
608 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
613 printf("error: This server appears not to support timed lock requests\n");
615 printf("server slept for %u seconds for a %u second timeout\n",
616 (uint_t)(t2-t1), lock_timeout);
618 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum2))) {
619 printf("close1 failed (%s)\n", cli_errstr(cli1->tree));
623 if (NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
624 printf("lock4 succeeded! This is a locking bug\n");
627 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
628 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
631 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
632 printf("close2 failed (%s)\n", cli_errstr(cli1->tree));
636 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum3))) {
637 printf("close3 failed (%s)\n", cli_errstr(cli2->tree));
641 if (NT_STATUS_IS_ERR(cli_unlink(cli1->tree, fname))) {
642 printf("unlink failed (%s)\n", cli_errstr(cli1->tree));
647 if (!torture_close_connection(cli1)) {
651 if (!torture_close_connection(cli2)) {
655 printf("Passed locktest1\n");
660 this checks to see if a secondary tconx can use open files from an
663 static BOOL run_tcon_test(int dummy)
665 struct cli_state *cli;
666 const char *fname = "\\tcontest.tmp";
668 uint16_t cnum1, cnum2, cnum3;
669 uint16_t vuid1, vuid2;
672 struct cli_tree *tree1;
673 const char *host = lp_parm_string(-1, "torture", "host");
674 const char *share = lp_parm_string(-1, "torture", "share");
675 const 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 const 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 const char *host = lp_parm_string(-1, "torture", "host");
826 const char *share = lp_parm_string(-1, "torture", "share");
827 const char *username = lp_parm_string(-1, "torture", "username");
828 const char *password = lp_parm_string(-1, "torture", "password");
830 status = cli_full_connection(&cli1, lp_netbios_name(),
833 username, lp_workgroup(),
834 password, flags, &retry);
836 if (!NT_STATUS_IS_OK(status)) {
837 printf("could not open connection\n");
841 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
844 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
847 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
850 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
853 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
856 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
859 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
862 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
865 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
868 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
874 printf("Passed tcondevtest\n");
881 This test checks that
883 1) the server supports multiple locking contexts on the one SMB
884 connection, distinguished by PID.
886 2) the server correctly fails overlapping locks made by the same PID (this
887 goes against POSIX behaviour, which is why it is tricky to implement)
889 3) the server denies unlock requests by an incorrect client PID
891 static BOOL run_locktest2(int dummy)
893 struct cli_state *cli;
894 const char *fname = "\\lockt2.lck";
895 int fnum1, fnum2, fnum3;
898 if (!torture_open_connection(&cli)) {
902 printf("starting locktest2\n");
904 cli_unlink(cli->tree, fname);
906 printf("Testing pid context\n");
908 cli->session->pid = 1;
910 fnum1 = cli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
912 printf("open of %s failed (%s)\n", fname, cli_errstr(cli->tree));
916 fnum2 = cli_open(cli->tree, fname, O_RDWR, DENY_NONE);
918 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli->tree));
922 cli->session->pid = 2;
924 fnum3 = cli_open(cli->tree, fname, O_RDWR, DENY_NONE);
926 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli->tree));
930 cli->session->pid = 1;
932 if (NT_STATUS_IS_ERR(cli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
933 printf("lock1 failed (%s)\n", cli_errstr(cli->tree));
937 if (NT_STATUS_IS_OK(cli_lock(cli->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
938 printf("WRITE lock1 succeeded! This is a locking bug\n");
941 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
942 NT_STATUS_LOCK_NOT_GRANTED)) return False;
945 if (NT_STATUS_IS_OK(cli_lock(cli->tree, fnum2, 0, 4, 0, WRITE_LOCK))) {
946 printf("WRITE lock2 succeeded! This is a locking bug\n");
949 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
950 NT_STATUS_LOCK_NOT_GRANTED)) return False;
953 if (NT_STATUS_IS_OK(cli_lock(cli->tree, fnum2, 0, 4, 0, READ_LOCK))) {
954 printf("READ lock2 succeeded! This is a locking bug\n");
957 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
958 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
961 if (NT_STATUS_IS_ERR(cli_lock(cli->tree, fnum1, 100, 4, 0, WRITE_LOCK))) {
962 printf("lock at 100 failed (%s)\n", cli_errstr(cli->tree));
965 cli->session->pid = 2;
967 if (NT_STATUS_IS_OK(cli_unlock(cli->tree, fnum1, 100, 4))) {
968 printf("unlock at 100 succeeded! This is a locking bug\n");
972 if (NT_STATUS_IS_OK(cli_unlock(cli->tree, fnum1, 0, 4))) {
973 printf("unlock1 succeeded! This is a locking bug\n");
976 if (!check_error(__LINE__, cli,
978 NT_STATUS_RANGE_NOT_LOCKED)) return False;
981 if (NT_STATUS_IS_OK(cli_unlock(cli->tree, fnum1, 0, 8))) {
982 printf("unlock2 succeeded! This is a locking bug\n");
985 if (!check_error(__LINE__, cli,
987 NT_STATUS_RANGE_NOT_LOCKED)) return False;
990 if (NT_STATUS_IS_OK(cli_lock(cli->tree, fnum3, 0, 4, 0, WRITE_LOCK))) {
991 printf("lock3 succeeded! This is a locking bug\n");
994 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
997 cli->session->pid = 1;
999 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum1))) {
1000 printf("close1 failed (%s)\n", cli_errstr(cli->tree));
1004 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum2))) {
1005 printf("close2 failed (%s)\n", cli_errstr(cli->tree));
1009 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum3))) {
1010 printf("close3 failed (%s)\n", cli_errstr(cli->tree));
1014 if (!torture_close_connection(cli)) {
1018 printf("locktest2 finished\n");
1025 This test checks that
1027 1) the server supports the full offset range in lock requests
1029 static BOOL run_locktest3(int dummy)
1031 struct cli_state *cli1, *cli2;
1032 const char *fname = "\\lockt3.lck";
1033 int fnum1, fnum2, i;
1035 BOOL correct = True;
1037 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1039 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1043 printf("starting locktest3\n");
1045 printf("Testing 32 bit offset ranges\n");
1047 cli_unlink(cli1->tree, fname);
1049 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1051 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
1054 fnum2 = cli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1056 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
1060 printf("Establishing %d locks\n", torture_numops);
1062 for (offset=i=0;i<torture_numops;i++) {
1064 if (NT_STATUS_IS_ERR(cli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
1065 printf("lock1 %d failed (%s)\n",
1067 cli_errstr(cli1->tree));
1071 if (NT_STATUS_IS_ERR(cli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
1072 printf("lock2 %d failed (%s)\n",
1074 cli_errstr(cli1->tree));
1079 printf("Testing %d locks\n", torture_numops);
1081 for (offset=i=0;i<torture_numops;i++) {
1084 if (NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, offset-2, 1, 0, WRITE_LOCK))) {
1085 printf("error: lock1 %d succeeded!\n", i);
1089 if (NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum2, offset-1, 1, 0, WRITE_LOCK))) {
1090 printf("error: lock2 %d succeeded!\n", i);
1094 if (NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, offset-1, 1, 0, WRITE_LOCK))) {
1095 printf("error: lock3 %d succeeded!\n", i);
1099 if (NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum2, offset-2, 1, 0, WRITE_LOCK))) {
1100 printf("error: lock4 %d succeeded!\n", i);
1105 printf("Removing %d locks\n", torture_numops);
1107 for (offset=i=0;i<torture_numops;i++) {
1110 if (NT_STATUS_IS_ERR(cli_unlock(cli1->tree, fnum1, offset-1, 1))) {
1111 printf("unlock1 %d failed (%s)\n",
1113 cli_errstr(cli1->tree));
1117 if (NT_STATUS_IS_ERR(cli_unlock(cli2->tree, fnum2, offset-2, 1))) {
1118 printf("unlock2 %d failed (%s)\n",
1120 cli_errstr(cli1->tree));
1125 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
1126 printf("close1 failed (%s)\n", cli_errstr(cli1->tree));
1130 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
1131 printf("close2 failed (%s)\n", cli_errstr(cli2->tree));
1135 if (NT_STATUS_IS_ERR(cli_unlink(cli1->tree, fname))) {
1136 printf("unlink failed (%s)\n", cli_errstr(cli1->tree));
1140 if (!torture_close_connection(cli1)) {
1144 if (!torture_close_connection(cli2)) {
1148 printf("finished locktest3\n");
1153 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1154 printf("** "); correct = False; \
1158 looks at overlapping locks
1160 static BOOL run_locktest4(int dummy)
1162 struct cli_state *cli1, *cli2;
1163 const char *fname = "\\lockt4.lck";
1164 int fnum1, fnum2, f;
1167 BOOL correct = True;
1169 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1173 printf("starting locktest4\n");
1175 cli_unlink(cli1->tree, fname);
1177 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1178 fnum2 = cli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1180 memset(buf, 0, sizeof(buf));
1182 if (cli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1183 printf("Failed to create file\n");
1188 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1189 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 2, 4, 0, WRITE_LOCK));
1190 EXPECTED(ret, False);
1191 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1193 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 10, 4, 0, READ_LOCK)) &&
1194 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 12, 4, 0, READ_LOCK));
1195 EXPECTED(ret, True);
1196 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1198 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1199 NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum2, 22, 4, 0, WRITE_LOCK));
1200 EXPECTED(ret, False);
1201 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1203 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 30, 4, 0, READ_LOCK)) &&
1204 NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum2, 32, 4, 0, READ_LOCK));
1205 EXPECTED(ret, True);
1206 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1208 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, cli_lock(cli1->tree, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1209 NT_STATUS_IS_OK((cli1->session->pid = 2, cli_lock(cli1->tree, fnum1, 42, 4, 0, WRITE_LOCK)));
1210 EXPECTED(ret, False);
1211 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1213 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, cli_lock(cli1->tree, fnum1, 50, 4, 0, READ_LOCK))) &&
1214 NT_STATUS_IS_OK((cli1->session->pid = 2, cli_lock(cli1->tree, fnum1, 52, 4, 0, READ_LOCK)));
1215 EXPECTED(ret, True);
1216 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1218 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK)) &&
1219 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 60, 4, 0, READ_LOCK));
1220 EXPECTED(ret, True);
1221 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1223 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1224 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 70, 4, 0, WRITE_LOCK));
1225 EXPECTED(ret, False);
1226 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1228 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 80, 4, 0, READ_LOCK)) &&
1229 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 80, 4, 0, WRITE_LOCK));
1230 EXPECTED(ret, False);
1231 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1233 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 90, 4, 0, WRITE_LOCK)) &&
1234 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 90, 4, 0, READ_LOCK));
1235 EXPECTED(ret, True);
1236 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1238 ret = NT_STATUS_IS_OK((cli1->session->pid = 1, cli_lock(cli1->tree, fnum1, 100, 4, 0, WRITE_LOCK))) &&
1239 NT_STATUS_IS_OK((cli1->session->pid = 2, cli_lock(cli1->tree, fnum1, 100, 4, 0, READ_LOCK)));
1240 EXPECTED(ret, False);
1241 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1243 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 110, 4, 0, READ_LOCK)) &&
1244 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 112, 4, 0, READ_LOCK)) &&
1245 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 110, 6));
1246 EXPECTED(ret, False);
1247 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1250 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 120, 4, 0, WRITE_LOCK)) &&
1251 (cli_read(cli2->tree, fnum2, buf, 120, 4) == 4);
1252 EXPECTED(ret, False);
1253 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1255 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK)) &&
1256 (cli_write(cli2->tree, fnum2, 0, buf, 130, 4) == 4);
1257 EXPECTED(ret, False);
1258 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1261 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
1262 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 140, 4, 0, READ_LOCK)) &&
1263 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 140, 4)) &&
1264 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 140, 4));
1265 EXPECTED(ret, True);
1266 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1269 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 150, 4, 0, WRITE_LOCK)) &&
1270 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 150, 4, 0, READ_LOCK)) &&
1271 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 150, 4)) &&
1272 (cli_read(cli2->tree, fnum2, buf, 150, 4) == 4) &&
1273 !(cli_write(cli2->tree, fnum2, 0, buf, 150, 4) == 4) &&
1274 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 150, 4));
1275 EXPECTED(ret, True);
1276 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1278 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 160, 4, 0, READ_LOCK)) &&
1279 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 160, 4)) &&
1280 (cli_write(cli2->tree, fnum2, 0, buf, 160, 4) == 4) &&
1281 (cli_read(cli2->tree, fnum2, buf, 160, 4) == 4);
1282 EXPECTED(ret, True);
1283 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1285 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 170, 4, 0, WRITE_LOCK)) &&
1286 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 170, 4)) &&
1287 (cli_write(cli2->tree, fnum2, 0, buf, 170, 4) == 4) &&
1288 (cli_read(cli2->tree, fnum2, buf, 170, 4) == 4);
1289 EXPECTED(ret, True);
1290 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1292 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 190, 4, 0, WRITE_LOCK)) &&
1293 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 190, 4, 0, READ_LOCK)) &&
1294 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 190, 4)) &&
1295 !(cli_write(cli2->tree, fnum2, 0, buf, 190, 4) == 4) &&
1296 (cli_read(cli2->tree, fnum2, buf, 190, 4) == 4);
1297 EXPECTED(ret, True);
1298 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1300 cli_close(cli1->tree, fnum1);
1301 cli_close(cli2->tree, fnum2);
1302 fnum1 = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1303 f = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1304 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
1305 NT_STATUS_IS_OK(cli_lock(cli1->tree, f, 0, 1, 0, READ_LOCK)) &&
1306 NT_STATUS_IS_OK(cli_close(cli1->tree, fnum1)) &&
1307 ((fnum1 = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE)) != -1) &&
1308 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
1309 cli_close(cli1->tree, f);
1310 cli_close(cli1->tree, fnum1);
1311 EXPECTED(ret, True);
1312 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1315 cli_close(cli1->tree, fnum1);
1316 cli_close(cli2->tree, fnum2);
1317 cli_unlink(cli1->tree, fname);
1318 torture_close_connection(cli1);
1319 torture_close_connection(cli2);
1321 printf("finished locktest4\n");
1326 looks at lock upgrade/downgrade.
1328 static BOOL run_locktest5(int dummy)
1330 struct cli_state *cli1, *cli2;
1331 const char *fname = "\\lockt5.lck";
1332 int fnum1, fnum2, fnum3;
1335 BOOL correct = True;
1337 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1341 printf("starting locktest5\n");
1343 cli_unlink(cli1->tree, fname);
1345 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1346 fnum2 = cli_open(cli2->tree, fname, O_RDWR, DENY_NONE);
1347 fnum3 = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1349 memset(buf, 0, sizeof(buf));
1351 if (cli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1352 printf("Failed to create file\n");
1357 /* Check for NT bug... */
1358 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 0, 8, 0, READ_LOCK)) &&
1359 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum3, 0, 1, 0, READ_LOCK));
1360 cli_close(cli1->tree, fnum1);
1361 fnum1 = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1362 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 7, 1, 0, WRITE_LOCK));
1363 EXPECTED(ret, True);
1364 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1365 cli_close(cli1->tree, fnum1);
1366 fnum1 = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
1367 cli_unlock(cli1->tree, fnum3, 0, 1);
1369 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1370 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 1, 1, 0, READ_LOCK));
1371 EXPECTED(ret, True);
1372 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1374 ret = NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
1375 EXPECTED(ret, False);
1377 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1379 /* Unlock the process 2 lock. */
1380 cli_unlock(cli2->tree, fnum2, 0, 4);
1382 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum3, 0, 4, 0, READ_LOCK));
1383 EXPECTED(ret, False);
1385 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1387 /* Unlock the process 1 fnum3 lock. */
1388 cli_unlock(cli1->tree, fnum3, 0, 4);
1390 /* Stack 2 more locks here. */
1391 ret = NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK)) &&
1392 NT_STATUS_IS_OK(cli_lock(cli1->tree, fnum1, 0, 4, 0, READ_LOCK));
1394 EXPECTED(ret, True);
1395 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1397 /* Unlock the first process lock, then check this was the WRITE lock that was
1400 ret = NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 0, 4)) &&
1401 NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum2, 0, 4, 0, READ_LOCK));
1403 EXPECTED(ret, True);
1404 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1406 /* Unlock the process 2 lock. */
1407 cli_unlock(cli2->tree, fnum2, 0, 4);
1409 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1411 ret = NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 1, 1)) &&
1412 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 0, 4)) &&
1413 NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 0, 4));
1415 EXPECTED(ret, True);
1416 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1418 /* Ensure the next unlock fails. */
1419 ret = NT_STATUS_IS_OK(cli_unlock(cli1->tree, fnum1, 0, 4));
1420 EXPECTED(ret, False);
1421 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1423 /* Ensure connection 2 can get a write lock. */
1424 ret = NT_STATUS_IS_OK(cli_lock(cli2->tree, fnum2, 0, 4, 0, WRITE_LOCK));
1425 EXPECTED(ret, True);
1427 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1431 cli_close(cli1->tree, fnum1);
1432 cli_close(cli2->tree, fnum2);
1433 cli_unlink(cli1->tree, fname);
1434 if (!torture_close_connection(cli1)) {
1437 if (!torture_close_connection(cli2)) {
1441 printf("finished locktest5\n");
1447 tries the unusual lockingX locktype bits
1449 static BOOL run_locktest6(int dummy)
1451 struct cli_state *cli;
1452 const char *fname[1] = { "\\lock6.txt" };
1457 if (!torture_open_connection(&cli)) {
1461 printf("starting locktest6\n");
1464 printf("Testing %s\n", fname[i]);
1466 cli_unlink(cli->tree, fname[i]);
1468 fnum = cli_open(cli->tree, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1469 status = cli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1470 cli_close(cli->tree, fnum);
1471 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1473 fnum = cli_open(cli->tree, fname[i], O_RDWR, DENY_NONE);
1474 status = cli_locktype(cli->tree, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1475 cli_close(cli->tree, fnum);
1476 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1478 cli_unlink(cli->tree, fname[i]);
1481 torture_close_connection(cli);
1483 printf("finished locktest6\n");
1487 static BOOL run_locktest7(int dummy)
1489 struct cli_state *cli1;
1490 const char *fname = "\\lockt7.lck";
1495 BOOL correct = False;
1497 if (!torture_open_connection(&cli1)) {
1501 printf("starting locktest7\n");
1503 cli_unlink(cli1->tree, fname);
1505 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1507 memset(buf, 0, sizeof(buf));
1509 if (cli_write(cli1->tree, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1510 printf("Failed to create file\n");
1514 cli1->session->pid = 1;
1516 if (NT_STATUS_IS_ERR(cli_lock(cli1->tree, fnum1, 130, 4, 0, READ_LOCK))) {
1517 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1->tree));
1520 printf("pid1 successfully locked range 130:4 for READ\n");
1523 if (cli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1524 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1->tree));
1527 printf("pid1 successfully read the range 130:4\n");
1530 if (cli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1531 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1->tree));
1532 if (NT_STATUS_V(cli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1533 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1537 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1541 cli1->session->pid = 2;
1543 if (cli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1544 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1->tree));
1546 printf("pid2 successfully read the range 130:4\n");
1549 if (cli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1550 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1->tree));
1551 if (NT_STATUS_V(cli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1552 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1556 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1560 cli1->session->pid = 1;
1561 cli_unlock(cli1->tree, fnum1, 130, 4);
1563 if (NT_STATUS_IS_ERR(cli_lock(cli1->tree, fnum1, 130, 4, 0, WRITE_LOCK))) {
1564 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1->tree));
1567 printf("pid1 successfully locked range 130:4 for WRITE\n");
1570 if (cli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1571 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1->tree));
1574 printf("pid1 successfully read the range 130:4\n");
1577 if (cli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1578 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1->tree));
1581 printf("pid1 successfully wrote to the range 130:4\n");
1584 cli1->session->pid = 2;
1586 if (cli_read(cli1->tree, fnum1, buf, 130, 4) != 4) {
1587 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1->tree));
1588 if (NT_STATUS_V(cli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1589 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1593 printf("pid2 successfully read the range 130:4 (should be denied)\n");
1597 if (cli_write(cli1->tree, fnum1, 0, buf, 130, 4) != 4) {
1598 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1->tree));
1599 if (NT_STATUS_V(cli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1600 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1604 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1608 printf("Testing truncate of locked file.\n");
1610 fnum2 = cli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
1613 printf("Unable to truncate locked file.\n");
1617 printf("Truncated locked file.\n");
1620 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &size, NULL))) {
1621 printf("getatr failed (%s)\n", cli_errstr(cli1->tree));
1627 printf("Unable to truncate locked file. Size was %u\n", size);
1632 cli1->session->pid = 1;
1634 cli_unlock(cli1->tree, fnum1, 130, 4);
1638 cli_close(cli1->tree, fnum1);
1639 cli_close(cli1->tree, fnum2);
1640 cli_unlink(cli1->tree, fname);
1641 torture_close_connection(cli1);
1643 printf("finished locktest7\n");
1648 test whether fnums and tids open on one VC are available on another (a major
1651 static BOOL run_fdpasstest(int dummy)
1653 struct cli_state *cli1, *cli2;
1654 const char *fname = "\\fdpass.tst";
1658 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1662 printf("starting fdpasstest\n");
1664 cli_unlink(cli1->tree, fname);
1666 printf("Opening a file on connection 1\n");
1668 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1670 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
1674 printf("writing to file on connection 1\n");
1676 if (cli_write(cli1->tree, fnum1, 0, "hello world\n", 0, 13) != 13) {
1677 printf("write failed (%s)\n", cli_errstr(cli1->tree));
1681 oldtid = cli2->tree->tid;
1682 cli2->session->vuid = cli1->session->vuid;
1683 cli2->tree->tid = cli1->tree->tid;
1684 cli2->session->pid = cli1->session->pid;
1686 printf("reading from file on connection 2\n");
1688 if (cli_read(cli2->tree, fnum1, buf, 0, 13) == 13) {
1689 printf("read succeeded! nasty security hole [%s]\n",
1694 cli_close(cli1->tree, fnum1);
1695 cli_unlink(cli1->tree, fname);
1697 cli2->tree->tid = oldtid;
1699 torture_close_connection(cli1);
1700 torture_close_connection(cli2);
1702 printf("finished fdpasstest\n");
1708 This test checks that
1710 1) the server does not allow an unlink on a file that is open
1712 static BOOL run_unlinktest(int dummy)
1714 struct cli_state *cli;
1715 const char *fname = "\\unlink.tst";
1717 BOOL correct = True;
1719 if (!torture_open_connection(&cli)) {
1723 printf("starting unlink test\n");
1725 cli_unlink(cli->tree, fname);
1727 cli->session->pid = 1;
1729 printf("Opening a file\n");
1731 fnum = cli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1733 printf("open of %s failed (%s)\n", fname, cli_errstr(cli->tree));
1737 printf("Unlinking a open file\n");
1739 if (NT_STATUS_IS_OK(cli_unlink(cli->tree, fname))) {
1740 printf("error: server allowed unlink on an open file\n");
1743 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
1744 NT_STATUS_SHARING_VIOLATION);
1747 cli_close(cli->tree, fnum);
1748 cli_unlink(cli->tree, fname);
1750 if (!torture_close_connection(cli)) {
1754 printf("unlink test finished\n");
1761 test how many open files this server supports on the one socket
1764 static BOOL run_deferopen(struct cli_state *cli, int dummy)
1766 const char *fname = "\\defer_open_test.dat";
1769 BOOL correct = True;
1772 printf("failed to connect\n");
1776 printf("Testing deferred open requests.\n");
1782 struct timeval tv_start, tv_end;
1783 GetTimeOfDay(&tv_start);
1784 fnum = cli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
1785 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
1786 NTCREATEX_DISP_OPEN_IF, 0, 0);
1790 GetTimeOfDay(&tv_end);
1791 if (NT_STATUS_EQUAL(cli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
1792 /* Sharing violation errors need to be 1 second apart. */
1793 int64_t tdif = usec_time_diff(&tv_end, &tv_start);
1794 if (tdif < 500000 || tdif > 1500000) {
1795 fprintf(stderr,"Timing incorrect %lld.%lld for share violation\n",
1796 tdif / (int64_t)1000000,
1797 tdif % (int64_t)1000000);
1800 } while (NT_STATUS_EQUAL(cli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
1803 fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli->tree));
1807 printf("pid %u open %d\n", getpid(), i);
1811 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum))) {
1812 fprintf(stderr,"Failed to close %s, error=%s\n", fname, cli_errstr(cli->tree));
1818 if (NT_STATUS_IS_ERR(cli_unlink(cli->tree, fname))) {
1819 /* All until the last unlink will fail with sharing violation. */
1820 if (!NT_STATUS_EQUAL(cli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
1821 printf("unlink of %s failed (%s)\n", fname, cli_errstr(cli->tree));
1826 printf("deferred test finished\n");
1827 if (!torture_close_connection(cli)) {
1834 test how many open files this server supports on the one socket
1836 static BOOL run_maxfidtest(struct cli_state *cli, int dummy)
1838 const char *template = "\\maxfid.%d.%d";
1840 int fnums[0x11000], i;
1842 BOOL correct = True;
1845 printf("failed to connect\n");
1849 printf("Testing maximum number of open files\n");
1851 for (i=0; i<0x11000; i++) {
1852 asprintf(&fname, template, i,(int)getpid());
1853 if ((fnums[i] = cli_open(cli->tree, fname,
1854 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1856 printf("open of %s failed (%s)\n",
1857 fname, cli_errstr(cli->tree));
1858 printf("maximum fnum is %d\n", i);
1867 printf("cleaning up\n");
1869 asprintf(&fname, template, i,(int)getpid());
1870 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnums[i]))) {
1871 printf("Close of fnum %d failed - %s\n", fnums[i], cli_errstr(cli->tree));
1873 if (NT_STATUS_IS_ERR(cli_unlink(cli->tree, fname))) {
1874 printf("unlink of %s failed (%s)\n",
1875 fname, cli_errstr(cli->tree));
1883 printf("maxfid test finished\n");
1884 if (!torture_close_connection(cli)) {
1890 /* send smb negprot commands, not reading the response */
1891 static BOOL run_negprot_nowait(int dummy)
1894 struct cli_state *cli;
1895 BOOL correct = True;
1897 printf("starting negprot nowait test\n");
1899 cli = open_nbt_connection();
1904 printf("Establishing protocol negotiations - connect with another client\n");
1906 for (i=0;i<50000;i++) {
1907 smb_negprot_send(cli->transport, PROTOCOL_NT1);
1910 if (!torture_close_connection(cli)) {
1914 printf("finished negprot nowait test\n");
1921 This checks how the getatr calls works
1923 static BOOL run_attrtest(int dummy)
1925 struct cli_state *cli;
1928 const char *fname = "\\attrib123456789.tst";
1929 BOOL correct = True;
1931 printf("starting attrib test\n");
1933 if (!torture_open_connection(&cli)) {
1937 cli_unlink(cli->tree, fname);
1938 fnum = cli_open(cli->tree, fname,
1939 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1940 cli_close(cli->tree, fnum);
1942 if (NT_STATUS_IS_ERR(cli_getatr(cli->tree, fname, NULL, NULL, &t))) {
1943 printf("getatr failed (%s)\n", cli_errstr(cli->tree));
1947 printf("New file time is %s", ctime(&t));
1949 if (abs(t - time(NULL)) > 60*60*24*10) {
1950 printf("ERROR: SMBgetatr bug. time is %s",
1956 t2 = t-60*60*24; /* 1 day ago */
1958 printf("Setting file time to %s", ctime(&t2));
1960 if (NT_STATUS_IS_ERR(cli_setatr(cli->tree, fname, 0, t2))) {
1961 printf("setatr failed (%s)\n", cli_errstr(cli->tree));
1965 if (NT_STATUS_IS_ERR(cli_getatr(cli->tree, fname, NULL, NULL, &t))) {
1966 printf("getatr failed (%s)\n", cli_errstr(cli->tree));
1970 printf("Retrieved file time as %s", ctime(&t));
1973 printf("ERROR: getatr/setatr bug. times are\n%s",
1975 printf("%s", ctime(&t2));
1979 cli_unlink(cli->tree, fname);
1981 if (!torture_close_connection(cli)) {
1985 printf("attrib test finished\n");
1992 This checks a couple of trans2 calls
1994 static BOOL run_trans2test(int dummy)
1996 struct cli_state *cli;
1999 time_t c_time, a_time, m_time, w_time, m_time2;
2000 const char *fname = "\\trans2.tst";
2001 const char *dname = "\\trans2";
2002 const char *fname2 = "\\trans2\\trans2.tst";
2004 BOOL correct = True;
2006 printf("starting trans2 test\n");
2008 if (!torture_open_connection(&cli)) {
2012 cli_unlink(cli->tree, fname);
2014 printf("Testing qfileinfo\n");
2016 fnum = cli_open(cli->tree, fname,
2017 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2018 if (NT_STATUS_IS_ERR(cli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
2020 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli->tree));
2024 printf("Testing NAME_INFO\n");
2026 if (NT_STATUS_IS_ERR(cli_qfilename(cli->tree, fnum, &pname))) {
2027 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli->tree));
2031 if (!pname || strcmp(pname, fname)) {
2032 printf("qfilename gave different name? [%s] [%s]\n",
2037 cli_close(cli->tree, fnum);
2038 cli_unlink(cli->tree, fname);
2040 fnum = cli_open(cli->tree, fname,
2041 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2043 printf("open of %s failed (%s)\n", fname, cli_errstr(cli->tree));
2046 cli_close(cli->tree, fnum);
2048 printf("Checking for sticky create times\n");
2050 if (NT_STATUS_IS_ERR(cli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
2051 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli->tree));
2054 if (c_time != m_time) {
2055 printf("create time=%s", ctime(&c_time));
2056 printf("modify time=%s", ctime(&m_time));
2057 printf("This system appears to have sticky create times\n");
2059 if (a_time % (60*60) == 0) {
2060 printf("access time=%s", ctime(&a_time));
2061 printf("This system appears to set a midnight access time\n");
2065 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2066 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2072 cli_unlink(cli->tree, fname);
2073 fnum = cli_open(cli->tree, fname,
2074 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2075 cli_close(cli->tree, fnum);
2076 if (NT_STATUS_IS_ERR(cli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2077 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli->tree));
2080 if (w_time < 60*60*24*2) {
2081 printf("write time=%s", ctime(&w_time));
2082 printf("This system appears to set a initial 0 write time\n");
2087 cli_unlink(cli->tree, fname);
2090 /* check if the server updates the directory modification time
2091 when creating a new file */
2092 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, dname))) {
2093 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli->tree));
2097 if (NT_STATUS_IS_ERR(cli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2098 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli->tree));
2102 fnum = cli_open(cli->tree, fname2,
2103 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2104 cli_write(cli->tree, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2105 cli_close(cli->tree, fnum);
2106 if (NT_STATUS_IS_ERR(cli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
2107 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli->tree));
2110 if (m_time2 == m_time) {
2111 printf("This system does not update directory modification times\n");
2115 cli_unlink(cli->tree, fname2);
2116 cli_rmdir(cli->tree, dname);
2118 if (!torture_close_connection(cli)) {
2122 printf("trans2 test finished\n");
2128 Test delete on close semantics.
2130 static BOOL run_deletetest(int dummy)
2132 struct cli_state *cli1;
2133 struct cli_state *cli2 = NULL;
2134 const char *fname = "\\delete.file";
2137 BOOL correct = True;
2139 printf("starting delete test\n");
2141 if (!torture_open_connection(&cli1)) {
2145 /* Test 1 - this should delete the file on close. */
2147 cli_setatr(cli1->tree, fname, 0, 0);
2148 cli_unlink(cli1->tree, fname);
2150 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2151 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF,
2152 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2155 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2160 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2161 printf("[1] close failed (%s)\n", cli_errstr(cli1->tree));
2166 fnum1 = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
2168 printf("[1] open of %s succeeded (should fail)\n", fname);
2173 printf("first delete on close test succeeded.\n");
2175 /* Test 2 - this should delete the file on close. */
2177 cli_setatr(cli1->tree, fname, 0, 0);
2178 cli_unlink(cli1->tree, fname);
2180 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
2181 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
2182 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2185 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2190 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2191 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1->tree));
2196 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2197 printf("[2] close failed (%s)\n", cli_errstr(cli1->tree));
2202 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2204 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2205 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2206 printf("[2] close failed (%s)\n", cli_errstr(cli1->tree));
2210 cli_unlink(cli1->tree, fname);
2212 printf("second delete on close test succeeded.\n");
2215 cli_setatr(cli1->tree, fname, 0, 0);
2216 cli_unlink(cli1->tree, fname);
2218 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2219 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2222 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2227 /* This should fail with a sharing violation - open for delete is only compatible
2228 with SHARE_DELETE. */
2230 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2231 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2232 NTCREATEX_DISP_OPEN, 0, 0);
2235 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2240 /* This should succeed. */
2242 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2243 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN, 0, 0);
2246 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2251 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2252 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1->tree));
2257 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2258 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1->tree));
2263 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum2))) {
2264 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1->tree));
2269 /* This should fail - file should no longer be there. */
2271 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2273 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2274 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2275 printf("[3] close failed (%s)\n", cli_errstr(cli1->tree));
2277 cli_unlink(cli1->tree, fname);
2281 printf("third delete on close test succeeded.\n");
2284 cli_setatr(cli1->tree, fname, 0, 0);
2285 cli_unlink(cli1->tree, fname);
2287 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
2288 SA_RIGHT_FILE_READ_DATA |
2289 SA_RIGHT_FILE_WRITE_DATA |
2290 STD_RIGHT_DELETE_ACCESS,
2291 FILE_ATTRIBUTE_NORMAL,
2292 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2293 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2296 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2301 /* This should succeed. */
2302 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2303 FILE_ATTRIBUTE_NORMAL,
2304 NTCREATEX_SHARE_ACCESS_READ |
2305 NTCREATEX_SHARE_ACCESS_WRITE |
2306 NTCREATEX_SHARE_ACCESS_DELETE,
2307 NTCREATEX_DISP_OPEN, 0, 0);
2309 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2314 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum2))) {
2315 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1->tree));
2320 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2321 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1->tree));
2326 /* This should fail - no more opens once delete on close set. */
2327 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2328 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2329 NTCREATEX_DISP_OPEN, 0, 0);
2331 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2335 printf("fourth delete on close test succeeded.\n");
2337 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2338 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2344 cli_setatr(cli1->tree, fname, 0, 0);
2345 cli_unlink(cli1->tree, fname);
2347 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
2349 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2354 /* This should fail - only allowed on NT opens with DELETE access. */
2356 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2357 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2362 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2363 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2368 printf("fifth delete on close test succeeded.\n");
2371 cli_setatr(cli1->tree, fname, 0, 0);
2372 cli_unlink(cli1->tree, fname);
2374 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
2375 SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA,
2376 FILE_ATTRIBUTE_NORMAL,
2377 NTCREATEX_SHARE_ACCESS_READ |
2378 NTCREATEX_SHARE_ACCESS_WRITE |
2379 NTCREATEX_SHARE_ACCESS_DELETE,
2380 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2383 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2388 /* This should fail - only allowed on NT opens with DELETE access. */
2390 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2391 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2396 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2397 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2402 printf("sixth delete on close test succeeded.\n");
2405 cli_setatr(cli1->tree, fname, 0, 0);
2406 cli_unlink(cli1->tree, fname);
2408 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
2409 SA_RIGHT_FILE_READ_DATA |
2410 SA_RIGHT_FILE_WRITE_DATA |
2411 STD_RIGHT_DELETE_ACCESS,
2412 FILE_ATTRIBUTE_NORMAL, 0, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2415 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2420 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2421 printf("[7] setting delete_on_close on file failed !\n");
2426 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, False))) {
2427 printf("[7] unsetting delete_on_close on file failed !\n");
2432 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2433 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2438 /* This next open should succeed - we reset the flag. */
2440 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2442 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2447 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2448 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2453 printf("seventh delete on close test succeeded.\n");
2456 cli_setatr(cli1->tree, fname, 0, 0);
2457 cli_unlink(cli1->tree, fname);
2459 if (!torture_open_connection(&cli2)) {
2460 printf("[8] failed to open second connection.\n");
2465 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2466 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2467 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2470 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2475 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2476 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2477 NTCREATEX_DISP_OPEN, 0, 0);
2480 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2485 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2486 printf("[8] setting delete_on_close on file failed !\n");
2491 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2492 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1->tree));
2497 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
2498 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2->tree));
2503 /* This should fail.. */
2504 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2506 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2510 printf("eighth delete on close test succeeded.\n");
2512 /* This should fail - we need to set DELETE_ACCESS. */
2513 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
2514 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2517 printf("[9] open of %s succeeded should have failed!\n", fname);
2522 printf("ninth delete on close test succeeded.\n");
2524 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2525 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2527 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2532 /* This should delete the file. */
2533 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2534 printf("[10] close failed (%s)\n", cli_errstr(cli1->tree));
2539 /* This should fail.. */
2540 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2542 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2546 printf("tenth delete on close test succeeded.\n");
2547 printf("finished delete test\n");
2550 /* FIXME: This will crash if we aborted before cli2 got
2551 * intialized, because these functions don't handle
2552 * uninitialized connections. */
2554 cli_close(cli1->tree, fnum1);
2555 cli_close(cli1->tree, fnum2);
2556 cli_setatr(cli1->tree, fname, 0, 0);
2557 cli_unlink(cli1->tree, fname);
2559 if (!torture_close_connection(cli1)) {
2562 if (!torture_close_connection(cli2)) {
2570 print out server properties
2572 static BOOL run_properties(int dummy)
2574 struct cli_state *cli;
2575 BOOL correct = True;
2577 printf("starting properties test\n");
2581 if (!torture_open_connection(&cli)) {
2585 d_printf("Capabilities 0x%08x\n", cli->transport->negotiate.capabilities);
2587 if (!torture_close_connection(cli)) {
2596 /* FIRST_DESIRED_ACCESS 0xf019f */
2597 #define FIRST_DESIRED_ACCESS SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_APPEND_DATA|\
2598 SA_RIGHT_FILE_READ_EA| /* 0xf */ \
2599 SA_RIGHT_FILE_WRITE_EA|SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x90 */ \
2600 SA_RIGHT_FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
2601 STD_RIGHT_DELETE_ACCESS|STD_RIGHT_READ_CONTROL_ACCESS|\
2602 STD_RIGHT_WRITE_DAC_ACCESS|STD_RIGHT_WRITE_OWNER_ACCESS /* 0xf0000 */
2603 /* SECOND_DESIRED_ACCESS 0xe0080 */
2604 #define SECOND_DESIRED_ACCESS SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x80 */ \
2605 STD_RIGHT_READ_CONTROL_ACCESS|STD_RIGHT_WRITE_DAC_ACCESS|\
2606 STD_RIGHT_WRITE_OWNER_ACCESS /* 0xe0000 */
2609 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
2610 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2611 SA_RIGHT_FILE_READ_DATA|\
2612 WRITE_OWNER_ACCESS /* */
2616 Test ntcreate calls made by xcopy
2618 static BOOL run_xcopy(int dummy)
2620 struct cli_state *cli1;
2621 const char *fname = "\\test.txt";
2622 BOOL correct = True;
2625 printf("starting xcopy test\n");
2627 if (!torture_open_connection(&cli1)) {
2631 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
2632 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2633 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF,
2637 printf("First open failed - %s\n", cli_errstr(cli1->tree));
2641 fnum2 = cli_nt_create_full(cli1->tree, fname, 0,
2642 SECOND_DESIRED_ACCESS, 0,
2643 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
2646 printf("second open failed - %s\n", cli_errstr(cli1->tree));
2650 if (!torture_close_connection(cli1)) {
2658 Test rename on files open with share delete and no share delete.
2660 static BOOL run_rename(int dummy)
2662 struct cli_state *cli1;
2663 const char *fname = "\\test.txt";
2664 const char *fname1 = "\\test1.txt";
2665 BOOL correct = True;
2668 printf("starting rename test\n");
2670 if (!torture_open_connection(&cli1)) {
2674 cli_unlink(cli1->tree, fname);
2675 cli_unlink(cli1->tree, fname1);
2676 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2677 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2680 printf("First open failed - %s\n", cli_errstr(cli1->tree));
2684 if (NT_STATUS_IS_ERR(cli_rename(cli1->tree, fname, fname1))) {
2685 printf("First rename failed (this is correct) - %s\n", cli_errstr(cli1->tree));
2687 printf("First rename succeeded - this should have failed !\n");
2691 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2692 printf("close - 1 failed (%s)\n", cli_errstr(cli1->tree));
2696 cli_unlink(cli1->tree, fname);
2697 cli_unlink(cli1->tree, fname1);
2698 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2700 NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2702 NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2706 printf("Second open failed - %s\n", cli_errstr(cli1->tree));
2710 if (NT_STATUS_IS_ERR(cli_rename(cli1->tree, fname, fname1))) {
2711 printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(cli1->tree));
2714 printf("Second rename succeeded\n");
2717 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2718 printf("close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2722 cli_unlink(cli1->tree, fname);
2723 cli_unlink(cli1->tree, fname1);
2725 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2726 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2729 printf("Third open failed - %s\n", cli_errstr(cli1->tree));
2738 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2739 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2742 printf("Fourth open failed - %s\n", cli_errstr(cli1->tree));
2745 if (!cli_nt_delete_on_close(cli1->tree, fnum2, True)) {
2746 printf("[8] setting delete_on_close on file failed !\n");
2750 if (!cli_close(cli1->tree, fnum2)) {
2751 printf("close - 4 failed (%s)\n", cli_errstr(cli1->tree));
2757 if (NT_STATUS_IS_ERR(cli_rename(cli1->tree, fname, fname1))) {
2758 printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(cli1->tree));
2761 printf("Third rename succeeded\n");
2764 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2765 printf("close - 3 failed (%s)\n", cli_errstr(cli1->tree));
2769 cli_unlink(cli1->tree, fname);
2770 cli_unlink(cli1->tree, fname1);
2772 if (!torture_close_connection(cli1)) {
2779 static BOOL run_pipe_number(int dummy)
2781 struct cli_state *cli1;
2782 const char *pipe_name = "\\WKSSVC";
2786 printf("starting pipenumber test\n");
2787 if (!torture_open_connection(&cli1)) {
2792 fnum = cli_nt_create_full(cli1->tree, pipe_name, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
2793 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
2796 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1->tree));
2802 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
2803 torture_close_connection(cli1);
2811 open N connections to the server and just hold them open
2812 used for testing performance when there are N idle users
2815 static BOOL torture_holdcon(int dummy)
2818 struct cli_state **cli;
2821 printf("Opening %d connections\n", torture_numops);
2823 cli = malloc(sizeof(struct cli_state *) * torture_numops);
2825 for (i=0;i<torture_numops;i++) {
2826 if (!torture_open_connection(&cli[i])) {
2829 printf("opened %d connections\r", i);
2833 printf("\nStarting pings\n");
2836 for (i=0;i<torture_numops;i++) {
2839 status = cli_chkpath(cli[i]->tree, "\\");
2840 if (!NT_STATUS_IS_OK(status)) {
2841 printf("Connection %d is dead\n", i);
2849 if (num_dead == torture_numops) {
2850 printf("All connections dead - finishing\n");
2862 Try with a wrong vuid and check error message.
2865 static BOOL run_vuidtest(int dummy)
2867 struct cli_state *cli;
2868 const char *fname = "\\vuid.tst";
2871 time_t c_time, a_time, m_time;
2872 BOOL correct = True;
2877 printf("starting vuid test\n");
2879 if (!torture_open_connection(&cli)) {
2883 cli_unlink(cli->tree, fname);
2885 fnum = cli_open(cli->tree, fname,
2886 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2888 orig_vuid = cli->session->vuid;
2890 cli->session->vuid += 1234;
2892 printf("Testing qfileinfo with wrong vuid\n");
2894 if (NT_STATUS_IS_OK(result = cli_qfileinfo(cli->tree, fnum, NULL,
2895 &size, &c_time, &a_time,
2896 &m_time, NULL, NULL))) {
2897 printf("ERROR: qfileinfo passed with wrong vuid\n");
2901 if ( (cli->transport->error.etype != ETYPE_DOS) ||
2902 (cli->transport->error.e.dos.eclass != ERRSRV) ||
2903 (cli->transport->error.e.dos.ecode != ERRbaduid) ) {
2904 printf("ERROR: qfileinfo should have returned DOS error "
2905 "ERRSRV:ERRbaduid\n but returned %s\n",
2906 cli_errstr(cli->tree));
2910 cli->session->vuid -= 1234;
2912 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum))) {
2913 printf("close failed (%s)\n", cli_errstr(cli->tree));
2917 cli_unlink(cli->tree, fname);
2919 if (!torture_close_connection(cli)) {
2923 printf("vuid test finished\n");
2929 Test open mode returns on read-only files.
2931 static BOOL run_opentest(int dummy)
2933 static struct cli_state *cli1;
2934 static struct cli_state *cli2;
2935 const char *fname = "\\readonly.file";
2939 BOOL correct = True;
2943 printf("starting open test\n");
2945 if (!torture_open_connection(&cli1)) {
2949 cli_setatr(cli1->tree, fname, 0, 0);
2950 cli_unlink(cli1->tree, fname);
2952 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2954 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2958 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2959 printf("close2 failed (%s)\n", cli_errstr(cli1->tree));
2963 if (NT_STATUS_IS_ERR(cli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
2964 printf("cli_setatr failed (%s)\n", cli_errstr(cli1->tree));
2965 CHECK_MAX_FAILURES(error_test1);
2969 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
2971 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2972 CHECK_MAX_FAILURES(error_test1);
2976 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
2977 fnum2 = cli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
2979 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
2980 NT_STATUS_ACCESS_DENIED)) {
2981 printf("correct error code ERRDOS/ERRnoaccess returned\n");
2984 printf("finished open test 1\n");
2986 cli_close(cli1->tree, fnum1);
2988 /* Now try not readonly and ensure ERRbadshare is returned. */
2990 cli_setatr(cli1->tree, fname, 0, 0);
2992 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
2994 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2998 /* This will fail - but the error should be ERRshare. */
2999 fnum2 = cli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
3001 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3002 NT_STATUS_SHARING_VIOLATION)) {
3003 printf("correct error code ERRDOS/ERRbadshare returned\n");
3006 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3007 printf("close2 failed (%s)\n", cli_errstr(cli1->tree));
3011 cli_unlink(cli1->tree, fname);
3013 printf("finished open test 2\n");
3015 /* Test truncate open disposition on file opened for read. */
3017 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3019 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3023 /* write 20 bytes. */
3025 memset(buf, '\0', 20);
3027 if (cli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
3028 printf("write failed (%s)\n", cli_errstr(cli1->tree));
3032 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3033 printf("(3) close1 failed (%s)\n", cli_errstr(cli1->tree));
3037 /* Ensure size == 20. */
3038 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3039 printf("(3) getatr failed (%s)\n", cli_errstr(cli1->tree));
3040 CHECK_MAX_FAILURES(error_test3);
3045 printf("(3) file size != 20\n");
3046 CHECK_MAX_FAILURES(error_test3);
3050 /* Now test if we can truncate a file opened for readonly. */
3052 fnum1 = cli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3054 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3055 CHECK_MAX_FAILURES(error_test3);
3059 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3060 printf("close2 failed (%s)\n", cli_errstr(cli1->tree));
3064 /* Ensure size == 0. */
3065 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3066 printf("(3) getatr failed (%s)\n", cli_errstr(cli1->tree));
3067 CHECK_MAX_FAILURES(error_test3);
3072 printf("(3) file size != 0\n");
3073 CHECK_MAX_FAILURES(error_test3);
3076 printf("finished open test 3\n");
3078 cli_unlink(cli1->tree, fname);
3081 printf("testing ctemp\n");
3082 fnum1 = cli_ctemp(cli1->tree, "\\", &tmp_path);
3084 printf("ctemp failed (%s)\n", cli_errstr(cli1->tree));
3085 CHECK_MAX_FAILURES(error_test4);
3088 printf("ctemp gave path %s\n", tmp_path);
3089 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3090 printf("close of temp failed (%s)\n", cli_errstr(cli1->tree));
3092 if (NT_STATUS_IS_ERR(cli_unlink(cli1->tree, tmp_path))) {
3093 printf("unlink of temp failed (%s)\n", cli_errstr(cli1->tree));
3096 /* Test the non-io opens... */
3098 if (!torture_open_connection(&cli2)) {
3102 cli_setatr(cli2->tree, fname, 0, 0);
3103 cli_unlink(cli2->tree, fname);
3105 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3107 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3108 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3111 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3112 CHECK_MAX_FAILURES(error_test10);
3116 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3117 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3119 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3120 CHECK_MAX_FAILURES(error_test10);
3124 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3125 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3128 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3129 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3133 printf("non-io open test #1 passed.\n");
3135 cli_unlink(cli1->tree, fname);
3137 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3139 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3140 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3143 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3144 CHECK_MAX_FAILURES(error_test20);
3148 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3149 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3152 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3153 CHECK_MAX_FAILURES(error_test20);
3157 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3158 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3161 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3162 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3166 printf("non-io open test #2 passed.\n");
3168 cli_unlink(cli1->tree, fname);
3170 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3172 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3173 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3176 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3177 CHECK_MAX_FAILURES(error_test30);
3181 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3182 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3185 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3186 CHECK_MAX_FAILURES(error_test30);
3190 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3191 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3194 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3195 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3199 printf("non-io open test #3 passed.\n");
3201 cli_unlink(cli1->tree, fname);
3203 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3205 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3206 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3209 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3210 CHECK_MAX_FAILURES(error_test40);
3214 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3215 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3218 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2->tree));
3219 CHECK_MAX_FAILURES(error_test40);
3223 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2->tree), "sharing violation");
3225 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3226 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3230 printf("non-io open test #4 passed.\n");
3232 cli_unlink(cli1->tree, fname);
3234 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3236 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3237 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3240 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3241 CHECK_MAX_FAILURES(error_test50);
3245 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3246 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3249 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3250 CHECK_MAX_FAILURES(error_test50);
3254 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3255 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3259 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3260 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3264 printf("non-io open test #5 passed.\n");
3266 printf("TEST #6 testing 1 non-io open, one io open\n");
3268 cli_unlink(cli1->tree, fname);
3270 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3271 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3274 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3275 CHECK_MAX_FAILURES(error_test60);
3279 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3280 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
3283 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3284 CHECK_MAX_FAILURES(error_test60);
3288 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3289 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3293 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3294 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3298 printf("non-io open test #6 passed.\n");
3300 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3302 cli_unlink(cli1->tree, fname);
3304 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3305 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3308 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3309 CHECK_MAX_FAILURES(error_test70);
3313 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3314 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3317 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2->tree));
3318 CHECK_MAX_FAILURES(error_test70);
3322 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2->tree), "sharing violation");
3324 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3325 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3329 printf("non-io open test #7 passed.\n");
3333 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
3335 cli_unlink(cli1->tree, fname);
3337 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3339 printf("(8) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3343 /* write 20 bytes. */
3345 memset(buf, '\0', 20);
3347 if (cli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
3348 printf("(8) write failed (%s)\n", cli_errstr(cli1->tree));
3352 /* Ensure size == 20. */
3353 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3354 printf("(8) getatr (1) failed (%s)\n", cli_errstr(cli1->tree));
3355 CHECK_MAX_FAILURES(error_test80);
3360 printf("(8) file size != 20\n");
3361 CHECK_MAX_FAILURES(error_test80);
3365 /* Get an exclusive lock on the open file. */
3366 if (NT_STATUS_IS_ERR(cli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
3367 printf("(8) lock1 failed (%s)\n", cli_errstr(cli1->tree));
3368 CHECK_MAX_FAILURES(error_test80);
3372 fnum2 = cli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
3374 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, cli_errstr(cli1->tree));
3378 /* Ensure size == 0. */
3379 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3380 printf("(8) getatr (2) failed (%s)\n", cli_errstr(cli1->tree));
3381 CHECK_MAX_FAILURES(error_test80);
3386 printf("(8) file size != 0\n");
3387 CHECK_MAX_FAILURES(error_test80);
3391 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3392 printf("(8) close1 failed (%s)\n", cli_errstr(cli1->tree));
3396 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum2))) {
3397 printf("(8) close1 failed (%s)\n", cli_errstr(cli1->tree));
3403 printf("open test #8 passed.\n");
3405 cli_unlink(cli1->tree, fname);
3407 if (!torture_close_connection(cli1)) {
3410 if (!torture_close_connection(cli2)) {
3418 static uint32_t open_attrs_table[] = {
3419 FILE_ATTRIBUTE_NORMAL,
3420 FILE_ATTRIBUTE_ARCHIVE,
3421 FILE_ATTRIBUTE_READONLY,
3422 FILE_ATTRIBUTE_HIDDEN,
3423 FILE_ATTRIBUTE_SYSTEM,
3425 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
3426 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
3427 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
3428 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3429 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3430 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3432 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3433 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3434 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3435 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
3438 struct trunc_open_results {
3441 uint32_t trunc_attr;
3442 uint32_t result_attr;
3445 static struct trunc_open_results attr_results[] = {
3446 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3447 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3448 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3449 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3450 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3451 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3452 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3453 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3454 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3455 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3456 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3457 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
3458 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3459 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3460 { 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 },
3461 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3462 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3463 { 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 },
3464 { 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 },
3465 { 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 },
3466 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3467 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3468 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3469 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3470 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3471 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
3474 static BOOL run_openattrtest(int dummy)
3476 struct cli_state *cli1;
3477 const char *fname = "\\openattr.file";
3479 BOOL correct = True;
3484 printf("starting open attr test\n");
3486 if (!torture_open_connection(&cli1)) {
3490 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
3491 cli_setatr(cli1->tree, fname, 0, 0);
3492 cli_unlink(cli1->tree, fname);
3493 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_WRITE_DATA, open_attrs_table[i],
3494 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3497 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1->tree));
3501 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3502 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1->tree));
3506 for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
3507 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
3508 SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
3509 open_attrs_table[j],
3510 NTCREATEX_SHARE_ACCESS_NONE,
3511 NTCREATEX_DISP_OVERWRITE, 0, 0);
3514 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3515 if (attr_results[l].num == k) {
3516 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
3517 k, open_attrs_table[i],
3518 open_attrs_table[j],
3519 fname, NT_STATUS_V(cli_nt_error(cli1->tree)), cli_errstr(cli1->tree));
3521 CHECK_MAX_FAILURES(error_exit);
3524 if (NT_STATUS_V(cli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
3525 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
3526 k, open_attrs_table[i], open_attrs_table[j],
3527 cli_errstr(cli1->tree));
3529 CHECK_MAX_FAILURES(error_exit);
3532 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
3538 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3539 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1->tree));
3543 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, &attr, NULL, NULL))) {
3544 printf("getatr(2) failed (%s)\n", cli_errstr(cli1->tree));
3549 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
3550 k, open_attrs_table[i], open_attrs_table[j], attr );
3553 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3554 if (attr_results[l].num == k) {
3555 if (attr != attr_results[l].result_attr ||
3556 open_attrs_table[i] != attr_results[l].init_attr ||
3557 open_attrs_table[j] != attr_results[l].trunc_attr) {
3558 printf("[%d] getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
3559 k, open_attrs_table[i],
3560 open_attrs_table[j],
3562 attr_results[l].result_attr);
3564 CHECK_MAX_FAILURES(error_exit);
3573 cli_setatr(cli1->tree, fname, 0, 0);
3574 cli_unlink(cli1->tree, fname);
3576 printf("open attr test %s.\n", correct ? "passed" : "failed");
3578 if (!torture_close_connection(cli1)) {
3584 static void list_fn(file_info *finfo, const char *name, void *state)
3590 test directory listing speed
3592 static BOOL run_dirtest(int dummy)
3595 struct cli_state *cli;
3598 BOOL correct = True;
3600 printf("starting directory test\n");
3602 if (!torture_open_connection(&cli)) {
3606 printf("Creating %d random filenames\n", torture_numops);
3609 for (i=0;i<torture_numops;i++) {
3611 asprintf(&fname, "\\%x", (int)random());
3612 fnum = cli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3614 fprintf(stderr,"Failed to open %s\n", fname);
3617 cli_close(cli->tree, fnum);
3623 printf("Matched %d\n", cli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3624 printf("Matched %d\n", cli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3625 printf("Matched %d\n", cli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3627 printf("dirtest core %g seconds\n", end_timer() - t1);
3630 for (i=0;i<torture_numops;i++) {
3632 asprintf(&fname, "\\%x", (int)random());
3633 cli_unlink(cli->tree, fname);
3637 if (!torture_close_connection(cli)) {
3641 printf("finished dirtest\n");
3646 static void del_fn(file_info *finfo, const char *mask, void *state)
3648 struct cli_state *pcli = (struct cli_state *)state;
3650 asprintf(&fname, "\\LISTDIR\\%s", finfo->name);
3652 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
3655 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
3656 if (NT_STATUS_IS_ERR(cli_rmdir(pcli->tree, fname)))
3657 printf("del_fn: failed to rmdir %s, error=%s\n", fname, cli_errstr(pcli->tree) );
3659 if (NT_STATUS_IS_ERR(cli_unlink(pcli->tree, fname)))
3660 printf("del_fn: failed to unlink %s, error=%s\n", fname, cli_errstr(pcli->tree) );
3667 sees what IOCTLs are supported
3669 BOOL torture_ioctl_test(int dummy)
3671 struct cli_state *cli;
3672 uint16_t device, function;
3674 const char *fname = "\\ioctl.dat";
3676 union smb_ioctl parms;
3677 TALLOC_CTX *mem_ctx;
3679 if (!torture_open_connection(&cli)) {
3683 mem_ctx = talloc_init("ioctl_test");
3685 printf("starting ioctl test\n");
3687 cli_unlink(cli->tree, fname);
3689 fnum = cli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3691 printf("open of %s failed (%s)\n", fname, cli_errstr(cli->tree));
3695 parms.ioctl.level = RAW_IOCTL_IOCTL;
3696 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
3697 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3698 printf("ioctl job info: %s\n", cli_errstr(cli->tree));
3700 for (device=0;device<0x100;device++) {
3701 printf("testing device=0x%x\n", device);
3702 for (function=0;function<0x100;function++) {
3703 parms.ioctl.in.request = (device << 16) | function;
3704 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3706 if (NT_STATUS_IS_OK(status)) {
3707 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
3708 device, function, parms.ioctl.out.blob.length);
3713 if (!torture_close_connection(cli)) {
3722 tries variants of chkpath
3724 BOOL torture_chkpath_test(int dummy)
3726 struct cli_state *cli;
3730 if (!torture_open_connection(&cli)) {
3734 printf("starting chkpath test\n");
3736 printf("Testing valid and invalid paths\n");
3738 /* cleanup from an old run */
3739 cli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3740 cli_unlink(cli->tree, "\\chkpath.dir\\*");
3741 cli_rmdir(cli->tree, "\\chkpath.dir");
3743 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, "\\chkpath.dir"))) {
3744 printf("mkdir1 failed : %s\n", cli_errstr(cli->tree));
3748 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
3749 printf("mkdir2 failed : %s\n", cli_errstr(cli->tree));
3753 fnum = cli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3755 printf("open1 failed (%s)\n", cli_errstr(cli->tree));
3758 cli_close(cli->tree, fnum);
3760 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir"))) {
3761 printf("chkpath1 failed: %s\n", cli_errstr(cli->tree));
3765 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
3766 printf("chkpath2 failed: %s\n", cli_errstr(cli->tree));
3770 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
3771 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3772 NT_STATUS_NOT_A_DIRECTORY);
3774 printf("* chkpath on a file should fail\n");
3778 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
3779 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
3780 NT_STATUS_OBJECT_NAME_NOT_FOUND);
3782 printf("* chkpath on a non existent file should fail\n");
3786 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
3787 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3788 NT_STATUS_OBJECT_PATH_NOT_FOUND);
3790 printf("* chkpath on a non existent component should fail\n");
3794 cli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3795 cli_unlink(cli->tree, "\\chkpath.dir\\*");
3796 cli_rmdir(cli->tree, "\\chkpath.dir");
3798 if (!torture_close_connection(cli)) {
3805 static BOOL run_dirtest1(int dummy)
3808 struct cli_state *cli;
3810 BOOL correct = True;
3812 printf("starting directory test\n");
3814 if (!torture_open_connection(&cli)) {
3818 cli_list(cli->tree, "\\LISTDIR\\*", 0, del_fn, cli);
3819 cli_list(cli->tree, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
3820 if (cli_deltree(cli->tree, "\\LISTDIR") == -1) {
3821 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", cli_errstr(cli->tree));
3824 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, "\\LISTDIR"))) {
3825 fprintf(stderr,"Failed to mkdir %s, error=%s\n", "\\LISTDIR", cli_errstr(cli->tree));
3829 printf("Creating %d files\n", torture_entries);
3831 /* Create torture_entries files and torture_entries directories. */
3832 for (i=0;i<torture_entries;i++) {
3834 asprintf(&fname, "\\LISTDIR\\f%d", i);
3835 fnum = cli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3836 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3838 fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli->tree));
3842 cli_close(cli->tree, fnum);
3844 for (i=0;i<torture_entries;i++) {
3846 asprintf(&fname, "\\LISTDIR\\d%d", i);
3847 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, fname))) {
3848 fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli->tree));
3854 /* Now ensure that doing an old list sees both files and directories. */
3855 num_seen = cli_list_old(cli->tree, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3856 printf("num_seen = %d\n", num_seen );
3857 /* We should see (torture_entries) each of files & directories + . and .. */
3858 if (num_seen != (2*torture_entries)+2) {
3860 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3861 (2*torture_entries)+2, num_seen);
3865 /* Ensure if we have the "must have" bits we only see the
3868 num_seen = cli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3869 printf("num_seen = %d\n", num_seen );
3870 if (num_seen != torture_entries+2) {
3872 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3873 torture_entries+2, num_seen);
3876 num_seen = cli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3877 printf("num_seen = %d\n", num_seen );
3878 if (num_seen != torture_entries) {
3880 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3881 torture_entries, num_seen);
3884 /* Delete everything. */
3885 cli_list(cli->tree, "\\LISTDIR\\*", 0, del_fn, cli);
3886 cli_list(cli->tree, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
3887 cli_rmdir(cli->tree, "\\LISTDIR");
3890 printf("Matched %d\n", cli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3891 printf("Matched %d\n", cli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3892 printf("Matched %d\n", cli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3895 if (!torture_close_connection(cli)) {
3899 printf("finished dirtest1\n");
3906 simple test harness for playing with deny modes
3908 static BOOL run_deny3test(int dummy)
3910 struct cli_state *cli1, *cli2;
3914 printf("starting deny3 test\n");
3916 printf("Testing simple deny modes\n");
3918 if (!torture_open_connection(&cli1)) {
3921 if (!torture_open_connection(&cli2)) {
3925 fname = "\\deny_dos1.dat";
3927 cli_unlink(cli1->tree, fname);
3928 fnum1 = cli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3929 fnum2 = cli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3930 if (fnum1 != -1) cli_close(cli1->tree, fnum1);
3931 if (fnum2 != -1) cli_close(cli1->tree, fnum2);
3932 cli_unlink(cli1->tree, fname);
3933 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3936 fname = "\\deny_dos2.dat";
3938 cli_unlink(cli1->tree, fname);
3939 fnum1 = cli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3940 fnum2 = cli_open(cli2->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3941 if (fnum1 != -1) cli_close(cli1->tree, fnum1);
3942 if (fnum2 != -1) cli_close(cli2->tree, fnum2);
3943 cli_unlink(cli1->tree, fname);
3944 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3947 torture_close_connection(cli1);
3948 torture_close_connection(cli2);
3954 parse a //server/share type UNC name
3956 static BOOL parse_unc(const char *unc_name, char **hostname, char **sharename)
3960 if (strncmp(unc_name, "//", 2)) {
3964 *hostname = strdup(&unc_name[2]);
3965 p = strchr_m(&(*hostname)[2],'/');
3970 *sharename = strdup(p+1);
3977 static void sigcont(void)
3981 double torture_create_procs(BOOL (*fn)(struct cli_state *, int), BOOL *result)
3984 volatile pid_t *child_status;
3985 volatile BOOL *child_status_out;
3988 double start_time_limit = 10 + (torture_nprocs * 1.5);
3989 char **unc_list = NULL;
3991 int num_unc_names = 0;
3995 signal(SIGCONT, sigcont);
3997 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
3998 if (!child_status) {
3999 printf("Failed to setup shared memory\n");
4003 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
4004 if (!child_status_out) {
4005 printf("Failed to setup result status shared memory\n");
4009 p = lp_parm_string(-1, "torture", "unclist");
4011 unc_list = file_lines_load(p, &num_unc_names);
4012 if (!unc_list || num_unc_names <= 0) {
4013 printf("Failed to load unc names list from %s\n", p);
4018 for (i = 0; i < torture_nprocs; i++) {
4019 child_status[i] = 0;
4020 child_status_out[i] = True;
4025 for (i=0;i<torture_nprocs;i++) {
4029 char *hostname=NULL, *sharename;
4031 pid_t mypid = getpid();
4032 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
4034 asprintf(&myname, "CLIENT%d", i);
4035 lp_set_cmdline("netbios name", myname);
4040 if (!parse_unc(unc_list[i % num_unc_names],
4041 &hostname, &sharename)) {
4042 printf("Failed to parse UNC name %s\n",
4043 unc_list[i % num_unc_names]);
4050 if (torture_open_connection_share(¤t_cli,
4055 } else if (torture_open_connection(¤t_cli)) {
4059 printf("pid %d failed to start\n", (int)getpid());
4065 child_status[i] = getpid();
4069 if (child_status[i]) {
4070 printf("Child %d failed to start!\n", i);
4071 child_status_out[i] = 1;
4075 child_status_out[i] = fn(current_cli, i);
4082 for (i=0;i<torture_nprocs;i++) {
4083 if (child_status[i]) synccount++;
4085 if (synccount == torture_nprocs) break;
4087 } while (end_timer() < start_time_limit);
4089 if (synccount != torture_nprocs) {
4090 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
4095 printf("Starting %d clients\n", torture_nprocs);
4097 /* start the client load */
4099 for (i=0;i<torture_nprocs;i++) {
4100 child_status[i] = 0;
4104 printf("%d clients started\n", torture_nprocs);
4106 for (i=0;i<torture_nprocs;i++) {
4108 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
4109 if (ret == -1 || WEXITSTATUS(status) != 0) {
4116 for (i=0;i<torture_nprocs;i++) {
4117 if (!child_status_out[i]) {
4124 #define FLAG_MULTIPROC 1
4131 {"FDPASS", run_fdpasstest, 0},
4132 {"LOCK1", run_locktest1, 0},
4133 {"LOCK2", run_locktest2, 0},
4134 {"LOCK3", run_locktest3, 0},
4135 {"LOCK4", run_locktest4, 0},
4136 {"LOCK5", run_locktest5, 0},
4137 {"LOCK6", run_locktest6, 0},
4138 {"LOCK7", run_locktest7, 0},
4139 {"UNLINK", run_unlinktest, 0},
4140 {"ATTR", run_attrtest, 0},
4141 {"TRANS2", run_trans2test, 0},
4142 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
4143 {"TORTURE",run_torture, FLAG_MULTIPROC},
4144 {"NEGNOWAIT", run_negprot_nowait, 0},
4145 {"NBENCH", torture_nbench, 0},
4146 {"DIR", run_dirtest, 0},
4147 {"DIR1", run_dirtest1, 0},
4148 {"DENY1", torture_denytest1, 0},
4149 {"DENY2", torture_denytest2, 0},
4150 {"TCON", run_tcon_test, 0},
4151 {"TCONDEV", run_tcon_devtype_test, 0},
4152 {"VUID", run_vuidtest, 0},
4154 {"DFSBASIC", torture_dfs_basic, 0},
4155 {"DFSRENAME", torture_dfs_rename, 0},
4156 {"DFSRANDOM", torture_dfs_random, 0},
4158 {"RW1", run_readwritetest, 0},
4159 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
4160 {"OPEN", run_opentest, 0},
4161 {"DENY3", run_deny3test, 0},
4163 {"OPENATTR", run_openattrtest, 0},
4165 {"DEFER_OPEN", run_deferopen, FLAG_MULTIPROC},
4166 {"XCOPY", run_xcopy, 0},
4167 {"RENAME", run_rename, 0},
4168 {"DELETE", run_deletetest, 0},
4169 {"PROPERTIES", run_properties, 0},
4170 {"MANGLE", torture_mangle, 0},
4171 {"UTABLE", torture_utable, 0},
4172 {"CASETABLE", torture_casetable, 0},
4173 {"CHARSET", torture_charset, 0},
4174 {"PIPE_NUMBER", run_pipe_number, 0},
4175 {"IOCTL", torture_ioctl_test, 0},
4176 {"CHKPATH", torture_chkpath_test, 0},
4177 {"HOLDCON", torture_holdcon, 0},
4178 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
4179 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
4180 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
4181 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
4182 {"RAW-SEARCH", torture_raw_search, 0},
4183 {"RAW-CLOSE", torture_raw_close, 0},
4184 {"RAW-OPEN", torture_raw_open, 0},
4185 {"RAW-MKDIR", torture_raw_mkdir, 0},
4186 {"RAW-OPLOCK", torture_raw_oplock, 0},
4187 {"RAW-NOTIFY", torture_raw_notify, 0},
4188 {"RAW-MUX", torture_raw_mux, 0},
4189 {"RAW-IOCTL", torture_raw_ioctl, 0},
4190 {"RAW-CHKPATH", torture_raw_chkpath, 0},
4191 {"RAW-UNLINK", torture_raw_unlink, 0},
4192 {"RAW-READ", torture_raw_read, 0},
4193 {"RAW-WRITE", torture_raw_write, 0},
4194 {"RAW-LOCK", torture_raw_lock, 0},
4195 {"RAW-CONTEXT", torture_raw_context, 0},
4196 {"RAW-RENAME", torture_raw_rename, 0},
4197 {"RAW-SEEK", torture_raw_seek, 0},
4198 {"RAW-RAP", torture_raw_rap, 0},
4199 {"SCAN-TRANS2", torture_trans2_scan, 0},
4200 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
4201 {"SCAN-ALIASES", torture_trans2_aliases, 0},
4202 {"SCAN-SMB", torture_smb_scan, 0},
4203 {"RPC-LSA", torture_rpc_lsa, 0},
4204 {"RPC-ECHO", torture_rpc_echo, 0},
4205 {"RPC-DFS", torture_rpc_dfs, 0},
4206 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
4207 {"RPC-SAMR", torture_rpc_samr, 0},
4208 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
4209 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
4210 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
4211 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
4212 {"RPC-ATSVC", torture_rpc_atsvc, 0},
4213 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
4214 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
4215 {"RPC-WINREG", torture_rpc_winreg, 0},
4216 {"RPC-MGMT", torture_rpc_mgmt, 0},
4217 {"RPC-SCANNER", torture_rpc_scanner, 0},
4218 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
4219 {"RPC-MULTIBIND", torture_multi_bind, 0},
4220 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
4221 {"NTLMSSP-SELFCHECK", torture_ntlmssp_self_check, 0},
4226 /****************************************************************************
4227 run a specified test or "ALL"
4228 ****************************************************************************/
4229 static BOOL run_test(const char *name)
4233 BOOL matched = False;
4235 if (strequal(name,"ALL")) {
4236 for (i=0;torture_ops[i].name;i++) {
4237 if (!run_test(torture_ops[i].name)) {
4244 for (i=0;torture_ops[i].name;i++) {
4245 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
4248 printf("Running %s\n", torture_ops[i].name);
4249 if (torture_ops[i].flags & FLAG_MULTIPROC) {
4251 t = torture_create_procs(torture_ops[i].fn, &result);
4254 printf("TEST %s FAILED!\n", torture_ops[i].name);
4259 if (!torture_ops[i].fn(0)) {
4261 printf("TEST %s FAILED!\n", torture_ops[i].name);
4265 printf("%s took %g secs\n\n", torture_ops[i].name, t);
4270 printf("Unknown torture operation '%s'\n", name);
4278 parse a username%password
4280 static void parse_user(const char *user)
4282 char *username, *password = NULL, *p;
4284 username = strdup(user);
4285 p = strchr_m(username,'%');
4288 password = strdup(p+1);
4291 lp_set_cmdline("torture:username", username);
4294 lp_set_cmdline("torture:password", password);
4297 if (!lp_parm_string(-1,"torture","password")) {
4298 password = getpass("password:");
4300 lp_set_cmdline("torture:password", password);
4304 static void usage(void)
4308 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
4310 printf("\t-d debuglevel\n");
4311 printf("\t-U user%%pass\n");
4312 printf("\t-k use kerberos\n");
4313 printf("\t-N numprocs\n");
4314 printf("\t-n my_netbios_name\n");
4315 printf("\t-W workgroup\n");
4316 printf("\t-o num_operations\n");
4317 printf("\t-e num files(entries)\n");
4318 printf("\t-O socket_options\n");
4319 printf("\t-m maximum protocol\n");
4320 printf("\t-L use oplocks\n");
4321 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
4322 printf("\t-t timelimit specify NBENCH time limit (seconds)\n");
4323 printf("\t-C filename specifies file with list of UNCs for connections\n");
4324 printf("\t-A showall\n");
4325 printf("\t-p port\n");
4326 printf("\t-s seed\n");
4327 printf("\t-f max failures\n");
4328 printf("\t-X enable dangerous tests\n");
4331 printf("tests are:");
4332 for (i=0;torture_ops[i].name;i++) {
4333 printf(" %s", torture_ops[i].name);
4337 printf("default test is ALL\n");
4342 /****************************************************************************
4344 ****************************************************************************/
4345 int main(int argc,char *argv[])
4349 BOOL correct = True;
4350 char *host, *share, *username;
4352 setup_logging("smbtorture", DEBUG_STDOUT);
4354 #ifdef HAVE_SETBUFFER
4355 setbuffer(stdout, NULL, 0);
4358 lp_load(dyn_CONFIGFILE,True,False,False);
4365 for(p = argv[1]; *p; p++)
4370 /* see if its a RPC transport specifier */
4371 if (strncmp(argv[1], "ncacn_", 6) == 0) {
4372 lp_set_cmdline("torture:binding", argv[1]);
4374 char *binding = NULL;
4376 if (!parse_unc(argv[1], &host, &share)) {
4380 lp_set_cmdline("torture:host", host);
4381 lp_set_cmdline("torture:share", share);
4382 asprintf(&binding, "ncacn_np:%s", host);
4383 lp_set_cmdline("torture:binding", binding);
4386 if (getenv("LOGNAME")) {
4387 username = strdup(getenv("LOGNAME"));
4389 lp_set_cmdline("torture:username", username);
4395 srandom(time(NULL));
4397 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:e:m:Ld:Ac:ks:f:s:t:C:X")) != EOF) {
4400 lp_set_cmdline("smb ports", optarg);
4403 lp_set_cmdline("workgroup", optarg);
4406 lp_set_cmdline("protocol", optarg);
4409 lp_set_cmdline("netbios name", optarg);
4412 lp_set_cmdline("debug level", optarg);
4413 setup_logging(NULL, DEBUG_STDOUT);
4416 lp_set_cmdline("socket options", optarg);
4419 srandom(atoi(optarg));
4422 torture_nprocs = atoi(optarg);
4425 torture_numops = atoi(optarg);
4428 torture_entries = atoi(optarg);
4434 torture_showall = True;
4437 lp_set_cmdline("torture:loadfile", optarg);
4440 lp_set_cmdline("torture:unclist", optarg);
4443 lp_set_cmdline("torture:timelimit", optarg);
4447 use_kerberos = True;
4449 d_printf("No kerberos support compiled in\n");
4457 torture_failures = atoi(optarg);
4461 lp_set_cmdline("torture:dangerous", "1");
4465 printf("Unknown option %c (%d)\n", (char)opt, opt);
4470 if (!lp_parm_string(-1,"torture","password")) {
4471 lp_set_cmdline("torture:password", "");
4474 if (argc == optind) {
4475 printf("You must specify a test to run, or 'ALL'\n");
4477 for (i=optind;i<argc;i++) {
4478 if (!run_test(argv[i])) {