Antti Andreimann <Antti.Andreimann@mail.ee> has done some changes to enable
[gd/samba-autobuild/.git] / source3 / torture / torture.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB torture tester
4    Copyright (C) Andrew Tridgell 1997-1998
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #define NO_SYSLOG
22
23 #include "includes.h"
24
25 static fstring host, workgroup, share, password, username, myname;
26 static int max_protocol = PROTOCOL_NT1;
27 static 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 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                                    FILE_DELETE_ON_CLOSE);
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 succeeded (should fail)\n", fname);
2407                 correct = False;
2408                 goto fail;
2409         }
2410         
2411         printf("first delete on close test succeeded.\n");
2412         
2413         /* Test 2 - this should delete the file on close. */
2414         
2415         cli_setatr(&cli1, fname, 0, 0);
2416         cli_unlink(&cli1, fname);
2417         
2418         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS,
2419                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, 
2420                                    FILE_OVERWRITE_IF, 0);
2421         
2422         if (fnum1 == -1) {
2423                 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2424                 correct = False;
2425                 goto fail;
2426         }
2427         
2428         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2429                 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2430                 correct = False;
2431                 goto fail;
2432         }
2433         
2434         if (!cli_close(&cli1, fnum1)) {
2435                 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2436                 correct = False;
2437                 goto fail;
2438         }
2439         
2440         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2441         if (fnum1 != -1) {
2442                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2443                 if (!cli_close(&cli1, fnum1)) {
2444                         printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2445                         correct = False;
2446                         goto fail;
2447                 }
2448                 cli_unlink(&cli1, fname);
2449         } else
2450                 printf("second delete on close test succeeded.\n");
2451         
2452         /* Test 3 - ... */
2453         cli_setatr(&cli1, fname, 0, 0);
2454         cli_unlink(&cli1, fname);
2455
2456         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2457                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2458
2459         if (fnum1 == -1) {
2460                 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2461                 correct = False;
2462                 goto fail;
2463         }
2464
2465         /* This should fail with a sharing violation - open for delete is only compatible
2466            with SHARE_DELETE. */
2467
2468         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2469                         FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0);
2470
2471         if (fnum2 != -1) {
2472                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
2473                 correct = False;
2474                 goto fail;
2475         }
2476
2477         /* This should succeed. */
2478
2479         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2480                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2481
2482         if (fnum2 == -1) {
2483                 printf("[3] open  - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2484                 correct = False;
2485                 goto fail;
2486         }
2487
2488         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2489                 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2490                 correct = False;
2491                 goto fail;
2492         }
2493         
2494         if (!cli_close(&cli1, fnum1)) {
2495                 printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1));
2496                 correct = False;
2497                 goto fail;
2498         }
2499         
2500         if (!cli_close(&cli1, fnum2)) {
2501                 printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1));
2502                 correct = False;
2503                 goto fail;
2504         }
2505         
2506         /* This should fail - file should no longer be there. */
2507
2508         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2509         if (fnum1 != -1) {
2510                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2511                 if (!cli_close(&cli1, fnum1)) {
2512                         printf("[3] close failed (%s)\n", cli_errstr(&cli1));
2513                 }
2514                 cli_unlink(&cli1, fname);
2515                 correct = False;
2516                 goto fail;
2517         } else
2518                 printf("third delete on close test succeeded.\n");
2519
2520         /* Test 4 ... */
2521         cli_setatr(&cli1, fname, 0, 0);
2522         cli_unlink(&cli1, fname);
2523
2524         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2525                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2526                                                                 
2527         if (fnum1 == -1) {
2528                 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2529                 correct = False;
2530                 goto fail;
2531         }
2532
2533         /* This should succeed. */
2534         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2535                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2536         if (fnum2 == -1) {
2537                 printf("[4] open  - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2538                 correct = False;
2539                 goto fail;
2540         }
2541         
2542         if (!cli_close(&cli1, fnum2)) {
2543                 printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1));
2544                 correct = False;
2545                 goto fail;
2546         }
2547         
2548         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2549                 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2550                 correct = False;
2551                 goto fail;
2552         }
2553         
2554         /* This should fail - no more opens once delete on close set. */
2555         fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2556                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2557         if (fnum2 != -1) {
2558                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
2559                 correct = False;
2560                 goto fail;
2561         } else
2562                 printf("fourth delete on close test succeeded.\n");
2563         
2564         if (!cli_close(&cli1, fnum1)) {
2565                 printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1));
2566                 correct = False;
2567                 goto fail;
2568         }
2569         
2570         /* Test 5 ... */
2571         cli_setatr(&cli1, fname, 0, 0);
2572         cli_unlink(&cli1, fname);
2573         
2574         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
2575         if (fnum1 == -1) {
2576                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2577                 correct = False;
2578                 goto fail;
2579         }
2580
2581         /* This should fail - only allowed on NT opens with DELETE access. */
2582
2583         if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2584                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2585                 correct = False;
2586                 goto fail;
2587         }
2588
2589         if (!cli_close(&cli1, fnum1)) {
2590                 printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1));
2591                 correct = False;
2592                 goto fail;
2593         }
2594         
2595         printf("fifth delete on close test succeeded.\n");
2596         
2597         /* Test 6 ... */
2598         cli_setatr(&cli1, fname, 0, 0);
2599         cli_unlink(&cli1, fname);
2600         
2601         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2602                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2603                                    FILE_OVERWRITE_IF, 0);
2604         
2605         if (fnum1 == -1) {
2606                 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2607                 correct = False;
2608                 goto fail;
2609         }
2610         
2611         /* This should fail - only allowed on NT opens with DELETE access. */
2612         
2613         if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2614                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2615                 correct = False;
2616                 goto fail;
2617         }
2618
2619         if (!cli_close(&cli1, fnum1)) {
2620                 printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1));
2621                 correct = False;
2622                 goto fail;
2623         }
2624
2625         printf("sixth delete on close test succeeded.\n");
2626         
2627         /* Test 7 ... */
2628         cli_setatr(&cli1, fname, 0, 0);
2629         cli_unlink(&cli1, fname);
2630         
2631         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2632                                    FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0);
2633                                                                 
2634         if (fnum1 == -1) {
2635                 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2636                 correct = False;
2637                 goto fail;
2638         }
2639
2640         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2641                 printf("[7] setting delete_on_close on file failed !\n");
2642                 correct = False;
2643                 goto fail;
2644         }
2645         
2646         if (!cli_nt_delete_on_close(&cli1, fnum1, False)) {
2647                 printf("[7] unsetting delete_on_close on file failed !\n");
2648                 correct = False;
2649                 goto fail;
2650         }
2651
2652         if (!cli_close(&cli1, fnum1)) {
2653                 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2654                 correct = False;
2655                 goto fail;
2656         }
2657         
2658         /* This next open should succeed - we reset the flag. */
2659         
2660         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2661         if (fnum1 == -1) {
2662                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2663                 correct = False;
2664                 goto fail;
2665         }
2666
2667         if (!cli_close(&cli1, fnum1)) {
2668                 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2669                 correct = False;
2670                 goto fail;
2671         }
2672
2673         printf("seventh delete on close test succeeded.\n");
2674         
2675         /* Test 7 ... */
2676         cli_setatr(&cli1, fname, 0, 0);
2677         cli_unlink(&cli1, fname);
2678         
2679         if (!torture_open_connection(&cli2)) {
2680                 printf("[8] failed to open second connection.\n");
2681                 correct = False;
2682                 goto fail;
2683         }
2684
2685         cli_sockopt(&cli1, sockops);
2686         
2687         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2688                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
2689         
2690         if (fnum1 == -1) {
2691                 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2692                 correct = False;
2693                 goto fail;
2694         }
2695
2696         fnum2 = cli_nt_create_full(&cli2, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2697                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2698         
2699         if (fnum2 == -1) {
2700                 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2701                 correct = False;
2702                 goto fail;
2703         }
2704
2705         if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2706                 printf("[8] setting delete_on_close on file failed !\n");
2707                 correct = False;
2708                 goto fail;
2709         }
2710         
2711         if (!cli_close(&cli1, fnum1)) {
2712                 printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1));
2713                 correct = False;
2714                 goto fail;
2715         }
2716
2717         if (!cli_close(&cli2, fnum2)) {
2718                 printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2));
2719                 correct = False;
2720                 goto fail;
2721         }
2722
2723         /* This should fail.. */
2724         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2725         if (fnum1 != -1) {
2726                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2727                 goto fail;
2728                 correct = False;
2729         } else
2730                 printf("eighth delete on close test succeeded.\n");
2731
2732         /* This should fail - we need to set DELETE_ACCESS. */
2733         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2734                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
2735         
2736         if (fnum1 != -1) {
2737                 printf("[9] open of %s succeeded should have failed!\n", fname);
2738                 correct = False;
2739                 goto fail;
2740         }
2741
2742         printf("ninth delete on close test succeeded.\n");
2743
2744         fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2745                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
2746         if (fnum1 == -1) {
2747                 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2748                 correct = False;
2749                 goto fail;
2750         }
2751
2752         /* This should delete the file. */
2753         if (!cli_close(&cli1, fnum1)) {
2754                 printf("[10] close failed (%s)\n", cli_errstr(&cli1));
2755                 correct = False;
2756                 goto fail;
2757         }
2758
2759         /* This should fail.. */
2760         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2761         if (fnum1 != -1) {
2762                 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2763                 goto fail;
2764                 correct = False;
2765         } else
2766                 printf("tenth delete on close test succeeded.\n");
2767         printf("finished delete test\n");
2768
2769   fail:
2770         
2771         cli_close(&cli1, fnum1);
2772         cli_close(&cli1, fnum2);
2773         cli_setatr(&cli1, fname, 0, 0);
2774         cli_unlink(&cli1, fname);
2775         
2776         if (!torture_close_connection(&cli1)) {
2777                 correct = False;
2778         }
2779         if (!torture_close_connection(&cli2)) {
2780                 correct = False;
2781         }
2782         return correct;
2783 }
2784
2785
2786 /*
2787   print out server properties
2788  */
2789 static BOOL run_properties(int dummy)
2790 {
2791         static struct cli_state cli;
2792         BOOL correct = True;
2793         
2794         printf("starting properties test\n");
2795         
2796         ZERO_STRUCT(cli);
2797
2798         if (!torture_open_connection(&cli)) {
2799                 return False;
2800         }
2801         
2802         cli_sockopt(&cli, sockops);
2803
2804         d_printf("Capabilities 0x%08x\n", cli.capabilities);
2805
2806         if (!torture_close_connection(&cli)) {
2807                 correct = False;
2808         }
2809
2810         return correct;
2811 }
2812
2813
2814
2815 /* FIRST_DESIRED_ACCESS   0xf019f */
2816 #define FIRST_DESIRED_ACCESS   FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
2817                                FILE_READ_EA|                           /* 0xf */ \
2818                                FILE_WRITE_EA|FILE_READ_ATTRIBUTES|     /* 0x90 */ \
2819                                FILE_WRITE_ATTRIBUTES|                  /* 0x100 */ \
2820                                DELETE_ACCESS|READ_CONTROL_ACCESS|\
2821                                WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS     /* 0xf0000 */
2822 /* SECOND_DESIRED_ACCESS  0xe0080 */
2823 #define SECOND_DESIRED_ACCESS  FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
2824                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2825                                WRITE_OWNER_ACCESS                      /* 0xe0000 */
2826
2827 #if 0
2828 #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
2829                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2830                                FILE_READ_DATA|\
2831                                WRITE_OWNER_ACCESS                      /* */
2832 #endif
2833
2834 /*
2835   Test ntcreate calls made by xcopy
2836  */
2837 static BOOL run_xcopy(int dummy)
2838 {
2839         static struct cli_state cli1;
2840         const char *fname = "\\test.txt";
2841         BOOL correct = True;
2842         int fnum1, fnum2;
2843
2844         printf("starting xcopy test\n");
2845         
2846         if (!torture_open_connection(&cli1)) {
2847                 return False;
2848         }
2849         
2850         fnum1 = cli_nt_create_full(&cli1, fname, 
2851                                    FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
2852                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 
2853                                    0x4044);
2854
2855         if (fnum1 == -1) {
2856                 printf("First open failed - %s\n", cli_errstr(&cli1));
2857                 return False;
2858         }
2859
2860         fnum2 = cli_nt_create_full(&cli1, fname, 
2861                                    SECOND_DESIRED_ACCESS, 0,
2862                                    FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 
2863                                    0x200000);
2864         if (fnum2 == -1) {
2865                 printf("second open failed - %s\n", cli_errstr(&cli1));
2866                 return False;
2867         }
2868         
2869         if (!torture_close_connection(&cli1)) {
2870                 correct = False;
2871         }
2872         
2873         return correct;
2874 }
2875
2876 /*
2877   Test rename on files open with share delete and no share delete.
2878  */
2879 static BOOL run_rename(int dummy)
2880 {
2881         static struct cli_state cli1;
2882         const char *fname = "\\test.txt";
2883         const char *fname1 = "\\test1.txt";
2884         BOOL correct = True;
2885         int fnum1;
2886
2887         printf("starting rename test\n");
2888         
2889         if (!torture_open_connection(&cli1)) {
2890                 return False;
2891         }
2892         
2893         cli_unlink(&cli1, fname);
2894         cli_unlink(&cli1, fname1);
2895         fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2896                                    FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
2897
2898         if (fnum1 == -1) {
2899                 printf("First open failed - %s\n", cli_errstr(&cli1));
2900                 return False;
2901         }
2902
2903         if (!cli_rename(&cli1, fname, fname1)) {
2904                 printf("First rename failed (this is correct) - %s\n", cli_errstr(&cli1));
2905         } else {
2906                 printf("First rename succeeded - this should have failed !\n");
2907                 correct = False;
2908         }
2909
2910         if (!cli_close(&cli1, fnum1)) {
2911                 printf("close - 1 failed (%s)\n", cli_errstr(&cli1));
2912                 return False;
2913         }
2914
2915         cli_unlink(&cli1, fname);
2916         cli_unlink(&cli1, fname1);
2917         fnum1 = cli_nt_create_full(&cli1, fname,GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2918 #if 0
2919                                    FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
2920 #else
2921                                    FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
2922 #endif
2923
2924         if (fnum1 == -1) {
2925                 printf("Second open failed - %s\n", cli_errstr(&cli1));
2926                 return False;
2927         }
2928
2929         if (!cli_rename(&cli1, fname, fname1)) {
2930                 printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(&cli1));
2931                 correct = False;
2932         } else {
2933                 printf("Second rename succeeded\n");
2934         }
2935
2936         if (!cli_close(&cli1, fnum1)) {
2937                 printf("close - 2 failed (%s)\n", cli_errstr(&cli1));
2938                 return False;
2939         }
2940
2941         cli_unlink(&cli1, fname);
2942         cli_unlink(&cli1, fname1);
2943
2944         fnum1 = cli_nt_create_full(&cli1, fname,READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2945                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
2946
2947         if (fnum1 == -1) {
2948                 printf("Third open failed - %s\n", cli_errstr(&cli1));
2949                 return False;
2950         }
2951
2952
2953 #if 0
2954   {
2955   int fnum2;
2956
2957         fnum2 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2958                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
2959
2960         if (fnum2 == -1) {
2961                 printf("Fourth open failed - %s\n", cli_errstr(&cli1));
2962                 return False;
2963         }
2964         if (!cli_nt_delete_on_close(&cli1, fnum2, True)) {
2965                 printf("[8] setting delete_on_close on file failed !\n");
2966                 return False;
2967         }
2968         
2969         if (!cli_close(&cli1, fnum2)) {
2970                 printf("close - 4 failed (%s)\n", cli_errstr(&cli1));
2971                 return False;
2972         }
2973   }
2974 #endif
2975
2976         if (!cli_rename(&cli1, fname, fname1)) {
2977                 printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(&cli1));
2978                 correct = False;
2979         } else {
2980                 printf("Third rename succeeded\n");
2981         }
2982
2983         if (!cli_close(&cli1, fnum1)) {
2984                 printf("close - 3 failed (%s)\n", cli_errstr(&cli1));
2985                 return False;
2986         }
2987
2988         cli_unlink(&cli1, fname);
2989         cli_unlink(&cli1, fname1);
2990
2991         if (!torture_close_connection(&cli1)) {
2992                 correct = False;
2993         }
2994         
2995         return correct;
2996 }
2997
2998 static BOOL run_pipe_number(int dummy)
2999 {
3000         static struct cli_state cli1;
3001         const char *pipe_name = "\\SPOOLSS";
3002         int fnum;
3003         int num_pipes = 0;
3004
3005         printf("starting pipenumber test\n");
3006         if (!torture_open_connection(&cli1)) {
3007                 return False;
3008         }
3009
3010         cli_sockopt(&cli1, sockops);
3011         while(1) {
3012                 fnum = cli_nt_create_full(&cli1, pipe_name,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3013                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0);
3014
3015                 if (fnum == -1) {
3016                         printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(&cli1));
3017                         break;
3018                 }
3019                 num_pipes++;
3020         }
3021
3022         printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3023         torture_close_connection(&cli1);
3024         return True;
3025 }
3026
3027 /*
3028   Test open mode returns on read-only files.
3029  */
3030 static BOOL run_opentest(int dummy)
3031 {
3032         static struct cli_state cli1;
3033         static struct cli_state cli2;
3034         const char *fname = "\\readonly.file";
3035         int fnum1, fnum2;
3036         char buf[20];
3037         size_t fsize;
3038         BOOL correct = True;
3039         char *tmp_path;
3040
3041         printf("starting open test\n");
3042         
3043         if (!torture_open_connection(&cli1)) {
3044                 return False;
3045         }
3046         
3047         cli_setatr(&cli1, fname, 0, 0);
3048         cli_unlink(&cli1, fname);
3049         
3050         cli_sockopt(&cli1, sockops);
3051         
3052         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3053         if (fnum1 == -1) {
3054                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3055                 return False;
3056         }
3057
3058         if (!cli_close(&cli1, fnum1)) {
3059                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3060                 return False;
3061         }
3062         
3063         if (!cli_setatr(&cli1, fname, aRONLY, 0)) {
3064                 printf("cli_setatr failed (%s)\n", cli_errstr(&cli1));
3065                 return False;
3066         }
3067         
3068         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
3069         if (fnum1 == -1) {
3070                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3071                 return False;
3072         }
3073         
3074         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3075         fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
3076         
3077         if (check_error(__LINE__, &cli1, ERRDOS, ERRnoaccess, 
3078                         NT_STATUS_ACCESS_DENIED)) {
3079                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3080         }
3081         
3082         printf("finished open test 1\n");
3083         
3084         cli_close(&cli1, fnum1);
3085         
3086         /* Now try not readonly and ensure ERRbadshare is returned. */
3087         
3088         cli_setatr(&cli1, fname, 0, 0);
3089         
3090         fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
3091         if (fnum1 == -1) {
3092                 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3093                 return False;
3094         }
3095         
3096         /* This will fail - but the error should be ERRshare. */
3097         fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
3098         
3099         if (check_error(__LINE__, &cli1, ERRDOS, ERRbadshare, 
3100                         NT_STATUS_SHARING_VIOLATION)) {
3101                 printf("correct error code ERRDOS/ERRbadshare returned\n");
3102         }
3103         
3104         if (!cli_close(&cli1, fnum1)) {
3105                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3106                 return False;
3107         }
3108         
3109         cli_unlink(&cli1, fname);
3110         
3111         printf("finished open test 2\n");
3112         
3113         /* Test truncate open disposition on file opened for read. */
3114         
3115         fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3116         if (fnum1 == -1) {
3117                 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(&cli1));
3118                 return False;
3119         }
3120         
3121         /* write 20 bytes. */
3122         
3123         memset(buf, '\0', 20);
3124
3125         if (cli_write(&cli1, fnum1, 0, buf, 0, 20) != 20) {
3126                 printf("write failed (%s)\n", cli_errstr(&cli1));
3127                 correct = False;
3128         }
3129
3130         if (!cli_close(&cli1, fnum1)) {
3131                 printf("(3) close1 failed (%s)\n", cli_errstr(&cli1));
3132                 return False;
3133         }
3134         
3135         /* Ensure size == 20. */
3136         if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
3137                 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
3138                 return False;
3139         }
3140         
3141         if (fsize != 20) {
3142                 printf("(3) file size != 20\n");
3143                 return False;
3144         }
3145
3146         /* Now test if we can truncate a file opened for readonly. */
3147         
3148         fnum1 = cli_open(&cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3149         if (fnum1 == -1) {
3150                 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(&cli1));
3151                 return False;
3152         }
3153         
3154         if (!cli_close(&cli1, fnum1)) {
3155                 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3156                 return False;
3157         }
3158
3159         /* Ensure size == 0. */
3160         if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
3161                 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
3162                 return False;
3163         }
3164
3165         if (fsize != 0) {
3166                 printf("(3) file size != 0\n");
3167                 return False;
3168         }
3169         printf("finished open test 3\n");
3170         
3171         cli_unlink(&cli1, fname);
3172
3173
3174         printf("testing ctemp\n");
3175         fnum1 = cli_ctemp(&cli1, "\\", &tmp_path);
3176         if (fnum1 == -1) {
3177                 printf("ctemp failed (%s)\n", cli_errstr(&cli1));
3178                 return False;
3179         }
3180         printf("ctemp gave path %s\n", tmp_path);
3181         if (!cli_close(&cli1, fnum1)) {
3182                 printf("close of temp failed (%s)\n", cli_errstr(&cli1));
3183         }
3184         if (!cli_unlink(&cli1, tmp_path)) {
3185                 printf("unlink of temp failed (%s)\n", cli_errstr(&cli1));
3186         }
3187         
3188         /* Test the non-io opens... */
3189
3190         if (!torture_open_connection(&cli2)) {
3191                 return False;
3192         }
3193         
3194         cli_setatr(&cli2, fname, 0, 0);
3195         cli_unlink(&cli2, fname);
3196         
3197         cli_sockopt(&cli2, sockops);
3198
3199         printf("TEST #1 testing 2 non-io opens (no delete)\n");
3200         
3201         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3202                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3203
3204         if (fnum1 == -1) {
3205                 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3206                 return False;
3207         }
3208
3209         fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3210                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3211
3212         if (fnum2 == -1) {
3213                 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3214                 return False;
3215         }
3216
3217         if (!cli_close(&cli1, fnum1)) {
3218                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3219                 return False;
3220         }
3221         if (!cli_close(&cli2, fnum2)) {
3222                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3223                 return False;
3224         }
3225
3226         printf("non-io open test #1 passed.\n");
3227
3228         cli_unlink(&cli1, fname);
3229
3230         printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3231         
3232         fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3233                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3234
3235         if (fnum1 == -1) {
3236                 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3237                 return False;
3238         }
3239
3240         fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3241                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3242
3243         if (fnum2 == -1) {
3244                 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3245                 return False;
3246         }
3247
3248         if (!cli_close(&cli1, fnum1)) {
3249                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3250                 return False;
3251         }
3252         if (!cli_close(&cli2, fnum2)) {
3253                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3254                 return False;
3255         }
3256
3257         printf("non-io open test #2 passed.\n");
3258
3259         cli_unlink(&cli1, fname);
3260
3261         printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3262         
3263         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3264                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3265
3266         if (fnum1 == -1) {
3267                 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3268                 return False;
3269         }
3270
3271         fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3272                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3273
3274         if (fnum2 == -1) {
3275                 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3276                 return False;
3277         }
3278
3279         if (!cli_close(&cli1, fnum1)) {
3280                 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3281                 return False;
3282         }
3283         if (!cli_close(&cli2, fnum2)) {
3284                 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3285                 return False;
3286         }
3287
3288         printf("non-io open test #3 passed.\n");
3289
3290         cli_unlink(&cli1, fname);
3291
3292         printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3293         
3294         fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3295                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3296
3297         if (fnum1 == -1) {
3298                 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3299                 return False;
3300         }
3301
3302         fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3303                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3304
3305         if (fnum2 != -1) {
3306                 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(&cli2));
3307                 return False;
3308         }
3309
3310         printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(&cli2), "sharing violation");
3311
3312         if (!cli_close(&cli1, fnum1)) {
3313                 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3314                 return False;
3315         }
3316
3317         printf("non-io open test #4 passed.\n");
3318
3319         cli_unlink(&cli1, fname);
3320
3321         printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3322         
3323         fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3324                                    FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
3325
3326         if (fnum1 == -1) {
3327                 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3328                 return False;
3329         }
3330
3331         fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3332                                    FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
3333
3334         if (fnum2 == -1) {
3335                 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3336                 return False;
3337         }
3338
3339         if (!cli_close(&cli1, fnum1)) {
3340                 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3341                 return False;
3342         }
3343
3344         if (!cli_close(&cli2, fnum2)) {
3345                 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3346                 return False;
3347         }
3348
3349         printf("non-io open test #5 passed.\n");
3350
3351         printf("TEST #6 testing 1 non-io open, one io open\n");
3352         
3353         cli_unlink(&cli1, fname);
3354
3355         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3356                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3357
3358         if (fnum1 == -1) {
3359                 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3360                 return False;
3361         }
3362
3363         fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3364                                    FILE_SHARE_READ, FILE_OPEN_IF, 0);
3365
3366         if (fnum2 == -1) {
3367                 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3368                 return False;
3369         }
3370
3371         if (!cli_close(&cli1, fnum1)) {
3372                 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3373                 return False;
3374         }
3375
3376         if (!cli_close(&cli2, fnum2)) {
3377                 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3378                 return False;
3379         }
3380
3381         printf("non-io open test #6 passed.\n");
3382
3383         printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3384
3385         cli_unlink(&cli1, fname);
3386
3387         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3388                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3389
3390         if (fnum1 == -1) {
3391                 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3392                 return False;
3393         }
3394
3395         fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3396                                    FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
3397
3398         if (fnum2 != -1) {
3399                 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(&cli2));
3400                 return False;
3401         }
3402
3403         printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(&cli2), "sharing violation");
3404
3405         if (!cli_close(&cli1, fnum1)) {
3406                 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3407                 return False;
3408         }
3409
3410         printf("non-io open test #7 passed.\n");
3411
3412         cli_unlink(&cli1, fname);
3413
3414         if (!torture_close_connection(&cli1)) {
3415                 correct = False;
3416         }
3417         if (!torture_close_connection(&cli2)) {
3418                 correct = False;
3419         }
3420         
3421         return correct;
3422 }
3423
3424 static uint32 open_attrs_table[] = {
3425                 FILE_ATTRIBUTE_NORMAL,
3426                 FILE_ATTRIBUTE_ARCHIVE,
3427                 FILE_ATTRIBUTE_READONLY,
3428                 FILE_ATTRIBUTE_HIDDEN,
3429                 FILE_ATTRIBUTE_SYSTEM,
3430
3431                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
3432                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
3433                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
3434                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3435                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3436                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3437
3438                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3439                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3440                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3441                 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
3442 };
3443
3444 struct trunc_open_results {
3445         int num;
3446         uint32 init_attr;
3447         uint32 trunc_attr;
3448         uint32 result_attr;
3449 };
3450
3451 static struct trunc_open_results attr_results[] = {
3452         { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3453         { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3454         { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3455         { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3456         { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3457         { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3458         { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3459         { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3460         { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3461         { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3462         { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3463         { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
3464         { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3465         { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3466         { 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 },
3467         { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3468         { 119,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3469         { 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 },
3470         { 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 },
3471         { 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 },
3472         { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3473         { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3474         { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3475         { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3476         { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3477         { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
3478 };
3479
3480 static BOOL run_openattrtest(int dummy)
3481 {
3482         static struct cli_state cli1;
3483         const char *fname = "\\openattr.file";
3484         int fnum1;
3485         BOOL correct = True;
3486         uint16 attr;
3487         int i, j, k, l;
3488
3489         printf("starting open attr test\n");
3490         
3491         if (!torture_open_connection(&cli1)) {
3492                 return False;
3493         }
3494         
3495         cli_sockopt(&cli1, sockops);
3496
3497         for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
3498                 cli_setatr(&cli1, fname, 0, 0);
3499                 cli_unlink(&cli1, fname);
3500                 fnum1 = cli_nt_create_full(&cli1, fname,FILE_WRITE_DATA, open_attrs_table[i],
3501                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3502
3503                 if (fnum1 == -1) {
3504                         printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(&cli1));
3505                         return False;
3506                 }
3507
3508                 if (!cli_close(&cli1, fnum1)) {
3509                         printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(&cli1));
3510                         return False;
3511                 }
3512
3513                 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
3514                         fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
3515                                            FILE_SHARE_NONE, FILE_OVERWRITE, 0);
3516
3517                         if (fnum1 == -1) {
3518                                 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
3519                                         if (attr_results[l].num == k) {
3520                                                 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
3521                                                                 k, open_attrs_table[i],
3522                                                                 open_attrs_table[j],
3523                                                                 fname, NT_STATUS_V(cli_nt_error(&cli1)), cli_errstr(&cli1));
3524                                                 correct = False;
3525                                         }
3526                                 }
3527                                 if (NT_STATUS_V(cli_nt_error(&cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
3528                                         printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
3529                                                         k, open_attrs_table[i], open_attrs_table[j],
3530                                                         cli_errstr(&cli1));
3531                                         correct = False;
3532                                 }
3533 #if 0
3534                                 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
3535 #endif
3536                                 k++;
3537                                 continue;
3538                         }
3539
3540                         if (!cli_close(&cli1, fnum1)) {
3541                                 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(&cli1));
3542                                 return False;
3543                         }
3544
3545                         if (!cli_getatr(&cli1, fname, &attr, NULL, NULL)) {
3546                                 printf("getatr(2) failed (%s)\n", cli_errstr(&cli1));
3547                                 return False;
3548                         }
3549
3550 #if 0
3551                         printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
3552                                         k,  open_attrs_table[i],  open_attrs_table[j], attr );
3553 #endif
3554
3555                         for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
3556                                 if (attr_results[l].num == k) {
3557                                         if (attr != attr_results[l].result_attr ||
3558                                                         open_attrs_table[i] != attr_results[l].init_attr ||
3559                                                         open_attrs_table[j] != attr_results[l].trunc_attr) {
3560                                                 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
3561                                                 open_attrs_table[i],
3562                                                 open_attrs_table[j],
3563                                                 (unsigned int)attr,
3564                                                 attr_results[l].result_attr);
3565                                                 correct = False;
3566                                         }
3567                                         break;
3568                                 }
3569                         }
3570                         k++;
3571                 }
3572         }
3573
3574         cli_setatr(&cli1, fname, 0, 0);
3575         cli_unlink(&cli1, fname);
3576
3577         printf("open attr test %s.\n", correct ? "passed" : "failed");
3578
3579         if (!torture_close_connection(&cli1)) {
3580                 correct = False;
3581         }
3582         return correct;
3583 }
3584
3585 static void list_fn(file_info *finfo, const char *name, void *state)
3586 {
3587         
3588 }
3589
3590 /*
3591   test directory listing speed
3592  */
3593 static BOOL run_dirtest(int dummy)
3594 {
3595         int i;
3596         static struct cli_state cli;
3597         int fnum;
3598         double t1;
3599         BOOL correct = True;
3600
3601         printf("starting directory test\n");
3602
3603         if (!torture_open_connection(&cli)) {
3604                 return False;
3605         }
3606
3607         cli_sockopt(&cli, sockops);
3608
3609         srandom(0);
3610         for (i=0;i<torture_numops;i++) {
3611                 fstring fname;
3612                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3613                 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
3614                 if (fnum == -1) {
3615                         fprintf(stderr,"Failed to open %s\n", fname);
3616                         return False;
3617                 }
3618                 cli_close(&cli, fnum);
3619         }
3620
3621         t1 = end_timer();
3622
3623         printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
3624         printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
3625         printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
3626
3627         printf("dirtest core %g seconds\n", end_timer() - t1);
3628
3629         srandom(0);
3630         for (i=0;i<torture_numops;i++) {
3631                 fstring fname;
3632                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3633                 cli_unlink(&cli, fname);
3634         }
3635
3636         if (!torture_close_connection(&cli)) {
3637                 correct = False;
3638         }
3639
3640         printf("finished dirtest\n");
3641
3642         return correct;
3643 }
3644
3645 static void del_fn(file_info *finfo, const char *mask, void *state)
3646 {
3647         struct cli_state *pcli = (struct cli_state *)state;
3648         fstring fname;
3649         slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
3650
3651         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
3652                 return;
3653
3654         if (finfo->mode & aDIR) {
3655                 if (!cli_rmdir(pcli, fname))
3656                         printf("del_fn: failed to rmdir %s\n,", fname );
3657         } else {
3658                 if (!cli_unlink(pcli, fname))
3659                         printf("del_fn: failed to unlink %s\n,", fname );
3660         }
3661 }
3662
3663 static BOOL run_dirtest1(int dummy)
3664 {
3665         int i;
3666         static struct cli_state cli;
3667         int fnum, num_seen;
3668         BOOL correct = True;
3669
3670         printf("starting directory test\n");
3671
3672         if (!torture_open_connection(&cli)) {
3673                 return False;
3674         }
3675
3676         cli_sockopt(&cli, sockops);
3677
3678         cli_list(&cli, "\\LISTDIR\\*", 0, del_fn, &cli);
3679         cli_list(&cli, "\\LISTDIR\\*", aDIR, del_fn, &cli);
3680         cli_rmdir(&cli, "\\LISTDIR");
3681         cli_mkdir(&cli, "\\LISTDIR");
3682
3683         /* Create 1000 files and 1000 directories. */
3684         for (i=0;i<1000;i++) {
3685                 fstring fname;
3686                 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
3687                 fnum = cli_nt_create_full(&cli, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3688                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
3689                 if (fnum == -1) {
3690                         fprintf(stderr,"Failed to open %s\n", fname);
3691                         return False;
3692                 }
3693                 cli_close(&cli, fnum);
3694         }
3695         for (i=0;i<1000;i++) {
3696                 fstring fname;
3697                 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
3698                 if (!cli_mkdir(&cli, fname)) {
3699                         fprintf(stderr,"Failed to open %s\n", fname);
3700                         return False;
3701                 }
3702         }
3703
3704         /* Now ensure that doing an old list sees both files and directories. */
3705         num_seen = cli_list_old(&cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
3706         printf("num_seen = %d\n", num_seen );
3707         /* We should see 100 files + 1000 directories + . and .. */
3708         if (num_seen != 2002)
3709                 correct = False;
3710
3711         /* Ensure if we have the "must have" bits we only see the
3712          * relevent entries.
3713          */
3714         num_seen = cli_list_old(&cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
3715         printf("num_seen = %d\n", num_seen );
3716         if (num_seen != 1002)
3717                 correct = False;
3718
3719         num_seen = cli_list_old(&cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
3720         printf("num_seen = %d\n", num_seen );
3721         if (num_seen != 1000)
3722                 correct = False;
3723
3724         /* Delete everything. */
3725         cli_list(&cli, "\\LISTDIR\\*", 0, del_fn, &cli);
3726         cli_list(&cli, "\\LISTDIR\\*", aDIR, del_fn, &cli);
3727         cli_rmdir(&cli, "\\LISTDIR");
3728
3729 #if 0
3730         printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
3731         printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
3732         printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
3733 #endif
3734
3735         if (!torture_close_connection(&cli)) {
3736                 correct = False;
3737         }
3738
3739         printf("finished dirtest1\n");
3740
3741         return correct;
3742 }
3743
3744 static BOOL run_error_map_extract(int dummy) {
3745         
3746         static struct cli_state c_dos;
3747         static struct cli_state c_nt;
3748
3749         uint32 error;
3750
3751         uint32 flgs2, errnum;
3752         uint8 errclass;
3753
3754         NTSTATUS nt_status;
3755
3756         fstring user;
3757
3758         /* NT-Error connection */
3759
3760         if (!open_nbt_connection(&c_nt)) {
3761                 return False;
3762         }
3763
3764         c_nt.use_spnego = False;
3765
3766         if (!cli_negprot(&c_nt)) {
3767                 printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(&c_nt));
3768                 cli_shutdown(&c_nt);
3769                 return False;
3770         }
3771
3772         if (!cli_session_setup(&c_nt, "", "", 0, "", 0,
3773                                workgroup)) {
3774                 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(&c_nt));
3775                 return False;
3776         }
3777
3778         /* DOS-Error connection */
3779
3780         if (!open_nbt_connection(&c_dos)) {
3781                 return False;
3782         }
3783
3784         c_dos.use_spnego = False;
3785         c_dos.force_dos_errors = True;
3786
3787         if (!cli_negprot(&c_dos)) {
3788                 printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(&c_dos));
3789                 cli_shutdown(&c_dos);
3790                 return False;
3791         }
3792
3793         if (!cli_session_setup(&c_dos, "", "", 0, "", 0,
3794                                workgroup)) {
3795                 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(&c_dos));
3796                 return False;
3797         }
3798
3799         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
3800                 snprintf(user, sizeof(user), "%X", error);
3801
3802                 if (cli_session_setup(&c_nt, user, 
3803                                        password, strlen(password),
3804                                        password, strlen(password),
3805                                       workgroup)) {
3806                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
3807                 }
3808                 
3809                 flgs2 = SVAL(c_nt.inbuf,smb_flg2);
3810                 
3811                 /* Case #1: 32-bit NT errors */
3812                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
3813                         nt_status = NT_STATUS(IVAL(c_nt.inbuf,smb_rcls));
3814                 } else {
3815                         printf("/** Dos error on NT connection! (%s) */\n", 
3816                                cli_errstr(&c_nt));
3817                         nt_status = NT_STATUS(0xc0000000);
3818                 }
3819
3820                 if (cli_session_setup(&c_dos, user, 
3821                                        password, strlen(password),
3822                                        password, strlen(password),
3823                                        workgroup)) {
3824                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
3825                 }
3826                 flgs2 = SVAL(c_dos.inbuf,smb_flg2), errnum;
3827                 
3828                 /* Case #1: 32-bit NT errors */
3829                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
3830                         printf("/** NT error on DOS connection! (%s) */\n", 
3831                                cli_errstr(&c_nt));
3832                         errnum = errclass = 0;
3833                 } else {
3834                         cli_dos_error(&c_dos, &errclass, &errnum);
3835                 }
3836
3837                 if (NT_STATUS_V(nt_status) != error) { 
3838                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
3839                                get_nt_error_c_code(NT_STATUS(error)), 
3840                                get_nt_error_c_code(nt_status));
3841                 }
3842                 
3843                 printf("\t{%s,\t%s,\t%s},\n", 
3844                        smb_dos_err_class(errclass), 
3845                        smb_dos_err_name(errclass, errnum), 
3846                        get_nt_error_c_code(NT_STATUS(error)));
3847         }
3848         return True;
3849 }
3850
3851 static double create_procs(BOOL (*fn)(int), BOOL *result)
3852 {
3853         int i, status;
3854         volatile pid_t *child_status;
3855         volatile BOOL *child_status_out;
3856         int synccount;
3857         int tries = 8;
3858
3859         synccount = 0;
3860
3861         child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
3862         if (!child_status) {
3863                 printf("Failed to setup shared memory\n");
3864                 return -1;
3865         }
3866
3867         child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
3868         if (!child_status_out) {
3869                 printf("Failed to setup result status shared memory\n");
3870                 return -1;
3871         }
3872
3873         for (i = 0; i < nprocs; i++) {
3874                 child_status[i] = 0;
3875                 child_status_out[i] = True;
3876         }
3877
3878         start_timer();
3879
3880         for (i=0;i<nprocs;i++) {
3881                 procnum = i;
3882                 if (fork() == 0) {
3883                         pid_t mypid = getpid();
3884                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
3885
3886                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
3887
3888                         while (1) {
3889                                 memset(&current_cli, 0, sizeof(current_cli));
3890                                 if (torture_open_connection(&current_cli)) break;
3891                                 if (tries-- == 0) {
3892                                         printf("pid %d failed to start\n", (int)getpid());
3893                                         _exit(1);
3894                                 }
3895                                 msleep(10);     
3896                         }
3897
3898                         child_status[i] = getpid();
3899
3900                         while (child_status[i] && end_timer() < 5) msleep(2);
3901
3902                         child_status_out[i] = fn(i);
3903                         _exit(0);
3904                 }
3905         }
3906
3907         do {
3908                 synccount = 0;
3909                 for (i=0;i<nprocs;i++) {
3910                         if (child_status[i]) synccount++;
3911                 }
3912                 if (synccount == nprocs) break;
3913                 msleep(10);
3914         } while (end_timer() < 30);
3915
3916         if (synccount != nprocs) {
3917                 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
3918                 *result = False;
3919                 return end_timer();
3920         }
3921
3922         /* start the client load */
3923         start_timer();
3924
3925         for (i=0;i<nprocs;i++) {
3926                 child_status[i] = 0;
3927         }
3928
3929         printf("%d clients started\n", nprocs);
3930
3931         for (i=0;i<nprocs;i++) {
3932                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
3933         }
3934
3935         printf("\n");
3936         
3937         for (i=0;i<nprocs;i++) {
3938                 if (!child_status_out[i]) {
3939                         *result = False;
3940                 }
3941         }
3942         return end_timer();
3943 }
3944
3945 #define FLAG_MULTIPROC 1
3946
3947 static struct {
3948         const char *name;
3949         BOOL (*fn)(int);
3950         unsigned flags;
3951 } torture_ops[] = {
3952         {"FDPASS", run_fdpasstest, 0},
3953         {"LOCK1",  run_locktest1,  0},
3954         {"LOCK2",  run_locktest2,  0},
3955         {"LOCK3",  run_locktest3,  0},
3956         {"LOCK4",  run_locktest4,  0},
3957         {"LOCK5",  run_locktest5,  0},
3958         {"LOCK6",  run_locktest6,  0},
3959         {"UNLINK", run_unlinktest, 0},
3960         {"BROWSE", run_browsetest, 0},
3961         {"ATTR",   run_attrtest,   0},
3962         {"TRANS2", run_trans2test, 0},
3963         {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
3964         {"TORTURE",run_torture,    FLAG_MULTIPROC},
3965         {"RANDOMIPC", run_randomipc, 0},
3966         {"NEGNOWAIT", run_negprot_nowait, 0},
3967         {"NBENCH",  run_nbench, 0},
3968         {"OPLOCK1",  run_oplock1, 0},
3969         {"OPLOCK2",  run_oplock2, 0},
3970         {"OPLOCK3",  run_oplock3, 0},
3971         {"DIR",  run_dirtest, 0},
3972         {"DIR1",  run_dirtest1, 0},
3973         {"DENY1",  torture_denytest1, 0},
3974         {"DENY2",  torture_denytest2, 0},
3975         {"TCON",  run_tcon_test, 0},
3976         {"RW1",  run_readwritetest, 0},
3977         {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
3978         {"RW3",  run_readwritelarge, 0},
3979         {"OPEN", run_opentest, 0},
3980 #if 1
3981         {"OPENATTR", run_openattrtest, 0},
3982 #endif
3983         {"XCOPY", run_xcopy, 0},
3984         {"RENAME", run_rename, 0},
3985         {"DELETE", run_deletetest, 0},
3986         {"PROPERTIES", run_properties, 0},
3987         {"MANGLE", torture_mangle, 0},
3988         {"W2K", run_w2ktest, 0},
3989         {"TRANS2SCAN", torture_trans2_scan, 0},
3990         {"NTTRANSSCAN", torture_nttrans_scan, 0},
3991         {"UTABLE", torture_utable, 0},
3992         {"CASETABLE", torture_casetable, 0},
3993         {"ERRMAPEXTRACT", run_error_map_extract, 0},
3994         {"PIPE_NUMBER", run_pipe_number, 0},
3995         {NULL, NULL, 0}};
3996
3997
3998
3999 /****************************************************************************
4000 run a specified test or "ALL"
4001 ****************************************************************************/
4002 static BOOL run_test(const char *name)
4003 {
4004         BOOL ret = True;
4005         BOOL result = True;
4006         int i;
4007         double t;
4008         if (strequal(name,"ALL")) {
4009                 for (i=0;torture_ops[i].name;i++) {
4010                         run_test(torture_ops[i].name);
4011                 }
4012         }
4013         
4014         for (i=0;torture_ops[i].name;i++) {
4015                 snprintf(randomfname, sizeof(randomfname), "\\XX%x", 
4016                          (unsigned)random());
4017
4018                 if (strequal(name, torture_ops[i].name)) {
4019                         printf("Running %s\n", name);
4020                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
4021                                 t = create_procs(torture_ops[i].fn, &result);
4022                                 if (!result) { 
4023                                         ret = False;
4024                                         printf("TEST %s FAILED!\n", name);
4025                                 }
4026                                          
4027                         } else {
4028                                 start_timer();
4029                                 if (!torture_ops[i].fn(0)) {
4030                                         ret = False;
4031                                         printf("TEST %s FAILED!\n", name);
4032                                 }
4033                                 t = end_timer();
4034                         }
4035                         printf("%s took %g secs\n\n", name, t);
4036                 }
4037         }
4038         return ret;
4039 }
4040
4041
4042 static void usage(void)
4043 {
4044         int i;
4045
4046         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
4047
4048         printf("\t-d debuglevel\n");
4049         printf("\t-U user%%pass\n");
4050         printf("\t-k               use kerberos\n");
4051         printf("\t-N numprocs\n");
4052         printf("\t-n my_netbios_name\n");
4053         printf("\t-W workgroup\n");
4054         printf("\t-o num_operations\n");
4055         printf("\t-O socket_options\n");
4056         printf("\t-m maximum protocol\n");
4057         printf("\t-L use oplocks\n");
4058         printf("\t-c CLIENT.TXT   specify client load file for NBENCH\n");
4059         printf("\t-A showall\n");
4060         printf("\t-s seed\n");
4061         printf("\n\n");
4062
4063         printf("tests are:");
4064         for (i=0;torture_ops[i].name;i++) {
4065                 printf(" %s", torture_ops[i].name);
4066         }
4067         printf("\n");
4068
4069         printf("default test is ALL\n");
4070         
4071         exit(1);
4072 }
4073
4074
4075
4076
4077
4078 /****************************************************************************
4079   main program
4080 ****************************************************************************/
4081  int main(int argc,char *argv[])
4082 {
4083         int opt, i;
4084         char *p;
4085         int gotuser = 0;
4086         int gotpass = 0;
4087         extern char *optarg;
4088         extern int optind;
4089         BOOL correct = True;
4090
4091         dbf = x_stdout;
4092
4093 #ifdef HAVE_SETBUFFER
4094         setbuffer(stdout, NULL, 0);
4095 #endif
4096
4097         lp_load(dyn_CONFIGFILE,True,False,False);
4098         load_interfaces();
4099
4100         if (argc < 2) {
4101                 usage();
4102         }
4103
4104         for(p = argv[1]; *p; p++)
4105           if(*p == '\\')
4106             *p = '/';
4107  
4108         if (strncmp(argv[1], "//", 2)) {
4109                 usage();
4110         }
4111
4112         fstrcpy(host, &argv[1][2]);
4113         p = strchr_m(&host[2],'/');
4114         if (!p) {
4115                 usage();
4116         }
4117         *p = 0;
4118         fstrcpy(share, p+1);
4119
4120         get_myname(myname);
4121
4122         if (*username == 0 && getenv("LOGNAME")) {
4123           fstrcpy(username,getenv("LOGNAME"));
4124         }
4125
4126         argc--;
4127         argv++;
4128
4129         srandom(time(NULL));
4130
4131         fstrcpy(workgroup, lp_workgroup());
4132
4133         while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:Ld:Ac:ks:")) != EOF) {
4134                 switch (opt) {
4135                 case 's':
4136                         srandom(atoi(optarg));
4137                         break;
4138                 case 'W':
4139                         fstrcpy(workgroup,optarg);
4140                         break;
4141                 case 'm':
4142                         max_protocol = interpret_protocol(optarg, max_protocol);
4143                         break;
4144                 case 'N':
4145                         nprocs = atoi(optarg);
4146                         break;
4147                 case 'o':
4148                         torture_numops = atoi(optarg);
4149                         break;
4150                 case 'd':
4151                         DEBUGLEVEL = atoi(optarg);
4152                         break;
4153                 case 'O':
4154                         sockops = optarg;
4155                         break;
4156                 case 'L':
4157                         use_oplocks = True;
4158                         break;
4159                 case 'A':
4160                         torture_showall = True;
4161                         break;
4162                 case 'n':
4163                         fstrcpy(myname, optarg);
4164                         break;
4165                 case 'c':
4166                         client_txt = optarg;
4167                         break;
4168                 case 'k':
4169 #ifdef HAVE_KRB5
4170                         use_kerberos = True;
4171 #else
4172                         d_printf("No kerberos support compiled in\n");
4173                         exit(1);
4174 #endif
4175                         break;
4176                 case 'U':
4177                         gotuser = 1;
4178                         fstrcpy(username,optarg);
4179                         p = strchr_m(username,'%');
4180                         if (p) {
4181                                 *p = 0;
4182                                 fstrcpy(password, p+1);
4183                                 gotpass = 1;
4184                         }
4185                         break;
4186                 default:
4187                         printf("Unknown option %c (%d)\n", (char)opt, opt);
4188                         usage();
4189                 }
4190         }
4191
4192         if(use_kerberos && !gotuser) gotpass = True;
4193
4194         while (!gotpass) {
4195                 p = getpass("Password:");
4196                 if (p) {
4197                         fstrcpy(password, p);
4198                         gotpass = 1;
4199                 }
4200         }
4201
4202         printf("host=%s share=%s user=%s myname=%s\n", 
4203                host, share, username, myname);
4204
4205         if (argc == 1) {
4206                 correct = run_test("ALL");
4207         } else {
4208                 for (i=1;i<argc;i++) {
4209                         if (!run_test(argv[i])) {
4210                                 correct = False;
4211                         }
4212                 }
4213         }
4214
4215         if (correct) {
4216                 return(0);
4217         } else {
4218                 return(1);
4219         }
4220 }