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