nicer measurement of failures and collisions
[samba.git] / source3 / torture / torture.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB torture tester
4    Copyright (C) Andrew Tridgell 1997-1998
5    
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.
10    
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.
15    
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.
19 */
20
21 #define NO_SYSLOG
22
23 #include "includes.h"
24
25 static fstring host, workgroup, share, password, username, myname;
26 static int max_protocol = PROTOCOL_NT1;
27 static char *sockops="TCP_NODELAY";
28 static int nprocs=1;
29 int torture_numops=100;
30 static int procnum; /* records process count number when forking */
31 static struct cli_state current_cli;
32 static fstring randomfname;
33 static BOOL use_oplocks;
34 static BOOL use_level_II_oplocks;
35 static char *client_txt = "client_oplocks.txt";
36 static BOOL use_kerberos;
37
38 BOOL torture_showall = False;
39
40 static double create_procs(BOOL (*fn)(int), BOOL *result);
41
42
43 static struct timeval tp1,tp2;
44
45 void start_timer(void)
46 {
47         gettimeofday(&tp1,NULL);
48 }
49
50 double end_timer(void)
51 {
52         gettimeofday(&tp2,NULL);
53         return((tp2.tv_sec - tp1.tv_sec) + 
54                (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
55 }
56
57
58 /* return a pointer to a anonymous shared memory segment of size "size"
59    which will persist across fork() but will disappear when all processes
60    exit 
61
62    The memory is not zeroed 
63
64    This function uses system5 shared memory. It takes advantage of a property
65    that the memory is not destroyed if it is attached when the id is removed
66    */
67 void *shm_setup(int size)
68 {
69         int shmid;
70         void *ret;
71
72         shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
73         if (shmid == -1) {
74                 printf("can't get shared memory\n");
75                 exit(1);
76         }
77         ret = (void *)shmat(shmid, 0, 0);
78         if (!ret || ret == (void *)-1) {
79                 printf("can't attach to shared memory\n");
80                 return NULL;
81         }
82         /* the following releases the ipc, but note that this process
83            and all its children will still have access to the memory, its
84            just that the shmid is no longer valid for other shm calls. This
85            means we don't leave behind lots of shm segments after we exit 
86
87            See Stevens "advanced programming in unix env" for details
88            */
89         shmctl(shmid, IPC_RMID, 0);
90         
91         return ret;
92 }
93
94
95 static BOOL open_nbt_connection(struct cli_state *c)
96 {
97         struct nmb_name called, calling;
98         struct in_addr ip;
99
100         ZERO_STRUCTP(c);
101
102         make_nmb_name(&calling, myname, 0x0);
103         make_nmb_name(&called , host, 0x20);
104
105         zero_ip(&ip);
106
107         if (!cli_initialise(c) || !cli_connect(c, host, &ip)) {
108                 printf("Failed to connect with %s\n", host);
109                 return False;
110         }
111
112         c->use_kerberos = use_kerberos;
113
114         c->timeout = 120000; /* set a really long timeout (2 minutes) */
115         if (use_oplocks) c->use_oplocks = True;
116         if (use_level_II_oplocks) c->use_level_II_oplocks = True;
117
118         if (!cli_session_request(c, &calling, &called)) {
119                 printf("%s rejected the session\n",host);
120                 cli_shutdown(c);
121                 return False;
122         }
123
124         return True;
125 }
126
127 BOOL torture_open_connection(struct cli_state *c)
128 {
129         ZERO_STRUCTP(c);
130
131         if (!open_nbt_connection(c)) {
132                 return False;
133         }
134
135         if (!cli_negprot(c)) {
136                 printf("%s rejected the negprot (%s)\n",host, cli_errstr(c));
137                 cli_shutdown(c);
138                 return False;
139         }
140
141         if (!cli_session_setup(c, username, 
142                                password, strlen(password),
143                                password, strlen(password),
144                                workgroup)) {
145                 printf("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c));
146                 cli_shutdown(c);
147                 return False;
148         }
149
150         if (!cli_send_tconX(c, share, "?????",
151                             password, strlen(password)+1)) {
152                 printf("%s refused tree connect (%s)\n", host, cli_errstr(c));
153                 cli_shutdown(c);
154                 return False;
155         }
156
157         return True;
158 }
159
160
161 BOOL torture_close_connection(struct cli_state *c)
162 {
163         BOOL ret = True;
164         if (!cli_tdis(c)) {
165                 printf("tdis failed (%s)\n", cli_errstr(c));
166                 ret = False;
167         }
168
169         cli_shutdown(c);
170
171         return ret;
172 }
173
174
175 /* check if the server produced the expected error code */
176 static BOOL check_error(int line, struct cli_state *c, 
177                         uint8 eclass, uint32 ecode, NTSTATUS nterr)
178 {
179         if (cli_is_dos_error(c)) {
180                 uint8 class;
181                 uint32 num;
182
183                 /* Check DOS error */
184
185                 cli_dos_error(c, &class, &num);
186
187                 if (eclass != class || ecode != num) {
188                         printf("unexpected error code class=%d code=%d\n", 
189                                (int)class, (int)num);
190                         printf(" expected %d/%d %s (line=%d)\n", 
191                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
192                         return False;
193                 }
194
195         } else {
196                 NTSTATUS status;
197
198                 /* Check NT error */
199
200                 status = cli_nt_error(c);
201
202                 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
203                         printf("unexpected error code %s\n", nt_errstr(status));
204                         printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
205                         return False;
206                 }
207         }
208
209         return True;
210 }
211
212
213 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
214 {
215         while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
216                 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
217         }
218         return True;
219 }
220
221
222 static BOOL rw_torture(struct cli_state *c)
223 {
224         char *lockfname = "\\torture.lck";
225         fstring fname;
226         int fnum;
227         int fnum2;
228         pid_t pid2, pid = getpid();
229         int i, j;
230         char buf[1024];
231         BOOL correct = True;
232
233         fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
234                          DENY_NONE);
235         if (fnum2 == -1)
236                 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
237         if (fnum2 == -1) {
238                 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
239                 return False;
240         }
241
242
243         for (i=0;i<torture_numops;i++) {
244                 unsigned n = (unsigned)sys_random()%10;
245                 if (i % 10 == 0) {
246                         printf("%d\r", i); fflush(stdout);
247                 }
248                 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
249
250                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
251                         return False;
252                 }
253
254                 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
255                 if (fnum == -1) {
256                         printf("open failed (%s)\n", cli_errstr(c));
257                         correct = False;
258                         break;
259                 }
260
261                 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
262                         printf("write failed (%s)\n", cli_errstr(c));
263                         correct = False;
264                 }
265
266                 for (j=0;j<50;j++) {
267                         if (cli_write(c, fnum, 0, (char *)buf, 
268                                       sizeof(pid)+(j*sizeof(buf)), 
269                                       sizeof(buf)) != sizeof(buf)) {
270                                 printf("write failed (%s)\n", cli_errstr(c));
271                                 correct = False;
272                         }
273                 }
274
275                 pid2 = 0;
276
277                 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
278                         printf("read failed (%s)\n", cli_errstr(c));
279                         correct = False;
280                 }
281
282                 if (pid2 != pid) {
283                         printf("data corruption!\n");
284                         correct = False;
285                 }
286
287                 if (!cli_close(c, fnum)) {
288                         printf("close failed (%s)\n", cli_errstr(c));
289                         correct = False;
290                 }
291
292                 if (!cli_unlink(c, fname)) {
293                         printf("unlink failed (%s)\n", cli_errstr(c));
294                         correct = False;
295                 }
296
297                 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
298                         printf("unlock failed (%s)\n", cli_errstr(c));
299                         correct = False;
300                 }
301         }
302
303         cli_close(c, fnum2);
304         cli_unlink(c, lockfname);
305
306         printf("%d\n", i);
307
308         return correct;
309 }
310
311 static BOOL run_torture(int dummy)
312 {
313         struct cli_state cli;
314         BOOL ret;
315
316         cli = current_cli;
317
318         cli_sockopt(&cli, sockops);
319
320         ret = rw_torture(&cli);
321         
322         if (!torture_close_connection(&cli)) {
323                 ret = False;
324         }
325
326         return ret;
327 }
328
329 static BOOL rw_torture3(struct cli_state *c, char *lockfname)
330 {
331         int fnum = -1;
332         int i = 0;
333         char buf[131072];
334         char buf_rd[131072];
335         unsigned count;
336         unsigned countprev = 0;
337         ssize_t sent = 0;
338         BOOL correct = True;
339
340         srandom(1);
341         for (i = 0; i < sizeof(buf); i += sizeof(uint32))
342         {
343                 SIVAL(buf, i, sys_random());
344         }
345
346         if (procnum == 0)
347         {
348                 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
349                                  DENY_NONE);
350                 if (fnum == -1) {
351                         printf("first open read/write of %s failed (%s)\n",
352                                         lockfname, cli_errstr(c));
353                         return False;
354                 }
355         }
356         else
357         {
358                 for (i = 0; i < 500 && fnum == -1; i++)
359                 {
360                         fnum = cli_open(c, lockfname, O_RDONLY, 
361                                          DENY_NONE);
362                         msleep(10);
363                 }
364                 if (fnum == -1) {
365                         printf("second open read-only of %s failed (%s)\n",
366                                         lockfname, cli_errstr(c));
367                         return False;
368                 }
369         }
370
371         i = 0;
372         for (count = 0; count < sizeof(buf); count += sent)
373         {
374                 if (count >= countprev) {
375                         printf("%d %8d\r", i, count);
376                         fflush(stdout);
377                         i++;
378                         countprev += (sizeof(buf) / 20);
379                 }
380
381                 if (procnum == 0)
382                 {
383                         sent = ((unsigned)sys_random()%(20))+ 1;
384                         if (sent > sizeof(buf) - count)
385                         {
386                                 sent = sizeof(buf) - count;
387                         }
388
389                         if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
390                                 printf("write failed (%s)\n", cli_errstr(c));
391                                 correct = False;
392                         }
393                 }
394                 else
395                 {
396                         sent = cli_read(c, fnum, buf_rd+count, count,
397                                                   sizeof(buf)-count);
398                         if (sent < 0)
399                         {
400                                 printf("read failed offset:%d size:%d (%s)\n",
401                                                 count, sizeof(buf)-count,
402                                                 cli_errstr(c));
403                                 correct = False;
404                                 sent = 0;
405                         }
406                         if (sent > 0)
407                         {
408                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
409                                 {
410                                         printf("read/write compare failed\n");
411                                         printf("offset: %d req %d recvd %d\n",
412                                                 count, sizeof(buf)-count, sent);
413                                         correct = False;
414                                         break;
415                                 }
416                         }
417                 }
418
419         }
420
421         if (!cli_close(c, fnum)) {
422                 printf("close failed (%s)\n", cli_errstr(c));
423                 correct = False;
424         }
425
426         return correct;
427 }
428
429 static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
430 {
431         char *lockfname = "\\torture2.lck";
432         int fnum1;
433         int fnum2;
434         int i;
435         uchar buf[131072];
436         uchar buf_rd[131072];
437         BOOL correct = True;
438         ssize_t bytes_read;
439
440         if (!cli_unlink(c1, lockfname)) {
441                 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
442         }
443
444         fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL, 
445                          DENY_NONE);
446         if (fnum1 == -1) {
447                 printf("first open read/write of %s failed (%s)\n",
448                                 lockfname, cli_errstr(c1));
449                 return False;
450         }
451         fnum2 = cli_open(c2, lockfname, O_RDONLY, 
452                          DENY_NONE);
453         if (fnum2 == -1) {
454                 printf("second open read-only of %s failed (%s)\n",
455                                 lockfname, cli_errstr(c2));
456                 cli_close(c1, fnum1);
457                 return False;
458         }
459
460         for (i=0;i<torture_numops;i++)
461         {
462                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
463                 if (i % 10 == 0) {
464                         printf("%d\r", i); fflush(stdout);
465                 }
466
467                 generate_random_buffer(buf, buf_size, False);
468
469                 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
470                         printf("write failed (%s)\n", cli_errstr(c1));
471                         correct = False;
472                 }
473
474                 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
475                         printf("read failed (%s)\n", cli_errstr(c2));
476                         printf("read %d, expected %d\n", bytes_read, buf_size); 
477                         correct = False;
478                 }
479
480                 if (memcmp(buf_rd, buf, buf_size) != 0)
481                 {
482                         printf("read/write compare failed\n");
483                         correct = False;
484                 }
485         }
486
487         if (!cli_close(c2, fnum2)) {
488                 printf("close failed (%s)\n", cli_errstr(c2));
489                 correct = False;
490         }
491         if (!cli_close(c1, fnum1)) {
492                 printf("close failed (%s)\n", cli_errstr(c1));
493                 correct = False;
494         }
495
496         if (!cli_unlink(c1, lockfname)) {
497                 printf("unlink failed (%s)\n", cli_errstr(c1));
498                 correct = False;
499         }
500
501         return correct;
502 }
503
504 static BOOL run_readwritetest(int dummy)
505 {
506         static struct cli_state cli1, cli2;
507         BOOL test1, test2;
508
509         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
510                 return False;
511         }
512         cli_sockopt(&cli1, sockops);
513         cli_sockopt(&cli2, sockops);
514
515         printf("starting readwritetest\n");
516
517         test1 = rw_torture2(&cli1, &cli2);
518         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
519
520         test2 = rw_torture2(&cli1, &cli1);
521         printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
522
523         if (!torture_close_connection(&cli1)) {
524                 test1 = False;
525         }
526
527         if (!torture_close_connection(&cli2)) {
528                 test2 = False;
529         }
530
531         return (test1 && test2);
532 }
533
534 static BOOL run_readwritemulti(int dummy)
535 {
536         static struct cli_state cli;
537         BOOL test;
538
539         cli = current_cli;
540
541         cli_sockopt(&cli, sockops);
542
543         printf("run_readwritemulti: fname %s\n", randomfname);
544         test = rw_torture3(&cli, randomfname);
545
546         if (!torture_close_connection(&cli)) {
547                 test = False;
548         }
549         
550         return test;
551 }
552
553 static BOOL run_readwritelarge(int dummy)
554 {
555         static struct cli_state cli1;
556         int fnum1;
557         char *lockfname = "\\large.dat";
558         size_t fsize;
559         char buf[126*1024];
560         BOOL correct = True;
561  
562         if (!torture_open_connection(&cli1)) {
563                 return False;
564         }
565         cli_sockopt(&cli1, sockops);
566         memset(buf,'\0',sizeof(buf));
567         
568         cli1.max_xmit = 128*1024;
569         
570         printf("starting readwritelarge\n");
571  
572         cli_unlink(&cli1, lockfname);
573
574         fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
575         if (fnum1 == -1) {
576                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
577                 return False;
578         }
579    
580         cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf));
581
582         if (!cli_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
583                 printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
584                 correct = False;
585         }
586
587         if (fsize == sizeof(buf))
588                 printf("readwritelarge test 1 succeeded (size = %x)\n", fsize);
589         else {
590                 printf("readwritelarge test 1 failed (size = %x)\n", fsize);
591                 correct = False;
592         }
593
594         if (!cli_close(&cli1, fnum1)) {
595                 printf("close failed (%s)\n", cli_errstr(&cli1));
596                 correct = False;
597         }
598
599         if (!cli_unlink(&cli1, lockfname)) {
600                 printf("unlink failed (%s)\n", cli_errstr(&cli1));
601                 correct = False;
602         }
603
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;
608         }
609         
610         cli1.max_xmit = 4*1024;
611         
612         cli_smbwrite(&cli1, fnum1, buf, 0, sizeof(buf));
613         
614         if (!cli_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
615                 printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
616                 correct = False;
617         }
618
619         if (fsize == sizeof(buf))
620                 printf("readwritelarge test 2 succeeded (size = %x)\n", fsize);
621         else {
622                 printf("readwritelarge test 2 failed (size = %x)\n", fsize);
623                 correct = False;
624         }
625
626 #if 0
627         /* ToDo - set allocation. JRA */
628         if(!cli_set_allocation_size(&cli1, fnum1, 0)) {
629                 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
630                 return False;
631         }
632         if (!cli_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
633                 printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
634                 correct = False;
635         }
636         if (fsize != 0)
637                 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
638 #endif
639
640         if (!cli_close(&cli1, fnum1)) {
641                 printf("close failed (%s)\n", cli_errstr(&cli1));
642                 correct = False;
643         }
644         
645         if (!torture_close_connection(&cli1)) {
646                 correct = False;
647         }
648         return correct;
649         }
650
651 int line_count = 0;
652 int nbio_id;
653
654 #define ival(s) strtol(s, NULL, 0)
655
656 /* run a test that simulates an approximate netbench client load */
657 static BOOL run_netbench(int client)
658 {
659         struct cli_state cli;
660         int i;
661         fstring fname;
662         pstring line;
663         char cname[20];
664         FILE *f;
665         char *params[20];
666         BOOL correct = True;
667
668         cli = current_cli;
669
670         nbio_id = client;
671
672         cli_sockopt(&cli, sockops);
673
674         nb_setup(&cli);
675
676         slprintf(cname,sizeof(fname), "client%d", client);
677
678         f = fopen(client_txt, "r");
679
680         if (!f) {
681                 perror(client_txt);
682                 return False;
683         }
684
685         while (fgets(line, sizeof(line)-1, f)) {
686                 line_count++;
687
688                 line[strlen(line)-1] = 0;
689
690                 /* printf("[%d] %s\n", line_count, line); */
691
692                 all_string_sub(line,"client1", cname, sizeof(line));
693                 
694                 /* parse the command parameters */
695                 params[0] = strtok(line," ");
696                 i = 0;
697                 while (params[i]) params[++i] = strtok(NULL," ");
698
699                 params[i] = "";
700
701                 if (i < 2) continue;
702
703                 if (!strncmp(params[0],"SMB", 3)) {
704                         printf("ERROR: You are using a dbench 1 load file\n");
705                         exit(1);
706                 }
707
708                 if (!strcmp(params[0],"NTCreateX")) {
709                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
710                                    ival(params[4]));
711                 } else if (!strcmp(params[0],"Close")) {
712                         nb_close(ival(params[1]));
713                 } else if (!strcmp(params[0],"Rename")) {
714                         nb_rename(params[1], params[2]);
715                 } else if (!strcmp(params[0],"Unlink")) {
716                         nb_unlink(params[1]);
717                 } else if (!strcmp(params[0],"Deltree")) {
718                         nb_deltree(params[1]);
719                 } else if (!strcmp(params[0],"Rmdir")) {
720                         nb_rmdir(params[1]);
721                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
722                         nb_qpathinfo(params[1]);
723                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
724                         nb_qfileinfo(ival(params[1]));
725                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
726                         nb_qfsinfo(ival(params[1]));
727                 } else if (!strcmp(params[0],"FIND_FIRST")) {
728                         nb_findfirst(params[1]);
729                 } else if (!strcmp(params[0],"WriteX")) {
730                         nb_writex(ival(params[1]), 
731                                   ival(params[2]), ival(params[3]), ival(params[4]));
732                 } else if (!strcmp(params[0],"ReadX")) {
733                         nb_readx(ival(params[1]), 
734                                   ival(params[2]), ival(params[3]), ival(params[4]));
735                 } else if (!strcmp(params[0],"Flush")) {
736                         nb_flush(ival(params[1]));
737                 } else {
738                         printf("Unknown operation %s\n", params[0]);
739                         exit(1);
740                 }
741         }
742         fclose(f);
743
744         nb_cleanup();
745
746         if (!torture_close_connection(&cli)) {
747                 correct = False;
748         }
749         
750         return correct;
751 }
752
753
754 /* run a test that simulates an approximate netbench client load */
755 static BOOL run_nbench(int dummy)
756 {
757         double t;
758         BOOL correct = True;
759
760         nbio_shmem(nprocs);
761
762         nbio_id = -1;
763
764         signal(SIGALRM, nb_alarm);
765         alarm(1);
766         t = create_procs(run_netbench, &correct);
767         alarm(0);
768
769         printf("\nThroughput %g MB/sec\n", 
770                1.0e-6 * nbio_total() / t);
771         return correct;
772 }
773
774
775 /*
776   This test checks for two things:
777
778   1) correct support for retaining locks over a close (ie. the server
779      must not use posix semantics)
780   2) support for lock timeouts
781  */
782 static BOOL run_locktest1(int dummy)
783 {
784         static struct cli_state cli1, cli2;
785         char *fname = "\\lockt1.lck";
786         int fnum1, fnum2, fnum3;
787         time_t t1, t2;
788
789         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
790                 return False;
791         }
792         cli_sockopt(&cli1, sockops);
793         cli_sockopt(&cli2, sockops);
794
795         printf("starting locktest1\n");
796
797         cli_unlink(&cli1, fname);
798
799         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
800         if (fnum1 == -1) {
801                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
802                 return False;
803         }
804         fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
805         if (fnum2 == -1) {
806                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
807                 return False;
808         }
809         fnum3 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
810         if (fnum3 == -1) {
811                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2));
812                 return False;
813         }
814
815         if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
816                 printf("lock1 failed (%s)\n", cli_errstr(&cli1));
817                 return False;
818         }
819
820
821         if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
822                 printf("lock2 succeeded! This is a locking bug\n");
823                 return False;
824         } else {
825                 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock, 
826                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
827         }
828
829
830         printf("Testing lock timeouts\n");
831         t1 = time(NULL);
832         if (cli_lock(&cli2, fnum3, 0, 4, 10*1000, WRITE_LOCK)) {
833                 printf("lock3 succeeded! This is a locking bug\n");
834                 return False;
835         } else {
836                 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock, 
837                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
838         }
839         t2 = time(NULL);
840
841         if (t2 - t1 < 5) {
842                 printf("error: This server appears not to support timed lock requests\n");
843         }
844
845         if (!cli_close(&cli1, fnum2)) {
846                 printf("close1 failed (%s)\n", cli_errstr(&cli1));
847                 return False;
848         }
849
850         if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
851                 printf("lock4 succeeded! This is a locking bug\n");
852                 return False;
853         } else {
854                 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock, 
855                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
856         }
857
858         if (!cli_close(&cli1, fnum1)) {
859                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
860                 return False;
861         }
862
863         if (!cli_close(&cli2, fnum3)) {
864                 printf("close3 failed (%s)\n", cli_errstr(&cli2));
865                 return False;
866         }
867
868         if (!cli_unlink(&cli1, fname)) {
869                 printf("unlink failed (%s)\n", cli_errstr(&cli1));
870                 return False;
871         }
872
873
874         if (!torture_close_connection(&cli1)) {
875                 return False;
876         }
877
878         if (!torture_close_connection(&cli2)) {
879                 return False;
880         }
881
882         printf("Passed locktest1\n");
883         return True;
884 }
885
886 /*
887  checks for correct tconX support
888  */
889 static BOOL run_tcon_test(int dummy)
890 {
891         static struct cli_state cli1;
892         char *fname = "\\tcontest.tmp";
893         int fnum1;
894         uint16 cnum;
895         char buf[4];
896
897         if (!torture_open_connection(&cli1)) {
898                 return False;
899         }
900         cli_sockopt(&cli1, sockops);
901
902         printf("starting tcontest\n");
903
904         cli_unlink(&cli1, fname);
905
906         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
907         if (fnum1 == -1)
908         {
909                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
910                 return False;
911         }
912
913         cnum = cli1.cnum;
914
915         if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4)
916         {
917                 printf("write failed (%s)", cli_errstr(&cli1));
918                 return False;
919         }
920
921         if (!cli_send_tconX(&cli1, share, "?????",
922                             password, strlen(password)+1)) {
923                 printf("%s refused 2nd tree connect (%s)\n", host,
924                            cli_errstr(&cli1));
925                 cli_shutdown(&cli1);
926                 return False;
927         }
928
929         if (cli_write(&cli1, fnum1, 0, buf, 130, 4) == 4)
930         {
931                 printf("write succeeded (%s)", cli_errstr(&cli1));
932                 return False;
933         }
934
935         if (cli_close(&cli1, fnum1)) {
936                 printf("close2 succeeded (%s)\n", cli_errstr(&cli1));
937                 return False;
938         }
939
940         if (!cli_tdis(&cli1)) {
941                 printf("tdis failed (%s)\n", cli_errstr(&cli1));
942                 return False;
943         }
944
945         cli1.cnum = cnum;
946
947         if (!cli_close(&cli1, fnum1)) {
948                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
949                 return False;
950         }
951
952         if (!torture_close_connection(&cli1)) {
953                 return False;
954         }
955
956         printf("Passed tcontest\n");
957         return True;
958 }
959
960
961 /*
962   This test checks that 
963
964   1) the server supports multiple locking contexts on the one SMB
965   connection, distinguished by PID.  
966
967   2) the server correctly fails overlapping locks made by the same PID (this
968      goes against POSIX behaviour, which is why it is tricky to implement)
969
970   3) the server denies unlock requests by an incorrect client PID
971 */
972 static BOOL run_locktest2(int dummy)
973 {
974         static struct cli_state cli;
975         char *fname = "\\lockt2.lck";
976         int fnum1, fnum2, fnum3;
977         BOOL correct = True;
978
979         if (!torture_open_connection(&cli)) {
980                 return False;
981         }
982
983         cli_sockopt(&cli, sockops);
984
985         printf("starting locktest2\n");
986
987         cli_unlink(&cli, fname);
988
989         cli_setpid(&cli, 1);
990
991         fnum1 = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
992         if (fnum1 == -1) {
993                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
994                 return False;
995         }
996
997         fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
998         if (fnum2 == -1) {
999                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli));
1000                 return False;
1001         }
1002
1003         cli_setpid(&cli, 2);
1004
1005         fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
1006         if (fnum3 == -1) {
1007                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli));
1008                 return False;
1009         }
1010
1011         cli_setpid(&cli, 1);
1012
1013         if (!cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1014                 printf("lock1 failed (%s)\n", cli_errstr(&cli));
1015                 return False;
1016         }
1017
1018         if (cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1019                 printf("WRITE lock1 succeeded! This is a locking bug\n");
1020                 correct = False;
1021         } else {
1022                 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, 
1023                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1024         }
1025
1026         if (cli_lock(&cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1027                 printf("WRITE lock2 succeeded! This is a locking bug\n");
1028                 correct = False;
1029         } else {
1030                 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, 
1031                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1032         }
1033
1034         if (cli_lock(&cli, fnum2, 0, 4, 0, READ_LOCK)) {
1035                 printf("READ lock2 succeeded! This is a locking bug\n");
1036                 correct = False;
1037         } else {
1038                 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, 
1039                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1040         }
1041
1042         if (!cli_lock(&cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1043                 printf("lock at 100 failed (%s)\n", cli_errstr(&cli));
1044         }
1045         cli_setpid(&cli, 2);
1046         if (cli_unlock(&cli, fnum1, 100, 4)) {
1047                 printf("unlock at 100 succeeded! This is a locking bug\n");
1048                 correct = False;
1049         }
1050
1051         if (cli_unlock(&cli, fnum1, 0, 4)) {
1052                 printf("unlock1 succeeded! This is a locking bug\n");
1053                 correct = False;
1054         } else {
1055                 if (!check_error(__LINE__, &cli, 
1056                                  ERRDOS, ERRlock, 
1057                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1058         }
1059
1060         if (cli_unlock(&cli, fnum1, 0, 8)) {
1061                 printf("unlock2 succeeded! This is a locking bug\n");
1062                 correct = False;
1063         } else {
1064                 if (!check_error(__LINE__, &cli, 
1065                                  ERRDOS, ERRlock, 
1066                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1067         }
1068
1069         if (cli_lock(&cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1070                 printf("lock3 succeeded! This is a locking bug\n");
1071                 correct = False;
1072         } else {
1073                 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1074         }
1075
1076         cli_setpid(&cli, 1);
1077
1078         if (!cli_close(&cli, fnum1)) {
1079                 printf("close1 failed (%s)\n", cli_errstr(&cli));
1080                 return False;
1081         }
1082
1083         if (!cli_close(&cli, fnum2)) {
1084                 printf("close2 failed (%s)\n", cli_errstr(&cli));
1085                 return False;
1086         }
1087
1088         if (!cli_close(&cli, fnum3)) {
1089                 printf("close3 failed (%s)\n", cli_errstr(&cli));
1090                 return False;
1091         }
1092
1093         if (!torture_close_connection(&cli)) {
1094                 correct = False;
1095         }
1096
1097         printf("locktest2 finished\n");
1098
1099         return correct;
1100 }
1101
1102
1103 /*
1104   This test checks that 
1105
1106   1) the server supports the full offset range in lock requests
1107 */
1108 static BOOL run_locktest3(int dummy)
1109 {
1110         static struct cli_state cli1, cli2;
1111         char *fname = "\\lockt3.lck";
1112         int fnum1, fnum2, i;
1113         uint32 offset;
1114         BOOL correct = True;
1115
1116 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1117
1118         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1119                 return False;
1120         }
1121         cli_sockopt(&cli1, sockops);
1122         cli_sockopt(&cli2, sockops);
1123
1124         printf("starting locktest3\n");
1125
1126         cli_unlink(&cli1, fname);
1127
1128         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1129         if (fnum1 == -1) {
1130                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1131                 return False;
1132         }
1133         fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1134         if (fnum2 == -1) {
1135                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
1136                 return False;
1137         }
1138
1139         for (offset=i=0;i<torture_numops;i++) {
1140                 NEXT_OFFSET;
1141                 if (!cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1142                         printf("lock1 %d failed (%s)\n", 
1143                                i,
1144                                cli_errstr(&cli1));
1145                         return False;
1146                 }
1147
1148                 if (!cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1149                         printf("lock2 %d failed (%s)\n", 
1150                                i,
1151                                cli_errstr(&cli1));
1152                         return False;
1153                 }
1154         }
1155
1156         for (offset=i=0;i<torture_numops;i++) {
1157                 NEXT_OFFSET;
1158
1159                 if (cli_lock(&cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1160                         printf("error: lock1 %d succeeded!\n", i);
1161                         return False;
1162                 }
1163
1164                 if (cli_lock(&cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1165                         printf("error: lock2 %d succeeded!\n", i);
1166                         return False;
1167                 }
1168
1169                 if (cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1170                         printf("error: lock3 %d succeeded!\n", i);
1171                         return False;
1172                 }
1173
1174                 if (cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1175                         printf("error: lock4 %d succeeded!\n", i);
1176                         return False;
1177                 }
1178         }
1179
1180         for (offset=i=0;i<torture_numops;i++) {
1181                 NEXT_OFFSET;
1182
1183                 if (!cli_unlock(&cli1, fnum1, offset-1, 1)) {
1184                         printf("unlock1 %d failed (%s)\n", 
1185                                i,
1186                                cli_errstr(&cli1));
1187                         return False;
1188                 }
1189
1190                 if (!cli_unlock(&cli2, fnum2, offset-2, 1)) {
1191                         printf("unlock2 %d failed (%s)\n", 
1192                                i,
1193                                cli_errstr(&cli1));
1194                         return False;
1195                 }
1196         }
1197
1198         if (!cli_close(&cli1, fnum1)) {
1199                 printf("close1 failed (%s)\n", cli_errstr(&cli1));
1200                 return False;
1201         }
1202
1203         if (!cli_close(&cli2, fnum2)) {
1204                 printf("close2 failed (%s)\n", cli_errstr(&cli2));
1205                 return False;
1206         }
1207
1208         if (!cli_unlink(&cli1, fname)) {
1209                 printf("unlink failed (%s)\n", cli_errstr(&cli1));
1210                 return False;
1211         }
1212
1213         if (!torture_close_connection(&cli1)) {
1214                 correct = False;
1215         }
1216         
1217         if (!torture_close_connection(&cli2)) {
1218                 correct = False;
1219         }
1220
1221         printf("finished locktest3\n");
1222
1223         return correct;
1224 }
1225
1226 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1227         printf("** "); correct = False; \
1228         }
1229
1230 /*
1231   looks at overlapping locks
1232 */
1233 static BOOL run_locktest4(int dummy)
1234 {
1235         static struct cli_state cli1, cli2;
1236         char *fname = "\\lockt4.lck";
1237         int fnum1, fnum2, f;
1238         BOOL ret;
1239         char buf[1000];
1240         BOOL correct = True;
1241
1242         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1243                 return False;
1244         }
1245
1246         cli_sockopt(&cli1, sockops);
1247         cli_sockopt(&cli2, sockops);
1248
1249         printf("starting locktest4\n");
1250
1251         cli_unlink(&cli1, fname);
1252
1253         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1254         fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1255
1256         memset(buf, 0, sizeof(buf));
1257
1258         if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1259                 printf("Failed to create file\n");
1260                 correct = False;
1261                 goto fail;
1262         }
1263
1264         ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1265               cli_lock(&cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1266         EXPECTED(ret, False);
1267         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1268             
1269         ret = cli_lock(&cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1270               cli_lock(&cli1, fnum1, 12, 4, 0, READ_LOCK);
1271         EXPECTED(ret, True);
1272         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1273
1274         ret = cli_lock(&cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1275               cli_lock(&cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1276         EXPECTED(ret, False);
1277         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1278             
1279         ret = cli_lock(&cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1280               cli_lock(&cli2, fnum2, 32, 4, 0, READ_LOCK);
1281         EXPECTED(ret, True);
1282         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1283         
1284         ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1285               (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1286         EXPECTED(ret, False);
1287         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1288             
1289         ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1290               (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 52, 4, 0, READ_LOCK));
1291         EXPECTED(ret, True);
1292         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1293
1294         ret = cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1295               cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK);
1296         EXPECTED(ret, True);
1297         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1298
1299         ret = cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1300               cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1301         EXPECTED(ret, False);
1302         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1303
1304         ret = cli_lock(&cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1305               cli_lock(&cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1306         EXPECTED(ret, False);
1307         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1308
1309         ret = cli_lock(&cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1310               cli_lock(&cli1, fnum1, 90, 4, 0, READ_LOCK);
1311         EXPECTED(ret, True);
1312         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1313
1314         ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1315               (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 100, 4, 0, READ_LOCK));
1316         EXPECTED(ret, False);
1317         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1318
1319         ret = cli_lock(&cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1320               cli_lock(&cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1321               cli_unlock(&cli1, fnum1, 110, 6);
1322         EXPECTED(ret, False);
1323         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1324
1325
1326         ret = cli_lock(&cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1327               (cli_read(&cli2, fnum2, buf, 120, 4) == 4);
1328         EXPECTED(ret, False);
1329         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1330
1331         ret = cli_lock(&cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1332               (cli_write(&cli2, fnum2, 0, buf, 130, 4) == 4);
1333         EXPECTED(ret, False);
1334         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1335
1336
1337         ret = cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1338               cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1339               cli_unlock(&cli1, fnum1, 140, 4) &&
1340               cli_unlock(&cli1, fnum1, 140, 4);
1341         EXPECTED(ret, True);
1342         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1343
1344
1345         ret = cli_lock(&cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1346               cli_lock(&cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1347               cli_unlock(&cli1, fnum1, 150, 4) &&
1348               (cli_read(&cli2, fnum2, buf, 150, 4) == 4) &&
1349               !(cli_write(&cli2, fnum2, 0, buf, 150, 4) == 4) &&
1350               cli_unlock(&cli1, fnum1, 150, 4);
1351         EXPECTED(ret, True);
1352         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1353
1354         ret = cli_lock(&cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1355               cli_unlock(&cli1, fnum1, 160, 4) &&
1356               (cli_write(&cli2, fnum2, 0, buf, 160, 4) == 4) &&         
1357               (cli_read(&cli2, fnum2, buf, 160, 4) == 4);               
1358         EXPECTED(ret, True);
1359         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1360
1361         ret = cli_lock(&cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1362               cli_unlock(&cli1, fnum1, 170, 4) &&
1363               (cli_write(&cli2, fnum2, 0, buf, 170, 4) == 4) &&         
1364               (cli_read(&cli2, fnum2, buf, 170, 4) == 4);               
1365         EXPECTED(ret, True);
1366         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1367
1368         ret = cli_lock(&cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1369               cli_lock(&cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1370               cli_unlock(&cli1, fnum1, 190, 4) &&
1371               !(cli_write(&cli2, fnum2, 0, buf, 190, 4) == 4) &&                
1372               (cli_read(&cli2, fnum2, buf, 190, 4) == 4);               
1373         EXPECTED(ret, True);
1374         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1375
1376         cli_close(&cli1, fnum1);
1377         cli_close(&cli2, fnum2);
1378         fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1379         f = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1380         ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1381               cli_lock(&cli1, f, 0, 1, 0, READ_LOCK) &&
1382               cli_close(&cli1, fnum1) &&
1383               ((fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1384               cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1385         cli_close(&cli1, f);
1386         cli_close(&cli1, fnum1);
1387         EXPECTED(ret, True);
1388         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1389
1390  fail:
1391         cli_close(&cli1, fnum1);
1392         cli_close(&cli2, fnum2);
1393         cli_unlink(&cli1, fname);
1394         torture_close_connection(&cli1);
1395         torture_close_connection(&cli2);
1396
1397         printf("finished locktest4\n");
1398         return correct;
1399 }
1400
1401 /*
1402   looks at lock upgrade/downgrade.
1403 */
1404 static BOOL run_locktest5(int dummy)
1405 {
1406         static struct cli_state cli1, cli2;
1407         char *fname = "\\lockt5.lck";
1408         int fnum1, fnum2, fnum3;
1409         BOOL ret;
1410         char buf[1000];
1411         BOOL correct = True;
1412
1413         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1414                 return False;
1415         }
1416
1417         cli_sockopt(&cli1, sockops);
1418         cli_sockopt(&cli2, sockops);
1419
1420         printf("starting locktest5\n");
1421
1422         cli_unlink(&cli1, fname);
1423
1424         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1425         fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1426         fnum3 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1427
1428         memset(buf, 0, sizeof(buf));
1429
1430         if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1431                 printf("Failed to create file\n");
1432                 correct = False;
1433                 goto fail;
1434         }
1435
1436         /* Check for NT bug... */
1437         ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1438                   cli_lock(&cli1, fnum3, 0, 1, 0, READ_LOCK);
1439         cli_close(&cli1, fnum1);
1440         fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1441         ret = cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1442         EXPECTED(ret, True);
1443         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1444         cli_close(&cli1, fnum1);
1445         fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1446         cli_unlock(&cli1, fnum3, 0, 1);
1447
1448         ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1449               cli_lock(&cli1, fnum1, 1, 1, 0, READ_LOCK);
1450         EXPECTED(ret, True);
1451         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1452
1453         ret = cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1454         EXPECTED(ret, False);
1455
1456         printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1457
1458         /* Unlock the process 2 lock. */
1459         cli_unlock(&cli2, fnum2, 0, 4);
1460
1461         ret = cli_lock(&cli1, fnum3, 0, 4, 0, READ_LOCK);
1462         EXPECTED(ret, False);
1463
1464         printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1465
1466         /* Unlock the process 1 fnum3 lock. */
1467         cli_unlock(&cli1, fnum3, 0, 4);
1468
1469         /* Stack 2 more locks here. */
1470         ret = cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1471                   cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK);
1472
1473         EXPECTED(ret, True);
1474         printf("the same process %s stack read locks\n", ret?"can":"cannot");
1475
1476         /* Unlock the first process lock, then check this was the WRITE lock that was
1477                 removed. */
1478
1479         ret = cli_unlock(&cli1, fnum1, 0, 4) &&
1480                         cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1481
1482         EXPECTED(ret, True);
1483         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1484
1485         /* Unlock the process 2 lock. */
1486         cli_unlock(&cli2, fnum2, 0, 4);
1487
1488         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1489
1490         ret = cli_unlock(&cli1, fnum1, 1, 1) &&
1491                   cli_unlock(&cli1, fnum1, 0, 4) &&
1492                   cli_unlock(&cli1, fnum1, 0, 4);
1493
1494         EXPECTED(ret, True);
1495         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
1496
1497         /* Ensure the next unlock fails. */
1498         ret = cli_unlock(&cli1, fnum1, 0, 4);
1499         EXPECTED(ret, False);
1500         printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
1501
1502         /* Ensure connection 2 can get a write lock. */
1503         ret = cli_lock(&cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1504         EXPECTED(ret, True);
1505
1506         printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1507
1508
1509  fail:
1510         cli_close(&cli1, fnum1);
1511         cli_close(&cli2, fnum2);
1512         cli_unlink(&cli1, fname);
1513         if (!torture_close_connection(&cli1)) {
1514                 correct = False;
1515         }
1516         if (!torture_close_connection(&cli2)) {
1517                 correct = False;
1518         }
1519
1520         printf("finished locktest5\n");
1521        
1522         return correct;
1523 }
1524
1525 /*
1526   tries the unusual lockingX locktype bits
1527 */
1528 static BOOL run_locktest6(int dummy)
1529 {
1530         static struct cli_state cli;
1531         char *fname[1] = { "\\lock6.txt" };
1532         int i;
1533         int fnum;
1534         NTSTATUS status;
1535
1536         if (!torture_open_connection(&cli)) {
1537                 return False;
1538         }
1539
1540         cli_sockopt(&cli, sockops);
1541
1542         printf("starting locktest6\n");
1543
1544         for (i=0;i<1;i++) {
1545                 printf("Testing %s\n", fname[i]);
1546
1547                 cli_unlink(&cli, fname[i]);
1548
1549                 fnum = cli_open(&cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1550                 status = cli_locktype(&cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1551                 cli_close(&cli, fnum);
1552                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1553
1554                 fnum = cli_open(&cli, fname[i], O_RDWR, DENY_NONE);
1555                 status = cli_locktype(&cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1556                 cli_close(&cli, fnum);
1557                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1558
1559                 cli_unlink(&cli, fname[i]);
1560         }
1561
1562         torture_close_connection(&cli);
1563
1564         printf("finished locktest6\n");
1565         return True;
1566 }
1567
1568 /*
1569 test whether fnums and tids open on one VC are available on another (a major
1570 security hole)
1571 */
1572 static BOOL run_fdpasstest(int dummy)
1573 {
1574         static struct cli_state cli1, cli2, cli3;
1575         char *fname = "\\fdpass.tst";
1576         int fnum1;
1577         pstring buf;
1578
1579         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1580                 return False;
1581         }
1582         cli_sockopt(&cli1, sockops);
1583         cli_sockopt(&cli2, sockops);
1584
1585         printf("starting fdpasstest\n");
1586
1587         cli_unlink(&cli1, fname);
1588
1589         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1590         if (fnum1 == -1) {
1591                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1592                 return False;
1593         }
1594
1595         if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
1596                 printf("write failed (%s)\n", cli_errstr(&cli1));
1597                 return False;
1598         }
1599
1600         cli3 = cli2;
1601         cli3.vuid = cli1.vuid;
1602         cli3.cnum = cli1.cnum;
1603         cli3.pid = cli1.pid;
1604
1605         if (cli_read(&cli3, fnum1, buf, 0, 13) == 13) {
1606                 printf("read succeeded! nasty security hole [%s]\n",
1607                        buf);
1608                 return False;
1609         }
1610
1611         cli_close(&cli1, fnum1);
1612         cli_unlink(&cli1, fname);
1613
1614         torture_close_connection(&cli1);
1615         torture_close_connection(&cli2);
1616
1617         printf("finished fdpasstest\n");
1618         return True;
1619 }
1620
1621
1622 /*
1623   This test checks that 
1624
1625   1) the server does not allow an unlink on a file that is open
1626 */
1627 static BOOL run_unlinktest(int dummy)
1628 {
1629         static struct cli_state cli;
1630         char *fname = "\\unlink.tst";
1631         int fnum;
1632         BOOL correct = True;
1633
1634         if (!torture_open_connection(&cli)) {
1635                 return False;
1636         }
1637
1638         cli_sockopt(&cli, sockops);
1639
1640         printf("starting unlink test\n");
1641
1642         cli_unlink(&cli, fname);
1643
1644         cli_setpid(&cli, 1);
1645
1646         fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1647         if (fnum == -1) {
1648                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1649                 return False;
1650         }
1651
1652         if (cli_unlink(&cli, fname)) {
1653                 printf("error: server allowed unlink on an open file\n");
1654                 correct = False;
1655         } else {
1656                 correct = check_error(__LINE__, &cli, ERRDOS, ERRbadshare, 
1657                                       NT_STATUS_SHARING_VIOLATION);
1658         }
1659
1660         cli_close(&cli, fnum);
1661         cli_unlink(&cli, fname);
1662
1663         if (!torture_close_connection(&cli)) {
1664                 correct = False;
1665         }
1666
1667         printf("unlink test finished\n");
1668         
1669         return correct;
1670 }
1671
1672
1673 /*
1674 test how many open files this server supports on the one socket
1675 */
1676 static BOOL run_maxfidtest(int dummy)
1677 {
1678         static struct cli_state cli;
1679         char *template = "\\maxfid.%d.%d";
1680         fstring fname;
1681         int fnums[0x11000], i;
1682         int retries=4;
1683         BOOL correct = True;
1684
1685         cli = current_cli;
1686
1687         if (retries <= 0) {
1688                 printf("failed to connect\n");
1689                 return False;
1690         }
1691
1692         cli_sockopt(&cli, sockops);
1693
1694         for (i=0; i<0x11000; i++) {
1695                 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1696                 if ((fnums[i] = cli_open(&cli, fname, 
1697                                         O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1698                     -1) {
1699                         printf("open of %s failed (%s)\n", 
1700                                fname, cli_errstr(&cli));
1701                         printf("maximum fnum is %d\n", i);
1702                         break;
1703                 }
1704                 printf("%6d\r", i);
1705         }
1706         printf("%6d\n", i);
1707         i--;
1708
1709         printf("cleaning up\n");
1710         for (;i>=0;i--) {
1711                 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1712                 cli_close(&cli, fnums[i]);
1713                 if (!cli_unlink(&cli, fname)) {
1714                         printf("unlink of %s failed (%s)\n", 
1715                                fname, cli_errstr(&cli));
1716                         correct = False;
1717                 }
1718                 printf("%6d\r", i);
1719         }
1720         printf("%6d\n", 0);
1721
1722         printf("maxfid test finished\n");
1723         if (!torture_close_connection(&cli)) {
1724                 correct = False;
1725         }
1726         return correct;
1727 }
1728
1729 /* generate a random buffer */
1730 static void rand_buf(char *buf, int len)
1731 {
1732         while (len--) {
1733                 *buf = (char)sys_random();
1734                 buf++;
1735         }
1736 }
1737
1738 /* send smb negprot commands, not reading the response */
1739 static BOOL run_negprot_nowait(int dummy)
1740 {
1741         int i;
1742         static struct cli_state cli;
1743         BOOL correct = True;
1744
1745         printf("starting negprot nowait test\n");
1746
1747         if (!open_nbt_connection(&cli)) {
1748                 return False;
1749         }
1750
1751         for (i=0;i<50000;i++) {
1752                 cli_negprot_send(&cli);
1753         }
1754
1755         if (!torture_close_connection(&cli)) {
1756                 correct = False;
1757         }
1758
1759         printf("finished negprot nowait test\n");
1760
1761         return correct;
1762 }
1763
1764
1765 /* send random IPC commands */
1766 static BOOL run_randomipc(int dummy)
1767 {
1768         char *rparam = NULL;
1769         char *rdata = NULL;
1770         int rdrcnt,rprcnt;
1771         pstring param;
1772         int api, param_len, i;
1773         static struct cli_state cli;
1774         BOOL correct = True;
1775         int count = 50000;
1776
1777         printf("starting random ipc test\n");
1778
1779         if (!torture_open_connection(&cli)) {
1780                 return False;
1781         }
1782
1783         for (i=0;i<count;i++) {
1784                 api = sys_random() % 500;
1785                 param_len = (sys_random() % 64);
1786
1787                 rand_buf(param, param_len);
1788   
1789                 SSVAL(param,0,api); 
1790
1791                 cli_api(&cli, 
1792                         param, param_len, 8,  
1793                         NULL, 0, BUFFER_SIZE, 
1794                         &rparam, &rprcnt,     
1795                         &rdata, &rdrcnt);
1796                 if (i % 100 == 0) {
1797                         printf("%d/%d\r", i,count);
1798                 }
1799         }
1800         printf("%d/%d\n", i, count);
1801
1802         if (!torture_close_connection(&cli)) {
1803                 correct = False;
1804         }
1805
1806         printf("finished random ipc test\n");
1807
1808         return correct;
1809 }
1810
1811
1812
1813 static void browse_callback(const char *sname, uint32 stype, 
1814                             const char *comment, void *state)
1815 {
1816         printf("\t%20.20s %08x %s\n", sname, stype, comment);
1817 }
1818
1819
1820
1821 /*
1822   This test checks the browse list code
1823
1824 */
1825 static BOOL run_browsetest(int dummy)
1826 {
1827         static struct cli_state cli;
1828         BOOL correct = True;
1829
1830         printf("starting browse test\n");
1831
1832         if (!torture_open_connection(&cli)) {
1833                 return False;
1834         }
1835
1836         printf("domain list:\n");
1837         cli_NetServerEnum(&cli, cli.server_domain, 
1838                           SV_TYPE_DOMAIN_ENUM,
1839                           browse_callback, NULL);
1840
1841         printf("machine list:\n");
1842         cli_NetServerEnum(&cli, cli.server_domain, 
1843                           SV_TYPE_ALL,
1844                           browse_callback, NULL);
1845
1846         if (!torture_close_connection(&cli)) {
1847                 correct = False;
1848         }
1849
1850         printf("browse test finished\n");
1851
1852         return correct;
1853
1854 }
1855
1856
1857 /*
1858   This checks how the getatr calls works
1859 */
1860 static BOOL run_attrtest(int dummy)
1861 {
1862         static struct cli_state cli;
1863         int fnum;
1864         time_t t, t2;
1865         char *fname = "\\attrib.tst";
1866         BOOL correct = True;
1867
1868         printf("starting attrib test\n");
1869
1870         if (!torture_open_connection(&cli)) {
1871                 return False;
1872         }
1873
1874         cli_unlink(&cli, fname);
1875         fnum = cli_open(&cli, fname, 
1876                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1877         cli_close(&cli, fnum);
1878         if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1879                 printf("getatr failed (%s)\n", cli_errstr(&cli));
1880                 correct = False;
1881         }
1882
1883         if (abs(t - time(NULL)) > 60*60*24*10) {
1884                 printf("ERROR: SMBgetatr bug. time is %s",
1885                        ctime(&t));
1886                 t = time(NULL);
1887                 correct = True;
1888         }
1889
1890         t2 = t-60*60*24; /* 1 day ago */
1891
1892         if (!cli_setatr(&cli, fname, 0, t2)) {
1893                 printf("setatr failed (%s)\n", cli_errstr(&cli));
1894                 correct = True;
1895         }
1896
1897         if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1898                 printf("getatr failed (%s)\n", cli_errstr(&cli));
1899                 correct = True;
1900         }
1901
1902         if (t != t2) {
1903                 printf("ERROR: getatr/setatr bug. times are\n%s",
1904                        ctime(&t));
1905                 printf("%s", ctime(&t2));
1906                 correct = True;
1907         }
1908
1909         cli_unlink(&cli, fname);
1910
1911         if (!torture_close_connection(&cli)) {
1912                 correct = False;
1913         }
1914
1915         printf("attrib test finished\n");
1916
1917         return correct;
1918 }
1919
1920
1921 /*
1922   This checks a couple of trans2 calls
1923 */
1924 static BOOL run_trans2test(int dummy)
1925 {
1926         static struct cli_state cli;
1927         int fnum;
1928         size_t size;
1929         time_t c_time, a_time, m_time, w_time, m_time2;
1930         char *fname = "\\trans2.tst";
1931         char *dname = "\\trans2";
1932         char *fname2 = "\\trans2\\trans2.tst";
1933         pstring pname;
1934         BOOL correct = True;
1935
1936         printf("starting trans2 test\n");
1937
1938         if (!torture_open_connection(&cli)) {
1939                 return False;
1940         }
1941
1942         cli_unlink(&cli, fname);
1943         fnum = cli_open(&cli, fname, 
1944                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1945         if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
1946                            NULL, NULL)) {
1947                 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
1948                 correct = False;
1949         }
1950
1951         if (!cli_qfilename(&cli, fnum, pname)) {
1952                 printf("ERROR: qfilename failed (%s)\n", cli_errstr(&cli));
1953                 correct = False;
1954         }
1955
1956         if (strcmp(pname, fname)) {
1957                 printf("qfilename gave different name? [%s] [%s]\n",
1958                        fname, pname);
1959                 correct = False;
1960         }
1961
1962         cli_close(&cli, fnum);
1963
1964         sleep(2);
1965
1966         cli_unlink(&cli, fname);
1967         fnum = cli_open(&cli, fname, 
1968                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1969         if (fnum == -1) {
1970                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1971                 return False;
1972         }
1973         cli_close(&cli, fnum);
1974
1975         if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
1976                 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
1977                 correct = False;
1978         } else {
1979                 if (c_time != m_time) {
1980                         printf("create time=%s", ctime(&c_time));
1981                         printf("modify time=%s", ctime(&m_time));
1982                         printf("This system appears to have sticky create times\n");
1983                         correct = False;
1984                 }
1985                 if (a_time % (60*60) == 0) {
1986                         printf("access time=%s", ctime(&a_time));
1987                         printf("This system appears to set a midnight access time\n");
1988                         correct = False;
1989                 }
1990
1991                 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1992                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1993                         correct = False;
1994                 }
1995         }
1996
1997
1998         cli_unlink(&cli, fname);
1999         fnum = cli_open(&cli, fname, 
2000                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2001         cli_close(&cli, fnum);
2002         if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time, 
2003                             &w_time, &size, NULL, NULL)) {
2004                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2005                 correct = False;
2006         } else {
2007                 if (w_time < 60*60*24*2) {
2008                         printf("write time=%s", ctime(&w_time));
2009                         printf("This system appears to set a initial 0 write time\n");
2010                         correct = False;
2011                 }
2012         }
2013
2014         cli_unlink(&cli, fname);
2015
2016
2017         /* check if the server updates the directory modification time
2018            when creating a new file */
2019         if (!cli_mkdir(&cli, dname)) {
2020                 printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
2021                 correct = False;
2022         }
2023         sleep(3);
2024         if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time, 
2025                             &w_time, &size, NULL, NULL)) {
2026                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2027                 correct = False;
2028         }
2029
2030         fnum = cli_open(&cli, fname2, 
2031                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2032         cli_write(&cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
2033         cli_close(&cli, fnum);
2034         if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2, 
2035                             &w_time, &size, NULL, NULL)) {
2036                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2037                 correct = False;
2038         } else {
2039                 if (m_time2 == m_time) {
2040                         printf("This system does not update directory modification times\n");
2041                         correct = False;
2042                 }
2043         }
2044         cli_unlink(&cli, fname2);
2045         cli_rmdir(&cli, dname);
2046
2047         if (!torture_close_connection(&cli)) {
2048                 correct = False;
2049         }
2050
2051         printf("trans2 test finished\n");
2052
2053         return correct;
2054 }
2055
2056 /*
2057   This checks new W2K calls.
2058 */
2059
2060 static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
2061 {
2062         char buf[4096];
2063         BOOL correct = True;
2064
2065         memset(buf, 0xff, sizeof(buf));
2066
2067         if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
2068                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2069                 correct = False;
2070         } else {
2071                 printf("qfileinfo: level %d\n", level);
2072                 dump_data(0, buf, 256);
2073                 printf("\n");
2074         }
2075         return correct;
2076 }
2077
2078 static BOOL run_w2ktest(int dummy)
2079 {
2080         static struct cli_state cli;
2081         int fnum;
2082         char *fname = "\\w2ktest\\w2k.tst";
2083         int level;
2084         BOOL correct = True;
2085
2086         printf("starting w2k test\n");
2087
2088         if (!torture_open_connection(&cli)) {
2089                 return False;
2090         }
2091
2092         fnum = cli_open(&cli, fname, 
2093                         O_RDWR | O_CREAT , DENY_NONE);
2094
2095         for (level = 1004; level < 1040; level++) {
2096                 new_trans(&cli, fnum, level);
2097         }
2098
2099         cli_close(&cli, fnum);
2100
2101         if (!torture_close_connection(&cli)) {
2102                 correct = False;
2103         }
2104
2105         printf("w2k test finished\n");
2106         
2107         return correct;
2108 }
2109
2110
2111 /*
2112   this is a harness for some oplock tests
2113  */
2114 static BOOL run_oplock1(int dummy)
2115 {
2116         static struct cli_state cli1;
2117         char *fname = "\\lockt1.lck";
2118         int fnum1;
2119         BOOL correct = True;
2120
2121         printf("starting oplock test 1\n");
2122
2123         if (!torture_open_connection(&cli1)) {
2124                 return False;
2125         }
2126
2127         cli_unlink(&cli1, fname);
2128
2129         cli_sockopt(&cli1, sockops);
2130
2131         cli1.use_oplocks = True;
2132
2133         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2134         if (fnum1 == -1) {
2135                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2136                 return False;
2137         }
2138
2139         cli1.use_oplocks = False;
2140
2141         cli_unlink(&cli1, fname);
2142         cli_unlink(&cli1, fname);
2143
2144         if (!cli_close(&cli1, fnum1)) {
2145                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2146                 return False;
2147         }
2148
2149         if (!cli_unlink(&cli1, fname)) {
2150                 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2151                 return False;
2152         }
2153
2154         if (!torture_close_connection(&cli1)) {
2155                 correct = False;
2156         }
2157
2158         printf("finished oplock test 1\n");
2159
2160         return correct;
2161 }
2162
2163 static BOOL run_oplock2(int dummy)
2164 {
2165         static struct cli_state cli1, cli2;
2166         char *fname = "\\lockt2.lck";
2167         int fnum1, fnum2;
2168         int saved_use_oplocks = use_oplocks;
2169         char buf[4];
2170         BOOL correct = True;
2171         volatile BOOL *shared_correct;
2172
2173         shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2174         *shared_correct = True;
2175
2176         use_level_II_oplocks = True;
2177         use_oplocks = True;
2178
2179         printf("starting oplock test 2\n");
2180
2181         if (!torture_open_connection(&cli1)) {
2182                 use_level_II_oplocks = False;
2183                 use_oplocks = saved_use_oplocks;
2184                 return False;
2185         }
2186
2187         cli1.use_oplocks = True;
2188         cli1.use_level_II_oplocks = True;
2189
2190         if (!torture_open_connection(&cli2)) {
2191                 use_level_II_oplocks = False;
2192                 use_oplocks = saved_use_oplocks;
2193                 return False;
2194         }
2195
2196         cli2.use_oplocks = True;
2197         cli2.use_level_II_oplocks = True;
2198
2199         cli_unlink(&cli1, fname);
2200
2201         cli_sockopt(&cli1, sockops);
2202         cli_sockopt(&cli2, sockops);
2203
2204         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2205         if (fnum1 == -1) {
2206                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2207                 return False;
2208         }
2209
2210         /* Don't need the globals any more. */
2211         use_level_II_oplocks = False;
2212         use_oplocks = saved_use_oplocks;
2213
2214         if (fork() == 0) {
2215                 /* Child code */
2216                 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
2217                 if (fnum2 == -1) {
2218                         printf("second open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2219                         *shared_correct = False;
2220                         exit(0);
2221                 }
2222
2223                 sleep(2);
2224
2225                 if (!cli_close(&cli2, fnum2)) {
2226                         printf("close2 failed (%s)\n", cli_errstr(&cli1));
2227                         *shared_correct = False;
2228                 }
2229
2230                 exit(0);
2231         }
2232
2233         sleep(2);
2234
2235         /* Ensure cli1 processes the break. */
2236
2237         if (cli_read(&cli1, fnum1, buf, 0, 4) != 4) {
2238                 printf("read on fnum1 failed (%s)\n", cli_errstr(&cli1));
2239                 correct = False;
2240         }
2241
2242         /* Should now be at level II. */
2243         /* Test if sending a write locks causes a break to none. */
2244
2245         if (!cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2246                 printf("lock failed (%s)\n", cli_errstr(&cli1));
2247                 correct = False;
2248         }
2249
2250         cli_unlock(&cli1, fnum1, 0, 4);
2251
2252         sleep(2);
2253
2254         if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2255                 printf("lock failed (%s)\n", cli_errstr(&cli1));
2256                 correct = False;
2257         }
2258
2259         cli_unlock(&cli1, fnum1, 0, 4);
2260
2261         sleep(2);
2262
2263         cli_read(&cli1, fnum1, buf, 0, 4);
2264
2265 #if 0
2266         if (cli_write(&cli1, fnum1, 0, buf, 0, 4) != 4) {
2267                 printf("write on fnum1 failed (%s)\n", cli_errstr(&cli1));
2268                 correct = False;
2269         }
2270 #endif
2271
2272         if (!cli_close(&cli1, fnum1)) {
2273                 printf("close1 failed (%s)\n", cli_errstr(&cli1));
2274                 correct = False;
2275         }
2276
2277         sleep(4);
2278
2279         if (!cli_unlink(&cli1, fname)) {
2280                 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2281                 correct = False;
2282         }
2283
2284         if (!torture_close_connection(&cli1)) {
2285                 correct = False;
2286         }
2287
2288         if (!*shared_correct) {
2289                 correct = False;
2290         }
2291
2292         printf("finished oplock test 2\n");
2293
2294         return correct;
2295 }
2296
2297 /* handler for oplock 3 tests */
2298 static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2299 {
2300         printf("got oplock break fnum=%d level=%d\n",
2301                fnum, level);
2302         return cli_oplock_ack(cli, fnum, level);
2303 }
2304
2305 static BOOL run_oplock3(int dummy)
2306 {
2307         static struct cli_state cli;
2308         char *fname = "\\oplockt3.dat";
2309         int fnum;
2310         char buf[4] = "abcd";
2311         BOOL correct = True;
2312         volatile BOOL *shared_correct;
2313
2314         shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2315         *shared_correct = True;
2316
2317         printf("starting oplock test 3\n");
2318
2319         if (fork() == 0) {
2320                 /* Child code */
2321                 use_oplocks = True;
2322                 use_level_II_oplocks = True;
2323                 if (!torture_open_connection(&cli)) {
2324                         *shared_correct = False;
2325                         exit(0);
2326                 } 
2327                 sleep(2);
2328                 /* try to trigger a oplock break in parent */
2329                 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2330                 cli_write(&cli, fnum, 0, buf, 0, 4);
2331                 exit(0);
2332         }
2333
2334         /* parent code */
2335         use_oplocks = True;
2336         use_level_II_oplocks = True;
2337         if (!torture_open_connection(&cli)) { 
2338                 return False;
2339         }
2340         cli_oplock_handler(&cli, oplock3_handler);
2341         fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2342         cli_write(&cli, fnum, 0, buf, 0, 4);
2343         cli_close(&cli, fnum);
2344         fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2345         cli.timeout = 20000;
2346         cli_receive_smb(&cli);
2347         printf("finished oplock test 3\n");
2348
2349         return (correct && *shared_correct);
2350
2351 /* What are we looking for here?  What's sucess and what's FAILURE? */
2352 }
2353
2354
2355
2356 /*
2357   Test delete on close semantics.
2358  */
2359 static BOOL run_deletetest(int dummy)
2360 {
2361         static struct cli_state cli1;
2362         static struct cli_state cli2;
2363         char *fname = "\\delete.file";
2364         int fnum1 = -1;
2365         int fnum2 = -1;
2366         BOOL correct = True;
2367         
2368         printf("starting delete test\n");
2369         
2370         ZERO_STRUCT(cli1);
2371         ZERO_STRUCT(cli2);
2372
2373         if (!torture_open_connection(&cli1)) {
2374                 return False;
2375         }
2376         
2377         cli_sockopt(&cli1, sockops);
2378
2379         /* Test 1 - this should *NOT* delete the file on close. */
2380         
2381         cli_setatr(&cli1, fname, 0, 0);
2382         cli_unlink(&cli1, fname);
2383         
2384         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2385                                    FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 
2386                                    DELETE_ON_CLOSE_FLAG);
2387         
2388         if (fnum1 == -1) {
2389                 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2390                 correct = False;
2391                 goto fail;
2392         }
2393         
2394         if (!cli_close(&cli1, fnum1)) {
2395                 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2396                 correct = False;
2397                 goto fail;
2398         }
2399
2400         fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
2401         if (fnum1 == -1) {
2402                 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2403                 correct = False;
2404                 goto fail;
2405         }
2406         
2407         if (!cli_close(&cli1, fnum1)) {
2408                 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2409                 correct = False;
2410                 goto fail;
2411         }
2412         
2413         printf("first delete on close test succeeded.\n");
2414         
2415         /* Test 2 - this should delete the file on close. */
2416         
2417         cli_setatr(&cli1, fname, 0, 0);
2418         cli_unlink(&cli1, fname);
2419         
2420         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS,
2421                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, 
2422                                    FILE_OVERWRITE_IF, 0);
2423         
2424         if (fnum1 == -1) {
2425                 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2426                 correct = False;
2427                 goto fail;
2428         }
2429         
2430         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2431                 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2432                 correct = False;
2433                 goto fail;
2434         }
2435         
2436         if (!cli_close(&cli1, fnum1)) {
2437                 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2438                 correct = False;
2439                 goto fail;
2440         }
2441         
2442         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2443         if (fnum1 != -1) {
2444                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2445                 if (!cli_close(&cli1, fnum1)) {
2446                         printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2447                         correct = False;
2448                         goto fail;
2449                 }
2450                 cli_unlink(&cli1, fname);
2451         } else
2452                 printf("second delete on close test succeeded.\n");
2453         
2454         /* Test 3 - ... */
2455         cli_setatr(&cli1, fname, 0, 0);
2456         cli_unlink(&cli1, fname);
2457
2458         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2459                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2460
2461         if (fnum1 == -1) {
2462                 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2463                 correct = False;
2464                 goto fail;
2465         }
2466
2467         /* This should fail with a sharing violation - open for delete is only compatible
2468            with SHARE_DELETE. */
2469
2470         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2471                         FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0);
2472
2473         if (fnum2 != -1) {
2474                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
2475                 correct = False;
2476                 goto fail;
2477         }
2478
2479         /* This should succeed. */
2480
2481         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2482                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2483
2484         if (fnum2 == -1) {
2485                 printf("[3] open  - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2486                 correct = False;
2487                 goto fail;
2488         }
2489
2490         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2491                 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2492                 correct = False;
2493                 goto fail;
2494         }
2495         
2496         if (!cli_close(&cli1, fnum1)) {
2497                 printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1));
2498                 correct = False;
2499                 goto fail;
2500         }
2501         
2502         if (!cli_close(&cli1, fnum2)) {
2503                 printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1));
2504                 correct = False;
2505                 goto fail;
2506         }
2507         
2508         /* This should fail - file should no longer be there. */
2509
2510         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2511         if (fnum1 != -1) {
2512                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2513                 if (!cli_close(&cli1, fnum1)) {
2514                         printf("[3] close failed (%s)\n", cli_errstr(&cli1));
2515                 }
2516                 cli_unlink(&cli1, fname);
2517                 correct = False;
2518                 goto fail;
2519         } else
2520                 printf("third delete on close test succeeded.\n");
2521
2522         /* Test 4 ... */
2523         cli_setatr(&cli1, fname, 0, 0);
2524         cli_unlink(&cli1, fname);
2525
2526         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2527                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2528                                                                 
2529         if (fnum1 == -1) {
2530                 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2531                 correct = False;
2532                 goto fail;
2533         }
2534
2535         /* This should succeed. */
2536         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2537                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2538         if (fnum2 == -1) {
2539                 printf("[4] open  - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2540                 correct = False;
2541                 goto fail;
2542         }
2543         
2544         if (!cli_close(&cli1, fnum2)) {
2545                 printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1));
2546                 correct = False;
2547                 goto fail;
2548         }
2549         
2550         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2551                 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2552                 correct = False;
2553                 goto fail;
2554         }
2555         
2556         /* This should fail - no more opens once delete on close set. */
2557         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2558                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2559         if (fnum2 != -1) {
2560                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
2561                 correct = False;
2562                 goto fail;
2563         } else
2564                 printf("fourth delete on close test succeeded.\n");
2565         
2566         if (!cli_close(&cli1, fnum1)) {
2567                 printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1));
2568                 correct = False;
2569                 goto fail;
2570         }
2571         
2572         /* Test 5 ... */
2573         cli_setatr(&cli1, fname, 0, 0);
2574         cli_unlink(&cli1, fname);
2575         
2576         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
2577         if (fnum1 == -1) {
2578                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2579                 correct = False;
2580                 goto fail;
2581         }
2582
2583         /* This should fail - only allowed on NT opens with DELETE access. */
2584
2585         if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2586                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2587                 correct = False;
2588                 goto fail;
2589         }
2590
2591         if (!cli_close(&cli1, fnum1)) {
2592                 printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1));
2593                 correct = False;
2594                 goto fail;
2595         }
2596         
2597         printf("fifth delete on close test succeeded.\n");
2598         
2599         /* Test 6 ... */
2600         cli_setatr(&cli1, fname, 0, 0);
2601         cli_unlink(&cli1, fname);
2602         
2603         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2604                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2605                                    FILE_OVERWRITE_IF, 0);
2606         
2607         if (fnum1 == -1) {
2608                 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2609                 correct = False;
2610                 goto fail;
2611         }
2612         
2613         /* This should fail - only allowed on NT opens with DELETE access. */
2614         
2615         if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2616                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2617                 correct = False;
2618                 goto fail;
2619         }
2620
2621         if (!cli_close(&cli1, fnum1)) {
2622                 printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1));
2623                 correct = False;
2624                 goto fail;
2625         }
2626
2627         printf("sixth delete on close test succeeded.\n");
2628         
2629         /* Test 7 ... */
2630         cli_setatr(&cli1, fname, 0, 0);
2631         cli_unlink(&cli1, fname);
2632         
2633         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2634                                    FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0);
2635                                                                 
2636         if (fnum1 == -1) {
2637                 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2638                 correct = False;
2639                 goto fail;
2640         }
2641
2642         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2643                 printf("[7] setting delete_on_close on file failed !\n");
2644                 correct = False;
2645                 goto fail;
2646         }
2647         
2648         if (!cli_nt_delete_on_close(&cli1, fnum1, False)) {
2649                 printf("[7] unsetting delete_on_close on file failed !\n");
2650                 correct = False;
2651                 goto fail;
2652         }
2653
2654         if (!cli_close(&cli1, fnum1)) {
2655                 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2656                 correct = False;
2657                 goto fail;
2658         }
2659         
2660         /* This next open should succeed - we reset the flag. */
2661         
2662         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2663         if (fnum1 == -1) {
2664                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2665                 correct = False;
2666                 goto fail;
2667         }
2668
2669         if (!cli_close(&cli1, fnum1)) {
2670                 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2671                 correct = False;
2672                 goto fail;
2673         }
2674
2675         printf("seventh delete on close test succeeded.\n");
2676         
2677         /* Test 7 ... */
2678         cli_setatr(&cli1, fname, 0, 0);
2679         cli_unlink(&cli1, fname);
2680         
2681         if (!torture_open_connection(&cli2)) {
2682                 printf("[8] failed to open second connection.\n");
2683                 correct = False;
2684                 goto fail;
2685         }
2686
2687         cli_sockopt(&cli1, sockops);
2688         
2689         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2690                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
2691         
2692         if (fnum1 == -1) {
2693                 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2694                 correct = False;
2695                 goto fail;
2696         }
2697
2698         fnum2 = cli_nt_create_full(&cli2, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2699                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2700         
2701         if (fnum2 == -1) {
2702                 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2703                 correct = False;
2704                 goto fail;
2705         }
2706
2707         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2708                 printf("[8] setting delete_on_close on file failed !\n");
2709                 correct = False;
2710                 goto fail;
2711         }
2712         
2713         if (!cli_close(&cli1, fnum1)) {
2714                 printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1));
2715                 correct = False;
2716                 goto fail;
2717         }
2718
2719         if (!cli_close(&cli2, fnum2)) {
2720                 printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2));
2721                 correct = False;
2722                 goto fail;
2723         }
2724
2725         /* This should fail.. */
2726         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2727         if (fnum1 != -1) {
2728                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2729                 goto fail;
2730                 correct = False;
2731         } else
2732                 printf("eighth delete on close test succeeded.\n");
2733
2734         /* This should fail - we need to set DELETE_ACCESS. */
2735         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2736                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
2737         
2738         if (fnum1 != -1) {
2739                 printf("[9] open of %s succeeded should have failed!\n", fname);
2740                 correct = False;
2741                 goto fail;
2742         }
2743
2744         printf("ninth delete on close test succeeded.\n");
2745
2746         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2747                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
2748         if (fnum1 == -1) {
2749                 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2750                 correct = False;
2751                 goto fail;
2752         }
2753
2754         /* This should delete the file. */
2755         if (!cli_close(&cli1, fnum1)) {
2756                 printf("[10] close failed (%s)\n", cli_errstr(&cli1));
2757                 correct = False;
2758                 goto fail;
2759         }
2760
2761         /* This should fail.. */
2762         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2763         if (fnum1 != -1) {
2764                 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2765                 goto fail;
2766                 correct = False;
2767         } else
2768                 printf("tenth delete on close test succeeded.\n");
2769         printf("finished delete test\n");
2770
2771   fail:
2772         
2773         cli_close(&cli1, fnum1);
2774         cli_close(&cli1, fnum2);
2775         cli_setatr(&cli1, fname, 0, 0);
2776         cli_unlink(&cli1, fname);
2777         
2778         if (!torture_close_connection(&cli1)) {
2779                 correct = False;
2780         }
2781         if (!torture_close_connection(&cli2)) {
2782                 correct = False;
2783         }
2784         return correct;
2785 }
2786
2787
2788 /*
2789   print out server properties
2790  */
2791 static BOOL run_properties(int dummy)
2792 {
2793         static struct cli_state cli;
2794         BOOL correct = True;
2795         
2796         printf("starting properties test\n");
2797         
2798         ZERO_STRUCT(cli);
2799
2800         if (!torture_open_connection(&cli)) {
2801                 return False;
2802         }
2803         
2804         cli_sockopt(&cli, sockops);
2805
2806         d_printf("Capabilities 0x%08x\n", cli.capabilities);
2807
2808         if (!torture_close_connection(&cli)) {
2809                 correct = False;
2810         }
2811
2812         return correct;
2813 }
2814
2815
2816
2817 /* FIRST_DESIRED_ACCESS   0xf019f */
2818 #define FIRST_DESIRED_ACCESS   FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
2819                                FILE_READ_EA|                           /* 0xf */ \
2820                                FILE_WRITE_EA|FILE_READ_ATTRIBUTES|     /* 0x90 */ \
2821                                FILE_WRITE_ATTRIBUTES|                  /* 0x100 */ \
2822                                DELETE_ACCESS|READ_CONTROL_ACCESS|\
2823                                WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS     /* 0xf0000 */
2824 /* SECOND_DESIRED_ACCESS  0xe0080 */
2825 #define SECOND_DESIRED_ACCESS  FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
2826                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2827                                WRITE_OWNER_ACCESS                      /* 0xe0000 */
2828
2829 #if 0
2830 #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
2831                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2832                                FILE_READ_DATA|\
2833                                WRITE_OWNER_ACCESS                      /* */
2834 #endif
2835
2836 /*
2837   Test ntcreate calls made by xcopy
2838  */
2839 static BOOL run_xcopy(int dummy)
2840 {
2841         static struct cli_state cli1;
2842         char *fname = "\\test.txt";
2843         BOOL correct = True;
2844         int fnum1, fnum2;
2845
2846         printf("starting xcopy test\n");
2847         
2848         if (!torture_open_connection(&cli1)) {
2849                 return False;
2850         }
2851         
2852         fnum1 = cli_nt_create_full(&cli1, fname, 
2853                                    FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2854                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 
2855                                    0x4044);
2856
2857         if (fnum1 == -1) {
2858                 printf("First open failed - %s\n", cli_errstr(&cli1));
2859                 return False;
2860         }
2861
2862         fnum2 = cli_nt_create_full(&cli1, fname, 
2863                                    SECOND_DESIRED_ACCESS, 0,
2864                                    FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 
2865                                    0x200000);
2866         if (fnum2 == -1) {
2867                 printf("second open failed - %s\n", cli_errstr(&cli1));
2868                 return False;
2869         }
2870         
2871         if (!torture_close_connection(&cli1)) {
2872                 correct = False;
2873         }
2874         
2875         return correct;
2876 }
2877
2878 /*
2879   Test rename on files open with share delete and no share delete.
2880  */
2881 static BOOL run_rename(int dummy)
2882 {
2883         static struct cli_state cli1;
2884         char *fname = "\\test.txt";
2885         char *fname1 = "\\test1.txt";
2886         BOOL correct = True;
2887         int fnum1;
2888
2889         printf("starting rename test\n");
2890         
2891         if (!torture_open_connection(&cli1)) {
2892                 return False;
2893         }
2894         
2895         cli_unlink(&cli1, fname);
2896         cli_unlink(&cli1, fname1);
2897         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2898                                    FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
2899
2900         if (fnum1 == -1) {
2901                 printf("First open failed - %s\n", cli_errstr(&cli1));
2902                 return False;
2903         }
2904
2905         if (!cli_rename(&cli1, fname, fname1)) {
2906                 printf("First rename failed (this is correct) - %s\n", cli_errstr(&cli1));
2907         } else {
2908                 printf("First rename succeeded - this should have failed !\n");
2909                 correct = False;
2910         }
2911
2912         if (!cli_close(&cli1, fnum1)) {
2913                 printf("close - 1 failed (%s)\n", cli_errstr(&cli1));
2914                 return False;
2915         }
2916
2917         cli_unlink(&cli1, fname);
2918         cli_unlink(&cli1, fname1);
2919         fnum1 = cli_nt_create_full(&cli1, fname,GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2920 #if 0
2921                                    FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
2922 #else
2923                                    FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
2924 #endif
2925
2926         if (fnum1 == -1) {
2927                 printf("Second open failed - %s\n", cli_errstr(&cli1));
2928                 return False;
2929         }
2930
2931         if (!cli_rename(&cli1, fname, fname1)) {
2932                 printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(&cli1));
2933                 correct = False;
2934         } else {
2935                 printf("Second rename succeeded\n");
2936         }
2937
2938         if (!cli_close(&cli1, fnum1)) {
2939                 printf("close - 2 failed (%s)\n", cli_errstr(&cli1));
2940                 return False;
2941         }
2942
2943         cli_unlink(&cli1, fname);
2944         cli_unlink(&cli1, fname1);
2945
2946         fnum1 = cli_nt_create_full(&cli1, fname,READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2947                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
2948
2949         if (fnum1 == -1) {
2950                 printf("Third open failed - %s\n", cli_errstr(&cli1));
2951                 return False;
2952         }
2953
2954
2955 #if 0
2956   {
2957   int fnum2;
2958
2959         fnum2 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2960                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
2961
2962         if (fnum2 == -1) {
2963                 printf("Fourth open failed - %s\n", cli_errstr(&cli1));
2964                 return False;
2965         }
2966         if (!cli_nt_delete_on_close(&cli1, fnum2, True)) {
2967                 printf("[8] setting delete_on_close on file failed !\n");
2968                 return False;
2969         }
2970         
2971         if (!cli_close(&cli1, fnum2)) {
2972                 printf("close - 4 failed (%s)\n", cli_errstr(&cli1));
2973                 return False;
2974         }
2975   }
2976 #endif
2977
2978         if (!cli_rename(&cli1, fname, fname1)) {
2979                 printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(&cli1));
2980                 correct = False;
2981         } else {
2982                 printf("Third rename succeeded\n");
2983         }
2984
2985         if (!cli_close(&cli1, fnum1)) {
2986                 printf("close - 3 failed (%s)\n", cli_errstr(&cli1));
2987                 return False;
2988         }
2989
2990         cli_unlink(&cli1, fname);
2991         cli_unlink(&cli1, fname1);
2992
2993         if (!torture_close_connection(&cli1)) {
2994                 correct = False;
2995         }
2996         
2997         return correct;
2998 }
2999
3000
3001 /*
3002   Test open mode returns on read-only files.
3003  */
3004 static BOOL run_opentest(int dummy)
3005 {
3006         static struct cli_state cli1;
3007         static struct cli_state cli2;
3008         char *fname = "\\readonly.file";
3009         int fnum1, fnum2;
3010         char buf[20];
3011         size_t fsize;
3012         BOOL correct = True;
3013         char *tmp_path;
3014
3015         printf("starting open test\n");
3016         
3017         if (!torture_open_connection(&cli1)) {
3018                 return False;
3019         }
3020         
3021         cli_setatr(&cli1, fname, 0, 0);
3022         cli_unlink(&cli1, fname);
3023         
3024         cli_sockopt(&cli1, sockops);
3025         
3026         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3027         if (fnum1 == -1) {
3028                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3029                 return False;
3030         }
3031
3032         if (!cli_close(&cli1, fnum1)) {
3033                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3034                 return False;
3035         }
3036         
3037         if (!cli_setatr(&cli1, fname, aRONLY, 0)) {
3038                 printf("cli_setatr failed (%s)\n", cli_errstr(&cli1));
3039                 return False;
3040         }
3041         
3042         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
3043         if (fnum1 == -1) {
3044                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3045                 return False;
3046         }
3047         
3048         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3049         fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
3050         
3051         if (check_error(__LINE__, &cli1, ERRDOS, ERRnoaccess, 
3052                         NT_STATUS_ACCESS_DENIED)) {
3053                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3054         }
3055         
3056         printf("finished open test 1\n");
3057         
3058         cli_close(&cli1, fnum1);
3059         
3060         /* Now try not readonly and ensure ERRbadshare is returned. */
3061         
3062         cli_setatr(&cli1, fname, 0, 0);
3063         
3064         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
3065         if (fnum1 == -1) {
3066                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3067                 return False;
3068         }
3069         
3070         /* This will fail - but the error should be ERRshare. */
3071         fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
3072         
3073         if (check_error(__LINE__, &cli1, ERRDOS, ERRbadshare, 
3074                         NT_STATUS_SHARING_VIOLATION)) {
3075                 printf("correct error code ERRDOS/ERRbadshare returned\n");
3076         }
3077         
3078         if (!cli_close(&cli1, fnum1)) {
3079                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3080                 return False;
3081         }
3082         
3083         cli_unlink(&cli1, fname);
3084         
3085         printf("finished open test 2\n");
3086         
3087         /* Test truncate open disposition on file opened for read. */
3088         
3089         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3090         if (fnum1 == -1) {
3091                 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(&cli1));
3092                 return False;
3093         }
3094         
3095         /* write 20 bytes. */
3096         
3097         memset(buf, '\0', 20);
3098
3099         if (cli_write(&cli1, fnum1, 0, buf, 0, 20) != 20) {
3100                 printf("write failed (%s)\n", cli_errstr(&cli1));
3101                 correct = False;
3102         }
3103
3104         if (!cli_close(&cli1, fnum1)) {
3105                 printf("(3) close1 failed (%s)\n", cli_errstr(&cli1));
3106                 return False;
3107         }
3108         
3109         /* Ensure size == 20. */
3110         if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
3111                 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
3112                 return False;
3113         }
3114         
3115         if (fsize != 20) {
3116                 printf("(3) file size != 20\n");
3117                 return False;
3118         }
3119
3120         /* Now test if we can truncate a file opened for readonly. */
3121         
3122         fnum1 = cli_open(&cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3123         if (fnum1 == -1) {
3124                 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(&cli1));
3125                 return False;
3126         }
3127         
3128         if (!cli_close(&cli1, fnum1)) {
3129                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3130                 return False;
3131         }
3132
3133         /* Ensure size == 0. */
3134         if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
3135                 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
3136                 return False;
3137         }
3138
3139         if (fsize != 0) {
3140                 printf("(3) file size != 0\n");
3141                 return False;
3142         }
3143         printf("finished open test 3\n");
3144         
3145         cli_unlink(&cli1, fname);
3146
3147
3148         printf("testing ctemp\n");
3149         fnum1 = cli_ctemp(&cli1, "\\", &tmp_path);
3150         if (fnum1 == -1) {
3151                 printf("ctemp failed (%s)\n", cli_errstr(&cli1));
3152                 return False;
3153         }
3154         printf("ctemp gave path %s\n", tmp_path);
3155         if (!cli_close(&cli1, fnum1)) {
3156                 printf("close of temp failed (%s)\n", cli_errstr(&cli1));
3157         }
3158         if (!cli_unlink(&cli1, tmp_path)) {
3159                 printf("unlink of temp failed (%s)\n", cli_errstr(&cli1));
3160         }
3161         
3162         /* Test the non-io opens... */
3163
3164         if (!torture_open_connection(&cli2)) {
3165                 return False;
3166         }
3167         
3168         cli_setatr(&cli2, fname, 0, 0);
3169         cli_unlink(&cli2, fname);
3170         
3171         cli_sockopt(&cli2, sockops);
3172
3173         printf("TEST #1 testing 2 non-io opens (no delete)\n");
3174         
3175         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3176                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3177
3178         if (fnum1 == -1) {
3179                 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3180                 return False;
3181         }
3182
3183         fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3184                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3185
3186         if (fnum2 == -1) {
3187                 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3188                 return False;
3189         }
3190
3191         if (!cli_close(&cli1, fnum1)) {
3192                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3193                 return False;
3194         }
3195         if (!cli_close(&cli2, fnum2)) {
3196                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3197                 return False;
3198         }
3199
3200         printf("non-io open test #1 passed.\n");
3201
3202         cli_unlink(&cli1, fname);
3203
3204         printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3205         
3206         fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3207                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3208
3209         if (fnum1 == -1) {
3210                 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3211                 return False;
3212         }
3213
3214         fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3215                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3216
3217         if (fnum2 == -1) {
3218                 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3219                 return False;
3220         }
3221
3222         if (!cli_close(&cli1, fnum1)) {
3223                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3224                 return False;
3225         }
3226         if (!cli_close(&cli2, fnum2)) {
3227                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3228                 return False;
3229         }
3230
3231         printf("non-io open test #2 passed.\n");
3232
3233         cli_unlink(&cli1, fname);
3234
3235         printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3236         
3237         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3238                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3239
3240         if (fnum1 == -1) {
3241                 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3242                 return False;
3243         }
3244
3245         fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3246                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3247
3248         if (fnum2 == -1) {
3249                 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3250                 return False;
3251         }
3252
3253         if (!cli_close(&cli1, fnum1)) {
3254                 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3255                 return False;
3256         }
3257         if (!cli_close(&cli2, fnum2)) {
3258                 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3259                 return False;
3260         }
3261
3262         printf("non-io open test #3 passed.\n");
3263
3264         cli_unlink(&cli1, fname);
3265
3266         printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3267         
3268         fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3269                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3270
3271         if (fnum1 == -1) {
3272                 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3273                 return False;
3274         }
3275
3276         fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3277                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3278
3279         if (fnum2 != -1) {
3280                 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(&cli2));
3281                 return False;
3282         }
3283
3284         printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(&cli2), "sharing violation");
3285
3286         if (!cli_close(&cli1, fnum1)) {
3287                 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3288                 return False;
3289         }
3290
3291         printf("non-io open test #4 passed.\n");
3292
3293         cli_unlink(&cli1, fname);
3294
3295         printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3296         
3297         fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3298                                    FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
3299
3300         if (fnum1 == -1) {
3301                 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3302                 return False;
3303         }
3304
3305         fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3306                                    FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
3307
3308         if (fnum2 == -1) {
3309                 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3310                 return False;
3311         }
3312
3313         if (!cli_close(&cli1, fnum1)) {
3314                 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3315                 return False;
3316         }
3317
3318         if (!cli_close(&cli2, fnum2)) {
3319                 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3320                 return False;
3321         }
3322
3323         printf("non-io open test #5 passed.\n");
3324
3325         printf("TEST #6 testing 1 non-io open, one io open\n");
3326         
3327         cli_unlink(&cli1, fname);
3328
3329         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3330                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3331
3332         if (fnum1 == -1) {
3333                 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3334                 return False;
3335         }
3336
3337         fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3338                                    FILE_SHARE_READ, FILE_OPEN_IF, 0);
3339
3340         if (fnum2 == -1) {
3341                 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3342                 return False;
3343         }
3344
3345         if (!cli_close(&cli1, fnum1)) {
3346                 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3347                 return False;
3348         }
3349
3350         if (!cli_close(&cli2, fnum2)) {
3351                 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3352                 return False;
3353         }
3354
3355         printf("non-io open test #6 passed.\n");
3356
3357         printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3358
3359         cli_unlink(&cli1, fname);
3360
3361         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3362                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3363
3364         if (fnum1 == -1) {
3365                 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3366                 return False;
3367         }
3368
3369         fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3370                                    FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
3371
3372         if (fnum2 != -1) {
3373                 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(&cli2));
3374                 return False;
3375         }
3376
3377         printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(&cli2), "sharing violation");
3378
3379         if (!cli_close(&cli1, fnum1)) {
3380                 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3381                 return False;
3382         }
3383
3384         printf("non-io open test #7 passed.\n");
3385
3386         cli_unlink(&cli1, fname);
3387
3388         if (!torture_close_connection(&cli1)) {
3389                 correct = False;
3390         }
3391         if (!torture_close_connection(&cli2)) {
3392                 correct = False;
3393         }
3394         
3395         return correct;
3396 }
3397
3398 static void list_fn(file_info *finfo, const char *name, void *state)
3399 {
3400         
3401 }
3402
3403 /*
3404   test directory listing speed
3405  */
3406 static BOOL run_dirtest(int dummy)
3407 {
3408         int i;
3409         static struct cli_state cli;
3410         int fnum;
3411         double t1;
3412         BOOL correct = True;
3413
3414         printf("starting directory test\n");
3415
3416         if (!torture_open_connection(&cli)) {
3417                 return False;
3418         }
3419
3420         cli_sockopt(&cli, sockops);
3421
3422         srandom(0);
3423         for (i=0;i<torture_numops;i++) {
3424                 fstring fname;
3425                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3426                 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
3427                 if (fnum == -1) {
3428                         fprintf(stderr,"Failed to open %s\n", fname);
3429                         return False;
3430                 }
3431                 cli_close(&cli, fnum);
3432         }
3433
3434         t1 = end_timer();
3435
3436         printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
3437         printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
3438         printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
3439
3440         printf("dirtest core %g seconds\n", end_timer() - t1);
3441
3442         srandom(0);
3443         for (i=0;i<torture_numops;i++) {
3444                 fstring fname;
3445                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3446                 cli_unlink(&cli, fname);
3447         }
3448
3449         if (!torture_close_connection(&cli)) {
3450                 correct = False;
3451         }
3452
3453         printf("finished dirtest\n");
3454
3455         return correct;
3456 }
3457
3458 static BOOL run_error_map_extract(int dummy) {
3459         
3460         static struct cli_state c_dos;
3461         static struct cli_state c_nt;
3462
3463         uint32 error;
3464
3465         uint32 flgs2, errnum;
3466         uint8 errclass;
3467
3468         NTSTATUS nt_status;
3469
3470         fstring user;
3471
3472         /* NT-Error connection */
3473
3474         if (!open_nbt_connection(&c_nt)) {
3475                 return False;
3476         }
3477
3478         c_nt.use_spnego = False;
3479
3480         if (!cli_negprot(&c_nt)) {
3481                 printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(&c_nt));
3482                 cli_shutdown(&c_nt);
3483                 return False;
3484         }
3485
3486         if (!cli_session_setup(&c_nt, "", "", 0, "", 0,
3487                                workgroup)) {
3488                 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(&c_nt));
3489                 return False;
3490         }
3491
3492         /* DOS-Error connection */
3493
3494         if (!open_nbt_connection(&c_dos)) {
3495                 return False;
3496         }
3497
3498         c_dos.use_spnego = False;
3499         c_dos.force_dos_errors = True;
3500
3501         if (!cli_negprot(&c_dos)) {
3502                 printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(&c_dos));
3503                 cli_shutdown(&c_dos);
3504                 return False;
3505         }
3506
3507         if (!cli_session_setup(&c_dos, "", "", 0, "", 0,
3508                                workgroup)) {
3509                 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(&c_dos));
3510                 return False;
3511         }
3512
3513         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
3514                 snprintf(user, sizeof(user), "%X", error);
3515
3516                 if (cli_session_setup(&c_nt, user, 
3517                                        password, strlen(password),
3518                                        password, strlen(password),
3519                                       workgroup)) {
3520                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
3521                 }
3522                 
3523                 flgs2 = SVAL(c_nt.inbuf,smb_flg2);
3524                 
3525                 /* Case #1: 32-bit NT errors */
3526                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
3527                         nt_status = NT_STATUS(IVAL(c_nt.inbuf,smb_rcls));
3528                 } else {
3529                         printf("/** Dos error on NT connection! (%s) */\n", 
3530                                cli_errstr(&c_nt));
3531                         nt_status = NT_STATUS(0xc0000000);
3532                 }
3533
3534                 if (cli_session_setup(&c_dos, user, 
3535                                        password, strlen(password),
3536                                        password, strlen(password),
3537                                        workgroup)) {
3538                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
3539                 }
3540                 flgs2 = SVAL(c_dos.inbuf,smb_flg2), errnum;
3541                 
3542                 /* Case #1: 32-bit NT errors */
3543                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
3544                         printf("/** NT error on DOS connection! (%s) */\n", 
3545                                cli_errstr(&c_nt));
3546                         errnum = errclass = 0;
3547                 } else {
3548                         cli_dos_error(&c_dos, &errclass, &errnum);
3549                 }
3550
3551                 if (NT_STATUS_V(nt_status) != error) { 
3552                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
3553                                get_nt_error_c_code(NT_STATUS(error)), 
3554                                get_nt_error_c_code(nt_status));
3555                 }
3556                 
3557                 printf("\t{%s,\t%s,\t%s},\n", 
3558                        smb_dos_err_class(errclass), 
3559                        smb_dos_err_name(errclass, errnum), 
3560                        get_nt_error_c_code(NT_STATUS(error)));
3561         }
3562         return True;
3563 }
3564
3565 static double create_procs(BOOL (*fn)(int), BOOL *result)
3566 {
3567         int i, status;
3568         volatile pid_t *child_status;
3569         volatile BOOL *child_status_out;
3570         int synccount;
3571         int tries = 8;
3572
3573         synccount = 0;
3574
3575         child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
3576         if (!child_status) {
3577                 printf("Failed to setup shared memory\n");
3578                 return -1;
3579         }
3580
3581         child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
3582         if (!child_status_out) {
3583                 printf("Failed to setup result status shared memory\n");
3584                 return -1;
3585         }
3586
3587         for (i = 0; i < nprocs; i++) {
3588                 child_status[i] = 0;
3589                 child_status_out[i] = True;
3590         }
3591
3592         start_timer();
3593
3594         for (i=0;i<nprocs;i++) {
3595                 procnum = i;
3596                 if (fork() == 0) {
3597                         pid_t mypid = getpid();
3598                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
3599
3600                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
3601
3602                         while (1) {
3603                                 memset(&current_cli, 0, sizeof(current_cli));
3604                                 if (torture_open_connection(&current_cli)) break;
3605                                 if (tries-- == 0) {
3606                                         printf("pid %d failed to start\n", (int)getpid());
3607                                         _exit(1);
3608                                 }
3609                                 msleep(10);     
3610                         }
3611
3612                         child_status[i] = getpid();
3613
3614                         while (child_status[i] && end_timer() < 5) msleep(2);
3615
3616                         child_status_out[i] = fn(i);
3617                         _exit(0);
3618                 }
3619         }
3620
3621         do {
3622                 synccount = 0;
3623                 for (i=0;i<nprocs;i++) {
3624                         if (child_status[i]) synccount++;
3625                 }
3626                 if (synccount == nprocs) break;
3627                 msleep(10);
3628         } while (end_timer() < 30);
3629
3630         if (synccount != nprocs) {
3631                 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
3632                 *result = False;
3633                 return end_timer();
3634         }
3635
3636         /* start the client load */
3637         start_timer();
3638
3639         for (i=0;i<nprocs;i++) {
3640                 child_status[i] = 0;
3641         }
3642
3643         printf("%d clients started\n", nprocs);
3644
3645         for (i=0;i<nprocs;i++) {
3646                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
3647         }
3648
3649         printf("\n");
3650         
3651         for (i=0;i<nprocs;i++) {
3652                 if (!child_status_out[i]) {
3653                         *result = False;
3654                 }
3655         }
3656         return end_timer();
3657 }
3658
3659 #define FLAG_MULTIPROC 1
3660
3661 static struct {
3662         char *name;
3663         BOOL (*fn)(int);
3664         unsigned flags;
3665 } torture_ops[] = {
3666         {"FDPASS", run_fdpasstest, 0},
3667         {"LOCK1",  run_locktest1,  0},
3668         {"LOCK2",  run_locktest2,  0},
3669         {"LOCK3",  run_locktest3,  0},
3670         {"LOCK4",  run_locktest4,  0},
3671         {"LOCK5",  run_locktest5,  0},
3672         {"LOCK6",  run_locktest6,  0},
3673         {"UNLINK", run_unlinktest, 0},
3674         {"BROWSE", run_browsetest, 0},
3675         {"ATTR",   run_attrtest,   0},
3676         {"TRANS2", run_trans2test, 0},
3677         {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
3678         {"TORTURE",run_torture,    FLAG_MULTIPROC},
3679         {"RANDOMIPC", run_randomipc, 0},
3680         {"NEGNOWAIT", run_negprot_nowait, 0},
3681         {"NBENCH",  run_nbench, 0},
3682         {"OPLOCK1",  run_oplock1, 0},
3683         {"OPLOCK2",  run_oplock2, 0},
3684         {"OPLOCK3",  run_oplock3, 0},
3685         {"DIR",  run_dirtest, 0},
3686         {"DENY1",  torture_denytest1, 0},
3687         {"DENY2",  torture_denytest2, 0},
3688         {"TCON",  run_tcon_test, 0},
3689         {"RW1",  run_readwritetest, 0},
3690         {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
3691         {"RW3",  run_readwritelarge, 0},
3692         {"OPEN", run_opentest, 0},
3693         {"XCOPY", run_xcopy, 0},
3694         {"RENAME", run_rename, 0},
3695         {"DELETE", run_deletetest, 0},
3696         {"PROPERTIES", run_properties, 0},
3697         {"MANGLE", torture_mangle, 0},
3698         {"W2K", run_w2ktest, 0},
3699         {"TRANS2SCAN", torture_trans2_scan, 0},
3700         {"NTTRANSSCAN", torture_nttrans_scan, 0},
3701         {"UTABLE", torture_utable, 0},
3702         {"CASETABLE", torture_casetable, 0},
3703         {"ERRMAPEXTRACT", run_error_map_extract, 0},
3704         {NULL, NULL, 0}};
3705
3706
3707
3708 /****************************************************************************
3709 run a specified test or "ALL"
3710 ****************************************************************************/
3711 static BOOL run_test(char *name)
3712 {
3713         BOOL ret = True;
3714         BOOL result = True;
3715         int i;
3716         double t;
3717         if (strequal(name,"ALL")) {
3718                 for (i=0;torture_ops[i].name;i++) {
3719                         run_test(torture_ops[i].name);
3720                 }
3721         }
3722         
3723         for (i=0;torture_ops[i].name;i++) {
3724                 snprintf(randomfname, sizeof(randomfname), "\\XX%x", 
3725                          (unsigned)random());
3726
3727                 if (strequal(name, torture_ops[i].name)) {
3728                         printf("Running %s\n", name);
3729                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
3730                                 t = create_procs(torture_ops[i].fn, &result);
3731                                 if (!result) { 
3732                                         ret = False;
3733                                         printf("TEST %s FAILED!\n", name);
3734                                 }
3735                                          
3736                         } else {
3737                                 start_timer();
3738                                 if (!torture_ops[i].fn(0)) {
3739                                         ret = False;
3740                                         printf("TEST %s FAILED!\n", name);
3741                                 }
3742                                 t = end_timer();
3743                         }
3744                         printf("%s took %g secs\n\n", name, t);
3745                 }
3746         }
3747         return ret;
3748 }
3749
3750
3751 static void usage(void)
3752 {
3753         int i;
3754
3755         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
3756
3757         printf("\t-d debuglevel\n");
3758         printf("\t-U user%%pass\n");
3759         printf("\t-k               use kerberos\n");
3760         printf("\t-N numprocs\n");
3761         printf("\t-n my_netbios_name\n");
3762         printf("\t-W workgroup\n");
3763         printf("\t-o num_operations\n");
3764         printf("\t-O socket_options\n");
3765         printf("\t-m maximum protocol\n");
3766         printf("\t-L use oplocks\n");
3767         printf("\t-c CLIENT.TXT   specify client load file for NBENCH\n");
3768         printf("\t-A showall\n");
3769         printf("\t-s seed\n");
3770         printf("\n\n");
3771
3772         printf("tests are:");
3773         for (i=0;torture_ops[i].name;i++) {
3774                 printf(" %s", torture_ops[i].name);
3775         }
3776         printf("\n");
3777
3778         printf("default test is ALL\n");
3779         
3780         exit(1);
3781 }
3782
3783
3784
3785
3786
3787 /****************************************************************************
3788   main program
3789 ****************************************************************************/
3790  int main(int argc,char *argv[])
3791 {
3792         int opt, i;
3793         char *p;
3794         int gotpass = 0;
3795         extern char *optarg;
3796         extern int optind;
3797         BOOL correct = True;
3798
3799         dbf = x_stdout;
3800
3801 #ifdef HAVE_SETBUFFER
3802         setbuffer(stdout, NULL, 0);
3803 #endif
3804
3805         lp_load(dyn_CONFIGFILE,True,False,False);
3806         load_interfaces();
3807
3808         if (argc < 2) {
3809                 usage();
3810         }
3811
3812         for(p = argv[1]; *p; p++)
3813           if(*p == '\\')
3814             *p = '/';
3815  
3816         if (strncmp(argv[1], "//", 2)) {
3817                 usage();
3818         }
3819
3820         fstrcpy(host, &argv[1][2]);
3821         p = strchr_m(&host[2],'/');
3822         if (!p) {
3823                 usage();
3824         }
3825         *p = 0;
3826         fstrcpy(share, p+1);
3827
3828         get_myname(myname);
3829
3830         if (*username == 0 && getenv("LOGNAME")) {
3831           pstrcpy(username,getenv("LOGNAME"));
3832         }
3833
3834         argc--;
3835         argv++;
3836
3837
3838         fstrcpy(workgroup, lp_workgroup());
3839
3840         while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:Ld:Ac:ks:")) != EOF) {
3841                 switch (opt) {
3842                 case 's':
3843                         srandom(atoi(optarg));
3844                         break;
3845                 case 'W':
3846                         fstrcpy(workgroup,optarg);
3847                         break;
3848                 case 'm':
3849                         max_protocol = interpret_protocol(optarg, max_protocol);
3850                         break;
3851                 case 'N':
3852                         nprocs = atoi(optarg);
3853                         break;
3854                 case 'o':
3855                         torture_numops = atoi(optarg);
3856                         break;
3857                 case 'd':
3858                         DEBUGLEVEL = atoi(optarg);
3859                         break;
3860                 case 'O':
3861                         sockops = optarg;
3862                         break;
3863                 case 'L':
3864                         use_oplocks = True;
3865                         break;
3866                 case 'A':
3867                         torture_showall = True;
3868                         break;
3869                 case 'n':
3870                         fstrcpy(myname, optarg);
3871                         break;
3872                 case 'c':
3873                         client_txt = optarg;
3874                         break;
3875                 case 'k':
3876 #ifdef HAVE_KRB5
3877                         use_kerberos = True;
3878                         gotpass = True;
3879 #else
3880                         d_printf("No kerberos support compiled in\n");
3881                         exit(1);
3882 #endif
3883                         break;
3884                 case 'U':
3885                         pstrcpy(username,optarg);
3886                         p = strchr_m(username,'%');
3887                         if (p) {
3888                                 *p = 0;
3889                                 pstrcpy(password, p+1);
3890                                 gotpass = 1;
3891                         }
3892                         break;
3893                 default:
3894                         printf("Unknown option %c (%d)\n", (char)opt, opt);
3895                         usage();
3896                 }
3897         }
3898
3899
3900         while (!gotpass) {
3901                 p = getpass("Password:");
3902                 if (p) {
3903                         pstrcpy(password, p);
3904                         gotpass = 1;
3905                 }
3906         }
3907
3908         printf("host=%s share=%s user=%s myname=%s\n", 
3909                host, share, username, myname);
3910
3911         if (argc == 1) {
3912                 correct = run_test("ALL");
3913         } else {
3914                 for (i=1;i<argc;i++) {
3915                         if (!run_test(argv[i])) {
3916                                 correct = False;
3917                         }
3918                 }
3919         }
3920
3921         if (correct) {
3922                 return(0);
3923         } else {
3924                 return(1);
3925         }
3926 }