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