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