Re-add bail on failure.
[ira/wip.git] / source / torture / torture.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    SMB torture tester
5    Copyright (C) Andrew Tridgell 1997-1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #define NO_SYSLOG
23
24 #include "includes.h"
25
26 static fstring host, workgroup, share, password, username, myname;
27 static int max_protocol = PROTOCOL_NT1;
28 static char *sockops="TCP_NODELAY";
29 static int nprocs=1, numops=100;
30 static int procnum; /* records process count number when forking */
31 static struct cli_state current_cli;
32 static fstring randomfname;
33 static BOOL use_oplocks;
34 static BOOL use_level_II_oplocks;
35 BOOL torture_showall = False;
36
37 static double create_procs(BOOL (*fn)(int), BOOL *result);
38
39
40 static struct timeval tp1,tp2;
41
42 static void start_timer(void)
43 {
44         gettimeofday(&tp1,NULL);
45 }
46
47 static double end_timer(void)
48 {
49         gettimeofday(&tp2,NULL);
50         return((tp2.tv_sec - tp1.tv_sec) + 
51                (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
52 }
53
54
55 /* return a pointer to a anonymous shared memory segment of size "size"
56    which will persist across fork() but will disappear when all processes
57    exit 
58
59    The memory is not zeroed 
60
61    This function uses system5 shared memory. It takes advantage of a property
62    that the memory is not destroyed if it is attached when the id is removed
63    */
64 static void *shm_setup(int size)
65 {
66         int shmid;
67         void *ret;
68
69         shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
70         if (shmid == -1) {
71                 printf("can't get shared memory\n");
72                 exit(1);
73         }
74         ret = (void *)shmat(shmid, 0, 0);
75         if (!ret || ret == (void *)-1) {
76                 printf("can't attach to shared memory\n");
77                 return NULL;
78         }
79         /* the following releases the ipc, but note that this process
80            and all its children will still have access to the memory, its
81            just that the shmid is no longer valid for other shm calls. This
82            means we don't leave behind lots of shm segments after we exit 
83
84            See Stevens "advanced programming in unix env" for details
85            */
86         shmctl(shmid, IPC_RMID, 0);
87         
88         return ret;
89 }
90
91
92 static BOOL open_nbt_connection(struct cli_state *c)
93 {
94         struct nmb_name called, calling;
95         struct in_addr ip;
96
97         ZERO_STRUCTP(c);
98
99         make_nmb_name(&calling, myname, 0x0);
100         make_nmb_name(&called , host, 0x20);
101
102         zero_ip(&ip);
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         ssize_t 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, (size_t)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 = "\\torture2.lck";
427         int fnum1;
428         int fnum2;
429         int i;
430         uchar buf[131072];
431         uchar 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_LOCK_NOT_GRANTED)) 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_LOCK_NOT_GRANTED)) 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_LOCK_NOT_GRANTED)) 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, ERRlock, 
1037                                  NT_STATUS_LOCK_NOT_GRANTED)) 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, ERRlock, 
1046                                  NT_STATUS_LOCK_NOT_GRANTED)) 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 test whether fnums and tids open on one VC are available on another (a major
1506 security hole)
1507 */
1508 static BOOL run_fdpasstest(int dummy)
1509 {
1510         static struct cli_state cli1, cli2, cli3;
1511         char *fname = "\\fdpass.tst";
1512         int fnum1;
1513         pstring buf;
1514
1515         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1516                 return False;
1517         }
1518         cli_sockopt(&cli1, sockops);
1519         cli_sockopt(&cli2, sockops);
1520
1521         printf("starting fdpasstest\n");
1522
1523         cli_unlink(&cli1, fname);
1524
1525         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1526         if (fnum1 == -1) {
1527                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1528                 return False;
1529         }
1530
1531         if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
1532                 printf("write failed (%s)\n", cli_errstr(&cli1));
1533                 return False;
1534         }
1535
1536         cli3 = cli2;
1537         cli3.vuid = cli1.vuid;
1538         cli3.cnum = cli1.cnum;
1539         cli3.pid = cli1.pid;
1540
1541         if (cli_read(&cli3, fnum1, buf, 0, 13) == 13) {
1542                 printf("read succeeded! nasty security hole [%s]\n",
1543                        buf);
1544                 return False;
1545         }
1546
1547         cli_close(&cli1, fnum1);
1548         cli_unlink(&cli1, fname);
1549
1550         torture_close_connection(&cli1);
1551         torture_close_connection(&cli2);
1552
1553         printf("finished fdpasstest\n");
1554         return True;
1555 }
1556
1557
1558 /*
1559   This test checks that 
1560
1561   1) the server does not allow an unlink on a file that is open
1562 */
1563 static BOOL run_unlinktest(int dummy)
1564 {
1565         static struct cli_state cli;
1566         char *fname = "\\unlink.tst";
1567         int fnum;
1568         BOOL correct = True;
1569
1570         if (!torture_open_connection(&cli)) {
1571                 return False;
1572         }
1573
1574         cli_sockopt(&cli, sockops);
1575
1576         printf("starting unlink test\n");
1577
1578         cli_unlink(&cli, fname);
1579
1580         cli_setpid(&cli, 1);
1581
1582         fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1583         if (fnum == -1) {
1584                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1585                 return False;
1586         }
1587
1588         if (cli_unlink(&cli, fname)) {
1589                 printf("error: server allowed unlink on an open file\n");
1590                 correct = False;
1591         } else {
1592                 correct = check_error(__LINE__, &cli, ERRDOS, ERRbadshare, 
1593                                       NT_STATUS_SHARING_VIOLATION);
1594         }
1595
1596         cli_close(&cli, fnum);
1597         cli_unlink(&cli, fname);
1598
1599         if (!torture_close_connection(&cli)) {
1600                 correct = False;
1601         }
1602
1603         printf("unlink test finished\n");
1604         
1605         return correct;
1606 }
1607
1608
1609 /*
1610 test how many open files this server supports on the one socket
1611 */
1612 static BOOL run_maxfidtest(int dummy)
1613 {
1614         static struct cli_state cli;
1615         char *template = "\\maxfid.%d.%d";
1616         fstring fname;
1617         int fnums[0x11000], i;
1618         int retries=4;
1619         BOOL correct = True;
1620
1621         cli = current_cli;
1622
1623         if (retries <= 0) {
1624                 printf("failed to connect\n");
1625                 return False;
1626         }
1627
1628         cli_sockopt(&cli, sockops);
1629
1630         for (i=0; i<0x11000; i++) {
1631                 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1632                 if ((fnums[i] = cli_open(&cli, fname, 
1633                                         O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1634                     -1) {
1635                         printf("open of %s failed (%s)\n", 
1636                                fname, cli_errstr(&cli));
1637                         printf("maximum fnum is %d\n", i);
1638                         break;
1639                 }
1640                 printf("%6d\r", i);
1641         }
1642         printf("%6d\n", i);
1643         i--;
1644
1645         printf("cleaning up\n");
1646         for (;i>=0;i--) {
1647                 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1648                 cli_close(&cli, fnums[i]);
1649                 if (!cli_unlink(&cli, fname)) {
1650                         printf("unlink of %s failed (%s)\n", 
1651                                fname, cli_errstr(&cli));
1652                         correct = False;
1653                 }
1654                 printf("%6d\r", i);
1655         }
1656         printf("%6d\n", 0);
1657
1658         printf("maxfid test finished\n");
1659         if (!torture_close_connection(&cli)) {
1660                 correct = False;
1661         }
1662         return correct;
1663 }
1664
1665 /* generate a random buffer */
1666 static void rand_buf(char *buf, int len)
1667 {
1668         while (len--) {
1669                 *buf = (char)sys_random();
1670                 buf++;
1671         }
1672 }
1673
1674 /* send smb negprot commands, not reading the response */
1675 static BOOL run_negprot_nowait(int dummy)
1676 {
1677         int i;
1678         static struct cli_state cli;
1679         BOOL correct = True;
1680
1681         printf("starting negprot nowait test\n");
1682
1683         if (!open_nbt_connection(&cli)) {
1684                 return False;
1685         }
1686
1687         for (i=0;i<50000;i++) {
1688                 cli_negprot_send(&cli);
1689         }
1690
1691         if (!torture_close_connection(&cli)) {
1692                 correct = False;
1693         }
1694
1695         printf("finished negprot nowait test\n");
1696
1697         return correct;
1698 }
1699
1700
1701 /* send random IPC commands */
1702 static BOOL run_randomipc(int dummy)
1703 {
1704         char *rparam = NULL;
1705         char *rdata = NULL;
1706         int rdrcnt,rprcnt;
1707         pstring param;
1708         int api, param_len, i;
1709         static struct cli_state cli;
1710         BOOL correct = True;
1711         int count = 50000;
1712
1713         printf("starting random ipc test\n");
1714
1715         if (!torture_open_connection(&cli)) {
1716                 return False;
1717         }
1718
1719         for (i=0;i<count;i++) {
1720                 api = sys_random() % 500;
1721                 param_len = (sys_random() % 64);
1722
1723                 rand_buf(param, param_len);
1724   
1725                 SSVAL(param,0,api); 
1726
1727                 cli_api(&cli, 
1728                         param, param_len, 8,  
1729                         NULL, 0, BUFFER_SIZE, 
1730                         &rparam, &rprcnt,     
1731                         &rdata, &rdrcnt);
1732                 if (i % 100 == 0) {
1733                         printf("%d/%d\r", i,count);
1734                 }
1735         }
1736         printf("%d/%d\n", i, count);
1737
1738         if (!torture_close_connection(&cli)) {
1739                 correct = False;
1740         }
1741
1742         printf("finished random ipc test\n");
1743
1744         return correct;
1745 }
1746
1747
1748
1749 static void browse_callback(const char *sname, uint32 stype, 
1750                             const char *comment, void *state)
1751 {
1752         printf("\t%20.20s %08x %s\n", sname, stype, comment);
1753 }
1754
1755
1756
1757 /*
1758   This test checks the browse list code
1759
1760 */
1761 static BOOL run_browsetest(int dummy)
1762 {
1763         static struct cli_state cli;
1764         BOOL correct = True;
1765
1766         printf("starting browse test\n");
1767
1768         if (!torture_open_connection(&cli)) {
1769                 return False;
1770         }
1771
1772         printf("domain list:\n");
1773         cli_NetServerEnum(&cli, cli.server_domain, 
1774                           SV_TYPE_DOMAIN_ENUM,
1775                           browse_callback, NULL);
1776
1777         printf("machine list:\n");
1778         cli_NetServerEnum(&cli, cli.server_domain, 
1779                           SV_TYPE_ALL,
1780                           browse_callback, NULL);
1781
1782         if (!torture_close_connection(&cli)) {
1783                 correct = False;
1784         }
1785
1786         printf("browse test finished\n");
1787
1788         return correct;
1789
1790 }
1791
1792
1793 /*
1794   This checks how the getatr calls works
1795 */
1796 static BOOL run_attrtest(int dummy)
1797 {
1798         static struct cli_state cli;
1799         int fnum;
1800         time_t t, t2;
1801         char *fname = "\\attrib.tst";
1802         BOOL correct = True;
1803
1804         printf("starting attrib test\n");
1805
1806         if (!torture_open_connection(&cli)) {
1807                 return False;
1808         }
1809
1810         cli_unlink(&cli, fname);
1811         fnum = cli_open(&cli, fname, 
1812                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1813         cli_close(&cli, fnum);
1814         if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1815                 printf("getatr failed (%s)\n", cli_errstr(&cli));
1816                 correct = False;
1817         }
1818
1819         if (abs(t - time(NULL)) > 2) {
1820                 printf("ERROR: SMBgetatr bug. time is %s",
1821                        ctime(&t));
1822                 t = time(NULL);
1823                 correct = True;
1824         }
1825
1826         t2 = t-60*60*24; /* 1 day ago */
1827
1828         if (!cli_setatr(&cli, fname, 0, t2)) {
1829                 printf("setatr failed (%s)\n", cli_errstr(&cli));
1830                 correct = True;
1831         }
1832
1833         if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1834                 printf("getatr failed (%s)\n", cli_errstr(&cli));
1835                 correct = True;
1836         }
1837
1838         if (t != t2) {
1839                 printf("ERROR: getatr/setatr bug. times are\n%s",
1840                        ctime(&t));
1841                 printf("%s", ctime(&t2));
1842                 correct = True;
1843         }
1844
1845         cli_unlink(&cli, fname);
1846
1847         if (!torture_close_connection(&cli)) {
1848                 correct = False;
1849         }
1850
1851         printf("attrib test finished\n");
1852
1853         return correct;
1854 }
1855
1856
1857 /*
1858   This checks a couple of trans2 calls
1859 */
1860 static BOOL run_trans2test(int dummy)
1861 {
1862         static struct cli_state cli;
1863         int fnum;
1864         size_t size;
1865         time_t c_time, a_time, m_time, w_time, m_time2;
1866         char *fname = "\\trans2.tst";
1867         char *dname = "\\trans2";
1868         char *fname2 = "\\trans2\\trans2.tst";
1869         BOOL correct = True;
1870
1871         printf("starting trans2 test\n");
1872
1873         if (!torture_open_connection(&cli)) {
1874                 return False;
1875         }
1876
1877         cli_unlink(&cli, fname);
1878         fnum = cli_open(&cli, fname, 
1879                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1880         if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
1881                            NULL, NULL)) {
1882                 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
1883                 correct = False;
1884         }
1885         cli_close(&cli, fnum);
1886
1887         sleep(2);
1888
1889         cli_unlink(&cli, fname);
1890         fnum = cli_open(&cli, fname, 
1891                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1892         if (fnum == -1) {
1893                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1894                 return False;
1895         }
1896         cli_close(&cli, fnum);
1897
1898         if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
1899                 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
1900                 correct = False;
1901         } else {
1902                 if (c_time != m_time) {
1903                         printf("create time=%s", ctime(&c_time));
1904                         printf("modify time=%s", ctime(&m_time));
1905                         printf("This system appears to have sticky create times\n");
1906                         correct = False;
1907                 }
1908                 if (a_time % (60*60) == 0) {
1909                         printf("access time=%s", ctime(&a_time));
1910                         printf("This system appears to set a midnight access time\n");
1911                         correct = False;
1912                 }
1913
1914                 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1915                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1916                         correct = False;
1917                 }
1918         }
1919
1920
1921         cli_unlink(&cli, fname);
1922         fnum = cli_open(&cli, fname, 
1923                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1924         cli_close(&cli, fnum);
1925         if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time, 
1926                             &w_time, &size, NULL, NULL)) {
1927                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
1928                 correct = False;
1929         } else {
1930                 if (w_time < 60*60*24*2) {
1931                         printf("write time=%s", ctime(&w_time));
1932                         printf("This system appears to set a initial 0 write time\n");
1933                         correct = False;
1934                 }
1935         }
1936
1937         cli_unlink(&cli, fname);
1938
1939
1940         /* check if the server updates the directory modification time
1941            when creating a new file */
1942         if (!cli_mkdir(&cli, dname)) {
1943                 printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
1944                 correct = False;
1945         }
1946         sleep(3);
1947         if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time, 
1948                             &w_time, &size, NULL, NULL)) {
1949                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
1950                 correct = False;
1951         }
1952
1953         fnum = cli_open(&cli, fname2, 
1954                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1955         cli_write(&cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
1956         cli_close(&cli, fnum);
1957         if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2, 
1958                             &w_time, &size, NULL, NULL)) {
1959                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
1960                 correct = False;
1961         } else {
1962                 if (m_time2 == m_time) {
1963                         printf("This system does not update directory modification times\n");
1964                         correct = False;
1965                 }
1966         }
1967         cli_unlink(&cli, fname2);
1968         cli_rmdir(&cli, dname);
1969
1970         if (!torture_close_connection(&cli)) {
1971                 correct = False;
1972         }
1973
1974         printf("trans2 test finished\n");
1975
1976         return correct;
1977 }
1978
1979 /*
1980   This checks new W2K calls.
1981 */
1982
1983 static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
1984 {
1985         char buf[4096];
1986         BOOL correct = True;
1987
1988         memset(buf, 0xff, sizeof(buf));
1989
1990         if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
1991                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
1992                 correct = False;
1993         } else {
1994                 printf("qfileinfo: level %d\n", level);
1995                 dump_data(0, buf, 256);
1996                 printf("\n");
1997         }
1998         return correct;
1999 }
2000
2001 static BOOL run_w2ktest(int dummy)
2002 {
2003         static struct cli_state cli;
2004         int fnum;
2005         char *fname = "\\w2ktest\\w2k.tst";
2006         int level;
2007         BOOL correct = True;
2008
2009         printf("starting w2k test\n");
2010
2011         if (!torture_open_connection(&cli)) {
2012                 return False;
2013         }
2014
2015         fnum = cli_open(&cli, fname, 
2016                         O_RDWR | O_CREAT , DENY_NONE);
2017
2018         for (level = 1004; level < 1040; level++) {
2019                 new_trans(&cli, fnum, level);
2020         }
2021
2022         cli_close(&cli, fnum);
2023
2024         if (!torture_close_connection(&cli)) {
2025                 correct = False;
2026         }
2027
2028         printf("w2k test finished\n");
2029         
2030         return correct;
2031 }
2032
2033
2034 /*
2035   this is a harness for some oplock tests
2036  */
2037 static BOOL run_oplock1(int dummy)
2038 {
2039         static struct cli_state cli1;
2040         char *fname = "\\lockt1.lck";
2041         int fnum1;
2042         BOOL correct = True;
2043
2044         printf("starting oplock test 1\n");
2045
2046         if (!torture_open_connection(&cli1)) {
2047                 return False;
2048         }
2049
2050         cli_unlink(&cli1, fname);
2051
2052         cli_sockopt(&cli1, sockops);
2053
2054         cli1.use_oplocks = True;
2055
2056         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2057         if (fnum1 == -1) {
2058                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2059                 return False;
2060         }
2061
2062         cli1.use_oplocks = False;
2063
2064         cli_unlink(&cli1, fname);
2065         cli_unlink(&cli1, fname);
2066
2067         if (!cli_close(&cli1, fnum1)) {
2068                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2069                 return False;
2070         }
2071
2072         if (!cli_unlink(&cli1, fname)) {
2073                 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2074                 return False;
2075         }
2076
2077         if (!torture_close_connection(&cli1)) {
2078                 correct = False;
2079         }
2080
2081         printf("finished oplock test 1\n");
2082
2083         return correct;
2084 }
2085
2086 static BOOL run_oplock2(int dummy)
2087 {
2088         static struct cli_state cli1, cli2;
2089         char *fname = "\\lockt2.lck";
2090         int fnum1, fnum2;
2091         int saved_use_oplocks = use_oplocks;
2092         char buf[4];
2093         BOOL correct = True;
2094         volatile BOOL *shared_correct;
2095
2096         shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2097         *shared_correct = True;
2098
2099         use_level_II_oplocks = True;
2100         use_oplocks = True;
2101
2102         printf("starting oplock test 2\n");
2103
2104         if (!torture_open_connection(&cli1)) {
2105                 use_level_II_oplocks = False;
2106                 use_oplocks = saved_use_oplocks;
2107                 return False;
2108         }
2109
2110         cli1.use_oplocks = True;
2111         cli1.use_level_II_oplocks = True;
2112
2113         if (!torture_open_connection(&cli2)) {
2114                 use_level_II_oplocks = False;
2115                 use_oplocks = saved_use_oplocks;
2116                 return False;
2117         }
2118
2119         cli2.use_oplocks = True;
2120         cli2.use_level_II_oplocks = True;
2121
2122         cli_unlink(&cli1, fname);
2123
2124         cli_sockopt(&cli1, sockops);
2125         cli_sockopt(&cli2, sockops);
2126
2127         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2128         if (fnum1 == -1) {
2129                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2130                 return False;
2131         }
2132
2133         /* Don't need the globals any more. */
2134         use_level_II_oplocks = False;
2135         use_oplocks = saved_use_oplocks;
2136
2137         if (fork() == 0) {
2138                 /* Child code */
2139                 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
2140                 if (fnum2 == -1) {
2141                         printf("second open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2142                         *shared_correct = False;
2143                         exit(0);
2144                 }
2145
2146                 sleep(2);
2147
2148                 if (!cli_close(&cli2, fnum2)) {
2149                         printf("close2 failed (%s)\n", cli_errstr(&cli1));
2150                         *shared_correct = False;
2151                 }
2152
2153                 exit(0);
2154         }
2155
2156         sleep(2);
2157
2158         /* Ensure cli1 processes the break. */
2159
2160         if (cli_read(&cli1, fnum1, buf, 0, 4) != 4) {
2161                 printf("read on fnum1 failed (%s)\n", cli_errstr(&cli1));
2162                 correct = False;
2163         }
2164
2165         /* Should now be at level II. */
2166         /* Test if sending a write locks causes a break to none. */
2167
2168         if (!cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2169                 printf("lock failed (%s)\n", cli_errstr(&cli1));
2170                 correct = False;
2171         }
2172
2173         cli_unlock(&cli1, fnum1, 0, 4);
2174
2175         sleep(2);
2176
2177         if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2178                 printf("lock failed (%s)\n", cli_errstr(&cli1));
2179                 correct = False;
2180         }
2181
2182         cli_unlock(&cli1, fnum1, 0, 4);
2183
2184         sleep(2);
2185
2186         cli_read(&cli1, fnum1, buf, 0, 4);
2187
2188 #if 0
2189         if (cli_write(&cli1, fnum1, 0, buf, 0, 4) != 4) {
2190                 printf("write on fnum1 failed (%s)\n", cli_errstr(&cli1));
2191                 correct = False;
2192         }
2193 #endif
2194
2195         if (!cli_close(&cli1, fnum1)) {
2196                 printf("close1 failed (%s)\n", cli_errstr(&cli1));
2197                 correct = False;
2198         }
2199
2200         sleep(4);
2201
2202         if (!cli_unlink(&cli1, fname)) {
2203                 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2204                 correct = False;
2205         }
2206
2207         if (!torture_close_connection(&cli1)) {
2208                 correct = False;
2209         }
2210
2211         if (!*shared_correct) {
2212                 correct = False;
2213         }
2214
2215         printf("finished oplock test 2\n");
2216
2217         return correct;
2218 }
2219
2220 /* handler for oplock 3 tests */
2221 static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2222 {
2223         printf("got oplock break fnum=%d level=%d\n",
2224                fnum, level);
2225         return cli_oplock_ack(cli, fnum, level);
2226 }
2227
2228 static BOOL run_oplock3(int dummy)
2229 {
2230         static struct cli_state cli;
2231         char *fname = "\\oplockt3.dat";
2232         int fnum;
2233         char buf[4] = "abcd";
2234         BOOL correct = True;
2235         volatile BOOL *shared_correct;
2236
2237         shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2238         *shared_correct = True;
2239
2240         printf("starting oplock test 3\n");
2241
2242         if (fork() == 0) {
2243                 /* Child code */
2244                 use_oplocks = True;
2245                 use_level_II_oplocks = True;
2246                 if (!torture_open_connection(&cli)) {
2247                         *shared_correct = False;
2248                         exit(0);
2249                 } 
2250                 sleep(2);
2251                 /* try to trigger a oplock break in parent */
2252                 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2253                 cli_write(&cli, fnum, 0, buf, 0, 4);
2254                 exit(0);
2255         }
2256
2257         /* parent code */
2258         use_oplocks = True;
2259         use_level_II_oplocks = True;
2260         if (!torture_open_connection(&cli)) { 
2261                 return False;
2262         }
2263         cli_oplock_handler(&cli, oplock3_handler);
2264         fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2265         cli_write(&cli, fnum, 0, buf, 0, 4);
2266         cli_close(&cli, fnum);
2267         fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2268         cli.timeout = 20000;
2269         cli_receive_smb(&cli);
2270         printf("finished oplock test 3\n");
2271
2272         return (correct && *shared_correct);
2273
2274 /* What are we looking for here?  What's sucess and what's FAILURE? */
2275 }
2276
2277
2278
2279 /*
2280   Test delete on close semantics.
2281  */
2282 static BOOL run_deletetest(int dummy)
2283 {
2284         static struct cli_state cli1;
2285         static struct cli_state cli2;
2286         char *fname = "\\delete.file";
2287         int fnum1, fnum2;
2288         BOOL correct = True;
2289         
2290         printf("starting delete test\n");
2291         
2292         if (!torture_open_connection(&cli1)) {
2293                 return False;
2294         }
2295         
2296         cli_sockopt(&cli1, sockops);
2297
2298         /* Test 1 - this should *NOT* delete the file on close. */
2299         
2300         cli_setatr(&cli1, fname, 0, 0);
2301         cli_unlink(&cli1, fname);
2302         
2303         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2304                                    FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 
2305                                    DELETE_ON_CLOSE_FLAG);
2306         
2307         if (fnum1 == -1) {
2308                 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2309                 return False;
2310         }
2311         
2312         if (!cli_close(&cli1, fnum1)) {
2313                 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2314                 return False;
2315         }
2316
2317         fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
2318         if (fnum1 == -1) {
2319                 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2320                 return False;
2321         }
2322         
2323         if (!cli_close(&cli1, fnum1)) {
2324                 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2325                 return False;
2326         }
2327         
2328         printf("first delete on close test succeeded.\n");
2329         
2330         /* Test 2 - this should delete the file on close. */
2331         
2332         cli_setatr(&cli1, fname, 0, 0);
2333         cli_unlink(&cli1, fname);
2334         
2335         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS,
2336                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, 
2337                                    FILE_OVERWRITE_IF, 0);
2338         
2339         if (fnum1 == -1) {
2340                 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2341                 return False;
2342         }
2343         
2344         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2345                 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2346                 return False;
2347         }
2348         
2349         if (!cli_close(&cli1, fnum1)) {
2350                 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2351                 return False;
2352         }
2353         
2354         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2355         if (fnum1 != -1) {
2356                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2357                 if (!cli_close(&cli1, fnum1)) {
2358                         printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2359                         correct = False;
2360                 }
2361                 cli_unlink(&cli1, fname);
2362         } else
2363                 printf("second delete on close test succeeded.\n");
2364         
2365         /* Test 3 - ... */
2366         cli_setatr(&cli1, fname, 0, 0);
2367         cli_unlink(&cli1, fname);
2368
2369         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2370                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2371
2372         if (fnum1 == -1) {
2373                 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2374                 return False;
2375         }
2376
2377         /* This should fail with a sharing violation - open for delete is only compatible
2378            with SHARE_DELETE. */
2379
2380         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2381                         FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0);
2382
2383         if (fnum2 != -1) {
2384                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
2385                 return False;
2386         }
2387
2388         /* This should succeed. */
2389
2390         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2391                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2392
2393         if (fnum2 == -1) {
2394                 printf("[3] open  - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2395                 return False;
2396         }
2397
2398         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2399                 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2400                 return False;
2401         }
2402         
2403         if (!cli_close(&cli1, fnum1)) {
2404                 printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1));
2405                 return False;
2406         }
2407         
2408         if (!cli_close(&cli1, fnum2)) {
2409                 printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1));
2410                 return False;
2411         }
2412         
2413         /* This should fail - file should no longer be there. */
2414
2415         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2416         if (fnum1 != -1) {
2417                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2418                 if (!cli_close(&cli1, fnum1)) {
2419                         printf("[3] close failed (%s)\n", cli_errstr(&cli1));
2420                 }
2421                 cli_unlink(&cli1, fname);
2422                 correct = False;
2423         } else
2424                 printf("third delete on close test succeeded.\n");
2425
2426         /* Test 4 ... */
2427         cli_setatr(&cli1, fname, 0, 0);
2428         cli_unlink(&cli1, fname);
2429
2430         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2431                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2432                                                                 
2433         if (fnum1 == -1) {
2434                 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2435                 return False;
2436         }
2437
2438         /* This should succeed. */
2439         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2440                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2441         if (fnum2 == -1) {
2442                 printf("[4] open  - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2443                 return False;
2444         }
2445         
2446         if (!cli_close(&cli1, fnum2)) {
2447                 printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1));
2448                 return False;
2449         }
2450         
2451         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2452                 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2453                 return False;
2454         }
2455         
2456         /* This should fail - no more opens once delete on close set. */
2457         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2458                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2459         if (fnum2 != -1) {
2460                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
2461                 return False;
2462         } else
2463                 printf("fourth delete on close test succeeded.\n");
2464         
2465         if (!cli_close(&cli1, fnum1)) {
2466                 printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1));
2467                 return False;
2468         }
2469         
2470         /* Test 5 ... */
2471         cli_setatr(&cli1, fname, 0, 0);
2472         cli_unlink(&cli1, fname);
2473         
2474         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
2475         if (fnum1 == -1) {
2476                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2477                 return False;
2478         }
2479
2480         /* This should fail - only allowed on NT opens with DELETE access. */
2481
2482         if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2483                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2484                 return False;
2485         }
2486
2487         if (!cli_close(&cli1, fnum1)) {
2488                 printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1));
2489                 return False;
2490         }
2491         
2492         printf("fifth delete on close test succeeded.\n");
2493         
2494         /* Test 6 ... */
2495         cli_setatr(&cli1, fname, 0, 0);
2496         cli_unlink(&cli1, fname);
2497         
2498         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2499                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2500                                    FILE_OVERWRITE_IF, 0);
2501         
2502         if (fnum1 == -1) {
2503                 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2504                 return False;
2505         }
2506         
2507         /* This should fail - only allowed on NT opens with DELETE access. */
2508         
2509         if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2510                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2511                 return False;
2512         }
2513
2514         if (!cli_close(&cli1, fnum1)) {
2515                 printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1));
2516                 return False;
2517         }
2518
2519         printf("sixth delete on close test succeeded.\n");
2520         
2521         /* Test 7 ... */
2522         cli_setatr(&cli1, fname, 0, 0);
2523         cli_unlink(&cli1, fname);
2524         
2525         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2526                                    FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0);
2527                                                                 
2528         if (fnum1 == -1) {
2529                 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2530                 return False;
2531         }
2532
2533         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2534                 printf("[7] setting delete_on_close on file failed !\n");
2535                 return False;
2536         }
2537         
2538         if (!cli_nt_delete_on_close(&cli1, fnum1, False)) {
2539                 printf("[7] unsetting delete_on_close on file failed !\n");
2540                 return False;
2541         }
2542
2543         if (!cli_close(&cli1, fnum1)) {
2544                 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2545                 return False;
2546         }
2547         
2548         /* This next open should succeed - we reset the flag. */
2549         
2550         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2551         if (fnum1 == -1) {
2552                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2553                 return False;
2554         }
2555
2556         if (!cli_close(&cli1, fnum1)) {
2557                 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2558                 return False;
2559         }
2560
2561         printf("seventh delete on close test succeeded.\n");
2562         
2563         /* Test 7 ... */
2564         cli_setatr(&cli1, fname, 0, 0);
2565         cli_unlink(&cli1, fname);
2566         
2567         if (!torture_open_connection(&cli2)) {
2568                 printf("[8] failed to open second connection.\n");
2569                 return False;
2570         }
2571
2572         cli_sockopt(&cli1, sockops);
2573         
2574         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2575                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
2576         
2577         if (fnum1 == -1) {
2578                 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2579                 return False;
2580         }
2581
2582         fnum2 = cli_nt_create_full(&cli2, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2583                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2584         
2585         if (fnum2 == -1) {
2586                 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2587                 return False;
2588         }
2589
2590         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2591                 printf("[8] setting delete_on_close on file failed !\n");
2592                 return False;
2593         }
2594         
2595         if (!cli_close(&cli1, fnum1)) {
2596                 printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1));
2597                 return False;
2598         }
2599
2600         if (!cli_close(&cli2, fnum2)) {
2601                 printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2));
2602                 return False;
2603         }
2604
2605         /* This should fail.. */
2606         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2607         if (fnum1 != -1) {
2608                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2609                 if (!cli_close(&cli1, fnum1)) {
2610                         printf("[8] close failed (%s)\n", cli_errstr(&cli1));
2611                 }
2612                 cli_unlink(&cli1, fname);
2613                 correct = False;
2614         } else
2615                 printf("eighth delete on close test succeeded.\n");
2616
2617         printf("finished delete test\n");
2618         
2619         cli_setatr(&cli1, fname, 0, 0);
2620         cli_unlink(&cli1, fname);
2621         
2622         if (!torture_close_connection(&cli1)) {
2623                 correct = False;
2624         }
2625         if (!torture_close_connection(&cli2)) {
2626                 correct = False;
2627         }
2628         return correct;
2629 }
2630
2631 /*
2632   Test open mode returns on read-only files.
2633  */
2634 static BOOL run_opentest(int dummy)
2635 {
2636         static struct cli_state cli1;
2637         char *fname = "\\readonly.file";
2638         int fnum1, fnum2;
2639         char buf[20];
2640         size_t fsize;
2641         BOOL correct = True;
2642         char *tmp_path;
2643
2644         printf("starting open test\n");
2645         
2646         if (!torture_open_connection(&cli1)) {
2647                 return False;
2648         }
2649         
2650         cli_setatr(&cli1, fname, 0, 0);
2651         cli_unlink(&cli1, fname);
2652         
2653         cli_sockopt(&cli1, sockops);
2654         
2655         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2656         if (fnum1 == -1) {
2657                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2658                 return False;
2659         }
2660
2661         if (!cli_close(&cli1, fnum1)) {
2662                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2663                 return False;
2664         }
2665         
2666         if (!cli_setatr(&cli1, fname, aRONLY, 0)) {
2667                 printf("cli_setatr failed (%s)\n", cli_errstr(&cli1));
2668                 return False;
2669         }
2670         
2671         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
2672         if (fnum1 == -1) {
2673                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2674                 return False;
2675         }
2676         
2677         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
2678         fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
2679         
2680         if (check_error(__LINE__, &cli1, ERRDOS, ERRnoaccess, 
2681                         NT_STATUS_ACCESS_DENIED)) {
2682                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
2683         }
2684         
2685         printf("finished open test 1\n");
2686         
2687         cli_close(&cli1, fnum1);
2688         
2689         /* Now try not readonly and ensure ERRbadshare is returned. */
2690         
2691         cli_setatr(&cli1, fname, 0, 0);
2692         
2693         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
2694         if (fnum1 == -1) {
2695                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2696                 return False;
2697         }
2698         
2699         /* This will fail - but the error should be ERRshare. */
2700         fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
2701         
2702         if (check_error(__LINE__, &cli1, ERRDOS, ERRbadshare, 
2703                         NT_STATUS_SHARING_VIOLATION)) {
2704                 printf("correct error code ERRDOS/ERRbadshare returned\n");
2705         }
2706         
2707         if (!cli_close(&cli1, fnum1)) {
2708                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2709                 return False;
2710         }
2711         
2712         cli_unlink(&cli1, fname);
2713         
2714         printf("finished open test 2\n");
2715         
2716         /* Test truncate open disposition on file opened for read. */
2717         
2718         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2719         if (fnum1 == -1) {
2720                 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(&cli1));
2721                 return False;
2722         }
2723         
2724         /* write 20 bytes. */
2725         
2726         memset(buf, '\0', 20);
2727
2728         if (cli_write(&cli1, fnum1, 0, buf, 0, 20) != 20) {
2729                 printf("write failed (%s)\n", cli_errstr(&cli1));
2730                 correct = False;
2731         }
2732
2733         if (!cli_close(&cli1, fnum1)) {
2734                 printf("(3) close1 failed (%s)\n", cli_errstr(&cli1));
2735                 return False;
2736         }
2737         
2738         /* Ensure size == 20. */
2739         if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
2740                 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
2741                 return False;
2742         }
2743         
2744         if (fsize != 20) {
2745                 printf("(3) file size != 20\n");
2746                 return False;
2747         }
2748
2749         /* Now test if we can truncate a file opened for readonly. */
2750         
2751         fnum1 = cli_open(&cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
2752         if (fnum1 == -1) {
2753                 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(&cli1));
2754                 return False;
2755         }
2756         
2757         if (!cli_close(&cli1, fnum1)) {
2758                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2759                 return False;
2760         }
2761
2762         /* Ensure size == 0. */
2763         if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
2764                 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
2765                 return False;
2766         }
2767
2768         if (fsize != 0) {
2769                 printf("(3) file size != 0\n");
2770                 return False;
2771         }
2772         printf("finished open test 3\n");
2773         
2774         cli_unlink(&cli1, fname);
2775
2776
2777         printf("testing ctemp\n");
2778         fnum1 = cli_ctemp(&cli1, "\\", &tmp_path);
2779         if (fnum1 == -1) {
2780                 printf("ctemp failed (%s)\n", cli_errstr(&cli1));
2781                 return False;
2782         }
2783         printf("ctemp gave path %s\n", tmp_path);
2784         if (!cli_close(&cli1, fnum1)) {
2785                 printf("close of temp failed (%s)\n", cli_errstr(&cli1));
2786         }
2787         if (!cli_unlink(&cli1, tmp_path)) {
2788                 printf("unlink of temp failed (%s)\n", cli_errstr(&cli1));
2789         }
2790         
2791         if (!torture_close_connection(&cli1)) {
2792                 correct = False;
2793         }
2794         
2795         return correct;
2796 }
2797
2798 static void list_fn(file_info *finfo, const char *name, void *state)
2799 {
2800         
2801 }
2802
2803 /*
2804   test directory listing speed
2805  */
2806 static BOOL run_dirtest(int dummy)
2807 {
2808         int i;
2809         static struct cli_state cli;
2810         int fnum;
2811         double t1;
2812         BOOL correct = True;
2813
2814         printf("starting directory test\n");
2815
2816         if (!torture_open_connection(&cli)) {
2817                 return False;
2818         }
2819
2820         cli_sockopt(&cli, sockops);
2821
2822         srandom(0);
2823         for (i=0;i<numops;i++) {
2824                 fstring fname;
2825                 slprintf(fname, sizeof(fname), "%x", (int)random());
2826                 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2827                 if (fnum == -1) {
2828                         fprintf(stderr,"Failed to open %s\n", fname);
2829                         return False;
2830                 }
2831                 cli_close(&cli, fnum);
2832         }
2833
2834         t1 = end_timer();
2835
2836         printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
2837         printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
2838         printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
2839
2840         printf("dirtest core %g seconds\n", end_timer() - t1);
2841
2842         srandom(0);
2843         for (i=0;i<numops;i++) {
2844                 fstring fname;
2845                 slprintf(fname, sizeof(fname), "%x", (int)random());
2846                 cli_unlink(&cli, fname);
2847         }
2848
2849         if (!torture_close_connection(&cli)) {
2850                 correct = False;
2851         }
2852
2853         printf("finished dirtest\n");
2854
2855         return correct;
2856 }
2857
2858 static BOOL run_error_map_extract(int dummy) {
2859         
2860         static struct cli_state c_dos;
2861         static struct cli_state c_nt;
2862
2863         uint32 error;
2864
2865         uint32 flgs2, errnum;
2866         uint8 errclass;
2867
2868         NTSTATUS nt_status;
2869
2870         fstring user;
2871
2872         if (!open_nbt_connection(&c_nt)) {
2873                 return False;
2874         }
2875
2876         if (!cli_negprot(&c_nt)) {
2877                 printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(&c_nt));
2878                 cli_shutdown(&c_nt);
2879                 return False;
2880         }
2881
2882         if (!open_nbt_connection(&c_dos)) {
2883                 return False;
2884         }
2885
2886         c_dos.force_dos_errors = True;
2887         if (!cli_negprot(&c_dos)) {
2888                 printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(&c_dos));
2889                 cli_shutdown(&c_dos);
2890                 return False;
2891         }
2892
2893         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
2894                 snprintf(user, sizeof(user), "%X", error);
2895
2896                 if (!cli_session_setup(&c_nt, user, 
2897                                        password, strlen(password),
2898                                        password, strlen(password),
2899                                        workgroup)) {
2900                         flgs2 = SVAL(c_nt.inbuf,smb_flg2);
2901                         
2902                         /* Case #1: 32-bit NT errors */
2903                         if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
2904                                 nt_status = NT_STATUS(IVAL(c_nt.inbuf,smb_rcls));
2905                         } else {
2906                                 printf("** Dos error on NT connection! (%s)\n", cli_errstr(&c_nt));
2907                                 nt_status = NT_STATUS(0xc0000000);
2908                         }
2909                 } else {
2910                         printf("** Session setup succeeded.  This shouldn't happen...\n");
2911                 }
2912
2913                 if (!cli_session_setup(&c_dos, user, 
2914                                        password, strlen(password),
2915                                        password, strlen(password),
2916                                        workgroup)) {
2917                         flgs2 = SVAL(c_dos.inbuf,smb_flg2), errnum;
2918                         
2919                         /* Case #1: 32-bit NT errors */
2920                         if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
2921                                 printf("** NT error on DOS connection! (%s)\n", cli_errstr(&c_nt));
2922                                 errnum = errclass = 0;
2923                         } else {
2924                                 cli_dos_error(&c_dos, &errclass, &errnum);
2925                         }
2926                 } else {
2927                         printf("** Session setup succeeded.  This shouldn't happen...\n");
2928                 }
2929                 if (NT_STATUS_V(nt_status) == error) { 
2930                         printf("\t{%s,\t%s,\t%s},\n", smb_dos_err_class(errclass), smb_dos_err_name(errclass, errnum), get_nt_error_c_code(nt_status));
2931                 } else {
2932                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", get_nt_error_c_code(NT_STATUS(error)), get_nt_error_c_code(nt_status));
2933                 }
2934         }
2935         return True;
2936 }
2937
2938 static double create_procs(BOOL (*fn)(int), BOOL *result)
2939 {
2940         int i, status;
2941         volatile pid_t *child_status;
2942         volatile BOOL *child_status_out;
2943         int synccount;
2944         int tries = 8;
2945
2946         synccount = 0;
2947
2948         child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
2949         if (!child_status) {
2950                 printf("Failed to setup shared memory\n");
2951                 return -1;
2952         }
2953
2954         child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
2955         if (!child_status_out) {
2956                 printf("Failed to setup result status shared memory\n");
2957                 return -1;
2958         }
2959
2960         memset((void *)child_status, 0, sizeof(pid_t)*nprocs);
2961         memset((void *)child_status_out, True, sizeof(BOOL)*nprocs);
2962
2963         start_timer();
2964
2965         for (i=0;i<nprocs;i++) {
2966                 procnum = i;
2967                 if (fork() == 0) {
2968                         pid_t mypid = getpid();
2969                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
2970
2971                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
2972
2973                         while (1) {
2974                                 memset(&current_cli, 0, sizeof(current_cli));
2975                                 if (torture_open_connection(&current_cli)) break;
2976                                 if (tries-- == 0) {
2977                                         printf("pid %d failed to start\n", (int)getpid());
2978                                         _exit(1);
2979                                 }
2980                                 msleep(10);     
2981                         }
2982
2983                         child_status[i] = getpid();
2984
2985                         while (child_status[i]) msleep(2);
2986
2987                         child_status_out[i] = fn(i);
2988                         _exit(0);
2989                 }
2990         }
2991
2992         do {
2993                 synccount = 0;
2994                 for (i=0;i<nprocs;i++) {
2995                         if (child_status[i]) synccount++;
2996                 }
2997                 if (synccount == nprocs) break;
2998                 msleep(10);
2999         } while (end_timer() < 30);
3000
3001         if (synccount != nprocs) {
3002                 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
3003                 *result = False;
3004                 return end_timer();
3005         }
3006
3007         /* start the client load */
3008         start_timer();
3009
3010         for (i=0;i<nprocs;i++) {
3011                 child_status[i] = 0;
3012         }
3013
3014         printf("%d clients started\n", nprocs);
3015
3016         for (i=0;i<nprocs;i++) {
3017                 waitpid(0, &status, 0);
3018                 printf("*");
3019         }
3020
3021         printf("\n");
3022         
3023         for (i=0;i<nprocs;i++) {
3024                 if (!child_status_out[i]) {
3025                         *result = False;
3026                 }
3027         }
3028         return end_timer();
3029 }
3030
3031
3032 #define FLAG_MULTIPROC 1
3033
3034 static struct {
3035         char *name;
3036         BOOL (*fn)(int);
3037         unsigned flags;
3038 } torture_ops[] = {
3039         {"FDPASS", run_fdpasstest, 0},
3040         {"LOCK1",  run_locktest1,  0},
3041         {"LOCK2",  run_locktest2,  0},
3042         {"LOCK3",  run_locktest3,  0},
3043         {"LOCK4",  run_locktest4,  0},
3044         {"LOCK5",  run_locktest5,  0},
3045         {"UNLINK", run_unlinktest, 0},
3046         {"BROWSE", run_browsetest, 0},
3047         {"ATTR",   run_attrtest,   0},
3048         {"TRANS2", run_trans2test, 0},
3049         {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
3050         {"TORTURE",run_torture,    FLAG_MULTIPROC},
3051         {"RANDOMIPC", run_randomipc, 0},
3052         {"NEGNOWAIT", run_negprot_nowait, 0},
3053         {"NBW95",  run_nbw95, 0},
3054         {"NBWNT",  run_nbwnt, 0},
3055         {"OPLOCK1",  run_oplock1, 0},
3056         {"OPLOCK2",  run_oplock2, 0},
3057         {"OPLOCK3",  run_oplock3, 0},
3058         {"DIR",  run_dirtest, 0},
3059         {"DENY1",  torture_denytest1, 0},
3060         {"DENY2",  torture_denytest2, 0},
3061         {"TCON",  run_tcon_test, 0},
3062         {"RW1",  run_readwritetest, 0},
3063         {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
3064         {"RW3",  run_readwritelarge, 0},
3065         {"OPEN", run_opentest, 0},
3066         {"DELETE", run_deletetest, 0},
3067         {"W2K", run_w2ktest, 0},
3068         {"TRANS2SCAN", torture_trans2_scan, 0},
3069         {"NTTRANSSCAN", torture_nttrans_scan, 0},
3070         {"UTABLE", torture_utable, 0},
3071         {"CASETABLE", torture_casetable, 0},
3072         {"ERRMAPEXTRACT", run_error_map_extract, 0},
3073         {NULL, NULL, 0}};
3074
3075
3076
3077 /****************************************************************************
3078 run a specified test or "ALL"
3079 ****************************************************************************/
3080 static BOOL run_test(char *name)
3081 {
3082         BOOL ret = True;
3083         BOOL result = True;
3084         int i;
3085         double t;
3086         if (strequal(name,"ALL")) {
3087                 for (i=0;torture_ops[i].name;i++) {
3088                         run_test(torture_ops[i].name);
3089                 }
3090         }
3091         
3092         for (i=0;torture_ops[i].name;i++) {
3093                 snprintf(randomfname, sizeof(randomfname), "\\XX%x", 
3094                          (unsigned)random());
3095
3096                 if (strequal(name, torture_ops[i].name)) {
3097                         printf("Running %s\n", name);
3098                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
3099                                 t = create_procs(torture_ops[i].fn, &result);
3100                                 if (!result) { 
3101                                         ret = False;
3102                                         printf("TEST %s FAILED!\n", name);
3103                                 }
3104                                          
3105                         } else {
3106                                 start_timer();
3107                                 if (!torture_ops[i].fn(0)) {
3108                                         ret = False;
3109                                         printf("TEST %s FAILED!\n", name);
3110                                 }
3111                                 t = end_timer();
3112                         }
3113                         printf("%s took %g secs\n\n", name, t);
3114                 }
3115         }
3116         return ret;
3117 }
3118
3119
3120 static void usage(void)
3121 {
3122         int i;
3123
3124         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
3125
3126         printf("\t-d debuglevel\n");
3127         printf("\t-U user%%pass\n");
3128         printf("\t-N numprocs\n");
3129         printf("\t-n my_netbios_name\n");
3130         printf("\t-W workgroup\n");
3131         printf("\t-o num_operations\n");
3132         printf("\t-O socket_options\n");
3133         printf("\t-m maximum protocol\n");
3134         printf("\t-L use oplocks\n");
3135         printf("\t-A showall\n");
3136         printf("\n\n");
3137
3138         printf("tests are:");
3139         for (i=0;torture_ops[i].name;i++) {
3140                 printf(" %s", torture_ops[i].name);
3141         }
3142         printf("\n");
3143
3144         printf("default test is ALL\n");
3145         
3146         exit(1);
3147 }
3148
3149
3150
3151
3152
3153 /****************************************************************************
3154   main program
3155 ****************************************************************************/
3156  int main(int argc,char *argv[])
3157 {
3158         int opt, i;
3159         char *p;
3160         int gotpass = 0;
3161         extern char *optarg;
3162         extern int optind;
3163         BOOL correct = True;
3164
3165         dbf = x_stdout;
3166
3167 #ifdef HAVE_SETBUFFER
3168         setbuffer(stdout, NULL, 0);
3169 #endif
3170
3171         lp_load(dyn_CONFIGFILE,True,False,False);
3172         load_interfaces();
3173
3174         if (argc < 2) {
3175                 usage();
3176         }
3177
3178         for(p = argv[1]; *p; p++)
3179           if(*p == '\\')
3180             *p = '/';
3181  
3182         if (strncmp(argv[1], "//", 2)) {
3183                 usage();
3184         }
3185
3186         fstrcpy(host, &argv[1][2]);
3187         p = strchr_m(&host[2],'/');
3188         if (!p) {
3189                 usage();
3190         }
3191         *p = 0;
3192         fstrcpy(share, p+1);
3193
3194         get_myname(myname);
3195
3196         if (*username == 0 && getenv("LOGNAME")) {
3197           pstrcpy(username,getenv("LOGNAME"));
3198         }
3199
3200         argc--;
3201         argv++;
3202
3203
3204         fstrcpy(workgroup, lp_workgroup());
3205
3206         while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:Ld:A")) != EOF) {
3207                 switch (opt) {
3208                 case 'W':
3209                         fstrcpy(workgroup,optarg);
3210                         break;
3211                 case 'm':
3212                         max_protocol = interpret_protocol(optarg, max_protocol);
3213                         break;
3214                 case 'N':
3215                         nprocs = atoi(optarg);
3216                         break;
3217                 case 'o':
3218                         numops = atoi(optarg);
3219                         break;
3220                 case 'd':
3221                         DEBUGLEVEL = atoi(optarg);
3222                         break;
3223                 case 'O':
3224                         sockops = optarg;
3225                         break;
3226                 case 'L':
3227                         use_oplocks = True;
3228                         break;
3229                 case 'A':
3230                         torture_showall = True;
3231                         break;
3232                 case 'n':
3233                         fstrcpy(myname, optarg);
3234                         break;
3235                 case 'U':
3236                         pstrcpy(username,optarg);
3237                         p = strchr_m(username,'%');
3238                         if (p) {
3239                                 *p = 0;
3240                                 pstrcpy(password, p+1);
3241                                 gotpass = 1;
3242                         }
3243                         break;
3244                 default:
3245                         printf("Unknown option %c (%d)\n", (char)opt, opt);
3246                         usage();
3247                 }
3248         }
3249
3250
3251         while (!gotpass) {
3252                 p = getpass("Password:");
3253                 if (p) {
3254                         pstrcpy(password, p);
3255                         gotpass = 1;
3256                 }
3257         }
3258
3259         printf("host=%s share=%s user=%s myname=%s\n", 
3260                host, share, username, myname);
3261
3262         if (argc == 1) {
3263                 correct = run_test("ALL");
3264         } else {
3265                 for (i=1;i<argc;i++) {
3266                         if (!run_test(argv[i])) {
3267                                 correct = False;
3268                         }
3269                 }
3270         }
3271
3272         if (correct) {
3273                 return(0);
3274         } else {
3275                 return(1);
3276         }
3277 }