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