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