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