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 const char *client_txt = "client_oplocks.txt";
32 static BOOL use_kerberos;
34 BOOL torture_showall = False;
36 static double create_procs(BOOL (*fn)(int), BOOL *result);
38 #define CHECK_MAX_FAILURES(label) do { if (++failures >= torture_failures) goto label; } while (0)
40 static struct cli_state *open_nbt_connection(void)
42 struct nmb_name called, calling;
44 struct cli_state *cli;
45 char *host = lp_parm_string(-1, "torture", "host");
47 make_nmb_name(&calling, lp_netbios_name(), 0x0);
48 make_nmb_name(&called , host, 0x20);
52 cli = cli_state_init();
54 printf("Failed initialize cli_struct to connect with %s\n", host);
58 if (!cli_socket_connect(cli, host, &ip)) {
59 printf("Failed to connect with %s\n", host);
63 cli->transport->socket->timeout = 120000; /* set a really long timeout (2 minutes) */
65 if (!cli_transport_establish(cli, &calling, &called)) {
67 * Well, that failed, try *SMBSERVER ...
68 * However, we must reconnect as well ...
70 if (!cli_socket_connect(cli, host, &ip)) {
71 printf("Failed to connect with %s\n", host);
75 make_nmb_name(&called, "*SMBSERVER", 0x20);
76 if (!cli_transport_establish(cli, &calling, &called)) {
77 printf("%s rejected the session\n",host);
78 printf("We tried with a called name of %s & %s\n",
88 BOOL torture_open_connection(struct cli_state **c)
93 char *host = lp_parm_string(-1, "torture", "host");
94 char *share = lp_parm_string(-1, "torture", "share");
95 char *username = lp_parm_string(-1, "torture", "username");
96 char *password = lp_parm_string(-1, "torture", "password");
99 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
101 status = cli_full_connection(c, lp_netbios_name(),
104 username, username[0]?lp_workgroup():"",
105 password, flags, &retry);
106 if (!NT_STATUS_IS_OK(status)) {
107 printf("Failed to open connection - %s\n", nt_errstr(status));
111 (*c)->transport->options.use_oplocks = use_oplocks;
112 (*c)->transport->options.use_level2_oplocks = use_level_II_oplocks;
113 (*c)->transport->socket->timeout = 120000;
118 BOOL torture_close_connection(struct cli_state *c)
121 DEBUG(9,("torture_close_connection: cli_state@%p\n", c));
124 printf("tdis failed (%s)\n", cli_errstr(c));
127 DEBUG(9,("torture_close_connection: call cli_shutdown\n"));
129 DEBUG(9,("torture_close_connection: exit\n"));
134 /* open a rpc connection to a named pipe */
135 NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p,
136 const char *pipe_name,
137 const char *pipe_uuid,
141 char *binding = lp_parm_string(-1, "torture", "binding");
144 printf("You must specify a ncacn binding string\n");
145 return NT_STATUS_INVALID_PARAMETER;
148 status = dcerpc_pipe_connect(p, binding, pipe_uuid, pipe_version,
150 lp_parm_string(-1, "torture", "username"),
151 lp_parm_string(-1, "torture", "password"));
156 /* close a rpc connection to a named pipe */
157 NTSTATUS torture_rpc_close(struct dcerpc_pipe *p)
159 dcerpc_pipe_close(p);
164 /* check if the server produced the expected error code */
165 static BOOL check_error(int line, struct cli_state *c,
166 uint8 eclass, uint32 ecode, NTSTATUS nterr)
168 if (cli_is_dos_error(c)) {
172 /* Check DOS error */
174 cli_dos_error(c, &class, &num);
176 if (eclass != class || ecode != num) {
177 printf("unexpected error code class=%d code=%d\n",
178 (int)class, (int)num);
179 printf(" expected %d/%d %s (line=%d)\n",
180 (int)eclass, (int)ecode, nt_errstr(nterr), line);
189 status = cli_nt_error(c);
191 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
192 printf("unexpected error code %s\n", nt_errstr(status));
193 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
202 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
204 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
205 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
211 static BOOL rw_torture(struct cli_state *c)
213 const char *lockfname = "\\torture.lck";
217 pid_t pid2, pid = getpid();
222 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
225 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
227 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
232 for (i=0;i<torture_numops;i++) {
233 unsigned n = (unsigned)sys_random()%10;
235 printf("%d\r", i); fflush(stdout);
237 asprintf(&fname, "\\torture.%u", n);
239 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
243 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
245 printf("open failed (%s)\n", cli_errstr(c));
250 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
251 printf("write failed (%s)\n", cli_errstr(c));
256 if (cli_write(c, fnum, 0, (char *)buf,
257 sizeof(pid)+(j*sizeof(buf)),
258 sizeof(buf)) != sizeof(buf)) {
259 printf("write failed (%s)\n", cli_errstr(c));
266 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
267 printf("read failed (%s)\n", cli_errstr(c));
272 printf("data corruption!\n");
276 if (!cli_close(c, fnum)) {
277 printf("close failed (%s)\n", cli_errstr(c));
281 if (!cli_unlink(c, fname)) {
282 printf("unlink failed (%s)\n", cli_errstr(c));
286 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
287 printf("unlock failed (%s)\n", cli_errstr(c));
294 cli_unlink(c, lockfname);
301 static BOOL run_torture(int dummy)
303 struct cli_state *cli;
308 ret = rw_torture(cli);
310 if (!torture_close_connection(cli)) {
317 static BOOL rw_torture3(struct cli_state *c, const char *lockfname)
324 unsigned countprev = 0;
329 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
331 SIVAL(buf, i, sys_random());
336 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
339 printf("first open read/write of %s failed (%s)\n",
340 lockfname, cli_errstr(c));
346 for (i = 0; i < 500 && fnum == -1; i++)
348 fnum = cli_open(c, lockfname, O_RDONLY,
353 printf("second open read-only of %s failed (%s)\n",
354 lockfname, cli_errstr(c));
360 for (count = 0; count < sizeof(buf); count += sent)
362 if (count >= countprev) {
363 printf("%d %8d\r", i, count);
366 countprev += (sizeof(buf) / 20);
371 sent = ((unsigned)sys_random()%(20))+ 1;
372 if (sent > sizeof(buf) - count)
374 sent = sizeof(buf) - count;
377 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
378 printf("write failed (%s)\n", cli_errstr(c));
384 sent = cli_read(c, fnum, buf_rd+count, count,
388 printf("read failed offset:%d size:%d (%s)\n",
389 count, sizeof(buf)-count,
396 if (memcmp(buf_rd+count, buf+count, sent) != 0)
398 printf("read/write compare failed\n");
399 printf("offset: %d req %d recvd %d\n",
400 count, sizeof(buf)-count, sent);
409 if (!cli_close(c, fnum)) {
410 printf("close failed (%s)\n", cli_errstr(c));
417 static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
419 const char *lockfname = "\\torture2.lck";
424 uchar buf_rd[131072];
426 ssize_t bytes_read, bytes_written;
428 if (cli_deltree(c1, lockfname) == -1) {
429 printf("unlink failed (%s)\n", cli_errstr(c1));
432 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
435 printf("first open read/write of %s failed (%s)\n",
436 lockfname, cli_errstr(c1));
439 fnum2 = cli_open(c2, lockfname, O_RDONLY,
442 printf("second open read-only of %s failed (%s)\n",
443 lockfname, cli_errstr(c2));
444 cli_close(c1, fnum1);
448 printf("Checking data integrity over %d ops\n", torture_numops);
450 for (i=0;i<torture_numops;i++)
452 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
454 printf("%d\r", i); fflush(stdout);
457 generate_random_buffer(buf, buf_size, False);
459 if ((bytes_written = cli_write(c1, fnum1, 0, buf, 0, buf_size)) != buf_size) {
460 printf("write failed (%s)\n", cli_errstr(c1));
461 printf("wrote %d, expected %d\n", bytes_written, buf_size);
466 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
467 printf("read failed (%s)\n", cli_errstr(c2));
468 printf("read %d, expected %d\n", bytes_read, buf_size);
473 if (memcmp(buf_rd, buf, buf_size) != 0)
475 printf("read/write compare failed\n");
481 if (!cli_close(c2, fnum2)) {
482 printf("close failed (%s)\n", cli_errstr(c2));
485 if (!cli_close(c1, fnum1)) {
486 printf("close failed (%s)\n", cli_errstr(c1));
490 if (!cli_unlink(c1, lockfname)) {
491 printf("unlink failed (%s)\n", cli_errstr(c1));
498 static BOOL run_readwritetest(int dummy)
500 struct cli_state *cli1, *cli2;
501 BOOL test1, test2 = True;
503 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
507 printf("starting readwritetest\n");
509 test1 = rw_torture2(cli1, cli2);
510 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
513 test2 = rw_torture2(cli1, cli1);
514 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
517 if (!torture_close_connection(cli1)) {
521 if (!torture_close_connection(cli2)) {
525 return (test1 && test2);
528 static BOOL run_readwritemulti(int dummy)
530 struct cli_state *cli;
535 test = rw_torture3(cli, "\\multitest.txt");
537 if (!torture_close_connection(cli)) {
548 #define ival(s) strtol(s, NULL, 0)
550 /* run a test that simulates an approximate netbench client load */
551 static BOOL run_netbench(int client)
553 struct cli_state *cli;
558 const char *params[20];
567 asprintf(&cname, "client%d", client);
569 f = fopen(client_txt, "r");
576 while (fgets(line, sizeof(line)-1, f)) {
579 line[strlen(line)-1] = 0;
581 /* printf("[%d] %s\n", line_count, line); */
583 all_string_sub(line,"client1", cname, sizeof(line));
585 /* parse the command parameters */
586 params[0] = strtok(line," ");
588 while (params[i]) params[++i] = strtok(NULL," ");
594 if (!strncmp(params[0],"SMB", 3)) {
595 printf("ERROR: You are using a dbench 1 load file\n");
598 DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));
600 if (!strcmp(params[0],"NTCreateX")) {
601 nb_createx(params[1], ival(params[2]), ival(params[3]),
603 } else if (!strcmp(params[0],"Close")) {
604 nb_close(ival(params[1]));
605 } else if (!strcmp(params[0],"Rename")) {
606 nb_rename(params[1], params[2]);
607 } else if (!strcmp(params[0],"Unlink")) {
608 nb_unlink(params[1]);
609 } else if (!strcmp(params[0],"Deltree")) {
610 nb_deltree(params[1]);
611 } else if (!strcmp(params[0],"Rmdir")) {
613 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
614 nb_qpathinfo(params[1]);
615 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
616 nb_qfileinfo(ival(params[1]));
617 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
618 nb_qfsinfo(ival(params[1]));
619 } else if (!strcmp(params[0],"FIND_FIRST")) {
620 nb_findfirst(params[1]);
621 } else if (!strcmp(params[0],"WriteX")) {
622 nb_writex(ival(params[1]),
623 ival(params[2]), ival(params[3]), ival(params[4]));
624 } else if (!strcmp(params[0],"ReadX")) {
625 nb_readx(ival(params[1]),
626 ival(params[2]), ival(params[3]), ival(params[4]));
627 } else if (!strcmp(params[0],"Flush")) {
628 nb_flush(ival(params[1]));
630 printf("Unknown operation %s\n", params[0]);
638 if (!torture_close_connection(cli)) {
646 /* run a test that simulates an approximate netbench client load */
647 static BOOL run_nbench(int dummy)
656 signal(SIGALRM, SIGNAL_CAST nb_alarm);
658 t = create_procs(run_netbench, &correct);
661 printf("\nThroughput %g MB/sec\n",
662 1.0e-6 * nbio_total() / t);
668 This test checks for two things:
670 1) correct support for retaining locks over a close (ie. the server
671 must not use posix semantics)
672 2) support for lock timeouts
674 static BOOL run_locktest1(int dummy)
676 struct cli_state *cli1, *cli2;
677 const char *fname = "\\lockt1.lck";
678 int fnum1, fnum2, fnum3;
680 unsigned lock_timeout;
682 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
686 printf("starting locktest1\n");
688 cli_unlink(cli1, fname);
690 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
692 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
695 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
697 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
700 fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
702 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
706 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
707 printf("lock1 failed (%s)\n", cli_errstr(cli1));
712 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
713 printf("lock2 succeeded! This is a locking bug\n");
716 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
717 NT_STATUS_LOCK_NOT_GRANTED)) return False;
721 lock_timeout = (6 + (random() % 20));
722 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
724 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
725 printf("lock3 succeeded! This is a locking bug\n");
728 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
729 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
734 printf("error: This server appears not to support timed lock requests\n");
736 printf("server slept for %u seconds for a %u second timeout\n",
737 (unsigned int)(t2-t1), lock_timeout);
739 if (!cli_close(cli1, fnum2)) {
740 printf("close1 failed (%s)\n", cli_errstr(cli1));
744 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
745 printf("lock4 succeeded! This is a locking bug\n");
748 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
749 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
752 if (!cli_close(cli1, fnum1)) {
753 printf("close2 failed (%s)\n", cli_errstr(cli1));
757 if (!cli_close(cli2, fnum3)) {
758 printf("close3 failed (%s)\n", cli_errstr(cli2));
762 if (!cli_unlink(cli1, fname)) {
763 printf("unlink failed (%s)\n", cli_errstr(cli1));
768 if (!torture_close_connection(cli1)) {
772 if (!torture_close_connection(cli2)) {
776 printf("Passed locktest1\n");
781 this checks to see if a secondary tconx can use open files from an
784 static BOOL run_tcon_test(int dummy)
786 struct cli_state *cli;
787 const char *fname = "\\tcontest.tmp";
789 uint16 cnum1, cnum2, cnum3;
793 struct cli_tree *tree1;
794 char *host = lp_parm_string(-1, "torture", "host");
795 char *share = lp_parm_string(-1, "torture", "share");
796 char *password = lp_parm_string(-1, "torture", "password");
798 if (!torture_open_connection(&cli)) {
802 printf("starting tcontest\n");
804 if (cli_deltree(cli, fname) == -1) {
805 printf("unlink of %s failed (%s)\n", fname, cli_errstr(cli));
808 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
810 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
814 cnum1 = cli->tree->tid;
815 vuid1 = cli->session->vuid;
817 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
818 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
819 printf("initial write failed (%s)\n", cli_errstr(cli));
823 tree1 = cli->tree; /* save old tree connection */
824 if (!cli_send_tconX(cli, share, "?????",
826 printf("%s refused 2nd tree connect (%s)\n", host,
832 cnum2 = cli->tree->tid;
833 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
834 vuid2 = cli->session->vuid + 1;
836 /* try a write with the wrong tid */
837 cli->tree->tid = cnum2;
839 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
840 printf("* server allows write with wrong TID\n");
843 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
847 /* try a write with an invalid tid */
848 cli->tree->tid = cnum3;
850 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
851 printf("* server allows write with invalid TID\n");
854 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
857 /* try a write with an invalid vuid */
858 cli->session->vuid = vuid2;
859 cli->tree->tid = cnum1;
861 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
862 printf("* server allows write with invalid VUID\n");
865 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
868 cli->session->vuid = vuid1;
869 cli->tree->tid = cnum1;
871 if (!cli_close(cli, fnum1)) {
872 printf("close failed (%s)\n", cli_errstr(cli));
876 cli->tree->tid = cnum2;
878 if (!cli_tdis(cli)) {
879 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
883 cli->tree = tree1; /* restore initial tree */
884 cli->tree->tid = cnum1;
886 if (!torture_close_connection(cli)) {
895 static BOOL tcon_devtest(struct cli_state *cli,
896 const char *myshare, const char *devtype,
897 NTSTATUS expected_error)
901 char *password = lp_parm_string(-1, "torture", "password");
903 status = cli_send_tconX(cli, myshare, devtype,
906 printf("Trying share %s with devtype %s\n", myshare, devtype);
908 if (NT_STATUS_IS_OK(expected_error)) {
912 printf("tconX to share %s with type %s "
913 "should have succeeded but failed\n",
920 printf("tconx to share %s with type %s "
921 "should have failed but succeeded\n",
925 if (NT_STATUS_EQUAL(cli_nt_error(cli),
929 printf("Returned unexpected error\n");
938 checks for correct tconX support
940 static BOOL run_tcon_devtype_test(int dummy)
942 struct cli_state *cli1 = NULL;
947 char *host = lp_parm_string(-1, "torture", "host");
948 char *share = lp_parm_string(-1, "torture", "share");
949 char *username = lp_parm_string(-1, "torture", "username");
950 char *password = lp_parm_string(-1, "torture", "password");
952 status = cli_full_connection(&cli1, lp_netbios_name(),
955 username, lp_workgroup(),
956 password, flags, &retry);
958 if (!NT_STATUS_IS_OK(status)) {
959 printf("could not open connection\n");
963 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
966 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
969 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
972 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
975 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
978 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
981 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
984 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
987 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
990 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
996 printf("Passed tcondevtest\n");
1003 This test checks that
1005 1) the server supports multiple locking contexts on the one SMB
1006 connection, distinguished by PID.
1008 2) the server correctly fails overlapping locks made by the same PID (this
1009 goes against POSIX behaviour, which is why it is tricky to implement)
1011 3) the server denies unlock requests by an incorrect client PID
1013 static BOOL run_locktest2(int dummy)
1015 struct cli_state *cli;
1016 const char *fname = "\\lockt2.lck";
1017 int fnum1, fnum2, fnum3;
1018 BOOL correct = True;
1020 if (!torture_open_connection(&cli)) {
1024 printf("starting locktest2\n");
1026 cli_unlink(cli, fname);
1028 printf("Testing pid context\n");
1030 cli->session->pid = 1;
1032 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1034 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1038 fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1040 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1044 cli->session->pid = 2;
1046 fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1048 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1052 cli->session->pid = 1;
1054 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1055 printf("lock1 failed (%s)\n", cli_errstr(cli));
1059 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1060 printf("WRITE lock1 succeeded! This is a locking bug\n");
1063 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1064 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1067 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1068 printf("WRITE lock2 succeeded! This is a locking bug\n");
1071 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1072 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1075 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1076 printf("READ lock2 succeeded! This is a locking bug\n");
1079 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1080 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1083 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1084 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1087 cli->session->pid = 2;
1089 if (cli_unlock(cli, fnum1, 100, 4)) {
1090 printf("unlock at 100 succeeded! This is a locking bug\n");
1094 if (cli_unlock(cli, fnum1, 0, 4)) {
1095 printf("unlock1 succeeded! This is a locking bug\n");
1098 if (!check_error(__LINE__, cli,
1100 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1103 if (cli_unlock(cli, fnum1, 0, 8)) {
1104 printf("unlock2 succeeded! This is a locking bug\n");
1107 if (!check_error(__LINE__, cli,
1109 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1112 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1113 printf("lock3 succeeded! This is a locking bug\n");
1116 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1119 cli->session->pid = 1;
1121 if (!cli_close(cli, fnum1)) {
1122 printf("close1 failed (%s)\n", cli_errstr(cli));
1126 if (!cli_close(cli, fnum2)) {
1127 printf("close2 failed (%s)\n", cli_errstr(cli));
1131 if (!cli_close(cli, fnum3)) {
1132 printf("close3 failed (%s)\n", cli_errstr(cli));
1136 if (!torture_close_connection(cli)) {
1140 printf("locktest2 finished\n");
1147 This test checks that
1149 1) the server supports the full offset range in lock requests
1151 static BOOL run_locktest3(int dummy)
1153 struct cli_state *cli1, *cli2;
1154 const char *fname = "\\lockt3.lck";
1155 int fnum1, fnum2, i;
1157 BOOL correct = True;
1159 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1161 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1165 printf("starting locktest3\n");
1167 printf("Testing 32 bit offset ranges\n");
1169 cli_unlink(cli1, fname);
1171 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1173 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1176 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1178 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1182 printf("Establishing %d locks\n", torture_numops);
1184 for (offset=i=0;i<torture_numops;i++) {
1186 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1187 printf("lock1 %d failed (%s)\n",
1193 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1194 printf("lock2 %d failed (%s)\n",
1201 printf("Testing %d locks\n", torture_numops);
1203 for (offset=i=0;i<torture_numops;i++) {
1206 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1207 printf("error: lock1 %d succeeded!\n", i);
1211 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1212 printf("error: lock2 %d succeeded!\n", i);
1216 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1217 printf("error: lock3 %d succeeded!\n", i);
1221 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1222 printf("error: lock4 %d succeeded!\n", i);
1227 printf("Removing %d locks\n", torture_numops);
1229 for (offset=i=0;i<torture_numops;i++) {
1232 if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
1233 printf("unlock1 %d failed (%s)\n",
1239 if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
1240 printf("unlock2 %d failed (%s)\n",
1247 if (!cli_close(cli1, fnum1)) {
1248 printf("close1 failed (%s)\n", cli_errstr(cli1));
1252 if (!cli_close(cli2, fnum2)) {
1253 printf("close2 failed (%s)\n", cli_errstr(cli2));
1257 if (!cli_unlink(cli1, fname)) {
1258 printf("unlink failed (%s)\n", cli_errstr(cli1));
1262 if (!torture_close_connection(cli1)) {
1266 if (!torture_close_connection(cli2)) {
1270 printf("finished locktest3\n");
1275 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1276 printf("** "); correct = False; \
1280 looks at overlapping locks
1282 static BOOL run_locktest4(int dummy)
1284 struct cli_state *cli1, *cli2;
1285 const char *fname = "\\lockt4.lck";
1286 int fnum1, fnum2, f;
1289 BOOL correct = True;
1291 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1295 printf("starting locktest4\n");
1297 cli_unlink(cli1, fname);
1299 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1300 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1302 memset(buf, 0, sizeof(buf));
1304 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1305 printf("Failed to create file\n");
1310 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1311 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1312 EXPECTED(ret, False);
1313 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1315 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1316 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1317 EXPECTED(ret, True);
1318 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1320 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1321 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1322 EXPECTED(ret, False);
1323 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1325 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1326 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1327 EXPECTED(ret, True);
1328 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1330 ret = (cli1->session->pid = 1, cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1331 (cli1->session->pid = 2, cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1332 EXPECTED(ret, False);
1333 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1335 ret = (cli1->session->pid = 1, cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1336 (cli1->session->pid = 2, cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1337 EXPECTED(ret, True);
1338 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1340 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1341 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1342 EXPECTED(ret, True);
1343 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1345 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1346 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1347 EXPECTED(ret, False);
1348 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1350 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1351 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1352 EXPECTED(ret, False);
1353 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1355 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1356 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1357 EXPECTED(ret, True);
1358 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1360 ret = (cli1->session->pid = 1, cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1361 (cli1->session->pid = 2, cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1362 EXPECTED(ret, False);
1363 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1365 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1366 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1367 cli_unlock(cli1, fnum1, 110, 6);
1368 EXPECTED(ret, False);
1369 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1372 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1373 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1374 EXPECTED(ret, False);
1375 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1377 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1378 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1379 EXPECTED(ret, False);
1380 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1383 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1384 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1385 cli_unlock(cli1, fnum1, 140, 4) &&
1386 cli_unlock(cli1, fnum1, 140, 4);
1387 EXPECTED(ret, True);
1388 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1391 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1392 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1393 cli_unlock(cli1, fnum1, 150, 4) &&
1394 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1395 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1396 cli_unlock(cli1, fnum1, 150, 4);
1397 EXPECTED(ret, True);
1398 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1400 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1401 cli_unlock(cli1, fnum1, 160, 4) &&
1402 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1403 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1404 EXPECTED(ret, True);
1405 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1407 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1408 cli_unlock(cli1, fnum1, 170, 4) &&
1409 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1410 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1411 EXPECTED(ret, True);
1412 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1414 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1415 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1416 cli_unlock(cli1, fnum1, 190, 4) &&
1417 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1418 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1419 EXPECTED(ret, True);
1420 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1422 cli_close(cli1, fnum1);
1423 cli_close(cli2, fnum2);
1424 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1425 f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1426 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1427 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1428 cli_close(cli1, fnum1) &&
1429 ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1430 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1432 cli_close(cli1, fnum1);
1433 EXPECTED(ret, True);
1434 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1437 cli_close(cli1, fnum1);
1438 cli_close(cli2, fnum2);
1439 cli_unlink(cli1, fname);
1440 torture_close_connection(cli1);
1441 torture_close_connection(cli2);
1443 printf("finished locktest4\n");
1448 looks at lock upgrade/downgrade.
1450 static BOOL run_locktest5(int dummy)
1452 struct cli_state *cli1, *cli2;
1453 const char *fname = "\\lockt5.lck";
1454 int fnum1, fnum2, fnum3;
1457 BOOL correct = True;
1459 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1463 printf("starting locktest5\n");
1465 cli_unlink(cli1, fname);
1467 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1468 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1469 fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1471 memset(buf, 0, sizeof(buf));
1473 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1474 printf("Failed to create file\n");
1479 /* Check for NT bug... */
1480 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1481 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1482 cli_close(cli1, fnum1);
1483 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1484 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1485 EXPECTED(ret, True);
1486 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1487 cli_close(cli1, fnum1);
1488 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1489 cli_unlock(cli1, fnum3, 0, 1);
1491 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1492 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1493 EXPECTED(ret, True);
1494 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1496 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1497 EXPECTED(ret, False);
1499 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1501 /* Unlock the process 2 lock. */
1502 cli_unlock(cli2, fnum2, 0, 4);
1504 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1505 EXPECTED(ret, False);
1507 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1509 /* Unlock the process 1 fnum3 lock. */
1510 cli_unlock(cli1, fnum3, 0, 4);
1512 /* Stack 2 more locks here. */
1513 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1514 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1516 EXPECTED(ret, True);
1517 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1519 /* Unlock the first process lock, then check this was the WRITE lock that was
1522 ret = cli_unlock(cli1, fnum1, 0, 4) &&
1523 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1525 EXPECTED(ret, True);
1526 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1528 /* Unlock the process 2 lock. */
1529 cli_unlock(cli2, fnum2, 0, 4);
1531 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1533 ret = cli_unlock(cli1, fnum1, 1, 1) &&
1534 cli_unlock(cli1, fnum1, 0, 4) &&
1535 cli_unlock(cli1, fnum1, 0, 4);
1537 EXPECTED(ret, True);
1538 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1540 /* Ensure the next unlock fails. */
1541 ret = cli_unlock(cli1, fnum1, 0, 4);
1542 EXPECTED(ret, False);
1543 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1545 /* Ensure connection 2 can get a write lock. */
1546 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1547 EXPECTED(ret, True);
1549 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1553 cli_close(cli1, fnum1);
1554 cli_close(cli2, fnum2);
1555 cli_unlink(cli1, fname);
1556 if (!torture_close_connection(cli1)) {
1559 if (!torture_close_connection(cli2)) {
1563 printf("finished locktest5\n");
1569 tries the unusual lockingX locktype bits
1571 static BOOL run_locktest6(int dummy)
1573 struct cli_state *cli;
1574 const char *fname[1] = { "\\lock6.txt" };
1579 if (!torture_open_connection(&cli)) {
1583 printf("starting locktest6\n");
1586 printf("Testing %s\n", fname[i]);
1588 cli_unlink(cli, fname[i]);
1590 fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1591 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1592 cli_close(cli, fnum);
1593 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1595 fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
1596 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1597 cli_close(cli, fnum);
1598 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1600 cli_unlink(cli, fname[i]);
1603 torture_close_connection(cli);
1605 printf("finished locktest6\n");
1609 static BOOL run_locktest7(int dummy)
1611 struct cli_state *cli1;
1612 const char *fname = "\\lockt7.lck";
1615 BOOL correct = False;
1617 if (!torture_open_connection(&cli1)) {
1621 printf("starting locktest7\n");
1623 cli_unlink(cli1, fname);
1625 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1627 memset(buf, 0, sizeof(buf));
1629 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1630 printf("Failed to create file\n");
1634 cli1->session->pid = 1;
1636 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1637 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1640 printf("pid1 successfully locked range 130:4 for READ\n");
1643 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1644 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1647 printf("pid1 successfully read the range 130:4\n");
1650 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1651 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1652 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1653 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1657 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1661 cli1->session->pid = 2;
1663 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1664 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1666 printf("pid2 successfully read the range 130:4\n");
1669 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1670 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1671 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1672 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1676 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1680 cli1->session->pid = 1;
1681 cli_unlock(cli1, fnum1, 130, 4);
1683 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
1684 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
1687 printf("pid1 successfully locked range 130:4 for WRITE\n");
1690 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1691 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1694 printf("pid1 successfully read the range 130:4\n");
1697 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1698 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1701 printf("pid1 successfully wrote to the range 130:4\n");
1704 cli1->session->pid = 2;
1706 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1707 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1708 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1709 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1713 printf("pid2 successfully read the range 130:4 (should be denied)\n");
1717 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1718 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1719 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1720 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1724 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1728 cli_unlock(cli1, fnum1, 130, 0);
1732 cli_close(cli1, fnum1);
1733 cli_unlink(cli1, fname);
1734 torture_close_connection(cli1);
1736 printf("finished locktest7\n");
1741 test whether fnums and tids open on one VC are available on another (a major
1744 static BOOL run_fdpasstest(int dummy)
1746 struct cli_state *cli1, *cli2;
1747 const char *fname = "\\fdpass.tst";
1751 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1755 printf("starting fdpasstest\n");
1757 cli_unlink(cli1, fname);
1759 printf("Opening a file on connection 1\n");
1761 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1763 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1767 printf("writing to file on connection 1\n");
1769 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
1770 printf("write failed (%s)\n", cli_errstr(cli1));
1774 oldtid = cli2->tree->tid;
1775 cli2->session->vuid = cli1->session->vuid;
1776 cli2->tree->tid = cli1->tree->tid;
1777 cli2->session->pid = cli1->session->pid;
1779 printf("reading from file on connection 2\n");
1781 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
1782 printf("read succeeded! nasty security hole [%s]\n",
1787 cli_close(cli1, fnum1);
1788 cli_unlink(cli1, fname);
1790 cli2->tree->tid = oldtid;
1792 torture_close_connection(cli1);
1793 torture_close_connection(cli2);
1795 printf("finished fdpasstest\n");
1801 This test checks that
1803 1) the server does not allow an unlink on a file that is open
1805 static BOOL run_unlinktest(int dummy)
1807 struct cli_state *cli;
1808 const char *fname = "\\unlink.tst";
1810 BOOL correct = True;
1812 if (!torture_open_connection(&cli)) {
1816 printf("starting unlink test\n");
1818 cli_unlink(cli, fname);
1820 cli->session->pid = 1;
1822 printf("Opening a file\n");
1824 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1826 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1830 printf("Unlinking a open file\n");
1832 if (cli_unlink(cli, fname)) {
1833 printf("error: server allowed unlink on an open file\n");
1836 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
1837 NT_STATUS_SHARING_VIOLATION);
1840 cli_close(cli, fnum);
1841 cli_unlink(cli, fname);
1843 if (!torture_close_connection(cli)) {
1847 printf("unlink test finished\n");
1854 test how many open files this server supports on the one socket
1856 static BOOL run_maxfidtest(int dummy)
1858 struct cli_state *cli;
1859 const char *template = "\\maxfid.%d.%d";
1861 int fnums[0x11000], i;
1863 BOOL correct = True;
1868 printf("failed to connect\n");
1872 printf("Testing maximum number of open files\n");
1874 for (i=0; i<0x11000; i++) {
1875 asprintf(&fname, template, i,(int)getpid());
1876 if ((fnums[i] = cli_open(cli, fname,
1877 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1879 printf("open of %s failed (%s)\n",
1880 fname, cli_errstr(cli));
1881 printf("maximum fnum is %d\n", i);
1890 printf("cleaning up\n");
1892 asprintf(&fname, template, i,(int)getpid());
1893 if (!cli_close(cli, fnums[i])) {
1894 printf("Close of fnum %d failed - %s\n", fnums[i], cli_errstr(cli));
1896 if (!cli_unlink(cli, fname)) {
1897 printf("unlink of %s failed (%s)\n",
1898 fname, cli_errstr(cli));
1906 printf("maxfid test finished\n");
1907 if (!torture_close_connection(cli)) {
1913 /* send smb negprot commands, not reading the response */
1914 static BOOL run_negprot_nowait(int dummy)
1917 struct cli_state *cli;
1918 BOOL correct = True;
1920 printf("starting negprot nowait test\n");
1922 cli = open_nbt_connection();
1927 printf("Establishing protocol negotiations - connect with another client\n");
1929 for (i=0;i<50000;i++) {
1930 smb_negprot_send(cli->transport, PROTOCOL_NT1);
1933 if (!torture_close_connection(cli)) {
1937 printf("finished negprot nowait test\n");
1944 This checks how the getatr calls works
1946 static BOOL run_attrtest(int dummy)
1948 struct cli_state *cli;
1951 const char *fname = "\\attrib123456789.tst";
1952 BOOL correct = True;
1954 printf("starting attrib test\n");
1956 if (!torture_open_connection(&cli)) {
1960 cli_unlink(cli, fname);
1961 fnum = cli_open(cli, fname,
1962 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1963 cli_close(cli, fnum);
1965 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
1966 printf("getatr failed (%s)\n", cli_errstr(cli));
1970 printf("New file time is %s", ctime(&t));
1972 if (abs(t - time(NULL)) > 60*60*24*10) {
1973 printf("ERROR: SMBgetatr bug. time is %s",
1979 t2 = t-60*60*24; /* 1 day ago */
1981 printf("Setting file time to %s", ctime(&t2));
1983 if (!cli_setatr(cli, fname, 0, t2)) {
1984 printf("setatr failed (%s)\n", cli_errstr(cli));
1988 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
1989 printf("getatr failed (%s)\n", cli_errstr(cli));
1993 printf("Retrieved file time as %s", ctime(&t));
1996 printf("ERROR: getatr/setatr bug. times are\n%s",
1998 printf("%s", ctime(&t2));
2002 cli_unlink(cli, fname);
2004 if (!torture_close_connection(cli)) {
2008 printf("attrib test finished\n");
2015 This checks a couple of trans2 calls
2017 static BOOL run_trans2test(int dummy)
2019 struct cli_state *cli;
2022 time_t c_time, a_time, m_time, w_time, m_time2;
2023 const char *fname = "\\trans2.tst";
2024 const char *dname = "\\trans2";
2025 const char *fname2 = "\\trans2\\trans2.tst";
2027 BOOL correct = True;
2029 printf("starting trans2 test\n");
2031 if (!torture_open_connection(&cli)) {
2035 cli_unlink(cli, fname);
2037 printf("Testing qfileinfo\n");
2039 fnum = cli_open(cli, fname,
2040 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2041 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
2043 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2047 printf("Testing NAME_INFO\n");
2049 if (!cli_qfilename(cli, fnum, &pname)) {
2050 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2054 if (!pname || strcmp(pname, fname)) {
2055 printf("qfilename gave different name? [%s] [%s]\n",
2060 cli_close(cli, fnum);
2061 cli_unlink(cli, fname);
2063 fnum = cli_open(cli, fname,
2064 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2066 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2069 cli_close(cli, fnum);
2071 printf("Checking for sticky create times\n");
2073 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2074 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2077 if (c_time != m_time) {
2078 printf("create time=%s", ctime(&c_time));
2079 printf("modify time=%s", ctime(&m_time));
2080 printf("This system appears to have sticky create times\n");
2082 if (a_time % (60*60) == 0) {
2083 printf("access time=%s", ctime(&a_time));
2084 printf("This system appears to set a midnight access time\n");
2088 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2089 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2095 cli_unlink(cli, fname);
2096 fnum = cli_open(cli, fname,
2097 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2098 cli_close(cli, fnum);
2099 if (!cli_qpathinfo2(cli, fname, &c_time, &a_time, &m_time,
2100 &w_time, &size, NULL, NULL)) {
2101 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2104 if (w_time < 60*60*24*2) {
2105 printf("write time=%s", ctime(&w_time));
2106 printf("This system appears to set a initial 0 write time\n");
2111 cli_unlink(cli, fname);
2114 /* check if the server updates the directory modification time
2115 when creating a new file */
2116 if (!cli_mkdir(cli, dname)) {
2117 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2121 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &m_time,
2122 &w_time, &size, NULL, NULL)) {
2123 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2127 fnum = cli_open(cli, fname2,
2128 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2129 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2130 cli_close(cli, fnum);
2131 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &m_time2,
2132 &w_time, &size, NULL, NULL)) {
2133 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2136 if (m_time2 == m_time) {
2137 printf("This system does not update directory modification times\n");
2141 cli_unlink(cli, fname2);
2142 cli_rmdir(cli, dname);
2144 if (!torture_close_connection(cli)) {
2148 printf("trans2 test finished\n");
2154 Test delete on close semantics.
2156 static BOOL run_deletetest(int dummy)
2158 struct cli_state *cli1;
2159 struct cli_state *cli2 = NULL;
2160 const char *fname = "\\delete.file";
2163 BOOL correct = True;
2165 printf("starting delete test\n");
2167 if (!torture_open_connection(&cli1)) {
2171 /* Test 1 - this should delete the file on close. */
2173 cli_setatr(cli1, fname, 0, 0);
2174 cli_unlink(cli1, fname);
2176 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2177 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF,
2178 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2181 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2186 if (!cli_close(cli1, fnum1)) {
2187 printf("[1] close failed (%s)\n", cli_errstr(cli1));
2192 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
2194 printf("[1] open of %s succeeded (should fail)\n", fname);
2199 printf("first delete on close test succeeded.\n");
2201 /* Test 2 - this should delete the file on close. */
2203 cli_setatr(cli1, fname, 0, 0);
2204 cli_unlink(cli1, fname);
2206 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
2207 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
2208 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2211 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2216 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2217 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2222 if (!cli_close(cli1, fnum1)) {
2223 printf("[2] close failed (%s)\n", cli_errstr(cli1));
2228 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2230 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2231 if (!cli_close(cli1, fnum1)) {
2232 printf("[2] close failed (%s)\n", cli_errstr(cli1));
2236 cli_unlink(cli1, fname);
2238 printf("second delete on close test succeeded.\n");
2241 cli_setatr(cli1, fname, 0, 0);
2242 cli_unlink(cli1, fname);
2244 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2245 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2248 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
2253 /* This should fail with a sharing violation - open for delete is only compatible
2254 with SHARE_DELETE. */
2256 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2257 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2258 NTCREATEX_DISP_OPEN, 0, 0);
2261 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2266 /* This should succeed. */
2268 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2269 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN, 0, 0);
2272 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
2277 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2278 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2283 if (!cli_close(cli1, fnum1)) {
2284 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
2289 if (!cli_close(cli1, fnum2)) {
2290 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
2295 /* This should fail - file should no longer be there. */
2297 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2299 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2300 if (!cli_close(cli1, fnum1)) {
2301 printf("[3] close failed (%s)\n", cli_errstr(cli1));
2303 cli_unlink(cli1, fname);
2307 printf("third delete on close test succeeded.\n");
2310 cli_setatr(cli1, fname, 0, 0);
2311 cli_unlink(cli1, fname);
2313 fnum1 = cli_nt_create_full(cli1, fname, 0,
2314 SA_RIGHT_FILE_READ_DATA |
2315 SA_RIGHT_FILE_WRITE_DATA |
2316 STD_RIGHT_DELETE_ACCESS,
2317 FILE_ATTRIBUTE_NORMAL,
2318 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2319 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2322 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2327 /* This should succeed. */
2328 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ,
2329 FILE_ATTRIBUTE_NORMAL,
2330 NTCREATEX_SHARE_ACCESS_READ |
2331 NTCREATEX_SHARE_ACCESS_WRITE |
2332 NTCREATEX_SHARE_ACCESS_DELETE,
2333 NTCREATEX_DISP_OPEN, 0, 0);
2335 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
2340 if (!cli_close(cli1, fnum2)) {
2341 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
2346 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2347 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2352 /* This should fail - no more opens once delete on close set. */
2353 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ,
2354 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2355 NTCREATEX_DISP_OPEN, 0, 0);
2357 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2361 printf("fourth delete on close test succeeded.\n");
2363 if (!cli_close(cli1, fnum1)) {
2364 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
2370 cli_setatr(cli1, fname, 0, 0);
2371 cli_unlink(cli1, fname);
2373 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
2375 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2380 /* This should fail - only allowed on NT opens with DELETE access. */
2382 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
2383 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2388 if (!cli_close(cli1, fnum1)) {
2389 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
2394 printf("fifth delete on close test succeeded.\n");
2397 cli_setatr(cli1, fname, 0, 0);
2398 cli_unlink(cli1, fname);
2400 fnum1 = cli_nt_create_full(cli1, fname, 0,
2401 SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA,
2402 FILE_ATTRIBUTE_NORMAL,
2403 NTCREATEX_SHARE_ACCESS_READ |
2404 NTCREATEX_SHARE_ACCESS_WRITE |
2405 NTCREATEX_SHARE_ACCESS_DELETE,
2406 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2409 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2414 /* This should fail - only allowed on NT opens with DELETE access. */
2416 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
2417 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2422 if (!cli_close(cli1, fnum1)) {
2423 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
2428 printf("sixth delete on close test succeeded.\n");
2431 cli_setatr(cli1, fname, 0, 0);
2432 cli_unlink(cli1, fname);
2434 fnum1 = cli_nt_create_full(cli1, fname, 0,
2435 SA_RIGHT_FILE_READ_DATA |
2436 SA_RIGHT_FILE_WRITE_DATA |
2437 STD_RIGHT_DELETE_ACCESS,
2438 FILE_ATTRIBUTE_NORMAL, 0, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2441 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2446 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2447 printf("[7] setting delete_on_close on file failed !\n");
2452 if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
2453 printf("[7] unsetting delete_on_close on file failed !\n");
2458 if (!cli_close(cli1, fnum1)) {
2459 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
2464 /* This next open should succeed - we reset the flag. */
2466 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2468 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2473 if (!cli_close(cli1, fnum1)) {
2474 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
2479 printf("seventh delete on close test succeeded.\n");
2482 cli_setatr(cli1, fname, 0, 0);
2483 cli_unlink(cli1, fname);
2485 if (!torture_open_connection(&cli2)) {
2486 printf("[8] failed to open second connection.\n");
2491 fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2492 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2493 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2496 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2501 fnum2 = cli_nt_create_full(cli2, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2502 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2503 NTCREATEX_DISP_OPEN, 0, 0);
2506 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2511 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2512 printf("[8] setting delete_on_close on file failed !\n");
2517 if (!cli_close(cli1, fnum1)) {
2518 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
2523 if (!cli_close(cli2, fnum2)) {
2524 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
2529 /* This should fail.. */
2530 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2532 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2536 printf("eighth delete on close test succeeded.\n");
2538 /* This should fail - we need to set DELETE_ACCESS. */
2539 fnum1 = cli_nt_create_full(cli1, fname, 0,SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
2540 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2543 printf("[9] open of %s succeeded should have failed!\n", fname);
2548 printf("ninth delete on close test succeeded.\n");
2550 fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2551 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2553 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2558 /* This should delete the file. */
2559 if (!cli_close(cli1, fnum1)) {
2560 printf("[10] close failed (%s)\n", cli_errstr(cli1));
2565 /* This should fail.. */
2566 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2568 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2572 printf("tenth delete on close test succeeded.\n");
2573 printf("finished delete test\n");
2576 /* FIXME: This will crash if we aborted before cli2 got
2577 * intialized, because these functions don't handle
2578 * uninitialized connections. */
2580 cli_close(cli1, fnum1);
2581 cli_close(cli1, fnum2);
2582 cli_setatr(cli1, fname, 0, 0);
2583 cli_unlink(cli1, fname);
2585 if (!torture_close_connection(cli1)) {
2588 if (!torture_close_connection(cli2)) {
2596 print out server properties
2598 static BOOL run_properties(int dummy)
2600 struct cli_state *cli;
2601 BOOL correct = True;
2603 printf("starting properties test\n");
2607 if (!torture_open_connection(&cli)) {
2611 d_printf("Capabilities 0x%08x\n", cli->transport->negotiate.capabilities);
2613 if (!torture_close_connection(cli)) {
2622 /* FIRST_DESIRED_ACCESS 0xf019f */
2623 #define FIRST_DESIRED_ACCESS SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_APPEND_DATA|\
2624 SA_RIGHT_FILE_READ_EA| /* 0xf */ \
2625 SA_RIGHT_FILE_WRITE_EA|SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x90 */ \
2626 SA_RIGHT_FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
2627 STD_RIGHT_DELETE_ACCESS|STD_RIGHT_READ_CONTROL_ACCESS|\
2628 STD_RIGHT_WRITE_DAC_ACCESS|STD_RIGHT_WRITE_OWNER_ACCESS /* 0xf0000 */
2629 /* SECOND_DESIRED_ACCESS 0xe0080 */
2630 #define SECOND_DESIRED_ACCESS SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x80 */ \
2631 STD_RIGHT_READ_CONTROL_ACCESS|STD_RIGHT_WRITE_DAC_ACCESS|\
2632 STD_RIGHT_WRITE_OWNER_ACCESS /* 0xe0000 */
2635 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
2636 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2637 SA_RIGHT_FILE_READ_DATA|\
2638 WRITE_OWNER_ACCESS /* */
2642 Test ntcreate calls made by xcopy
2644 static BOOL run_xcopy(int dummy)
2646 struct cli_state *cli1;
2647 const char *fname = "\\test.txt";
2648 BOOL correct = True;
2651 printf("starting xcopy test\n");
2653 if (!torture_open_connection(&cli1)) {
2657 fnum1 = cli_nt_create_full(cli1, fname, 0,
2658 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2659 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF,
2663 printf("First open failed - %s\n", cli_errstr(cli1));
2667 fnum2 = cli_nt_create_full(cli1, fname, 0,
2668 SECOND_DESIRED_ACCESS, 0,
2669 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
2672 printf("second open failed - %s\n", cli_errstr(cli1));
2676 if (!torture_close_connection(cli1)) {
2684 Test rename on files open with share delete and no share delete.
2686 static BOOL run_rename(int dummy)
2688 struct cli_state *cli1;
2689 const char *fname = "\\test.txt";
2690 const char *fname1 = "\\test1.txt";
2691 BOOL correct = True;
2694 printf("starting rename test\n");
2696 if (!torture_open_connection(&cli1)) {
2700 cli_unlink(cli1, fname);
2701 cli_unlink(cli1, fname1);
2702 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2703 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2706 printf("First open failed - %s\n", cli_errstr(cli1));
2710 if (!cli_rename(cli1, fname, fname1)) {
2711 printf("First rename failed (this is correct) - %s\n", cli_errstr(cli1));
2713 printf("First rename succeeded - this should have failed !\n");
2717 if (!cli_close(cli1, fnum1)) {
2718 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
2722 cli_unlink(cli1, fname);
2723 cli_unlink(cli1, fname1);
2724 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2726 NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2728 NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2732 printf("Second open failed - %s\n", cli_errstr(cli1));
2736 if (!cli_rename(cli1, fname, fname1)) {
2737 printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(cli1));
2740 printf("Second rename succeeded\n");
2743 if (!cli_close(cli1, fnum1)) {
2744 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
2748 cli_unlink(cli1, fname);
2749 cli_unlink(cli1, fname1);
2751 fnum1 = cli_nt_create_full(cli1, fname, 0, STD_RIGHT_READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2752 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2755 printf("Third open failed - %s\n", cli_errstr(cli1));
2764 fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2765 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2768 printf("Fourth open failed - %s\n", cli_errstr(cli1));
2771 if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
2772 printf("[8] setting delete_on_close on file failed !\n");
2776 if (!cli_close(cli1, fnum2)) {
2777 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
2783 if (!cli_rename(cli1, fname, fname1)) {
2784 printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(cli1));
2787 printf("Third rename succeeded\n");
2790 if (!cli_close(cli1, fnum1)) {
2791 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
2795 cli_unlink(cli1, fname);
2796 cli_unlink(cli1, fname1);
2798 if (!torture_close_connection(cli1)) {
2805 static BOOL run_pipe_number(int dummy)
2807 struct cli_state *cli1;
2808 const char *pipe_name = "\\WKSSVC";
2812 printf("starting pipenumber test\n");
2813 if (!torture_open_connection(&cli1)) {
2818 fnum = cli_nt_create_full(cli1, pipe_name, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
2819 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
2822 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
2828 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
2829 torture_close_connection(cli1);
2835 Test open mode returns on read-only files.
2837 static BOOL run_opentest(int dummy)
2839 static struct cli_state *cli1;
2840 static struct cli_state *cli2;
2841 const char *fname = "\\readonly.file";
2845 BOOL correct = True;
2849 printf("starting open test\n");
2851 if (!torture_open_connection(&cli1)) {
2855 cli_setatr(cli1, fname, 0, 0);
2856 cli_unlink(cli1, fname);
2858 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2860 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2864 if (!cli_close(cli1, fnum1)) {
2865 printf("close2 failed (%s)\n", cli_errstr(cli1));
2869 if (!cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0)) {
2870 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
2871 CHECK_MAX_FAILURES(error_test1);
2875 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
2877 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2878 CHECK_MAX_FAILURES(error_test1);
2882 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
2883 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
2885 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
2886 NT_STATUS_ACCESS_DENIED)) {
2887 printf("correct error code ERRDOS/ERRnoaccess returned\n");
2890 printf("finished open test 1\n");
2892 cli_close(cli1, fnum1);
2894 /* Now try not readonly and ensure ERRbadshare is returned. */
2896 cli_setatr(cli1, fname, 0, 0);
2898 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
2900 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2904 /* This will fail - but the error should be ERRshare. */
2905 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
2907 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
2908 NT_STATUS_SHARING_VIOLATION)) {
2909 printf("correct error code ERRDOS/ERRbadshare returned\n");
2912 if (!cli_close(cli1, fnum1)) {
2913 printf("close2 failed (%s)\n", cli_errstr(cli1));
2917 cli_unlink(cli1, fname);
2919 printf("finished open test 2\n");
2921 /* Test truncate open disposition on file opened for read. */
2923 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2925 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
2929 /* write 20 bytes. */
2931 memset(buf, '\0', 20);
2933 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
2934 printf("write failed (%s)\n", cli_errstr(cli1));
2938 if (!cli_close(cli1, fnum1)) {
2939 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
2943 /* Ensure size == 20. */
2944 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
2945 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
2946 CHECK_MAX_FAILURES(error_test3);
2951 printf("(3) file size != 20\n");
2952 CHECK_MAX_FAILURES(error_test3);
2956 /* Now test if we can truncate a file opened for readonly. */
2958 fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
2960 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
2961 CHECK_MAX_FAILURES(error_test3);
2965 if (!cli_close(cli1, fnum1)) {
2966 printf("close2 failed (%s)\n", cli_errstr(cli1));
2970 /* Ensure size == 0. */
2971 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
2972 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
2973 CHECK_MAX_FAILURES(error_test3);
2978 printf("(3) file size != 0\n");
2979 CHECK_MAX_FAILURES(error_test3);
2982 printf("finished open test 3\n");
2984 cli_unlink(cli1, fname);
2987 printf("testing ctemp\n");
2988 fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
2990 printf("ctemp failed (%s)\n", cli_errstr(cli1));
2991 CHECK_MAX_FAILURES(error_test4);
2994 printf("ctemp gave path %s\n", tmp_path);
2995 if (!cli_close(cli1, fnum1)) {
2996 printf("close of temp failed (%s)\n", cli_errstr(cli1));
2998 if (!cli_unlink(cli1, tmp_path)) {
2999 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3002 /* Test the non-io opens... */
3004 if (!torture_open_connection(&cli2)) {
3008 cli_setatr(cli2, fname, 0, 0);
3009 cli_unlink(cli2, fname);
3011 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3013 fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3014 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3017 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3018 CHECK_MAX_FAILURES(error_test10);
3022 fnum2 = cli_nt_create_full(cli2, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3023 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3025 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3026 CHECK_MAX_FAILURES(error_test10);
3030 if (!cli_close(cli1, fnum1)) {
3031 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3034 if (!cli_close(cli2, fnum2)) {
3035 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3039 printf("non-io open test #1 passed.\n");
3041 cli_unlink(cli1, fname);
3043 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3045 fnum1 = cli_nt_create_full(cli1, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3046 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3049 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3050 CHECK_MAX_FAILURES(error_test20);
3054 fnum2 = cli_nt_create_full(cli2, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3055 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3058 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3059 CHECK_MAX_FAILURES(error_test20);
3063 if (!cli_close(cli1, fnum1)) {
3064 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3067 if (!cli_close(cli2, fnum2)) {
3068 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3072 printf("non-io open test #2 passed.\n");
3074 cli_unlink(cli1, fname);
3076 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3078 fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3079 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3082 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3083 CHECK_MAX_FAILURES(error_test30);
3087 fnum2 = cli_nt_create_full(cli2, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3088 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3091 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3092 CHECK_MAX_FAILURES(error_test30);
3096 if (!cli_close(cli1, fnum1)) {
3097 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3100 if (!cli_close(cli2, fnum2)) {
3101 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3105 printf("non-io open test #3 passed.\n");
3107 cli_unlink(cli1, fname);
3109 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3111 fnum1 = cli_nt_create_full(cli1, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3112 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3115 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3116 CHECK_MAX_FAILURES(error_test40);
3120 fnum2 = cli_nt_create_full(cli2, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3121 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3124 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
3125 CHECK_MAX_FAILURES(error_test40);
3129 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
3131 if (!cli_close(cli1, fnum1)) {
3132 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3136 printf("non-io open test #4 passed.\n");
3138 cli_unlink(cli1, fname);
3140 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3142 fnum1 = cli_nt_create_full(cli1, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3143 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3146 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3147 CHECK_MAX_FAILURES(error_test50);
3151 fnum2 = cli_nt_create_full(cli2, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3152 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3155 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3156 CHECK_MAX_FAILURES(error_test50);
3160 if (!cli_close(cli1, fnum1)) {
3161 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3165 if (!cli_close(cli2, fnum2)) {
3166 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3170 printf("non-io open test #5 passed.\n");
3172 printf("TEST #6 testing 1 non-io open, one io open\n");
3174 cli_unlink(cli1, fname);
3176 fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3177 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3180 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3181 CHECK_MAX_FAILURES(error_test60);
3185 fnum2 = cli_nt_create_full(cli2, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3186 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
3189 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3190 CHECK_MAX_FAILURES(error_test60);
3194 if (!cli_close(cli1, fnum1)) {
3195 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3199 if (!cli_close(cli2, fnum2)) {
3200 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3204 printf("non-io open test #6 passed.\n");
3206 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3208 cli_unlink(cli1, fname);
3210 fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3211 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3214 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3215 CHECK_MAX_FAILURES(error_test70);
3219 fnum2 = cli_nt_create_full(cli2, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3220 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3223 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
3224 CHECK_MAX_FAILURES(error_test70);
3228 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
3230 if (!cli_close(cli1, fnum1)) {
3231 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3235 printf("non-io open test #7 passed.\n");
3237 cli_unlink(cli1, fname);
3239 if (!torture_close_connection(cli1)) {
3242 if (!torture_close_connection(cli2)) {
3250 static uint32 open_attrs_table[] = {
3251 FILE_ATTRIBUTE_NORMAL,
3252 FILE_ATTRIBUTE_ARCHIVE,
3253 FILE_ATTRIBUTE_READONLY,
3254 FILE_ATTRIBUTE_HIDDEN,
3255 FILE_ATTRIBUTE_SYSTEM,
3257 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
3258 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
3259 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
3260 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3261 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3262 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3264 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3265 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3266 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3267 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
3270 struct trunc_open_results {
3277 static struct trunc_open_results attr_results[] = {
3278 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3279 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3280 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3281 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3282 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3283 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3284 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3285 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3286 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3287 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3288 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3289 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
3290 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3291 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3292 { 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 },
3293 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3294 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3295 { 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 },
3296 { 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 },
3297 { 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 },
3298 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3299 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3300 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3301 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3302 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3303 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
3306 static BOOL run_openattrtest(int dummy)
3308 struct cli_state *cli1;
3309 const char *fname = "\\openattr.file";
3311 BOOL correct = True;
3313 unsigned int i, j, k, l;
3316 printf("starting open attr test\n");
3318 if (!torture_open_connection(&cli1)) {
3322 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
3323 cli_setatr(cli1, fname, 0, 0);
3324 cli_unlink(cli1, fname);
3325 fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_WRITE_DATA, open_attrs_table[i],
3326 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3329 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
3333 if (!cli_close(cli1, fnum1)) {
3334 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
3338 for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
3339 fnum1 = cli_nt_create_full(cli1, fname, 0,
3340 SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
3341 open_attrs_table[j],
3342 NTCREATEX_SHARE_ACCESS_NONE,
3343 NTCREATEX_DISP_OVERWRITE, 0, 0);
3346 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3347 if (attr_results[l].num == k) {
3348 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
3349 k, open_attrs_table[i],
3350 open_attrs_table[j],
3351 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
3353 CHECK_MAX_FAILURES(error_exit);
3356 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
3357 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
3358 k, open_attrs_table[i], open_attrs_table[j],
3361 CHECK_MAX_FAILURES(error_exit);
3364 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
3370 if (!cli_close(cli1, fnum1)) {
3371 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
3375 if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
3376 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
3381 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
3382 k, open_attrs_table[i], open_attrs_table[j], attr );
3385 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3386 if (attr_results[l].num == k) {
3387 if (attr != attr_results[l].result_attr ||
3388 open_attrs_table[i] != attr_results[l].init_attr ||
3389 open_attrs_table[j] != attr_results[l].trunc_attr) {
3390 printf("[%d] getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
3391 k, open_attrs_table[i],
3392 open_attrs_table[j],
3394 attr_results[l].result_attr);
3396 CHECK_MAX_FAILURES(error_exit);
3405 cli_setatr(cli1, fname, 0, 0);
3406 cli_unlink(cli1, fname);
3408 printf("open attr test %s.\n", correct ? "passed" : "failed");
3410 if (!torture_close_connection(cli1)) {
3416 static void list_fn(file_info *finfo, const char *name, void *state)
3422 test directory listing speed
3424 static BOOL run_dirtest(int dummy)
3427 struct cli_state *cli;
3430 BOOL correct = True;
3432 printf("starting directory test\n");
3434 if (!torture_open_connection(&cli)) {
3438 printf("Creating %d random filenames\n", torture_numops);
3441 for (i=0;i<torture_numops;i++) {
3443 asprintf(&fname, "\\%x", (int)random());
3444 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
3446 fprintf(stderr,"Failed to open %s\n", fname);
3449 cli_close(cli, fnum);
3455 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
3456 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
3457 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
3459 printf("dirtest core %g seconds\n", end_timer() - t1);
3462 for (i=0;i<torture_numops;i++) {
3464 asprintf(&fname, "\\%x", (int)random());
3465 cli_unlink(cli, fname);
3469 if (!torture_close_connection(cli)) {
3473 printf("finished dirtest\n");
3478 static void del_fn(file_info *finfo, const char *mask, void *state)
3480 struct cli_state *pcli = (struct cli_state *)state;
3482 asprintf(&fname, "\\LISTDIR\\%s", finfo->name);
3484 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
3487 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
3488 if (!cli_rmdir(pcli, fname))
3489 printf("del_fn: failed to rmdir %s, error=%s\n", fname, cli_errstr(pcli) );
3491 if (!cli_unlink(pcli, fname))
3492 printf("del_fn: failed to unlink %s, error=%s\n", fname, cli_errstr(pcli) );
3499 sees what IOCTLs are supported
3501 BOOL torture_ioctl_test(int dummy)
3503 struct cli_state *cli;
3504 uint16 device, function;
3506 const char *fname = "\\ioctl.dat";
3508 union smb_ioctl parms;
3509 TALLOC_CTX *mem_ctx;
3511 if (!torture_open_connection(&cli)) {
3515 mem_ctx = talloc_init("ioctl_test");
3517 printf("starting ioctl test\n");
3519 cli_unlink(cli, fname);
3521 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3523 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3527 parms.ioctl.level = RAW_IOCTL_IOCTL;
3528 parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
3529 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3530 printf("ioctl job info: %s\n", cli_errstr(cli));
3532 for (device=0;device<0x100;device++) {
3533 printf("testing device=0x%x\n", device);
3534 for (function=0;function<0x100;function++) {
3535 parms.ioctl.in.request = (device << 16) | function;
3536 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3538 if (NT_STATUS_IS_OK(status)) {
3539 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
3540 device, function, parms.ioctl.out.blob.length);
3545 if (!torture_close_connection(cli)) {
3554 tries variants of chkpath
3556 BOOL torture_chkpath_test(int dummy)
3558 struct cli_state *cli;
3562 if (!torture_open_connection(&cli)) {
3566 printf("starting chkpath test\n");
3568 printf("Testing valid and invalid paths\n");
3570 /* cleanup from an old run */
3571 cli_rmdir(cli, "\\chkpath.dir\\dir2");
3572 cli_unlink(cli, "\\chkpath.dir\\*");
3573 cli_rmdir(cli, "\\chkpath.dir");
3575 if (!cli_mkdir(cli, "\\chkpath.dir")) {
3576 printf("mkdir1 failed : %s\n", cli_errstr(cli));
3580 if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
3581 printf("mkdir2 failed : %s\n", cli_errstr(cli));
3585 fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3587 printf("open1 failed (%s)\n", cli_errstr(cli));
3590 cli_close(cli, fnum);
3592 if (!cli_chkpath(cli, "\\chkpath.dir")) {
3593 printf("chkpath1 failed: %s\n", cli_errstr(cli));
3597 if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
3598 printf("chkpath2 failed: %s\n", cli_errstr(cli));
3602 if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
3603 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3604 NT_STATUS_NOT_A_DIRECTORY);
3606 printf("* chkpath on a file should fail\n");
3610 if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
3611 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
3612 NT_STATUS_OBJECT_NAME_NOT_FOUND);
3614 printf("* chkpath on a non existent file should fail\n");
3618 if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
3619 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3620 NT_STATUS_OBJECT_PATH_NOT_FOUND);
3622 printf("* chkpath on a non existent component should fail\n");
3626 cli_rmdir(cli, "\\chkpath.dir\\dir2");
3627 cli_unlink(cli, "\\chkpath.dir\\*");
3628 cli_rmdir(cli, "\\chkpath.dir");
3630 if (!torture_close_connection(cli)) {
3637 static BOOL run_dirtest1(int dummy)
3640 struct cli_state *cli;
3642 BOOL correct = True;
3644 printf("starting directory test\n");
3646 if (!torture_open_connection(&cli)) {
3650 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
3651 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
3652 if (cli_deltree(cli, "\\LISTDIR") == -1) {
3653 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", cli_errstr(cli));
3656 if (!cli_mkdir(cli, "\\LISTDIR")) {
3657 fprintf(stderr,"Failed to mkdir %s, error=%s\n", "\\LISTDIR", cli_errstr(cli));
3661 printf("Creating %d files\n", torture_entries);
3663 /* Create torture_entries files and torture_entries directories. */
3664 for (i=0;i<torture_entries;i++) {
3666 asprintf(&fname, "\\LISTDIR\\f%d", i);
3667 fnum = cli_nt_create_full(cli, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3668 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3670 fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli));
3674 cli_close(cli, fnum);
3676 for (i=0;i<torture_entries;i++) {
3678 asprintf(&fname, "\\LISTDIR\\d%d", i);
3679 if (!cli_mkdir(cli, fname)) {
3680 fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli));
3686 /* Now ensure that doing an old list sees both files and directories. */
3687 num_seen = cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3688 printf("num_seen = %d\n", num_seen );
3689 /* We should see (torture_entries) each of files & directories + . and .. */
3690 if (num_seen != (2*torture_entries)+2) {
3692 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3693 (2*torture_entries)+2, num_seen);
3697 /* Ensure if we have the "must have" bits we only see the
3700 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3701 printf("num_seen = %d\n", num_seen );
3702 if (num_seen != torture_entries+2) {
3704 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3705 torture_entries+2, num_seen);
3708 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3709 printf("num_seen = %d\n", num_seen );
3710 if (num_seen != torture_entries) {
3712 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3713 torture_entries, num_seen);
3716 /* Delete everything. */
3717 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
3718 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
3719 cli_rmdir(cli, "\\LISTDIR");
3722 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
3723 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
3724 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
3727 if (!torture_close_connection(cli)) {
3731 printf("finished dirtest1\n");
3738 simple test harness for playing with deny modes
3740 static BOOL run_deny3test(int dummy)
3742 struct cli_state *cli1, *cli2;
3746 printf("starting deny3 test\n");
3748 printf("Testing simple deny modes\n");
3750 if (!torture_open_connection(&cli1)) {
3753 if (!torture_open_connection(&cli2)) {
3757 fname = "\\deny_dos1.dat";
3759 cli_unlink(cli1, fname);
3760 fnum1 = cli_open(cli1, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3761 fnum2 = cli_open(cli1, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3762 if (fnum1 != -1) cli_close(cli1, fnum1);
3763 if (fnum2 != -1) cli_close(cli1, fnum2);
3764 cli_unlink(cli1, fname);
3765 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3768 fname = "\\deny_dos2.dat";
3770 cli_unlink(cli1, fname);
3771 fnum1 = cli_open(cli1, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3772 fnum2 = cli_open(cli2, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3773 if (fnum1 != -1) cli_close(cli1, fnum1);
3774 if (fnum2 != -1) cli_close(cli2, fnum2);
3775 cli_unlink(cli1, fname);
3776 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3779 torture_close_connection(cli1);
3780 torture_close_connection(cli2);
3785 static void sigcont(void)
3789 static double create_procs(BOOL (*fn)(int), BOOL *result)
3792 volatile pid_t *child_status;
3793 volatile BOOL *child_status_out;
3796 double start_time_limit = 10 + (nprocs * 1.5);
3800 signal(SIGCONT, sigcont);
3802 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
3803 if (!child_status) {
3804 printf("Failed to setup shared memory\n");
3808 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
3809 if (!child_status_out) {
3810 printf("Failed to setup result status shared memory\n");
3814 for (i = 0; i < nprocs; i++) {
3815 child_status[i] = 0;
3816 child_status_out[i] = True;
3821 for (i=0;i<nprocs;i++) {
3825 pid_t mypid = getpid();
3826 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
3828 asprintf(&myname, "CLIENT%d", i);
3829 lp_set_cmdline("netbios name", myname);
3833 if (torture_open_connection(¤t_cli)) break;
3835 printf("pid %d failed to start\n", (int)getpid());
3841 child_status[i] = getpid();
3845 if (child_status[i]) {
3846 printf("Child %d failed to start!\n", i);
3847 child_status_out[i] = 1;
3851 child_status_out[i] = fn(i);
3858 for (i=0;i<nprocs;i++) {
3859 if (child_status[i]) synccount++;
3861 if (synccount == nprocs) break;
3863 } while (end_timer() < start_time_limit);
3865 if (synccount != nprocs) {
3866 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
3871 printf("Starting %d clients\n", nprocs);
3873 /* start the client load */
3875 for (i=0;i<nprocs;i++) {
3876 child_status[i] = 0;
3880 printf("%d clients started\n", nprocs);
3882 for (i=0;i<nprocs;i++) {
3884 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
3885 if (ret == -1 || WEXITSTATUS(status) != 0) {
3892 for (i=0;i<nprocs;i++) {
3893 if (!child_status_out[i]) {
3900 #define FLAG_MULTIPROC 1
3907 {"FDPASS", run_fdpasstest, 0},
3908 {"LOCK1", run_locktest1, 0},
3909 {"LOCK2", run_locktest2, 0},
3910 {"LOCK3", run_locktest3, 0},
3911 {"LOCK4", run_locktest4, 0},
3912 {"LOCK5", run_locktest5, 0},
3913 {"LOCK6", run_locktest6, 0},
3914 {"LOCK7", run_locktest7, 0},
3915 {"UNLINK", run_unlinktest, 0},
3916 {"ATTR", run_attrtest, 0},
3917 {"TRANS2", run_trans2test, 0},
3918 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
3919 {"TORTURE",run_torture, FLAG_MULTIPROC},
3920 {"NEGNOWAIT", run_negprot_nowait, 0},
3921 {"NBENCH", run_nbench, 0},
3922 {"DIR", run_dirtest, 0},
3923 {"DIR1", run_dirtest1, 0},
3924 {"DENY1", torture_denytest1, 0},
3925 {"DENY2", torture_denytest2, 0},
3926 {"TCON", run_tcon_test, 0},
3927 {"TCONDEV", run_tcon_devtype_test, 0},
3929 {"DFSBASIC", torture_dfs_basic, 0},
3930 {"DFSRENAME", torture_dfs_rename, 0},
3931 {"DFSRANDOM", torture_dfs_random, 0},
3933 {"RW1", run_readwritetest, 0},
3934 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
3935 {"OPEN", run_opentest, 0},
3936 {"DENY3", run_deny3test, 0},
3938 {"OPENATTR", run_openattrtest, 0},
3940 {"XCOPY", run_xcopy, 0},
3941 {"RENAME", run_rename, 0},
3942 {"DELETE", run_deletetest, 0},
3943 {"PROPERTIES", run_properties, 0},
3944 {"MANGLE", torture_mangle, 0},
3945 {"UTABLE", torture_utable, 0},
3946 {"CASETABLE", torture_casetable, 0},
3947 {"PIPE_NUMBER", run_pipe_number, 0},
3948 {"IOCTL", torture_ioctl_test, 0},
3949 {"CHKPATH", torture_chkpath_test, 0},
3950 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
3951 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
3952 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
3953 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
3954 {"RAW-SEARCH", torture_raw_search, 0},
3955 {"RAW-CLOSE", torture_raw_close, 0},
3956 {"RAW-OPEN", torture_raw_open, 0},
3957 {"RAW-MKDIR", torture_raw_mkdir, 0},
3958 {"RAW-OPLOCK", torture_raw_oplock, 0},
3959 {"RAW-NOTIFY", torture_raw_notify, 0},
3960 {"RAW-MUX", torture_raw_mux, 0},
3961 {"RAW-IOCTL", torture_raw_ioctl, 0},
3962 {"RAW-CHKPATH", torture_raw_chkpath, 0},
3963 {"RAW-UNLINK", torture_raw_unlink, 0},
3964 {"RAW-READ", torture_raw_read, 0},
3965 {"RAW-WRITE", torture_raw_write, 0},
3966 {"RAW-LOCK", torture_raw_lock, 0},
3967 {"RAW-CONTEXT", torture_raw_context, 0},
3968 {"RAW-RENAME", torture_raw_rename, 0},
3969 {"RAW-SEEK", torture_raw_seek, 0},
3970 {"SCAN-TRANS2", torture_trans2_scan, 0},
3971 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
3972 {"SCAN-ALIASES", torture_trans2_aliases, 0},
3973 {"SCAN-SMB", torture_smb_scan, 0},
3974 {"RPC-LSA", torture_rpc_lsa, 0},
3975 {"RPC-ECHO", torture_rpc_echo, 0},
3976 {"RPC-DFS", torture_rpc_dfs, 0},
3977 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
3978 {"RPC-SAMR", torture_rpc_samr, 0},
3979 {"RPC-NETLOGON", torture_rpc_netlogon, 0},
3980 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
3981 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
3982 {"RPC-ATSVC", torture_rpc_atsvc, 0},
3983 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
3984 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
3985 {"RPC-WINREG", torture_rpc_winreg, 0},
3986 {"RPC-MGMT", torture_rpc_mgmt, 0},
3987 {"RPC-SCANNER", torture_rpc_scanner, 0},
3988 {"RPC-AUTOIDL", torture_rpc_autoidl, 0},
3993 /****************************************************************************
3994 run a specified test or "ALL"
3995 ****************************************************************************/
3996 static BOOL run_test(const char *name)
4000 BOOL matched = False;
4002 if (strequal(name,"ALL")) {
4003 for (i=0;torture_ops[i].name;i++) {
4004 if (!run_test(torture_ops[i].name)) {
4011 for (i=0;torture_ops[i].name;i++) {
4012 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
4015 printf("Running %s\n", torture_ops[i].name);
4016 if (torture_ops[i].flags & FLAG_MULTIPROC) {
4018 t = create_procs(torture_ops[i].fn, &result);
4021 printf("TEST %s FAILED!\n", torture_ops[i].name);
4026 if (!torture_ops[i].fn(0)) {
4028 printf("TEST %s FAILED!\n", torture_ops[i].name);
4032 printf("%s took %g secs\n\n", torture_ops[i].name, t);
4037 printf("Unknown torture operation '%s'\n", name);
4045 parse a username%password
4047 static void parse_user(const char *user)
4049 char *username, *password, *p;
4051 username = strdup(user);
4052 p = strchr_m(username,'%');
4055 password = strdup(p+1);
4058 lp_set_cmdline("torture:username", username);
4059 lp_set_cmdline("torture:password", password);
4063 static void usage(void)
4067 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
4069 printf("\t-d debuglevel\n");
4070 printf("\t-U user%%pass\n");
4071 printf("\t-k use kerberos\n");
4072 printf("\t-N numprocs\n");
4073 printf("\t-n my_netbios_name\n");
4074 printf("\t-W workgroup\n");
4075 printf("\t-o num_operations\n");
4076 printf("\t-e num files(entries)\n");
4077 printf("\t-O socket_options\n");
4078 printf("\t-m maximum protocol\n");
4079 printf("\t-L use oplocks\n");
4080 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
4081 printf("\t-A showall\n");
4082 printf("\t-p port\n");
4083 printf("\t-s seed\n");
4084 printf("\t-f max failures\n");
4085 printf("\t-b bypass I/O (NBENCH)\n");
4088 printf("tests are:");
4089 for (i=0;torture_ops[i].name;i++) {
4090 printf(" %s", torture_ops[i].name);
4094 printf("default test is ALL\n");
4099 /****************************************************************************
4101 ****************************************************************************/
4102 int main(int argc,char *argv[])
4106 BOOL correct = True;
4107 char *host, *share, *username;
4109 setup_logging("smbtorture", DEBUG_STDOUT);
4111 #ifdef HAVE_SETBUFFER
4112 setbuffer(stdout, NULL, 0);
4115 lp_load(dyn_CONFIGFILE,True,False,False);
4122 for(p = argv[1]; *p; p++)
4127 /* see if its a RPC transport specifier */
4128 if (strncmp(argv[1], "ncacn_", 6) == 0) {
4129 lp_set_cmdline("torture:binding", argv[1]);
4131 char *binding = NULL;
4132 if (strncmp(argv[1], "//", 2)) {
4136 host = strdup(&argv[1][2]);
4137 p = strchr_m(&host[2],'/');
4142 share = strdup(p+1);
4144 lp_set_cmdline("torture:host", host);
4145 lp_set_cmdline("torture:share", share);
4146 lp_set_cmdline("torture:password", "");
4147 asprintf(&binding, "ncacn_np:%s", host);
4148 lp_set_cmdline("torture:binding", binding);
4151 if (getenv("LOGNAME")) {
4152 username = strdup(getenv("LOGNAME"));
4154 lp_set_cmdline("torture:username", username);
4160 srandom(time(NULL));
4162 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:e:m:Ld:Ac:ks:f:s:")) != EOF) {
4165 lp_set_cmdline("smb ports", optarg);
4168 lp_set_cmdline("workgroup", optarg);
4171 lp_set_cmdline("protocol", optarg);
4174 lp_set_cmdline("netbios name", optarg);
4177 lp_set_cmdline("debug level", optarg);
4178 setup_logging(NULL, DEBUG_STDOUT);
4181 lp_set_cmdline("socket options", optarg);
4184 srandom(atoi(optarg));
4187 nprocs = atoi(optarg);
4190 torture_numops = atoi(optarg);
4193 torture_entries = atoi(optarg);
4199 torture_showall = True;
4202 client_txt = optarg;
4206 use_kerberos = True;
4208 d_printf("No kerberos support compiled in\n");
4216 torture_failures = atoi(optarg);
4220 printf("Unknown option %c (%d)\n", (char)opt, opt);
4225 if (argc == optind) {
4226 printf("You must specify a test to run, or 'ALL'\n");
4228 for (i=optind;i<argc;i++) {
4229 if (!run_test(argv[i])) {