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