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);
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 the timing of deferred open requests
1763 static BOOL run_deferopen(struct cli_state *cli, int dummy)
1765 const char *fname = "\\defer_open_test.dat";
1768 BOOL correct = True;
1771 printf("failed to connect\n");
1775 printf("Testing deferred open requests.\n");
1781 struct timeval tv_start, tv_end;
1782 GetTimeOfDay(&tv_start);
1783 fnum = cli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
1784 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
1785 NTCREATEX_DISP_OPEN_IF, 0, 0);
1789 GetTimeOfDay(&tv_end);
1790 if (NT_STATUS_EQUAL(cli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
1791 /* Sharing violation errors need to be 1 second apart. */
1792 int64_t tdif = usec_time_diff(&tv_end, &tv_start);
1793 if (tdif < 500000 || tdif > 1500000) {
1794 fprintf(stderr,"Timing incorrect %lld.%lld for share violation\n",
1795 tdif / (int64_t)1000000,
1796 tdif % (int64_t)1000000);
1799 } while (NT_STATUS_EQUAL(cli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION));
1802 fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli->tree));
1806 printf("pid %u open %d\n", getpid(), i);
1810 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum))) {
1811 fprintf(stderr,"Failed to close %s, error=%s\n", fname, cli_errstr(cli->tree));
1817 if (NT_STATUS_IS_ERR(cli_unlink(cli->tree, fname))) {
1818 /* All until the last unlink will fail with sharing violation. */
1819 if (!NT_STATUS_EQUAL(cli_nt_error(cli->tree),NT_STATUS_SHARING_VIOLATION)) {
1820 printf("unlink of %s failed (%s)\n", fname, cli_errstr(cli->tree));
1825 printf("deferred test finished\n");
1826 if (!torture_close_connection(cli)) {
1833 test how many open files this server supports on the one socket
1835 static BOOL run_maxfidtest(struct cli_state *cli, int dummy)
1837 const char *template = "\\maxfid.%d.%d";
1839 int fnums[0x11000], i;
1841 BOOL correct = True;
1844 printf("failed to connect\n");
1848 printf("Testing maximum number of open files\n");
1850 for (i=0; i<0x11000; i++) {
1851 asprintf(&fname, template, i,(int)getpid());
1852 if ((fnums[i] = cli_open(cli->tree, fname,
1853 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1855 printf("open of %s failed (%s)\n",
1856 fname, cli_errstr(cli->tree));
1857 printf("maximum fnum is %d\n", i);
1866 printf("cleaning up\n");
1868 asprintf(&fname, template, i,(int)getpid());
1869 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnums[i]))) {
1870 printf("Close of fnum %d failed - %s\n", fnums[i], cli_errstr(cli->tree));
1872 if (NT_STATUS_IS_ERR(cli_unlink(cli->tree, fname))) {
1873 printf("unlink of %s failed (%s)\n",
1874 fname, cli_errstr(cli->tree));
1882 printf("maxfid test finished\n");
1883 if (!torture_close_connection(cli)) {
1889 /* send smb negprot commands, not reading the response */
1890 static BOOL run_negprot_nowait(int dummy)
1893 struct cli_state *cli;
1894 BOOL correct = True;
1896 printf("starting negprot nowait test\n");
1898 cli = open_nbt_connection();
1903 printf("Establishing protocol negotiations - connect with another client\n");
1905 for (i=0;i<50000;i++) {
1906 smb_negprot_send(cli->transport, PROTOCOL_NT1);
1909 if (!torture_close_connection(cli)) {
1913 printf("finished negprot nowait test\n");
1920 This checks how the getatr calls works
1922 static BOOL run_attrtest(int dummy)
1924 struct cli_state *cli;
1927 const char *fname = "\\attrib123456789.tst";
1928 BOOL correct = True;
1930 printf("starting attrib test\n");
1932 if (!torture_open_connection(&cli)) {
1936 cli_unlink(cli->tree, fname);
1937 fnum = cli_open(cli->tree, fname,
1938 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1939 cli_close(cli->tree, fnum);
1941 if (NT_STATUS_IS_ERR(cli_getatr(cli->tree, fname, NULL, NULL, &t))) {
1942 printf("getatr failed (%s)\n", cli_errstr(cli->tree));
1946 printf("New file time is %s", ctime(&t));
1948 if (abs(t - time(NULL)) > 60*60*24*10) {
1949 printf("ERROR: SMBgetatr bug. time is %s",
1955 t2 = t-60*60*24; /* 1 day ago */
1957 printf("Setting file time to %s", ctime(&t2));
1959 if (NT_STATUS_IS_ERR(cli_setatr(cli->tree, fname, 0, t2))) {
1960 printf("setatr failed (%s)\n", cli_errstr(cli->tree));
1964 if (NT_STATUS_IS_ERR(cli_getatr(cli->tree, fname, NULL, NULL, &t))) {
1965 printf("getatr failed (%s)\n", cli_errstr(cli->tree));
1969 printf("Retrieved file time as %s", ctime(&t));
1972 printf("ERROR: getatr/setatr bug. times are\n%s",
1974 printf("%s", ctime(&t2));
1978 cli_unlink(cli->tree, fname);
1980 if (!torture_close_connection(cli)) {
1984 printf("attrib test finished\n");
1991 This checks a couple of trans2 calls
1993 static BOOL run_trans2test(int dummy)
1995 struct cli_state *cli;
1998 time_t c_time, a_time, m_time, w_time, m_time2;
1999 const char *fname = "\\trans2.tst";
2000 const char *dname = "\\trans2";
2001 const char *fname2 = "\\trans2\\trans2.tst";
2003 BOOL correct = True;
2005 printf("starting trans2 test\n");
2007 if (!torture_open_connection(&cli)) {
2011 cli_unlink(cli->tree, fname);
2013 printf("Testing qfileinfo\n");
2015 fnum = cli_open(cli->tree, fname,
2016 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2017 if (NT_STATUS_IS_ERR(cli_qfileinfo(cli->tree, fnum, NULL, &size, &c_time, &a_time, &m_time,
2019 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli->tree));
2023 printf("Testing NAME_INFO\n");
2025 if (NT_STATUS_IS_ERR(cli_qfilename(cli->tree, fnum, &pname))) {
2026 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli->tree));
2030 if (!pname || strcmp(pname, fname)) {
2031 printf("qfilename gave different name? [%s] [%s]\n",
2036 cli_close(cli->tree, fnum);
2037 cli_unlink(cli->tree, fname);
2039 fnum = cli_open(cli->tree, fname,
2040 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2042 printf("open of %s failed (%s)\n", fname, cli_errstr(cli->tree));
2045 cli_close(cli->tree, fnum);
2047 printf("Checking for sticky create times\n");
2049 if (NT_STATUS_IS_ERR(cli_qpathinfo(cli->tree, fname, &c_time, &a_time, &m_time, &size, NULL))) {
2050 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli->tree));
2053 if (c_time != m_time) {
2054 printf("create time=%s", ctime(&c_time));
2055 printf("modify time=%s", ctime(&m_time));
2056 printf("This system appears to have sticky create times\n");
2058 if (a_time % (60*60) == 0) {
2059 printf("access time=%s", ctime(&a_time));
2060 printf("This system appears to set a midnight access time\n");
2064 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2065 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2071 cli_unlink(cli->tree, fname);
2072 fnum = cli_open(cli->tree, fname,
2073 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2074 cli_close(cli->tree, fnum);
2075 if (NT_STATUS_IS_ERR(cli_qpathinfo2(cli->tree, fname, &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2076 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli->tree));
2079 if (w_time < 60*60*24*2) {
2080 printf("write time=%s", ctime(&w_time));
2081 printf("This system appears to set a initial 0 write time\n");
2086 cli_unlink(cli->tree, fname);
2089 /* check if the server updates the directory modification time
2090 when creating a new file */
2091 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, dname))) {
2092 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli->tree));
2096 if (NT_STATUS_IS_ERR(cli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time, &w_time, &size, NULL, NULL))) {
2097 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli->tree));
2101 fnum = cli_open(cli->tree, fname2,
2102 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2103 cli_write(cli->tree, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2104 cli_close(cli->tree, fnum);
2105 if (NT_STATUS_IS_ERR(cli_qpathinfo2(cli->tree, "\\trans2\\", &c_time, &a_time, &m_time2, &w_time, &size, NULL, NULL))) {
2106 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli->tree));
2109 if (m_time2 == m_time) {
2110 printf("This system does not update directory modification times\n");
2114 cli_unlink(cli->tree, fname2);
2115 cli_rmdir(cli->tree, dname);
2117 if (!torture_close_connection(cli)) {
2121 printf("trans2 test finished\n");
2127 Test delete on close semantics.
2129 static BOOL run_deletetest(int dummy)
2131 struct cli_state *cli1;
2132 struct cli_state *cli2 = NULL;
2133 const char *fname = "\\delete.file";
2136 BOOL correct = True;
2138 printf("starting delete test\n");
2140 if (!torture_open_connection(&cli1)) {
2144 /* Test 1 - this should delete the file on close. */
2146 cli_setatr(cli1->tree, fname, 0, 0);
2147 cli_unlink(cli1->tree, fname);
2149 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2150 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF,
2151 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2154 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2159 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2160 printf("[1] close failed (%s)\n", cli_errstr(cli1->tree));
2165 fnum1 = cli_open(cli1->tree, fname, O_RDWR, DENY_NONE);
2167 printf("[1] open of %s succeeded (should fail)\n", fname);
2172 printf("first delete on close test succeeded.\n");
2174 /* Test 2 - this should delete the file on close. */
2176 cli_setatr(cli1->tree, fname, 0, 0);
2177 cli_unlink(cli1->tree, fname);
2179 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
2180 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
2181 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2184 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2189 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2190 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1->tree));
2195 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2196 printf("[2] close failed (%s)\n", cli_errstr(cli1->tree));
2201 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2203 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2204 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2205 printf("[2] close failed (%s)\n", cli_errstr(cli1->tree));
2209 cli_unlink(cli1->tree, fname);
2211 printf("second delete on close test succeeded.\n");
2214 cli_setatr(cli1->tree, fname, 0, 0);
2215 cli_unlink(cli1->tree, fname);
2217 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2218 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2221 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2226 /* This should fail with a sharing violation - open for delete is only compatible
2227 with SHARE_DELETE. */
2229 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2230 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2231 NTCREATEX_DISP_OPEN, 0, 0);
2234 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2239 /* This should succeed. */
2241 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2242 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN, 0, 0);
2245 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2250 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2251 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1->tree));
2256 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2257 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1->tree));
2262 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum2))) {
2263 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1->tree));
2268 /* This should fail - file should no longer be there. */
2270 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2272 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2273 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2274 printf("[3] close failed (%s)\n", cli_errstr(cli1->tree));
2276 cli_unlink(cli1->tree, fname);
2280 printf("third delete on close test succeeded.\n");
2283 cli_setatr(cli1->tree, fname, 0, 0);
2284 cli_unlink(cli1->tree, fname);
2286 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
2287 SA_RIGHT_FILE_READ_DATA |
2288 SA_RIGHT_FILE_WRITE_DATA |
2289 STD_RIGHT_DELETE_ACCESS,
2290 FILE_ATTRIBUTE_NORMAL,
2291 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2292 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2295 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2300 /* This should succeed. */
2301 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2302 FILE_ATTRIBUTE_NORMAL,
2303 NTCREATEX_SHARE_ACCESS_READ |
2304 NTCREATEX_SHARE_ACCESS_WRITE |
2305 NTCREATEX_SHARE_ACCESS_DELETE,
2306 NTCREATEX_DISP_OPEN, 0, 0);
2308 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2313 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum2))) {
2314 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1->tree));
2319 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2320 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1->tree));
2325 /* This should fail - no more opens once delete on close set. */
2326 fnum2 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ,
2327 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2328 NTCREATEX_DISP_OPEN, 0, 0);
2330 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2334 printf("fourth delete on close test succeeded.\n");
2336 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2337 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2343 cli_setatr(cli1->tree, fname, 0, 0);
2344 cli_unlink(cli1->tree, fname);
2346 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
2348 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2353 /* This should fail - only allowed on NT opens with DELETE access. */
2355 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2356 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2361 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2362 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2367 printf("fifth delete on close test succeeded.\n");
2370 cli_setatr(cli1->tree, fname, 0, 0);
2371 cli_unlink(cli1->tree, fname);
2373 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
2374 SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA,
2375 FILE_ATTRIBUTE_NORMAL,
2376 NTCREATEX_SHARE_ACCESS_READ |
2377 NTCREATEX_SHARE_ACCESS_WRITE |
2378 NTCREATEX_SHARE_ACCESS_DELETE,
2379 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2382 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2387 /* This should fail - only allowed on NT opens with DELETE access. */
2389 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2390 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2395 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2396 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2401 printf("sixth delete on close test succeeded.\n");
2404 cli_setatr(cli1->tree, fname, 0, 0);
2405 cli_unlink(cli1->tree, fname);
2407 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
2408 SA_RIGHT_FILE_READ_DATA |
2409 SA_RIGHT_FILE_WRITE_DATA |
2410 STD_RIGHT_DELETE_ACCESS,
2411 FILE_ATTRIBUTE_NORMAL, 0, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2414 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2419 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2420 printf("[7] setting delete_on_close on file failed !\n");
2425 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, False))) {
2426 printf("[7] unsetting delete_on_close on file failed !\n");
2431 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2432 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2437 /* This next open should succeed - we reset the flag. */
2439 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2441 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2446 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2447 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2452 printf("seventh delete on close test succeeded.\n");
2455 cli_setatr(cli1->tree, fname, 0, 0);
2456 cli_unlink(cli1->tree, fname);
2458 if (!torture_open_connection(&cli2)) {
2459 printf("[8] failed to open second connection.\n");
2464 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2465 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2466 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2469 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2474 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2475 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2476 NTCREATEX_DISP_OPEN, 0, 0);
2479 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2484 if (NT_STATUS_IS_ERR(cli_nt_delete_on_close(cli1->tree, fnum1, True))) {
2485 printf("[8] setting delete_on_close on file failed !\n");
2490 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2491 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1->tree));
2496 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
2497 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2->tree));
2502 /* This should fail.. */
2503 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2505 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2509 printf("eighth delete on close test succeeded.\n");
2511 /* This should fail - we need to set DELETE_ACCESS. */
2512 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
2513 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2516 printf("[9] open of %s succeeded should have failed!\n", fname);
2521 printf("ninth delete on close test succeeded.\n");
2523 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2524 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2526 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2531 /* This should delete the file. */
2532 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2533 printf("[10] close failed (%s)\n", cli_errstr(cli1->tree));
2538 /* This should fail.. */
2539 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_NONE);
2541 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2545 printf("tenth delete on close test succeeded.\n");
2546 printf("finished delete test\n");
2549 /* FIXME: This will crash if we aborted before cli2 got
2550 * intialized, because these functions don't handle
2551 * uninitialized connections. */
2553 cli_close(cli1->tree, fnum1);
2554 cli_close(cli1->tree, fnum2);
2555 cli_setatr(cli1->tree, fname, 0, 0);
2556 cli_unlink(cli1->tree, fname);
2558 if (!torture_close_connection(cli1)) {
2561 if (!torture_close_connection(cli2)) {
2569 print out server properties
2571 static BOOL run_properties(int dummy)
2573 struct cli_state *cli;
2574 BOOL correct = True;
2576 printf("starting properties test\n");
2580 if (!torture_open_connection(&cli)) {
2584 d_printf("Capabilities 0x%08x\n", cli->transport->negotiate.capabilities);
2586 if (!torture_close_connection(cli)) {
2595 /* FIRST_DESIRED_ACCESS 0xf019f */
2596 #define FIRST_DESIRED_ACCESS SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_APPEND_DATA|\
2597 SA_RIGHT_FILE_READ_EA| /* 0xf */ \
2598 SA_RIGHT_FILE_WRITE_EA|SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x90 */ \
2599 SA_RIGHT_FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
2600 STD_RIGHT_DELETE_ACCESS|STD_RIGHT_READ_CONTROL_ACCESS|\
2601 STD_RIGHT_WRITE_DAC_ACCESS|STD_RIGHT_WRITE_OWNER_ACCESS /* 0xf0000 */
2602 /* SECOND_DESIRED_ACCESS 0xe0080 */
2603 #define SECOND_DESIRED_ACCESS SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x80 */ \
2604 STD_RIGHT_READ_CONTROL_ACCESS|STD_RIGHT_WRITE_DAC_ACCESS|\
2605 STD_RIGHT_WRITE_OWNER_ACCESS /* 0xe0000 */
2608 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
2609 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2610 SA_RIGHT_FILE_READ_DATA|\
2611 WRITE_OWNER_ACCESS /* */
2615 Test ntcreate calls made by xcopy
2617 static BOOL run_xcopy(int dummy)
2619 struct cli_state *cli1;
2620 const char *fname = "\\test.txt";
2621 BOOL correct = True;
2624 printf("starting xcopy test\n");
2626 if (!torture_open_connection(&cli1)) {
2630 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
2631 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2632 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF,
2636 printf("First open failed - %s\n", cli_errstr(cli1->tree));
2640 fnum2 = cli_nt_create_full(cli1->tree, fname, 0,
2641 SECOND_DESIRED_ACCESS, 0,
2642 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
2645 printf("second open failed - %s\n", cli_errstr(cli1->tree));
2649 if (!torture_close_connection(cli1)) {
2657 Test rename on files open with share delete and no share delete.
2659 static BOOL run_rename(int dummy)
2661 struct cli_state *cli1;
2662 const char *fname = "\\test.txt";
2663 const char *fname1 = "\\test1.txt";
2664 BOOL correct = True;
2667 printf("starting rename test\n");
2669 if (!torture_open_connection(&cli1)) {
2673 cli_unlink(cli1->tree, fname);
2674 cli_unlink(cli1->tree, fname1);
2675 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2676 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2679 printf("First open failed - %s\n", cli_errstr(cli1->tree));
2683 if (NT_STATUS_IS_ERR(cli_rename(cli1->tree, fname, fname1))) {
2684 printf("First rename failed (this is correct) - %s\n", cli_errstr(cli1->tree));
2686 printf("First rename succeeded - this should have failed !\n");
2690 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2691 printf("close - 1 failed (%s)\n", cli_errstr(cli1->tree));
2695 cli_unlink(cli1->tree, fname);
2696 cli_unlink(cli1->tree, fname1);
2697 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2698 NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2701 printf("Second open failed - %s\n", cli_errstr(cli1->tree));
2705 if (NT_STATUS_IS_ERR(cli_rename(cli1->tree, fname, fname1))) {
2706 printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(cli1->tree));
2709 printf("Second rename succeeded\n");
2712 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2713 printf("close - 2 failed (%s)\n", cli_errstr(cli1->tree));
2717 cli_unlink(cli1->tree, fname);
2718 cli_unlink(cli1->tree, fname1);
2720 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2721 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2724 printf("Third open failed - %s\n", cli_errstr(cli1->tree));
2729 if (NT_STATUS_IS_ERR(cli_rename(cli1->tree, fname, fname1))) {
2730 printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(cli1->tree));
2733 printf("Third rename succeeded\n");
2736 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2737 printf("close - 3 failed (%s)\n", cli_errstr(cli1->tree));
2741 cli_unlink(cli1->tree, fname);
2742 cli_unlink(cli1->tree, fname1);
2744 if (!torture_close_connection(cli1)) {
2753 see how many RPC pipes we can open at once
2755 static BOOL run_pipe_number(int dummy)
2757 struct cli_state *cli1;
2758 const char *pipe_name = "\\WKSSVC";
2762 printf("starting pipenumber test\n");
2763 if (!torture_open_connection(&cli1)) {
2768 fnum = cli_nt_create_full(cli1->tree, pipe_name, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
2769 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
2772 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1->tree));
2776 printf("%d\r", num_pipes);
2780 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
2781 torture_close_connection(cli1);
2789 open N connections to the server and just hold them open
2790 used for testing performance when there are N idle users
2793 static BOOL torture_holdcon(int dummy)
2796 struct cli_state **cli;
2799 printf("Opening %d connections\n", torture_numops);
2801 cli = malloc(sizeof(struct cli_state *) * torture_numops);
2803 for (i=0;i<torture_numops;i++) {
2804 if (!torture_open_connection(&cli[i])) {
2807 printf("opened %d connections\r", i);
2811 printf("\nStarting pings\n");
2814 for (i=0;i<torture_numops;i++) {
2817 status = cli_chkpath(cli[i]->tree, "\\");
2818 if (!NT_STATUS_IS_OK(status)) {
2819 printf("Connection %d is dead\n", i);
2827 if (num_dead == torture_numops) {
2828 printf("All connections dead - finishing\n");
2840 Try with a wrong vuid and check error message.
2843 static BOOL run_vuidtest(int dummy)
2845 struct cli_state *cli;
2846 const char *fname = "\\vuid.tst";
2849 time_t c_time, a_time, m_time;
2850 BOOL correct = True;
2855 printf("starting vuid test\n");
2857 if (!torture_open_connection(&cli)) {
2861 cli_unlink(cli->tree, fname);
2863 fnum = cli_open(cli->tree, fname,
2864 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2866 orig_vuid = cli->session->vuid;
2868 cli->session->vuid += 1234;
2870 printf("Testing qfileinfo with wrong vuid\n");
2872 if (NT_STATUS_IS_OK(result = cli_qfileinfo(cli->tree, fnum, NULL,
2873 &size, &c_time, &a_time,
2874 &m_time, NULL, NULL))) {
2875 printf("ERROR: qfileinfo passed with wrong vuid\n");
2879 if ( (cli->transport->error.etype != ETYPE_DOS) ||
2880 (cli->transport->error.e.dos.eclass != ERRSRV) ||
2881 (cli->transport->error.e.dos.ecode != ERRbaduid) ) {
2882 printf("ERROR: qfileinfo should have returned DOS error "
2883 "ERRSRV:ERRbaduid\n but returned %s\n",
2884 cli_errstr(cli->tree));
2888 cli->session->vuid -= 1234;
2890 if (NT_STATUS_IS_ERR(cli_close(cli->tree, fnum))) {
2891 printf("close failed (%s)\n", cli_errstr(cli->tree));
2895 cli_unlink(cli->tree, fname);
2897 if (!torture_close_connection(cli)) {
2901 printf("vuid test finished\n");
2907 Test open mode returns on read-only files.
2909 static BOOL run_opentest(int dummy)
2911 static struct cli_state *cli1;
2912 static struct cli_state *cli2;
2913 const char *fname = "\\readonly.file";
2917 BOOL correct = True;
2921 printf("starting open test\n");
2923 if (!torture_open_connection(&cli1)) {
2927 cli_setatr(cli1->tree, fname, 0, 0);
2928 cli_unlink(cli1->tree, fname);
2930 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2932 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2936 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2937 printf("close2 failed (%s)\n", cli_errstr(cli1->tree));
2941 if (NT_STATUS_IS_ERR(cli_setatr(cli1->tree, fname, FILE_ATTRIBUTE_READONLY, 0))) {
2942 printf("cli_setatr failed (%s)\n", cli_errstr(cli1->tree));
2943 CHECK_MAX_FAILURES(error_test1);
2947 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
2949 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2950 CHECK_MAX_FAILURES(error_test1);
2954 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
2955 fnum2 = cli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
2957 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
2958 NT_STATUS_ACCESS_DENIED)) {
2959 printf("correct error code ERRDOS/ERRnoaccess returned\n");
2962 printf("finished open test 1\n");
2964 cli_close(cli1->tree, fnum1);
2966 /* Now try not readonly and ensure ERRbadshare is returned. */
2968 cli_setatr(cli1->tree, fname, 0, 0);
2970 fnum1 = cli_open(cli1->tree, fname, O_RDONLY, DENY_WRITE);
2972 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
2976 /* This will fail - but the error should be ERRshare. */
2977 fnum2 = cli_open(cli1->tree, fname, O_RDWR, DENY_ALL);
2979 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
2980 NT_STATUS_SHARING_VIOLATION)) {
2981 printf("correct error code ERRDOS/ERRbadshare returned\n");
2984 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
2985 printf("close2 failed (%s)\n", cli_errstr(cli1->tree));
2989 cli_unlink(cli1->tree, fname);
2991 printf("finished open test 2\n");
2993 /* Test truncate open disposition on file opened for read. */
2995 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2997 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3001 /* write 20 bytes. */
3003 memset(buf, '\0', 20);
3005 if (cli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
3006 printf("write failed (%s)\n", cli_errstr(cli1->tree));
3010 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3011 printf("(3) close1 failed (%s)\n", cli_errstr(cli1->tree));
3015 /* Ensure size == 20. */
3016 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3017 printf("(3) getatr failed (%s)\n", cli_errstr(cli1->tree));
3018 CHECK_MAX_FAILURES(error_test3);
3023 printf("(3) file size != 20\n");
3024 CHECK_MAX_FAILURES(error_test3);
3028 /* Now test if we can truncate a file opened for readonly. */
3030 fnum1 = cli_open(cli1->tree, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3032 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3033 CHECK_MAX_FAILURES(error_test3);
3037 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3038 printf("close2 failed (%s)\n", cli_errstr(cli1->tree));
3042 /* Ensure size == 0. */
3043 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3044 printf("(3) getatr failed (%s)\n", cli_errstr(cli1->tree));
3045 CHECK_MAX_FAILURES(error_test3);
3050 printf("(3) file size != 0\n");
3051 CHECK_MAX_FAILURES(error_test3);
3054 printf("finished open test 3\n");
3056 cli_unlink(cli1->tree, fname);
3059 printf("testing ctemp\n");
3060 fnum1 = cli_ctemp(cli1->tree, "\\", &tmp_path);
3062 printf("ctemp failed (%s)\n", cli_errstr(cli1->tree));
3063 CHECK_MAX_FAILURES(error_test4);
3066 printf("ctemp gave path %s\n", tmp_path);
3067 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3068 printf("close of temp failed (%s)\n", cli_errstr(cli1->tree));
3070 if (NT_STATUS_IS_ERR(cli_unlink(cli1->tree, tmp_path))) {
3071 printf("unlink of temp failed (%s)\n", cli_errstr(cli1->tree));
3074 /* Test the non-io opens... */
3076 if (!torture_open_connection(&cli2)) {
3080 cli_setatr(cli2->tree, fname, 0, 0);
3081 cli_unlink(cli2->tree, fname);
3083 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3085 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3086 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3089 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3090 CHECK_MAX_FAILURES(error_test10);
3094 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3095 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3097 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3098 CHECK_MAX_FAILURES(error_test10);
3102 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3103 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3106 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3107 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3111 printf("non-io open test #1 passed.\n");
3113 cli_unlink(cli1->tree, fname);
3115 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3117 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3118 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3121 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3122 CHECK_MAX_FAILURES(error_test20);
3126 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3127 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3130 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3131 CHECK_MAX_FAILURES(error_test20);
3135 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3136 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3139 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3140 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3144 printf("non-io open test #2 passed.\n");
3146 cli_unlink(cli1->tree, fname);
3148 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3150 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3151 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3154 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3155 CHECK_MAX_FAILURES(error_test30);
3159 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3160 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3163 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3164 CHECK_MAX_FAILURES(error_test30);
3168 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3169 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3172 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3173 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3177 printf("non-io open test #3 passed.\n");
3179 cli_unlink(cli1->tree, fname);
3181 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3183 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3184 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3187 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3188 CHECK_MAX_FAILURES(error_test40);
3192 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3193 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3196 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2->tree));
3197 CHECK_MAX_FAILURES(error_test40);
3201 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2->tree), "sharing violation");
3203 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3204 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3208 printf("non-io open test #4 passed.\n");
3210 cli_unlink(cli1->tree, fname);
3212 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3214 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3215 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3218 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3219 CHECK_MAX_FAILURES(error_test50);
3223 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3224 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3227 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3228 CHECK_MAX_FAILURES(error_test50);
3232 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3233 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3237 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3238 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3242 printf("non-io open test #5 passed.\n");
3244 printf("TEST #6 testing 1 non-io open, one io open\n");
3246 cli_unlink(cli1->tree, fname);
3248 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3249 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3252 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3253 CHECK_MAX_FAILURES(error_test60);
3257 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3258 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
3261 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3262 CHECK_MAX_FAILURES(error_test60);
3266 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3267 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3271 if (NT_STATUS_IS_ERR(cli_close(cli2->tree, fnum2))) {
3272 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2->tree));
3276 printf("non-io open test #6 passed.\n");
3278 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3280 cli_unlink(cli1->tree, fname);
3282 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3283 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3286 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3287 CHECK_MAX_FAILURES(error_test70);
3291 fnum2 = cli_nt_create_full(cli2->tree, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3292 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3295 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2->tree));
3296 CHECK_MAX_FAILURES(error_test70);
3300 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2->tree), "sharing violation");
3302 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3303 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3307 printf("non-io open test #7 passed.\n");
3311 printf("TEST #8 testing one normal open, followed by lock, followed by open with truncate\n");
3313 cli_unlink(cli1->tree, fname);
3315 fnum1 = cli_open(cli1->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3317 printf("(8) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1->tree));
3321 /* write 20 bytes. */
3323 memset(buf, '\0', 20);
3325 if (cli_write(cli1->tree, fnum1, 0, buf, 0, 20) != 20) {
3326 printf("(8) write failed (%s)\n", cli_errstr(cli1->tree));
3330 /* Ensure size == 20. */
3331 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3332 printf("(8) getatr (1) failed (%s)\n", cli_errstr(cli1->tree));
3333 CHECK_MAX_FAILURES(error_test80);
3338 printf("(8) file size != 20\n");
3339 CHECK_MAX_FAILURES(error_test80);
3343 /* Get an exclusive lock on the open file. */
3344 if (NT_STATUS_IS_ERR(cli_lock(cli1->tree, fnum1, 0, 4, 0, WRITE_LOCK))) {
3345 printf("(8) lock1 failed (%s)\n", cli_errstr(cli1->tree));
3346 CHECK_MAX_FAILURES(error_test80);
3350 fnum2 = cli_open(cli1->tree, fname, O_RDWR|O_TRUNC, DENY_NONE);
3352 printf("(8) open (2) of %s with truncate failed (%s)\n", fname, cli_errstr(cli1->tree));
3356 /* Ensure size == 0. */
3357 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, NULL, &fsize, NULL))) {
3358 printf("(8) getatr (2) failed (%s)\n", cli_errstr(cli1->tree));
3359 CHECK_MAX_FAILURES(error_test80);
3364 printf("(8) file size != 0\n");
3365 CHECK_MAX_FAILURES(error_test80);
3369 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3370 printf("(8) close1 failed (%s)\n", cli_errstr(cli1->tree));
3374 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum2))) {
3375 printf("(8) close1 failed (%s)\n", cli_errstr(cli1->tree));
3381 printf("open test #8 passed.\n");
3383 cli_unlink(cli1->tree, fname);
3385 if (!torture_close_connection(cli1)) {
3388 if (!torture_close_connection(cli2)) {
3396 static uint32_t open_attrs_table[] = {
3397 FILE_ATTRIBUTE_NORMAL,
3398 FILE_ATTRIBUTE_ARCHIVE,
3399 FILE_ATTRIBUTE_READONLY,
3400 FILE_ATTRIBUTE_HIDDEN,
3401 FILE_ATTRIBUTE_SYSTEM,
3403 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
3404 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
3405 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
3406 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3407 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3408 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3410 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3411 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3412 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3413 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
3416 struct trunc_open_results {
3419 uint32_t trunc_attr;
3420 uint32_t result_attr;
3423 static struct trunc_open_results attr_results[] = {
3424 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3425 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3426 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3427 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3428 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3429 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3430 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3431 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3432 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3433 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3434 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3435 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
3436 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3437 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3438 { 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 },
3439 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3440 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3441 { 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 },
3442 { 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 },
3443 { 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 },
3444 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3445 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3446 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3447 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3448 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3449 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
3452 static BOOL run_openattrtest(int dummy)
3454 struct cli_state *cli1;
3455 const char *fname = "\\openattr.file";
3457 BOOL correct = True;
3462 printf("starting open attr test\n");
3464 if (!torture_open_connection(&cli1)) {
3468 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
3469 cli_setatr(cli1->tree, fname, 0, 0);
3470 cli_unlink(cli1->tree, fname);
3471 fnum1 = cli_nt_create_full(cli1->tree, fname, 0, SA_RIGHT_FILE_WRITE_DATA, open_attrs_table[i],
3472 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3475 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1->tree));
3479 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3480 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1->tree));
3484 for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
3485 fnum1 = cli_nt_create_full(cli1->tree, fname, 0,
3486 SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
3487 open_attrs_table[j],
3488 NTCREATEX_SHARE_ACCESS_NONE,
3489 NTCREATEX_DISP_OVERWRITE, 0, 0);
3492 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3493 if (attr_results[l].num == k) {
3494 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
3495 k, open_attrs_table[i],
3496 open_attrs_table[j],
3497 fname, NT_STATUS_V(cli_nt_error(cli1->tree)), cli_errstr(cli1->tree));
3499 CHECK_MAX_FAILURES(error_exit);
3502 if (NT_STATUS_V(cli_nt_error(cli1->tree)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
3503 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
3504 k, open_attrs_table[i], open_attrs_table[j],
3505 cli_errstr(cli1->tree));
3507 CHECK_MAX_FAILURES(error_exit);
3510 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
3516 if (NT_STATUS_IS_ERR(cli_close(cli1->tree, fnum1))) {
3517 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1->tree));
3521 if (NT_STATUS_IS_ERR(cli_getatr(cli1->tree, fname, &attr, NULL, NULL))) {
3522 printf("getatr(2) failed (%s)\n", cli_errstr(cli1->tree));
3527 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
3528 k, open_attrs_table[i], open_attrs_table[j], attr );
3531 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3532 if (attr_results[l].num == k) {
3533 if (attr != attr_results[l].result_attr ||
3534 open_attrs_table[i] != attr_results[l].init_attr ||
3535 open_attrs_table[j] != attr_results[l].trunc_attr) {
3536 printf("[%d] getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
3537 k, open_attrs_table[i],
3538 open_attrs_table[j],
3540 attr_results[l].result_attr);
3542 CHECK_MAX_FAILURES(error_exit);
3551 cli_setatr(cli1->tree, fname, 0, 0);
3552 cli_unlink(cli1->tree, fname);
3554 printf("open attr test %s.\n", correct ? "passed" : "failed");
3556 if (!torture_close_connection(cli1)) {
3562 static void list_fn(file_info *finfo, const char *name, void *state)
3568 test directory listing speed
3570 static BOOL run_dirtest(int dummy)
3573 struct cli_state *cli;
3576 BOOL correct = True;
3578 printf("starting directory test\n");
3580 if (!torture_open_connection(&cli)) {
3584 printf("Creating %d random filenames\n", torture_numops);
3587 for (i=0;i<torture_numops;i++) {
3589 asprintf(&fname, "\\%x", (int)random());
3590 fnum = cli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE);
3592 fprintf(stderr,"Failed to open %s\n", fname);
3595 cli_close(cli->tree, fnum);
3601 printf("Matched %d\n", cli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3602 printf("Matched %d\n", cli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3603 printf("Matched %d\n", cli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3605 printf("dirtest core %g seconds\n", end_timer() - t1);
3608 for (i=0;i<torture_numops;i++) {
3610 asprintf(&fname, "\\%x", (int)random());
3611 cli_unlink(cli->tree, fname);
3615 if (!torture_close_connection(cli)) {
3619 printf("finished dirtest\n");
3625 sees what IOCTLs are supported
3627 BOOL torture_ioctl_test(int dummy)
3629 struct cli_state *cli;
3630 uint16_t device, function;
3632 const char *fname = "\\ioctl.dat";
3634 union smb_ioctl parms;
3635 TALLOC_CTX *mem_ctx;
3637 if (!torture_open_connection(&cli)) {
3641 mem_ctx = talloc_init("ioctl_test");
3643 printf("starting ioctl test\n");
3645 cli_unlink(cli->tree, fname);
3647 fnum = cli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3649 printf("open of %s failed (%s)\n", fname, cli_errstr(cli->tree));
3653 parms.ioctl.level = RAW_IOCTL_IOCTL;
3654 parms.ioctl.in.fnum = fnum;
3655 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
3656 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3657 printf("ioctl job info: %s\n", cli_errstr(cli->tree));
3659 for (device=0;device<0x100;device++) {
3660 printf("testing device=0x%x\n", device);
3661 for (function=0;function<0x100;function++) {
3662 parms.ioctl.in.request = (device << 16) | function;
3663 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3665 if (NT_STATUS_IS_OK(status)) {
3666 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
3667 device, function, parms.ioctl.out.blob.length);
3672 if (!torture_close_connection(cli)) {
3681 tries variants of chkpath
3683 BOOL torture_chkpath_test(int dummy)
3685 struct cli_state *cli;
3689 if (!torture_open_connection(&cli)) {
3693 printf("starting chkpath test\n");
3695 printf("Testing valid and invalid paths\n");
3697 /* cleanup from an old run */
3698 cli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3699 cli_unlink(cli->tree, "\\chkpath.dir\\*");
3700 cli_rmdir(cli->tree, "\\chkpath.dir");
3702 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, "\\chkpath.dir"))) {
3703 printf("mkdir1 failed : %s\n", cli_errstr(cli->tree));
3707 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, "\\chkpath.dir\\dir2"))) {
3708 printf("mkdir2 failed : %s\n", cli_errstr(cli->tree));
3712 fnum = cli_open(cli->tree, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3714 printf("open1 failed (%s)\n", cli_errstr(cli->tree));
3717 cli_close(cli->tree, fnum);
3719 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir"))) {
3720 printf("chkpath1 failed: %s\n", cli_errstr(cli->tree));
3724 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir\\dir2"))) {
3725 printf("chkpath2 failed: %s\n", cli_errstr(cli->tree));
3729 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir\\foo.txt"))) {
3730 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3731 NT_STATUS_NOT_A_DIRECTORY);
3733 printf("* chkpath on a file should fail\n");
3737 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir\\bar.txt"))) {
3738 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
3739 NT_STATUS_OBJECT_NAME_NOT_FOUND);
3741 printf("* chkpath on a non existent file should fail\n");
3745 if (NT_STATUS_IS_ERR(cli_chkpath(cli->tree, "\\chkpath.dir\\dirxx\\bar.txt"))) {
3746 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3747 NT_STATUS_OBJECT_PATH_NOT_FOUND);
3749 printf("* chkpath on a non existent component should fail\n");
3753 cli_rmdir(cli->tree, "\\chkpath.dir\\dir2");
3754 cli_unlink(cli->tree, "\\chkpath.dir\\*");
3755 cli_rmdir(cli->tree, "\\chkpath.dir");
3757 if (!torture_close_connection(cli)) {
3764 static BOOL run_dirtest1(int dummy)
3767 struct cli_state *cli;
3769 BOOL correct = True;
3771 printf("starting directory test\n");
3773 if (!torture_open_connection(&cli)) {
3777 if (cli_deltree(cli->tree, "\\LISTDIR") == -1) {
3778 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", cli_errstr(cli->tree));
3781 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, "\\LISTDIR"))) {
3782 fprintf(stderr,"Failed to mkdir %s, error=%s\n", "\\LISTDIR", cli_errstr(cli->tree));
3786 printf("Creating %d files\n", torture_entries);
3788 /* Create torture_entries files and torture_entries directories. */
3789 for (i=0;i<torture_entries;i++) {
3791 asprintf(&fname, "\\LISTDIR\\f%d", i);
3792 fnum = cli_nt_create_full(cli->tree, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3793 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3795 fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli->tree));
3799 cli_close(cli->tree, fnum);
3801 for (i=0;i<torture_entries;i++) {
3803 asprintf(&fname, "\\LISTDIR\\d%d", i);
3804 if (NT_STATUS_IS_ERR(cli_mkdir(cli->tree, fname))) {
3805 fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli->tree));
3811 /* Now ensure that doing an old list sees both files and directories. */
3812 num_seen = cli_list_old(cli->tree, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3813 printf("num_seen = %d\n", num_seen );
3814 /* We should see (torture_entries) each of files & directories + . and .. */
3815 if (num_seen != (2*torture_entries)+2) {
3817 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3818 (2*torture_entries)+2, num_seen);
3822 /* Ensure if we have the "must have" bits we only see the
3825 num_seen = cli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3826 printf("num_seen = %d\n", num_seen );
3827 if (num_seen != torture_entries+2) {
3829 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3830 torture_entries+2, num_seen);
3833 num_seen = cli_list_old(cli->tree, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3834 printf("num_seen = %d\n", num_seen );
3835 if (num_seen != torture_entries) {
3837 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3838 torture_entries, num_seen);
3841 /* Delete everything. */
3842 if (cli_deltree(cli->tree, "\\LISTDIR") == -1) {
3843 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", cli_errstr(cli->tree));
3848 printf("Matched %d\n", cli_list(cli->tree, "a*.*", 0, list_fn, NULL));
3849 printf("Matched %d\n", cli_list(cli->tree, "b*.*", 0, list_fn, NULL));
3850 printf("Matched %d\n", cli_list(cli->tree, "xyzabc", 0, list_fn, NULL));
3853 if (!torture_close_connection(cli)) {
3857 printf("finished dirtest1\n");
3864 simple test harness for playing with deny modes
3866 static BOOL run_deny3test(int dummy)
3868 struct cli_state *cli1, *cli2;
3872 printf("starting deny3 test\n");
3874 printf("Testing simple deny modes\n");
3876 if (!torture_open_connection(&cli1)) {
3879 if (!torture_open_connection(&cli2)) {
3883 fname = "\\deny_dos1.dat";
3885 cli_unlink(cli1->tree, fname);
3886 fnum1 = cli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3887 fnum2 = cli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3888 if (fnum1 != -1) cli_close(cli1->tree, fnum1);
3889 if (fnum2 != -1) cli_close(cli1->tree, fnum2);
3890 cli_unlink(cli1->tree, fname);
3891 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3894 fname = "\\deny_dos2.dat";
3896 cli_unlink(cli1->tree, fname);
3897 fnum1 = cli_open(cli1->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3898 fnum2 = cli_open(cli2->tree, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3899 if (fnum1 != -1) cli_close(cli1->tree, fnum1);
3900 if (fnum2 != -1) cli_close(cli2->tree, fnum2);
3901 cli_unlink(cli1->tree, fname);
3902 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3905 torture_close_connection(cli1);
3906 torture_close_connection(cli2);
3912 parse a //server/share type UNC name
3914 static BOOL parse_unc(const char *unc_name, char **hostname, char **sharename)
3918 if (strncmp(unc_name, "//", 2)) {
3922 *hostname = strdup(&unc_name[2]);
3923 p = strchr_m(&(*hostname)[2],'/');
3928 *sharename = strdup(p+1);
3935 static void sigcont(void)
3939 double torture_create_procs(BOOL (*fn)(struct cli_state *, int), BOOL *result)
3942 volatile pid_t *child_status;
3943 volatile BOOL *child_status_out;
3946 double start_time_limit = 10 + (torture_nprocs * 1.5);
3947 char **unc_list = NULL;
3949 int num_unc_names = 0;
3953 signal(SIGCONT, sigcont);
3955 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
3956 if (!child_status) {
3957 printf("Failed to setup shared memory\n");
3961 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*torture_nprocs);
3962 if (!child_status_out) {
3963 printf("Failed to setup result status shared memory\n");
3967 p = lp_parm_string(-1, "torture", "unclist");
3969 unc_list = file_lines_load(p, &num_unc_names);
3970 if (!unc_list || num_unc_names <= 0) {
3971 printf("Failed to load unc names list from %s\n", p);
3976 for (i = 0; i < torture_nprocs; i++) {
3977 child_status[i] = 0;
3978 child_status_out[i] = True;
3983 for (i=0;i<torture_nprocs;i++) {
3987 char *hostname=NULL, *sharename;
3989 pid_t mypid = getpid();
3990 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
3992 asprintf(&myname, "CLIENT%d", i);
3993 lp_set_cmdline("netbios name", myname);
3998 if (!parse_unc(unc_list[i % num_unc_names],
3999 &hostname, &sharename)) {
4000 printf("Failed to parse UNC name %s\n",
4001 unc_list[i % num_unc_names]);
4008 if (torture_open_connection_share(¤t_cli,
4013 } else if (torture_open_connection(¤t_cli)) {
4017 printf("pid %d failed to start\n", (int)getpid());
4023 child_status[i] = getpid();
4027 if (child_status[i]) {
4028 printf("Child %d failed to start!\n", i);
4029 child_status_out[i] = 1;
4033 child_status_out[i] = fn(current_cli, i);
4040 for (i=0;i<torture_nprocs;i++) {
4041 if (child_status[i]) synccount++;
4043 if (synccount == torture_nprocs) break;
4045 } while (end_timer() < start_time_limit);
4047 if (synccount != torture_nprocs) {
4048 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
4053 printf("Starting %d clients\n", torture_nprocs);
4055 /* start the client load */
4057 for (i=0;i<torture_nprocs;i++) {
4058 child_status[i] = 0;
4062 printf("%d clients started\n", torture_nprocs);
4064 for (i=0;i<torture_nprocs;i++) {
4066 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
4067 if (ret == -1 || WEXITSTATUS(status) != 0) {
4074 for (i=0;i<torture_nprocs;i++) {
4075 if (!child_status_out[i]) {
4082 #define FLAG_MULTIPROC 1
4090 {"BASE-FDPASS", run_fdpasstest, 0},
4091 {"BASE-LOCK1", run_locktest1, 0},
4092 {"BASE-LOCK2", run_locktest2, 0},
4093 {"BASE-LOCK3", run_locktest3, 0},
4094 {"BASE-LOCK4", run_locktest4, 0},
4095 {"BASE-LOCK5", run_locktest5, 0},
4096 {"BASE-LOCK6", run_locktest6, 0},
4097 {"BASE-LOCK7", run_locktest7, 0},
4098 {"BASE-UNLINK", run_unlinktest, 0},
4099 {"BASE-ATTR", run_attrtest, 0},
4100 {"BASE-TRANS2", run_trans2test, 0},
4101 {"BASE-NEGNOWAIT", run_negprot_nowait, 0},
4102 {"BASE-DIR", run_dirtest, 0},
4103 {"BASE-DIR1", run_dirtest1, 0},
4104 {"BASE-DENY1", torture_denytest1, 0},
4105 {"BASE-DENY2", torture_denytest2, 0},
4106 {"BASE-TCON", run_tcon_test, 0},
4107 {"BASE-TCONDEV", run_tcon_devtype_test, 0},
4108 {"BASE-VUID", run_vuidtest, 0},
4109 {"BASE-RW1", run_readwritetest, 0},
4110 {"BASE-RW2", run_readwritemulti, FLAG_MULTIPROC},
4111 {"BASE-OPEN", run_opentest, 0},
4112 {"BASE-DENY3", run_deny3test, 0},
4113 {"BASE-DEFER_OPEN", run_deferopen, FLAG_MULTIPROC},
4114 {"BASE-XCOPY", run_xcopy, 0},
4115 {"BASE-RENAME", run_rename, 0},
4116 {"BASE-DELETE", run_deletetest, 0},
4117 {"BASE-PROPERTIES", run_properties, 0},
4118 {"BASE-MANGLE", torture_mangle, 0},
4119 {"BASE-OPENATTR", run_openattrtest, 0},
4120 {"BASE-CHARSET", torture_charset, 0},
4121 {"BASE-CHKPATH", torture_chkpath_test, 0},
4123 /* benchmarking tests */
4124 {"BENCH-HOLDCON", torture_holdcon, 0},
4125 {"BENCH-NBENCH", torture_nbench, 0},
4126 {"BENCH-TORTURE",run_torture, FLAG_MULTIPROC},
4129 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
4130 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
4131 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
4132 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
4133 {"RAW-SEARCH", torture_raw_search, 0},
4134 {"RAW-CLOSE", torture_raw_close, 0},
4135 {"RAW-OPEN", torture_raw_open, 0},
4136 {"RAW-MKDIR", torture_raw_mkdir, 0},
4137 {"RAW-OPLOCK", torture_raw_oplock, 0},
4138 {"RAW-NOTIFY", torture_raw_notify, 0},
4139 {"RAW-MUX", torture_raw_mux, 0},
4140 {"RAW-IOCTL", torture_raw_ioctl, 0},
4141 {"RAW-CHKPATH", torture_raw_chkpath, 0},
4142 {"RAW-UNLINK", torture_raw_unlink, 0},
4143 {"RAW-READ", torture_raw_read, 0},
4144 {"RAW-WRITE", torture_raw_write, 0},
4145 {"RAW-LOCK", torture_raw_lock, 0},
4146 {"RAW-CONTEXT", torture_raw_context, 0},
4147 {"RAW-RENAME", torture_raw_rename, 0},
4148 {"RAW-SEEK", torture_raw_seek, 0},
4149 {"RAW-RAP", torture_raw_rap, 0},
4151 /* protocol scanners */
4152 {"SCAN-TRANS2", torture_trans2_scan, 0},
4153 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
4154 {"SCAN-ALIASES", torture_trans2_aliases, 0},
4155 {"SCAN-SMB", torture_smb_scan, 0},
4156 {"SCAN-MAXFID", run_maxfidtest, FLAG_MULTIPROC},
4157 {"SCAN-UTABLE", torture_utable, 0},
4158 {"SCAN-CASETABLE", torture_casetable, 0},
4159 {"SCAN-PIPE_NUMBER", run_pipe_number, 0},
4160 {"SCAN-IOCTL", torture_ioctl_test, 0},
4163 {"RPC-LSA", torture_rpc_lsa, 0},
4164 {"RPC-ECHO", torture_rpc_echo, 0},
4165 {"RPC-DFS", torture_rpc_dfs, 0},
4166 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
4167 {"RPC-SAMR", torture_rpc_samr, 0},
4168 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
4169 {"RPC-SCHANNEL", torture_rpc_schannel, 0},
4170 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
4171 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
4172 {"RPC-SVCCTL", torture_rpc_svcctl, 0},
4173 {"RPC-ATSVC", torture_rpc_atsvc, 0},
4174 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
4175 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
4176 {"RPC-WINREG", torture_rpc_winreg, 0},
4177 {"RPC-MGMT", torture_rpc_mgmt, 0},
4178 {"RPC-SCANNER", torture_rpc_scanner, 0},
4179 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
4180 {"RPC-MULTIBIND", torture_multi_bind, 0},
4181 {"RPC-DRSUAPI", torture_rpc_drsuapi, 0},
4183 /* crypto testers */
4184 {"CRYPT-NTLMSSP", torture_ntlmssp_self_check, 0},
4190 /****************************************************************************
4191 run a specified test or "ALL"
4192 ****************************************************************************/
4193 static BOOL run_test(const char *name)
4197 BOOL matched = False;
4199 if (strequal(name,"ALL")) {
4200 for (i=0;torture_ops[i].name;i++) {
4201 if (!run_test(torture_ops[i].name)) {
4208 for (i=0;torture_ops[i].name;i++) {
4209 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
4212 printf("Running %s\n", torture_ops[i].name);
4213 if (torture_ops[i].flags & FLAG_MULTIPROC) {
4215 t = torture_create_procs(torture_ops[i].fn, &result);
4218 printf("TEST %s FAILED!\n", torture_ops[i].name);
4223 if (!torture_ops[i].fn(0)) {
4225 printf("TEST %s FAILED!\n", torture_ops[i].name);
4229 printf("%s took %g secs\n\n", torture_ops[i].name, t);
4234 printf("Unknown torture operation '%s'\n", name);
4242 parse a username%password
4244 static void parse_user(const char *user)
4246 char *username, *password = NULL, *p;
4248 username = strdup(user);
4249 p = strchr_m(username,'%');
4252 password = strdup(p+1);
4255 lp_set_cmdline("torture:username", username);
4258 lp_set_cmdline("torture:password", password);
4261 if (!lp_parm_string(-1,"torture","password")) {
4262 password = getpass("password:");
4264 lp_set_cmdline("torture:password", password);
4268 static void usage(void)
4272 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
4274 printf("\t-d debuglevel\n");
4275 printf("\t-U user%%pass\n");
4276 printf("\t-k use kerberos\n");
4277 printf("\t-N numprocs\n");
4278 printf("\t-n my_netbios_name\n");
4279 printf("\t-W workgroup\n");
4280 printf("\t-o num_operations\n");
4281 printf("\t-e num files(entries)\n");
4282 printf("\t-O socket_options\n");
4283 printf("\t-m maximum protocol\n");
4284 printf("\t-L use oplocks\n");
4285 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
4286 printf("\t-t timelimit specify NBENCH time limit (seconds)\n");
4287 printf("\t-C filename specifies file with list of UNCs for connections\n");
4288 printf("\t-A showall\n");
4289 printf("\t-p port\n");
4290 printf("\t-s seed\n");
4291 printf("\t-f max failures\n");
4292 printf("\t-X enable dangerous tests\n");
4295 printf("tests are:");
4296 for (i=0;torture_ops[i].name;i++) {
4297 printf(" %s", torture_ops[i].name);
4301 printf("default test is ALL\n");
4306 /****************************************************************************
4308 ****************************************************************************/
4309 int main(int argc,char *argv[])
4313 BOOL correct = True;
4314 char *host, *share, *username;
4316 setup_logging("smbtorture", DEBUG_STDOUT);
4318 #ifdef HAVE_SETBUFFER
4319 setbuffer(stdout, NULL, 0);
4322 lp_load(dyn_CONFIGFILE,True,False,False);
4329 for(p = argv[1]; *p; p++)
4334 /* see if its a RPC transport specifier */
4335 if (strncmp(argv[1], "ncacn_", 6) == 0) {
4336 lp_set_cmdline("torture:binding", argv[1]);
4338 char *binding = NULL;
4340 if (!parse_unc(argv[1], &host, &share)) {
4344 lp_set_cmdline("torture:host", host);
4345 lp_set_cmdline("torture:share", share);
4346 asprintf(&binding, "ncacn_np:%s", host);
4347 lp_set_cmdline("torture:binding", binding);
4350 if (getenv("LOGNAME")) {
4351 username = strdup(getenv("LOGNAME"));
4353 lp_set_cmdline("torture:username", username);
4359 srandom(time(NULL));
4361 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:e:m:Ld:Ac:ks:f:s:t:C:X")) != EOF) {
4364 lp_set_cmdline("smb ports", optarg);
4367 lp_set_cmdline("workgroup", optarg);
4370 lp_set_cmdline("protocol", optarg);
4373 lp_set_cmdline("netbios name", optarg);
4376 lp_set_cmdline("debug level", optarg);
4377 setup_logging(NULL, DEBUG_STDOUT);
4380 lp_set_cmdline("socket options", optarg);
4383 srandom(atoi(optarg));
4386 torture_nprocs = atoi(optarg);
4389 torture_numops = atoi(optarg);
4392 torture_entries = atoi(optarg);
4398 torture_showall = True;
4401 lp_set_cmdline("torture:loadfile", optarg);
4404 lp_set_cmdline("torture:unclist", optarg);
4407 lp_set_cmdline("torture:timelimit", optarg);
4411 use_kerberos = True;
4413 d_printf("No kerberos support compiled in\n");
4421 torture_failures = atoi(optarg);
4425 lp_set_cmdline("torture:dangerous", "1");
4429 printf("Unknown option %c (%d)\n", (char)opt, opt);
4434 if (!lp_parm_string(-1,"torture","password")) {
4435 lp_set_cmdline("torture:password", "");
4438 if (argc == optind) {
4439 printf("You must specify a test to run, or 'ALL'\n");
4441 for (i=optind;i<argc;i++) {
4442 if (!run_test(argv[i])) {