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