Add a in-memory cache
[nivanova/samba-autobuild/.git] / source3 / torture / torture.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB torture tester
4    Copyright (C) Andrew Tridgell 1997-1998
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21
22 extern char *optarg;
23 extern int optind;
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 static fstring multishare_conn_fname;
39 static bool use_multishare_conn = False;
40
41 bool torture_showall = False;
42
43 static double create_procs(bool (*fn)(int), bool *result);
44
45
46 static struct timeval tp1,tp2;
47
48
49 void start_timer(void)
50 {
51         GetTimeOfDay(&tp1);
52 }
53
54 double end_timer(void)
55 {
56         GetTimeOfDay(&tp2);
57         return((tp2.tv_sec - tp1.tv_sec) + 
58                (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
59 }
60
61
62 /* return a pointer to a anonymous shared memory segment of size "size"
63    which will persist across fork() but will disappear when all processes
64    exit 
65
66    The memory is not zeroed 
67
68    This function uses system5 shared memory. It takes advantage of a property
69    that the memory is not destroyed if it is attached when the id is removed
70    */
71 void *shm_setup(int size)
72 {
73         int shmid;
74         void *ret;
75
76         shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
77         if (shmid == -1) {
78                 printf("can't get shared memory\n");
79                 exit(1);
80         }
81         ret = (void *)shmat(shmid, 0, 0);
82         if (!ret || ret == (void *)-1) {
83                 printf("can't attach to shared memory\n");
84                 return NULL;
85         }
86         /* the following releases the ipc, but note that this process
87            and all its children will still have access to the memory, its
88            just that the shmid is no longer valid for other shm calls. This
89            means we don't leave behind lots of shm segments after we exit 
90
91            See Stevens "advanced programming in unix env" for details
92            */
93         shmctl(shmid, IPC_RMID, 0);
94         
95         return ret;
96 }
97
98
99 static struct cli_state *open_nbt_connection(void)
100 {
101         struct nmb_name called, calling;
102         struct sockaddr_storage ss;
103         struct cli_state *c;
104         NTSTATUS status;
105
106         make_nmb_name(&calling, myname, 0x0);
107         make_nmb_name(&called , host, 0x20);
108
109         zero_addr(&ss);
110
111         if (!(c = cli_initialise())) {
112                 printf("Failed initialize cli_struct to connect with %s\n", host);
113                 return NULL;
114         }
115
116         c->port = port_to_use;
117
118         status = cli_connect(c, host, &ss);
119         if (!NT_STATUS_IS_OK(status)) {
120                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
121                 return NULL;
122         }
123
124         c->use_kerberos = use_kerberos;
125
126         c->timeout = 120000; /* set a really long timeout (2 minutes) */
127         if (use_oplocks) c->use_oplocks = True;
128         if (use_level_II_oplocks) c->use_level_II_oplocks = True;
129
130         if (!cli_session_request(c, &calling, &called)) {
131                 /*
132                  * Well, that failed, try *SMBSERVER ...
133                  * However, we must reconnect as well ...
134                  */
135                 status = cli_connect(c, host, &ss);
136                 if (!NT_STATUS_IS_OK(status)) {
137                         printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
138                         return NULL;
139                 }
140
141                 make_nmb_name(&called, "*SMBSERVER", 0x20);
142                 if (!cli_session_request(c, &calling, &called)) {
143                         printf("%s rejected the session\n",host);
144                         printf("We tried with a called name of %s & %s\n",
145                                 host, "*SMBSERVER");
146                         cli_shutdown(c);
147                         return NULL;
148                 }
149         }
150
151         return c;
152 }
153
154 /* Insert a NULL at the first separator of the given path and return a pointer
155  * to the remainder of the string.
156  */
157 static char *
158 terminate_path_at_separator(char * path)
159 {
160         char * p;
161
162         if (!path) {
163                 return NULL;
164         }
165
166         if ((p = strchr_m(path, '/'))) {
167                 *p = '\0';
168                 return p + 1;
169         }
170
171         if ((p = strchr_m(path, '\\'))) {
172                 *p = '\0';
173                 return p + 1;
174         }
175         
176         /* No separator. */
177         return NULL;
178 }
179
180 /*
181   parse a //server/share type UNC name
182 */
183 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
184                       char **hostname, char **sharename)
185 {
186         char *p;
187
188         *hostname = *sharename = NULL;
189
190         if (strncmp(unc_name, "\\\\", 2) &&
191             strncmp(unc_name, "//", 2)) {
192                 return False;
193         }
194
195         *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
196         p = terminate_path_at_separator(*hostname);
197
198         if (p && *p) {
199                 *sharename = talloc_strdup(mem_ctx, p);
200                 terminate_path_at_separator(*sharename);
201         }
202
203         if (*hostname && *sharename) {
204                 return True;
205         }
206
207         TALLOC_FREE(*hostname);
208         TALLOC_FREE(*sharename);
209         return False;
210 }
211
212 static bool torture_open_connection_share(struct cli_state **c,
213                                    const char *hostname, 
214                                    const char *sharename)
215 {
216         bool retry;
217         int flags = 0;
218         NTSTATUS status;
219
220         if (use_kerberos)
221                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
222
223         status = cli_full_connection(c, myname,
224                                      hostname, NULL, port_to_use, 
225                                      sharename, "?????", 
226                                      username, workgroup, 
227                                      password, flags, Undefined, &retry);
228         if (!NT_STATUS_IS_OK(status)) {
229                 printf("failed to open share connection: //%s/%s port:%d - %s\n",
230                         hostname, sharename, port_to_use, nt_errstr(status));
231                 return False;
232         }
233
234         if (use_oplocks) (*c)->use_oplocks = True;
235         if (use_level_II_oplocks) (*c)->use_level_II_oplocks = True;
236         (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
237
238         return True;
239 }
240
241 void torture_open_connection_free_unclist(char **unc_list)
242 {
243         if (unc_list!=NULL)
244         {
245                 SAFE_FREE(unc_list[0]);
246                 SAFE_FREE(unc_list);
247         }
248 }
249
250 bool torture_open_connection(struct cli_state **c, int conn_index)
251 {
252         char **unc_list = NULL;
253         int num_unc_names = 0;
254         bool result;
255
256         if (use_multishare_conn==True) {
257                 char *h, *s;
258                 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0);
259                 if (!unc_list || num_unc_names <= 0) {
260                         printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
261                         exit(1);
262                 }
263
264                 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
265                                       NULL, &h, &s)) {
266                         printf("Failed to parse UNC name %s\n",
267                                unc_list[conn_index % num_unc_names]);
268                         torture_open_connection_free_unclist(unc_list);
269                         exit(1);
270                 }
271
272                 result = torture_open_connection_share(c, h, s);
273
274                 /* h, s were copied earlier */
275                 torture_open_connection_free_unclist(unc_list);
276                 return result;
277         }
278
279         return torture_open_connection_share(c, host, share);
280 }
281
282 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
283 {
284         uint16 old_vuid = cli->vuid;
285         fstring old_user_name;
286         size_t passlen = strlen(password);
287         bool ret;
288
289         fstrcpy(old_user_name, cli->user_name);
290         cli->vuid = 0;
291         ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
292                                                 password, passlen,
293                                                 password, passlen,
294                                                 workgroup));
295         *new_vuid = cli->vuid;
296         cli->vuid = old_vuid;
297         fstrcpy(cli->user_name, old_user_name);
298         return ret;
299 }
300
301
302 bool torture_close_connection(struct cli_state *c)
303 {
304         bool ret = True;
305         if (!cli_tdis(c)) {
306                 printf("tdis failed (%s)\n", cli_errstr(c));
307                 ret = False;
308         }
309
310         cli_shutdown(c);
311
312         return ret;
313 }
314
315
316 /* check if the server produced the expected error code */
317 static bool check_error(int line, struct cli_state *c, 
318                         uint8 eclass, uint32 ecode, NTSTATUS nterr)
319 {
320         if (cli_is_dos_error(c)) {
321                 uint8 cclass;
322                 uint32 num;
323
324                 /* Check DOS error */
325
326                 cli_dos_error(c, &cclass, &num);
327
328                 if (eclass != cclass || ecode != num) {
329                         printf("unexpected error code class=%d code=%d\n", 
330                                (int)cclass, (int)num);
331                         printf(" expected %d/%d %s (line=%d)\n", 
332                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
333                         return False;
334                 }
335
336         } else {
337                 NTSTATUS status;
338
339                 /* Check NT error */
340
341                 status = cli_nt_error(c);
342
343                 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
344                         printf("unexpected error code %s\n", nt_errstr(status));
345                         printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
346                         return False;
347                 }
348         }
349
350         return True;
351 }
352
353
354 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
355 {
356         while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
357                 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
358         }
359         return True;
360 }
361
362
363 static bool rw_torture(struct cli_state *c)
364 {
365         const char *lockfname = "\\torture.lck";
366         fstring fname;
367         int fnum;
368         int fnum2;
369         pid_t pid2, pid = getpid();
370         int i, j;
371         char buf[1024];
372         bool correct = True;
373
374         memset(buf, '\0', sizeof(buf));
375
376         fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
377                          DENY_NONE);
378         if (fnum2 == -1)
379                 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
380         if (fnum2 == -1) {
381                 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
382                 return False;
383         }
384
385
386         for (i=0;i<torture_numops;i++) {
387                 unsigned n = (unsigned)sys_random()%10;
388                 if (i % 10 == 0) {
389                         printf("%d\r", i); fflush(stdout);
390                 }
391                 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
392
393                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
394                         return False;
395                 }
396
397                 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
398                 if (fnum == -1) {
399                         printf("open failed (%s)\n", cli_errstr(c));
400                         correct = False;
401                         break;
402                 }
403
404                 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
405                         printf("write failed (%s)\n", cli_errstr(c));
406                         correct = False;
407                 }
408
409                 for (j=0;j<50;j++) {
410                         if (cli_write(c, fnum, 0, (char *)buf, 
411                                       sizeof(pid)+(j*sizeof(buf)), 
412                                       sizeof(buf)) != sizeof(buf)) {
413                                 printf("write failed (%s)\n", cli_errstr(c));
414                                 correct = False;
415                         }
416                 }
417
418                 pid2 = 0;
419
420                 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
421                         printf("read failed (%s)\n", cli_errstr(c));
422                         correct = False;
423                 }
424
425                 if (pid2 != pid) {
426                         printf("data corruption!\n");
427                         correct = False;
428                 }
429
430                 if (!cli_close(c, fnum)) {
431                         printf("close failed (%s)\n", cli_errstr(c));
432                         correct = False;
433                 }
434
435                 if (!cli_unlink(c, fname)) {
436                         printf("unlink failed (%s)\n", cli_errstr(c));
437                         correct = False;
438                 }
439
440                 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
441                         printf("unlock failed (%s)\n", cli_errstr(c));
442                         correct = False;
443                 }
444         }
445
446         cli_close(c, fnum2);
447         cli_unlink(c, lockfname);
448
449         printf("%d\n", i);
450
451         return correct;
452 }
453
454 static bool run_torture(int dummy)
455 {
456         struct cli_state *cli;
457         bool ret;
458
459         cli = current_cli;
460
461         cli_sockopt(cli, sockops);
462
463         ret = rw_torture(cli);
464         
465         if (!torture_close_connection(cli)) {
466                 ret = False;
467         }
468
469         return ret;
470 }
471
472 static bool rw_torture3(struct cli_state *c, char *lockfname)
473 {
474         int fnum = -1;
475         unsigned int i = 0;
476         char buf[131072];
477         char buf_rd[131072];
478         unsigned count;
479         unsigned countprev = 0;
480         ssize_t sent = 0;
481         bool correct = True;
482
483         srandom(1);
484         for (i = 0; i < sizeof(buf); i += sizeof(uint32))
485         {
486                 SIVAL(buf, i, sys_random());
487         }
488
489         if (procnum == 0)
490         {
491                 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
492                                  DENY_NONE);
493                 if (fnum == -1) {
494                         printf("first open read/write of %s failed (%s)\n",
495                                         lockfname, cli_errstr(c));
496                         return False;
497                 }
498         }
499         else
500         {
501                 for (i = 0; i < 500 && fnum == -1; i++)
502                 {
503                         fnum = cli_open(c, lockfname, O_RDONLY, 
504                                          DENY_NONE);
505                         smb_msleep(10);
506                 }
507                 if (fnum == -1) {
508                         printf("second open read-only of %s failed (%s)\n",
509                                         lockfname, cli_errstr(c));
510                         return False;
511                 }
512         }
513
514         i = 0;
515         for (count = 0; count < sizeof(buf); count += sent)
516         {
517                 if (count >= countprev) {
518                         printf("%d %8d\r", i, count);
519                         fflush(stdout);
520                         i++;
521                         countprev += (sizeof(buf) / 20);
522                 }
523
524                 if (procnum == 0)
525                 {
526                         sent = ((unsigned)sys_random()%(20))+ 1;
527                         if (sent > sizeof(buf) - count)
528                         {
529                                 sent = sizeof(buf) - count;
530                         }
531
532                         if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
533                                 printf("write failed (%s)\n", cli_errstr(c));
534                                 correct = False;
535                         }
536                 }
537                 else
538                 {
539                         sent = cli_read(c, fnum, buf_rd+count, count,
540                                                   sizeof(buf)-count);
541                         if (sent < 0)
542                         {
543                                 printf("read failed offset:%d size:%ld (%s)\n",
544                                        count, (unsigned long)sizeof(buf)-count,
545                                        cli_errstr(c));
546                                 correct = False;
547                                 sent = 0;
548                         }
549                         if (sent > 0)
550                         {
551                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
552                                 {
553                                         printf("read/write compare failed\n");
554                                         printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
555                                         correct = False;
556                                         break;
557                                 }
558                         }
559                 }
560
561         }
562
563         if (!cli_close(c, fnum)) {
564                 printf("close failed (%s)\n", cli_errstr(c));
565                 correct = False;
566         }
567
568         return correct;
569 }
570
571 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
572 {
573         const char *lockfname = "\\torture2.lck";
574         int fnum1;
575         int fnum2;
576         int i;
577         char buf[131072];
578         char buf_rd[131072];
579         bool correct = True;
580         ssize_t bytes_read;
581
582         if (!cli_unlink(c1, lockfname)) {
583                 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
584         }
585
586         fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL, 
587                          DENY_NONE);
588         if (fnum1 == -1) {
589                 printf("first open read/write of %s failed (%s)\n",
590                                 lockfname, cli_errstr(c1));
591                 return False;
592         }
593         fnum2 = cli_open(c2, lockfname, O_RDONLY, 
594                          DENY_NONE);
595         if (fnum2 == -1) {
596                 printf("second open read-only of %s failed (%s)\n",
597                                 lockfname, cli_errstr(c2));
598                 cli_close(c1, fnum1);
599                 return False;
600         }
601
602         for (i=0;i<torture_numops;i++)
603         {
604                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
605                 if (i % 10 == 0) {
606                         printf("%d\r", i); fflush(stdout);
607                 }
608
609                 generate_random_buffer((unsigned char *)buf, buf_size);
610
611                 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
612                         printf("write failed (%s)\n", cli_errstr(c1));
613                         correct = False;
614                         break;
615                 }
616
617                 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
618                         printf("read failed (%s)\n", cli_errstr(c2));
619                         printf("read %d, expected %ld\n", (int)bytes_read, 
620                                (unsigned long)buf_size); 
621                         correct = False;
622                         break;
623                 }
624
625                 if (memcmp(buf_rd, buf, buf_size) != 0)
626                 {
627                         printf("read/write compare failed\n");
628                         correct = False;
629                         break;
630                 }
631         }
632
633         if (!cli_close(c2, fnum2)) {
634                 printf("close failed (%s)\n", cli_errstr(c2));
635                 correct = False;
636         }
637         if (!cli_close(c1, fnum1)) {
638                 printf("close failed (%s)\n", cli_errstr(c1));
639                 correct = False;
640         }
641
642         if (!cli_unlink(c1, lockfname)) {
643                 printf("unlink failed (%s)\n", cli_errstr(c1));
644                 correct = False;
645         }
646
647         return correct;
648 }
649
650 static bool run_readwritetest(int dummy)
651 {
652         static struct cli_state *cli1, *cli2;
653         bool test1, test2 = False;
654
655         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
656                 return False;
657         }
658         cli_sockopt(cli1, sockops);
659         cli_sockopt(cli2, sockops);
660
661         printf("starting readwritetest\n");
662
663         test1 = rw_torture2(cli1, cli2);
664         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
665
666         if (test1) {
667                 test2 = rw_torture2(cli1, cli1);
668                 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
669         }
670
671         if (!torture_close_connection(cli1)) {
672                 test1 = False;
673         }
674
675         if (!torture_close_connection(cli2)) {
676                 test2 = False;
677         }
678
679         return (test1 && test2);
680 }
681
682 static bool run_readwritemulti(int dummy)
683 {
684         struct cli_state *cli;
685         bool test;
686
687         cli = current_cli;
688
689         cli_sockopt(cli, sockops);
690
691         printf("run_readwritemulti: fname %s\n", randomfname);
692         test = rw_torture3(cli, randomfname);
693
694         if (!torture_close_connection(cli)) {
695                 test = False;
696         }
697         
698         return test;
699 }
700
701 static bool run_readwritelarge(int dummy)
702 {
703         static struct cli_state *cli1;
704         int fnum1;
705         const char *lockfname = "\\large.dat";
706         SMB_OFF_T fsize;
707         char buf[126*1024];
708         bool correct = True;
709  
710         if (!torture_open_connection(&cli1, 0)) {
711                 return False;
712         }
713         cli_sockopt(cli1, sockops);
714         memset(buf,'\0',sizeof(buf));
715         
716         cli1->max_xmit = 128*1024;
717         
718         printf("starting readwritelarge\n");
719  
720         cli_unlink(cli1, lockfname);
721
722         fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
723         if (fnum1 == -1) {
724                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
725                 return False;
726         }
727    
728         cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
729
730         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
731                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
732                 correct = False;
733         }
734
735         if (fsize == sizeof(buf))
736                 printf("readwritelarge test 1 succeeded (size = %lx)\n", 
737                        (unsigned long)fsize);
738         else {
739                 printf("readwritelarge test 1 failed (size = %lx)\n", 
740                        (unsigned long)fsize);
741                 correct = False;
742         }
743
744         if (!cli_close(cli1, fnum1)) {
745                 printf("close failed (%s)\n", cli_errstr(cli1));
746                 correct = False;
747         }
748
749         if (!cli_unlink(cli1, lockfname)) {
750                 printf("unlink failed (%s)\n", cli_errstr(cli1));
751                 correct = False;
752         }
753
754         fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
755         if (fnum1 == -1) {
756                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
757                 return False;
758         }
759         
760         cli1->max_xmit = 4*1024;
761         
762         cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
763         
764         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
765                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
766                 correct = False;
767         }
768
769         if (fsize == sizeof(buf))
770                 printf("readwritelarge test 2 succeeded (size = %lx)\n", 
771                        (unsigned long)fsize);
772         else {
773                 printf("readwritelarge test 2 failed (size = %lx)\n", 
774                        (unsigned long)fsize);
775                 correct = False;
776         }
777
778 #if 0
779         /* ToDo - set allocation. JRA */
780         if(!cli_set_allocation_size(cli1, fnum1, 0)) {
781                 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
782                 return False;
783         }
784         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
785                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
786                 correct = False;
787         }
788         if (fsize != 0)
789                 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
790 #endif
791
792         if (!cli_close(cli1, fnum1)) {
793                 printf("close failed (%s)\n", cli_errstr(cli1));
794                 correct = False;
795         }
796         
797         if (!torture_close_connection(cli1)) {
798                 correct = False;
799         }
800         return correct;
801 }
802
803 int line_count = 0;
804 int nbio_id;
805
806 #define ival(s) strtol(s, NULL, 0)
807
808 /* run a test that simulates an approximate netbench client load */
809 static bool run_netbench(int client)
810 {
811         struct cli_state *cli;
812         int i;
813         char line[1024];
814         char cname[20];
815         FILE *f;
816         const char *params[20];
817         bool correct = True;
818
819         cli = current_cli;
820
821         nbio_id = client;
822
823         cli_sockopt(cli, sockops);
824
825         nb_setup(cli);
826
827         slprintf(cname,sizeof(cname)-1, "client%d", client);
828
829         f = fopen(client_txt, "r");
830
831         if (!f) {
832                 perror(client_txt);
833                 return False;
834         }
835
836         while (fgets(line, sizeof(line)-1, f)) {
837                 line_count++;
838
839                 line[strlen(line)-1] = 0;
840
841                 /* printf("[%d] %s\n", line_count, line); */
842
843                 all_string_sub(line,"client1", cname, sizeof(line));
844
845                 /* parse the command parameters */
846                 params[0] = strtok(line," ");
847                 i = 0;
848                 while (params[i]) params[++i] = strtok(NULL," ");
849
850                 params[i] = "";
851
852                 if (i < 2) continue;
853
854                 if (!strncmp(params[0],"SMB", 3)) {
855                         printf("ERROR: You are using a dbench 1 load file\n");
856                         exit(1);
857                 }
858
859                 if (!strcmp(params[0],"NTCreateX")) {
860                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
861                                    ival(params[4]));
862                 } else if (!strcmp(params[0],"Close")) {
863                         nb_close(ival(params[1]));
864                 } else if (!strcmp(params[0],"Rename")) {
865                         nb_rename(params[1], params[2]);
866                 } else if (!strcmp(params[0],"Unlink")) {
867                         nb_unlink(params[1]);
868                 } else if (!strcmp(params[0],"Deltree")) {
869                         nb_deltree(params[1]);
870                 } else if (!strcmp(params[0],"Rmdir")) {
871                         nb_rmdir(params[1]);
872                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
873                         nb_qpathinfo(params[1]);
874                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
875                         nb_qfileinfo(ival(params[1]));
876                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
877                         nb_qfsinfo(ival(params[1]));
878                 } else if (!strcmp(params[0],"FIND_FIRST")) {
879                         nb_findfirst(params[1]);
880                 } else if (!strcmp(params[0],"WriteX")) {
881                         nb_writex(ival(params[1]), 
882                                   ival(params[2]), ival(params[3]), ival(params[4]));
883                 } else if (!strcmp(params[0],"ReadX")) {
884                         nb_readx(ival(params[1]), 
885                                   ival(params[2]), ival(params[3]), ival(params[4]));
886                 } else if (!strcmp(params[0],"Flush")) {
887                         nb_flush(ival(params[1]));
888                 } else {
889                         printf("Unknown operation %s\n", params[0]);
890                         exit(1);
891                 }
892         }
893         fclose(f);
894
895         nb_cleanup();
896
897         if (!torture_close_connection(cli)) {
898                 correct = False;
899         }
900         
901         return correct;
902 }
903
904
905 /* run a test that simulates an approximate netbench client load */
906 static bool run_nbench(int dummy)
907 {
908         double t;
909         bool correct = True;
910
911         nbio_shmem(nprocs);
912
913         nbio_id = -1;
914
915         signal(SIGALRM, nb_alarm);
916         alarm(1);
917         t = create_procs(run_netbench, &correct);
918         alarm(0);
919
920         printf("\nThroughput %g MB/sec\n", 
921                1.0e-6 * nbio_total() / t);
922         return correct;
923 }
924
925
926 /*
927   This test checks for two things:
928
929   1) correct support for retaining locks over a close (ie. the server
930      must not use posix semantics)
931   2) support for lock timeouts
932  */
933 static bool run_locktest1(int dummy)
934 {
935         struct cli_state *cli1, *cli2;
936         const char *fname = "\\lockt1.lck";
937         int fnum1, fnum2, fnum3;
938         time_t t1, t2;
939         unsigned lock_timeout;
940
941         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
942                 return False;
943         }
944         cli_sockopt(cli1, sockops);
945         cli_sockopt(cli2, sockops);
946
947         printf("starting locktest1\n");
948
949         cli_unlink(cli1, fname);
950
951         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
952         if (fnum1 == -1) {
953                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
954                 return False;
955         }
956         fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
957         if (fnum2 == -1) {
958                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
959                 return False;
960         }
961         fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
962         if (fnum3 == -1) {
963                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
964                 return False;
965         }
966
967         if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
968                 printf("lock1 failed (%s)\n", cli_errstr(cli1));
969                 return False;
970         }
971
972
973         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
974                 printf("lock2 succeeded! This is a locking bug\n");
975                 return False;
976         } else {
977                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
978                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
979         }
980
981
982         lock_timeout = (1 + (random() % 20));
983         printf("Testing lock timeout with timeout=%u\n", lock_timeout);
984         t1 = time(NULL);
985         if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
986                 printf("lock3 succeeded! This is a locking bug\n");
987                 return False;
988         } else {
989                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
990                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
991         }
992         t2 = time(NULL);
993
994         if (ABS(t2 - t1) < lock_timeout-1) {
995                 printf("error: This server appears not to support timed lock requests\n");
996         }
997
998         printf("server slept for %u seconds for a %u second timeout\n",
999                (unsigned int)(t2-t1), lock_timeout);
1000
1001         if (!cli_close(cli1, fnum2)) {
1002                 printf("close1 failed (%s)\n", cli_errstr(cli1));
1003                 return False;
1004         }
1005
1006         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1007                 printf("lock4 succeeded! This is a locking bug\n");
1008                 return False;
1009         } else {
1010                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1011                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1012         }
1013
1014         if (!cli_close(cli1, fnum1)) {
1015                 printf("close2 failed (%s)\n", cli_errstr(cli1));
1016                 return False;
1017         }
1018
1019         if (!cli_close(cli2, fnum3)) {
1020                 printf("close3 failed (%s)\n", cli_errstr(cli2));
1021                 return False;
1022         }
1023
1024         if (!cli_unlink(cli1, fname)) {
1025                 printf("unlink failed (%s)\n", cli_errstr(cli1));
1026                 return False;
1027         }
1028
1029
1030         if (!torture_close_connection(cli1)) {
1031                 return False;
1032         }
1033
1034         if (!torture_close_connection(cli2)) {
1035                 return False;
1036         }
1037
1038         printf("Passed locktest1\n");
1039         return True;
1040 }
1041
1042 /*
1043   this checks to see if a secondary tconx can use open files from an
1044   earlier tconx
1045  */
1046 static bool run_tcon_test(int dummy)
1047 {
1048         static struct cli_state *cli;
1049         const char *fname = "\\tcontest.tmp";
1050         int fnum1;
1051         uint16 cnum1, cnum2, cnum3;
1052         uint16 vuid1, vuid2;
1053         char buf[4];
1054         bool ret = True;
1055
1056         memset(buf, '\0', sizeof(buf));
1057
1058         if (!torture_open_connection(&cli, 0)) {
1059                 return False;
1060         }
1061         cli_sockopt(cli, sockops);
1062
1063         printf("starting tcontest\n");
1064
1065         cli_unlink(cli, fname);
1066
1067         fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1068         if (fnum1 == -1) {
1069                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1070                 return False;
1071         }
1072
1073         cnum1 = cli->cnum;
1074         vuid1 = cli->vuid;
1075
1076         if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1077                 printf("initial write failed (%s)", cli_errstr(cli));
1078                 return False;
1079         }
1080
1081         if (!cli_send_tconX(cli, share, "?????",
1082                             password, strlen(password)+1)) {
1083                 printf("%s refused 2nd tree connect (%s)\n", host,
1084                            cli_errstr(cli));
1085                 cli_shutdown(cli);
1086                 return False;
1087         }
1088
1089         cnum2 = cli->cnum;
1090         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1091         vuid2 = cli->vuid + 1;
1092
1093         /* try a write with the wrong tid */
1094         cli->cnum = cnum2;
1095
1096         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1097                 printf("* server allows write with wrong TID\n");
1098                 ret = False;
1099         } else {
1100                 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1101         }
1102
1103
1104         /* try a write with an invalid tid */
1105         cli->cnum = cnum3;
1106
1107         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1108                 printf("* server allows write with invalid TID\n");
1109                 ret = False;
1110         } else {
1111                 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1112         }
1113
1114         /* try a write with an invalid vuid */
1115         cli->vuid = vuid2;
1116         cli->cnum = cnum1;
1117
1118         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1119                 printf("* server allows write with invalid VUID\n");
1120                 ret = False;
1121         } else {
1122                 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1123         }
1124
1125         cli->cnum = cnum1;
1126         cli->vuid = vuid1;
1127
1128         if (!cli_close(cli, fnum1)) {
1129                 printf("close failed (%s)\n", cli_errstr(cli));
1130                 return False;
1131         }
1132
1133         cli->cnum = cnum2;
1134
1135         if (!cli_tdis(cli)) {
1136                 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
1137                 return False;
1138         }
1139
1140         cli->cnum = cnum1;
1141
1142         if (!torture_close_connection(cli)) {
1143                 return False;
1144         }
1145
1146         return ret;
1147 }
1148
1149
1150 /*
1151  checks for old style tcon support
1152  */
1153 static bool run_tcon2_test(int dummy)
1154 {
1155         static struct cli_state *cli;
1156         uint16 cnum, max_xmit;
1157         char *service;
1158         NTSTATUS status;
1159
1160         if (!torture_open_connection(&cli, 0)) {
1161                 return False;
1162         }
1163         cli_sockopt(cli, sockops);
1164
1165         printf("starting tcon2 test\n");
1166
1167         asprintf(&service, "\\\\%s\\%s", host, share);
1168
1169         status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1170
1171         if (!NT_STATUS_IS_OK(status)) {
1172                 printf("tcon2 failed : %s\n", cli_errstr(cli));
1173         } else {
1174                 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n", 
1175                        (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1176         }
1177
1178         if (!torture_close_connection(cli)) {
1179                 return False;
1180         }
1181
1182         printf("Passed tcon2 test\n");
1183         return True;
1184 }
1185
1186 static bool tcon_devtest(struct cli_state *cli,
1187                          const char *myshare, const char *devtype,
1188                          const char *return_devtype,
1189                          NTSTATUS expected_error)
1190 {
1191         bool status;
1192         bool ret;
1193
1194         status = cli_send_tconX(cli, myshare, devtype,
1195                                 password, strlen(password)+1);
1196
1197         if (NT_STATUS_IS_OK(expected_error)) {
1198                 if (status) {
1199                         if (strcmp(cli->dev, return_devtype) == 0) {
1200                                 ret = True;
1201                         } else { 
1202                                 printf("tconX to share %s with type %s "
1203                                        "succeeded but returned the wrong "
1204                                        "device type (got [%s] but should have got [%s])\n",
1205                                        myshare, devtype, cli->dev, return_devtype);
1206                                 ret = False;
1207                         }
1208                 } else {
1209                         printf("tconX to share %s with type %s "
1210                                "should have succeeded but failed\n",
1211                                myshare, devtype);
1212                         ret = False;
1213                 }
1214                 cli_tdis(cli);
1215         } else {
1216                 if (status) {
1217                         printf("tconx to share %s with type %s "
1218                                "should have failed but succeeded\n",
1219                                myshare, devtype);
1220                         ret = False;
1221                 } else {
1222                         if (NT_STATUS_EQUAL(cli_nt_error(cli),
1223                                             expected_error)) {
1224                                 ret = True;
1225                         } else {
1226                                 printf("Returned unexpected error\n");
1227                                 ret = False;
1228                         }
1229                 }
1230         }
1231         return ret;
1232 }
1233
1234 /*
1235  checks for correct tconX support
1236  */
1237 static bool run_tcon_devtype_test(int dummy)
1238 {
1239         static struct cli_state *cli1 = NULL;
1240         bool retry;
1241         int flags = 0;
1242         NTSTATUS status;
1243         bool ret = True;
1244
1245         status = cli_full_connection(&cli1, myname,
1246                                      host, NULL, port_to_use,
1247                                      NULL, NULL,
1248                                      username, workgroup,
1249                                      password, flags, Undefined, &retry);
1250
1251         if (!NT_STATUS_IS_OK(status)) {
1252                 printf("could not open connection\n");
1253                 return False;
1254         }
1255
1256         if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1257                 ret = False;
1258
1259         if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1260                 ret = False;
1261
1262         if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1263                 ret = False;
1264
1265         if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1266                 ret = False;
1267                         
1268         if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1269                 ret = False;
1270
1271         if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1272                 ret = False;
1273
1274         if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1275                 ret = False;
1276
1277         if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1278                 ret = False;
1279
1280         if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1281                 ret = False;
1282                         
1283         if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1284                 ret = False;
1285
1286         cli_shutdown(cli1);
1287
1288         if (ret)
1289                 printf("Passed tcondevtest\n");
1290
1291         return ret;
1292 }
1293
1294
1295 /*
1296   This test checks that 
1297
1298   1) the server supports multiple locking contexts on the one SMB
1299   connection, distinguished by PID.  
1300
1301   2) the server correctly fails overlapping locks made by the same PID (this
1302      goes against POSIX behaviour, which is why it is tricky to implement)
1303
1304   3) the server denies unlock requests by an incorrect client PID
1305 */
1306 static bool run_locktest2(int dummy)
1307 {
1308         static struct cli_state *cli;
1309         const char *fname = "\\lockt2.lck";
1310         int fnum1, fnum2, fnum3;
1311         bool correct = True;
1312
1313         if (!torture_open_connection(&cli, 0)) {
1314                 return False;
1315         }
1316
1317         cli_sockopt(cli, sockops);
1318
1319         printf("starting locktest2\n");
1320
1321         cli_unlink(cli, fname);
1322
1323         cli_setpid(cli, 1);
1324
1325         fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1326         if (fnum1 == -1) {
1327                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1328                 return False;
1329         }
1330
1331         fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1332         if (fnum2 == -1) {
1333                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1334                 return False;
1335         }
1336
1337         cli_setpid(cli, 2);
1338
1339         fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1340         if (fnum3 == -1) {
1341                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1342                 return False;
1343         }
1344
1345         cli_setpid(cli, 1);
1346
1347         if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1348                 printf("lock1 failed (%s)\n", cli_errstr(cli));
1349                 return False;
1350         }
1351
1352         if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1353                 printf("WRITE lock1 succeeded! This is a locking bug\n");
1354                 correct = False;
1355         } else {
1356                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1357                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1358         }
1359
1360         if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1361                 printf("WRITE lock2 succeeded! This is a locking bug\n");
1362                 correct = False;
1363         } else {
1364                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1365                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1366         }
1367
1368         if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1369                 printf("READ lock2 succeeded! This is a locking bug\n");
1370                 correct = False;
1371         } else {
1372                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1373                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1374         }
1375
1376         if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1377                 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1378         }
1379         cli_setpid(cli, 2);
1380         if (cli_unlock(cli, fnum1, 100, 4)) {
1381                 printf("unlock at 100 succeeded! This is a locking bug\n");
1382                 correct = False;
1383         }
1384
1385         if (cli_unlock(cli, fnum1, 0, 4)) {
1386                 printf("unlock1 succeeded! This is a locking bug\n");
1387                 correct = False;
1388         } else {
1389                 if (!check_error(__LINE__, cli, 
1390                                  ERRDOS, ERRlock, 
1391                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1392         }
1393
1394         if (cli_unlock(cli, fnum1, 0, 8)) {
1395                 printf("unlock2 succeeded! This is a locking bug\n");
1396                 correct = False;
1397         } else {
1398                 if (!check_error(__LINE__, cli, 
1399                                  ERRDOS, ERRlock, 
1400                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1401         }
1402
1403         if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1404                 printf("lock3 succeeded! This is a locking bug\n");
1405                 correct = False;
1406         } else {
1407                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1408         }
1409
1410         cli_setpid(cli, 1);
1411
1412         if (!cli_close(cli, fnum1)) {
1413                 printf("close1 failed (%s)\n", cli_errstr(cli));
1414                 return False;
1415         }
1416
1417         if (!cli_close(cli, fnum2)) {
1418                 printf("close2 failed (%s)\n", cli_errstr(cli));
1419                 return False;
1420         }
1421
1422         if (!cli_close(cli, fnum3)) {
1423                 printf("close3 failed (%s)\n", cli_errstr(cli));
1424                 return False;
1425         }
1426
1427         if (!torture_close_connection(cli)) {
1428                 correct = False;
1429         }
1430
1431         printf("locktest2 finished\n");
1432
1433         return correct;
1434 }
1435
1436
1437 /*
1438   This test checks that 
1439
1440   1) the server supports the full offset range in lock requests
1441 */
1442 static bool run_locktest3(int dummy)
1443 {
1444         static struct cli_state *cli1, *cli2;
1445         const char *fname = "\\lockt3.lck";
1446         int fnum1, fnum2, i;
1447         uint32 offset;
1448         bool correct = True;
1449
1450 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1451
1452         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1453                 return False;
1454         }
1455         cli_sockopt(cli1, sockops);
1456         cli_sockopt(cli2, sockops);
1457
1458         printf("starting locktest3\n");
1459
1460         cli_unlink(cli1, fname);
1461
1462         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1463         if (fnum1 == -1) {
1464                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1465                 return False;
1466         }
1467         fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1468         if (fnum2 == -1) {
1469                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1470                 return False;
1471         }
1472
1473         for (offset=i=0;i<torture_numops;i++) {
1474                 NEXT_OFFSET;
1475                 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1476                         printf("lock1 %d failed (%s)\n", 
1477                                i,
1478                                cli_errstr(cli1));
1479                         return False;
1480                 }
1481
1482                 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1483                         printf("lock2 %d failed (%s)\n", 
1484                                i,
1485                                cli_errstr(cli1));
1486                         return False;
1487                 }
1488         }
1489
1490         for (offset=i=0;i<torture_numops;i++) {
1491                 NEXT_OFFSET;
1492
1493                 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1494                         printf("error: lock1 %d succeeded!\n", i);
1495                         return False;
1496                 }
1497
1498                 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1499                         printf("error: lock2 %d succeeded!\n", i);
1500                         return False;
1501                 }
1502
1503                 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1504                         printf("error: lock3 %d succeeded!\n", i);
1505                         return False;
1506                 }
1507
1508                 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1509                         printf("error: lock4 %d succeeded!\n", i);
1510                         return False;
1511                 }
1512         }
1513
1514         for (offset=i=0;i<torture_numops;i++) {
1515                 NEXT_OFFSET;
1516
1517                 if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
1518                         printf("unlock1 %d failed (%s)\n", 
1519                                i,
1520                                cli_errstr(cli1));
1521                         return False;
1522                 }
1523
1524                 if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
1525                         printf("unlock2 %d failed (%s)\n", 
1526                                i,
1527                                cli_errstr(cli1));
1528                         return False;
1529                 }
1530         }
1531
1532         if (!cli_close(cli1, fnum1)) {
1533                 printf("close1 failed (%s)\n", cli_errstr(cli1));
1534                 return False;
1535         }
1536
1537         if (!cli_close(cli2, fnum2)) {
1538                 printf("close2 failed (%s)\n", cli_errstr(cli2));
1539                 return False;
1540         }
1541
1542         if (!cli_unlink(cli1, fname)) {
1543                 printf("unlink failed (%s)\n", cli_errstr(cli1));
1544                 return False;
1545         }
1546
1547         if (!torture_close_connection(cli1)) {
1548                 correct = False;
1549         }
1550         
1551         if (!torture_close_connection(cli2)) {
1552                 correct = False;
1553         }
1554
1555         printf("finished locktest3\n");
1556
1557         return correct;
1558 }
1559
1560 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1561         printf("** "); correct = False; \
1562         }
1563
1564 /*
1565   looks at overlapping locks
1566 */
1567 static bool run_locktest4(int dummy)
1568 {
1569         static struct cli_state *cli1, *cli2;
1570         const char *fname = "\\lockt4.lck";
1571         int fnum1, fnum2, f;
1572         bool ret;
1573         char buf[1000];
1574         bool correct = True;
1575
1576         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1577                 return False;
1578         }
1579
1580         cli_sockopt(cli1, sockops);
1581         cli_sockopt(cli2, sockops);
1582
1583         printf("starting locktest4\n");
1584
1585         cli_unlink(cli1, fname);
1586
1587         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1588         fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1589
1590         memset(buf, 0, sizeof(buf));
1591
1592         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1593                 printf("Failed to create file\n");
1594                 correct = False;
1595                 goto fail;
1596         }
1597
1598         ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1599               cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1600         EXPECTED(ret, False);
1601         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1602             
1603         ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1604               cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1605         EXPECTED(ret, True);
1606         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1607
1608         ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1609               cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1610         EXPECTED(ret, False);
1611         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1612             
1613         ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1614               cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1615         EXPECTED(ret, True);
1616         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1617         
1618         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1619               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1620         EXPECTED(ret, False);
1621         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1622             
1623         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1624               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1625         EXPECTED(ret, True);
1626         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1627
1628         ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1629               cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1630         EXPECTED(ret, True);
1631         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1632
1633         ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1634               cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1635         EXPECTED(ret, False);
1636         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1637
1638         ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1639               cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1640         EXPECTED(ret, False);
1641         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1642
1643         ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1644               cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1645         EXPECTED(ret, True);
1646         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1647
1648         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1649               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1650         EXPECTED(ret, False);
1651         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1652
1653         ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1654               cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1655               cli_unlock(cli1, fnum1, 110, 6);
1656         EXPECTED(ret, False);
1657         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1658
1659
1660         ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1661               (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1662         EXPECTED(ret, False);
1663         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1664
1665         ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1666               (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1667         EXPECTED(ret, False);
1668         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1669
1670
1671         ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1672               cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1673               cli_unlock(cli1, fnum1, 140, 4) &&
1674               cli_unlock(cli1, fnum1, 140, 4);
1675         EXPECTED(ret, True);
1676         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1677
1678
1679         ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1680               cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1681               cli_unlock(cli1, fnum1, 150, 4) &&
1682               (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1683               !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1684               cli_unlock(cli1, fnum1, 150, 4);
1685         EXPECTED(ret, True);
1686         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1687
1688         ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1689               cli_unlock(cli1, fnum1, 160, 4) &&
1690               (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&          
1691               (cli_read(cli2, fnum2, buf, 160, 4) == 4);                
1692         EXPECTED(ret, True);
1693         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1694
1695         ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1696               cli_unlock(cli1, fnum1, 170, 4) &&
1697               (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&          
1698               (cli_read(cli2, fnum2, buf, 170, 4) == 4);                
1699         EXPECTED(ret, True);
1700         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1701
1702         ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1703               cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1704               cli_unlock(cli1, fnum1, 190, 4) &&
1705               !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&         
1706               (cli_read(cli2, fnum2, buf, 190, 4) == 4);                
1707         EXPECTED(ret, True);
1708         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1709
1710         cli_close(cli1, fnum1);
1711         cli_close(cli2, fnum2);
1712         fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1713         f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1714         ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1715               cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1716               cli_close(cli1, fnum1) &&
1717               ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1718               cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1719         cli_close(cli1, f);
1720         cli_close(cli1, fnum1);
1721         EXPECTED(ret, True);
1722         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1723
1724  fail:
1725         cli_close(cli1, fnum1);
1726         cli_close(cli2, fnum2);
1727         cli_unlink(cli1, fname);
1728         torture_close_connection(cli1);
1729         torture_close_connection(cli2);
1730
1731         printf("finished locktest4\n");
1732         return correct;
1733 }
1734
1735 /*
1736   looks at lock upgrade/downgrade.
1737 */
1738 static bool run_locktest5(int dummy)
1739 {
1740         static struct cli_state *cli1, *cli2;
1741         const char *fname = "\\lockt5.lck";
1742         int fnum1, fnum2, fnum3;
1743         bool ret;
1744         char buf[1000];
1745         bool correct = True;
1746
1747         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1748                 return False;
1749         }
1750
1751         cli_sockopt(cli1, sockops);
1752         cli_sockopt(cli2, sockops);
1753
1754         printf("starting locktest5\n");
1755
1756         cli_unlink(cli1, fname);
1757
1758         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1759         fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1760         fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1761
1762         memset(buf, 0, sizeof(buf));
1763
1764         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1765                 printf("Failed to create file\n");
1766                 correct = False;
1767                 goto fail;
1768         }
1769
1770         /* Check for NT bug... */
1771         ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1772                   cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1773         cli_close(cli1, fnum1);
1774         fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1775         ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1776         EXPECTED(ret, True);
1777         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1778         cli_close(cli1, fnum1);
1779         fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1780         cli_unlock(cli1, fnum3, 0, 1);
1781
1782         ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1783               cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1784         EXPECTED(ret, True);
1785         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1786
1787         ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1788         EXPECTED(ret, False);
1789
1790         printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1791
1792         /* Unlock the process 2 lock. */
1793         cli_unlock(cli2, fnum2, 0, 4);
1794
1795         ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1796         EXPECTED(ret, False);
1797
1798         printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1799
1800         /* Unlock the process 1 fnum3 lock. */
1801         cli_unlock(cli1, fnum3, 0, 4);
1802
1803         /* Stack 2 more locks here. */
1804         ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1805                   cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1806
1807         EXPECTED(ret, True);
1808         printf("the same process %s stack read locks\n", ret?"can":"cannot");
1809
1810         /* Unlock the first process lock, then check this was the WRITE lock that was
1811                 removed. */
1812
1813         ret = cli_unlock(cli1, fnum1, 0, 4) &&
1814                         cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1815
1816         EXPECTED(ret, True);
1817         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1818
1819         /* Unlock the process 2 lock. */
1820         cli_unlock(cli2, fnum2, 0, 4);
1821
1822         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1823
1824         ret = cli_unlock(cli1, fnum1, 1, 1) &&
1825                   cli_unlock(cli1, fnum1, 0, 4) &&
1826                   cli_unlock(cli1, fnum1, 0, 4);
1827
1828         EXPECTED(ret, True);
1829         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
1830
1831         /* Ensure the next unlock fails. */
1832         ret = cli_unlock(cli1, fnum1, 0, 4);
1833         EXPECTED(ret, False);
1834         printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
1835
1836         /* Ensure connection 2 can get a write lock. */
1837         ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1838         EXPECTED(ret, True);
1839
1840         printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1841
1842
1843  fail:
1844         cli_close(cli1, fnum1);
1845         cli_close(cli2, fnum2);
1846         cli_unlink(cli1, fname);
1847         if (!torture_close_connection(cli1)) {
1848                 correct = False;
1849         }
1850         if (!torture_close_connection(cli2)) {
1851                 correct = False;
1852         }
1853
1854         printf("finished locktest5\n");
1855        
1856         return correct;
1857 }
1858
1859 /*
1860   tries the unusual lockingX locktype bits
1861 */
1862 static bool run_locktest6(int dummy)
1863 {
1864         static struct cli_state *cli;
1865         const char *fname[1] = { "\\lock6.txt" };
1866         int i;
1867         int fnum;
1868         NTSTATUS status;
1869
1870         if (!torture_open_connection(&cli, 0)) {
1871                 return False;
1872         }
1873
1874         cli_sockopt(cli, sockops);
1875
1876         printf("starting locktest6\n");
1877
1878         for (i=0;i<1;i++) {
1879                 printf("Testing %s\n", fname[i]);
1880
1881                 cli_unlink(cli, fname[i]);
1882
1883                 fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1884                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1885                 cli_close(cli, fnum);
1886                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1887
1888                 fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
1889                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1890                 cli_close(cli, fnum);
1891                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1892
1893                 cli_unlink(cli, fname[i]);
1894         }
1895
1896         torture_close_connection(cli);
1897
1898         printf("finished locktest6\n");
1899         return True;
1900 }
1901
1902 static bool run_locktest7(int dummy)
1903 {
1904         struct cli_state *cli1;
1905         const char *fname = "\\lockt7.lck";
1906         int fnum1;
1907         char buf[200];
1908         bool correct = False;
1909
1910         if (!torture_open_connection(&cli1, 0)) {
1911                 return False;
1912         }
1913
1914         cli_sockopt(cli1, sockops);
1915
1916         printf("starting locktest7\n");
1917
1918         cli_unlink(cli1, fname);
1919
1920         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1921
1922         memset(buf, 0, sizeof(buf));
1923
1924         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1925                 printf("Failed to create file\n");
1926                 goto fail;
1927         }
1928
1929         cli_setpid(cli1, 1);
1930
1931         if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1932                 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1933                 goto fail;
1934         } else {
1935                 printf("pid1 successfully locked range 130:4 for READ\n");
1936         }
1937
1938         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1939                 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1940                 goto fail;
1941         } else {
1942                 printf("pid1 successfully read the range 130:4\n");
1943         }
1944
1945         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1946                 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1947                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1948                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1949                         goto fail;
1950                 }
1951         } else {
1952                 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1953                 goto fail;
1954         }
1955
1956         cli_setpid(cli1, 2);
1957
1958         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1959                 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1960         } else {
1961                 printf("pid2 successfully read the range 130:4\n");
1962         }
1963
1964         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1965                 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1966                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1967                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1968                         goto fail;
1969                 }
1970         } else {
1971                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1972                 goto fail;
1973         }
1974
1975         cli_setpid(cli1, 1);
1976         cli_unlock(cli1, fnum1, 130, 4);
1977
1978         if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
1979                 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
1980                 goto fail;
1981         } else {
1982                 printf("pid1 successfully locked range 130:4 for WRITE\n");
1983         }
1984
1985         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1986                 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1987                 goto fail;
1988         } else {
1989                 printf("pid1 successfully read the range 130:4\n");
1990         }
1991
1992         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1993                 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1994                 goto fail;
1995         } else {
1996                 printf("pid1 successfully wrote to the range 130:4\n");
1997         }
1998
1999         cli_setpid(cli1, 2);
2000
2001         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2002                 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2003                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2004                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2005                         goto fail;
2006                 }
2007         } else {
2008                 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2009                 goto fail;
2010         }
2011
2012         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2013                 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2014                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2015                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2016                         goto fail;
2017                 }
2018         } else {
2019                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2020                 goto fail;
2021         }
2022
2023         cli_unlock(cli1, fnum1, 130, 0);
2024         correct = True;
2025
2026 fail:
2027         cli_close(cli1, fnum1);
2028         cli_unlink(cli1, fname);
2029         torture_close_connection(cli1);
2030
2031         printf("finished locktest7\n");
2032         return correct;
2033 }
2034
2035 /*
2036 test whether fnums and tids open on one VC are available on another (a major
2037 security hole)
2038 */
2039 static bool run_fdpasstest(int dummy)
2040 {
2041         struct cli_state *cli1, *cli2;
2042         const char *fname = "\\fdpass.tst";
2043         int fnum1;
2044         char buf[1024];
2045
2046         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2047                 return False;
2048         }
2049         cli_sockopt(cli1, sockops);
2050         cli_sockopt(cli2, sockops);
2051
2052         printf("starting fdpasstest\n");
2053
2054         cli_unlink(cli1, fname);
2055
2056         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2057         if (fnum1 == -1) {
2058                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2059                 return False;
2060         }
2061
2062         if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2063                 printf("write failed (%s)\n", cli_errstr(cli1));
2064                 return False;
2065         }
2066
2067         cli2->vuid = cli1->vuid;
2068         cli2->cnum = cli1->cnum;
2069         cli2->pid = cli1->pid;
2070
2071         if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2072                 printf("read succeeded! nasty security hole [%s]\n",
2073                        buf);
2074                 return False;
2075         }
2076
2077         cli_close(cli1, fnum1);
2078         cli_unlink(cli1, fname);
2079
2080         torture_close_connection(cli1);
2081         torture_close_connection(cli2);
2082
2083         printf("finished fdpasstest\n");
2084         return True;
2085 }
2086
2087 static bool run_fdsesstest(int dummy)
2088 {
2089         struct cli_state *cli;
2090         uint16 new_vuid;
2091         uint16 saved_vuid;
2092         uint16 new_cnum;
2093         uint16 saved_cnum;
2094         const char *fname = "\\fdsess.tst";
2095         const char *fname1 = "\\fdsess1.tst";
2096         int fnum1;
2097         int fnum2;
2098         char buf[1024];
2099         bool ret = True;
2100
2101         if (!torture_open_connection(&cli, 0))
2102                 return False;
2103         cli_sockopt(cli, sockops);
2104
2105         if (!torture_cli_session_setup2(cli, &new_vuid))
2106                 return False;
2107
2108         saved_cnum = cli->cnum;
2109         if (!cli_send_tconX(cli, share, "?????", "", 1))
2110                 return False;
2111         new_cnum = cli->cnum;
2112         cli->cnum = saved_cnum;
2113
2114         printf("starting fdsesstest\n");
2115
2116         cli_unlink(cli, fname);
2117         cli_unlink(cli, fname1);
2118
2119         fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2120         if (fnum1 == -1) {
2121                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2122                 return False;
2123         }
2124
2125         if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2126                 printf("write failed (%s)\n", cli_errstr(cli));
2127                 return False;
2128         }
2129
2130         saved_vuid = cli->vuid;
2131         cli->vuid = new_vuid;
2132
2133         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2134                 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2135                        buf);
2136                 ret = False;
2137         }
2138         /* Try to open a file with different vuid, samba cnum. */
2139         fnum2 = cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2140         if (fnum2 != -1) {
2141                 printf("create with different vuid, same cnum succeeded.\n");
2142                 cli_close(cli, fnum2);
2143                 cli_unlink(cli, fname1);
2144         } else {
2145                 printf("create with different vuid, same cnum failed.\n");
2146                 printf("This will cause problems with service clients.\n");
2147                 ret = False;
2148         }
2149
2150         cli->vuid = saved_vuid;
2151
2152         /* Try with same vuid, different cnum. */
2153         cli->cnum = new_cnum;
2154
2155         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2156                 printf("read succeeded with different cnum![%s]\n",
2157                        buf);
2158                 ret = False;
2159         }
2160
2161         cli->cnum = saved_cnum;
2162         cli_close(cli, fnum1);
2163         cli_unlink(cli, fname);
2164
2165         torture_close_connection(cli);
2166
2167         printf("finished fdsesstest\n");
2168         return ret;
2169 }
2170
2171 /*
2172   This test checks that 
2173
2174   1) the server does not allow an unlink on a file that is open
2175 */
2176 static bool run_unlinktest(int dummy)
2177 {
2178         struct cli_state *cli;
2179         const char *fname = "\\unlink.tst";
2180         int fnum;
2181         bool correct = True;
2182
2183         if (!torture_open_connection(&cli, 0)) {
2184                 return False;
2185         }
2186
2187         cli_sockopt(cli, sockops);
2188
2189         printf("starting unlink test\n");
2190
2191         cli_unlink(cli, fname);
2192
2193         cli_setpid(cli, 1);
2194
2195         fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2196         if (fnum == -1) {
2197                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2198                 return False;
2199         }
2200
2201         if (cli_unlink(cli, fname)) {
2202                 printf("error: server allowed unlink on an open file\n");
2203                 correct = False;
2204         } else {
2205                 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare, 
2206                                       NT_STATUS_SHARING_VIOLATION);
2207         }
2208
2209         cli_close(cli, fnum);
2210         cli_unlink(cli, fname);
2211
2212         if (!torture_close_connection(cli)) {
2213                 correct = False;
2214         }
2215
2216         printf("unlink test finished\n");
2217         
2218         return correct;
2219 }
2220
2221
2222 /*
2223 test how many open files this server supports on the one socket
2224 */
2225 static bool run_maxfidtest(int dummy)
2226 {
2227         struct cli_state *cli;
2228         const char *ftemplate = "\\maxfid.%d.%d";
2229         fstring fname;
2230         int fnums[0x11000], i;
2231         int retries=4;
2232         bool correct = True;
2233
2234         cli = current_cli;
2235
2236         if (retries <= 0) {
2237                 printf("failed to connect\n");
2238                 return False;
2239         }
2240
2241         cli_sockopt(cli, sockops);
2242
2243         for (i=0; i<0x11000; i++) {
2244                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2245                 if ((fnums[i] = cli_open(cli, fname, 
2246                                         O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
2247                     -1) {
2248                         printf("open of %s failed (%s)\n", 
2249                                fname, cli_errstr(cli));
2250                         printf("maximum fnum is %d\n", i);
2251                         break;
2252                 }
2253                 printf("%6d\r", i);
2254         }
2255         printf("%6d\n", i);
2256         i--;
2257
2258         printf("cleaning up\n");
2259         for (;i>=0;i--) {
2260                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2261                 cli_close(cli, fnums[i]);
2262                 if (!cli_unlink(cli, fname)) {
2263                         printf("unlink of %s failed (%s)\n", 
2264                                fname, cli_errstr(cli));
2265                         correct = False;
2266                 }
2267                 printf("%6d\r", i);
2268         }
2269         printf("%6d\n", 0);
2270
2271         printf("maxfid test finished\n");
2272         if (!torture_close_connection(cli)) {
2273                 correct = False;
2274         }
2275         return correct;
2276 }
2277
2278 /* generate a random buffer */
2279 static void rand_buf(char *buf, int len)
2280 {
2281         while (len--) {
2282                 *buf = (char)sys_random();
2283                 buf++;
2284         }
2285 }
2286
2287 /* send smb negprot commands, not reading the response */
2288 static bool run_negprot_nowait(int dummy)
2289 {
2290         int i;
2291         static struct cli_state *cli;
2292         bool correct = True;
2293
2294         printf("starting negprot nowait test\n");
2295
2296         if (!(cli = open_nbt_connection())) {
2297                 return False;
2298         }
2299
2300         for (i=0;i<50000;i++) {
2301                 cli_negprot_send(cli);
2302         }
2303
2304         if (!torture_close_connection(cli)) {
2305                 correct = False;
2306         }
2307
2308         printf("finished negprot nowait test\n");
2309
2310         return correct;
2311 }
2312
2313
2314 /* send random IPC commands */
2315 static bool run_randomipc(int dummy)
2316 {
2317         char *rparam = NULL;
2318         char *rdata = NULL;
2319         unsigned int rdrcnt,rprcnt;
2320         char param[1024];
2321         int api, param_len, i;
2322         struct cli_state *cli;
2323         bool correct = True;
2324         int count = 50000;
2325
2326         printf("starting random ipc test\n");
2327
2328         if (!torture_open_connection(&cli, 0)) {
2329                 return False;
2330         }
2331
2332         for (i=0;i<count;i++) {
2333                 api = sys_random() % 500;
2334                 param_len = (sys_random() % 64);
2335
2336                 rand_buf(param, param_len);
2337   
2338                 SSVAL(param,0,api); 
2339
2340                 cli_api(cli, 
2341                         param, param_len, 8,  
2342                         NULL, 0, BUFFER_SIZE, 
2343                         &rparam, &rprcnt,     
2344                         &rdata, &rdrcnt);
2345                 if (i % 100 == 0) {
2346                         printf("%d/%d\r", i,count);
2347                 }
2348         }
2349         printf("%d/%d\n", i, count);
2350
2351         if (!torture_close_connection(cli)) {
2352                 correct = False;
2353         }
2354
2355         printf("finished random ipc test\n");
2356
2357         return correct;
2358 }
2359
2360
2361
2362 static void browse_callback(const char *sname, uint32 stype, 
2363                             const char *comment, void *state)
2364 {
2365         printf("\t%20.20s %08x %s\n", sname, stype, comment);
2366 }
2367
2368
2369
2370 /*
2371   This test checks the browse list code
2372
2373 */
2374 static bool run_browsetest(int dummy)
2375 {
2376         static struct cli_state *cli;
2377         bool correct = True;
2378
2379         printf("starting browse test\n");
2380
2381         if (!torture_open_connection(&cli, 0)) {
2382                 return False;
2383         }
2384
2385         printf("domain list:\n");
2386         cli_NetServerEnum(cli, cli->server_domain, 
2387                           SV_TYPE_DOMAIN_ENUM,
2388                           browse_callback, NULL);
2389
2390         printf("machine list:\n");
2391         cli_NetServerEnum(cli, cli->server_domain, 
2392                           SV_TYPE_ALL,
2393                           browse_callback, NULL);
2394
2395         if (!torture_close_connection(cli)) {
2396                 correct = False;
2397         }
2398
2399         printf("browse test finished\n");
2400
2401         return correct;
2402
2403 }
2404
2405
2406 /*
2407   This checks how the getatr calls works
2408 */
2409 static bool run_attrtest(int dummy)
2410 {
2411         struct cli_state *cli;
2412         int fnum;
2413         time_t t, t2;
2414         const char *fname = "\\attrib123456789.tst";
2415         bool correct = True;
2416
2417         printf("starting attrib test\n");
2418
2419         if (!torture_open_connection(&cli, 0)) {
2420                 return False;
2421         }
2422
2423         cli_unlink(cli, fname);
2424         fnum = cli_open(cli, fname, 
2425                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2426         cli_close(cli, fnum);
2427         if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2428                 printf("getatr failed (%s)\n", cli_errstr(cli));
2429                 correct = False;
2430         }
2431
2432         if (abs(t - time(NULL)) > 60*60*24*10) {
2433                 printf("ERROR: SMBgetatr bug. time is %s",
2434                        ctime(&t));
2435                 t = time(NULL);
2436                 correct = True;
2437         }
2438
2439         t2 = t-60*60*24; /* 1 day ago */
2440
2441         if (!cli_setatr(cli, fname, 0, t2)) {
2442                 printf("setatr failed (%s)\n", cli_errstr(cli));
2443                 correct = True;
2444         }
2445
2446         if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2447                 printf("getatr failed (%s)\n", cli_errstr(cli));
2448                 correct = True;
2449         }
2450
2451         if (t != t2) {
2452                 printf("ERROR: getatr/setatr bug. times are\n%s",
2453                        ctime(&t));
2454                 printf("%s", ctime(&t2));
2455                 correct = True;
2456         }
2457
2458         cli_unlink(cli, fname);
2459
2460         if (!torture_close_connection(cli)) {
2461                 correct = False;
2462         }
2463
2464         printf("attrib test finished\n");
2465
2466         return correct;
2467 }
2468
2469
2470 /*
2471   This checks a couple of trans2 calls
2472 */
2473 static bool run_trans2test(int dummy)
2474 {
2475         struct cli_state *cli;
2476         int fnum;
2477         SMB_OFF_T size;
2478         time_t c_time, a_time, m_time;
2479         struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2480         const char *fname = "\\trans2.tst";
2481         const char *dname = "\\trans2";
2482         const char *fname2 = "\\trans2\\trans2.tst";
2483         char pname[1024];
2484         bool correct = True;
2485
2486         printf("starting trans2 test\n");
2487
2488         if (!torture_open_connection(&cli, 0)) {
2489                 return False;
2490         }
2491
2492         cli_unlink(cli, fname);
2493         fnum = cli_open(cli, fname, 
2494                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2495         if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2496                            &m_time_ts, NULL)) {
2497                 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2498                 correct = False;
2499         }
2500
2501         if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2502                 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2503                 correct = False;
2504         }
2505
2506         if (strcmp(pname, fname)) {
2507                 printf("qfilename gave different name? [%s] [%s]\n",
2508                        fname, pname);
2509                 correct = False;
2510         }
2511
2512         cli_close(cli, fnum);
2513
2514         sleep(2);
2515
2516         cli_unlink(cli, fname);
2517         fnum = cli_open(cli, fname, 
2518                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2519         if (fnum == -1) {
2520                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2521                 return False;
2522         }
2523         cli_close(cli, fnum);
2524
2525         if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2526                 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2527                 correct = False;
2528         } else {
2529                 if (c_time != m_time) {
2530                         printf("create time=%s", ctime(&c_time));
2531                         printf("modify time=%s", ctime(&m_time));
2532                         printf("This system appears to have sticky create times\n");
2533                 }
2534                 if (a_time % (60*60) == 0) {
2535                         printf("access time=%s", ctime(&a_time));
2536                         printf("This system appears to set a midnight access time\n");
2537                         correct = False;
2538                 }
2539
2540                 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2541                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2542                         correct = False;
2543                 }
2544         }
2545
2546
2547         cli_unlink(cli, fname);
2548         fnum = cli_open(cli, fname, 
2549                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2550         cli_close(cli, fnum);
2551         if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts, 
2552                             &m_time_ts, &size, NULL, NULL)) {
2553                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2554                 correct = False;
2555         } else {
2556                 if (w_time_ts.tv_sec < 60*60*24*2) {
2557                         printf("write time=%s", ctime(&w_time_ts.tv_sec));
2558                         printf("This system appears to set a initial 0 write time\n");
2559                         correct = False;
2560                 }
2561         }
2562
2563         cli_unlink(cli, fname);
2564
2565
2566         /* check if the server updates the directory modification time
2567            when creating a new file */
2568         if (!cli_mkdir(cli, dname)) {
2569                 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2570                 correct = False;
2571         }
2572         sleep(3);
2573         if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts, 
2574                             &m_time_ts, &size, NULL, NULL)) {
2575                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2576                 correct = False;
2577         }
2578
2579         fnum = cli_open(cli, fname2, 
2580                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2581         cli_write(cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
2582         cli_close(cli, fnum);
2583         if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts, 
2584                             &m_time2_ts, &size, NULL, NULL)) {
2585                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2586                 correct = False;
2587         } else {
2588                 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2589                     == 0) {
2590                         printf("This system does not update directory modification times\n");
2591                         correct = False;
2592                 }
2593         }
2594         cli_unlink(cli, fname2);
2595         cli_rmdir(cli, dname);
2596
2597         if (!torture_close_connection(cli)) {
2598                 correct = False;
2599         }
2600
2601         printf("trans2 test finished\n");
2602
2603         return correct;
2604 }
2605
2606 /*
2607   This checks new W2K calls.
2608 */
2609
2610 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2611 {
2612         char *buf = NULL;
2613         uint32 len;
2614         bool correct = True;
2615
2616         if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2617                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2618                 correct = False;
2619         } else {
2620                 printf("qfileinfo: level %d, len = %u\n", level, len);
2621                 dump_data(0, (uint8 *)buf, len);
2622                 printf("\n");
2623         }
2624         SAFE_FREE(buf);
2625         return correct;
2626 }
2627
2628 static bool run_w2ktest(int dummy)
2629 {
2630         struct cli_state *cli;
2631         int fnum;
2632         const char *fname = "\\w2ktest\\w2k.tst";
2633         int level;
2634         bool correct = True;
2635
2636         printf("starting w2k test\n");
2637
2638         if (!torture_open_connection(&cli, 0)) {
2639                 return False;
2640         }
2641
2642         fnum = cli_open(cli, fname, 
2643                         O_RDWR | O_CREAT , DENY_NONE);
2644
2645         for (level = 1004; level < 1040; level++) {
2646                 new_trans(cli, fnum, level);
2647         }
2648
2649         cli_close(cli, fnum);
2650
2651         if (!torture_close_connection(cli)) {
2652                 correct = False;
2653         }
2654
2655         printf("w2k test finished\n");
2656         
2657         return correct;
2658 }
2659
2660
2661 /*
2662   this is a harness for some oplock tests
2663  */
2664 static bool run_oplock1(int dummy)
2665 {
2666         struct cli_state *cli1;
2667         const char *fname = "\\lockt1.lck";
2668         int fnum1;
2669         bool correct = True;
2670
2671         printf("starting oplock test 1\n");
2672
2673         if (!torture_open_connection(&cli1, 0)) {
2674                 return False;
2675         }
2676
2677         cli_unlink(cli1, fname);
2678
2679         cli_sockopt(cli1, sockops);
2680
2681         cli1->use_oplocks = True;
2682
2683         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2684         if (fnum1 == -1) {
2685                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2686                 return False;
2687         }
2688
2689         cli1->use_oplocks = False;
2690
2691         cli_unlink(cli1, fname);
2692         cli_unlink(cli1, fname);
2693
2694         if (!cli_close(cli1, fnum1)) {
2695                 printf("close2 failed (%s)\n", cli_errstr(cli1));
2696                 return False;
2697         }
2698
2699         if (!cli_unlink(cli1, fname)) {
2700                 printf("unlink failed (%s)\n", cli_errstr(cli1));
2701                 return False;
2702         }
2703
2704         if (!torture_close_connection(cli1)) {
2705                 correct = False;
2706         }
2707
2708         printf("finished oplock test 1\n");
2709
2710         return correct;
2711 }
2712
2713 static bool run_oplock2(int dummy)
2714 {
2715         struct cli_state *cli1, *cli2;
2716         const char *fname = "\\lockt2.lck";
2717         int fnum1, fnum2;
2718         int saved_use_oplocks = use_oplocks;
2719         char buf[4];
2720         bool correct = True;
2721         volatile bool *shared_correct;
2722
2723         shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2724         *shared_correct = True;
2725
2726         use_level_II_oplocks = True;
2727         use_oplocks = True;
2728
2729         printf("starting oplock test 2\n");
2730
2731         if (!torture_open_connection(&cli1, 0)) {
2732                 use_level_II_oplocks = False;
2733                 use_oplocks = saved_use_oplocks;
2734                 return False;
2735         }
2736
2737         cli1->use_oplocks = True;
2738         cli1->use_level_II_oplocks = True;
2739
2740         if (!torture_open_connection(&cli2, 1)) {
2741                 use_level_II_oplocks = False;
2742                 use_oplocks = saved_use_oplocks;
2743                 return False;
2744         }
2745
2746         cli2->use_oplocks = True;
2747         cli2->use_level_II_oplocks = True;
2748
2749         cli_unlink(cli1, fname);
2750
2751         cli_sockopt(cli1, sockops);
2752         cli_sockopt(cli2, sockops);
2753
2754         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2755         if (fnum1 == -1) {
2756                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2757                 return False;
2758         }
2759
2760         /* Don't need the globals any more. */
2761         use_level_II_oplocks = False;
2762         use_oplocks = saved_use_oplocks;
2763
2764         if (fork() == 0) {
2765                 /* Child code */
2766                 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
2767                 if (fnum2 == -1) {
2768                         printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
2769                         *shared_correct = False;
2770                         exit(0);
2771                 }
2772
2773                 sleep(2);
2774
2775                 if (!cli_close(cli2, fnum2)) {
2776                         printf("close2 failed (%s)\n", cli_errstr(cli1));
2777                         *shared_correct = False;
2778                 }
2779
2780                 exit(0);
2781         }
2782
2783         sleep(2);
2784
2785         /* Ensure cli1 processes the break. Empty file should always return 0
2786          * bytes.  */
2787
2788         if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
2789                 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
2790                 correct = False;
2791         }
2792
2793         /* Should now be at level II. */
2794         /* Test if sending a write locks causes a break to none. */
2795
2796         if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2797                 printf("lock failed (%s)\n", cli_errstr(cli1));
2798                 correct = False;
2799         }
2800
2801         cli_unlock(cli1, fnum1, 0, 4);
2802
2803         sleep(2);
2804
2805         if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2806                 printf("lock failed (%s)\n", cli_errstr(cli1));
2807                 correct = False;
2808         }
2809
2810         cli_unlock(cli1, fnum1, 0, 4);
2811
2812         sleep(2);
2813
2814         cli_read(cli1, fnum1, buf, 0, 4);
2815
2816 #if 0
2817         if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
2818                 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
2819                 correct = False;
2820         }
2821 #endif
2822
2823         if (!cli_close(cli1, fnum1)) {
2824                 printf("close1 failed (%s)\n", cli_errstr(cli1));
2825                 correct = False;
2826         }
2827
2828         sleep(4);
2829
2830         if (!cli_unlink(cli1, fname)) {
2831                 printf("unlink failed (%s)\n", cli_errstr(cli1));
2832                 correct = False;
2833         }
2834
2835         if (!torture_close_connection(cli1)) {
2836                 correct = False;
2837         }
2838
2839         if (!*shared_correct) {
2840                 correct = False;
2841         }
2842
2843         printf("finished oplock test 2\n");
2844
2845         return correct;
2846 }
2847
2848 /* handler for oplock 3 tests */
2849 static bool oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2850 {
2851         printf("got oplock break fnum=%d level=%d\n",
2852                fnum, level);
2853         return cli_oplock_ack(cli, fnum, level);
2854 }
2855
2856 static bool run_oplock3(int dummy)
2857 {
2858         struct cli_state *cli;
2859         const char *fname = "\\oplockt3.dat";
2860         int fnum;
2861         char buf[4] = "abcd";
2862         bool correct = True;
2863         volatile bool *shared_correct;
2864
2865         shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2866         *shared_correct = True;
2867
2868         printf("starting oplock test 3\n");
2869
2870         if (fork() == 0) {
2871                 /* Child code */
2872                 use_oplocks = True;
2873                 use_level_II_oplocks = True;
2874                 if (!torture_open_connection(&cli, 0)) {
2875                         *shared_correct = False;
2876                         exit(0);
2877                 } 
2878                 sleep(2);
2879                 /* try to trigger a oplock break in parent */
2880                 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2881                 cli_write(cli, fnum, 0, buf, 0, 4);
2882                 exit(0);
2883         }
2884
2885         /* parent code */
2886         use_oplocks = True;
2887         use_level_II_oplocks = True;
2888         if (!torture_open_connection(&cli, 1)) { /* other is forked */
2889                 return False;
2890         }
2891         cli_oplock_handler(cli, oplock3_handler);
2892         fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2893         cli_write(cli, fnum, 0, buf, 0, 4);
2894         cli_close(cli, fnum);
2895         fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2896         cli->timeout = 20000;
2897         cli_receive_smb(cli);
2898         printf("finished oplock test 3\n");
2899
2900         return (correct && *shared_correct);
2901
2902 /* What are we looking for here?  What's sucess and what's FAILURE? */
2903 }
2904
2905
2906
2907 /*
2908   Test delete on close semantics.
2909  */
2910 static bool run_deletetest(int dummy)
2911 {
2912         struct cli_state *cli1 = NULL;
2913         struct cli_state *cli2 = NULL;
2914         const char *fname = "\\delete.file";
2915         int fnum1 = -1;
2916         int fnum2 = -1;
2917         bool correct = True;
2918         
2919         printf("starting delete test\n");
2920         
2921         if (!torture_open_connection(&cli1, 0)) {
2922                 return False;
2923         }
2924         
2925         cli_sockopt(cli1, sockops);
2926
2927         /* Test 1 - this should delete the file on close. */
2928         
2929         cli_setatr(cli1, fname, 0, 0);
2930         cli_unlink(cli1, fname);
2931         
2932         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2933                                    0, FILE_OVERWRITE_IF, 
2934                                    FILE_DELETE_ON_CLOSE, 0);
2935         
2936         if (fnum1 == -1) {
2937                 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2938                 correct = False;
2939                 goto fail;
2940         }
2941
2942 #if 0 /* JRATEST */
2943         {
2944                 uint32 *accinfo = NULL;
2945                 uint32 len;
2946                 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
2947                 if (accinfo)
2948                         printf("access mode = 0x%lx\n", *accinfo);
2949                 SAFE_FREE(accinfo);
2950         }
2951 #endif
2952
2953         if (!cli_close(cli1, fnum1)) {
2954                 printf("[1] close failed (%s)\n", cli_errstr(cli1));
2955                 correct = False;
2956                 goto fail;
2957         }
2958
2959         fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
2960         if (fnum1 != -1) {
2961                 printf("[1] open of %s succeeded (should fail)\n", fname);
2962                 correct = False;
2963                 goto fail;
2964         }
2965         
2966         printf("first delete on close test succeeded.\n");
2967         
2968         /* Test 2 - this should delete the file on close. */
2969         
2970         cli_setatr(cli1, fname, 0, 0);
2971         cli_unlink(cli1, fname);
2972         
2973         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS,
2974                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, 
2975                                    FILE_OVERWRITE_IF, 0, 0);
2976         
2977         if (fnum1 == -1) {
2978                 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2979                 correct = False;
2980                 goto fail;
2981         }
2982         
2983         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
2984                 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
2985                 correct = False;
2986                 goto fail;
2987         }
2988         
2989         if (!cli_close(cli1, fnum1)) {
2990                 printf("[2] close failed (%s)\n", cli_errstr(cli1));
2991                 correct = False;
2992                 goto fail;
2993         }
2994         
2995         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
2996         if (fnum1 != -1) {
2997                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2998                 if (!cli_close(cli1, fnum1)) {
2999                         printf("[2] close failed (%s)\n", cli_errstr(cli1));
3000                         correct = False;
3001                         goto fail;
3002                 }
3003                 cli_unlink(cli1, fname);
3004         } else
3005                 printf("second delete on close test succeeded.\n");
3006         
3007         /* Test 3 - ... */
3008         cli_setatr(cli1, fname, 0, 0);
3009         cli_unlink(cli1, fname);
3010
3011         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3012                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3013
3014         if (fnum1 == -1) {
3015                 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3016                 correct = False;
3017                 goto fail;
3018         }
3019
3020         /* This should fail with a sharing violation - open for delete is only compatible
3021            with SHARE_DELETE. */
3022
3023         fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3024                         FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0);
3025
3026         if (fnum2 != -1) {
3027                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
3028                 correct = False;
3029                 goto fail;
3030         }
3031
3032         /* This should succeed. */
3033
3034         fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3035                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3036
3037         if (fnum2 == -1) {
3038                 printf("[3] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3039                 correct = False;
3040                 goto fail;
3041         }
3042
3043         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3044                 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3045                 correct = False;
3046                 goto fail;
3047         }
3048         
3049         if (!cli_close(cli1, fnum1)) {
3050                 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3051                 correct = False;
3052                 goto fail;
3053         }
3054         
3055         if (!cli_close(cli1, fnum2)) {
3056                 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3057                 correct = False;
3058                 goto fail;
3059         }
3060         
3061         /* This should fail - file should no longer be there. */
3062
3063         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3064         if (fnum1 != -1) {
3065                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3066                 if (!cli_close(cli1, fnum1)) {
3067                         printf("[3] close failed (%s)\n", cli_errstr(cli1));
3068                 }
3069                 cli_unlink(cli1, fname);
3070                 correct = False;
3071                 goto fail;
3072         } else
3073                 printf("third delete on close test succeeded.\n");
3074
3075         /* Test 4 ... */
3076         cli_setatr(cli1, fname, 0, 0);
3077         cli_unlink(cli1, fname);
3078
3079         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3080                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3081                                                                 
3082         if (fnum1 == -1) {
3083                 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3084                 correct = False;
3085                 goto fail;
3086         }
3087
3088         /* This should succeed. */
3089         fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3090                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3091         if (fnum2 == -1) {
3092                 printf("[4] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3093                 correct = False;
3094                 goto fail;
3095         }
3096         
3097         if (!cli_close(cli1, fnum2)) {
3098                 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3099                 correct = False;
3100                 goto fail;
3101         }
3102         
3103         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3104                 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3105                 correct = False;
3106                 goto fail;
3107         }
3108         
3109         /* This should fail - no more opens once delete on close set. */
3110         fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3111                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3112                                    FILE_OPEN, 0, 0);
3113         if (fnum2 != -1) {
3114                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
3115                 correct = False;
3116                 goto fail;
3117         } else
3118                 printf("fourth delete on close test succeeded.\n");
3119         
3120         if (!cli_close(cli1, fnum1)) {
3121                 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3122                 correct = False;
3123                 goto fail;
3124         }
3125         
3126         /* Test 5 ... */
3127         cli_setatr(cli1, fname, 0, 0);
3128         cli_unlink(cli1, fname);
3129         
3130         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
3131         if (fnum1 == -1) {
3132                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3133                 correct = False;
3134                 goto fail;
3135         }
3136
3137         /* This should fail - only allowed on NT opens with DELETE access. */
3138
3139         if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3140                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3141                 correct = False;
3142                 goto fail;
3143         }
3144
3145         if (!cli_close(cli1, fnum1)) {
3146                 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3147                 correct = False;
3148                 goto fail;
3149         }
3150         
3151         printf("fifth delete on close test succeeded.\n");
3152         
3153         /* Test 6 ... */
3154         cli_setatr(cli1, fname, 0, 0);