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