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