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