smbcquota patch from metze
[Samba/gebeck_regimport.git] / source / torture / torture.c
blob00d5b86ff88167cb3492b0387dbbebfb6d9fa893
1 /*
2 Unix SMB/CIFS implementation.
3 SMB torture tester
4 Copyright (C) Andrew Tridgell 1997-1998
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.
21 #define NO_SYSLOG
23 #include "includes.h"
25 static fstring host, workgroup, share, password, username, myname;
26 static int max_protocol = PROTOCOL_NT1;
27 static const char *sockops="TCP_NODELAY";
28 static int nprocs=1;
29 static int port_to_use=0;
30 int torture_numops=100;
31 static int procnum; /* records process count number when forking */
32 static struct cli_state *current_cli;
33 static fstring randomfname;
34 static BOOL use_oplocks;
35 static BOOL use_level_II_oplocks;
36 static const char *client_txt = "client_oplocks.txt";
37 static BOOL use_kerberos;
39 BOOL torture_showall = False;
41 static double create_procs(BOOL (*fn)(int), BOOL *result);
44 static struct timeval tp1,tp2;
46 void start_timer(void)
48 gettimeofday(&tp1,NULL);
51 double end_timer(void)
53 gettimeofday(&tp2,NULL);
54 return((tp2.tv_sec - tp1.tv_sec) +
55 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
59 /* return a pointer to a anonymous shared memory segment of size "size"
60 which will persist across fork() but will disappear when all processes
61 exit
63 The memory is not zeroed
65 This function uses system5 shared memory. It takes advantage of a property
66 that the memory is not destroyed if it is attached when the id is removed
68 void *shm_setup(int size)
70 int shmid;
71 void *ret;
73 shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
74 if (shmid == -1) {
75 printf("can't get shared memory\n");
76 exit(1);
78 ret = (void *)shmat(shmid, 0, 0);
79 if (!ret || ret == (void *)-1) {
80 printf("can't attach to shared memory\n");
81 return NULL;
83 /* the following releases the ipc, but note that this process
84 and all its children will still have access to the memory, its
85 just that the shmid is no longer valid for other shm calls. This
86 means we don't leave behind lots of shm segments after we exit
88 See Stevens "advanced programming in unix env" for details
90 shmctl(shmid, IPC_RMID, 0);
92 return ret;
96 static BOOL open_nbt_connection(struct cli_state *c)
98 struct nmb_name called, calling;
99 struct in_addr ip;
101 ZERO_STRUCTP(c);
103 make_nmb_name(&calling, myname, 0x0);
104 make_nmb_name(&called , host, 0x20);
106 zero_ip(&ip);
108 if (!cli_initialise(c)) {
109 printf("Failed initialize cli_struct to connect with %s\n", host);
110 return False;
113 c->port = port_to_use;
115 if (!cli_connect(c, host, &ip)) {
116 printf("Failed to connect with %s\n", host);
117 return False;
120 c->use_kerberos = use_kerberos;
122 c->timeout = 120000; /* set a really long timeout (2 minutes) */
123 if (use_oplocks) c->use_oplocks = True;
124 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
126 if (!cli_session_request(c, &calling, &called)) {
128 * Well, that failed, try *SMBSERVER ...
129 * However, we must reconnect as well ...
131 if (!cli_connect(c, host, &ip)) {
132 printf("Failed to connect with %s\n", host);
133 return False;
136 make_nmb_name(&called, "*SMBSERVER", 0x20);
137 if (!cli_session_request(c, &calling, &called)) {
138 printf("%s rejected the session\n",host);
139 printf("We tried with a called name of %s & %s\n",
140 host, "*SMBSERVER");
141 cli_shutdown(c);
142 return False;
146 return True;
149 BOOL torture_open_connection(struct cli_state **c)
151 BOOL retry;
152 int flags = 0;
153 NTSTATUS status;
155 if (use_kerberos)
156 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
158 status = cli_full_connection(c, myname,
159 host, NULL, port_to_use,
160 share, "?????",
161 username, workgroup,
162 password, flags, &retry);
163 if (!NT_STATUS_IS_OK(status)) {
164 return False;
167 if (use_oplocks) (*c)->use_oplocks = True;
168 if (use_level_II_oplocks) (*c)->use_level_II_oplocks = True;
169 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
171 return True;
174 BOOL torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
176 uint16 old_vuid = cli->vuid;
177 fstring old_user_name;
178 size_t passlen = strlen(password);
179 BOOL ret;
181 fstrcpy(old_user_name, cli->user_name);
182 cli->vuid = 0;
183 ret = cli_session_setup(cli, username, password, passlen, password, passlen, workgroup);
184 *new_vuid = cli->vuid;
185 cli->vuid = old_vuid;
186 fstrcpy(cli->user_name, old_user_name);
187 return ret;
191 BOOL torture_close_connection(struct cli_state *c)
193 BOOL ret = True;
194 if (!cli_tdis(c)) {
195 printf("tdis failed (%s)\n", cli_errstr(c));
196 ret = False;
199 cli_shutdown(c);
201 return ret;
205 /* check if the server produced the expected error code */
206 static BOOL check_error(int line, struct cli_state *c,
207 uint8 eclass, uint32 ecode, NTSTATUS nterr)
209 if (cli_is_dos_error(c)) {
210 uint8 class;
211 uint32 num;
213 /* Check DOS error */
215 cli_dos_error(c, &class, &num);
217 if (eclass != class || ecode != num) {
218 printf("unexpected error code class=%d code=%d\n",
219 (int)class, (int)num);
220 printf(" expected %d/%d %s (line=%d)\n",
221 (int)eclass, (int)ecode, nt_errstr(nterr), line);
222 return False;
225 } else {
226 NTSTATUS status;
228 /* Check NT error */
230 status = cli_nt_error(c);
232 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
233 printf("unexpected error code %s\n", nt_errstr(status));
234 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
235 return False;
239 return True;
243 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
245 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
246 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
248 return True;
252 static BOOL rw_torture(struct cli_state *c)
254 const char *lockfname = "\\torture.lck";
255 fstring fname;
256 int fnum;
257 int fnum2;
258 pid_t pid2, pid = getpid();
259 int i, j;
260 char buf[1024];
261 BOOL correct = True;
263 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
264 DENY_NONE);
265 if (fnum2 == -1)
266 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
267 if (fnum2 == -1) {
268 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
269 return False;
273 for (i=0;i<torture_numops;i++) {
274 unsigned n = (unsigned)sys_random()%10;
275 if (i % 10 == 0) {
276 printf("%d\r", i); fflush(stdout);
278 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
280 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
281 return False;
284 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
285 if (fnum == -1) {
286 printf("open failed (%s)\n", cli_errstr(c));
287 correct = False;
288 break;
291 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
292 printf("write failed (%s)\n", cli_errstr(c));
293 correct = False;
296 for (j=0;j<50;j++) {
297 if (cli_write(c, fnum, 0, (char *)buf,
298 sizeof(pid)+(j*sizeof(buf)),
299 sizeof(buf)) != sizeof(buf)) {
300 printf("write failed (%s)\n", cli_errstr(c));
301 correct = False;
305 pid2 = 0;
307 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
308 printf("read failed (%s)\n", cli_errstr(c));
309 correct = False;
312 if (pid2 != pid) {
313 printf("data corruption!\n");
314 correct = False;
317 if (!cli_close(c, fnum)) {
318 printf("close failed (%s)\n", cli_errstr(c));
319 correct = False;
322 if (!cli_unlink(c, fname)) {
323 printf("unlink failed (%s)\n", cli_errstr(c));
324 correct = False;
327 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
328 printf("unlock failed (%s)\n", cli_errstr(c));
329 correct = False;
333 cli_close(c, fnum2);
334 cli_unlink(c, lockfname);
336 printf("%d\n", i);
338 return correct;
341 static BOOL run_torture(int dummy)
343 struct cli_state *cli;
344 BOOL ret;
346 cli = current_cli;
348 cli_sockopt(cli, sockops);
350 ret = rw_torture(cli);
352 if (!torture_close_connection(cli)) {
353 ret = False;
356 return ret;
359 static BOOL rw_torture3(struct cli_state *c, char *lockfname)
361 int fnum = -1;
362 unsigned int i = 0;
363 char buf[131072];
364 char buf_rd[131072];
365 unsigned count;
366 unsigned countprev = 0;
367 ssize_t sent = 0;
368 BOOL correct = True;
370 srandom(1);
371 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
373 SIVAL(buf, i, sys_random());
376 if (procnum == 0)
378 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
379 DENY_NONE);
380 if (fnum == -1) {
381 printf("first open read/write of %s failed (%s)\n",
382 lockfname, cli_errstr(c));
383 return False;
386 else
388 for (i = 0; i < 500 && fnum == -1; i++)
390 fnum = cli_open(c, lockfname, O_RDONLY,
391 DENY_NONE);
392 msleep(10);
394 if (fnum == -1) {
395 printf("second open read-only of %s failed (%s)\n",
396 lockfname, cli_errstr(c));
397 return False;
401 i = 0;
402 for (count = 0; count < sizeof(buf); count += sent)
404 if (count >= countprev) {
405 printf("%d %8d\r", i, count);
406 fflush(stdout);
407 i++;
408 countprev += (sizeof(buf) / 20);
411 if (procnum == 0)
413 sent = ((unsigned)sys_random()%(20))+ 1;
414 if (sent > sizeof(buf) - count)
416 sent = sizeof(buf) - count;
419 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
420 printf("write failed (%s)\n", cli_errstr(c));
421 correct = False;
424 else
426 sent = cli_read(c, fnum, buf_rd+count, count,
427 sizeof(buf)-count);
428 if (sent < 0)
430 printf("read failed offset:%d size:%d (%s)\n",
431 count, sizeof(buf)-count,
432 cli_errstr(c));
433 correct = False;
434 sent = 0;
436 if (sent > 0)
438 if (memcmp(buf_rd+count, buf+count, sent) != 0)
440 printf("read/write compare failed\n");
441 printf("offset: %d req %d recvd %d\n",
442 count, sizeof(buf)-count, sent);
443 correct = False;
444 break;
451 if (!cli_close(c, fnum)) {
452 printf("close failed (%s)\n", cli_errstr(c));
453 correct = False;
456 return correct;
459 static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
461 const char *lockfname = "\\torture2.lck";
462 int fnum1;
463 int fnum2;
464 int i;
465 uchar buf[131072];
466 uchar buf_rd[131072];
467 BOOL correct = True;
468 ssize_t bytes_read;
470 if (!cli_unlink(c1, lockfname)) {
471 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
474 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
475 DENY_NONE);
476 if (fnum1 == -1) {
477 printf("first open read/write of %s failed (%s)\n",
478 lockfname, cli_errstr(c1));
479 return False;
481 fnum2 = cli_open(c2, lockfname, O_RDONLY,
482 DENY_NONE);
483 if (fnum2 == -1) {
484 printf("second open read-only of %s failed (%s)\n",
485 lockfname, cli_errstr(c2));
486 cli_close(c1, fnum1);
487 return False;
490 for (i=0;i<torture_numops;i++)
492 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
493 if (i % 10 == 0) {
494 printf("%d\r", i); fflush(stdout);
497 generate_random_buffer(buf, buf_size, False);
499 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
500 printf("write failed (%s)\n", cli_errstr(c1));
501 correct = False;
504 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
505 printf("read failed (%s)\n", cli_errstr(c2));
506 printf("read %d, expected %d\n", bytes_read, buf_size);
507 correct = False;
510 if (memcmp(buf_rd, buf, buf_size) != 0)
512 printf("read/write compare failed\n");
513 correct = False;
517 if (!cli_close(c2, fnum2)) {
518 printf("close failed (%s)\n", cli_errstr(c2));
519 correct = False;
521 if (!cli_close(c1, fnum1)) {
522 printf("close failed (%s)\n", cli_errstr(c1));
523 correct = False;
526 if (!cli_unlink(c1, lockfname)) {
527 printf("unlink failed (%s)\n", cli_errstr(c1));
528 correct = False;
531 return correct;
534 static BOOL run_readwritetest(int dummy)
536 static struct cli_state *cli1, *cli2;
537 BOOL test1, test2;
539 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
540 return False;
542 cli_sockopt(cli1, sockops);
543 cli_sockopt(cli2, sockops);
545 printf("starting readwritetest\n");
547 test1 = rw_torture2(cli1, cli2);
548 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
550 test2 = rw_torture2(cli1, cli1);
551 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
553 if (!torture_close_connection(cli1)) {
554 test1 = False;
557 if (!torture_close_connection(cli2)) {
558 test2 = False;
561 return (test1 && test2);
564 static BOOL run_readwritemulti(int dummy)
566 struct cli_state *cli;
567 BOOL test;
569 cli = current_cli;
571 cli_sockopt(&cli, sockops);
573 printf("run_readwritemulti: fname %s\n", randomfname);
574 test = rw_torture3(&cli, randomfname);
576 if (!torture_close_connection(&cli)) {
577 test = False;
580 return test;
583 static BOOL run_readwritelarge(int dummy)
585 static struct cli_state *cli1;
586 int fnum1;
587 const char *lockfname = "\\large.dat";
588 size_t fsize;
589 char buf[126*1024];
590 BOOL correct = True;
592 if (!torture_open_connection(&cli1)) {
593 return False;
595 cli_sockopt(cli1, sockops);
596 memset(buf,'\0',sizeof(buf));
598 cli1->max_xmit = 128*1024;
600 printf("starting readwritelarge\n");
602 cli_unlink(cli1, lockfname);
604 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
605 if (fnum1 == -1) {
606 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
607 return False;
610 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
612 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
613 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
614 correct = False;
617 if (fsize == sizeof(buf))
618 printf("readwritelarge test 1 succeeded (size = %x)\n", fsize);
619 else {
620 printf("readwritelarge test 1 failed (size = %x)\n", fsize);
621 correct = False;
624 if (!cli_close(cli1, fnum1)) {
625 printf("close failed (%s)\n", cli_errstr(cli1));
626 correct = False;
629 if (!cli_unlink(cli1, lockfname)) {
630 printf("unlink failed (%s)\n", cli_errstr(cli1));
631 correct = False;
634 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
635 if (fnum1 == -1) {
636 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
637 return False;
640 cli1->max_xmit = 4*1024;
642 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
644 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
645 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
646 correct = False;
649 if (fsize == sizeof(buf))
650 printf("readwritelarge test 2 succeeded (size = %x)\n", fsize);
651 else {
652 printf("readwritelarge test 2 failed (size = %x)\n", fsize);
653 correct = False;
656 #if 0
657 /* ToDo - set allocation. JRA */
658 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
659 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
660 return False;
662 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
663 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
664 correct = False;
666 if (fsize != 0)
667 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
668 #endif
670 if (!cli_close(cli1, fnum1)) {
671 printf("close failed (%s)\n", cli_errstr(cli1));
672 correct = False;
675 if (!torture_close_connection(cli1)) {
676 correct = False;
678 return correct;
681 int line_count = 0;
682 int nbio_id;
684 #define ival(s) strtol(s, NULL, 0)
686 /* run a test that simulates an approximate netbench client load */
687 static BOOL run_netbench(int client)
689 struct cli_state *cli;
690 int i;
691 fstring fname;
692 pstring line;
693 char cname[20];
694 FILE *f;
695 char *params[20];
696 BOOL correct = True;
698 cli = current_cli;
700 nbio_id = client;
702 cli_sockopt(cli, sockops);
704 nb_setup(cli);
706 slprintf(cname,sizeof(fname), "client%d", client);
708 f = fopen(client_txt, "r");
710 if (!f) {
711 perror(client_txt);
712 return False;
715 while (fgets(line, sizeof(line)-1, f)) {
716 line_count++;
718 line[strlen(line)-1] = 0;
720 /* printf("[%d] %s\n", line_count, line); */
722 all_string_sub(line,"client1", cname, sizeof(line));
724 /* parse the command parameters */
725 params[0] = strtok(line," ");
726 i = 0;
727 while (params[i]) params[++i] = strtok(NULL," ");
729 params[i] = "";
731 if (i < 2) continue;
733 if (!strncmp(params[0],"SMB", 3)) {
734 printf("ERROR: You are using a dbench 1 load file\n");
735 exit(1);
738 if (!strcmp(params[0],"NTCreateX")) {
739 nb_createx(params[1], ival(params[2]), ival(params[3]),
740 ival(params[4]));
741 } else if (!strcmp(params[0],"Close")) {
742 nb_close(ival(params[1]));
743 } else if (!strcmp(params[0],"Rename")) {
744 nb_rename(params[1], params[2]);
745 } else if (!strcmp(params[0],"Unlink")) {
746 nb_unlink(params[1]);
747 } else if (!strcmp(params[0],"Deltree")) {
748 nb_deltree(params[1]);
749 } else if (!strcmp(params[0],"Rmdir")) {
750 nb_rmdir(params[1]);
751 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
752 nb_qpathinfo(params[1]);
753 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
754 nb_qfileinfo(ival(params[1]));
755 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
756 nb_qfsinfo(ival(params[1]));
757 } else if (!strcmp(params[0],"FIND_FIRST")) {
758 nb_findfirst(params[1]);
759 } else if (!strcmp(params[0],"WriteX")) {
760 nb_writex(ival(params[1]),
761 ival(params[2]), ival(params[3]), ival(params[4]));
762 } else if (!strcmp(params[0],"ReadX")) {
763 nb_readx(ival(params[1]),
764 ival(params[2]), ival(params[3]), ival(params[4]));
765 } else if (!strcmp(params[0],"Flush")) {
766 nb_flush(ival(params[1]));
767 } else {
768 printf("Unknown operation %s\n", params[0]);
769 exit(1);
772 fclose(f);
774 nb_cleanup();
776 if (!torture_close_connection(cli)) {
777 correct = False;
780 return correct;
784 /* run a test that simulates an approximate netbench client load */
785 static BOOL run_nbench(int dummy)
787 double t;
788 BOOL correct = True;
790 nbio_shmem(nprocs);
792 nbio_id = -1;
794 signal(SIGALRM, nb_alarm);
795 alarm(1);
796 t = create_procs(run_netbench, &correct);
797 alarm(0);
799 printf("\nThroughput %g MB/sec\n",
800 1.0e-6 * nbio_total() / t);
801 return correct;
806 This test checks for two things:
808 1) correct support for retaining locks over a close (ie. the server
809 must not use posix semantics)
810 2) support for lock timeouts
812 static BOOL run_locktest1(int dummy)
814 struct cli_state *cli1, *cli2;
815 const char *fname = "\\lockt1.lck";
816 int fnum1, fnum2, fnum3;
817 time_t t1, t2;
818 unsigned lock_timeout;
820 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
821 return False;
823 cli_sockopt(cli1, sockops);
824 cli_sockopt(cli2, sockops);
826 printf("starting locktest1\n");
828 cli_unlink(cli1, fname);
830 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
831 if (fnum1 == -1) {
832 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
833 return False;
835 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
836 if (fnum2 == -1) {
837 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
838 return False;
840 fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
841 if (fnum3 == -1) {
842 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
843 return False;
846 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
847 printf("lock1 failed (%s)\n", cli_errstr(cli1));
848 return False;
852 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
853 printf("lock2 succeeded! This is a locking bug\n");
854 return False;
855 } else {
856 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
857 NT_STATUS_LOCK_NOT_GRANTED)) return False;
861 lock_timeout = (1 + (random() % 20));
862 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
863 t1 = time(NULL);
864 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
865 printf("lock3 succeeded! This is a locking bug\n");
866 return False;
867 } else {
868 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
869 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
871 t2 = time(NULL);
873 if (t2 - t1 < 5) {
874 printf("error: This server appears not to support timed lock requests\n");
876 printf("server slept for %u seconds for a %u second timeout\n",
877 (unsigned int)(t2-t1), lock_timeout);
879 if (!cli_close(cli1, fnum2)) {
880 printf("close1 failed (%s)\n", cli_errstr(cli1));
881 return False;
884 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
885 printf("lock4 succeeded! This is a locking bug\n");
886 return False;
887 } else {
888 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
889 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
892 if (!cli_close(cli1, fnum1)) {
893 printf("close2 failed (%s)\n", cli_errstr(cli1));
894 return False;
897 if (!cli_close(cli2, fnum3)) {
898 printf("close3 failed (%s)\n", cli_errstr(cli2));
899 return False;
902 if (!cli_unlink(cli1, fname)) {
903 printf("unlink failed (%s)\n", cli_errstr(cli1));
904 return False;
908 if (!torture_close_connection(cli1)) {
909 return False;
912 if (!torture_close_connection(cli2)) {
913 return False;
916 printf("Passed locktest1\n");
917 return True;
921 this checks to see if a secondary tconx can use open files from an
922 earlier tconx
924 static BOOL run_tcon_test(int dummy)
926 static struct cli_state *cli;
927 const char *fname = "\\tcontest.tmp";
928 int fnum1;
929 uint16 cnum1, cnum2, cnum3;
930 uint16 vuid1, vuid2;
931 char buf[4];
932 BOOL ret = True;
934 if (!torture_open_connection(&cli)) {
935 return False;
937 cli_sockopt(cli, sockops);
939 printf("starting tcontest\n");
941 cli_unlink(cli, fname);
943 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
944 if (fnum1 == -1) {
945 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
946 return False;
949 cnum1 = cli->cnum;
950 vuid1 = cli->vuid;
952 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
953 printf("initial write failed (%s)", cli_errstr(cli));
954 return False;
957 if (!cli_send_tconX(cli, share, "?????",
958 password, strlen(password)+1)) {
959 printf("%s refused 2nd tree connect (%s)\n", host,
960 cli_errstr(cli));
961 cli_shutdown(cli);
962 return False;
965 cnum2 = cli->cnum;
966 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
967 vuid2 = cli->vuid + 1;
969 /* try a write with the wrong tid */
970 cli->cnum = cnum2;
972 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
973 printf("* server allows write with wrong TID\n");
974 ret = False;
975 } else {
976 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
980 /* try a write with an invalid tid */
981 cli->cnum = cnum3;
983 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
984 printf("* server allows write with invalid TID\n");
985 ret = False;
986 } else {
987 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
990 /* try a write with an invalid vuid */
991 cli->vuid = vuid2;
992 cli->cnum = cnum1;
994 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
995 printf("* server allows write with invalid VUID\n");
996 ret = False;
997 } else {
998 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1001 cli->cnum = cnum1;
1002 cli->vuid = vuid1;
1004 if (!cli_close(cli, fnum1)) {
1005 printf("close failed (%s)\n", cli_errstr(cli));
1006 return False;
1009 cli->cnum = cnum2;
1011 if (!cli_tdis(cli)) {
1012 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
1013 return False;
1016 cli->cnum = cnum1;
1018 if (!torture_close_connection(cli)) {
1019 return False;
1022 return ret;
1027 checks for old style tcon support
1029 static BOOL run_tcon2_test(int dummy)
1031 static struct cli_state *cli;
1032 uint16 cnum, max_xmit;
1033 char *service;
1034 NTSTATUS status;
1036 if (!torture_open_connection(&cli)) {
1037 return False;
1039 cli_sockopt(cli, sockops);
1041 printf("starting tcon2 test\n");
1043 asprintf(&service, "\\\\%s\\%s", host, share);
1045 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1047 if (!NT_STATUS_IS_OK(status)) {
1048 printf("tcon2 failed : %s\n", cli_errstr(cli));
1049 } else {
1050 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1051 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1054 if (!torture_close_connection(cli)) {
1055 return False;
1058 printf("Passed tcon2 test\n");
1059 return True;
1062 static BOOL tcon_devtest(struct cli_state *cli,
1063 const char *myshare, const char *devtype,
1064 NTSTATUS expected_error)
1066 BOOL status;
1067 BOOL ret;
1069 status = cli_send_tconX(cli, myshare, devtype,
1070 password, strlen(password)+1);
1072 if (NT_STATUS_IS_OK(expected_error)) {
1073 if (status) {
1074 ret = True;
1075 } else {
1076 printf("tconX to share %s with type %s "
1077 "should have succeeded but failed\n",
1078 myshare, devtype);
1079 ret = False;
1081 cli_tdis(cli);
1082 } else {
1083 if (status) {
1084 printf("tconx to share %s with type %s "
1085 "should have failed but succeeded\n",
1086 myshare, devtype);
1087 ret = False;
1088 } else {
1089 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1090 expected_error)) {
1091 ret = True;
1092 } else {
1093 printf("Returned unexpected error\n");
1094 ret = False;
1098 return ret;
1102 checks for correct tconX support
1104 static BOOL run_tcon_devtype_test(int dummy)
1106 static struct cli_state *cli1 = NULL;
1107 BOOL retry;
1108 int flags = 0;
1109 NTSTATUS status;
1110 BOOL ret;
1112 status = cli_full_connection(&cli1, myname,
1113 host, NULL, port_to_use,
1114 NULL, NULL,
1115 username, workgroup,
1116 password, flags, &retry);
1118 if (!NT_STATUS_IS_OK(status)) {
1119 printf("could not open connection\n");
1120 return False;
1123 if (!tcon_devtest(cli1, "IPC$", "A:", NT_STATUS_BAD_DEVICE_TYPE))
1124 ret = False;
1126 if (!tcon_devtest(cli1, "IPC$", "?????", NT_STATUS_OK))
1127 ret = False;
1129 if (!tcon_devtest(cli1, "IPC$", "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
1130 ret = False;
1132 if (!tcon_devtest(cli1, "IPC$", "IPC", NT_STATUS_OK))
1133 ret = False;
1135 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
1136 ret = False;
1138 if (!tcon_devtest(cli1, share, "A:", NT_STATUS_OK))
1139 ret = False;
1141 if (!tcon_devtest(cli1, share, "?????", NT_STATUS_OK))
1142 ret = False;
1144 if (!tcon_devtest(cli1, share, "LPT:", NT_STATUS_BAD_DEVICE_TYPE))
1145 ret = False;
1147 if (!tcon_devtest(cli1, share, "IPC", NT_STATUS_BAD_DEVICE_TYPE))
1148 ret = False;
1150 if (!tcon_devtest(cli1, share, "FOOBA", NT_STATUS_BAD_DEVICE_TYPE))
1151 ret = False;
1153 cli_shutdown(cli1);
1155 if (ret)
1156 printf("Passed tcondevtest\n");
1158 return ret;
1163 This test checks that
1165 1) the server supports multiple locking contexts on the one SMB
1166 connection, distinguished by PID.
1168 2) the server correctly fails overlapping locks made by the same PID (this
1169 goes against POSIX behaviour, which is why it is tricky to implement)
1171 3) the server denies unlock requests by an incorrect client PID
1173 static BOOL run_locktest2(int dummy)
1175 static struct cli_state *cli;
1176 const char *fname = "\\lockt2.lck";
1177 int fnum1, fnum2, fnum3;
1178 BOOL correct = True;
1180 if (!torture_open_connection(&cli)) {
1181 return False;
1184 cli_sockopt(cli, sockops);
1186 printf("starting locktest2\n");
1188 cli_unlink(cli, fname);
1190 cli_setpid(cli, 1);
1192 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1193 if (fnum1 == -1) {
1194 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1195 return False;
1198 fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1199 if (fnum2 == -1) {
1200 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1201 return False;
1204 cli_setpid(cli, 2);
1206 fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1207 if (fnum3 == -1) {
1208 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1209 return False;
1212 cli_setpid(cli, 1);
1214 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1215 printf("lock1 failed (%s)\n", cli_errstr(cli));
1216 return False;
1219 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1220 printf("WRITE lock1 succeeded! This is a locking bug\n");
1221 correct = False;
1222 } else {
1223 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1224 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1227 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1228 printf("WRITE lock2 succeeded! This is a locking bug\n");
1229 correct = False;
1230 } else {
1231 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1232 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1235 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1236 printf("READ lock2 succeeded! This is a locking bug\n");
1237 correct = False;
1238 } else {
1239 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1240 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1243 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1244 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1246 cli_setpid(cli, 2);
1247 if (cli_unlock(cli, fnum1, 100, 4)) {
1248 printf("unlock at 100 succeeded! This is a locking bug\n");
1249 correct = False;
1252 if (cli_unlock(cli, fnum1, 0, 4)) {
1253 printf("unlock1 succeeded! This is a locking bug\n");
1254 correct = False;
1255 } else {
1256 if (!check_error(__LINE__, cli,
1257 ERRDOS, ERRlock,
1258 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1261 if (cli_unlock(cli, fnum1, 0, 8)) {
1262 printf("unlock2 succeeded! This is a locking bug\n");
1263 correct = False;
1264 } else {
1265 if (!check_error(__LINE__, cli,
1266 ERRDOS, ERRlock,
1267 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1270 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1271 printf("lock3 succeeded! This is a locking bug\n");
1272 correct = False;
1273 } else {
1274 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1277 cli_setpid(cli, 1);
1279 if (!cli_close(cli, fnum1)) {
1280 printf("close1 failed (%s)\n", cli_errstr(cli));
1281 return False;
1284 if (!cli_close(cli, fnum2)) {
1285 printf("close2 failed (%s)\n", cli_errstr(cli));
1286 return False;
1289 if (!cli_close(cli, fnum3)) {
1290 printf("close3 failed (%s)\n", cli_errstr(cli));
1291 return False;
1294 if (!torture_close_connection(cli)) {
1295 correct = False;
1298 printf("locktest2 finished\n");
1300 return correct;
1305 This test checks that
1307 1) the server supports the full offset range in lock requests
1309 static BOOL run_locktest3(int dummy)
1311 static struct cli_state *cli1, *cli2;
1312 const char *fname = "\\lockt3.lck";
1313 int fnum1, fnum2, i;
1314 uint32 offset;
1315 BOOL correct = True;
1317 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1319 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1320 return False;
1322 cli_sockopt(cli1, sockops);
1323 cli_sockopt(cli2, sockops);
1325 printf("starting locktest3\n");
1327 cli_unlink(cli1, fname);
1329 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1330 if (fnum1 == -1) {
1331 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1332 return False;
1334 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1335 if (fnum2 == -1) {
1336 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1337 return False;
1340 for (offset=i=0;i<torture_numops;i++) {
1341 NEXT_OFFSET;
1342 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1343 printf("lock1 %d failed (%s)\n",
1345 cli_errstr(cli1));
1346 return False;
1349 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1350 printf("lock2 %d failed (%s)\n",
1352 cli_errstr(cli1));
1353 return False;
1357 for (offset=i=0;i<torture_numops;i++) {
1358 NEXT_OFFSET;
1360 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1361 printf("error: lock1 %d succeeded!\n", i);
1362 return False;
1365 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1366 printf("error: lock2 %d succeeded!\n", i);
1367 return False;
1370 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1371 printf("error: lock3 %d succeeded!\n", i);
1372 return False;
1375 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1376 printf("error: lock4 %d succeeded!\n", i);
1377 return False;
1381 for (offset=i=0;i<torture_numops;i++) {
1382 NEXT_OFFSET;
1384 if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
1385 printf("unlock1 %d failed (%s)\n",
1387 cli_errstr(cli1));
1388 return False;
1391 if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
1392 printf("unlock2 %d failed (%s)\n",
1394 cli_errstr(cli1));
1395 return False;
1399 if (!cli_close(cli1, fnum1)) {
1400 printf("close1 failed (%s)\n", cli_errstr(cli1));
1401 return False;
1404 if (!cli_close(cli2, fnum2)) {
1405 printf("close2 failed (%s)\n", cli_errstr(cli2));
1406 return False;
1409 if (!cli_unlink(cli1, fname)) {
1410 printf("unlink failed (%s)\n", cli_errstr(cli1));
1411 return False;
1414 if (!torture_close_connection(cli1)) {
1415 correct = False;
1418 if (!torture_close_connection(cli2)) {
1419 correct = False;
1422 printf("finished locktest3\n");
1424 return correct;
1427 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1428 printf("** "); correct = False; \
1432 looks at overlapping locks
1434 static BOOL run_locktest4(int dummy)
1436 static struct cli_state *cli1, *cli2;
1437 const char *fname = "\\lockt4.lck";
1438 int fnum1, fnum2, f;
1439 BOOL ret;
1440 char buf[1000];
1441 BOOL correct = True;
1443 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1444 return False;
1447 cli_sockopt(cli1, sockops);
1448 cli_sockopt(cli2, sockops);
1450 printf("starting locktest4\n");
1452 cli_unlink(cli1, fname);
1454 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1455 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1457 memset(buf, 0, sizeof(buf));
1459 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1460 printf("Failed to create file\n");
1461 correct = False;
1462 goto fail;
1465 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1466 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1467 EXPECTED(ret, False);
1468 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1470 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1471 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1472 EXPECTED(ret, True);
1473 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1475 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1476 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1477 EXPECTED(ret, False);
1478 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1480 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1481 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1482 EXPECTED(ret, True);
1483 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1485 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1486 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1487 EXPECTED(ret, False);
1488 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1490 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1491 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1492 EXPECTED(ret, True);
1493 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1495 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1496 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1497 EXPECTED(ret, True);
1498 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1500 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1501 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1502 EXPECTED(ret, False);
1503 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1505 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1506 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1507 EXPECTED(ret, False);
1508 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1510 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1511 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1512 EXPECTED(ret, True);
1513 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1515 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1516 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1517 EXPECTED(ret, False);
1518 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1520 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1521 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1522 cli_unlock(cli1, fnum1, 110, 6);
1523 EXPECTED(ret, False);
1524 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1527 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1528 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1529 EXPECTED(ret, False);
1530 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1532 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1533 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1534 EXPECTED(ret, False);
1535 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1538 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1539 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1540 cli_unlock(cli1, fnum1, 140, 4) &&
1541 cli_unlock(cli1, fnum1, 140, 4);
1542 EXPECTED(ret, True);
1543 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1546 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1547 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1548 cli_unlock(cli1, fnum1, 150, 4) &&
1549 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1550 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1551 cli_unlock(cli1, fnum1, 150, 4);
1552 EXPECTED(ret, True);
1553 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1555 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1556 cli_unlock(cli1, fnum1, 160, 4) &&
1557 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1558 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1559 EXPECTED(ret, True);
1560 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1562 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1563 cli_unlock(cli1, fnum1, 170, 4) &&
1564 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1565 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1566 EXPECTED(ret, True);
1567 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1569 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1570 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1571 cli_unlock(cli1, fnum1, 190, 4) &&
1572 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1573 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1574 EXPECTED(ret, True);
1575 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1577 cli_close(cli1, fnum1);
1578 cli_close(cli2, fnum2);
1579 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1580 f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1581 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1582 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1583 cli_close(cli1, fnum1) &&
1584 ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1585 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1586 cli_close(cli1, f);
1587 cli_close(cli1, fnum1);
1588 EXPECTED(ret, True);
1589 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1591 fail:
1592 cli_close(cli1, fnum1);
1593 cli_close(cli2, fnum2);
1594 cli_unlink(cli1, fname);
1595 torture_close_connection(cli1);
1596 torture_close_connection(cli2);
1598 printf("finished locktest4\n");
1599 return correct;
1603 looks at lock upgrade/downgrade.
1605 static BOOL run_locktest5(int dummy)
1607 static struct cli_state *cli1, *cli2;
1608 const char *fname = "\\lockt5.lck";
1609 int fnum1, fnum2, fnum3;
1610 BOOL ret;
1611 char buf[1000];
1612 BOOL correct = True;
1614 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1615 return False;
1618 cli_sockopt(cli1, sockops);
1619 cli_sockopt(cli2, sockops);
1621 printf("starting locktest5\n");
1623 cli_unlink(cli1, fname);
1625 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1626 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1627 fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1629 memset(buf, 0, sizeof(buf));
1631 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1632 printf("Failed to create file\n");
1633 correct = False;
1634 goto fail;
1637 /* Check for NT bug... */
1638 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1639 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1640 cli_close(cli1, fnum1);
1641 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1642 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1643 EXPECTED(ret, True);
1644 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1645 cli_close(cli1, fnum1);
1646 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1647 cli_unlock(cli1, fnum3, 0, 1);
1649 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1650 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1651 EXPECTED(ret, True);
1652 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1654 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1655 EXPECTED(ret, False);
1657 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1659 /* Unlock the process 2 lock. */
1660 cli_unlock(cli2, fnum2, 0, 4);
1662 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1663 EXPECTED(ret, False);
1665 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1667 /* Unlock the process 1 fnum3 lock. */
1668 cli_unlock(cli1, fnum3, 0, 4);
1670 /* Stack 2 more locks here. */
1671 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1672 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1674 EXPECTED(ret, True);
1675 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1677 /* Unlock the first process lock, then check this was the WRITE lock that was
1678 removed. */
1680 ret = cli_unlock(cli1, fnum1, 0, 4) &&
1681 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1683 EXPECTED(ret, True);
1684 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1686 /* Unlock the process 2 lock. */
1687 cli_unlock(cli2, fnum2, 0, 4);
1689 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1691 ret = cli_unlock(cli1, fnum1, 1, 1) &&
1692 cli_unlock(cli1, fnum1, 0, 4) &&
1693 cli_unlock(cli1, fnum1, 0, 4);
1695 EXPECTED(ret, True);
1696 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1698 /* Ensure the next unlock fails. */
1699 ret = cli_unlock(cli1, fnum1, 0, 4);
1700 EXPECTED(ret, False);
1701 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1703 /* Ensure connection 2 can get a write lock. */
1704 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1705 EXPECTED(ret, True);
1707 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1710 fail:
1711 cli_close(cli1, fnum1);
1712 cli_close(cli2, fnum2);
1713 cli_unlink(cli1, fname);
1714 if (!torture_close_connection(cli1)) {
1715 correct = False;
1717 if (!torture_close_connection(cli2)) {
1718 correct = False;
1721 printf("finished locktest5\n");
1723 return correct;
1727 tries the unusual lockingX locktype bits
1729 static BOOL run_locktest6(int dummy)
1731 static struct cli_state *cli;
1732 const char *fname[1] = { "\\lock6.txt" };
1733 int i;
1734 int fnum;
1735 NTSTATUS status;
1737 if (!torture_open_connection(&cli)) {
1738 return False;
1741 cli_sockopt(cli, sockops);
1743 printf("starting locktest6\n");
1745 for (i=0;i<1;i++) {
1746 printf("Testing %s\n", fname[i]);
1748 cli_unlink(cli, fname[i]);
1750 fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1751 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1752 cli_close(cli, fnum);
1753 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1755 fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
1756 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1757 cli_close(cli, fnum);
1758 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1760 cli_unlink(cli, fname[i]);
1763 torture_close_connection(cli);
1765 printf("finished locktest6\n");
1766 return True;
1769 static BOOL run_locktest7(int dummy)
1771 struct cli_state *cli1;
1772 const char *fname = "\\lockt7.lck";
1773 int fnum1;
1774 char buf[200];
1775 BOOL correct = False;
1777 if (!torture_open_connection(&cli1)) {
1778 return False;
1781 cli_sockopt(cli1, sockops);
1783 printf("starting locktest7\n");
1785 cli_unlink(cli1, fname);
1787 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1789 memset(buf, 0, sizeof(buf));
1791 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1792 printf("Failed to create file\n");
1793 goto fail;
1796 cli_setpid(cli1, 1);
1798 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1799 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1800 goto fail;
1801 } else {
1802 printf("pid1 successfully locked range 130:4 for READ\n");
1805 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1806 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1807 goto fail;
1808 } else {
1809 printf("pid1 successfully read the range 130:4\n");
1812 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1813 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1814 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1815 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1816 goto fail;
1818 } else {
1819 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1820 goto fail;
1823 cli_setpid(cli1, 2);
1825 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1826 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1827 } else {
1828 printf("pid2 successfully read the range 130:4\n");
1831 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1832 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1833 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1834 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1835 goto fail;
1837 } else {
1838 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1839 goto fail;
1842 cli_setpid(cli1, 1);
1843 cli_unlock(cli1, fnum1, 130, 4);
1845 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
1846 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
1847 goto fail;
1848 } else {
1849 printf("pid1 successfully locked range 130:4 for WRITE\n");
1852 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1853 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1854 goto fail;
1855 } else {
1856 printf("pid1 successfully read the range 130:4\n");
1859 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1860 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1861 goto fail;
1862 } else {
1863 printf("pid1 successfully wrote to the range 130:4\n");
1866 cli_setpid(cli1, 2);
1868 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1869 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1870 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1871 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1872 goto fail;
1874 } else {
1875 printf("pid2 successfully read the range 130:4 (should be denied)\n");
1876 goto fail;
1879 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1880 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1881 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1882 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1883 goto fail;
1885 } else {
1886 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1887 goto fail;
1890 cli_unlock(cli1, fnum1, 130, 0);
1891 correct = True;
1893 fail:
1894 cli_close(cli1, fnum1);
1895 cli_unlink(cli1, fname);
1896 torture_close_connection(cli1);
1898 printf("finished locktest7\n");
1899 return correct;
1903 test whether fnums and tids open on one VC are available on another (a major
1904 security hole)
1906 static BOOL run_fdpasstest(int dummy)
1908 struct cli_state *cli1, *cli2;
1909 const char *fname = "\\fdpass.tst";
1910 int fnum1;
1911 pstring buf;
1913 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1914 return False;
1916 cli_sockopt(cli1, sockops);
1917 cli_sockopt(cli2, sockops);
1919 printf("starting fdpasstest\n");
1921 cli_unlink(cli1, fname);
1923 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1924 if (fnum1 == -1) {
1925 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1926 return False;
1929 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
1930 printf("write failed (%s)\n", cli_errstr(cli1));
1931 return False;
1934 cli2->vuid = cli1->vuid;
1935 cli2->cnum = cli1->cnum;
1936 cli2->pid = cli1->pid;
1938 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
1939 printf("read succeeded! nasty security hole [%s]\n",
1940 buf);
1941 return False;
1944 cli_close(cli1, fnum1);
1945 cli_unlink(cli1, fname);
1947 torture_close_connection(cli1);
1948 torture_close_connection(cli2);
1950 printf("finished fdpasstest\n");
1951 return True;
1954 static BOOL run_fdsesstest(int dummy)
1956 struct cli_state *cli;
1957 uint16 new_vuid;
1958 uint16 saved_vuid;
1959 uint16 new_cnum;
1960 uint16 saved_cnum;
1961 const char *fname = "\\fdsess.tst";
1962 int fnum1;
1963 pstring buf;
1964 BOOL ret = True;
1966 if (!torture_open_connection(&cli))
1967 return False;
1968 cli_sockopt(cli, sockops);
1970 if (!torture_cli_session_setup2(cli, &new_vuid))
1971 return False;
1973 saved_cnum = cli->cnum;
1974 if (!cli_send_tconX(cli, share, "?????", "", 1))
1975 return False;
1976 new_cnum = cli->cnum;
1977 cli->cnum = saved_cnum;
1979 printf("starting fdsesstest\n");
1981 cli_unlink(cli, fname);
1983 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1984 if (fnum1 == -1) {
1985 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1986 return False;
1989 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
1990 printf("write failed (%s)\n", cli_errstr(cli));
1991 return False;
1994 saved_vuid = cli->vuid;
1995 cli->vuid = new_vuid;
1997 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
1998 printf("read succeeded with different vuid! nasty security hole [%s]\n",
1999 buf);
2000 ret = False;
2002 cli->vuid = saved_vuid;
2004 /* Try with same vuid, different cnum. */
2005 cli->cnum = new_cnum;
2007 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2008 printf("read succeeded with different cnum![%s]\n",
2009 buf);
2010 ret = False;
2013 cli->cnum = saved_cnum;
2014 cli_close(cli, fnum1);
2015 cli_unlink(cli, fname);
2017 torture_close_connection(cli);
2019 printf("finished fdsesstest\n");
2020 return ret;
2024 This test checks that
2026 1) the server does not allow an unlink on a file that is open
2028 static BOOL run_unlinktest(int dummy)
2030 struct cli_state *cli;
2031 const char *fname = "\\unlink.tst";
2032 int fnum;
2033 BOOL correct = True;
2035 if (!torture_open_connection(&cli)) {
2036 return False;
2039 cli_sockopt(cli, sockops);
2041 printf("starting unlink test\n");
2043 cli_unlink(cli, fname);
2045 cli_setpid(cli, 1);
2047 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2048 if (fnum == -1) {
2049 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2050 return False;
2053 if (cli_unlink(cli, fname)) {
2054 printf("error: server allowed unlink on an open file\n");
2055 correct = False;
2056 } else {
2057 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2058 NT_STATUS_SHARING_VIOLATION);
2061 cli_close(cli, fnum);
2062 cli_unlink(cli, fname);
2064 if (!torture_close_connection(cli)) {
2065 correct = False;
2068 printf("unlink test finished\n");
2070 return correct;
2075 test how many open files this server supports on the one socket
2077 static BOOL run_maxfidtest(int dummy)
2079 struct cli_state *cli;
2080 const char *template = "\\maxfid.%d.%d";
2081 fstring fname;
2082 int fnums[0x11000], i;
2083 int retries=4;
2084 BOOL correct = True;
2086 cli = current_cli;
2088 if (retries <= 0) {
2089 printf("failed to connect\n");
2090 return False;
2093 cli_sockopt(cli, sockops);
2095 for (i=0; i<0x11000; i++) {
2096 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
2097 if ((fnums[i] = cli_open(cli, fname,
2098 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
2099 -1) {
2100 printf("open of %s failed (%s)\n",
2101 fname, cli_errstr(cli));
2102 printf("maximum fnum is %d\n", i);
2103 break;
2105 printf("%6d\r", i);
2107 printf("%6d\n", i);
2108 i--;
2110 printf("cleaning up\n");
2111 for (;i>=0;i--) {
2112 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
2113 cli_close(cli, fnums[i]);
2114 if (!cli_unlink(cli, fname)) {
2115 printf("unlink of %s failed (%s)\n",
2116 fname, cli_errstr(cli));
2117 correct = False;
2119 printf("%6d\r", i);
2121 printf("%6d\n", 0);
2123 printf("maxfid test finished\n");
2124 if (!torture_close_connection(cli)) {
2125 correct = False;
2127 return correct;
2130 /* generate a random buffer */
2131 static void rand_buf(char *buf, int len)
2133 while (len--) {
2134 *buf = (char)sys_random();
2135 buf++;
2139 /* send smb negprot commands, not reading the response */
2140 static BOOL run_negprot_nowait(int dummy)
2142 int i;
2143 static struct cli_state cli;
2144 BOOL correct = True;
2146 printf("starting negprot nowait test\n");
2148 if (!open_nbt_connection(&cli)) {
2149 return False;
2152 for (i=0;i<50000;i++) {
2153 cli_negprot_send(&cli);
2156 if (!torture_close_connection(&cli)) {
2157 correct = False;
2160 printf("finished negprot nowait test\n");
2162 return correct;
2166 /* send random IPC commands */
2167 static BOOL run_randomipc(int dummy)
2169 char *rparam = NULL;
2170 char *rdata = NULL;
2171 int rdrcnt,rprcnt;
2172 pstring param;
2173 int api, param_len, i;
2174 struct cli_state *cli;
2175 BOOL correct = True;
2176 int count = 50000;
2178 printf("starting random ipc test\n");
2180 if (!torture_open_connection(&cli)) {
2181 return False;
2184 for (i=0;i<count;i++) {
2185 api = sys_random() % 500;
2186 param_len = (sys_random() % 64);
2188 rand_buf(param, param_len);
2190 SSVAL(param,0,api);
2192 cli_api(cli,
2193 param, param_len, 8,
2194 NULL, 0, BUFFER_SIZE,
2195 &rparam, &rprcnt,
2196 &rdata, &rdrcnt);
2197 if (i % 100 == 0) {
2198 printf("%d/%d\r", i,count);
2201 printf("%d/%d\n", i, count);
2203 if (!torture_close_connection(cli)) {
2204 correct = False;
2207 printf("finished random ipc test\n");
2209 return correct;
2214 static void browse_callback(const char *sname, uint32 stype,
2215 const char *comment, void *state)
2217 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2223 This test checks the browse list code
2226 static BOOL run_browsetest(int dummy)
2228 static struct cli_state *cli;
2229 BOOL correct = True;
2231 printf("starting browse test\n");
2233 if (!torture_open_connection(&cli)) {
2234 return False;
2237 printf("domain list:\n");
2238 cli_NetServerEnum(cli, cli->server_domain,
2239 SV_TYPE_DOMAIN_ENUM,
2240 browse_callback, NULL);
2242 printf("machine list:\n");
2243 cli_NetServerEnum(cli, cli->server_domain,
2244 SV_TYPE_ALL,
2245 browse_callback, NULL);
2247 if (!torture_close_connection(cli)) {
2248 correct = False;
2251 printf("browse test finished\n");
2253 return correct;
2259 This checks how the getatr calls works
2261 static BOOL run_attrtest(int dummy)
2263 struct cli_state *cli;
2264 int fnum;
2265 time_t t, t2;
2266 const char *fname = "\\attrib123456789.tst";
2267 BOOL correct = True;
2269 printf("starting attrib test\n");
2271 if (!torture_open_connection(&cli)) {
2272 return False;
2275 cli_unlink(cli, fname);
2276 fnum = cli_open(cli, fname,
2277 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2278 cli_close(cli, fnum);
2279 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2280 printf("getatr failed (%s)\n", cli_errstr(cli));
2281 correct = False;
2284 if (abs(t - time(NULL)) > 60*60*24*10) {
2285 printf("ERROR: SMBgetatr bug. time is %s",
2286 ctime(&t));
2287 t = time(NULL);
2288 correct = True;
2291 t2 = t-60*60*24; /* 1 day ago */
2293 if (!cli_setatr(cli, fname, 0, t2)) {
2294 printf("setatr failed (%s)\n", cli_errstr(cli));
2295 correct = True;
2298 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2299 printf("getatr failed (%s)\n", cli_errstr(cli));
2300 correct = True;
2303 if (t != t2) {
2304 printf("ERROR: getatr/setatr bug. times are\n%s",
2305 ctime(&t));
2306 printf("%s", ctime(&t2));
2307 correct = True;
2310 cli_unlink(cli, fname);
2312 if (!torture_close_connection(cli)) {
2313 correct = False;
2316 printf("attrib test finished\n");
2318 return correct;
2323 This checks a couple of trans2 calls
2325 static BOOL run_trans2test(int dummy)
2327 struct cli_state *cli;
2328 int fnum;
2329 size_t size;
2330 time_t c_time, a_time, m_time, w_time, m_time2;
2331 const char *fname = "\\trans2.tst";
2332 const char *dname = "\\trans2";
2333 const char *fname2 = "\\trans2\\trans2.tst";
2334 pstring pname;
2335 BOOL correct = True;
2337 printf("starting trans2 test\n");
2339 if (!torture_open_connection(&cli)) {
2340 return False;
2343 cli_unlink(cli, fname);
2344 fnum = cli_open(cli, fname,
2345 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2346 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
2347 NULL, NULL)) {
2348 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2349 correct = False;
2352 if (!cli_qfilename(cli, fnum, pname)) {
2353 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2354 correct = False;
2357 if (strcmp(pname, fname)) {
2358 printf("qfilename gave different name? [%s] [%s]\n",
2359 fname, pname);
2360 correct = False;
2363 cli_close(cli, fnum);
2365 sleep(2);
2367 cli_unlink(cli, fname);
2368 fnum = cli_open(cli, fname,
2369 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2370 if (fnum == -1) {
2371 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2372 return False;
2374 cli_close(cli, fnum);
2376 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2377 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2378 correct = False;
2379 } else {
2380 if (c_time != m_time) {
2381 printf("create time=%s", ctime(&c_time));
2382 printf("modify time=%s", ctime(&m_time));
2383 printf("This system appears to have sticky create times\n");
2385 if (a_time % (60*60) == 0) {
2386 printf("access time=%s", ctime(&a_time));
2387 printf("This system appears to set a midnight access time\n");
2388 correct = False;
2391 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2392 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2393 correct = False;
2398 cli_unlink(cli, fname);
2399 fnum = cli_open(cli, fname,
2400 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2401 cli_close(cli, fnum);
2402 if (!cli_qpathinfo2(cli, fname, &c_time, &a_time, &m_time,
2403 &w_time, &size, NULL, NULL)) {
2404 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2405 correct = False;
2406 } else {
2407 if (w_time < 60*60*24*2) {
2408 printf("write time=%s", ctime(&w_time));
2409 printf("This system appears to set a initial 0 write time\n");
2410 correct = False;
2414 cli_unlink(cli, fname);
2417 /* check if the server updates the directory modification time
2418 when creating a new file */
2419 if (!cli_mkdir(cli, dname)) {
2420 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2421 correct = False;
2423 sleep(3);
2424 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &m_time,
2425 &w_time, &size, NULL, NULL)) {
2426 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2427 correct = False;
2430 fnum = cli_open(cli, fname2,
2431 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2432 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2433 cli_close(cli, fnum);
2434 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time, &a_time, &m_time2,
2435 &w_time, &size, NULL, NULL)) {
2436 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2437 correct = False;
2438 } else {
2439 if (m_time2 == m_time) {
2440 printf("This system does not update directory modification times\n");
2441 correct = False;
2444 cli_unlink(cli, fname2);
2445 cli_rmdir(cli, dname);
2447 if (!torture_close_connection(cli)) {
2448 correct = False;
2451 printf("trans2 test finished\n");
2453 return correct;
2457 This checks new W2K calls.
2460 static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
2462 char buf[4096];
2463 BOOL correct = True;
2465 memset(buf, 0xff, sizeof(buf));
2467 if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
2468 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2469 correct = False;
2470 } else {
2471 printf("qfileinfo: level %d\n", level);
2472 dump_data(0, buf, 256);
2473 printf("\n");
2475 return correct;
2478 static BOOL run_w2ktest(int dummy)
2480 struct cli_state *cli;
2481 int fnum;
2482 const char *fname = "\\w2ktest\\w2k.tst";
2483 int level;
2484 BOOL correct = True;
2486 printf("starting w2k test\n");
2488 if (!torture_open_connection(&cli)) {
2489 return False;
2492 fnum = cli_open(cli, fname,
2493 O_RDWR | O_CREAT , DENY_NONE);
2495 for (level = 1004; level < 1040; level++) {
2496 new_trans(cli, fnum, level);
2499 cli_close(cli, fnum);
2501 if (!torture_close_connection(cli)) {
2502 correct = False;
2505 printf("w2k test finished\n");
2507 return correct;
2512 this is a harness for some oplock tests
2514 static BOOL run_oplock1(int dummy)
2516 struct cli_state *cli1;
2517 const char *fname = "\\lockt1.lck";
2518 int fnum1;
2519 BOOL correct = True;
2521 printf("starting oplock test 1\n");
2523 if (!torture_open_connection(&cli1)) {
2524 return False;
2527 cli_unlink(cli1, fname);
2529 cli_sockopt(cli1, sockops);
2531 cli1->use_oplocks = True;
2533 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2534 if (fnum1 == -1) {
2535 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2536 return False;
2539 cli1->use_oplocks = False;
2541 cli_unlink(cli1, fname);
2542 cli_unlink(cli1, fname);
2544 if (!cli_close(cli1, fnum1)) {
2545 printf("close2 failed (%s)\n", cli_errstr(cli1));
2546 return False;
2549 if (!cli_unlink(cli1, fname)) {
2550 printf("unlink failed (%s)\n", cli_errstr(cli1));
2551 return False;
2554 if (!torture_close_connection(cli1)) {
2555 correct = False;
2558 printf("finished oplock test 1\n");
2560 return correct;
2563 static BOOL run_oplock2(int dummy)
2565 struct cli_state *cli1, *cli2;
2566 const char *fname = "\\lockt2.lck";
2567 int fnum1, fnum2;
2568 int saved_use_oplocks = use_oplocks;
2569 char buf[4];
2570 BOOL correct = True;
2571 volatile BOOL *shared_correct;
2573 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2574 *shared_correct = True;
2576 use_level_II_oplocks = True;
2577 use_oplocks = True;
2579 printf("starting oplock test 2\n");
2581 if (!torture_open_connection(&cli1)) {
2582 use_level_II_oplocks = False;
2583 use_oplocks = saved_use_oplocks;
2584 return False;
2587 cli1->use_oplocks = True;
2588 cli1->use_level_II_oplocks = True;
2590 if (!torture_open_connection(&cli2)) {
2591 use_level_II_oplocks = False;
2592 use_oplocks = saved_use_oplocks;
2593 return False;
2596 cli2->use_oplocks = True;
2597 cli2->use_level_II_oplocks = True;
2599 cli_unlink(cli1, fname);
2601 cli_sockopt(cli1, sockops);
2602 cli_sockopt(cli2, sockops);
2604 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2605 if (fnum1 == -1) {
2606 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2607 return False;
2610 /* Don't need the globals any more. */
2611 use_level_II_oplocks = False;
2612 use_oplocks = saved_use_oplocks;
2614 if (fork() == 0) {
2615 /* Child code */
2616 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
2617 if (fnum2 == -1) {
2618 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
2619 *shared_correct = False;
2620 exit(0);
2623 sleep(2);
2625 if (!cli_close(cli2, fnum2)) {
2626 printf("close2 failed (%s)\n", cli_errstr(cli1));
2627 *shared_correct = False;
2630 exit(0);
2633 sleep(2);
2635 /* Ensure cli1 processes the break. */
2637 if (cli_read(cli1, fnum1, buf, 0, 4) != 4) {
2638 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
2639 correct = False;
2642 /* Should now be at level II. */
2643 /* Test if sending a write locks causes a break to none. */
2645 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2646 printf("lock failed (%s)\n", cli_errstr(cli1));
2647 correct = False;
2650 cli_unlock(cli1, fnum1, 0, 4);
2652 sleep(2);
2654 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2655 printf("lock failed (%s)\n", cli_errstr(cli1));
2656 correct = False;
2659 cli_unlock(cli1, fnum1, 0, 4);
2661 sleep(2);
2663 cli_read(cli1, fnum1, buf, 0, 4);
2665 #if 0
2666 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
2667 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
2668 correct = False;
2670 #endif
2672 if (!cli_close(cli1, fnum1)) {
2673 printf("close1 failed (%s)\n", cli_errstr(cli1));
2674 correct = False;
2677 sleep(4);
2679 if (!cli_unlink(cli1, fname)) {
2680 printf("unlink failed (%s)\n", cli_errstr(cli1));
2681 correct = False;
2684 if (!torture_close_connection(cli1)) {
2685 correct = False;
2688 if (!*shared_correct) {
2689 correct = False;
2692 printf("finished oplock test 2\n");
2694 return correct;
2697 /* handler for oplock 3 tests */
2698 static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2700 printf("got oplock break fnum=%d level=%d\n",
2701 fnum, level);
2702 return cli_oplock_ack(cli, fnum, level);
2705 static BOOL run_oplock3(int dummy)
2707 struct cli_state *cli;
2708 const char *fname = "\\oplockt3.dat";
2709 int fnum;
2710 char buf[4] = "abcd";
2711 BOOL correct = True;
2712 volatile BOOL *shared_correct;
2714 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2715 *shared_correct = True;
2717 printf("starting oplock test 3\n");
2719 if (fork() == 0) {
2720 /* Child code */
2721 use_oplocks = True;
2722 use_level_II_oplocks = True;
2723 if (!torture_open_connection(&cli)) {
2724 *shared_correct = False;
2725 exit(0);
2727 sleep(2);
2728 /* try to trigger a oplock break in parent */
2729 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2730 cli_write(cli, fnum, 0, buf, 0, 4);
2731 exit(0);
2734 /* parent code */
2735 use_oplocks = True;
2736 use_level_II_oplocks = True;
2737 if (!torture_open_connection(&cli)) {
2738 return False;
2740 cli_oplock_handler(cli, oplock3_handler);
2741 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2742 cli_write(cli, fnum, 0, buf, 0, 4);
2743 cli_close(cli, fnum);
2744 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2745 cli->timeout = 20000;
2746 cli_receive_smb(cli);
2747 printf("finished oplock test 3\n");
2749 return (correct && *shared_correct);
2751 /* What are we looking for here? What's sucess and what's FAILURE? */
2757 Test delete on close semantics.
2759 static BOOL run_deletetest(int dummy)
2761 struct cli_state *cli1;
2762 struct cli_state *cli2;
2763 const char *fname = "\\delete.file";
2764 int fnum1 = -1;
2765 int fnum2 = -1;
2766 BOOL correct = True;
2768 printf("starting delete test\n");
2770 if (!torture_open_connection(&cli1)) {
2771 return False;
2774 cli_sockopt(cli1, sockops);
2776 /* Test 1 - this should delete the file on close. */
2778 cli_setatr(cli1, fname, 0, 0);
2779 cli_unlink(cli1, fname);
2781 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2782 FILE_SHARE_DELETE, FILE_OVERWRITE_IF,
2783 FILE_DELETE_ON_CLOSE, 0);
2785 if (fnum1 == -1) {
2786 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2787 correct = False;
2788 goto fail;
2791 if (!cli_close(cli1, fnum1)) {
2792 printf("[1] close failed (%s)\n", cli_errstr(cli1));
2793 correct = False;
2794 goto fail;
2797 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
2798 if (fnum1 != -1) {
2799 printf("[1] open of %s succeeded (should fail)\n", fname);
2800 correct = False;
2801 goto fail;
2804 printf("first delete on close test succeeded.\n");
2806 /* Test 2 - this should delete the file on close. */
2808 cli_setatr(cli1, fname, 0, 0);
2809 cli_unlink(cli1, fname);
2811 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS,
2812 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
2813 FILE_OVERWRITE_IF, 0, 0);
2815 if (fnum1 == -1) {
2816 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2817 correct = False;
2818 goto fail;
2821 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2822 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2823 correct = False;
2824 goto fail;
2827 if (!cli_close(cli1, fnum1)) {
2828 printf("[2] close failed (%s)\n", cli_errstr(cli1));
2829 correct = False;
2830 goto fail;
2833 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2834 if (fnum1 != -1) {
2835 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2836 if (!cli_close(cli1, fnum1)) {
2837 printf("[2] close failed (%s)\n", cli_errstr(cli1));
2838 correct = False;
2839 goto fail;
2841 cli_unlink(cli1, fname);
2842 } else
2843 printf("second delete on close test succeeded.\n");
2845 /* Test 3 - ... */
2846 cli_setatr(cli1, fname, 0, 0);
2847 cli_unlink(cli1, fname);
2849 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2850 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
2852 if (fnum1 == -1) {
2853 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
2854 correct = False;
2855 goto fail;
2858 /* This should fail with a sharing violation - open for delete is only compatible
2859 with SHARE_DELETE. */
2861 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2862 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0);
2864 if (fnum2 != -1) {
2865 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2866 correct = False;
2867 goto fail;
2870 /* This should succeed. */
2872 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2873 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
2875 if (fnum2 == -1) {
2876 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
2877 correct = False;
2878 goto fail;
2881 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2882 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2883 correct = False;
2884 goto fail;
2887 if (!cli_close(cli1, fnum1)) {
2888 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
2889 correct = False;
2890 goto fail;
2893 if (!cli_close(cli1, fnum2)) {
2894 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
2895 correct = False;
2896 goto fail;
2899 /* This should fail - file should no longer be there. */
2901 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2902 if (fnum1 != -1) {
2903 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2904 if (!cli_close(cli1, fnum1)) {
2905 printf("[3] close failed (%s)\n", cli_errstr(cli1));
2907 cli_unlink(cli1, fname);
2908 correct = False;
2909 goto fail;
2910 } else
2911 printf("third delete on close test succeeded.\n");
2913 /* Test 4 ... */
2914 cli_setatr(cli1, fname, 0, 0);
2915 cli_unlink(cli1, fname);
2917 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2918 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
2920 if (fnum1 == -1) {
2921 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2922 correct = False;
2923 goto fail;
2926 /* This should succeed. */
2927 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
2928 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
2929 if (fnum2 == -1) {
2930 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
2931 correct = False;
2932 goto fail;
2935 if (!cli_close(cli1, fnum2)) {
2936 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
2937 correct = False;
2938 goto fail;
2941 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2942 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2943 correct = False;
2944 goto fail;
2947 /* This should fail - no more opens once delete on close set. */
2948 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
2949 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2950 FILE_OPEN, 0, 0);
2951 if (fnum2 != -1) {
2952 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2953 correct = False;
2954 goto fail;
2955 } else
2956 printf("fourth delete on close test succeeded.\n");
2958 if (!cli_close(cli1, fnum1)) {
2959 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
2960 correct = False;
2961 goto fail;
2964 /* Test 5 ... */
2965 cli_setatr(cli1, fname, 0, 0);
2966 cli_unlink(cli1, fname);
2968 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
2969 if (fnum1 == -1) {
2970 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2971 correct = False;
2972 goto fail;
2975 /* This should fail - only allowed on NT opens with DELETE access. */
2977 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
2978 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2979 correct = False;
2980 goto fail;
2983 if (!cli_close(cli1, fnum1)) {
2984 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
2985 correct = False;
2986 goto fail;
2989 printf("fifth delete on close test succeeded.\n");
2991 /* Test 6 ... */
2992 cli_setatr(cli1, fname, 0, 0);
2993 cli_unlink(cli1, fname);
2995 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
2996 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2997 FILE_OVERWRITE_IF, 0, 0);
2999 if (fnum1 == -1) {
3000 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3001 correct = False;
3002 goto fail;
3005 /* This should fail - only allowed on NT opens with DELETE access. */
3007 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3008 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3009 correct = False;
3010 goto fail;
3013 if (!cli_close(cli1, fnum1)) {
3014 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3015 correct = False;
3016 goto fail;
3019 printf("sixth delete on close test succeeded.\n");
3021 /* Test 7 ... */
3022 cli_setatr(cli1, fname, 0, 0);
3023 cli_unlink(cli1, fname);
3025 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3026 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);
3028 if (fnum1 == -1) {
3029 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3030 correct = False;
3031 goto fail;
3034 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3035 printf("[7] setting delete_on_close on file failed !\n");
3036 correct = False;
3037 goto fail;
3040 if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
3041 printf("[7] unsetting delete_on_close on file failed !\n");
3042 correct = False;
3043 goto fail;
3046 if (!cli_close(cli1, fnum1)) {
3047 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3048 correct = False;
3049 goto fail;
3052 /* This next open should succeed - we reset the flag. */
3054 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3055 if (fnum1 == -1) {
3056 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3057 correct = False;
3058 goto fail;
3061 if (!cli_close(cli1, fnum1)) {
3062 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3063 correct = False;
3064 goto fail;
3067 printf("seventh delete on close test succeeded.\n");
3069 /* Test 7 ... */
3070 cli_setatr(cli1, fname, 0, 0);
3071 cli_unlink(cli1, fname);
3073 if (!torture_open_connection(&cli2)) {
3074 printf("[8] failed to open second connection.\n");
3075 correct = False;
3076 goto fail;
3079 cli_sockopt(cli1, sockops);
3081 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3082 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3083 FILE_OVERWRITE_IF, 0, 0);
3085 if (fnum1 == -1) {
3086 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3087 correct = False;
3088 goto fail;
3091 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3092 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3093 FILE_OPEN, 0, 0);
3095 if (fnum2 == -1) {
3096 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3097 correct = False;
3098 goto fail;
3101 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3102 printf("[8] setting delete_on_close on file failed !\n");
3103 correct = False;
3104 goto fail;
3107 if (!cli_close(cli1, fnum1)) {
3108 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3109 correct = False;
3110 goto fail;
3113 if (!cli_close(cli2, fnum2)) {
3114 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3115 correct = False;
3116 goto fail;
3119 /* This should fail.. */
3120 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3121 if (fnum1 != -1) {
3122 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3123 goto fail;
3124 correct = False;
3125 } else
3126 printf("eighth delete on close test succeeded.\n");
3128 /* This should fail - we need to set DELETE_ACCESS. */
3129 fnum1 = cli_nt_create_full(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3130 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3132 if (fnum1 != -1) {
3133 printf("[9] open of %s succeeded should have failed!\n", fname);
3134 correct = False;
3135 goto fail;
3138 printf("ninth delete on close test succeeded.\n");
3140 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3141 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3142 if (fnum1 == -1) {
3143 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3144 correct = False;
3145 goto fail;
3148 /* This should delete the file. */
3149 if (!cli_close(cli1, fnum1)) {
3150 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3151 correct = False;
3152 goto fail;
3155 /* This should fail.. */
3156 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3157 if (fnum1 != -1) {
3158 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3159 goto fail;
3160 correct = False;
3161 } else
3162 printf("tenth delete on close test succeeded.\n");
3163 printf("finished delete test\n");
3165 fail:
3166 /* FIXME: This will crash if we aborted before cli2 got
3167 * intialized, because these functions don't handle
3168 * uninitialized connections. */
3170 cli_close(cli1, fnum1);
3171 cli_close(cli1, fnum2);
3172 cli_setatr(cli1, fname, 0, 0);
3173 cli_unlink(cli1, fname);
3175 if (!torture_close_connection(cli1)) {
3176 correct = False;
3178 if (!torture_close_connection(cli2)) {
3179 correct = False;
3181 return correct;
3186 print out server properties
3188 static BOOL run_properties(int dummy)
3190 static struct cli_state *cli;
3191 BOOL correct = True;
3193 printf("starting properties test\n");
3195 ZERO_STRUCT(cli);
3197 if (!torture_open_connection(&cli)) {
3198 return False;
3201 cli_sockopt(cli, sockops);
3203 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3205 if (!torture_close_connection(cli)) {
3206 correct = False;
3209 return correct;
3214 /* FIRST_DESIRED_ACCESS 0xf019f */
3215 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3216 FILE_READ_EA| /* 0xf */ \
3217 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3218 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3219 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3220 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3221 /* SECOND_DESIRED_ACCESS 0xe0080 */
3222 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3223 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3224 WRITE_OWNER_ACCESS /* 0xe0000 */
3226 #if 0
3227 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3228 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3229 FILE_READ_DATA|\
3230 WRITE_OWNER_ACCESS /* */
3231 #endif
3234 Test ntcreate calls made by xcopy
3236 static BOOL run_xcopy(int dummy)
3238 static struct cli_state *cli1;
3239 const char *fname = "\\test.txt";
3240 BOOL correct = True;
3241 int fnum1, fnum2;
3243 printf("starting xcopy test\n");
3245 if (!torture_open_connection(&cli1)) {
3246 return False;
3249 fnum1 = cli_nt_create_full(cli1, fname, 0,
3250 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3251 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3252 0x4044, 0);
3254 if (fnum1 == -1) {
3255 printf("First open failed - %s\n", cli_errstr(cli1));
3256 return False;
3259 fnum2 = cli_nt_create_full(cli1, fname, 0,
3260 SECOND_DESIRED_ACCESS, 0,
3261 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3262 0x200000, 0);
3263 if (fnum2 == -1) {
3264 printf("second open failed - %s\n", cli_errstr(cli1));
3265 return False;
3268 if (!torture_close_connection(cli1)) {
3269 correct = False;
3272 return correct;
3276 Test rename on files open with share delete and no share delete.
3278 static BOOL run_rename(int dummy)
3280 static struct cli_state *cli1;
3281 const char *fname = "\\test.txt";
3282 const char *fname1 = "\\test1.txt";
3283 BOOL correct = True;
3284 int fnum1;
3286 printf("starting rename test\n");
3288 if (!torture_open_connection(&cli1)) {
3289 return False;
3292 cli_unlink(cli1, fname);
3293 cli_unlink(cli1, fname1);
3294 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3295 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3297 if (fnum1 == -1) {
3298 printf("First open failed - %s\n", cli_errstr(cli1));
3299 return False;
3302 if (!cli_rename(cli1, fname, fname1)) {
3303 printf("First rename failed (this is correct) - %s\n", cli_errstr(cli1));
3304 } else {
3305 printf("First rename succeeded - this should have failed !\n");
3306 correct = False;
3309 if (!cli_close(cli1, fnum1)) {
3310 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3311 return False;
3314 cli_unlink(cli1, fname);
3315 cli_unlink(cli1, fname1);
3316 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3317 #if 0
3318 FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3319 #else
3320 FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3321 #endif
3323 if (fnum1 == -1) {
3324 printf("Second open failed - %s\n", cli_errstr(cli1));
3325 return False;
3328 if (!cli_rename(cli1, fname, fname1)) {
3329 printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(cli1));
3330 correct = False;
3331 } else {
3332 printf("Second rename succeeded\n");
3335 if (!cli_close(cli1, fnum1)) {
3336 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3337 return False;
3340 cli_unlink(cli1, fname);
3341 cli_unlink(cli1, fname1);
3343 fnum1 = cli_nt_create_full(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3344 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3346 if (fnum1 == -1) {
3347 printf("Third open failed - %s\n", cli_errstr(cli1));
3348 return False;
3352 #if 0
3354 int fnum2;
3356 fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3357 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3359 if (fnum2 == -1) {
3360 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3361 return False;
3363 if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
3364 printf("[8] setting delete_on_close on file failed !\n");
3365 return False;
3368 if (!cli_close(cli1, fnum2)) {
3369 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3370 return False;
3373 #endif
3375 if (!cli_rename(cli1, fname, fname1)) {
3376 printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(cli1));
3377 correct = False;
3378 } else {
3379 printf("Third rename succeeded\n");
3382 if (!cli_close(cli1, fnum1)) {
3383 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3384 return False;
3387 cli_unlink(cli1, fname);
3388 cli_unlink(cli1, fname1);
3390 if (!torture_close_connection(cli1)) {
3391 correct = False;
3394 return correct;
3397 static BOOL run_pipe_number(int dummy)
3399 struct cli_state *cli1;
3400 const char *pipe_name = "\\SPOOLSS";
3401 int fnum;
3402 int num_pipes = 0;
3404 printf("starting pipenumber test\n");
3405 if (!torture_open_connection(&cli1)) {
3406 return False;
3409 cli_sockopt(cli1, sockops);
3410 while(1) {
3411 fnum = cli_nt_create_full(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3412 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0);
3414 if (fnum == -1) {
3415 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3416 break;
3418 num_pipes++;
3421 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3422 torture_close_connection(cli1);
3423 return True;
3427 Test open mode returns on read-only files.
3429 static BOOL run_opentest(int dummy)
3431 static struct cli_state *cli1;
3432 static struct cli_state *cli2;
3433 const char *fname = "\\readonly.file";
3434 int fnum1, fnum2;
3435 char buf[20];
3436 size_t fsize;
3437 BOOL correct = True;
3438 char *tmp_path;
3440 printf("starting open test\n");
3442 if (!torture_open_connection(&cli1)) {
3443 return False;
3446 cli_setatr(cli1, fname, 0, 0);
3447 cli_unlink(cli1, fname);
3449 cli_sockopt(cli1, sockops);
3451 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3452 if (fnum1 == -1) {
3453 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3454 return False;
3457 if (!cli_close(cli1, fnum1)) {
3458 printf("close2 failed (%s)\n", cli_errstr(cli1));
3459 return False;
3462 if (!cli_setatr(cli1, fname, aRONLY, 0)) {
3463 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
3464 return False;
3467 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3468 if (fnum1 == -1) {
3469 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3470 return False;
3473 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3474 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3476 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
3477 NT_STATUS_ACCESS_DENIED)) {
3478 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3481 printf("finished open test 1\n");
3483 cli_close(cli1, fnum1);
3485 /* Now try not readonly and ensure ERRbadshare is returned. */
3487 cli_setatr(cli1, fname, 0, 0);
3489 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3490 if (fnum1 == -1) {
3491 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3492 return False;
3495 /* This will fail - but the error should be ERRshare. */
3496 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3498 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3499 NT_STATUS_SHARING_VIOLATION)) {
3500 printf("correct error code ERRDOS/ERRbadshare returned\n");
3503 if (!cli_close(cli1, fnum1)) {
3504 printf("close2 failed (%s)\n", cli_errstr(cli1));
3505 return False;
3508 cli_unlink(cli1, fname);
3510 printf("finished open test 2\n");
3512 /* Test truncate open disposition on file opened for read. */
3514 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3515 if (fnum1 == -1) {
3516 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
3517 return False;
3520 /* write 20 bytes. */
3522 memset(buf, '\0', 20);
3524 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
3525 printf("write failed (%s)\n", cli_errstr(cli1));
3526 correct = False;
3529 if (!cli_close(cli1, fnum1)) {
3530 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
3531 return False;
3534 /* Ensure size == 20. */
3535 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3536 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3537 return False;
3540 if (fsize != 20) {
3541 printf("(3) file size != 20\n");
3542 return False;
3545 /* Now test if we can truncate a file opened for readonly. */
3547 fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3548 if (fnum1 == -1) {
3549 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
3550 return False;
3553 if (!cli_close(cli1, fnum1)) {
3554 printf("close2 failed (%s)\n", cli_errstr(cli1));
3555 return False;
3558 /* Ensure size == 0. */
3559 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3560 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3561 return False;
3564 if (fsize != 0) {
3565 printf("(3) file size != 0\n");
3566 return False;
3568 printf("finished open test 3\n");
3570 cli_unlink(cli1, fname);
3573 printf("testing ctemp\n");
3574 fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
3575 if (fnum1 == -1) {
3576 printf("ctemp failed (%s)\n", cli_errstr(cli1));
3577 return False;
3579 printf("ctemp gave path %s\n", tmp_path);
3580 if (!cli_close(cli1, fnum1)) {
3581 printf("close of temp failed (%s)\n", cli_errstr(cli1));
3583 if (!cli_unlink(cli1, tmp_path)) {
3584 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3587 /* Test the non-io opens... */
3589 if (!torture_open_connection(&cli2)) {
3590 return False;
3593 cli_setatr(cli2, fname, 0, 0);
3594 cli_unlink(cli2, fname);
3596 cli_sockopt(cli2, sockops);
3598 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3600 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3601 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3603 if (fnum1 == -1) {
3604 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3605 return False;
3608 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3609 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3611 if (fnum2 == -1) {
3612 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3613 return False;
3616 if (!cli_close(cli1, fnum1)) {
3617 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3618 return False;
3620 if (!cli_close(cli2, fnum2)) {
3621 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3622 return False;
3625 printf("non-io open test #1 passed.\n");
3627 cli_unlink(cli1, fname);
3629 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3631 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3632 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3634 if (fnum1 == -1) {
3635 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3636 return False;
3639 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3640 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3642 if (fnum2 == -1) {
3643 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3644 return False;
3647 if (!cli_close(cli1, fnum1)) {
3648 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3649 return False;
3651 if (!cli_close(cli2, fnum2)) {
3652 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3653 return False;
3656 printf("non-io open test #2 passed.\n");
3658 cli_unlink(cli1, fname);
3660 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3662 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3663 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3665 if (fnum1 == -1) {
3666 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3667 return False;
3670 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3671 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3673 if (fnum2 == -1) {
3674 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3675 return False;
3678 if (!cli_close(cli1, fnum1)) {
3679 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3680 return False;
3682 if (!cli_close(cli2, fnum2)) {
3683 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3684 return False;
3687 printf("non-io open test #3 passed.\n");
3689 cli_unlink(cli1, fname);
3691 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3693 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3694 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3696 if (fnum1 == -1) {
3697 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3698 return False;
3701 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3702 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3704 if (fnum2 != -1) {
3705 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
3706 return False;
3709 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
3711 if (!cli_close(cli1, fnum1)) {
3712 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3713 return False;
3716 printf("non-io open test #4 passed.\n");
3718 cli_unlink(cli1, fname);
3720 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3722 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3723 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3725 if (fnum1 == -1) {
3726 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3727 return False;
3730 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3731 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
3733 if (fnum2 == -1) {
3734 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3735 return False;
3738 if (!cli_close(cli1, fnum1)) {
3739 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3740 return False;
3743 if (!cli_close(cli2, fnum2)) {
3744 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3745 return False;
3748 printf("non-io open test #5 passed.\n");
3750 printf("TEST #6 testing 1 non-io open, one io open\n");
3752 cli_unlink(cli1, fname);
3754 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3755 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3757 if (fnum1 == -1) {
3758 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3759 return False;
3762 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3763 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0);
3765 if (fnum2 == -1) {
3766 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3767 return False;
3770 if (!cli_close(cli1, fnum1)) {
3771 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3772 return False;
3775 if (!cli_close(cli2, fnum2)) {
3776 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3777 return False;
3780 printf("non-io open test #6 passed.\n");
3782 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3784 cli_unlink(cli1, fname);
3786 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3787 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3789 if (fnum1 == -1) {
3790 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3791 return False;
3794 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3795 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
3797 if (fnum2 != -1) {
3798 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
3799 return False;
3802 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
3804 if (!cli_close(cli1, fnum1)) {
3805 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3806 return False;
3809 printf("non-io open test #7 passed.\n");
3811 cli_unlink(cli1, fname);
3813 if (!torture_close_connection(cli1)) {
3814 correct = False;
3816 if (!torture_close_connection(cli2)) {
3817 correct = False;
3820 return correct;
3823 static uint32 open_attrs_table[] = {
3824 FILE_ATTRIBUTE_NORMAL,
3825 FILE_ATTRIBUTE_ARCHIVE,
3826 FILE_ATTRIBUTE_READONLY,
3827 FILE_ATTRIBUTE_HIDDEN,
3828 FILE_ATTRIBUTE_SYSTEM,
3830 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
3831 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
3832 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
3833 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3834 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3835 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3837 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3838 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3839 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3840 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
3843 struct trunc_open_results {
3844 unsigned int num;
3845 uint32 init_attr;
3846 uint32 trunc_attr;
3847 uint32 result_attr;
3850 static struct trunc_open_results attr_results[] = {
3851 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3852 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3853 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3854 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3855 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3856 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3857 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3858 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3859 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3860 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3861 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3862 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
3863 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3864 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3865 { 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 },
3866 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3867 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3868 { 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 },
3869 { 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 },
3870 { 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 },
3871 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3872 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3873 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3874 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3875 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3876 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
3879 static BOOL run_openattrtest(int dummy)
3881 static struct cli_state *cli1;
3882 const char *fname = "\\openattr.file";
3883 int fnum1;
3884 BOOL correct = True;
3885 uint16 attr;
3886 unsigned int i, j, k, l;
3888 printf("starting open attr test\n");
3890 if (!torture_open_connection(&cli1)) {
3891 return False;
3894 cli_sockopt(cli1, sockops);
3896 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
3897 cli_setatr(cli1, fname, 0, 0);
3898 cli_unlink(cli1, fname);
3899 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
3900 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3902 if (fnum1 == -1) {
3903 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
3904 return False;
3907 if (!cli_close(cli1, fnum1)) {
3908 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
3909 return False;
3912 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
3913 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
3914 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0);
3916 if (fnum1 == -1) {
3917 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
3918 if (attr_results[l].num == k) {
3919 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
3920 k, open_attrs_table[i],
3921 open_attrs_table[j],
3922 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
3923 correct = False;
3926 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
3927 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
3928 k, open_attrs_table[i], open_attrs_table[j],
3929 cli_errstr(cli1));
3930 correct = False;
3932 #if 0
3933 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
3934 #endif
3935 k++;
3936 continue;
3939 if (!cli_close(cli1, fnum1)) {
3940 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
3941 return False;
3944 if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
3945 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
3946 return False;
3949 #if 0
3950 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
3951 k, open_attrs_table[i], open_attrs_table[j], attr );
3952 #endif
3954 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
3955 if (attr_results[l].num == k) {
3956 if (attr != attr_results[l].result_attr ||
3957 open_attrs_table[i] != attr_results[l].init_attr ||
3958 open_attrs_table[j] != attr_results[l].trunc_attr) {
3959 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
3960 open_attrs_table[i],
3961 open_attrs_table[j],
3962 (unsigned int)attr,
3963 attr_results[l].result_attr);
3964 correct = False;
3966 break;
3969 k++;
3973 cli_setatr(cli1, fname, 0, 0);
3974 cli_unlink(cli1, fname);
3976 printf("open attr test %s.\n", correct ? "passed" : "failed");
3978 if (!torture_close_connection(cli1)) {
3979 correct = False;
3981 return correct;
3984 static void list_fn(file_info *finfo, const char *name, void *state)
3990 test directory listing speed
3992 static BOOL run_dirtest(int dummy)
3994 int i;
3995 static struct cli_state *cli;
3996 int fnum;
3997 double t1;
3998 BOOL correct = True;
4000 printf("starting directory test\n");
4002 if (!torture_open_connection(&cli)) {
4003 return False;
4006 cli_sockopt(cli, sockops);
4008 srandom(0);
4009 for (i=0;i<torture_numops;i++) {
4010 fstring fname;
4011 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4012 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
4013 if (fnum == -1) {
4014 fprintf(stderr,"Failed to open %s\n", fname);
4015 return False;
4017 cli_close(cli, fnum);
4020 t1 = end_timer();
4022 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4023 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4024 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4026 printf("dirtest core %g seconds\n", end_timer() - t1);
4028 srandom(0);
4029 for (i=0;i<torture_numops;i++) {
4030 fstring fname;
4031 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4032 cli_unlink(cli, fname);
4035 if (!torture_close_connection(cli)) {
4036 correct = False;
4039 printf("finished dirtest\n");
4041 return correct;
4044 static void del_fn(file_info *finfo, const char *mask, void *state)
4046 struct cli_state *pcli = (struct cli_state *)state;
4047 fstring fname;
4048 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4050 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4051 return;
4053 if (finfo->mode & aDIR) {
4054 if (!cli_rmdir(pcli, fname))
4055 printf("del_fn: failed to rmdir %s\n,", fname );
4056 } else {
4057 if (!cli_unlink(pcli, fname))
4058 printf("del_fn: failed to unlink %s\n,", fname );
4064 sees what IOCTLs are supported
4066 BOOL torture_ioctl_test(int dummy)
4068 static struct cli_state *cli;
4069 uint16 device, function;
4070 int fnum;
4071 const char *fname = "\\ioctl.dat";
4072 DATA_BLOB blob;
4073 NTSTATUS status;
4075 if (!torture_open_connection(&cli)) {
4076 return False;
4079 printf("starting ioctl test\n");
4081 cli_unlink(cli, fname);
4083 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4084 if (fnum == -1) {
4085 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4086 return False;
4089 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4090 printf("ioctl device info: %s\n", cli_errstr(cli));
4092 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4093 printf("ioctl job info: %s\n", cli_errstr(cli));
4095 for (device=0;device<0x100;device++) {
4096 printf("testing device=0x%x\n", device);
4097 for (function=0;function<0x100;function++) {
4098 uint32 code = (device<<16) | function;
4100 status = cli_raw_ioctl(cli, fnum, code, &blob);
4102 if (NT_STATUS_IS_OK(status)) {
4103 printf("ioctl 0x%x OK : %d bytes\n", code, blob.length);
4104 data_blob_free(&blob);
4109 if (!torture_close_connection(cli)) {
4110 return False;
4113 return True;
4118 tries varients of chkpath
4120 BOOL torture_chkpath_test(int dummy)
4122 static struct cli_state *cli;
4123 int fnum;
4124 BOOL ret;
4126 if (!torture_open_connection(&cli)) {
4127 return False;
4130 printf("starting chkpath test\n");
4132 /* cleanup from an old run */
4133 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4134 cli_unlink(cli, "\\chkpath.dir\\*");
4135 cli_rmdir(cli, "\\chkpath.dir");
4137 if (!cli_mkdir(cli, "\\chkpath.dir")) {
4138 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4139 return False;
4142 if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
4143 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4144 return False;
4147 fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4148 if (fnum == -1) {
4149 printf("open1 failed (%s)\n", cli_errstr(cli));
4150 return False;
4152 cli_close(cli, fnum);
4154 if (!cli_chkpath(cli, "\\chkpath.dir")) {
4155 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4156 ret = False;
4159 if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
4160 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4161 ret = False;
4164 if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
4165 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4166 NT_STATUS_NOT_A_DIRECTORY);
4167 } else {
4168 printf("* chkpath on a file should fail\n");
4169 ret = False;
4172 if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
4173 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4174 NT_STATUS_OBJECT_NAME_NOT_FOUND);
4175 } else {
4176 printf("* chkpath on a non existant file should fail\n");
4177 ret = False;
4180 if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
4181 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4182 NT_STATUS_OBJECT_PATH_NOT_FOUND);
4183 } else {
4184 printf("* chkpath on a non existent component should fail\n");
4185 ret = False;
4188 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4189 cli_unlink(cli, "\\chkpath.dir\\*");
4190 cli_rmdir(cli, "\\chkpath.dir");
4192 if (!torture_close_connection(cli)) {
4193 return False;
4196 return ret;
4202 static BOOL run_dirtest1(int dummy)
4204 int i;
4205 static struct cli_state *cli;
4206 int fnum, num_seen;
4207 BOOL correct = True;
4209 printf("starting directory test\n");
4211 if (!torture_open_connection(&cli)) {
4212 return False;
4215 cli_sockopt(cli, sockops);
4217 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4218 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4219 cli_rmdir(cli, "\\LISTDIR");
4220 cli_mkdir(cli, "\\LISTDIR");
4222 /* Create 1000 files and 1000 directories. */
4223 for (i=0;i<1000;i++) {
4224 fstring fname;
4225 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
4226 fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4227 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
4228 if (fnum == -1) {
4229 fprintf(stderr,"Failed to open %s\n", fname);
4230 return False;
4232 cli_close(cli, fnum);
4234 for (i=0;i<1000;i++) {
4235 fstring fname;
4236 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
4237 if (!cli_mkdir(cli, fname)) {
4238 fprintf(stderr,"Failed to open %s\n", fname);
4239 return False;
4243 /* Now ensure that doing an old list sees both files and directories. */
4244 num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
4245 printf("num_seen = %d\n", num_seen );
4246 /* We should see 100 files + 1000 directories + . and .. */
4247 if (num_seen != 2002)
4248 correct = False;
4250 /* Ensure if we have the "must have" bits we only see the
4251 * relevent entries.
4253 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
4254 printf("num_seen = %d\n", num_seen );
4255 if (num_seen != 1002)
4256 correct = False;
4258 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
4259 printf("num_seen = %d\n", num_seen );
4260 if (num_seen != 1000)
4261 correct = False;
4263 /* Delete everything. */
4264 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4265 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4266 cli_rmdir(cli, "\\LISTDIR");
4268 #if 0
4269 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4270 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4271 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4272 #endif
4274 if (!torture_close_connection(cli)) {
4275 correct = False;
4278 printf("finished dirtest1\n");
4280 return correct;
4283 static BOOL run_error_map_extract(int dummy) {
4285 static struct cli_state c_dos;
4286 static struct cli_state c_nt;
4288 uint32 error;
4290 uint32 flgs2, errnum;
4291 uint8 errclass;
4293 NTSTATUS nt_status;
4295 fstring user;
4297 /* NT-Error connection */
4299 if (!open_nbt_connection(&c_nt)) {
4300 return False;
4303 c_nt.use_spnego = False;
4305 if (!cli_negprot(&c_nt)) {
4306 printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(&c_nt));
4307 cli_shutdown(&c_nt);
4308 return False;
4311 if (!cli_session_setup(&c_nt, "", "", 0, "", 0,
4312 workgroup)) {
4313 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(&c_nt));
4314 return False;
4317 /* DOS-Error connection */
4319 if (!open_nbt_connection(&c_dos)) {
4320 return False;
4323 c_dos.use_spnego = False;
4324 c_dos.force_dos_errors = True;
4326 if (!cli_negprot(&c_dos)) {
4327 printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(&c_dos));
4328 cli_shutdown(&c_dos);
4329 return False;
4332 if (!cli_session_setup(&c_dos, "", "", 0, "", 0,
4333 workgroup)) {
4334 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(&c_dos));
4335 return False;
4338 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
4339 snprintf(user, sizeof(user), "%X", error);
4341 if (cli_session_setup(&c_nt, user,
4342 password, strlen(password),
4343 password, strlen(password),
4344 workgroup)) {
4345 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4348 flgs2 = SVAL(c_nt.inbuf,smb_flg2);
4350 /* Case #1: 32-bit NT errors */
4351 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4352 nt_status = NT_STATUS(IVAL(c_nt.inbuf,smb_rcls));
4353 } else {
4354 printf("/** Dos error on NT connection! (%s) */\n",
4355 cli_errstr(&c_nt));
4356 nt_status = NT_STATUS(0xc0000000);
4359 if (cli_session_setup(&c_dos, user,
4360 password, strlen(password),
4361 password, strlen(password),
4362 workgroup)) {
4363 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4365 flgs2 = SVAL(c_dos.inbuf,smb_flg2), errnum;
4367 /* Case #1: 32-bit NT errors */
4368 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4369 printf("/** NT error on DOS connection! (%s) */\n",
4370 cli_errstr(&c_nt));
4371 errnum = errclass = 0;
4372 } else {
4373 cli_dos_error(&c_dos, &errclass, &errnum);
4376 if (NT_STATUS_V(nt_status) != error) {
4377 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
4378 get_nt_error_c_code(NT_STATUS(error)),
4379 get_nt_error_c_code(nt_status));
4382 printf("\t{%s,\t%s,\t%s},\n",
4383 smb_dos_err_class(errclass),
4384 smb_dos_err_name(errclass, errnum),
4385 get_nt_error_c_code(NT_STATUS(error)));
4387 return True;
4390 static double create_procs(BOOL (*fn)(int), BOOL *result)
4392 int i, status;
4393 volatile pid_t *child_status;
4394 volatile BOOL *child_status_out;
4395 int synccount;
4396 int tries = 8;
4398 synccount = 0;
4400 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
4401 if (!child_status) {
4402 printf("Failed to setup shared memory\n");
4403 return -1;
4406 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
4407 if (!child_status_out) {
4408 printf("Failed to setup result status shared memory\n");
4409 return -1;
4412 for (i = 0; i < nprocs; i++) {
4413 child_status[i] = 0;
4414 child_status_out[i] = True;
4417 start_timer();
4419 for (i=0;i<nprocs;i++) {
4420 procnum = i;
4421 if (fork() == 0) {
4422 pid_t mypid = getpid();
4423 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
4425 slprintf(myname,sizeof(myname),"CLIENT%d", i);
4427 while (1) {
4428 if (torture_open_connection(&current_cli)) break;
4429 if (tries-- == 0) {
4430 printf("pid %d failed to start\n", (int)getpid());
4431 _exit(1);
4433 msleep(10);
4436 child_status[i] = getpid();
4438 while (child_status[i] && end_timer() < 5) msleep(2);
4440 child_status_out[i] = fn(i);
4441 _exit(0);
4445 do {
4446 synccount = 0;
4447 for (i=0;i<nprocs;i++) {
4448 if (child_status[i]) synccount++;
4450 if (synccount == nprocs) break;
4451 msleep(10);
4452 } while (end_timer() < 30);
4454 if (synccount != nprocs) {
4455 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
4456 *result = False;
4457 return end_timer();
4460 /* start the client load */
4461 start_timer();
4463 for (i=0;i<nprocs;i++) {
4464 child_status[i] = 0;
4467 printf("%d clients started\n", nprocs);
4469 for (i=0;i<nprocs;i++) {
4470 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
4473 printf("\n");
4475 for (i=0;i<nprocs;i++) {
4476 if (!child_status_out[i]) {
4477 *result = False;
4480 return end_timer();
4483 #define FLAG_MULTIPROC 1
4485 static struct {
4486 const char *name;
4487 BOOL (*fn)(int);
4488 unsigned flags;
4489 } torture_ops[] = {
4490 {"FDPASS", run_fdpasstest, 0},
4491 {"LOCK1", run_locktest1, 0},
4492 {"LOCK2", run_locktest2, 0},
4493 {"LOCK3", run_locktest3, 0},
4494 {"LOCK4", run_locktest4, 0},
4495 {"LOCK5", run_locktest5, 0},
4496 {"LOCK6", run_locktest6, 0},
4497 {"LOCK7", run_locktest7, 0},
4498 {"UNLINK", run_unlinktest, 0},
4499 {"BROWSE", run_browsetest, 0},
4500 {"ATTR", run_attrtest, 0},
4501 {"TRANS2", run_trans2test, 0},
4502 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
4503 {"TORTURE",run_torture, FLAG_MULTIPROC},
4504 {"RANDOMIPC", run_randomipc, 0},
4505 {"NEGNOWAIT", run_negprot_nowait, 0},
4506 {"NBENCH", run_nbench, 0},
4507 {"OPLOCK1", run_oplock1, 0},
4508 {"OPLOCK2", run_oplock2, 0},
4509 {"OPLOCK3", run_oplock3, 0},
4510 {"DIR", run_dirtest, 0},
4511 {"DIR1", run_dirtest1, 0},
4512 {"DENY1", torture_denytest1, 0},
4513 {"DENY2", torture_denytest2, 0},
4514 {"TCON", run_tcon_test, 0},
4515 {"TCONDEV", run_tcon_devtype_test, 0},
4516 {"RW1", run_readwritetest, 0},
4517 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
4518 {"RW3", run_readwritelarge, 0},
4519 {"OPEN", run_opentest, 0},
4520 #if 1
4521 {"OPENATTR", run_openattrtest, 0},
4522 #endif
4523 {"XCOPY", run_xcopy, 0},
4524 {"RENAME", run_rename, 0},
4525 {"DELETE", run_deletetest, 0},
4526 {"PROPERTIES", run_properties, 0},
4527 {"MANGLE", torture_mangle, 0},
4528 {"W2K", run_w2ktest, 0},
4529 {"TRANS2SCAN", torture_trans2_scan, 0},
4530 {"NTTRANSSCAN", torture_nttrans_scan, 0},
4531 {"UTABLE", torture_utable, 0},
4532 {"CASETABLE", torture_casetable, 0},
4533 {"ERRMAPEXTRACT", run_error_map_extract, 0},
4534 {"PIPE_NUMBER", run_pipe_number, 0},
4535 {"TCON2", run_tcon2_test, 0},
4536 {"IOCTL", torture_ioctl_test, 0},
4537 {"CHKPATH", torture_chkpath_test, 0},
4538 {"FDSESS", run_fdsesstest, 0},
4539 {NULL, NULL, 0}};
4543 /****************************************************************************
4544 run a specified test or "ALL"
4545 ****************************************************************************/
4546 static BOOL run_test(const char *name)
4548 BOOL ret = True;
4549 BOOL result = True;
4550 int i;
4551 double t;
4552 if (strequal(name,"ALL")) {
4553 for (i=0;torture_ops[i].name;i++) {
4554 run_test(torture_ops[i].name);
4558 for (i=0;torture_ops[i].name;i++) {
4559 snprintf(randomfname, sizeof(randomfname), "\\XX%x",
4560 (unsigned)random());
4562 if (strequal(name, torture_ops[i].name)) {
4563 printf("Running %s\n", name);
4564 if (torture_ops[i].flags & FLAG_MULTIPROC) {
4565 t = create_procs(torture_ops[i].fn, &result);
4566 if (!result) {
4567 ret = False;
4568 printf("TEST %s FAILED!\n", name);
4571 } else {
4572 start_timer();
4573 if (!torture_ops[i].fn(0)) {
4574 ret = False;
4575 printf("TEST %s FAILED!\n", name);
4577 t = end_timer();
4579 printf("%s took %g secs\n\n", name, t);
4582 return ret;
4586 static void usage(void)
4588 int i;
4590 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
4592 printf("\t-d debuglevel\n");
4593 printf("\t-U user%%pass\n");
4594 printf("\t-k use kerberos\n");
4595 printf("\t-N numprocs\n");
4596 printf("\t-n my_netbios_name\n");
4597 printf("\t-W workgroup\n");
4598 printf("\t-o num_operations\n");
4599 printf("\t-O socket_options\n");
4600 printf("\t-m maximum protocol\n");
4601 printf("\t-L use oplocks\n");
4602 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
4603 printf("\t-A showall\n");
4604 printf("\t-p port\n");
4605 printf("\t-s seed\n");
4606 printf("\n\n");
4608 printf("tests are:");
4609 for (i=0;torture_ops[i].name;i++) {
4610 printf(" %s", torture_ops[i].name);
4612 printf("\n");
4614 printf("default test is ALL\n");
4616 exit(1);
4619 /****************************************************************************
4620 main program
4621 ****************************************************************************/
4622 int main(int argc,char *argv[])
4624 int opt, i;
4625 char *p;
4626 int gotuser = 0;
4627 int gotpass = 0;
4628 extern char *optarg;
4629 extern int optind;
4630 BOOL correct = True;
4632 dbf = x_stdout;
4634 #ifdef HAVE_SETBUFFER
4635 setbuffer(stdout, NULL, 0);
4636 #endif
4638 lp_load(dyn_CONFIGFILE,True,False,False);
4639 load_interfaces();
4641 if (argc < 2) {
4642 usage();
4645 for(p = argv[1]; *p; p++)
4646 if(*p == '\\')
4647 *p = '/';
4649 if (strncmp(argv[1], "//", 2)) {
4650 usage();
4653 fstrcpy(host, &argv[1][2]);
4654 p = strchr_m(&host[2],'/');
4655 if (!p) {
4656 usage();
4658 *p = 0;
4659 fstrcpy(share, p+1);
4661 get_myname(myname);
4663 if (*username == 0 && getenv("LOGNAME")) {
4664 fstrcpy(username,getenv("LOGNAME"));
4667 argc--;
4668 argv++;
4670 srandom(time(NULL));
4672 fstrcpy(workgroup, lp_workgroup());
4674 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Ac:ks:")) != EOF) {
4675 switch (opt) {
4676 case 'p':
4677 port_to_use = atoi(optarg);
4678 break;
4679 case 's':
4680 srandom(atoi(optarg));
4681 break;
4682 case 'W':
4683 fstrcpy(workgroup,optarg);
4684 break;
4685 case 'm':
4686 max_protocol = interpret_protocol(optarg, max_protocol);
4687 break;
4688 case 'N':
4689 nprocs = atoi(optarg);
4690 break;
4691 case 'o':
4692 torture_numops = atoi(optarg);
4693 break;
4694 case 'd':
4695 DEBUGLEVEL = atoi(optarg);
4696 break;
4697 case 'O':
4698 sockops = optarg;
4699 break;
4700 case 'L':
4701 use_oplocks = True;
4702 break;
4703 case 'A':
4704 torture_showall = True;
4705 break;
4706 case 'n':
4707 fstrcpy(myname, optarg);
4708 break;
4709 case 'c':
4710 client_txt = optarg;
4711 break;
4712 case 'k':
4713 #ifdef HAVE_KRB5
4714 use_kerberos = True;
4715 #else
4716 d_printf("No kerberos support compiled in\n");
4717 exit(1);
4718 #endif
4719 break;
4720 case 'U':
4721 gotuser = 1;
4722 fstrcpy(username,optarg);
4723 p = strchr_m(username,'%');
4724 if (p) {
4725 *p = 0;
4726 fstrcpy(password, p+1);
4727 gotpass = 1;
4729 break;
4730 default:
4731 printf("Unknown option %c (%d)\n", (char)opt, opt);
4732 usage();
4736 if(use_kerberos && !gotuser) gotpass = True;
4738 while (!gotpass) {
4739 p = getpass("Password:");
4740 if (p) {
4741 fstrcpy(password, p);
4742 gotpass = 1;
4746 printf("host=%s share=%s user=%s myname=%s\n",
4747 host, share, username, myname);
4749 if (argc == 1) {
4750 correct = run_test("ALL");
4751 } else {
4752 for (i=1;i<argc;i++) {
4753 if (!run_test(argv[i])) {
4754 correct = False;
4759 if (correct) {
4760 return(0);
4761 } else {
4762 return(1);