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