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