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