a dodgy fix for a dodgy race condition in smbtorture child startup
[gd/samba-autobuild/.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, nt_errstr(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", nt_errstr(status));
203                         printf(" expected %s (line=%d)\n", nt_errstr(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[126*1024];
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 = 128*1024;
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_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
582                 printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
583                 correct = False;
584         }
585
586         if (fsize == sizeof(buf))
587                 printf("readwritelarge test 1 succeeded (size = %x)\n", fsize);
588         else {
589                 printf("readwritelarge test 1 failed (size = %x)\n", fsize);
590                 correct = False;
591         }
592
593         if (!cli_close(&cli1, fnum1)) {
594                 printf("close failed (%s)\n", cli_errstr(&cli1));
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         cli1.max_xmit = 4*1024;
610         
611         cli_smbwrite(&cli1, fnum1, buf, 0, sizeof(buf));
612         
613         if (!cli_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
614                 printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
615                 correct = False;
616         }
617
618         if (fsize == sizeof(buf))
619                 printf("readwritelarge test 2 succeeded (size = %x)\n", fsize);
620         else {
621                 printf("readwritelarge test 2 failed (size = %x)\n", fsize);
622                 correct = False;
623         }
624
625 #if 0
626         /* ToDo - set allocation. JRA */
627         if(!cli_set_allocation_size(&cli1, fnum1, 0)) {
628                 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
629                 return False;
630         }
631         if (!cli_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
632                 printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
633                 correct = False;
634         }
635         if (fsize != 0)
636                 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
637 #endif
638
639         if (!cli_close(&cli1, fnum1)) {
640                 printf("close failed (%s)\n", cli_errstr(&cli1));
641                 correct = False;
642         }
643         
644         if (!torture_close_connection(&cli1)) {
645                 correct = False;
646         }
647         return correct;
648         }
649
650 int line_count = 0;
651 int nbio_id;
652
653 #define ival(s) strtol(s, NULL, 0)
654
655 /* run a test that simulates an approximate netbench client load */
656 static BOOL run_netbench(int client)
657 {
658         struct cli_state cli;
659         int i;
660         fstring fname;
661         pstring line;
662         char cname[20];
663         FILE *f;
664         char *params[20];
665         BOOL correct = True;
666
667         cli = current_cli;
668
669         nbio_id = client;
670
671         cli_sockopt(&cli, sockops);
672
673         nb_setup(&cli);
674
675         slprintf(cname,sizeof(fname), "client%d", client);
676
677         f = fopen(client_txt, "r");
678
679         if (!f) {
680                 perror(client_txt);
681                 return False;
682         }
683
684         while (fgets(line, sizeof(line)-1, f)) {
685                 line_count++;
686
687                 line[strlen(line)-1] = 0;
688
689                 /* printf("[%d] %s\n", line_count, line); */
690
691                 all_string_sub(line,"client1", cname, sizeof(line));
692                 
693                 /* parse the command parameters */
694                 params[0] = strtok(line," ");
695                 i = 0;
696                 while (params[i]) params[++i] = strtok(NULL," ");
697
698                 params[i] = "";
699
700                 if (i < 2) continue;
701
702                 if (!strncmp(params[0],"SMB", 3)) {
703                         printf("ERROR: You are using a dbench 1 load file\n");
704                         exit(1);
705                 }
706
707                 if (!strcmp(params[0],"NTCreateX")) {
708                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
709                                    ival(params[4]));
710                 } else if (!strcmp(params[0],"Close")) {
711                         nb_close(ival(params[1]));
712                 } else if (!strcmp(params[0],"Rename")) {
713                         nb_rename(params[1], params[2]);
714                 } else if (!strcmp(params[0],"Unlink")) {
715                         nb_unlink(params[1]);
716                 } else if (!strcmp(params[0],"Deltree")) {
717                         nb_deltree(params[1]);
718                 } else if (!strcmp(params[0],"Rmdir")) {
719                         nb_rmdir(params[1]);
720                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
721                         nb_qpathinfo(params[1]);
722                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
723                         nb_qfileinfo(ival(params[1]));
724                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
725                         nb_qfsinfo(ival(params[1]));
726                 } else if (!strcmp(params[0],"FIND_FIRST")) {
727                         nb_findfirst(params[1]);
728                 } else if (!strcmp(params[0],"WriteX")) {
729                         nb_writex(ival(params[1]), 
730                                   ival(params[2]), ival(params[3]), ival(params[4]));
731                 } else if (!strcmp(params[0],"ReadX")) {
732                         nb_readx(ival(params[1]), 
733                                   ival(params[2]), ival(params[3]), ival(params[4]));
734                 } else if (!strcmp(params[0],"Flush")) {
735                         nb_flush(ival(params[1]));
736                 } else {
737                         printf("Unknown operation %s\n", params[0]);
738                         exit(1);
739                 }
740         }
741         fclose(f);
742
743         nb_cleanup();
744
745         if (!torture_close_connection(&cli)) {
746                 correct = False;
747         }
748         
749         return correct;
750 }
751
752
753 /* run a test that simulates an approximate netbench client load */
754 static BOOL run_nbench(int dummy)
755 {
756         double t;
757         BOOL correct = True;
758
759         nbio_shmem(nprocs);
760
761         nbio_id = -1;
762
763         signal(SIGALRM, nb_alarm);
764         alarm(1);
765         t = create_procs(run_netbench, &correct);
766         alarm(0);
767
768         printf("\nThroughput %g MB/sec\n", 
769                1.0e-6 * nbio_total() / t);
770         return correct;
771 }
772
773
774 /*
775   This test checks for two things:
776
777   1) correct support for retaining locks over a close (ie. the server
778      must not use posix semantics)
779   2) support for lock timeouts
780  */
781 static BOOL run_locktest1(int dummy)
782 {
783         static struct cli_state cli1, cli2;
784         char *fname = "\\lockt1.lck";
785         int fnum1, fnum2, fnum3;
786         time_t t1, t2;
787
788         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
789                 return False;
790         }
791         cli_sockopt(&cli1, sockops);
792         cli_sockopt(&cli2, sockops);
793
794         printf("starting locktest1\n");
795
796         cli_unlink(&cli1, fname);
797
798         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
799         if (fnum1 == -1) {
800                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
801                 return False;
802         }
803         fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
804         if (fnum2 == -1) {
805                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
806                 return False;
807         }
808         fnum3 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
809         if (fnum3 == -1) {
810                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2));
811                 return False;
812         }
813
814         if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
815                 printf("lock1 failed (%s)\n", cli_errstr(&cli1));
816                 return False;
817         }
818
819
820         if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
821                 printf("lock2 succeeded! This is a locking bug\n");
822                 return False;
823         } else {
824                 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock, 
825                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
826         }
827
828
829         printf("Testing lock timeouts\n");
830         t1 = time(NULL);
831         if (cli_lock(&cli2, fnum3, 0, 4, 10*1000, WRITE_LOCK)) {
832                 printf("lock3 succeeded! This is a locking bug\n");
833                 return False;
834         } else {
835                 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock, 
836                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
837         }
838         t2 = time(NULL);
839
840         if (t2 - t1 < 5) {
841                 printf("error: This server appears not to support timed lock requests\n");
842         }
843
844         if (!cli_close(&cli1, fnum2)) {
845                 printf("close1 failed (%s)\n", cli_errstr(&cli1));
846                 return False;
847         }
848
849         if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
850                 printf("lock4 succeeded! This is a locking bug\n");
851                 return False;
852         } else {
853                 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock, 
854                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
855         }
856
857         if (!cli_close(&cli1, fnum1)) {
858                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
859                 return False;
860         }
861
862         if (!cli_close(&cli2, fnum3)) {
863                 printf("close3 failed (%s)\n", cli_errstr(&cli2));
864                 return False;
865         }
866
867         if (!cli_unlink(&cli1, fname)) {
868                 printf("unlink failed (%s)\n", cli_errstr(&cli1));
869                 return False;
870         }
871
872
873         if (!torture_close_connection(&cli1)) {
874                 return False;
875         }
876
877         if (!torture_close_connection(&cli2)) {
878                 return False;
879         }
880
881         printf("Passed locktest1\n");
882         return True;
883 }
884
885 /*
886  checks for correct tconX support
887  */
888 static BOOL run_tcon_test(int dummy)
889 {
890         static struct cli_state cli1;
891         char *fname = "\\tcontest.tmp";
892         int fnum1;
893         uint16 cnum;
894         char buf[4];
895
896         if (!torture_open_connection(&cli1)) {
897                 return False;
898         }
899         cli_sockopt(&cli1, sockops);
900
901         printf("starting tcontest\n");
902
903         cli_unlink(&cli1, fname);
904
905         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
906         if (fnum1 == -1)
907         {
908                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
909                 return False;
910         }
911
912         cnum = cli1.cnum;
913
914         if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4)
915         {
916                 printf("write failed (%s)", cli_errstr(&cli1));
917                 return False;
918         }
919
920         if (!cli_send_tconX(&cli1, share, "?????",
921                             password, strlen(password)+1)) {
922                 printf("%s refused 2nd tree connect (%s)\n", host,
923                            cli_errstr(&cli1));
924                 cli_shutdown(&cli1);
925                 return False;
926         }
927
928         if (cli_write(&cli1, fnum1, 0, buf, 130, 4) == 4)
929         {
930                 printf("write succeeded (%s)", cli_errstr(&cli1));
931                 return False;
932         }
933
934         if (cli_close(&cli1, fnum1)) {
935                 printf("close2 succeeded (%s)\n", cli_errstr(&cli1));
936                 return False;
937         }
938
939         if (!cli_tdis(&cli1)) {
940                 printf("tdis failed (%s)\n", cli_errstr(&cli1));
941                 return False;
942         }
943
944         cli1.cnum = cnum;
945
946         if (!cli_close(&cli1, fnum1)) {
947                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
948                 return False;
949         }
950
951         if (!torture_close_connection(&cli1)) {
952                 return False;
953         }
954
955         printf("Passed tcontest\n");
956         return True;
957 }
958
959
960 /*
961   This test checks that 
962
963   1) the server supports multiple locking contexts on the one SMB
964   connection, distinguished by PID.  
965
966   2) the server correctly fails overlapping locks made by the same PID (this
967      goes against POSIX behaviour, which is why it is tricky to implement)
968
969   3) the server denies unlock requests by an incorrect client PID
970 */
971 static BOOL run_locktest2(int dummy)
972 {
973         static struct cli_state cli;
974         char *fname = "\\lockt2.lck";
975         int fnum1, fnum2, fnum3;
976         BOOL correct = True;
977
978         if (!torture_open_connection(&cli)) {
979                 return False;
980         }
981
982         cli_sockopt(&cli, sockops);
983
984         printf("starting locktest2\n");
985
986         cli_unlink(&cli, fname);
987
988         cli_setpid(&cli, 1);
989
990         fnum1 = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
991         if (fnum1 == -1) {
992                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
993                 return False;
994         }
995
996         fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
997         if (fnum2 == -1) {
998                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli));
999                 return False;
1000         }
1001
1002         cli_setpid(&cli, 2);
1003
1004         fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
1005         if (fnum3 == -1) {
1006                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli));
1007                 return False;
1008         }
1009
1010         cli_setpid(&cli, 1);
1011
1012         if (!cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1013                 printf("lock1 failed (%s)\n", cli_errstr(&cli));
1014                 return False;
1015         }
1016
1017         if (cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1018                 printf("WRITE lock1 succeeded! This is a locking bug\n");
1019                 correct = False;
1020         } else {
1021                 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, 
1022                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1023         }
1024
1025         if (cli_lock(&cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1026                 printf("WRITE lock2 succeeded! This is a locking bug\n");
1027                 correct = False;
1028         } else {
1029                 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, 
1030                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1031         }
1032
1033         if (cli_lock(&cli, fnum2, 0, 4, 0, READ_LOCK)) {
1034                 printf("READ lock2 succeeded! This is a locking bug\n");
1035                 correct = False;
1036         } else {
1037                 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, 
1038                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1039         }
1040
1041         if (!cli_lock(&cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1042                 printf("lock at 100 failed (%s)\n", cli_errstr(&cli));
1043         }
1044         cli_setpid(&cli, 2);
1045         if (cli_unlock(&cli, fnum1, 100, 4)) {
1046                 printf("unlock at 100 succeeded! This is a locking bug\n");
1047                 correct = False;
1048         }
1049
1050         if (cli_unlock(&cli, fnum1, 0, 4)) {
1051                 printf("unlock1 succeeded! This is a locking bug\n");
1052                 correct = False;
1053         } else {
1054                 if (!check_error(__LINE__, &cli, 
1055                                  ERRDOS, ERRlock, 
1056                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1057         }
1058
1059         if (cli_unlock(&cli, fnum1, 0, 8)) {
1060                 printf("unlock2 succeeded! This is a locking bug\n");
1061                 correct = False;
1062         } else {
1063                 if (!check_error(__LINE__, &cli, 
1064                                  ERRDOS, ERRlock, 
1065                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1066         }
1067
1068         if (cli_lock(&cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1069                 printf("lock3 succeeded! This is a locking bug\n");
1070                 correct = False;
1071         } else {
1072                 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1073         }
1074
1075         cli_setpid(&cli, 1);
1076
1077         if (!cli_close(&cli, fnum1)) {
1078                 printf("close1 failed (%s)\n", cli_errstr(&cli));
1079                 return False;
1080         }
1081
1082         if (!cli_close(&cli, fnum2)) {
1083                 printf("close2 failed (%s)\n", cli_errstr(&cli));
1084                 return False;
1085         }
1086
1087         if (!cli_close(&cli, fnum3)) {
1088                 printf("close3 failed (%s)\n", cli_errstr(&cli));
1089                 return False;
1090         }
1091
1092         if (!torture_close_connection(&cli)) {
1093                 correct = False;
1094         }
1095
1096         printf("locktest2 finished\n");
1097
1098         return correct;
1099 }
1100
1101
1102 /*
1103   This test checks that 
1104
1105   1) the server supports the full offset range in lock requests
1106 */
1107 static BOOL run_locktest3(int dummy)
1108 {
1109         static struct cli_state cli1, cli2;
1110         char *fname = "\\lockt3.lck";
1111         int fnum1, fnum2, i;
1112         uint32 offset;
1113         BOOL correct = True;
1114
1115 #define NEXT_OFFSET offset += (~(uint32)0) / numops
1116
1117         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1118                 return False;
1119         }
1120         cli_sockopt(&cli1, sockops);
1121         cli_sockopt(&cli2, sockops);
1122
1123         printf("starting locktest3\n");
1124
1125         cli_unlink(&cli1, fname);
1126
1127         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1128         if (fnum1 == -1) {
1129                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1130                 return False;
1131         }
1132         fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1133         if (fnum2 == -1) {
1134                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
1135                 return False;
1136         }
1137
1138         for (offset=i=0;i<numops;i++) {
1139                 NEXT_OFFSET;
1140                 if (!cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1141                         printf("lock1 %d failed (%s)\n", 
1142                                i,
1143                                cli_errstr(&cli1));
1144                         return False;
1145                 }
1146
1147                 if (!cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1148                         printf("lock2 %d failed (%s)\n", 
1149                                i,
1150                                cli_errstr(&cli1));
1151                         return False;
1152                 }
1153         }
1154
1155         for (offset=i=0;i<numops;i++) {
1156                 NEXT_OFFSET;
1157
1158                 if (cli_lock(&cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1159                         printf("error: lock1 %d succeeded!\n", i);
1160                         return False;
1161                 }
1162
1163                 if (cli_lock(&cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1164                         printf("error: lock2 %d succeeded!\n", i);
1165                         return False;
1166                 }
1167
1168                 if (cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1169                         printf("error: lock3 %d succeeded!\n", i);
1170                         return False;
1171                 }
1172
1173                 if (cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1174                         printf("error: lock4 %d succeeded!\n", i);
1175                         return False;
1176                 }
1177         }
1178
1179         for (offset=i=0;i<numops;i++) {
1180                 NEXT_OFFSET;
1181
1182                 if (!cli_unlock(&cli1, fnum1, offset-1, 1)) {
1183                         printf("unlock1 %d failed (%s)\n", 
1184                                i,
1185                                cli_errstr(&cli1));
1186                         return False;
1187                 }
1188
1189                 if (!cli_unlock(&cli2, fnum2, offset-2, 1)) {
1190                         printf("unlock2 %d failed (%s)\n", 
1191                                i,
1192                                cli_errstr(&cli1));
1193                         return False;
1194                 }
1195         }
1196
1197         if (!cli_close(&cli1, fnum1)) {
1198                 printf("close1 failed (%s)\n", cli_errstr(&cli1));
1199                 return False;
1200         }
1201
1202         if (!cli_close(&cli2, fnum2)) {
1203                 printf("close2 failed (%s)\n", cli_errstr(&cli2));
1204                 return False;
1205         }
1206
1207         if (!cli_unlink(&cli1, fname)) {
1208                 printf("unlink failed (%s)\n", cli_errstr(&cli1));
1209                 return False;
1210         }
1211
1212         if (!torture_close_connection(&cli1)) {
1213                 correct = False;
1214         }
1215         
1216         if (!torture_close_connection(&cli2)) {
1217                 correct = False;
1218         }
1219
1220         printf("finished locktest3\n");
1221
1222         return correct;
1223 }
1224
1225 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1226         printf("** "); correct = False; \
1227         }
1228
1229 /*
1230   looks at overlapping locks
1231 */
1232 static BOOL run_locktest4(int dummy)
1233 {
1234         static struct cli_state cli1, cli2;
1235         char *fname = "\\lockt4.lck";
1236         int fnum1, fnum2, f;
1237         BOOL ret;
1238         char buf[1000];
1239         BOOL correct = True;
1240
1241         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1242                 return False;
1243         }
1244
1245         cli_sockopt(&cli1, sockops);
1246         cli_sockopt(&cli2, sockops);
1247
1248         printf("starting locktest4\n");
1249
1250         cli_unlink(&cli1, fname);
1251
1252         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1253         fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1254
1255         memset(buf, 0, sizeof(buf));
1256
1257         if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1258                 printf("Failed to create file\n");
1259                 correct = False;
1260                 goto fail;
1261         }
1262
1263         ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1264               cli_lock(&cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1265         EXPECTED(ret, False);
1266         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1267             
1268         ret = cli_lock(&cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1269               cli_lock(&cli1, fnum1, 12, 4, 0, READ_LOCK);
1270         EXPECTED(ret, True);
1271         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1272
1273         ret = cli_lock(&cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1274               cli_lock(&cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1275         EXPECTED(ret, False);
1276         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1277             
1278         ret = cli_lock(&cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1279               cli_lock(&cli2, fnum2, 32, 4, 0, READ_LOCK);
1280         EXPECTED(ret, True);
1281         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1282         
1283         ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1284               (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1285         EXPECTED(ret, False);
1286         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1287             
1288         ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1289               (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 52, 4, 0, READ_LOCK));
1290         EXPECTED(ret, True);
1291         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1292
1293         ret = cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1294               cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK);
1295         EXPECTED(ret, True);
1296         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1297
1298         ret = cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1299               cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1300         EXPECTED(ret, False);
1301         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1302
1303         ret = cli_lock(&cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1304               cli_lock(&cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1305         EXPECTED(ret, False);
1306         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1307
1308         ret = cli_lock(&cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1309               cli_lock(&cli1, fnum1, 90, 4, 0, READ_LOCK);
1310         EXPECTED(ret, True);
1311         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1312
1313         ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1314               (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 100, 4, 0, READ_LOCK));
1315         EXPECTED(ret, False);
1316         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1317
1318         ret = cli_lock(&cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1319               cli_lock(&cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1320               cli_unlock(&cli1, fnum1, 110, 6);
1321         EXPECTED(ret, False);
1322         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1323
1324
1325         ret = cli_lock(&cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1326               (cli_read(&cli2, fnum2, buf, 120, 4) == 4);
1327         EXPECTED(ret, False);
1328         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1329
1330         ret = cli_lock(&cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1331               (cli_write(&cli2, fnum2, 0, buf, 130, 4) == 4);
1332         EXPECTED(ret, False);
1333         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1334
1335
1336         ret = cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1337               cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1338               cli_unlock(&cli1, fnum1, 140, 4) &&
1339               cli_unlock(&cli1, fnum1, 140, 4);
1340         EXPECTED(ret, True);
1341         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1342
1343
1344         ret = cli_lock(&cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1345               cli_lock(&cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1346               cli_unlock(&cli1, fnum1, 150, 4) &&
1347               (cli_read(&cli2, fnum2, buf, 150, 4) == 4) &&
1348               !(cli_write(&cli2, fnum2, 0, buf, 150, 4) == 4) &&
1349               cli_unlock(&cli1, fnum1, 150, 4);
1350         EXPECTED(ret, True);
1351         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1352
1353         ret = cli_lock(&cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1354               cli_unlock(&cli1, fnum1, 160, 4) &&
1355               (cli_write(&cli2, fnum2, 0, buf, 160, 4) == 4) &&         
1356               (cli_read(&cli2, fnum2, buf, 160, 4) == 4);               
1357         EXPECTED(ret, True);
1358         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1359
1360         ret = cli_lock(&cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1361               cli_unlock(&cli1, fnum1, 170, 4) &&
1362               (cli_write(&cli2, fnum2, 0, buf, 170, 4) == 4) &&         
1363               (cli_read(&cli2, fnum2, buf, 170, 4) == 4);               
1364         EXPECTED(ret, True);
1365         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1366
1367         ret = cli_lock(&cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1368               cli_lock(&cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1369               cli_unlock(&cli1, fnum1, 190, 4) &&
1370               !(cli_write(&cli2, fnum2, 0, buf, 190, 4) == 4) &&                
1371               (cli_read(&cli2, fnum2, buf, 190, 4) == 4);               
1372         EXPECTED(ret, True);
1373         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1374
1375         cli_close(&cli1, fnum1);
1376         cli_close(&cli2, fnum2);
1377         fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1378         f = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1379         ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1380               cli_lock(&cli1, f, 0, 1, 0, READ_LOCK) &&
1381               cli_close(&cli1, fnum1) &&
1382               ((fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1383               cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1384         cli_close(&cli1, f);
1385         cli_close(&cli1, fnum1);
1386         EXPECTED(ret, True);
1387         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1388
1389  fail:
1390         cli_close(&cli1, fnum1);
1391         cli_close(&cli2, fnum2);
1392         cli_unlink(&cli1, fname);
1393         torture_close_connection(&cli1);
1394         torture_close_connection(&cli2);
1395
1396         printf("finished locktest4\n");
1397         return correct;
1398 }
1399
1400 /*
1401   looks at lock upgrade/downgrade.
1402 */
1403 static BOOL run_locktest5(int dummy)
1404 {
1405         static struct cli_state cli1, cli2;
1406         char *fname = "\\lockt5.lck";
1407         int fnum1, fnum2, fnum3;
1408         BOOL ret;
1409         char buf[1000];
1410         BOOL correct = True;
1411
1412         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1413                 return False;
1414         }
1415
1416         cli_sockopt(&cli1, sockops);
1417         cli_sockopt(&cli2, sockops);
1418
1419         printf("starting locktest5\n");
1420
1421         cli_unlink(&cli1, fname);
1422
1423         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1424         fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1425         fnum3 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1426
1427         memset(buf, 0, sizeof(buf));
1428
1429         if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1430                 printf("Failed to create file\n");
1431                 correct = False;
1432                 goto fail;
1433         }
1434
1435         /* Check for NT bug... */
1436         ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1437                   cli_lock(&cli1, fnum3, 0, 1, 0, READ_LOCK);
1438         cli_close(&cli1, fnum1);
1439         fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1440         ret = cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1441         EXPECTED(ret, True);
1442         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1443         cli_close(&cli1, fnum1);
1444         fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1445         cli_unlock(&cli1, fnum3, 0, 1);
1446
1447         ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1448               cli_lock(&cli1, fnum1, 1, 1, 0, READ_LOCK);
1449         EXPECTED(ret, True);
1450         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1451
1452         ret = cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1453         EXPECTED(ret, False);
1454
1455         printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1456
1457         /* Unlock the process 2 lock. */
1458         cli_unlock(&cli2, fnum2, 0, 4);
1459
1460         ret = cli_lock(&cli1, fnum3, 0, 4, 0, READ_LOCK);
1461         EXPECTED(ret, False);
1462
1463         printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1464
1465         /* Unlock the process 1 fnum3 lock. */
1466         cli_unlock(&cli1, fnum3, 0, 4);
1467
1468         /* Stack 2 more locks here. */
1469         ret = cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1470                   cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK);
1471
1472         EXPECTED(ret, True);
1473         printf("the same process %s stack read locks\n", ret?"can":"cannot");
1474
1475         /* Unlock the first process lock, then check this was the WRITE lock that was
1476                 removed. */
1477
1478         ret = cli_unlock(&cli1, fnum1, 0, 4) &&
1479                         cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1480
1481         EXPECTED(ret, True);
1482         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1483
1484         /* Unlock the process 2 lock. */
1485         cli_unlock(&cli2, fnum2, 0, 4);
1486
1487         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1488
1489         ret = cli_unlock(&cli1, fnum1, 1, 1) &&
1490                   cli_unlock(&cli1, fnum1, 0, 4) &&
1491                   cli_unlock(&cli1, fnum1, 0, 4);
1492
1493         EXPECTED(ret, True);
1494         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
1495
1496         /* Ensure the next unlock fails. */
1497         ret = cli_unlock(&cli1, fnum1, 0, 4);
1498         EXPECTED(ret, False);
1499         printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
1500
1501         /* Ensure connection 2 can get a write lock. */
1502         ret = cli_lock(&cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1503         EXPECTED(ret, True);
1504
1505         printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1506
1507
1508  fail:
1509         cli_close(&cli1, fnum1);
1510         cli_close(&cli2, fnum2);
1511         cli_unlink(&cli1, fname);
1512         if (!torture_close_connection(&cli1)) {
1513                 correct = False;
1514         }
1515         if (!torture_close_connection(&cli2)) {
1516                 correct = False;
1517         }
1518
1519         printf("finished locktest5\n");
1520        
1521         return correct;
1522 }
1523
1524 /*
1525   tries the unusual lockingX locktype bits
1526 */
1527 static BOOL run_locktest6(int dummy)
1528 {
1529         static struct cli_state cli;
1530         char *fname[1] = { "\\lock6.txt" };
1531         int i;
1532         int fnum;
1533         NTSTATUS status;
1534
1535         if (!torture_open_connection(&cli)) {
1536                 return False;
1537         }
1538
1539         cli_sockopt(&cli, sockops);
1540
1541         printf("starting locktest6\n");
1542
1543         for (i=0;i<1;i++) {
1544                 printf("Testing %s\n", fname[i]);
1545
1546                 cli_unlink(&cli, fname[i]);
1547
1548                 fnum = cli_open(&cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1549                 status = cli_locktype(&cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1550                 cli_close(&cli, fnum);
1551                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1552
1553                 fnum = cli_open(&cli, fname[i], O_RDWR, DENY_NONE);
1554                 status = cli_locktype(&cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1555                 cli_close(&cli, fnum);
1556                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1557
1558                 cli_unlink(&cli, fname[i]);
1559         }
1560
1561         torture_close_connection(&cli);
1562
1563         printf("finished locktest6\n");
1564         return True;
1565 }
1566
1567 /*
1568 test whether fnums and tids open on one VC are available on another (a major
1569 security hole)
1570 */
1571 static BOOL run_fdpasstest(int dummy)
1572 {
1573         static struct cli_state cli1, cli2, cli3;
1574         char *fname = "\\fdpass.tst";
1575         int fnum1;
1576         pstring buf;
1577
1578         if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1579                 return False;
1580         }
1581         cli_sockopt(&cli1, sockops);
1582         cli_sockopt(&cli2, sockops);
1583
1584         printf("starting fdpasstest\n");
1585
1586         cli_unlink(&cli1, fname);
1587
1588         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1589         if (fnum1 == -1) {
1590                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1591                 return False;
1592         }
1593
1594         if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
1595                 printf("write failed (%s)\n", cli_errstr(&cli1));
1596                 return False;
1597         }
1598
1599         cli3 = cli2;
1600         cli3.vuid = cli1.vuid;
1601         cli3.cnum = cli1.cnum;
1602         cli3.pid = cli1.pid;
1603
1604         if (cli_read(&cli3, fnum1, buf, 0, 13) == 13) {
1605                 printf("read succeeded! nasty security hole [%s]\n",
1606                        buf);
1607                 return False;
1608         }
1609
1610         cli_close(&cli1, fnum1);
1611         cli_unlink(&cli1, fname);
1612
1613         torture_close_connection(&cli1);
1614         torture_close_connection(&cli2);
1615
1616         printf("finished fdpasstest\n");
1617         return True;
1618 }
1619
1620
1621 /*
1622   This test checks that 
1623
1624   1) the server does not allow an unlink on a file that is open
1625 */
1626 static BOOL run_unlinktest(int dummy)
1627 {
1628         static struct cli_state cli;
1629         char *fname = "\\unlink.tst";
1630         int fnum;
1631         BOOL correct = True;
1632
1633         if (!torture_open_connection(&cli)) {
1634                 return False;
1635         }
1636
1637         cli_sockopt(&cli, sockops);
1638
1639         printf("starting unlink test\n");
1640
1641         cli_unlink(&cli, fname);
1642
1643         cli_setpid(&cli, 1);
1644
1645         fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1646         if (fnum == -1) {
1647                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1648                 return False;
1649         }
1650
1651         if (cli_unlink(&cli, fname)) {
1652                 printf("error: server allowed unlink on an open file\n");
1653                 correct = False;
1654         } else {
1655                 correct = check_error(__LINE__, &cli, ERRDOS, ERRbadshare, 
1656                                       NT_STATUS_SHARING_VIOLATION);
1657         }
1658
1659         cli_close(&cli, fnum);
1660         cli_unlink(&cli, fname);
1661
1662         if (!torture_close_connection(&cli)) {
1663                 correct = False;
1664         }
1665
1666         printf("unlink test finished\n");
1667         
1668         return correct;
1669 }
1670
1671
1672 /*
1673 test how many open files this server supports on the one socket
1674 */
1675 static BOOL run_maxfidtest(int dummy)
1676 {
1677         static struct cli_state cli;
1678         char *template = "\\maxfid.%d.%d";
1679         fstring fname;
1680         int fnums[0x11000], i;
1681         int retries=4;
1682         BOOL correct = True;
1683
1684         cli = current_cli;
1685
1686         if (retries <= 0) {
1687                 printf("failed to connect\n");
1688                 return False;
1689         }
1690
1691         cli_sockopt(&cli, sockops);
1692
1693         for (i=0; i<0x11000; i++) {
1694                 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1695                 if ((fnums[i] = cli_open(&cli, fname, 
1696                                         O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1697                     -1) {
1698                         printf("open of %s failed (%s)\n", 
1699                                fname, cli_errstr(&cli));
1700                         printf("maximum fnum is %d\n", i);
1701                         break;
1702                 }
1703                 printf("%6d\r", i);
1704         }
1705         printf("%6d\n", i);
1706         i--;
1707
1708         printf("cleaning up\n");
1709         for (;i>=0;i--) {
1710                 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1711                 cli_close(&cli, fnums[i]);
1712                 if (!cli_unlink(&cli, fname)) {
1713                         printf("unlink of %s failed (%s)\n", 
1714                                fname, cli_errstr(&cli));
1715                         correct = False;
1716                 }
1717                 printf("%6d\r", i);
1718         }
1719         printf("%6d\n", 0);
1720
1721         printf("maxfid test finished\n");
1722         if (!torture_close_connection(&cli)) {
1723                 correct = False;
1724         }
1725         return correct;
1726 }
1727
1728 /* generate a random buffer */
1729 static void rand_buf(char *buf, int len)
1730 {
1731         while (len--) {
1732                 *buf = (char)sys_random();
1733                 buf++;
1734         }
1735 }
1736
1737 /* send smb negprot commands, not reading the response */
1738 static BOOL run_negprot_nowait(int dummy)
1739 {
1740         int i;
1741         static struct cli_state cli;
1742         BOOL correct = True;
1743
1744         printf("starting negprot nowait test\n");
1745
1746         if (!open_nbt_connection(&cli)) {
1747                 return False;
1748         }
1749
1750         for (i=0;i<50000;i++) {
1751                 cli_negprot_send(&cli);
1752         }
1753
1754         if (!torture_close_connection(&cli)) {
1755                 correct = False;
1756         }
1757
1758         printf("finished negprot nowait test\n");
1759
1760         return correct;
1761 }
1762
1763
1764 /* send random IPC commands */
1765 static BOOL run_randomipc(int dummy)
1766 {
1767         char *rparam = NULL;
1768         char *rdata = NULL;
1769         int rdrcnt,rprcnt;
1770         pstring param;
1771         int api, param_len, i;
1772         static struct cli_state cli;
1773         BOOL correct = True;
1774         int count = 50000;
1775
1776         printf("starting random ipc test\n");
1777
1778         if (!torture_open_connection(&cli)) {
1779                 return False;
1780         }
1781
1782         for (i=0;i<count;i++) {
1783                 api = sys_random() % 500;
1784                 param_len = (sys_random() % 64);
1785
1786                 rand_buf(param, param_len);
1787   
1788                 SSVAL(param,0,api); 
1789
1790                 cli_api(&cli, 
1791                         param, param_len, 8,  
1792                         NULL, 0, BUFFER_SIZE, 
1793                         &rparam, &rprcnt,     
1794                         &rdata, &rdrcnt);
1795                 if (i % 100 == 0) {
1796                         printf("%d/%d\r", i,count);
1797                 }
1798         }
1799         printf("%d/%d\n", i, count);
1800
1801         if (!torture_close_connection(&cli)) {
1802                 correct = False;
1803         }
1804
1805         printf("finished random ipc test\n");
1806
1807         return correct;
1808 }
1809
1810
1811
1812 static void browse_callback(const char *sname, uint32 stype, 
1813                             const char *comment, void *state)
1814 {
1815         printf("\t%20.20s %08x %s\n", sname, stype, comment);
1816 }
1817
1818
1819
1820 /*
1821   This test checks the browse list code
1822
1823 */
1824 static BOOL run_browsetest(int dummy)
1825 {
1826         static struct cli_state cli;
1827         BOOL correct = True;
1828
1829         printf("starting browse test\n");
1830
1831         if (!torture_open_connection(&cli)) {
1832                 return False;
1833         }
1834
1835         printf("domain list:\n");
1836         cli_NetServerEnum(&cli, cli.server_domain, 
1837                           SV_TYPE_DOMAIN_ENUM,
1838                           browse_callback, NULL);
1839
1840         printf("machine list:\n");
1841         cli_NetServerEnum(&cli, cli.server_domain, 
1842                           SV_TYPE_ALL,
1843                           browse_callback, NULL);
1844
1845         if (!torture_close_connection(&cli)) {
1846                 correct = False;
1847         }
1848
1849         printf("browse test finished\n");
1850
1851         return correct;
1852
1853 }
1854
1855
1856 /*
1857   This checks how the getatr calls works
1858 */
1859 static BOOL run_attrtest(int dummy)
1860 {
1861         static struct cli_state cli;
1862         int fnum;
1863         time_t t, t2;
1864         char *fname = "\\attrib.tst";
1865         BOOL correct = True;
1866
1867         printf("starting attrib test\n");
1868
1869         if (!torture_open_connection(&cli)) {
1870                 return False;
1871         }
1872
1873         cli_unlink(&cli, fname);
1874         fnum = cli_open(&cli, fname, 
1875                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1876         cli_close(&cli, fnum);
1877         if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1878                 printf("getatr failed (%s)\n", cli_errstr(&cli));
1879                 correct = False;
1880         }
1881
1882         if (abs(t - time(NULL)) > 60*60*24*10) {
1883                 printf("ERROR: SMBgetatr bug. time is %s",
1884                        ctime(&t));
1885                 t = time(NULL);
1886                 correct = True;
1887         }
1888
1889         t2 = t-60*60*24; /* 1 day ago */
1890
1891         if (!cli_setatr(&cli, fname, 0, t2)) {
1892                 printf("setatr failed (%s)\n", cli_errstr(&cli));
1893                 correct = True;
1894         }
1895
1896         if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1897                 printf("getatr failed (%s)\n", cli_errstr(&cli));
1898                 correct = True;
1899         }
1900
1901         if (t != t2) {
1902                 printf("ERROR: getatr/setatr bug. times are\n%s",
1903                        ctime(&t));
1904                 printf("%s", ctime(&t2));
1905                 correct = True;
1906         }
1907
1908         cli_unlink(&cli, fname);
1909
1910         if (!torture_close_connection(&cli)) {
1911                 correct = False;
1912         }
1913
1914         printf("attrib test finished\n");
1915
1916         return correct;
1917 }
1918
1919
1920 /*
1921   This checks a couple of trans2 calls
1922 */
1923 static BOOL run_trans2test(int dummy)
1924 {
1925         static struct cli_state cli;
1926         int fnum;
1927         size_t size;
1928         time_t c_time, a_time, m_time, w_time, m_time2;
1929         char *fname = "\\trans2.tst";
1930         char *dname = "\\trans2";
1931         char *fname2 = "\\trans2\\trans2.tst";
1932         pstring pname;
1933         BOOL correct = True;
1934
1935         printf("starting trans2 test\n");
1936
1937         if (!torture_open_connection(&cli)) {
1938                 return False;
1939         }
1940
1941         cli_unlink(&cli, fname);
1942         fnum = cli_open(&cli, fname, 
1943                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1944         if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
1945                            NULL, NULL)) {
1946                 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
1947                 correct = False;
1948         }
1949
1950         if (!cli_qfilename(&cli, fnum, pname)) {
1951                 printf("ERROR: qfilename failed (%s)\n", cli_errstr(&cli));
1952                 correct = False;
1953         }
1954
1955         if (strcmp(pname, fname)) {
1956                 printf("qfilename gave different name? [%s] [%s]\n",
1957                        fname, pname);
1958                 correct = False;
1959         }
1960
1961         cli_close(&cli, fnum);
1962
1963         sleep(2);
1964
1965         cli_unlink(&cli, fname);
1966         fnum = cli_open(&cli, fname, 
1967                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1968         if (fnum == -1) {
1969                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1970                 return False;
1971         }
1972         cli_close(&cli, fnum);
1973
1974         if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
1975                 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
1976                 correct = False;
1977         } else {
1978                 if (c_time != m_time) {
1979                         printf("create time=%s", ctime(&c_time));
1980                         printf("modify time=%s", ctime(&m_time));
1981                         printf("This system appears to have sticky create times\n");
1982                         correct = False;
1983                 }
1984                 if (a_time % (60*60) == 0) {
1985                         printf("access time=%s", ctime(&a_time));
1986                         printf("This system appears to set a midnight access time\n");
1987                         correct = False;
1988                 }
1989
1990                 if (abs(m_time - time(NULL)) > 60*60*24*7) {
1991                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
1992                         correct = False;
1993                 }
1994         }
1995
1996
1997         cli_unlink(&cli, fname);
1998         fnum = cli_open(&cli, fname, 
1999                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2000         cli_close(&cli, fnum);
2001         if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time, 
2002                             &w_time, &size, NULL, NULL)) {
2003                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2004                 correct = False;
2005         } else {
2006                 if (w_time < 60*60*24*2) {
2007                         printf("write time=%s", ctime(&w_time));
2008                         printf("This system appears to set a initial 0 write time\n");
2009                         correct = False;
2010                 }
2011         }
2012
2013         cli_unlink(&cli, fname);
2014
2015
2016         /* check if the server updates the directory modification time
2017            when creating a new file */
2018         if (!cli_mkdir(&cli, dname)) {
2019                 printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
2020                 correct = False;
2021         }
2022         sleep(3);
2023         if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time, 
2024                             &w_time, &size, NULL, NULL)) {
2025                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2026                 correct = False;
2027         }
2028
2029         fnum = cli_open(&cli, fname2, 
2030                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2031         cli_write(&cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
2032         cli_close(&cli, fnum);
2033         if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2, 
2034                             &w_time, &size, NULL, NULL)) {
2035                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2036                 correct = False;
2037         } else {
2038                 if (m_time2 == m_time) {
2039                         printf("This system does not update directory modification times\n");
2040                         correct = False;
2041                 }
2042         }
2043         cli_unlink(&cli, fname2);
2044         cli_rmdir(&cli, dname);
2045
2046         if (!torture_close_connection(&cli)) {
2047                 correct = False;
2048         }
2049
2050         printf("trans2 test finished\n");
2051
2052         return correct;
2053 }
2054
2055 /*
2056   This checks new W2K calls.
2057 */
2058
2059 static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
2060 {
2061         char buf[4096];
2062         BOOL correct = True;
2063
2064         memset(buf, 0xff, sizeof(buf));
2065
2066         if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
2067                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2068                 correct = False;
2069         } else {
2070                 printf("qfileinfo: level %d\n", level);
2071                 dump_data(0, buf, 256);
2072                 printf("\n");
2073         }
2074         return correct;
2075 }
2076
2077 static BOOL run_w2ktest(int dummy)
2078 {
2079         static struct cli_state cli;
2080         int fnum;
2081         char *fname = "\\w2ktest\\w2k.tst";
2082         int level;
2083         BOOL correct = True;
2084
2085         printf("starting w2k test\n");
2086
2087         if (!torture_open_connection(&cli)) {
2088                 return False;
2089         }
2090
2091         fnum = cli_open(&cli, fname, 
2092                         O_RDWR | O_CREAT , DENY_NONE);
2093
2094         for (level = 1004; level < 1040; level++) {
2095                 new_trans(&cli, fnum, level);
2096         }
2097
2098         cli_close(&cli, fnum);
2099
2100         if (!torture_close_connection(&cli)) {
2101                 correct = False;
2102         }
2103
2104         printf("w2k test finished\n");
2105         
2106         return correct;
2107 }
2108
2109
2110 /*
2111   this is a harness for some oplock tests
2112  */
2113 static BOOL run_oplock1(int dummy)
2114 {
2115         static struct cli_state cli1;
2116         char *fname = "\\lockt1.lck";
2117         int fnum1;
2118         BOOL correct = True;
2119
2120         printf("starting oplock test 1\n");
2121
2122         if (!torture_open_connection(&cli1)) {
2123                 return False;
2124         }
2125
2126         cli_unlink(&cli1, fname);
2127
2128         cli_sockopt(&cli1, sockops);
2129
2130         cli1.use_oplocks = True;
2131
2132         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2133         if (fnum1 == -1) {
2134                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2135                 return False;
2136         }
2137
2138         cli1.use_oplocks = False;
2139
2140         cli_unlink(&cli1, fname);
2141         cli_unlink(&cli1, fname);
2142
2143         if (!cli_close(&cli1, fnum1)) {
2144                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2145                 return False;
2146         }
2147
2148         if (!cli_unlink(&cli1, fname)) {
2149                 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2150                 return False;
2151         }
2152
2153         if (!torture_close_connection(&cli1)) {
2154                 correct = False;
2155         }
2156
2157         printf("finished oplock test 1\n");
2158
2159         return correct;
2160 }
2161
2162 static BOOL run_oplock2(int dummy)
2163 {
2164         static struct cli_state cli1, cli2;
2165         char *fname = "\\lockt2.lck";
2166         int fnum1, fnum2;
2167         int saved_use_oplocks = use_oplocks;
2168         char buf[4];
2169         BOOL correct = True;
2170         volatile BOOL *shared_correct;
2171
2172         shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2173         *shared_correct = True;
2174
2175         use_level_II_oplocks = True;
2176         use_oplocks = True;
2177
2178         printf("starting oplock test 2\n");
2179
2180         if (!torture_open_connection(&cli1)) {
2181                 use_level_II_oplocks = False;
2182                 use_oplocks = saved_use_oplocks;
2183                 return False;
2184         }
2185
2186         cli1.use_oplocks = True;
2187         cli1.use_level_II_oplocks = True;
2188
2189         if (!torture_open_connection(&cli2)) {
2190                 use_level_II_oplocks = False;
2191                 use_oplocks = saved_use_oplocks;
2192                 return False;
2193         }
2194
2195         cli2.use_oplocks = True;
2196         cli2.use_level_II_oplocks = True;
2197
2198         cli_unlink(&cli1, fname);
2199
2200         cli_sockopt(&cli1, sockops);
2201         cli_sockopt(&cli2, sockops);
2202
2203         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2204         if (fnum1 == -1) {
2205                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2206                 return False;
2207         }
2208
2209         /* Don't need the globals any more. */
2210         use_level_II_oplocks = False;
2211         use_oplocks = saved_use_oplocks;
2212
2213         if (fork() == 0) {
2214                 /* Child code */
2215                 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
2216                 if (fnum2 == -1) {
2217                         printf("second open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2218                         *shared_correct = False;
2219                         exit(0);
2220                 }
2221
2222                 sleep(2);
2223
2224                 if (!cli_close(&cli2, fnum2)) {
2225                         printf("close2 failed (%s)\n", cli_errstr(&cli1));
2226                         *shared_correct = False;
2227                 }
2228
2229                 exit(0);
2230         }
2231
2232         sleep(2);
2233
2234         /* Ensure cli1 processes the break. */
2235
2236         if (cli_read(&cli1, fnum1, buf, 0, 4) != 4) {
2237                 printf("read on fnum1 failed (%s)\n", cli_errstr(&cli1));
2238                 correct = False;
2239         }
2240
2241         /* Should now be at level II. */
2242         /* Test if sending a write locks causes a break to none. */
2243
2244         if (!cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2245                 printf("lock failed (%s)\n", cli_errstr(&cli1));
2246                 correct = False;
2247         }
2248
2249         cli_unlock(&cli1, fnum1, 0, 4);
2250
2251         sleep(2);
2252
2253         if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2254                 printf("lock failed (%s)\n", cli_errstr(&cli1));
2255                 correct = False;
2256         }
2257
2258         cli_unlock(&cli1, fnum1, 0, 4);
2259
2260         sleep(2);
2261
2262         cli_read(&cli1, fnum1, buf, 0, 4);
2263
2264 #if 0
2265         if (cli_write(&cli1, fnum1, 0, buf, 0, 4) != 4) {
2266                 printf("write on fnum1 failed (%s)\n", cli_errstr(&cli1));
2267                 correct = False;
2268         }
2269 #endif
2270
2271         if (!cli_close(&cli1, fnum1)) {
2272                 printf("close1 failed (%s)\n", cli_errstr(&cli1));
2273                 correct = False;
2274         }
2275
2276         sleep(4);
2277
2278         if (!cli_unlink(&cli1, fname)) {
2279                 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2280                 correct = False;
2281         }
2282
2283         if (!torture_close_connection(&cli1)) {
2284                 correct = False;
2285         }
2286
2287         if (!*shared_correct) {
2288                 correct = False;
2289         }
2290
2291         printf("finished oplock test 2\n");
2292
2293         return correct;
2294 }
2295
2296 /* handler for oplock 3 tests */
2297 static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2298 {
2299         printf("got oplock break fnum=%d level=%d\n",
2300                fnum, level);
2301         return cli_oplock_ack(cli, fnum, level);
2302 }
2303
2304 static BOOL run_oplock3(int dummy)
2305 {
2306         static struct cli_state cli;
2307         char *fname = "\\oplockt3.dat";
2308         int fnum;
2309         char buf[4] = "abcd";
2310         BOOL correct = True;
2311         volatile BOOL *shared_correct;
2312
2313         shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2314         *shared_correct = True;
2315
2316         printf("starting oplock test 3\n");
2317
2318         if (fork() == 0) {
2319                 /* Child code */
2320                 use_oplocks = True;
2321                 use_level_II_oplocks = True;
2322                 if (!torture_open_connection(&cli)) {
2323                         *shared_correct = False;
2324                         exit(0);
2325                 } 
2326                 sleep(2);
2327                 /* try to trigger a oplock break in parent */
2328                 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2329                 cli_write(&cli, fnum, 0, buf, 0, 4);
2330                 exit(0);
2331         }
2332
2333         /* parent code */
2334         use_oplocks = True;
2335         use_level_II_oplocks = True;
2336         if (!torture_open_connection(&cli)) { 
2337                 return False;
2338         }
2339         cli_oplock_handler(&cli, oplock3_handler);
2340         fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2341         cli_write(&cli, fnum, 0, buf, 0, 4);
2342         cli_close(&cli, fnum);
2343         fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2344         cli.timeout = 20000;
2345         cli_receive_smb(&cli);
2346         printf("finished oplock test 3\n");
2347
2348         return (correct && *shared_correct);
2349
2350 /* What are we looking for here?  What's sucess and what's FAILURE? */
2351 }
2352
2353
2354
2355 /*
2356   Test delete on close semantics.
2357  */
2358 static BOOL run_deletetest(int dummy)
2359 {
2360         static struct cli_state cli1;
2361         static struct cli_state cli2;
2362         char *fname = "\\delete.file";
2363         int fnum1 = -1;
2364         int fnum2 = -1;
2365         BOOL correct = True;
2366         
2367         printf("starting delete test\n");
2368         
2369         ZERO_STRUCT(cli1);
2370         ZERO_STRUCT(cli2);
2371
2372         if (!torture_open_connection(&cli1)) {
2373                 return False;
2374         }
2375         
2376         cli_sockopt(&cli1, sockops);
2377
2378         /* Test 1 - this should *NOT* delete the file on close. */
2379         
2380         cli_setatr(&cli1, fname, 0, 0);
2381         cli_unlink(&cli1, fname);
2382         
2383         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2384                                    FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 
2385                                    DELETE_ON_CLOSE_FLAG);
2386         
2387         if (fnum1 == -1) {
2388                 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2389                 correct = False;
2390                 goto fail;
2391         }
2392         
2393         if (!cli_close(&cli1, fnum1)) {
2394                 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2395                 correct = False;
2396                 goto fail;
2397         }
2398
2399         fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
2400         if (fnum1 == -1) {
2401                 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2402                 correct = False;
2403                 goto fail;
2404         }
2405         
2406         if (!cli_close(&cli1, fnum1)) {
2407                 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2408                 correct = False;
2409                 goto fail;
2410         }
2411         
2412         printf("first delete on close test succeeded.\n");
2413         
2414         /* Test 2 - this should delete the file on close. */
2415         
2416         cli_setatr(&cli1, fname, 0, 0);
2417         cli_unlink(&cli1, fname);
2418         
2419         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS,
2420                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, 
2421                                    FILE_OVERWRITE_IF, 0);
2422         
2423         if (fnum1 == -1) {
2424                 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2425                 correct = False;
2426                 goto fail;
2427         }
2428         
2429         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2430                 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2431                 correct = False;
2432                 goto fail;
2433         }
2434         
2435         if (!cli_close(&cli1, fnum1)) {
2436                 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2437                 correct = False;
2438                 goto fail;
2439         }
2440         
2441         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2442         if (fnum1 != -1) {
2443                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2444                 if (!cli_close(&cli1, fnum1)) {
2445                         printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2446                         correct = False;
2447                         goto fail;
2448                 }
2449                 cli_unlink(&cli1, fname);
2450         } else
2451                 printf("second delete on close test succeeded.\n");
2452         
2453         /* Test 3 - ... */
2454         cli_setatr(&cli1, fname, 0, 0);
2455         cli_unlink(&cli1, fname);
2456
2457         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2458                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2459
2460         if (fnum1 == -1) {
2461                 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2462                 correct = False;
2463                 goto fail;
2464         }
2465
2466         /* This should fail with a sharing violation - open for delete is only compatible
2467            with SHARE_DELETE. */
2468
2469         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2470                         FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0);
2471
2472         if (fnum2 != -1) {
2473                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
2474                 correct = False;
2475                 goto fail;
2476         }
2477
2478         /* This should succeed. */
2479
2480         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2481                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2482
2483         if (fnum2 == -1) {
2484                 printf("[3] open  - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2485                 correct = False;
2486                 goto fail;
2487         }
2488
2489         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2490                 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2491                 correct = False;
2492                 goto fail;
2493         }
2494         
2495         if (!cli_close(&cli1, fnum1)) {
2496                 printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1));
2497                 correct = False;
2498                 goto fail;
2499         }
2500         
2501         if (!cli_close(&cli1, fnum2)) {
2502                 printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1));
2503                 correct = False;
2504                 goto fail;
2505         }
2506         
2507         /* This should fail - file should no longer be there. */
2508
2509         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2510         if (fnum1 != -1) {
2511                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2512                 if (!cli_close(&cli1, fnum1)) {
2513                         printf("[3] close failed (%s)\n", cli_errstr(&cli1));
2514                 }
2515                 cli_unlink(&cli1, fname);
2516                 correct = False;
2517                 goto fail;
2518         } else
2519                 printf("third delete on close test succeeded.\n");
2520
2521         /* Test 4 ... */
2522         cli_setatr(&cli1, fname, 0, 0);
2523         cli_unlink(&cli1, fname);
2524
2525         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2526                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2527                                                                 
2528         if (fnum1 == -1) {
2529                 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2530                 correct = False;
2531                 goto fail;
2532         }
2533
2534         /* This should succeed. */
2535         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2536                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2537         if (fnum2 == -1) {
2538                 printf("[4] open  - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2539                 correct = False;
2540                 goto fail;
2541         }
2542         
2543         if (!cli_close(&cli1, fnum2)) {
2544                 printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1));
2545                 correct = False;
2546                 goto fail;
2547         }
2548         
2549         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2550                 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2551                 correct = False;
2552                 goto fail;
2553         }
2554         
2555         /* This should fail - no more opens once delete on close set. */
2556         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2557                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2558         if (fnum2 != -1) {
2559                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
2560                 correct = False;
2561                 goto fail;
2562         } else
2563                 printf("fourth delete on close test succeeded.\n");
2564         
2565         if (!cli_close(&cli1, fnum1)) {
2566                 printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1));
2567                 correct = False;
2568                 goto fail;
2569         }
2570         
2571         /* Test 5 ... */
2572         cli_setatr(&cli1, fname, 0, 0);
2573         cli_unlink(&cli1, fname);
2574         
2575         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
2576         if (fnum1 == -1) {
2577                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2578                 correct = False;
2579                 goto fail;
2580         }
2581
2582         /* This should fail - only allowed on NT opens with DELETE access. */
2583
2584         if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2585                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2586                 correct = False;
2587                 goto fail;
2588         }
2589
2590         if (!cli_close(&cli1, fnum1)) {
2591                 printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1));
2592                 correct = False;
2593                 goto fail;
2594         }
2595         
2596         printf("fifth delete on close test succeeded.\n");
2597         
2598         /* Test 6 ... */
2599         cli_setatr(&cli1, fname, 0, 0);
2600         cli_unlink(&cli1, fname);
2601         
2602         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2603                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2604                                    FILE_OVERWRITE_IF, 0);
2605         
2606         if (fnum1 == -1) {
2607                 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2608                 correct = False;
2609                 goto fail;
2610         }
2611         
2612         /* This should fail - only allowed on NT opens with DELETE access. */
2613         
2614         if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2615                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2616                 correct = False;
2617                 goto fail;
2618         }
2619
2620         if (!cli_close(&cli1, fnum1)) {
2621                 printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1));
2622                 correct = False;
2623                 goto fail;
2624         }
2625
2626         printf("sixth delete on close test succeeded.\n");
2627         
2628         /* Test 7 ... */
2629         cli_setatr(&cli1, fname, 0, 0);
2630         cli_unlink(&cli1, fname);
2631         
2632         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2633                                    FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0);
2634                                                                 
2635         if (fnum1 == -1) {
2636                 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2637                 correct = False;
2638                 goto fail;
2639         }
2640
2641         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2642                 printf("[7] setting delete_on_close on file failed !\n");
2643                 correct = False;
2644                 goto fail;
2645         }
2646         
2647         if (!cli_nt_delete_on_close(&cli1, fnum1, False)) {
2648                 printf("[7] unsetting delete_on_close on file failed !\n");
2649                 correct = False;
2650                 goto fail;
2651         }
2652
2653         if (!cli_close(&cli1, fnum1)) {
2654                 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2655                 correct = False;
2656                 goto fail;
2657         }
2658         
2659         /* This next open should succeed - we reset the flag. */
2660         
2661         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2662         if (fnum1 == -1) {
2663                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2664                 correct = False;
2665                 goto fail;
2666         }
2667
2668         if (!cli_close(&cli1, fnum1)) {
2669                 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2670                 correct = False;
2671                 goto fail;
2672         }
2673
2674         printf("seventh delete on close test succeeded.\n");
2675         
2676         /* Test 7 ... */
2677         cli_setatr(&cli1, fname, 0, 0);
2678         cli_unlink(&cli1, fname);
2679         
2680         if (!torture_open_connection(&cli2)) {
2681                 printf("[8] failed to open second connection.\n");
2682                 correct = False;
2683                 goto fail;
2684         }
2685
2686         cli_sockopt(&cli1, sockops);
2687         
2688         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2689                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
2690         
2691         if (fnum1 == -1) {
2692                 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2693                 correct = False;
2694                 goto fail;
2695         }
2696
2697         fnum2 = cli_nt_create_full(&cli2, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2698                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2699         
2700         if (fnum2 == -1) {
2701                 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2702                 correct = False;
2703                 goto fail;
2704         }
2705
2706         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2707                 printf("[8] setting delete_on_close on file failed !\n");
2708                 correct = False;
2709                 goto fail;
2710         }
2711         
2712         if (!cli_close(&cli1, fnum1)) {
2713                 printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1));
2714                 correct = False;
2715                 goto fail;
2716         }
2717
2718         if (!cli_close(&cli2, fnum2)) {
2719                 printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2));
2720                 correct = False;
2721                 goto fail;
2722         }
2723
2724         /* This should fail.. */
2725         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2726         if (fnum1 != -1) {
2727                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2728                 goto fail;
2729                 correct = False;
2730         } else
2731                 printf("eighth delete on close test succeeded.\n");
2732
2733         /* This should fail - we need to set DELETE_ACCESS. */
2734         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2735                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
2736         
2737         if (fnum1 != -1) {
2738                 printf("[9] open of %s succeeded should have failed!\n", fname);
2739                 correct = False;
2740                 goto fail;
2741         }
2742
2743         printf("ninth delete on close test succeeded.\n");
2744
2745         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2746                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
2747         if (fnum1 == -1) {
2748                 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2749                 correct = False;
2750                 goto fail;
2751         }
2752
2753         /* This should delete the file. */
2754         if (!cli_close(&cli1, fnum1)) {
2755                 printf("[10] close failed (%s)\n", cli_errstr(&cli1));
2756                 correct = False;
2757                 goto fail;
2758         }
2759
2760         /* This should fail.. */
2761         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2762         if (fnum1 != -1) {
2763                 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2764                 goto fail;
2765                 correct = False;
2766         } else
2767                 printf("tenth delete on close test succeeded.\n");
2768         printf("finished delete test\n");
2769
2770   fail:
2771         
2772         cli_close(&cli1, fnum1);
2773         cli_close(&cli1, fnum2);
2774         cli_setatr(&cli1, fname, 0, 0);
2775         cli_unlink(&cli1, fname);
2776         
2777         if (!torture_close_connection(&cli1)) {
2778                 correct = False;
2779         }
2780         if (!torture_close_connection(&cli2)) {
2781                 correct = False;
2782         }
2783         return correct;
2784 }
2785
2786
2787 /*
2788   print out server properties
2789  */
2790 static BOOL run_properties(int dummy)
2791 {
2792         static struct cli_state cli;
2793         BOOL correct = True;
2794         
2795         printf("starting properties test\n");
2796         
2797         ZERO_STRUCT(cli);
2798
2799         if (!torture_open_connection(&cli)) {
2800                 return False;
2801         }
2802         
2803         cli_sockopt(&cli, sockops);
2804
2805         d_printf("Capabilities 0x%08x\n", cli.capabilities);
2806
2807         if (!torture_close_connection(&cli)) {
2808                 correct = False;
2809         }
2810
2811         return correct;
2812 }
2813
2814
2815
2816 /* FIRST_DESIRED_ACCESS   0xf019f */
2817 #define FIRST_DESIRED_ACCESS   FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
2818                                FILE_READ_EA|                           /* 0xf */ \
2819                                FILE_WRITE_EA|FILE_READ_ATTRIBUTES|     /* 0x90 */ \
2820                                FILE_WRITE_ATTRIBUTES|                  /* 0x100 */ \
2821                                DELETE_ACCESS|READ_CONTROL_ACCESS|\
2822                                WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS     /* 0xf0000 */
2823 /* SECOND_DESIRED_ACCESS  0xe0080 */
2824 #define SECOND_DESIRED_ACCESS  FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
2825                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2826                                WRITE_OWNER_ACCESS                      /* 0xe0000 */
2827
2828 #if 0
2829 #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
2830                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2831                                FILE_READ_DATA|\
2832                                WRITE_OWNER_ACCESS                      /* */
2833 #endif
2834
2835 /*
2836   Test ntcreate calls made by xcopy
2837  */
2838 static BOOL run_xcopy(int dummy)
2839 {
2840         static struct cli_state cli1;
2841         char *fname = "\\test.txt";
2842         BOOL correct = True;
2843         int fnum1, fnum2;
2844
2845         printf("starting xcopy test\n");
2846         
2847         if (!torture_open_connection(&cli1)) {
2848                 return False;
2849         }
2850         
2851         fnum1 = cli_nt_create_full(&cli1, fname, 
2852                                    FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2853                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 
2854                                    0x4044);
2855
2856         if (fnum1 == -1) {
2857                 printf("First open failed - %s\n", cli_errstr(&cli1));
2858                 return False;
2859         }
2860
2861         fnum2 = cli_nt_create_full(&cli1, fname, 
2862                                    SECOND_DESIRED_ACCESS, 0,
2863                                    FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 
2864                                    0x200000);
2865         if (fnum2 == -1) {
2866                 printf("second open failed - %s\n", cli_errstr(&cli1));
2867                 return False;
2868         }
2869         
2870         if (!torture_close_connection(&cli1)) {
2871                 correct = False;
2872         }
2873         
2874         return correct;
2875 }
2876
2877 /*
2878   Test rename on files open with share delete and no share delete.
2879  */
2880 static BOOL run_rename(int dummy)
2881 {
2882         static struct cli_state cli1;
2883         char *fname = "\\test.txt";
2884         char *fname1 = "\\test1.txt";
2885         BOOL correct = True;
2886         int fnum1;
2887
2888         printf("starting rename test\n");
2889         
2890         if (!torture_open_connection(&cli1)) {
2891                 return False;
2892         }
2893         
2894         cli_unlink(&cli1, fname);
2895         cli_unlink(&cli1, fname1);
2896         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2897                                    FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
2898
2899         if (fnum1 == -1) {
2900                 printf("First open failed - %s\n", cli_errstr(&cli1));
2901                 return False;
2902         }
2903
2904         if (!cli_rename(&cli1, fname, fname1)) {
2905                 printf("First rename failed (this is correct) - %s\n", cli_errstr(&cli1));
2906         } else {
2907                 printf("First rename succeeded - this should have failed !\n");
2908                 correct = False;
2909         }
2910
2911         if (!cli_close(&cli1, fnum1)) {
2912                 printf("close - 1 failed (%s)\n", cli_errstr(&cli1));
2913                 return False;
2914         }
2915
2916         cli_unlink(&cli1, fname);
2917         cli_unlink(&cli1, fname1);
2918         fnum1 = cli_nt_create_full(&cli1, fname,GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2919 #if 0
2920                                    FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
2921 #else
2922                                    FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
2923 #endif
2924
2925         if (fnum1 == -1) {
2926                 printf("Second open failed - %s\n", cli_errstr(&cli1));
2927                 return False;
2928         }
2929
2930         if (!cli_rename(&cli1, fname, fname1)) {
2931                 printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(&cli1));
2932                 correct = False;
2933         } else {
2934                 printf("Second rename succeeded\n");
2935         }
2936
2937         if (!cli_close(&cli1, fnum1)) {
2938                 printf("close - 2 failed (%s)\n", cli_errstr(&cli1));
2939                 return False;
2940         }
2941
2942         cli_unlink(&cli1, fname);
2943         cli_unlink(&cli1, fname1);
2944
2945         fnum1 = cli_nt_create_full(&cli1, fname,READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2946                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
2947
2948         if (fnum1 == -1) {
2949                 printf("Third open failed - %s\n", cli_errstr(&cli1));
2950                 return False;
2951         }
2952
2953
2954 #if 0
2955   {
2956   int fnum2;
2957
2958         fnum2 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2959                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
2960
2961         if (fnum2 == -1) {
2962                 printf("Fourth open failed - %s\n", cli_errstr(&cli1));
2963                 return False;
2964         }
2965         if (!cli_nt_delete_on_close(&cli1, fnum2, True)) {
2966                 printf("[8] setting delete_on_close on file failed !\n");
2967                 return False;
2968         }
2969         
2970         if (!cli_close(&cli1, fnum2)) {
2971                 printf("close - 4 failed (%s)\n", cli_errstr(&cli1));
2972                 return False;
2973         }
2974   }
2975 #endif
2976
2977         if (!cli_rename(&cli1, fname, fname1)) {
2978                 printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(&cli1));
2979                 correct = False;
2980         } else {
2981                 printf("Third rename succeeded\n");
2982         }
2983
2984         if (!cli_close(&cli1, fnum1)) {
2985                 printf("close - 3 failed (%s)\n", cli_errstr(&cli1));
2986                 return False;
2987         }
2988
2989         cli_unlink(&cli1, fname);
2990         cli_unlink(&cli1, fname1);
2991
2992         if (!torture_close_connection(&cli1)) {
2993                 correct = False;
2994         }
2995         
2996         return correct;
2997 }
2998
2999
3000 /*
3001   Test open mode returns on read-only files.
3002  */
3003 static BOOL run_opentest(int dummy)
3004 {
3005         static struct cli_state cli1;
3006         static struct cli_state cli2;
3007         char *fname = "\\readonly.file";
3008         int fnum1, fnum2;
3009         char buf[20];
3010         size_t fsize;
3011         BOOL correct = True;
3012         char *tmp_path;
3013
3014         printf("starting open test\n");
3015         
3016         if (!torture_open_connection(&cli1)) {
3017                 return False;
3018         }
3019         
3020         cli_setatr(&cli1, fname, 0, 0);
3021         cli_unlink(&cli1, fname);
3022         
3023         cli_sockopt(&cli1, sockops);
3024         
3025         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3026         if (fnum1 == -1) {
3027                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3028                 return False;
3029         }
3030
3031         if (!cli_close(&cli1, fnum1)) {
3032                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3033                 return False;
3034         }
3035         
3036         if (!cli_setatr(&cli1, fname, aRONLY, 0)) {
3037                 printf("cli_setatr failed (%s)\n", cli_errstr(&cli1));
3038                 return False;
3039         }
3040         
3041         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
3042         if (fnum1 == -1) {
3043                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3044                 return False;
3045         }
3046         
3047         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3048         fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
3049         
3050         if (check_error(__LINE__, &cli1, ERRDOS, ERRnoaccess, 
3051                         NT_STATUS_ACCESS_DENIED)) {
3052                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3053         }
3054         
3055         printf("finished open test 1\n");
3056         
3057         cli_close(&cli1, fnum1);
3058         
3059         /* Now try not readonly and ensure ERRbadshare is returned. */
3060         
3061         cli_setatr(&cli1, fname, 0, 0);
3062         
3063         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
3064         if (fnum1 == -1) {
3065                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3066                 return False;
3067         }
3068         
3069         /* This will fail - but the error should be ERRshare. */
3070         fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
3071         
3072         if (check_error(__LINE__, &cli1, ERRDOS, ERRbadshare, 
3073                         NT_STATUS_SHARING_VIOLATION)) {
3074                 printf("correct error code ERRDOS/ERRbadshare returned\n");
3075         }
3076         
3077         if (!cli_close(&cli1, fnum1)) {
3078                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3079                 return False;
3080         }
3081         
3082         cli_unlink(&cli1, fname);
3083         
3084         printf("finished open test 2\n");
3085         
3086         /* Test truncate open disposition on file opened for read. */
3087         
3088         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3089         if (fnum1 == -1) {
3090                 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(&cli1));
3091                 return False;
3092         }
3093         
3094         /* write 20 bytes. */
3095         
3096         memset(buf, '\0', 20);
3097
3098         if (cli_write(&cli1, fnum1, 0, buf, 0, 20) != 20) {
3099                 printf("write failed (%s)\n", cli_errstr(&cli1));
3100                 correct = False;
3101         }
3102
3103         if (!cli_close(&cli1, fnum1)) {
3104                 printf("(3) close1 failed (%s)\n", cli_errstr(&cli1));
3105                 return False;
3106         }
3107         
3108         /* Ensure size == 20. */
3109         if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
3110                 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
3111                 return False;
3112         }
3113         
3114         if (fsize != 20) {
3115                 printf("(3) file size != 20\n");
3116                 return False;
3117         }
3118
3119         /* Now test if we can truncate a file opened for readonly. */
3120         
3121         fnum1 = cli_open(&cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3122         if (fnum1 == -1) {
3123                 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(&cli1));
3124                 return False;
3125         }
3126         
3127         if (!cli_close(&cli1, fnum1)) {
3128                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3129                 return False;
3130         }
3131
3132         /* Ensure size == 0. */
3133         if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
3134                 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
3135                 return False;
3136         }
3137
3138         if (fsize != 0) {
3139                 printf("(3) file size != 0\n");
3140                 return False;
3141         }
3142         printf("finished open test 3\n");
3143         
3144         cli_unlink(&cli1, fname);
3145
3146
3147         printf("testing ctemp\n");
3148         fnum1 = cli_ctemp(&cli1, "\\", &tmp_path);
3149         if (fnum1 == -1) {
3150                 printf("ctemp failed (%s)\n", cli_errstr(&cli1));
3151                 return False;
3152         }
3153         printf("ctemp gave path %s\n", tmp_path);
3154         if (!cli_close(&cli1, fnum1)) {
3155                 printf("close of temp failed (%s)\n", cli_errstr(&cli1));
3156         }
3157         if (!cli_unlink(&cli1, tmp_path)) {
3158                 printf("unlink of temp failed (%s)\n", cli_errstr(&cli1));
3159         }
3160         
3161         /* Test the non-io opens... */
3162
3163         if (!torture_open_connection(&cli2)) {
3164                 return False;
3165         }
3166         
3167         cli_setatr(&cli2, fname, 0, 0);
3168         cli_unlink(&cli2, fname);
3169         
3170         cli_sockopt(&cli2, sockops);
3171
3172         printf("TEST #1 testing 2 non-io opens (no delete)\n");
3173         
3174         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3175                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3176
3177         if (fnum1 == -1) {
3178                 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3179                 return False;
3180         }
3181
3182         fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3183                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3184
3185         if (fnum2 == -1) {
3186                 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3187                 return False;
3188         }
3189
3190         if (!cli_close(&cli1, fnum1)) {
3191                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3192                 return False;
3193         }
3194         if (!cli_close(&cli2, fnum2)) {
3195                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3196                 return False;
3197         }
3198
3199         printf("non-io open test #1 passed.\n");
3200
3201         cli_unlink(&cli1, fname);
3202
3203         printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3204         
3205         fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3206                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3207
3208         if (fnum1 == -1) {
3209                 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3210                 return False;
3211         }
3212
3213         fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3214                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3215
3216         if (fnum2 == -1) {
3217                 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3218                 return False;
3219         }
3220
3221         if (!cli_close(&cli1, fnum1)) {
3222                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3223                 return False;
3224         }
3225         if (!cli_close(&cli2, fnum2)) {
3226                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3227                 return False;
3228         }
3229
3230         printf("non-io open test #2 passed.\n");
3231
3232         cli_unlink(&cli1, fname);
3233
3234         printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3235         
3236         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3237                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3238
3239         if (fnum1 == -1) {
3240                 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3241                 return False;
3242         }
3243
3244         fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3245                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3246
3247         if (fnum2 == -1) {
3248                 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3249                 return False;
3250         }
3251
3252         if (!cli_close(&cli1, fnum1)) {
3253                 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3254                 return False;
3255         }
3256         if (!cli_close(&cli2, fnum2)) {
3257                 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3258                 return False;
3259         }
3260
3261         printf("non-io open test #3 passed.\n");
3262
3263         cli_unlink(&cli1, fname);
3264
3265         printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3266         
3267         fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3268                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3269
3270         if (fnum1 == -1) {
3271                 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3272                 return False;
3273         }
3274
3275         fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3276                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3277
3278         if (fnum2 != -1) {
3279                 printf("test 4 open 2 of %s SUCCEEDED - should have failed\n", fname, cli_errstr(&cli2));
3280                 return False;
3281         }
3282
3283         printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(&cli2), "sharing violation");
3284
3285         if (!cli_close(&cli1, fnum1)) {
3286                 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3287                 return False;
3288         }
3289
3290         printf("non-io open test #4 passed.\n");
3291
3292         cli_unlink(&cli1, fname);
3293
3294         printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3295         
3296         fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3297                                    FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
3298
3299         if (fnum1 == -1) {
3300                 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3301                 return False;
3302         }
3303
3304         fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3305                                    FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
3306
3307         if (fnum2 == -1) {
3308                 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3309                 return False;
3310         }
3311
3312         if (!cli_close(&cli1, fnum1)) {
3313                 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3314                 return False;
3315         }
3316
3317         if (!cli_close(&cli2, fnum2)) {
3318                 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3319                 return False;
3320         }
3321
3322         printf("non-io open test #5 passed.\n");
3323
3324         printf("TEST #6 testing 1 non-io open, one io open\n");
3325         
3326         cli_unlink(&cli1, fname);
3327
3328         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3329                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3330
3331         if (fnum1 == -1) {
3332                 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3333                 return False;
3334         }
3335
3336         fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3337                                    FILE_SHARE_READ, FILE_OPEN_IF, 0);
3338
3339         if (fnum2 == -1) {
3340                 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3341                 return False;
3342         }
3343
3344         if (!cli_close(&cli1, fnum1)) {
3345                 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3346                 return False;
3347         }
3348
3349         if (!cli_close(&cli2, fnum2)) {
3350                 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3351                 return False;
3352         }
3353
3354         printf("non-io open test #6 passed.\n");
3355
3356         printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3357
3358         cli_unlink(&cli1, fname);
3359
3360         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3361                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3362
3363         if (fnum1 == -1) {
3364                 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3365                 return False;
3366         }
3367
3368         fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3369                                    FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
3370
3371         if (fnum2 != -1) {
3372                 printf("test 7 open 2 of %s SUCCEEDED - should have failed\n", fname, cli_errstr(&cli2));
3373                 return False;
3374         }
3375
3376         printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(&cli2), "sharing violation");
3377
3378         if (!cli_close(&cli1, fnum1)) {
3379                 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3380                 return False;
3381         }
3382
3383         printf("non-io open test #7 passed.\n");
3384
3385         cli_unlink(&cli1, fname);
3386
3387         if (!torture_close_connection(&cli1)) {
3388                 correct = False;
3389         }
3390         if (!torture_close_connection(&cli2)) {
3391                 correct = False;
3392         }
3393         
3394         return correct;
3395 }
3396
3397 static void list_fn(file_info *finfo, const char *name, void *state)
3398 {
3399         
3400 }
3401
3402 /*
3403   test directory listing speed
3404  */
3405 static BOOL run_dirtest(int dummy)
3406 {
3407         int i;
3408         static struct cli_state cli;
3409         int fnum;
3410         double t1;
3411         BOOL correct = True;
3412
3413         printf("starting directory test\n");
3414
3415         if (!torture_open_connection(&cli)) {
3416                 return False;
3417         }
3418
3419         cli_sockopt(&cli, sockops);
3420
3421         srandom(0);
3422         for (i=0;i<numops;i++) {
3423                 fstring fname;
3424                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3425                 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
3426                 if (fnum == -1) {
3427                         fprintf(stderr,"Failed to open %s\n", fname);
3428                         return False;
3429                 }
3430                 cli_close(&cli, fnum);
3431         }
3432
3433         t1 = end_timer();
3434
3435         printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
3436         printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
3437         printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
3438
3439         printf("dirtest core %g seconds\n", end_timer() - t1);
3440
3441         srandom(0);
3442         for (i=0;i<numops;i++) {
3443                 fstring fname;
3444                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3445                 cli_unlink(&cli, fname);
3446         }
3447
3448         if (!torture_close_connection(&cli)) {
3449                 correct = False;
3450         }
3451
3452         printf("finished dirtest\n");
3453
3454         return correct;
3455 }
3456
3457 static BOOL run_error_map_extract(int dummy) {
3458         
3459         static struct cli_state c_dos;
3460         static struct cli_state c_nt;
3461
3462         uint32 error;
3463
3464         uint32 flgs2, errnum;
3465         uint8 errclass;
3466
3467         NTSTATUS nt_status;
3468
3469         fstring user;
3470
3471         /* NT-Error connection */
3472
3473         if (!open_nbt_connection(&c_nt)) {
3474                 return False;
3475         }
3476
3477         c_nt.use_spnego = False;
3478
3479         if (!cli_negprot(&c_nt)) {
3480                 printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(&c_nt));
3481                 cli_shutdown(&c_nt);
3482                 return False;
3483         }
3484
3485         if (!cli_session_setup(&c_nt, "", "", 0, "", 0,
3486                                workgroup)) {
3487                 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(&c_nt));
3488                 return False;
3489         }
3490
3491         /* DOS-Error connection */
3492
3493         if (!open_nbt_connection(&c_dos)) {
3494                 return False;
3495         }
3496
3497         c_dos.use_spnego = False;
3498         c_dos.force_dos_errors = True;
3499
3500         if (!cli_negprot(&c_dos)) {
3501                 printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(&c_dos));
3502                 cli_shutdown(&c_dos);
3503                 return False;
3504         }
3505
3506         if (!cli_session_setup(&c_dos, "", "", 0, "", 0,
3507                                workgroup)) {
3508                 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(&c_dos));
3509                 return False;
3510         }
3511
3512         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
3513                 snprintf(user, sizeof(user), "%X", error);
3514
3515                 if (cli_session_setup(&c_nt, user, 
3516                                        password, strlen(password),
3517                                        password, strlen(password),
3518                                       workgroup)) {
3519                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
3520                 }
3521                 
3522                 flgs2 = SVAL(c_nt.inbuf,smb_flg2);
3523                 
3524                 /* Case #1: 32-bit NT errors */
3525                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
3526                         nt_status = NT_STATUS(IVAL(c_nt.inbuf,smb_rcls));
3527                 } else {
3528                         printf("/** Dos error on NT connection! (%s) */\n", 
3529                                cli_errstr(&c_nt));
3530                         nt_status = NT_STATUS(0xc0000000);
3531                 }
3532
3533                 if (cli_session_setup(&c_dos, user, 
3534                                        password, strlen(password),
3535                                        password, strlen(password),
3536                                        workgroup)) {
3537                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
3538                 }
3539                 flgs2 = SVAL(c_dos.inbuf,smb_flg2), errnum;
3540                 
3541                 /* Case #1: 32-bit NT errors */
3542                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
3543                         printf("/** NT error on DOS connection! (%s) */\n", 
3544                                cli_errstr(&c_nt));
3545                         errnum = errclass = 0;
3546                 } else {
3547                         cli_dos_error(&c_dos, &errclass, &errnum);
3548                 }
3549
3550                 if (NT_STATUS_V(nt_status) != error) { 
3551                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
3552                                get_nt_error_c_code(NT_STATUS(error)), 
3553                                get_nt_error_c_code(nt_status));
3554                 }
3555                 
3556                 printf("\t{%s,\t%s,\t%s},\n", 
3557                        smb_dos_err_class(errclass), 
3558                        smb_dos_err_name(errclass, errnum), 
3559                        get_nt_error_c_code(NT_STATUS(error)));
3560         }
3561         return True;
3562 }
3563
3564 static double create_procs(BOOL (*fn)(int), BOOL *result)
3565 {
3566         int i, status;
3567         volatile pid_t *child_status;
3568         volatile BOOL *child_status_out;
3569         int synccount;
3570         int tries = 8;
3571
3572         synccount = 0;
3573
3574         child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
3575         if (!child_status) {
3576                 printf("Failed to setup shared memory\n");
3577                 return -1;
3578         }
3579
3580         child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
3581         if (!child_status_out) {
3582                 printf("Failed to setup result status shared memory\n");
3583                 return -1;
3584         }
3585
3586         for (i = 0; i < nprocs; i++) {
3587                 child_status[i] = 0;
3588                 child_status_out[i] = True;
3589         }
3590
3591         start_timer();
3592
3593         for (i=0;i<nprocs;i++) {
3594                 procnum = i;
3595                 if (fork() == 0) {
3596                         pid_t mypid = getpid();
3597                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
3598
3599                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
3600
3601                         while (1) {
3602                                 memset(&current_cli, 0, sizeof(current_cli));
3603                                 if (torture_open_connection(&current_cli)) break;
3604                                 if (tries-- == 0) {
3605                                         printf("pid %d failed to start\n", (int)getpid());
3606                                         _exit(1);
3607                                 }
3608                                 msleep(10);     
3609                         }
3610
3611                         child_status[i] = getpid();
3612
3613                         while (child_status[i] && end_timer() < 5) msleep(2);
3614
3615                         child_status_out[i] = fn(i);
3616                         _exit(0);
3617                 }
3618         }
3619
3620         do {
3621                 synccount = 0;
3622                 for (i=0;i<nprocs;i++) {
3623                         if (child_status[i]) synccount++;
3624                 }
3625                 if (synccount == nprocs) break;
3626                 msleep(10);
3627         } while (end_timer() < 30);
3628
3629         if (synccount != nprocs) {
3630                 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
3631                 *result = False;
3632                 return end_timer();
3633         }
3634
3635         /* start the client load */
3636         start_timer();
3637
3638         for (i=0;i<nprocs;i++) {
3639                 child_status[i] = 0;
3640         }
3641
3642         printf("%d clients started\n", nprocs);
3643
3644         for (i=0;i<nprocs;i++) {
3645                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
3646         }
3647
3648         printf("\n");
3649         
3650         for (i=0;i<nprocs;i++) {
3651                 if (!child_status_out[i]) {
3652                         *result = False;
3653                 }
3654         }
3655         return end_timer();
3656 }
3657
3658 #define FLAG_MULTIPROC 1
3659
3660 static struct {
3661         char *name;
3662         BOOL (*fn)(int);
3663         unsigned flags;
3664 } torture_ops[] = {
3665         {"FDPASS", run_fdpasstest, 0},
3666         {"LOCK1",  run_locktest1,  0},
3667         {"LOCK2",  run_locktest2,  0},
3668         {"LOCK3",  run_locktest3,  0},
3669         {"LOCK4",  run_locktest4,  0},
3670         {"LOCK5",  run_locktest5,  0},
3671         {"LOCK6",  run_locktest6,  0},
3672         {"UNLINK", run_unlinktest, 0},
3673         {"BROWSE", run_browsetest, 0},
3674         {"ATTR",   run_attrtest,   0},
3675         {"TRANS2", run_trans2test, 0},
3676         {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
3677         {"TORTURE",run_torture,    FLAG_MULTIPROC},
3678         {"RANDOMIPC", run_randomipc, 0},
3679         {"NEGNOWAIT", run_negprot_nowait, 0},
3680         {"NBENCH",  run_nbench, 0},
3681         {"OPLOCK1",  run_oplock1, 0},
3682         {"OPLOCK2",  run_oplock2, 0},
3683         {"OPLOCK3",  run_oplock3, 0},
3684         {"DIR",  run_dirtest, 0},
3685         {"DENY1",  torture_denytest1, 0},
3686         {"DENY2",  torture_denytest2, 0},
3687         {"TCON",  run_tcon_test, 0},
3688         {"RW1",  run_readwritetest, 0},
3689         {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
3690         {"RW3",  run_readwritelarge, 0},
3691         {"OPEN", run_opentest, 0},
3692         {"XCOPY", run_xcopy, 0},
3693         {"RENAME", run_rename, 0},
3694         {"DELETE", run_deletetest, 0},
3695         {"PROPERTIES", run_properties, 0},
3696         {"W2K", run_w2ktest, 0},
3697         {"TRANS2SCAN", torture_trans2_scan, 0},
3698         {"NTTRANSSCAN", torture_nttrans_scan, 0},
3699         {"UTABLE", torture_utable, 0},
3700         {"CASETABLE", torture_casetable, 0},
3701         {"ERRMAPEXTRACT", run_error_map_extract, 0},
3702         {NULL, NULL, 0}};
3703
3704
3705
3706 /****************************************************************************
3707 run a specified test or "ALL"
3708 ****************************************************************************/
3709 static BOOL run_test(char *name)
3710 {
3711         BOOL ret = True;
3712         BOOL result = True;
3713         int i;
3714         double t;
3715         if (strequal(name,"ALL")) {
3716                 for (i=0;torture_ops[i].name;i++) {
3717                         run_test(torture_ops[i].name);
3718                 }
3719         }
3720         
3721         for (i=0;torture_ops[i].name;i++) {
3722                 snprintf(randomfname, sizeof(randomfname), "\\XX%x", 
3723                          (unsigned)random());
3724
3725                 if (strequal(name, torture_ops[i].name)) {
3726                         printf("Running %s\n", name);
3727                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
3728                                 t = create_procs(torture_ops[i].fn, &result);
3729                                 if (!result) { 
3730                                         ret = False;
3731                                         printf("TEST %s FAILED!\n", name);
3732                                 }
3733                                          
3734                         } else {
3735                                 start_timer();
3736                                 if (!torture_ops[i].fn(0)) {
3737                                         ret = False;
3738                                         printf("TEST %s FAILED!\n", name);
3739                                 }
3740                                 t = end_timer();
3741                         }
3742                         printf("%s took %g secs\n\n", name, t);
3743                 }
3744         }
3745         return ret;
3746 }
3747
3748
3749 static void usage(void)
3750 {
3751         int i;
3752
3753         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
3754
3755         printf("\t-d debuglevel\n");
3756         printf("\t-U user%%pass\n");
3757         printf("\t-k               use kerberos\n");
3758         printf("\t-N numprocs\n");
3759         printf("\t-n my_netbios_name\n");
3760         printf("\t-W workgroup\n");
3761         printf("\t-o num_operations\n");
3762         printf("\t-O socket_options\n");
3763         printf("\t-m maximum protocol\n");
3764         printf("\t-L use oplocks\n");
3765         printf("\t-c CLIENT.TXT   specify client load file for NBENCH\n");
3766         printf("\t-A showall\n");
3767         printf("\n\n");
3768
3769         printf("tests are:");
3770         for (i=0;torture_ops[i].name;i++) {
3771                 printf(" %s", torture_ops[i].name);
3772         }
3773         printf("\n");
3774
3775         printf("default test is ALL\n");
3776         
3777         exit(1);
3778 }
3779
3780
3781
3782
3783
3784 /****************************************************************************
3785   main program
3786 ****************************************************************************/
3787  int main(int argc,char *argv[])
3788 {
3789         int opt, i;
3790         char *p;
3791         int gotpass = 0;
3792         extern char *optarg;
3793         extern int optind;
3794         BOOL correct = True;
3795
3796         dbf = x_stdout;
3797
3798 #ifdef HAVE_SETBUFFER
3799         setbuffer(stdout, NULL, 0);
3800 #endif
3801
3802         lp_load(dyn_CONFIGFILE,True,False,False);
3803         load_interfaces();
3804
3805         if (argc < 2) {
3806                 usage();
3807         }
3808
3809         for(p = argv[1]; *p; p++)
3810           if(*p == '\\')
3811             *p = '/';
3812  
3813         if (strncmp(argv[1], "//", 2)) {
3814                 usage();
3815         }
3816
3817         fstrcpy(host, &argv[1][2]);
3818         p = strchr_m(&host[2],'/');
3819         if (!p) {
3820                 usage();
3821         }
3822         *p = 0;
3823         fstrcpy(share, p+1);
3824
3825         get_myname(myname);
3826
3827         if (*username == 0 && getenv("LOGNAME")) {
3828           pstrcpy(username,getenv("LOGNAME"));
3829         }
3830
3831         argc--;
3832         argv++;
3833
3834
3835         fstrcpy(workgroup, lp_workgroup());
3836
3837         while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:Ld:Ac:k")) != EOF) {
3838                 switch (opt) {
3839                 case 'W':
3840                         fstrcpy(workgroup,optarg);
3841                         break;
3842                 case 'm':
3843                         max_protocol = interpret_protocol(optarg, max_protocol);
3844                         break;
3845                 case 'N':
3846                         nprocs = atoi(optarg);
3847                         break;
3848                 case 'o':
3849                         numops = atoi(optarg);
3850                         break;
3851                 case 'd':
3852                         DEBUGLEVEL = atoi(optarg);
3853                         break;
3854                 case 'O':
3855                         sockops = optarg;
3856                         break;
3857                 case 'L':
3858                         use_oplocks = True;
3859                         break;
3860                 case 'A':
3861                         torture_showall = True;
3862                         break;
3863                 case 'n':
3864                         fstrcpy(myname, optarg);
3865                         break;
3866                 case 'c':
3867                         client_txt = optarg;
3868                         break;
3869                 case 'k':
3870 #ifdef HAVE_KRB5
3871                         use_kerberos = True;
3872                         gotpass = True;
3873 #else
3874                         d_printf("No kerberos support compiled in\n");
3875                         exit(1);
3876 #endif
3877                         break;
3878                 case 'U':
3879                         pstrcpy(username,optarg);
3880                         p = strchr_m(username,'%');
3881                         if (p) {
3882                                 *p = 0;
3883                                 pstrcpy(password, p+1);
3884                                 gotpass = 1;
3885                         }
3886                         break;
3887                 default:
3888                         printf("Unknown option %c (%d)\n", (char)opt, opt);
3889                         usage();
3890                 }
3891         }
3892
3893
3894         while (!gotpass) {
3895                 p = getpass("Password:");
3896                 if (p) {
3897                         pstrcpy(password, p);
3898                         gotpass = 1;
3899                 }
3900         }
3901
3902         printf("host=%s share=%s user=%s myname=%s\n", 
3903                host, share, username, myname);
3904
3905         if (argc == 1) {
3906                 correct = run_test("ALL");
3907         } else {
3908                 for (i=1;i<argc;i++) {
3909                         if (!run_test(argv[i])) {
3910                                 correct = False;
3911                         }
3912                 }
3913         }
3914
3915         if (correct) {
3916                 return(0);
3917         } else {
3918                 return(1);
3919         }
3920 }