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"));
133 /* open a rpc connection to a named pipe */
134 static NTSTATUS torture_rpc_tcp(struct dcerpc_pipe **p,
135 const char *pipe_name,
136 const char *pipe_uuid,
140 char *host = lp_parm_string(-1, "torture", "host");
141 const char *port_str = lp_parm_string(-1, "torture", "share");
142 uint32 port = atoi(port_str);
145 status = dcerpc_epm_map_tcp_port(host,
146 pipe_uuid, pipe_version,
148 if (!NT_STATUS_IS_OK(status)) {
149 DEBUG(0,("Failed to map DCERPC/TCP port for '%s' - %s\n",
150 pipe_name, nt_errstr(status)));
153 DEBUG(1,("Mapped to DCERPC/TCP port %u\n", port));
156 DEBUG(2,("Connecting to dcerpc server %s:%u\n", host, port));
158 status = dcerpc_pipe_open_tcp(p, host, port);
159 if (!NT_STATUS_IS_OK(status)) {
160 printf("Open of pipe '%s' failed with error (%s)\n",
161 pipe_name, nt_errstr(status));
165 /* always do NDR validation in smbtorture */
166 (*p)->flags |= DCERPC_DEBUG_VALIDATE_BOTH;
168 /* enable signing on tcp connections */
169 (*p)->flags |= DCERPC_SIGN;
171 /* bind to the pipe, using the uuid as the key */
172 status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version,
174 lp_parm_string(-1, "torture", "username"),
175 lp_parm_string(-1, "torture", "password"));
176 if (!NT_STATUS_IS_OK(status)) {
177 dcerpc_pipe_close(*p);
185 /* open a rpc connection to a named pipe */
186 NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p,
187 const char *pipe_name,
188 const char *pipe_uuid,
191 struct cli_state *cli;
193 char *transport = lp_parm_string(-1, "torture", "transport");
195 if (strcmp(transport, "ncacn_ip_tcp") == 0) {
196 return torture_rpc_tcp(p, pipe_name, pipe_uuid, pipe_version);
199 if (strcmp(transport, "ncacn_np") != 0) {
200 printf("Unsupported RPC transport '%s'\n", transport);
201 return NT_STATUS_UNSUCCESSFUL;
204 if (! *lp_parm_string(-1, "torture", "share")) {
205 lp_set_cmdline("torture:share", "ipc$");
208 if (!torture_open_connection(&cli)) {
209 return NT_STATUS_UNSUCCESSFUL;
212 status = dcerpc_pipe_open_smb(p, cli->tree, pipe_name);
213 if (!NT_STATUS_IS_OK(status)) {
214 printf("Open of pipe '%s' failed with error (%s)\n",
215 pipe_name, nt_errstr(status));
216 torture_close_connection(cli);
220 /* bind to the pipe, using the uuid as the key */
221 status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version);
222 if (!NT_STATUS_IS_OK(status)) {
223 dcerpc_pipe_close(*p);
227 /* always do NDR validation in smbtorture */
228 (*p)->flags |= DCERPC_DEBUG_VALIDATE_BOTH;
233 /* close a rpc connection to a named pipe */
234 NTSTATUS torture_rpc_close(struct dcerpc_pipe *p)
236 dcerpc_pipe_close(p);
241 /* check if the server produced the expected error code */
242 static BOOL check_error(int line, struct cli_state *c,
243 uint8 eclass, uint32 ecode, NTSTATUS nterr)
245 if (cli_is_dos_error(c)) {
249 /* Check DOS error */
251 cli_dos_error(c, &class, &num);
253 if (eclass != class || ecode != num) {
254 printf("unexpected error code class=%d code=%d\n",
255 (int)class, (int)num);
256 printf(" expected %d/%d %s (line=%d)\n",
257 (int)eclass, (int)ecode, nt_errstr(nterr), line);
266 status = cli_nt_error(c);
268 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
269 printf("unexpected error code %s\n", nt_errstr(status));
270 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
279 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
281 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
282 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
288 static BOOL rw_torture(struct cli_state *c)
290 const char *lockfname = "\\torture.lck";
294 pid_t pid2, pid = getpid();
299 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
302 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
304 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
309 for (i=0;i<torture_numops;i++) {
310 unsigned n = (unsigned)sys_random()%10;
312 printf("%d\r", i); fflush(stdout);
314 asprintf(&fname, "\\torture.%u", n);
316 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
320 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
322 printf("open failed (%s)\n", cli_errstr(c));
327 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
328 printf("write failed (%s)\n", cli_errstr(c));
333 if (cli_write(c, fnum, 0, (char *)buf,
334 sizeof(pid)+(j*sizeof(buf)),
335 sizeof(buf)) != sizeof(buf)) {
336 printf("write failed (%s)\n", cli_errstr(c));
343 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
344 printf("read failed (%s)\n", cli_errstr(c));
349 printf("data corruption!\n");
353 if (!cli_close(c, fnum)) {
354 printf("close failed (%s)\n", cli_errstr(c));
358 if (!cli_unlink(c, fname)) {
359 printf("unlink failed (%s)\n", cli_errstr(c));
363 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
364 printf("unlock failed (%s)\n", cli_errstr(c));
371 cli_unlink(c, lockfname);
378 static BOOL run_torture(int dummy)
380 struct cli_state *cli;
385 ret = rw_torture(cli);
387 if (!torture_close_connection(cli)) {
394 static BOOL rw_torture3(struct cli_state *c, const char *lockfname)
401 unsigned countprev = 0;
406 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
408 SIVAL(buf, i, sys_random());
413 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
416 printf("first open read/write of %s failed (%s)\n",
417 lockfname, cli_errstr(c));
423 for (i = 0; i < 500 && fnum == -1; i++)
425 fnum = cli_open(c, lockfname, O_RDONLY,
430 printf("second open read-only of %s failed (%s)\n",
431 lockfname, cli_errstr(c));
437 for (count = 0; count < sizeof(buf); count += sent)
439 if (count >= countprev) {
440 printf("%d %8d\r", i, count);
443 countprev += (sizeof(buf) / 20);
448 sent = ((unsigned)sys_random()%(20))+ 1;
449 if (sent > sizeof(buf) - count)
451 sent = sizeof(buf) - count;
454 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
455 printf("write failed (%s)\n", cli_errstr(c));
461 sent = cli_read(c, fnum, buf_rd+count, count,
465 printf("read failed offset:%d size:%d (%s)\n",
466 count, sizeof(buf)-count,
473 if (memcmp(buf_rd+count, buf+count, sent) != 0)
475 printf("read/write compare failed\n");
476 printf("offset: %d req %d recvd %d\n",
477 count, sizeof(buf)-count, sent);
486 if (!cli_close(c, fnum)) {
487 printf("close failed (%s)\n", cli_errstr(c));
494 static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
496 const char *lockfname = "\\torture2.lck";
501 uchar buf_rd[131072];
503 ssize_t bytes_read, bytes_written;
505 if (cli_deltree(c1, lockfname) == -1) {
506 printf("unlink failed (%s)\n", cli_errstr(c1));
509 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
512 printf("first open read/write of %s failed (%s)\n",
513 lockfname, cli_errstr(c1));
516 fnum2 = cli_open(c2, lockfname, O_RDONLY,
519 printf("second open read-only of %s failed (%s)\n",
520 lockfname, cli_errstr(c2));
521 cli_close(c1, fnum1);
525 printf("Checking data integrity over %d ops\n", torture_numops);
527 for (i=0;i<torture_numops;i++)
529 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
531 printf("%d\r", i); fflush(stdout);
534 generate_random_buffer(buf, buf_size, False);
536 if ((bytes_written = cli_write(c1, fnum1, 0, buf, 0, buf_size)) != buf_size) {
537 printf("write failed (%s)\n", cli_errstr(c1));
538 printf("wrote %d, expected %d\n", bytes_written, buf_size);
543 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
544 printf("read failed (%s)\n", cli_errstr(c2));
545 printf("read %d, expected %d\n", bytes_read, buf_size);
550 if (memcmp(buf_rd, buf, buf_size) != 0)
552 printf("read/write compare failed\n");
558 if (!cli_close(c2, fnum2)) {
559 printf("close failed (%s)\n", cli_errstr(c2));
562 if (!cli_close(c1, fnum1)) {
563 printf("close failed (%s)\n", cli_errstr(c1));
567 if (!cli_unlink(c1, lockfname)) {
568 printf("unlink failed (%s)\n", cli_errstr(c1));
575 static BOOL run_readwritetest(int dummy)
577 struct cli_state *cli1, *cli2;
578 BOOL test1, test2 = True;
580 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
584 printf("starting readwritetest\n");
586 test1 = rw_torture2(cli1, cli2);
587 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
590 test2 = rw_torture2(cli1, cli1);
591 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
594 if (!torture_close_connection(cli1)) {
598 if (!torture_close_connection(cli2)) {
602 return (test1 && test2);
605 static BOOL run_readwritemulti(int dummy)
607 struct cli_state *cli;
612 test = rw_torture3(cli, "\\multitest.txt");
614 if (!torture_close_connection(cli)) {
625 #define ival(s) strtol(s, NULL, 0)
627 /* run a test that simulates an approximate netbench client load */
628 static BOOL run_netbench(int client)
630 struct cli_state *cli;
635 const char *params[20];
644 asprintf(&cname, "client%d", client);
646 f = fopen(client_txt, "r");
653 while (fgets(line, sizeof(line)-1, f)) {
656 line[strlen(line)-1] = 0;
658 /* printf("[%d] %s\n", line_count, line); */
660 all_string_sub(line,"client1", cname, sizeof(line));
662 /* parse the command parameters */
663 params[0] = strtok(line," ");
665 while (params[i]) params[++i] = strtok(NULL," ");
671 if (!strncmp(params[0],"SMB", 3)) {
672 printf("ERROR: You are using a dbench 1 load file\n");
675 DEBUG(9,("run_netbench(%d): %s %s\n", client, params[0], params[1]));
677 if (!strcmp(params[0],"NTCreateX")) {
678 nb_createx(params[1], ival(params[2]), ival(params[3]),
680 } else if (!strcmp(params[0],"Close")) {
681 nb_close(ival(params[1]));
682 } else if (!strcmp(params[0],"Rename")) {
683 nb_rename(params[1], params[2]);
684 } else if (!strcmp(params[0],"Unlink")) {
685 nb_unlink(params[1]);
686 } else if (!strcmp(params[0],"Deltree")) {
687 nb_deltree(params[1]);
688 } else if (!strcmp(params[0],"Rmdir")) {
690 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
691 nb_qpathinfo(params[1]);
692 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
693 nb_qfileinfo(ival(params[1]));
694 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
695 nb_qfsinfo(ival(params[1]));
696 } else if (!strcmp(params[0],"FIND_FIRST")) {
697 nb_findfirst(params[1]);
698 } else if (!strcmp(params[0],"WriteX")) {
699 nb_writex(ival(params[1]),
700 ival(params[2]), ival(params[3]), ival(params[4]));
701 } else if (!strcmp(params[0],"ReadX")) {
702 nb_readx(ival(params[1]),
703 ival(params[2]), ival(params[3]), ival(params[4]));
704 } else if (!strcmp(params[0],"Flush")) {
705 nb_flush(ival(params[1]));
707 printf("Unknown operation %s\n", params[0]);
715 if (!torture_close_connection(cli)) {
723 /* run a test that simulates an approximate netbench client load */
724 static BOOL run_nbench(int dummy)
733 signal(SIGALRM, SIGNAL_CAST nb_alarm);
735 t = create_procs(run_netbench, &correct);
738 printf("\nThroughput %g MB/sec\n",
739 1.0e-6 * nbio_total() / t);
745 This test checks for two things:
747 1) correct support for retaining locks over a close (ie. the server
748 must not use posix semantics)
749 2) support for lock timeouts
751 static BOOL run_locktest1(int dummy)
753 struct cli_state *cli1, *cli2;
754 const char *fname = "\\lockt1.lck";
755 int fnum1, fnum2, fnum3;
757 unsigned lock_timeout;
759 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
763 printf("starting locktest1\n");
765 cli_unlink(cli1, fname);
767 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
769 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
772 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
774 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
777 fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
779 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
783 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
784 printf("lock1 failed (%s)\n", cli_errstr(cli1));
789 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
790 printf("lock2 succeeded! This is a locking bug\n");
793 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
794 NT_STATUS_LOCK_NOT_GRANTED)) return False;
798 lock_timeout = (6 + (random() % 20));
799 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
801 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
802 printf("lock3 succeeded! This is a locking bug\n");
805 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
806 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
811 printf("error: This server appears not to support timed lock requests\n");
813 printf("server slept for %u seconds for a %u second timeout\n",
814 (unsigned int)(t2-t1), lock_timeout);
816 if (!cli_close(cli1, fnum2)) {
817 printf("close1 failed (%s)\n", cli_errstr(cli1));
821 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
822 printf("lock4 succeeded! This is a locking bug\n");
825 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
826 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
829 if (!cli_close(cli1, fnum1)) {
830 printf("close2 failed (%s)\n", cli_errstr(cli1));
834 if (!cli_close(cli2, fnum3)) {
835 printf("close3 failed (%s)\n", cli_errstr(cli2));
839 if (!cli_unlink(cli1, fname)) {
840 printf("unlink failed (%s)\n", cli_errstr(cli1));
845 if (!torture_close_connection(cli1)) {
849 if (!torture_close_connection(cli2)) {
853 printf("Passed locktest1\n");
858 this checks to see if a secondary tconx can use open files from an
861 static BOOL run_tcon_test(int dummy)
863 struct cli_state *cli;
864 const char *fname = "\\tcontest.tmp";
866 uint16 cnum1, cnum2, cnum3;
870 struct cli_tree *tree1;
871 char *host = lp_parm_string(-1, "torture", "host");
872 char *share = lp_parm_string(-1, "torture", "share");
873 char *password = lp_parm_string(-1, "torture", "password");
875 if (!torture_open_connection(&cli)) {
879 printf("starting tcontest\n");
881 if (cli_deltree(cli, fname) == -1) {
882 printf("unlink of %s failed (%s)\n", fname, cli_errstr(cli));
885 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
887 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
891 cnum1 = cli->tree->tid;
892 vuid1 = cli->session->vuid;
894 memset(&buf, 0, 4); /* init buf so valgrind won't complain */
895 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
896 printf("initial write failed (%s)\n", cli_errstr(cli));
900 tree1 = cli->tree; /* save old tree connection */
901 if (!cli_send_tconX(cli, share, "?????",
903 printf("%s refused 2nd tree connect (%s)\n", host,
909 cnum2 = cli->tree->tid;
910 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
911 vuid2 = cli->session->vuid + 1;
913 /* try a write with the wrong tid */
914 cli->tree->tid = cnum2;
916 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
917 printf("* server allows write with wrong TID\n");
920 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
924 /* try a write with an invalid tid */
925 cli->tree->tid = cnum3;
927 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
928 printf("* server allows write with invalid TID\n");
931 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
934 /* try a write with an invalid vuid */
935 cli->session->vuid = vuid2;
936 cli->tree->tid = cnum1;
938 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
939 printf("* server allows write with invalid VUID\n");
942 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
945 cli->session->vuid = vuid1;
946 cli->tree->tid = cnum1;
948 if (!cli_close(cli, fnum1)) {
949 printf("close failed (%s)\n", cli_errstr(cli));
953 cli->tree->tid = cnum2;
955 if (!cli_tdis(cli)) {
956 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
960 cli->tree = tree1; /* restore initial tree */
961 cli->tree->tid = cnum1;
963 if (!torture_close_connection(cli)) {
972 static BOOL tcon_devtest(struct cli_state *cli,
973 const char *myshare, const char *devtype,
974 NTSTATUS expected_error)
978 char *password = lp_parm_string(-1, "torture", "password");
980 status = cli_send_tconX(cli, myshare, devtype,
983 printf("Trying share %s with devtype %s\n", myshare, devtype);
985 if (NT_STATUS_IS_OK(expected_error)) {
989 printf("tconX to share %s with type %s "
990 "should have succeeded but failed\n",
997 printf("tconx to share %s with type %s "
998 "should have failed but succeeded\n",
1002 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1006 printf("Returned unexpected error\n");
1015 checks for correct tconX support
1017 static BOOL run_tcon_devtype_test(int dummy)
1019 struct cli_state *cli1 = NULL;
1024 char *host = lp_parm_string(-1, "torture", "host");
1025 char *share = lp_parm_string(-1, "torture", "share");
1026 char *username = lp_parm_string(-1, "torture", "username");
1027 char *password = lp_parm_string(-1, "torture", "password");
1029 status = cli_full_connection(&cli1, lp_netbios_name(),
1032 username, lp_workgroup(),
1033 password, flags, &retry);
1035 if (!NT_STATUS_IS_OK(status)) {
1036 printf("could not open connection\n");
1040 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
1043 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
1046 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
1049 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
1052 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
1055 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
1058 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
1061 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
1064 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
1067 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
1073 printf("Passed tcondevtest\n");
1080 This test checks that
1082 1) the server supports multiple locking contexts on the one SMB
1083 connection, distinguished by PID.
1085 2) the server correctly fails overlapping locks made by the same PID (this
1086 goes against POSIX behaviour, which is why it is tricky to implement)
1088 3) the server denies unlock requests by an incorrect client PID
1090 static BOOL run_locktest2(int dummy)
1092 struct cli_state *cli;
1093 const char *fname = "\\lockt2.lck";
1094 int fnum1, fnum2, fnum3;
1095 BOOL correct = True;
1097 if (!torture_open_connection(&cli)) {
1101 printf("starting locktest2\n");
1103 cli_unlink(cli, fname);
1105 printf("Testing pid context\n");
1107 cli->session->pid = 1;
1109 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1111 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1115 fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1117 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1121 cli->session->pid = 2;
1123 fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1125 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1129 cli->session->pid = 1;
1131 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1132 printf("lock1 failed (%s)\n", cli_errstr(cli));
1136 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1137 printf("WRITE lock1 succeeded! This is a locking bug\n");
1140 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1141 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1144 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1145 printf("WRITE lock2 succeeded! This is a locking bug\n");
1148 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1149 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1152 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1153 printf("READ lock2 succeeded! This is a locking bug\n");
1156 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1157 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1160 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1161 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1164 cli->session->pid = 2;
1166 if (cli_unlock(cli, fnum1, 100, 4)) {
1167 printf("unlock at 100 succeeded! This is a locking bug\n");
1171 if (cli_unlock(cli, fnum1, 0, 4)) {
1172 printf("unlock1 succeeded! This is a locking bug\n");
1175 if (!check_error(__LINE__, cli,
1177 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1180 if (cli_unlock(cli, fnum1, 0, 8)) {
1181 printf("unlock2 succeeded! This is a locking bug\n");
1184 if (!check_error(__LINE__, cli,
1186 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1189 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1190 printf("lock3 succeeded! This is a locking bug\n");
1193 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1196 cli->session->pid = 1;
1198 if (!cli_close(cli, fnum1)) {
1199 printf("close1 failed (%s)\n", cli_errstr(cli));
1203 if (!cli_close(cli, fnum2)) {
1204 printf("close2 failed (%s)\n", cli_errstr(cli));
1208 if (!cli_close(cli, fnum3)) {
1209 printf("close3 failed (%s)\n", cli_errstr(cli));
1213 if (!torture_close_connection(cli)) {
1217 printf("locktest2 finished\n");
1224 This test checks that
1226 1) the server supports the full offset range in lock requests
1228 static BOOL run_locktest3(int dummy)
1230 struct cli_state *cli1, *cli2;
1231 const char *fname = "\\lockt3.lck";
1232 int fnum1, fnum2, i;
1234 BOOL correct = True;
1236 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1238 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1242 printf("starting locktest3\n");
1244 printf("Testing 32 bit offset ranges\n");
1246 cli_unlink(cli1, fname);
1248 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1250 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1253 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1255 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1259 printf("Establishing %d locks\n", torture_numops);
1261 for (offset=i=0;i<torture_numops;i++) {
1263 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1264 printf("lock1 %d failed (%s)\n",
1270 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1271 printf("lock2 %d failed (%s)\n",
1278 printf("Testing %d locks\n", torture_numops);
1280 for (offset=i=0;i<torture_numops;i++) {
1283 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1284 printf("error: lock1 %d succeeded!\n", i);
1288 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1289 printf("error: lock2 %d succeeded!\n", i);
1293 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1294 printf("error: lock3 %d succeeded!\n", i);
1298 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1299 printf("error: lock4 %d succeeded!\n", i);
1304 printf("Removing %d locks\n", torture_numops);
1306 for (offset=i=0;i<torture_numops;i++) {
1309 if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
1310 printf("unlock1 %d failed (%s)\n",
1316 if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
1317 printf("unlock2 %d failed (%s)\n",
1324 if (!cli_close(cli1, fnum1)) {
1325 printf("close1 failed (%s)\n", cli_errstr(cli1));
1329 if (!cli_close(cli2, fnum2)) {
1330 printf("close2 failed (%s)\n", cli_errstr(cli2));
1334 if (!cli_unlink(cli1, fname)) {
1335 printf("unlink failed (%s)\n", cli_errstr(cli1));
1339 if (!torture_close_connection(cli1)) {
1343 if (!torture_close_connection(cli2)) {
1347 printf("finished locktest3\n");
1352 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1353 printf("** "); correct = False; \
1357 looks at overlapping locks
1359 static BOOL run_locktest4(int dummy)
1361 struct cli_state *cli1, *cli2;
1362 const char *fname = "\\lockt4.lck";
1363 int fnum1, fnum2, f;
1366 BOOL correct = True;
1368 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1372 printf("starting locktest4\n");
1374 cli_unlink(cli1, fname);
1376 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1377 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1379 memset(buf, 0, sizeof(buf));
1381 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1382 printf("Failed to create file\n");
1387 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1388 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1389 EXPECTED(ret, False);
1390 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1392 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1393 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1394 EXPECTED(ret, True);
1395 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1397 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1398 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1399 EXPECTED(ret, False);
1400 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1402 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1403 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1404 EXPECTED(ret, True);
1405 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1407 ret = (cli1->session->pid = 1, cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1408 (cli1->session->pid = 2, cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1409 EXPECTED(ret, False);
1410 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1412 ret = (cli1->session->pid = 1, cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1413 (cli1->session->pid = 2, cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1414 EXPECTED(ret, True);
1415 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1417 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1418 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1419 EXPECTED(ret, True);
1420 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1422 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1423 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1424 EXPECTED(ret, False);
1425 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1427 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1428 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1429 EXPECTED(ret, False);
1430 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1432 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1433 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1434 EXPECTED(ret, True);
1435 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1437 ret = (cli1->session->pid = 1, cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1438 (cli1->session->pid = 2, cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1439 EXPECTED(ret, False);
1440 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1442 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1443 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1444 cli_unlock(cli1, fnum1, 110, 6);
1445 EXPECTED(ret, False);
1446 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1449 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1450 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1451 EXPECTED(ret, False);
1452 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1454 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1455 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1456 EXPECTED(ret, False);
1457 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1460 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1461 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1462 cli_unlock(cli1, fnum1, 140, 4) &&
1463 cli_unlock(cli1, fnum1, 140, 4);
1464 EXPECTED(ret, True);
1465 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1468 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1469 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1470 cli_unlock(cli1, fnum1, 150, 4) &&
1471 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1472 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1473 cli_unlock(cli1, fnum1, 150, 4);
1474 EXPECTED(ret, True);
1475 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1477 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1478 cli_unlock(cli1, fnum1, 160, 4) &&
1479 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1480 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1481 EXPECTED(ret, True);
1482 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1484 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1485 cli_unlock(cli1, fnum1, 170, 4) &&
1486 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1487 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1488 EXPECTED(ret, True);
1489 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1491 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1492 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1493 cli_unlock(cli1, fnum1, 190, 4) &&
1494 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1495 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1496 EXPECTED(ret, True);
1497 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1499 cli_close(cli1, fnum1);
1500 cli_close(cli2, fnum2);
1501 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1502 f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1503 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1504 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1505 cli_close(cli1, fnum1) &&
1506 ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1507 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1509 cli_close(cli1, fnum1);
1510 EXPECTED(ret, True);
1511 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1514 cli_close(cli1, fnum1);
1515 cli_close(cli2, fnum2);
1516 cli_unlink(cli1, fname);
1517 torture_close_connection(cli1);
1518 torture_close_connection(cli2);
1520 printf("finished locktest4\n");
1525 looks at lock upgrade/downgrade.
1527 static BOOL run_locktest5(int dummy)
1529 struct cli_state *cli1, *cli2;
1530 const char *fname = "\\lockt5.lck";
1531 int fnum1, fnum2, fnum3;
1534 BOOL correct = True;
1536 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1540 printf("starting locktest5\n");
1542 cli_unlink(cli1, fname);
1544 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1545 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1546 fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1548 memset(buf, 0, sizeof(buf));
1550 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1551 printf("Failed to create file\n");
1556 /* Check for NT bug... */
1557 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1558 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1559 cli_close(cli1, fnum1);
1560 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1561 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1562 EXPECTED(ret, True);
1563 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1564 cli_close(cli1, fnum1);
1565 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1566 cli_unlock(cli1, fnum3, 0, 1);
1568 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1569 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1570 EXPECTED(ret, True);
1571 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1573 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1574 EXPECTED(ret, False);
1576 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1578 /* Unlock the process 2 lock. */
1579 cli_unlock(cli2, fnum2, 0, 4);
1581 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1582 EXPECTED(ret, False);
1584 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1586 /* Unlock the process 1 fnum3 lock. */
1587 cli_unlock(cli1, fnum3, 0, 4);
1589 /* Stack 2 more locks here. */
1590 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1591 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1593 EXPECTED(ret, True);
1594 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1596 /* Unlock the first process lock, then check this was the WRITE lock that was
1599 ret = cli_unlock(cli1, fnum1, 0, 4) &&
1600 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1602 EXPECTED(ret, True);
1603 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1605 /* Unlock the process 2 lock. */
1606 cli_unlock(cli2, fnum2, 0, 4);
1608 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1610 ret = cli_unlock(cli1, fnum1, 1, 1) &&
1611 cli_unlock(cli1, fnum1, 0, 4) &&
1612 cli_unlock(cli1, fnum1, 0, 4);
1614 EXPECTED(ret, True);
1615 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1617 /* Ensure the next unlock fails. */
1618 ret = cli_unlock(cli1, fnum1, 0, 4);
1619 EXPECTED(ret, False);
1620 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1622 /* Ensure connection 2 can get a write lock. */
1623 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1624 EXPECTED(ret, True);
1626 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1630 cli_close(cli1, fnum1);
1631 cli_close(cli2, fnum2);
1632 cli_unlink(cli1, fname);
1633 if (!torture_close_connection(cli1)) {
1636 if (!torture_close_connection(cli2)) {
1640 printf("finished locktest5\n");
1646 tries the unusual lockingX locktype bits
1648 static BOOL run_locktest6(int dummy)
1650 struct cli_state *cli;
1651 const char *fname[1] = { "\\lock6.txt" };
1656 if (!torture_open_connection(&cli)) {
1660 printf("starting locktest6\n");
1663 printf("Testing %s\n", fname[i]);
1665 cli_unlink(cli, fname[i]);
1667 fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1668 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1669 cli_close(cli, fnum);
1670 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1672 fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
1673 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1674 cli_close(cli, fnum);
1675 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1677 cli_unlink(cli, fname[i]);
1680 torture_close_connection(cli);
1682 printf("finished locktest6\n");
1686 static BOOL run_locktest7(int dummy)
1688 struct cli_state *cli1;
1689 const char *fname = "\\lockt7.lck";
1692 BOOL correct = False;
1694 if (!torture_open_connection(&cli1)) {
1698 printf("starting locktest7\n");
1700 cli_unlink(cli1, fname);
1702 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1704 memset(buf, 0, sizeof(buf));
1706 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1707 printf("Failed to create file\n");
1711 cli1->session->pid = 1;
1713 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1714 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1717 printf("pid1 successfully locked range 130:4 for READ\n");
1720 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1721 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1724 printf("pid1 successfully read the range 130:4\n");
1727 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1728 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1729 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1730 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1734 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1738 cli1->session->pid = 2;
1740 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1741 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1743 printf("pid2 successfully read the range 130:4\n");
1746 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1747 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1748 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1749 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1753 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1757 cli1->session->pid = 1;
1758 cli_unlock(cli1, fnum1, 130, 4);
1760 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
1761 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
1764 printf("pid1 successfully locked range 130:4 for WRITE\n");
1767 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1768 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1771 printf("pid1 successfully read the range 130:4\n");
1774 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1775 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1778 printf("pid1 successfully wrote to the range 130:4\n");
1781 cli1->session->pid = 2;
1783 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1784 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1785 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1786 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1790 printf("pid2 successfully read the range 130:4 (should be denied)\n");
1794 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1795 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1796 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1797 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1801 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1805 cli_unlock(cli1, fnum1, 130, 0);
1809 cli_close(cli1, fnum1);
1810 cli_unlink(cli1, fname);
1811 torture_close_connection(cli1);
1813 printf("finished locktest7\n");
1818 test whether fnums and tids open on one VC are available on another (a major
1821 static BOOL run_fdpasstest(int dummy)
1823 struct cli_state *cli1, *cli2;
1824 const char *fname = "\\fdpass.tst";
1828 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1832 printf("starting fdpasstest\n");
1834 cli_unlink(cli1, fname);
1836 printf("Opening a file on connection 1\n");
1838 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1840 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1844 printf("writing to file on connection 1\n");
1846 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
1847 printf("write failed (%s)\n", cli_errstr(cli1));
1851 oldtid = cli2->tree->tid;
1852 cli2->session->vuid = cli1->session->vuid;
1853 cli2->tree->tid = cli1->tree->tid;
1854 cli2->session->pid = cli1->session->pid;
1856 printf("reading from file on connection 2\n");
1858 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
1859 printf("read succeeded! nasty security hole [%s]\n",
1864 cli_close(cli1, fnum1);
1865 cli_unlink(cli1, fname);
1867 cli2->tree->tid = oldtid;
1869 torture_close_connection(cli1);
1870 torture_close_connection(cli2);
1872 printf("finished fdpasstest\n");
1878 This test checks that
1880 1) the server does not allow an unlink on a file that is open
1882 static BOOL run_unlinktest(int dummy)
1884 struct cli_state *cli;
1885 const char *fname = "\\unlink.tst";
1887 BOOL correct = True;
1889 if (!torture_open_connection(&cli)) {
1893 printf("starting unlink test\n");
1895 cli_unlink(cli, fname);
1897 cli->session->pid = 1;
1899 printf("Opening a file\n");
1901 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1903 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1907 printf("Unlinking a open file\n");
1909 if (cli_unlink(cli, fname)) {
1910 printf("error: server allowed unlink on an open file\n");
1913 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
1914 NT_STATUS_SHARING_VIOLATION);
1917 cli_close(cli, fnum);
1918 cli_unlink(cli, fname);
1920 if (!torture_close_connection(cli)) {
1924 printf("unlink test finished\n");
1931 test how many open files this server supports on the one socket
1933 static BOOL run_maxfidtest(int dummy)
1935 struct cli_state *cli;
1936 const char *template = "\\maxfid.%d.%d";
1938 int fnums[0x11000], i;
1940 BOOL correct = True;
1945 printf("failed to connect\n");
1949 printf("Testing maximum number of open files\n");
1951 for (i=0; i<0x11000; i++) {
1952 asprintf(&fname, template, i,(int)getpid());
1953 if ((fnums[i] = cli_open(cli, fname,
1954 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1956 printf("open of %s failed (%s)\n",
1957 fname, cli_errstr(cli));
1958 printf("maximum fnum is %d\n", i);
1967 printf("cleaning up\n");
1969 asprintf(&fname, template, i,(int)getpid());
1970 if (!cli_close(cli, fnums[i])) {
1971 printf("Close of fnum %d failed - %s\n", fnums[i], cli_errstr(cli));
1973 if (!cli_unlink(cli, fname)) {
1974 printf("unlink of %s failed (%s)\n",
1975 fname, cli_errstr(cli));
1983 printf("maxfid test finished\n");
1984 if (!torture_close_connection(cli)) {
1990 /* send smb negprot commands, not reading the response */
1991 static BOOL run_negprot_nowait(int dummy)
1994 struct cli_state *cli;
1995 BOOL correct = True;
1997 printf("starting negprot nowait test\n");
1999 cli = open_nbt_connection();
2004 printf("Establishing protocol negotiations - connect with another client\n");
2006 for (i=0;i<50000;i++) {
2007 smb_negprot_send(cli->transport, PROTOCOL_NT1);
2010 if (!torture_close_connection(cli)) {
2014 printf("finished negprot nowait test\n");
2021 This checks how the getatr calls works
2023 static BOOL run_attrtest(int dummy)
2025 struct cli_state *cli;
2028 const char *fname = "\\attrib123456789.tst";
2029 BOOL correct = True;
2031 printf("starting attrib test\n");
2033 if (!torture_open_connection(&cli)) {
2037 cli_unlink(cli, fname);
2038 fnum = cli_open(cli, fname,
2039 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2040 cli_close(cli, fnum);
2042 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2043 printf("getatr failed (%s)\n", cli_errstr(cli));
2047 printf("New file time is %s", ctime(&t));
2049 if (abs(t - time(NULL)) > 60*60*24*10) {
2050 printf("ERROR: SMBgetatr bug. time is %s",
2056 t2 = t-60*60*24; /* 1 day ago */
2058 printf("Setting file time to %s", ctime(&t2));
2060 if (!cli_setatr(cli, fname, 0, t2)) {
2061 printf("setatr failed (%s)\n", cli_errstr(cli));
2065 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2066 printf("getatr failed (%s)\n", cli_errstr(cli));
2070 printf("Retrieved file time as %s", ctime(&t));
2073 printf("ERROR: getatr/setatr bug. times are\n%s",
2075 printf("%s", ctime(&t2));
2079 cli_unlink(cli, fname);
2081 if (!torture_close_connection(cli)) {
2085 printf("attrib test finished\n");
2092 This checks a couple of trans2 calls
2094 static BOOL run_trans2test(int dummy)
2096 struct cli_state *cli;
2099 time_t c_time, a_time, m_time, w_time, m_time2;
2100 const char *fname = "\\trans2.tst";
2101 const char *dname = "\\trans2";
2102 const char *fname2 = "\\trans2\\trans2.tst";
2104 BOOL correct = True;
2106 printf("starting trans2 test\n");
2108 if (!torture_open_connection(&cli)) {
2112 cli_unlink(cli, fname);
2114 printf("Testing qfileinfo\n");
2116 fnum = cli_open(cli, fname,
2117 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2118 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
2120 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2124 printf("Testing NAME_INFO\n");
2126 if (!cli_qfilename(cli, fnum, &pname)) {
2127 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2131 if (!pname || strcmp(pname, fname)) {
2132 printf("qfilename gave different name? [%s] [%s]\n",
2137 cli_close(cli, fnum);
2138 cli_unlink(cli, fname);
2140 fnum = cli_open(cli, fname,
2141 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2143 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2146 cli_close(cli, fnum);
2148 printf("Checking for sticky create times\n");
2150 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2151 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2154 if (c_time != m_time) {
2155 printf("create time=%s", ctime(&c_time));
2156 printf("modify time=%s", ctime(&m_time));
2157 printf("This system appears to have sticky create times\n");
2159 if (a_time % (60*60) == 0) {
2160 printf("access time=%s", ctime(&a_time));
2161 printf("This system appears to set a midnight access time\n");
2165 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2166 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2172 cli_unlink(cli, fname);
2173 fnum = cli_open(cli, fname,
2174 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2175 cli_close(cli, fnum);
2176 if (!cli_qpathinfo2(cli, fname, &c_time, &a_time, &m_time,
2177 &w_time, &size, NULL, NULL)) {
2178 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2181 if (w_time < 60*60*24*2) {
2182 printf("write time=%s", ctime(&w_time));
2183 printf("This system appears to set a initial 0 write time\n");
2188 cli_unlink(cli, fname);
2191 /* check if the server updates the directory modification time
2192 when creating a new file */
2193 if (!cli_mkdir(cli, dname)) {
2194 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2198 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &m_time,
2199 &w_time, &size, NULL, NULL)) {
2200 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2204 fnum = cli_open(cli, fname2,
2205 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2206 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2207 cli_close(cli, fnum);
2208 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &m_time2,
2209 &w_time, &size, NULL, NULL)) {
2210 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2213 if (m_time2 == m_time) {
2214 printf("This system does not update directory modification times\n");
2218 cli_unlink(cli, fname2);
2219 cli_rmdir(cli, dname);
2221 if (!torture_close_connection(cli)) {
2225 printf("trans2 test finished\n");
2231 Test delete on close semantics.
2233 static BOOL run_deletetest(int dummy)
2235 struct cli_state *cli1;
2236 struct cli_state *cli2 = NULL;
2237 const char *fname = "\\delete.file";
2240 BOOL correct = True;
2242 printf("starting delete test\n");
2244 if (!torture_open_connection(&cli1)) {
2248 /* Test 1 - this should delete the file on close. */
2250 cli_setatr(cli1, fname, 0, 0);
2251 cli_unlink(cli1, fname);
2253 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2254 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF,
2255 NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2258 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2263 if (!cli_close(cli1, fnum1)) {
2264 printf("[1] close failed (%s)\n", cli_errstr(cli1));
2269 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
2271 printf("[1] open of %s succeeded (should fail)\n", fname);
2276 printf("first delete on close test succeeded.\n");
2278 /* Test 2 - this should delete the file on close. */
2280 cli_setatr(cli1, fname, 0, 0);
2281 cli_unlink(cli1, fname);
2283 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS,
2284 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE,
2285 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2288 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2293 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2294 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2299 if (!cli_close(cli1, fnum1)) {
2300 printf("[2] close failed (%s)\n", cli_errstr(cli1));
2305 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2307 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2308 if (!cli_close(cli1, fnum1)) {
2309 printf("[2] close failed (%s)\n", cli_errstr(cli1));
2313 cli_unlink(cli1, fname);
2315 printf("second delete on close test succeeded.\n");
2318 cli_setatr(cli1, fname, 0, 0);
2319 cli_unlink(cli1, fname);
2321 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2322 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2325 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
2330 /* This should fail with a sharing violation - open for delete is only compatible
2331 with SHARE_DELETE. */
2333 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2334 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2335 NTCREATEX_DISP_OPEN, 0, 0);
2338 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2343 /* This should succeed. */
2345 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2346 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN, 0, 0);
2349 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
2354 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2355 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2360 if (!cli_close(cli1, fnum1)) {
2361 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
2366 if (!cli_close(cli1, fnum2)) {
2367 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
2372 /* This should fail - file should no longer be there. */
2374 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2376 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2377 if (!cli_close(cli1, fnum1)) {
2378 printf("[3] close failed (%s)\n", cli_errstr(cli1));
2380 cli_unlink(cli1, fname);
2384 printf("third delete on close test succeeded.\n");
2387 cli_setatr(cli1, fname, 0, 0);
2388 cli_unlink(cli1, fname);
2390 fnum1 = cli_nt_create_full(cli1, fname, 0,
2391 SA_RIGHT_FILE_READ_DATA |
2392 SA_RIGHT_FILE_WRITE_DATA |
2393 STD_RIGHT_DELETE_ACCESS,
2394 FILE_ATTRIBUTE_NORMAL,
2395 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE,
2396 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2399 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2404 /* This should succeed. */
2405 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ,
2406 FILE_ATTRIBUTE_NORMAL,
2407 NTCREATEX_SHARE_ACCESS_READ |
2408 NTCREATEX_SHARE_ACCESS_WRITE |
2409 NTCREATEX_SHARE_ACCESS_DELETE,
2410 NTCREATEX_DISP_OPEN, 0, 0);
2412 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
2417 if (!cli_close(cli1, fnum2)) {
2418 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
2423 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2424 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2429 /* This should fail - no more opens once delete on close set. */
2430 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ,
2431 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2432 NTCREATEX_DISP_OPEN, 0, 0);
2434 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2438 printf("fourth delete on close test succeeded.\n");
2440 if (!cli_close(cli1, fnum1)) {
2441 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
2447 cli_setatr(cli1, fname, 0, 0);
2448 cli_unlink(cli1, fname);
2450 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
2452 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2457 /* This should fail - only allowed on NT opens with DELETE access. */
2459 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
2460 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2465 if (!cli_close(cli1, fnum1)) {
2466 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
2471 printf("fifth delete on close test succeeded.\n");
2474 cli_setatr(cli1, fname, 0, 0);
2475 cli_unlink(cli1, fname);
2477 fnum1 = cli_nt_create_full(cli1, fname, 0,
2478 SA_RIGHT_FILE_READ_DATA | SA_RIGHT_FILE_WRITE_DATA,
2479 FILE_ATTRIBUTE_NORMAL,
2480 NTCREATEX_SHARE_ACCESS_READ |
2481 NTCREATEX_SHARE_ACCESS_WRITE |
2482 NTCREATEX_SHARE_ACCESS_DELETE,
2483 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2486 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2491 /* This should fail - only allowed on NT opens with DELETE access. */
2493 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
2494 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2499 if (!cli_close(cli1, fnum1)) {
2500 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
2505 printf("sixth delete on close test succeeded.\n");
2508 cli_setatr(cli1, fname, 0, 0);
2509 cli_unlink(cli1, fname);
2511 fnum1 = cli_nt_create_full(cli1, fname, 0,
2512 SA_RIGHT_FILE_READ_DATA |
2513 SA_RIGHT_FILE_WRITE_DATA |
2514 STD_RIGHT_DELETE_ACCESS,
2515 FILE_ATTRIBUTE_NORMAL, 0, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2518 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2523 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2524 printf("[7] setting delete_on_close on file failed !\n");
2529 if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
2530 printf("[7] unsetting delete_on_close on file failed !\n");
2535 if (!cli_close(cli1, fnum1)) {
2536 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
2541 /* This next open should succeed - we reset the flag. */
2543 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2545 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2550 if (!cli_close(cli1, fnum1)) {
2551 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
2556 printf("seventh delete on close test succeeded.\n");
2559 cli_setatr(cli1, fname, 0, 0);
2560 cli_unlink(cli1, fname);
2562 if (!torture_open_connection(&cli2)) {
2563 printf("[8] failed to open second connection.\n");
2568 fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2569 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2570 NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2573 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2578 fnum2 = cli_nt_create_full(cli2, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2579 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE,
2580 NTCREATEX_DISP_OPEN, 0, 0);
2583 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2588 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2589 printf("[8] setting delete_on_close on file failed !\n");
2594 if (!cli_close(cli1, fnum1)) {
2595 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
2600 if (!cli_close(cli2, fnum2)) {
2601 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
2606 /* This should fail.. */
2607 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2609 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2613 printf("eighth delete on close test succeeded.\n");
2615 /* This should fail - we need to set DELETE_ACCESS. */
2616 fnum1 = cli_nt_create_full(cli1, fname, 0,SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
2617 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2620 printf("[9] open of %s succeeded should have failed!\n", fname);
2625 printf("ninth delete on close test succeeded.\n");
2627 fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|STD_RIGHT_DELETE_ACCESS,
2628 FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0);
2630 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2635 /* This should delete the file. */
2636 if (!cli_close(cli1, fnum1)) {
2637 printf("[10] close failed (%s)\n", cli_errstr(cli1));
2642 /* This should fail.. */
2643 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2645 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2649 printf("tenth delete on close test succeeded.\n");
2650 printf("finished delete test\n");
2653 /* FIXME: This will crash if we aborted before cli2 got
2654 * intialized, because these functions don't handle
2655 * uninitialized connections. */
2657 cli_close(cli1, fnum1);
2658 cli_close(cli1, fnum2);
2659 cli_setatr(cli1, fname, 0, 0);
2660 cli_unlink(cli1, fname);
2662 if (!torture_close_connection(cli1)) {
2665 if (!torture_close_connection(cli2)) {
2673 print out server properties
2675 static BOOL run_properties(int dummy)
2677 struct cli_state *cli;
2678 BOOL correct = True;
2680 printf("starting properties test\n");
2684 if (!torture_open_connection(&cli)) {
2688 d_printf("Capabilities 0x%08x\n", cli->transport->negotiate.capabilities);
2690 if (!torture_close_connection(cli)) {
2699 /* FIRST_DESIRED_ACCESS 0xf019f */
2700 #define FIRST_DESIRED_ACCESS SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA|SA_RIGHT_FILE_APPEND_DATA|\
2701 SA_RIGHT_FILE_READ_EA| /* 0xf */ \
2702 SA_RIGHT_FILE_WRITE_EA|SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x90 */ \
2703 SA_RIGHT_FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
2704 STD_RIGHT_DELETE_ACCESS|STD_RIGHT_READ_CONTROL_ACCESS|\
2705 STD_RIGHT_WRITE_DAC_ACCESS|STD_RIGHT_WRITE_OWNER_ACCESS /* 0xf0000 */
2706 /* SECOND_DESIRED_ACCESS 0xe0080 */
2707 #define SECOND_DESIRED_ACCESS SA_RIGHT_FILE_READ_ATTRIBUTES| /* 0x80 */ \
2708 STD_RIGHT_READ_CONTROL_ACCESS|STD_RIGHT_WRITE_DAC_ACCESS|\
2709 STD_RIGHT_WRITE_OWNER_ACCESS /* 0xe0000 */
2712 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
2713 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2714 SA_RIGHT_FILE_READ_DATA|\
2715 WRITE_OWNER_ACCESS /* */
2719 Test ntcreate calls made by xcopy
2721 static BOOL run_xcopy(int dummy)
2723 struct cli_state *cli1;
2724 const char *fname = "\\test.txt";
2725 BOOL correct = True;
2728 printf("starting xcopy test\n");
2730 if (!torture_open_connection(&cli1)) {
2734 fnum1 = cli_nt_create_full(cli1, fname, 0,
2735 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2736 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF,
2740 printf("First open failed - %s\n", cli_errstr(cli1));
2744 fnum2 = cli_nt_create_full(cli1, fname, 0,
2745 SECOND_DESIRED_ACCESS, 0,
2746 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN,
2749 printf("second open failed - %s\n", cli_errstr(cli1));
2753 if (!torture_close_connection(cli1)) {
2761 Test rename on files open with share delete and no share delete.
2763 static BOOL run_rename(int dummy)
2765 struct cli_state *cli1;
2766 const char *fname = "\\test.txt";
2767 const char *fname1 = "\\test1.txt";
2768 BOOL correct = True;
2771 printf("starting rename test\n");
2773 if (!torture_open_connection(&cli1)) {
2777 cli_unlink(cli1, fname);
2778 cli_unlink(cli1, fname1);
2779 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2780 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2783 printf("First open failed - %s\n", cli_errstr(cli1));
2787 if (!cli_rename(cli1, fname, fname1)) {
2788 printf("First rename failed (this is correct) - %s\n", cli_errstr(cli1));
2790 printf("First rename succeeded - this should have failed !\n");
2794 if (!cli_close(cli1, fnum1)) {
2795 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
2799 cli_unlink(cli1, fname);
2800 cli_unlink(cli1, fname1);
2801 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_RIGHTS_FILE_READ, FILE_ATTRIBUTE_NORMAL,
2803 NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2805 NTCREATEX_SHARE_ACCESS_DELETE|NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2809 printf("Second open failed - %s\n", cli_errstr(cli1));
2813 if (!cli_rename(cli1, fname, fname1)) {
2814 printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(cli1));
2817 printf("Second rename succeeded\n");
2820 if (!cli_close(cli1, fnum1)) {
2821 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
2825 cli_unlink(cli1, fname);
2826 cli_unlink(cli1, fname1);
2828 fnum1 = cli_nt_create_full(cli1, fname, 0, STD_RIGHT_READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2829 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2832 printf("Third open failed - %s\n", cli_errstr(cli1));
2841 fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2842 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
2845 printf("Fourth open failed - %s\n", cli_errstr(cli1));
2848 if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
2849 printf("[8] setting delete_on_close on file failed !\n");
2853 if (!cli_close(cli1, fnum2)) {
2854 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
2860 if (!cli_rename(cli1, fname, fname1)) {
2861 printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(cli1));
2864 printf("Third rename succeeded\n");
2867 if (!cli_close(cli1, fnum1)) {
2868 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
2872 cli_unlink(cli1, fname);
2873 cli_unlink(cli1, fname1);
2875 if (!torture_close_connection(cli1)) {
2882 static BOOL run_pipe_number(int dummy)
2884 struct cli_state *cli1;
2885 const char *pipe_name = "\\WKSSVC";
2889 printf("starting pipenumber test\n");
2890 if (!torture_open_connection(&cli1)) {
2895 fnum = cli_nt_create_full(cli1, pipe_name, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
2896 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
2899 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
2905 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
2906 torture_close_connection(cli1);
2912 Test open mode returns on read-only files.
2914 static BOOL run_opentest(int dummy)
2916 static struct cli_state *cli1;
2917 static struct cli_state *cli2;
2918 const char *fname = "\\readonly.file";
2922 BOOL correct = True;
2926 printf("starting open test\n");
2928 if (!torture_open_connection(&cli1)) {
2932 cli_setatr(cli1, fname, 0, 0);
2933 cli_unlink(cli1, fname);
2935 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2937 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2941 if (!cli_close(cli1, fnum1)) {
2942 printf("close2 failed (%s)\n", cli_errstr(cli1));
2946 if (!cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0)) {
2947 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
2948 CHECK_MAX_FAILURES(error_test1);
2952 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
2954 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2955 CHECK_MAX_FAILURES(error_test1);
2959 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
2960 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
2962 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
2963 NT_STATUS_ACCESS_DENIED)) {
2964 printf("correct error code ERRDOS/ERRnoaccess returned\n");
2967 printf("finished open test 1\n");
2969 cli_close(cli1, fnum1);
2971 /* Now try not readonly and ensure ERRbadshare is returned. */
2973 cli_setatr(cli1, fname, 0, 0);
2975 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
2977 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2981 /* This will fail - but the error should be ERRshare. */
2982 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
2984 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
2985 NT_STATUS_SHARING_VIOLATION)) {
2986 printf("correct error code ERRDOS/ERRbadshare returned\n");
2989 if (!cli_close(cli1, fnum1)) {
2990 printf("close2 failed (%s)\n", cli_errstr(cli1));
2994 cli_unlink(cli1, fname);
2996 printf("finished open test 2\n");
2998 /* Test truncate open disposition on file opened for read. */
3000 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3002 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
3006 /* write 20 bytes. */
3008 memset(buf, '\0', 20);
3010 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
3011 printf("write failed (%s)\n", cli_errstr(cli1));
3015 if (!cli_close(cli1, fnum1)) {
3016 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
3020 /* Ensure size == 20. */
3021 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3022 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3023 CHECK_MAX_FAILURES(error_test3);
3028 printf("(3) file size != 20\n");
3029 CHECK_MAX_FAILURES(error_test3);
3033 /* Now test if we can truncate a file opened for readonly. */
3035 fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3037 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
3038 CHECK_MAX_FAILURES(error_test3);
3042 if (!cli_close(cli1, fnum1)) {
3043 printf("close2 failed (%s)\n", cli_errstr(cli1));
3047 /* Ensure size == 0. */
3048 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3049 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3050 CHECK_MAX_FAILURES(error_test3);
3055 printf("(3) file size != 0\n");
3056 CHECK_MAX_FAILURES(error_test3);
3059 printf("finished open test 3\n");
3061 cli_unlink(cli1, fname);
3064 printf("testing ctemp\n");
3065 fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
3067 printf("ctemp failed (%s)\n", cli_errstr(cli1));
3068 CHECK_MAX_FAILURES(error_test4);
3071 printf("ctemp gave path %s\n", tmp_path);
3072 if (!cli_close(cli1, fnum1)) {
3073 printf("close of temp failed (%s)\n", cli_errstr(cli1));
3075 if (!cli_unlink(cli1, tmp_path)) {
3076 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3079 /* Test the non-io opens... */
3081 if (!torture_open_connection(&cli2)) {
3085 cli_setatr(cli2, fname, 0, 0);
3086 cli_unlink(cli2, fname);
3088 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3090 fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3091 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3094 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3095 CHECK_MAX_FAILURES(error_test10);
3099 fnum2 = cli_nt_create_full(cli2, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3100 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3102 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3103 CHECK_MAX_FAILURES(error_test10);
3107 if (!cli_close(cli1, fnum1)) {
3108 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3111 if (!cli_close(cli2, fnum2)) {
3112 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3116 printf("non-io open test #1 passed.\n");
3118 cli_unlink(cli1, fname);
3120 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3122 fnum1 = cli_nt_create_full(cli1, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3123 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3126 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3127 CHECK_MAX_FAILURES(error_test20);
3131 fnum2 = cli_nt_create_full(cli2, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3132 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3135 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3136 CHECK_MAX_FAILURES(error_test20);
3140 if (!cli_close(cli1, fnum1)) {
3141 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3144 if (!cli_close(cli2, fnum2)) {
3145 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3149 printf("non-io open test #2 passed.\n");
3151 cli_unlink(cli1, fname);
3153 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3155 fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3156 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3159 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3160 CHECK_MAX_FAILURES(error_test30);
3164 fnum2 = cli_nt_create_full(cli2, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3165 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3168 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3169 CHECK_MAX_FAILURES(error_test30);
3173 if (!cli_close(cli1, fnum1)) {
3174 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3177 if (!cli_close(cli2, fnum2)) {
3178 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3182 printf("non-io open test #3 passed.\n");
3184 cli_unlink(cli1, fname);
3186 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3188 fnum1 = cli_nt_create_full(cli1, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3189 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3192 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3193 CHECK_MAX_FAILURES(error_test40);
3197 fnum2 = cli_nt_create_full(cli2, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3198 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3201 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
3202 CHECK_MAX_FAILURES(error_test40);
3206 printf("test 4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
3208 if (!cli_close(cli1, fnum1)) {
3209 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3213 printf("non-io open test #4 passed.\n");
3215 cli_unlink(cli1, fname);
3217 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3219 fnum1 = cli_nt_create_full(cli1, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3220 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3223 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3224 CHECK_MAX_FAILURES(error_test50);
3228 fnum2 = cli_nt_create_full(cli2, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3229 NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3232 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3233 CHECK_MAX_FAILURES(error_test50);
3237 if (!cli_close(cli1, fnum1)) {
3238 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3242 if (!cli_close(cli2, fnum2)) {
3243 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3247 printf("non-io open test #5 passed.\n");
3249 printf("TEST #6 testing 1 non-io open, one io open\n");
3251 cli_unlink(cli1, fname);
3253 fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3254 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3257 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3258 CHECK_MAX_FAILURES(error_test60);
3262 fnum2 = cli_nt_create_full(cli2, fname, 0, SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3263 NTCREATEX_SHARE_ACCESS_READ, NTCREATEX_DISP_OPEN_IF, 0, 0);
3266 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3267 CHECK_MAX_FAILURES(error_test60);
3271 if (!cli_close(cli1, fnum1)) {
3272 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3276 if (!cli_close(cli2, fnum2)) {
3277 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3281 printf("non-io open test #6 passed.\n");
3283 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3285 cli_unlink(cli1, fname);
3287 fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3288 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3291 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3292 CHECK_MAX_FAILURES(error_test70);
3296 fnum2 = cli_nt_create_full(cli2, fname, 0, STD_RIGHT_DELETE_ACCESS|SA_RIGHT_FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3297 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_DELETE, NTCREATEX_DISP_OPEN_IF, 0, 0);
3300 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
3301 CHECK_MAX_FAILURES(error_test70);
3305 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
3307 if (!cli_close(cli1, fnum1)) {
3308 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3312 printf("non-io open test #7 passed.\n");
3314 cli_unlink(cli1, fname);
3316 if (!torture_close_connection(cli1)) {
3319 if (!torture_close_connection(cli2)) {
3327 static uint32 open_attrs_table[] = {
3328 FILE_ATTRIBUTE_NORMAL,
3329 FILE_ATTRIBUTE_ARCHIVE,
3330 FILE_ATTRIBUTE_READONLY,
3331 FILE_ATTRIBUTE_HIDDEN,
3332 FILE_ATTRIBUTE_SYSTEM,
3334 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
3335 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
3336 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
3337 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3338 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3339 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3341 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3342 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3343 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3344 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
3347 struct trunc_open_results {
3354 static struct trunc_open_results attr_results[] = {
3355 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3356 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3357 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3358 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3359 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3360 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3361 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3362 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3363 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3364 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3365 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3366 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
3367 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3368 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3369 { 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 },
3370 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3371 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3372 { 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 },
3373 { 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 },
3374 { 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 },
3375 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3376 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3377 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3378 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3379 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3380 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
3383 static BOOL run_openattrtest(int dummy)
3385 struct cli_state *cli1;
3386 const char *fname = "\\openattr.file";
3388 BOOL correct = True;
3390 unsigned int i, j, k, l;
3393 printf("starting open attr test\n");
3395 if (!torture_open_connection(&cli1)) {
3399 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
3400 cli_setatr(cli1, fname, 0, 0);
3401 cli_unlink(cli1, fname);
3402 fnum1 = cli_nt_create_full(cli1, fname, 0, SA_RIGHT_FILE_WRITE_DATA, open_attrs_table[i],
3403 NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3406 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
3410 if (!cli_close(cli1, fnum1)) {
3411 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
3415 for (j = 0; j < ARRAY_SIZE(open_attrs_table); j++) {
3416 fnum1 = cli_nt_create_full(cli1, fname, 0,
3417 SA_RIGHT_FILE_READ_DATA|SA_RIGHT_FILE_WRITE_DATA,
3418 open_attrs_table[j],
3419 NTCREATEX_SHARE_ACCESS_NONE,
3420 NTCREATEX_DISP_OVERWRITE, 0, 0);
3423 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3424 if (attr_results[l].num == k) {
3425 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
3426 k, open_attrs_table[i],
3427 open_attrs_table[j],
3428 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
3430 CHECK_MAX_FAILURES(error_exit);
3433 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
3434 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
3435 k, open_attrs_table[i], open_attrs_table[j],
3438 CHECK_MAX_FAILURES(error_exit);
3441 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
3447 if (!cli_close(cli1, fnum1)) {
3448 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
3452 if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
3453 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
3458 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
3459 k, open_attrs_table[i], open_attrs_table[j], attr );
3462 for (l = 0; l < ARRAY_SIZE(attr_results); l++) {
3463 if (attr_results[l].num == k) {
3464 if (attr != attr_results[l].result_attr ||
3465 open_attrs_table[i] != attr_results[l].init_attr ||
3466 open_attrs_table[j] != attr_results[l].trunc_attr) {
3467 printf("[%d] getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
3468 k, open_attrs_table[i],
3469 open_attrs_table[j],
3471 attr_results[l].result_attr);
3473 CHECK_MAX_FAILURES(error_exit);
3482 cli_setatr(cli1, fname, 0, 0);
3483 cli_unlink(cli1, fname);
3485 printf("open attr test %s.\n", correct ? "passed" : "failed");
3487 if (!torture_close_connection(cli1)) {
3493 static void list_fn(file_info *finfo, const char *name, void *state)
3499 test directory listing speed
3501 static BOOL run_dirtest(int dummy)
3504 struct cli_state *cli;
3507 BOOL correct = True;
3509 printf("starting directory test\n");
3511 if (!torture_open_connection(&cli)) {
3515 printf("Creating %d random filenames\n", torture_numops);
3518 for (i=0;i<torture_numops;i++) {
3520 asprintf(&fname, "\\%x", (int)random());
3521 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
3523 fprintf(stderr,"Failed to open %s\n", fname);
3526 cli_close(cli, fnum);
3532 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
3533 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
3534 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
3536 printf("dirtest core %g seconds\n", end_timer() - t1);
3539 for (i=0;i<torture_numops;i++) {
3541 asprintf(&fname, "\\%x", (int)random());
3542 cli_unlink(cli, fname);
3546 if (!torture_close_connection(cli)) {
3550 printf("finished dirtest\n");
3555 static void del_fn(file_info *finfo, const char *mask, void *state)
3557 struct cli_state *pcli = (struct cli_state *)state;
3559 asprintf(&fname, "\\LISTDIR\\%s", finfo->name);
3561 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
3564 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
3565 if (!cli_rmdir(pcli, fname))
3566 printf("del_fn: failed to rmdir %s, error=%s\n", fname, cli_errstr(pcli) );
3568 if (!cli_unlink(pcli, fname))
3569 printf("del_fn: failed to unlink %s, error=%s\n", fname, cli_errstr(pcli) );
3576 sees what IOCTLs are supported
3578 BOOL torture_ioctl_test(int dummy)
3580 struct cli_state *cli;
3581 uint16 device, function;
3583 const char *fname = "\\ioctl.dat";
3586 struct smb_ioctl parms;
3587 TALLOC_CTX *mem_ctx;
3589 if (!torture_open_connection(&cli)) {
3593 mem_ctx = talloc_init("ioctl_test");
3595 printf("starting ioctl test\n");
3597 cli_unlink(cli, fname);
3599 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3601 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3605 parms.in.request = IOCTL_QUERY_JOB_INFO;
3606 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3607 printf("ioctl job info: %s\n", cli_errstr(cli));
3609 for (device=0;device<0x100;device++) {
3610 printf("testing device=0x%x\n", device);
3611 for (function=0;function<0x100;function++) {
3612 parms.in.request = (device << 16) | function;
3613 status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
3615 if (NT_STATUS_IS_OK(status)) {
3616 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
3617 device, function, blob.length);
3618 data_blob_free(&parms.out.blob);
3623 if (!torture_close_connection(cli)) {
3632 tries variants of chkpath
3634 BOOL torture_chkpath_test(int dummy)
3636 struct cli_state *cli;
3640 if (!torture_open_connection(&cli)) {
3644 printf("starting chkpath test\n");
3646 printf("Testing valid and invalid paths\n");
3648 /* cleanup from an old run */
3649 cli_rmdir(cli, "\\chkpath.dir\\dir2");
3650 cli_unlink(cli, "\\chkpath.dir\\*");
3651 cli_rmdir(cli, "\\chkpath.dir");
3653 if (!cli_mkdir(cli, "\\chkpath.dir")) {
3654 printf("mkdir1 failed : %s\n", cli_errstr(cli));
3658 if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
3659 printf("mkdir2 failed : %s\n", cli_errstr(cli));
3663 fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3665 printf("open1 failed (%s)\n", cli_errstr(cli));
3668 cli_close(cli, fnum);
3670 if (!cli_chkpath(cli, "\\chkpath.dir")) {
3671 printf("chkpath1 failed: %s\n", cli_errstr(cli));
3675 if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
3676 printf("chkpath2 failed: %s\n", cli_errstr(cli));
3680 if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
3681 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3682 NT_STATUS_NOT_A_DIRECTORY);
3684 printf("* chkpath on a file should fail\n");
3688 if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
3689 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
3690 NT_STATUS_OBJECT_NAME_NOT_FOUND);
3692 printf("* chkpath on a non existent file should fail\n");
3696 if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
3697 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
3698 NT_STATUS_OBJECT_PATH_NOT_FOUND);
3700 printf("* chkpath on a non existent component should fail\n");
3704 cli_rmdir(cli, "\\chkpath.dir\\dir2");
3705 cli_unlink(cli, "\\chkpath.dir\\*");
3706 cli_rmdir(cli, "\\chkpath.dir");
3708 if (!torture_close_connection(cli)) {
3715 static BOOL run_dirtest1(int dummy)
3718 struct cli_state *cli;
3720 BOOL correct = True;
3722 printf("starting directory test\n");
3724 if (!torture_open_connection(&cli)) {
3728 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
3729 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
3730 if (cli_deltree(cli, "\\LISTDIR") == -1) {
3731 fprintf(stderr,"Failed to deltree %s, error=%s\n", "\\LISTDIR", cli_errstr(cli));
3734 if (!cli_mkdir(cli, "\\LISTDIR")) {
3735 fprintf(stderr,"Failed to mkdir %s, error=%s\n", "\\LISTDIR", cli_errstr(cli));
3739 printf("Creating %d files\n", torture_entries);
3741 /* Create torture_entries files and torture_entries directories. */
3742 for (i=0;i<torture_entries;i++) {
3744 asprintf(&fname, "\\LISTDIR\\f%d", i);
3745 fnum = cli_nt_create_full(cli, fname, 0, GENERIC_RIGHTS_FILE_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3746 NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OVERWRITE_IF, 0, 0);
3748 fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli));
3752 cli_close(cli, fnum);
3754 for (i=0;i<torture_entries;i++) {
3756 asprintf(&fname, "\\LISTDIR\\d%d", i);
3757 if (!cli_mkdir(cli, fname)) {
3758 fprintf(stderr,"Failed to open %s, error=%s\n", fname, cli_errstr(cli));
3764 /* Now ensure that doing an old list sees both files and directories. */
3765 num_seen = cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3766 printf("num_seen = %d\n", num_seen );
3767 /* We should see (torture_entries) each of files & directories + . and .. */
3768 if (num_seen != (2*torture_entries)+2) {
3770 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3771 (2*torture_entries)+2, num_seen);
3775 /* Ensure if we have the "must have" bits we only see the
3778 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3779 printf("num_seen = %d\n", num_seen );
3780 if (num_seen != torture_entries+2) {
3782 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3783 torture_entries+2, num_seen);
3786 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, NULL);
3787 printf("num_seen = %d\n", num_seen );
3788 if (num_seen != torture_entries) {
3790 fprintf(stderr,"entry count mismatch, should be %d, was %d\n",
3791 torture_entries, num_seen);
3794 /* Delete everything. */
3795 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
3796 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
3797 cli_rmdir(cli, "\\LISTDIR");
3800 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
3801 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
3802 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
3805 if (!torture_close_connection(cli)) {
3809 printf("finished dirtest1\n");
3816 simple test harness for playing with deny modes
3818 static BOOL run_deny3test(int dummy)
3820 struct cli_state *cli1, *cli2;
3824 printf("starting deny3 test\n");
3826 printf("Testing simple deny modes\n");
3828 if (!torture_open_connection(&cli1)) {
3831 if (!torture_open_connection(&cli2)) {
3835 fname = "\\deny_dos1.dat";
3837 cli_unlink(cli1, fname);
3838 fnum1 = cli_open(cli1, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3839 fnum2 = cli_open(cli1, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3840 if (fnum1 != -1) cli_close(cli1, fnum1);
3841 if (fnum2 != -1) cli_close(cli1, fnum2);
3842 cli_unlink(cli1, fname);
3843 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3846 fname = "\\deny_dos2.dat";
3848 cli_unlink(cli1, fname);
3849 fnum1 = cli_open(cli1, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3850 fnum2 = cli_open(cli2, fname, O_CREAT|O_TRUNC|O_WRONLY, DENY_DOS);
3851 if (fnum1 != -1) cli_close(cli1, fnum1);
3852 if (fnum2 != -1) cli_close(cli2, fnum2);
3853 cli_unlink(cli1, fname);
3854 printf("fnum1=%d fnum2=%d\n", fnum1, fnum2);
3857 torture_close_connection(cli1);
3858 torture_close_connection(cli2);
3863 static void sigcont(void)
3867 static double create_procs(BOOL (*fn)(int), BOOL *result)
3870 volatile pid_t *child_status;
3871 volatile BOOL *child_status_out;
3874 double start_time_limit = 10 + (nprocs * 1.5);
3878 signal(SIGCONT, sigcont);
3880 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
3881 if (!child_status) {
3882 printf("Failed to setup shared memory\n");
3886 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
3887 if (!child_status_out) {
3888 printf("Failed to setup result status shared memory\n");
3892 for (i = 0; i < nprocs; i++) {
3893 child_status[i] = 0;
3894 child_status_out[i] = True;
3899 for (i=0;i<nprocs;i++) {
3903 pid_t mypid = getpid();
3904 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
3906 asprintf(&myname, "CLIENT%d", i);
3907 lp_set_cmdline("netbios name", myname);
3911 if (torture_open_connection(¤t_cli)) break;
3913 printf("pid %d failed to start\n", (int)getpid());
3919 child_status[i] = getpid();
3923 if (child_status[i]) {
3924 printf("Child %d failed to start!\n", i);
3925 child_status_out[i] = 1;
3929 child_status_out[i] = fn(i);
3936 for (i=0;i<nprocs;i++) {
3937 if (child_status[i]) synccount++;
3939 if (synccount == nprocs) break;
3941 } while (end_timer() < start_time_limit);
3943 if (synccount != nprocs) {
3944 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
3949 printf("Starting %d clients\n", nprocs);
3951 /* start the client load */
3953 for (i=0;i<nprocs;i++) {
3954 child_status[i] = 0;
3958 printf("%d clients started\n", nprocs);
3960 for (i=0;i<nprocs;i++) {
3962 while ((ret=waitpid(0, &status, 0)) == -1 && errno == EINTR) /* noop */ ;
3963 if (ret == -1 || WEXITSTATUS(status) != 0) {
3970 for (i=0;i<nprocs;i++) {
3971 if (!child_status_out[i]) {
3978 #define FLAG_MULTIPROC 1
3985 {"FDPASS", run_fdpasstest, 0},
3986 {"LOCK1", run_locktest1, 0},
3987 {"LOCK2", run_locktest2, 0},
3988 {"LOCK3", run_locktest3, 0},
3989 {"LOCK4", run_locktest4, 0},
3990 {"LOCK5", run_locktest5, 0},
3991 {"LOCK6", run_locktest6, 0},
3992 {"LOCK7", run_locktest7, 0},
3993 {"UNLINK", run_unlinktest, 0},
3994 {"ATTR", run_attrtest, 0},
3995 {"TRANS2", run_trans2test, 0},
3996 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
3997 {"TORTURE",run_torture, FLAG_MULTIPROC},
3998 {"NEGNOWAIT", run_negprot_nowait, 0},
3999 {"NBENCH", run_nbench, 0},
4000 {"DIR", run_dirtest, 0},
4001 {"DIR1", run_dirtest1, 0},
4002 {"DENY1", torture_denytest1, 0},
4003 {"DENY2", torture_denytest2, 0},
4004 {"TCON", run_tcon_test, 0},
4005 {"TCONDEV", run_tcon_devtype_test, 0},
4007 {"DFSBASIC", torture_dfs_basic, 0},
4008 {"DFSRENAME", torture_dfs_rename, 0},
4009 {"DFSRANDOM", torture_dfs_random, 0},
4011 {"RW1", run_readwritetest, 0},
4012 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
4013 {"OPEN", run_opentest, 0},
4014 {"DENY3", run_deny3test, 0},
4016 {"OPENATTR", run_openattrtest, 0},
4018 {"XCOPY", run_xcopy, 0},
4019 {"RENAME", run_rename, 0},
4020 {"DELETE", run_deletetest, 0},
4021 {"PROPERTIES", run_properties, 0},
4022 {"MANGLE", torture_mangle, 0},
4023 {"UTABLE", torture_utable, 0},
4024 {"CASETABLE", torture_casetable, 0},
4025 {"PIPE_NUMBER", run_pipe_number, 0},
4026 {"IOCTL", torture_ioctl_test, 0},
4027 {"CHKPATH", torture_chkpath_test, 0},
4028 {"RAW-QFSINFO", torture_raw_qfsinfo, 0},
4029 {"RAW-QFILEINFO", torture_raw_qfileinfo, 0},
4030 {"RAW-SFILEINFO", torture_raw_sfileinfo, 0},
4031 {"RAW-SFILEINFO-BUG", torture_raw_sfileinfo_bug, 0},
4032 {"RAW-SEARCH", torture_raw_search, 0},
4033 {"RAW-CLOSE", torture_raw_close, 0},
4034 {"RAW-OPEN", torture_raw_open, 0},
4035 {"RAW-MKDIR", torture_raw_mkdir, 0},
4036 {"RAW-OPLOCK", torture_raw_oplock, 0},
4037 {"RAW-NOTIFY", torture_raw_notify, 0},
4038 {"RAW-MUX", torture_raw_mux, 0},
4039 {"RAW-IOCTL", torture_raw_ioctl, 0},
4040 {"RAW-CHKPATH", torture_raw_chkpath, 0},
4041 {"RAW-UNLINK", torture_raw_unlink, 0},
4042 {"RAW-READ", torture_raw_read, 0},
4043 {"RAW-WRITE", torture_raw_write, 0},
4044 {"RAW-LOCK", torture_raw_lock, 0},
4045 {"RAW-CONTEXT", torture_raw_context, 0},
4046 {"RAW-RENAME", torture_raw_rename, 0},
4047 {"RAW-SEEK", torture_raw_seek, 0},
4048 {"SCAN-TRANS2", torture_trans2_scan, 0},
4049 {"SCAN-NTTRANS", torture_nttrans_scan, 0},
4050 {"SCAN-ALIASES", torture_trans2_aliases, 0},
4051 {"SCAN-SMB", torture_smb_scan, 0},
4052 {"RPC-LSA", torture_rpc_lsa, 0},
4053 {"RPC-ECHO", torture_rpc_echo, 0},
4054 {"RPC-DFS", torture_rpc_dfs, 0},
4055 {"RPC-SPOOLSS", torture_rpc_spoolss, 0},
4056 {"RPC-SAMR", torture_rpc_samr, 0},
4057 {"RPC-WKSSVC", torture_rpc_wkssvc, 0},
4058 {"RPC-SRVSVC", torture_rpc_srvsvc, 0},
4059 {"RPC-ATSVC", torture_rpc_atsvc, 0},
4060 {"RPC-EVENTLOG", torture_rpc_eventlog, 0},
4061 {"RPC-EPMAPPER", torture_rpc_epmapper, 0},
4062 {"RPC-WINREG", torture_rpc_winreg, 0},
4063 {"RPC-MGMT", torture_rpc_mgmt, 0},
4068 /****************************************************************************
4069 run a specified test or "ALL"
4070 ****************************************************************************/
4071 static BOOL run_test(const char *name)
4075 BOOL matched = False;
4077 if (strequal(name,"ALL")) {
4078 for (i=0;torture_ops[i].name;i++) {
4079 if (!run_test(torture_ops[i].name)) {
4086 for (i=0;torture_ops[i].name;i++) {
4087 if (gen_fnmatch(name, torture_ops[i].name) == 0) {
4090 printf("Running %s\n", torture_ops[i].name);
4091 if (torture_ops[i].flags & FLAG_MULTIPROC) {
4093 t = create_procs(torture_ops[i].fn, &result);
4096 printf("TEST %s FAILED!\n", torture_ops[i].name);
4101 if (!torture_ops[i].fn(0)) {
4103 printf("TEST %s FAILED!\n", torture_ops[i].name);
4107 printf("%s took %g secs\n\n", torture_ops[i].name, t);
4112 printf("Unknown torture operation '%s'\n", name);
4120 parse a username%password
4122 static void parse_user(const char *user)
4124 char *username, *password, *p;
4126 username = strdup(user);
4127 p = strchr_m(username,'%');
4130 password = strdup(p+1);
4133 lp_set_cmdline("torture:username", username);
4134 lp_set_cmdline("torture:password", password);
4138 static void usage(void)
4142 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
4144 printf("\t-d debuglevel\n");
4145 printf("\t-U user%%pass\n");
4146 printf("\t-k use kerberos\n");
4147 printf("\t-N numprocs\n");
4148 printf("\t-n my_netbios_name\n");
4149 printf("\t-W workgroup\n");
4150 printf("\t-o num_operations\n");
4151 printf("\t-e num files(entries)\n");
4152 printf("\t-O socket_options\n");
4153 printf("\t-m maximum protocol\n");
4154 printf("\t-L use oplocks\n");
4155 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
4156 printf("\t-A showall\n");
4157 printf("\t-p port\n");
4158 printf("\t-s seed\n");
4159 printf("\t-f max failures\n");
4160 printf("\t-b bypass I/O (NBENCH)\n");
4163 printf("tests are:");
4164 for (i=0;torture_ops[i].name;i++) {
4165 printf(" %s", torture_ops[i].name);
4169 printf("default test is ALL\n");
4174 /****************************************************************************
4176 ****************************************************************************/
4177 int main(int argc,char *argv[])
4181 BOOL correct = True;
4182 char *host, *share, *username;
4184 setup_logging("smbtorture", DEBUG_STDOUT);
4186 #ifdef HAVE_SETBUFFER
4187 setbuffer(stdout, NULL, 0);
4190 lp_load(dyn_CONFIGFILE,True,False,False);
4197 for(p = argv[1]; *p; p++)
4202 /* see if its a RPC transport specifier */
4203 if (strncmp(argv[1], "ncacn", 5) == 0) {
4204 char *transport = strdup(argv[1]);
4205 p = strchr_m(transport, ':');
4209 p = strchr_m(host, ':');
4213 lp_set_cmdline("torture:share", share);
4216 lp_set_cmdline("torture:share", share);
4218 lp_set_cmdline("torture:host", host);
4219 lp_set_cmdline("torture:transport", transport);
4221 if (strncmp(argv[1], "//", 2)) {
4225 host = strdup(&argv[1][2]);
4226 p = strchr_m(&host[2],'/');
4231 share = strdup(p+1);
4233 lp_set_cmdline("torture:host", host);
4234 lp_set_cmdline("torture:share", share);
4235 lp_set_cmdline("torture:password", "");
4236 lp_set_cmdline("torture:transport", "ncacn_np");
4239 if (getenv("LOGNAME")) {
4240 username = strdup(getenv("LOGNAME"));
4242 lp_set_cmdline("torture:username", username);
4248 srandom(time(NULL));
4250 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:e:m:Ld:Ac:ks:f:s:")) != EOF) {
4253 lp_set_cmdline("smb ports", optarg);
4256 lp_set_cmdline("workgroup", optarg);
4259 lp_set_cmdline("protocol", optarg);
4262 lp_set_cmdline("netbios name", optarg);
4265 lp_set_cmdline("debug level", optarg);
4266 setup_logging(NULL, DEBUG_STDOUT);
4269 lp_set_cmdline("socket options", optarg);
4272 srandom(atoi(optarg));
4275 nprocs = atoi(optarg);
4278 torture_numops = atoi(optarg);
4281 torture_entries = atoi(optarg);
4287 torture_showall = True;
4290 client_txt = optarg;
4294 use_kerberos = True;
4296 d_printf("No kerberos support compiled in\n");
4304 torture_failures = atoi(optarg);
4308 printf("Unknown option %c (%d)\n", (char)opt, opt);
4313 printf("host=%s share=%s user=%s myname=%s\n",
4314 host, share, lp_parm_string(-1, "torture", "username"),
4317 if (argc == optind) {
4318 printf("You must specify a test to run, or 'ALL'\n");
4320 for (i=optind;i<argc;i++) {
4321 if (!run_test(argv[i])) {