s3-build: only include async headers where needed.
[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 #include "torture/proto.h"
24 #include "libcli/security/dom_sid.h"
25 #include "tldap.h"
26 #include "tldap_util.h"
27 #include "../librpc/gen_ndr/svcctl.h"
28 #include "memcache.h"
29 #include "nsswitch/winbind_client.h"
30 #include "dbwrap.h"
31 #include "talloc_dict.h"
32 #include "async_smb.h"
33
34 extern char *optarg;
35 extern int optind;
36
37 static fstring host, workgroup, share, password, username, myname;
38 static int max_protocol = PROTOCOL_NT1;
39 static const char *sockops="TCP_NODELAY";
40 static int nprocs=1;
41 static int port_to_use=0;
42 int torture_numops=100;
43 int torture_blocksize=1024*1024;
44 static int procnum; /* records process count number when forking */
45 static struct cli_state *current_cli;
46 static fstring randomfname;
47 static bool use_oplocks;
48 static bool use_level_II_oplocks;
49 static const char *client_txt = "client_oplocks.txt";
50 static bool use_kerberos;
51 static fstring multishare_conn_fname;
52 static bool use_multishare_conn = False;
53 static bool do_encrypt;
54 static const char *local_path = NULL;
55
56 bool torture_showall = False;
57
58 static double create_procs(bool (*fn)(int), bool *result);
59
60
61 /* return a pointer to a anonymous shared memory segment of size "size"
62    which will persist across fork() but will disappear when all processes
63    exit 
64
65    The memory is not zeroed 
66
67    This function uses system5 shared memory. It takes advantage of a property
68    that the memory is not destroyed if it is attached when the id is removed
69    */
70 void *shm_setup(int size)
71 {
72         int shmid;
73         void *ret;
74
75 #ifdef __QNXNTO__
76         shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
77         if (shmid == -1) {
78                 printf("can't get shared memory\n");
79                 exit(1);
80         }
81         shm_unlink("private");
82         if (ftruncate(shmid, size) == -1) {
83                 printf("can't set shared memory size\n");
84                 exit(1);
85         }
86         ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
87         if (ret == MAP_FAILED) {
88                 printf("can't map shared memory\n");
89                 exit(1);
90         }
91 #else
92         shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
93         if (shmid == -1) {
94                 printf("can't get shared memory\n");
95                 exit(1);
96         }
97         ret = (void *)shmat(shmid, 0, 0);
98         if (!ret || ret == (void *)-1) {
99                 printf("can't attach to shared memory\n");
100                 return NULL;
101         }
102         /* the following releases the ipc, but note that this process
103            and all its children will still have access to the memory, its
104            just that the shmid is no longer valid for other shm calls. This
105            means we don't leave behind lots of shm segments after we exit 
106
107            See Stevens "advanced programming in unix env" for details
108            */
109         shmctl(shmid, IPC_RMID, 0);
110 #endif
111
112         return ret;
113 }
114
115 /********************************************************************
116  Ensure a connection is encrypted.
117 ********************************************************************/
118
119 static bool force_cli_encryption(struct cli_state *c,
120                         const char *sharename)
121 {
122         uint16 major, minor;
123         uint32 caplow, caphigh;
124         NTSTATUS status;
125
126         if (!SERVER_HAS_UNIX_CIFS(c)) {
127                 d_printf("Encryption required and "
128                         "server that doesn't support "
129                         "UNIX extensions - failing connect\n");
130                         return false;
131         }
132
133         status = cli_unix_extensions_version(c, &major, &minor, &caplow,
134                                              &caphigh);
135         if (!NT_STATUS_IS_OK(status)) {
136                 d_printf("Encryption required and "
137                         "can't get UNIX CIFS extensions "
138                         "version from server: %s\n", nt_errstr(status));
139                 return false;
140         }
141
142         if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
143                 d_printf("Encryption required and "
144                         "share %s doesn't support "
145                         "encryption.\n", sharename);
146                 return false;
147         }
148
149         if (c->use_kerberos) {
150                 status = cli_gss_smb_encryption_start(c);
151         } else {
152                 status = cli_raw_ntlm_smb_encryption_start(c,
153                                                 username,
154                                                 password,
155                                                 workgroup);
156         }
157
158         if (!NT_STATUS_IS_OK(status)) {
159                 d_printf("Encryption required and "
160                         "setup failed with error %s.\n",
161                         nt_errstr(status));
162                 return false;
163         }
164
165         return true;
166 }
167
168
169 static struct cli_state *open_nbt_connection(void)
170 {
171         struct nmb_name called, calling;
172         struct sockaddr_storage ss;
173         struct cli_state *c;
174         NTSTATUS status;
175
176         make_nmb_name(&calling, myname, 0x0);
177         make_nmb_name(&called , host, 0x20);
178
179         zero_sockaddr(&ss);
180
181         if (!(c = cli_initialise())) {
182                 printf("Failed initialize cli_struct to connect with %s\n", host);
183                 return NULL;
184         }
185
186         c->port = port_to_use;
187
188         status = cli_connect(c, host, &ss);
189         if (!NT_STATUS_IS_OK(status)) {
190                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
191                 return NULL;
192         }
193
194         c->use_kerberos = use_kerberos;
195
196         c->timeout = 120000; /* set a really long timeout (2 minutes) */
197         if (use_oplocks) c->use_oplocks = True;
198         if (use_level_II_oplocks) c->use_level_II_oplocks = True;
199
200         if (!cli_session_request(c, &calling, &called)) {
201                 /*
202                  * Well, that failed, try *SMBSERVER ...
203                  * However, we must reconnect as well ...
204                  */
205                 status = cli_connect(c, host, &ss);
206                 if (!NT_STATUS_IS_OK(status)) {
207                         printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
208                         return NULL;
209                 }
210
211                 make_nmb_name(&called, "*SMBSERVER", 0x20);
212                 if (!cli_session_request(c, &calling, &called)) {
213                         printf("%s rejected the session\n",host);
214                         printf("We tried with a called name of %s & %s\n",
215                                 host, "*SMBSERVER");
216                         cli_shutdown(c);
217                         return NULL;
218                 }
219         }
220
221         return c;
222 }
223
224 /* Insert a NULL at the first separator of the given path and return a pointer
225  * to the remainder of the string.
226  */
227 static char *
228 terminate_path_at_separator(char * path)
229 {
230         char * p;
231
232         if (!path) {
233                 return NULL;
234         }
235
236         if ((p = strchr_m(path, '/'))) {
237                 *p = '\0';
238                 return p + 1;
239         }
240
241         if ((p = strchr_m(path, '\\'))) {
242                 *p = '\0';
243                 return p + 1;
244         }
245
246         /* No separator. */
247         return NULL;
248 }
249
250 /*
251   parse a //server/share type UNC name
252 */
253 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
254                       char **hostname, char **sharename)
255 {
256         char *p;
257
258         *hostname = *sharename = NULL;
259
260         if (strncmp(unc_name, "\\\\", 2) &&
261             strncmp(unc_name, "//", 2)) {
262                 return False;
263         }
264
265         *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
266         p = terminate_path_at_separator(*hostname);
267
268         if (p && *p) {
269                 *sharename = talloc_strdup(mem_ctx, p);
270                 terminate_path_at_separator(*sharename);
271         }
272
273         if (*hostname && *sharename) {
274                 return True;
275         }
276
277         TALLOC_FREE(*hostname);
278         TALLOC_FREE(*sharename);
279         return False;
280 }
281
282 static bool torture_open_connection_share(struct cli_state **c,
283                                    const char *hostname, 
284                                    const char *sharename)
285 {
286         bool retry;
287         int flags = 0;
288         NTSTATUS status;
289
290         if (use_kerberos)
291                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
292         if (use_oplocks)
293                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
294         if (use_level_II_oplocks)
295                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
296
297         status = cli_full_connection(c, myname,
298                                      hostname, NULL, port_to_use, 
299                                      sharename, "?????", 
300                                      username, workgroup, 
301                                      password, flags, Undefined, &retry);
302         if (!NT_STATUS_IS_OK(status)) {
303                 printf("failed to open share connection: //%s/%s port:%d - %s\n",
304                         hostname, sharename, port_to_use, nt_errstr(status));
305                 return False;
306         }
307
308         (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
309
310         if (do_encrypt) {
311                 return force_cli_encryption(*c,
312                                         sharename);
313         }
314         return True;
315 }
316
317 bool torture_open_connection(struct cli_state **c, int conn_index)
318 {
319         char **unc_list = NULL;
320         int num_unc_names = 0;
321         bool result;
322
323         if (use_multishare_conn==True) {
324                 char *h, *s;
325                 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
326                 if (!unc_list || num_unc_names <= 0) {
327                         printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
328                         exit(1);
329                 }
330
331                 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
332                                       NULL, &h, &s)) {
333                         printf("Failed to parse UNC name %s\n",
334                                unc_list[conn_index % num_unc_names]);
335                         TALLOC_FREE(unc_list);
336                         exit(1);
337                 }
338
339                 result = torture_open_connection_share(c, h, s);
340
341                 /* h, s were copied earlier */
342                 TALLOC_FREE(unc_list);
343                 return result;
344         }
345
346         return torture_open_connection_share(c, host, share);
347 }
348
349 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
350 {
351         uint16 old_vuid = cli->vuid;
352         fstring old_user_name;
353         size_t passlen = strlen(password);
354         NTSTATUS status;
355         bool ret;
356
357         fstrcpy(old_user_name, cli->user_name);
358         cli->vuid = 0;
359         ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
360                                                 password, passlen,
361                                                 password, passlen,
362                                                 workgroup));
363         *new_vuid = cli->vuid;
364         cli->vuid = old_vuid;
365         status = cli_set_username(cli, old_user_name);
366         if (!NT_STATUS_IS_OK(status)) {
367                 return false;
368         }
369         return ret;
370 }
371
372
373 bool torture_close_connection(struct cli_state *c)
374 {
375         bool ret = True;
376         NTSTATUS status;
377
378         status = cli_tdis(c);
379         if (!NT_STATUS_IS_OK(status)) {
380                 printf("tdis failed (%s)\n", nt_errstr(status));
381                 ret = False;
382         }
383
384         cli_shutdown(c);
385
386         return ret;
387 }
388
389
390 /* check if the server produced the expected error code */
391 static bool check_error(int line, struct cli_state *c, 
392                         uint8 eclass, uint32 ecode, NTSTATUS nterr)
393 {
394         if (cli_is_dos_error(c)) {
395                 uint8 cclass;
396                 uint32 num;
397
398                 /* Check DOS error */
399
400                 cli_dos_error(c, &cclass, &num);
401
402                 if (eclass != cclass || ecode != num) {
403                         printf("unexpected error code class=%d code=%d\n", 
404                                (int)cclass, (int)num);
405                         printf(" expected %d/%d %s (line=%d)\n", 
406                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
407                         return False;
408                 }
409
410         } else {
411                 NTSTATUS status;
412
413                 /* Check NT error */
414
415                 status = cli_nt_error(c);
416
417                 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
418                         printf("unexpected error code %s\n", nt_errstr(status));
419                         printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
420                         return False;
421                 }
422         }
423
424         return True;
425 }
426
427
428 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
429 {
430         while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
431                 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
432         }
433         return True;
434 }
435
436
437 static bool rw_torture(struct cli_state *c)
438 {
439         const char *lockfname = "\\torture.lck";
440         fstring fname;
441         uint16_t fnum;
442         uint16_t fnum2;
443         pid_t pid2, pid = getpid();
444         int i, j;
445         char buf[1024];
446         bool correct = True;
447         NTSTATUS status;
448
449         memset(buf, '\0', sizeof(buf));
450
451         status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
452                          DENY_NONE, &fnum2);
453         if (!NT_STATUS_IS_OK(status)) {
454                 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
455         }
456         if (!NT_STATUS_IS_OK(status)) {
457                 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
458                 return False;
459         }
460
461         for (i=0;i<torture_numops;i++) {
462                 unsigned n = (unsigned)sys_random()%10;
463                 if (i % 10 == 0) {
464                         printf("%d\r", i); fflush(stdout);
465                 }
466                 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
467
468                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
469                         return False;
470                 }
471
472                 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
473                         printf("open failed (%s)\n", cli_errstr(c));
474                         correct = False;
475                         break;
476                 }
477
478                 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
479                         printf("write failed (%s)\n", cli_errstr(c));
480                         correct = False;
481                 }
482
483                 for (j=0;j<50;j++) {
484                         if (cli_write(c, fnum, 0, (char *)buf, 
485                                       sizeof(pid)+(j*sizeof(buf)), 
486                                       sizeof(buf)) != sizeof(buf)) {
487                                 printf("write failed (%s)\n", cli_errstr(c));
488                                 correct = False;
489                         }
490                 }
491
492                 pid2 = 0;
493
494                 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
495                         printf("read failed (%s)\n", cli_errstr(c));
496                         correct = False;
497                 }
498
499                 if (pid2 != pid) {
500                         printf("data corruption!\n");
501                         correct = False;
502                 }
503
504                 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
505                         printf("close failed (%s)\n", cli_errstr(c));
506                         correct = False;
507                 }
508
509                 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
510                         printf("unlink failed (%s)\n", cli_errstr(c));
511                         correct = False;
512                 }
513
514                 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
515                         printf("unlock failed (%s)\n", cli_errstr(c));
516                         correct = False;
517                 }
518         }
519
520         cli_close(c, fnum2);
521         cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
522
523         printf("%d\n", i);
524
525         return correct;
526 }
527
528 static bool run_torture(int dummy)
529 {
530         struct cli_state *cli;
531         bool ret;
532
533         cli = current_cli;
534
535         cli_sockopt(cli, sockops);
536
537         ret = rw_torture(cli);
538
539         if (!torture_close_connection(cli)) {
540                 ret = False;
541         }
542
543         return ret;
544 }
545
546 static bool rw_torture3(struct cli_state *c, char *lockfname)
547 {
548         uint16_t fnum = (uint16_t)-1;
549         unsigned int i = 0;
550         char buf[131072];
551         char buf_rd[131072];
552         unsigned count;
553         unsigned countprev = 0;
554         ssize_t sent = 0;
555         bool correct = True;
556         NTSTATUS status;
557
558         srandom(1);
559         for (i = 0; i < sizeof(buf); i += sizeof(uint32))
560         {
561                 SIVAL(buf, i, sys_random());
562         }
563
564         if (procnum == 0)
565         {
566                 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
567                                  DENY_NONE, &fnum))) {
568                         printf("first open read/write of %s failed (%s)\n",
569                                         lockfname, cli_errstr(c));
570                         return False;
571                 }
572         }
573         else
574         {
575                 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
576                 {
577                         status = cli_open(c, lockfname, O_RDONLY, 
578                                          DENY_NONE, &fnum);
579                         if (!NT_STATUS_IS_OK(status)) {
580                                 break;
581                         }
582                         smb_msleep(10);
583                 }
584                 if (!NT_STATUS_IS_OK(status)) {
585                         printf("second open read-only of %s failed (%s)\n",
586                                         lockfname, cli_errstr(c));
587                         return False;
588                 }
589         }
590
591         i = 0;
592         for (count = 0; count < sizeof(buf); count += sent)
593         {
594                 if (count >= countprev) {
595                         printf("%d %8d\r", i, count);
596                         fflush(stdout);
597                         i++;
598                         countprev += (sizeof(buf) / 20);
599                 }
600
601                 if (procnum == 0)
602                 {
603                         sent = ((unsigned)sys_random()%(20))+ 1;
604                         if (sent > sizeof(buf) - count)
605                         {
606                                 sent = sizeof(buf) - count;
607                         }
608
609                         if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
610                                 printf("write failed (%s)\n", cli_errstr(c));
611                                 correct = False;
612                         }
613                 }
614                 else
615                 {
616                         sent = cli_read(c, fnum, buf_rd+count, count,
617                                                   sizeof(buf)-count);
618                         if (sent < 0)
619                         {
620                                 printf("read failed offset:%d size:%ld (%s)\n",
621                                        count, (unsigned long)sizeof(buf)-count,
622                                        cli_errstr(c));
623                                 correct = False;
624                                 sent = 0;
625                         }
626                         if (sent > 0)
627                         {
628                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
629                                 {
630                                         printf("read/write compare failed\n");
631                                         printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
632                                         correct = False;
633                                         break;
634                                 }
635                         }
636                 }
637
638         }
639
640         if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
641                 printf("close failed (%s)\n", cli_errstr(c));
642                 correct = False;
643         }
644
645         return correct;
646 }
647
648 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
649 {
650         const char *lockfname = "\\torture2.lck";
651         uint16_t fnum1;
652         uint16_t fnum2;
653         int i;
654         char buf[131072];
655         char buf_rd[131072];
656         bool correct = True;
657         ssize_t bytes_read;
658
659         if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
660                 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
661         }
662
663         if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL, 
664                          DENY_NONE, &fnum1))) {
665                 printf("first open read/write of %s failed (%s)\n",
666                                 lockfname, cli_errstr(c1));
667                 return False;
668         }
669         if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY, 
670                          DENY_NONE, &fnum2))) {
671                 printf("second open read-only of %s failed (%s)\n",
672                                 lockfname, cli_errstr(c2));
673                 cli_close(c1, fnum1);
674                 return False;
675         }
676
677         for (i=0;i<torture_numops;i++)
678         {
679                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
680                 if (i % 10 == 0) {
681                         printf("%d\r", i); fflush(stdout);
682                 }
683
684                 generate_random_buffer((unsigned char *)buf, buf_size);
685
686                 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
687                         printf("write failed (%s)\n", cli_errstr(c1));
688                         correct = False;
689                         break;
690                 }
691
692                 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
693                         printf("read failed (%s)\n", cli_errstr(c2));
694                         printf("read %d, expected %ld\n", (int)bytes_read, 
695                                (unsigned long)buf_size); 
696                         correct = False;
697                         break;
698                 }
699
700                 if (memcmp(buf_rd, buf, buf_size) != 0)
701                 {
702                         printf("read/write compare failed\n");
703                         correct = False;
704                         break;
705                 }
706         }
707
708         if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
709                 printf("close failed (%s)\n", cli_errstr(c2));
710                 correct = False;
711         }
712         if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
713                 printf("close failed (%s)\n", cli_errstr(c1));
714                 correct = False;
715         }
716
717         if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
718                 printf("unlink failed (%s)\n", cli_errstr(c1));
719                 correct = False;
720         }
721
722         return correct;
723 }
724
725 static bool run_readwritetest(int dummy)
726 {
727         struct cli_state *cli1, *cli2;
728         bool test1, test2 = False;
729
730         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
731                 return False;
732         }
733         cli_sockopt(cli1, sockops);
734         cli_sockopt(cli2, sockops);
735
736         printf("starting readwritetest\n");
737
738         test1 = rw_torture2(cli1, cli2);
739         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
740
741         if (test1) {
742                 test2 = rw_torture2(cli1, cli1);
743                 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
744         }
745
746         if (!torture_close_connection(cli1)) {
747                 test1 = False;
748         }
749
750         if (!torture_close_connection(cli2)) {
751                 test2 = False;
752         }
753
754         return (test1 && test2);
755 }
756
757 static bool run_readwritemulti(int dummy)
758 {
759         struct cli_state *cli;
760         bool test;
761
762         cli = current_cli;
763
764         cli_sockopt(cli, sockops);
765
766         printf("run_readwritemulti: fname %s\n", randomfname);
767         test = rw_torture3(cli, randomfname);
768
769         if (!torture_close_connection(cli)) {
770                 test = False;
771         }
772
773         return test;
774 }
775
776 static bool run_readwritelarge(int dummy)
777 {
778         static struct cli_state *cli1;
779         uint16_t fnum1;
780         const char *lockfname = "\\large.dat";
781         SMB_OFF_T fsize;
782         char buf[126*1024];
783         bool correct = True;
784
785         if (!torture_open_connection(&cli1, 0)) {
786                 return False;
787         }
788         cli_sockopt(cli1, sockops);
789         memset(buf,'\0',sizeof(buf));
790
791         cli1->max_xmit = 128*1024;
792
793         printf("starting readwritelarge\n");
794
795         cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
796
797         if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
798                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
799                 return False;
800         }
801
802         cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
803
804         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
805                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
806                 correct = False;
807         }
808
809         if (fsize == sizeof(buf))
810                 printf("readwritelarge test 1 succeeded (size = %lx)\n", 
811                        (unsigned long)fsize);
812         else {
813                 printf("readwritelarge test 1 failed (size = %lx)\n", 
814                        (unsigned long)fsize);
815                 correct = False;
816         }
817
818         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
819                 printf("close failed (%s)\n", cli_errstr(cli1));
820                 correct = False;
821         }
822
823         if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
824                 printf("unlink failed (%s)\n", cli_errstr(cli1));
825                 correct = False;
826         }
827
828         if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
829                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
830                 return False;
831         }
832
833         cli1->max_xmit = 4*1024;
834
835         cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
836
837         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
838                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
839                 correct = False;
840         }
841
842         if (fsize == sizeof(buf))
843                 printf("readwritelarge test 2 succeeded (size = %lx)\n", 
844                        (unsigned long)fsize);
845         else {
846                 printf("readwritelarge test 2 failed (size = %lx)\n", 
847                        (unsigned long)fsize);
848                 correct = False;
849         }
850
851 #if 0
852         /* ToDo - set allocation. JRA */
853         if(!cli_set_allocation_size(cli1, fnum1, 0)) {
854                 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
855                 return False;
856         }
857         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
858                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
859                 correct = False;
860         }
861         if (fsize != 0)
862                 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
863 #endif
864
865         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
866                 printf("close failed (%s)\n", cli_errstr(cli1));
867                 correct = False;
868         }
869
870         if (!torture_close_connection(cli1)) {
871                 correct = False;
872         }
873         return correct;
874 }
875
876 int line_count = 0;
877 int nbio_id;
878
879 #define ival(s) strtol(s, NULL, 0)
880
881 /* run a test that simulates an approximate netbench client load */
882 static bool run_netbench(int client)
883 {
884         struct cli_state *cli;
885         int i;
886         char line[1024];
887         char cname[20];
888         FILE *f;
889         const char *params[20];
890         bool correct = True;
891
892         cli = current_cli;
893
894         nbio_id = client;
895
896         cli_sockopt(cli, sockops);
897
898         nb_setup(cli);
899
900         slprintf(cname,sizeof(cname)-1, "client%d", client);
901
902         f = fopen(client_txt, "r");
903
904         if (!f) {
905                 perror(client_txt);
906                 return False;
907         }
908
909         while (fgets(line, sizeof(line)-1, f)) {
910                 char *saveptr;
911                 line_count++;
912
913                 line[strlen(line)-1] = 0;
914
915                 /* printf("[%d] %s\n", line_count, line); */
916
917                 all_string_sub(line,"client1", cname, sizeof(line));
918
919                 /* parse the command parameters */
920                 params[0] = strtok_r(line, " ", &saveptr);
921                 i = 0;
922                 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
923
924                 params[i] = "";
925
926                 if (i < 2) continue;
927
928                 if (!strncmp(params[0],"SMB", 3)) {
929                         printf("ERROR: You are using a dbench 1 load file\n");
930                         exit(1);
931                 }
932
933                 if (!strcmp(params[0],"NTCreateX")) {
934                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
935                                    ival(params[4]));
936                 } else if (!strcmp(params[0],"Close")) {
937                         nb_close(ival(params[1]));
938                 } else if (!strcmp(params[0],"Rename")) {
939                         nb_rename(params[1], params[2]);
940                 } else if (!strcmp(params[0],"Unlink")) {
941                         nb_unlink(params[1]);
942                 } else if (!strcmp(params[0],"Deltree")) {
943                         nb_deltree(params[1]);
944                 } else if (!strcmp(params[0],"Rmdir")) {
945                         nb_rmdir(params[1]);
946                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
947                         nb_qpathinfo(params[1]);
948                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
949                         nb_qfileinfo(ival(params[1]));
950                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
951                         nb_qfsinfo(ival(params[1]));
952                 } else if (!strcmp(params[0],"FIND_FIRST")) {
953                         nb_findfirst(params[1]);
954                 } else if (!strcmp(params[0],"WriteX")) {
955                         nb_writex(ival(params[1]), 
956                                   ival(params[2]), ival(params[3]), ival(params[4]));
957                 } else if (!strcmp(params[0],"ReadX")) {
958                         nb_readx(ival(params[1]), 
959                                   ival(params[2]), ival(params[3]), ival(params[4]));
960                 } else if (!strcmp(params[0],"Flush")) {
961                         nb_flush(ival(params[1]));
962                 } else {
963                         printf("Unknown operation %s\n", params[0]);
964                         exit(1);
965                 }
966         }
967         fclose(f);
968
969         nb_cleanup();
970
971         if (!torture_close_connection(cli)) {
972                 correct = False;
973         }
974
975         return correct;
976 }
977
978
979 /* run a test that simulates an approximate netbench client load */
980 static bool run_nbench(int dummy)
981 {
982         double t;
983         bool correct = True;
984
985         nbio_shmem(nprocs);
986
987         nbio_id = -1;
988
989         signal(SIGALRM, nb_alarm);
990         alarm(1);
991         t = create_procs(run_netbench, &correct);
992         alarm(0);
993
994         printf("\nThroughput %g MB/sec\n", 
995                1.0e-6 * nbio_total() / t);
996         return correct;
997 }
998
999
1000 /*
1001   This test checks for two things:
1002
1003   1) correct support for retaining locks over a close (ie. the server
1004      must not use posix semantics)
1005   2) support for lock timeouts
1006  */
1007 static bool run_locktest1(int dummy)
1008 {
1009         struct cli_state *cli1, *cli2;
1010         const char *fname = "\\lockt1.lck";
1011         uint16_t fnum1, fnum2, fnum3;
1012         time_t t1, t2;
1013         unsigned lock_timeout;
1014
1015         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1016                 return False;
1017         }
1018         cli_sockopt(cli1, sockops);
1019         cli_sockopt(cli2, sockops);
1020
1021         printf("starting locktest1\n");
1022
1023         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1024
1025         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1026                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1027                 return False;
1028         }
1029         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1030                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1031                 return False;
1032         }
1033         if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1034                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1035                 return False;
1036         }
1037
1038         if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1039                 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1040                 return False;
1041         }
1042
1043
1044         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1045                 printf("lock2 succeeded! This is a locking bug\n");
1046                 return False;
1047         } else {
1048                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1049                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1050         }
1051
1052
1053         lock_timeout = (1 + (random() % 20));
1054         printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1055         t1 = time(NULL);
1056         if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1057                 printf("lock3 succeeded! This is a locking bug\n");
1058                 return False;
1059         } else {
1060                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1061                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1062         }
1063         t2 = time(NULL);
1064
1065         if (ABS(t2 - t1) < lock_timeout-1) {
1066                 printf("error: This server appears not to support timed lock requests\n");
1067         }
1068
1069         printf("server slept for %u seconds for a %u second timeout\n",
1070                (unsigned int)(t2-t1), lock_timeout);
1071
1072         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1073                 printf("close1 failed (%s)\n", cli_errstr(cli1));
1074                 return False;
1075         }
1076
1077         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1078                 printf("lock4 succeeded! This is a locking bug\n");
1079                 return False;
1080         } else {
1081                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1082                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1083         }
1084
1085         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1086                 printf("close2 failed (%s)\n", cli_errstr(cli1));
1087                 return False;
1088         }
1089
1090         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1091                 printf("close3 failed (%s)\n", cli_errstr(cli2));
1092                 return False;
1093         }
1094
1095         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1096                 printf("unlink failed (%s)\n", cli_errstr(cli1));
1097                 return False;
1098         }
1099
1100
1101         if (!torture_close_connection(cli1)) {
1102                 return False;
1103         }
1104
1105         if (!torture_close_connection(cli2)) {
1106                 return False;
1107         }
1108
1109         printf("Passed locktest1\n");
1110         return True;
1111 }
1112
1113 /*
1114   this checks to see if a secondary tconx can use open files from an
1115   earlier tconx
1116  */
1117 static bool run_tcon_test(int dummy)
1118 {
1119         static struct cli_state *cli;
1120         const char *fname = "\\tcontest.tmp";
1121         uint16 fnum1;
1122         uint16 cnum1, cnum2, cnum3;
1123         uint16 vuid1, vuid2;
1124         char buf[4];
1125         bool ret = True;
1126         NTSTATUS status;
1127
1128         memset(buf, '\0', sizeof(buf));
1129
1130         if (!torture_open_connection(&cli, 0)) {
1131                 return False;
1132         }
1133         cli_sockopt(cli, sockops);
1134
1135         printf("starting tcontest\n");
1136
1137         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1138
1139         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1140                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1141                 return False;
1142         }
1143
1144         cnum1 = cli->cnum;
1145         vuid1 = cli->vuid;
1146
1147         if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1148                 printf("initial write failed (%s)", cli_errstr(cli));
1149                 return False;
1150         }
1151
1152         status = cli_tcon_andx(cli, share, "?????",
1153                                password, strlen(password)+1);
1154         if (!NT_STATUS_IS_OK(status)) {
1155                 printf("%s refused 2nd tree connect (%s)\n", host,
1156                        nt_errstr(status));
1157                 cli_shutdown(cli);
1158                 return False;
1159         }
1160
1161         cnum2 = cli->cnum;
1162         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1163         vuid2 = cli->vuid + 1;
1164
1165         /* try a write with the wrong tid */
1166         cli->cnum = cnum2;
1167
1168         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1169                 printf("* server allows write with wrong TID\n");
1170                 ret = False;
1171         } else {
1172                 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1173         }
1174
1175
1176         /* try a write with an invalid tid */
1177         cli->cnum = cnum3;
1178
1179         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1180                 printf("* server allows write with invalid TID\n");
1181                 ret = False;
1182         } else {
1183                 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1184         }
1185
1186         /* try a write with an invalid vuid */
1187         cli->vuid = vuid2;
1188         cli->cnum = cnum1;
1189
1190         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1191                 printf("* server allows write with invalid VUID\n");
1192                 ret = False;
1193         } else {
1194                 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1195         }
1196
1197         cli->cnum = cnum1;
1198         cli->vuid = vuid1;
1199
1200         if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1201                 printf("close failed (%s)\n", cli_errstr(cli));
1202                 return False;
1203         }
1204
1205         cli->cnum = cnum2;
1206
1207         status = cli_tdis(cli);
1208         if (!NT_STATUS_IS_OK(status)) {
1209                 printf("secondary tdis failed (%s)\n", nt_errstr(status));
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         struct timeval start;
2279         double seconds;
2280         NTSTATUS status;
2281
2282         printf("starting locktest9\n");
2283
2284         if (local_path == NULL) {
2285                 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2286                 return false;
2287         }
2288
2289         if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2290                 return false;
2291         }
2292
2293         child_pid = fork();
2294         if (child_pid == -1) {
2295                 return false;
2296         }
2297
2298         if (child_pid == 0) {
2299                 /* Child. */
2300                 do_local_lock(pipe_out[0], pipe_in[1]);
2301                 exit(0);
2302         }
2303
2304         close(pipe_out[0]);
2305         close(pipe_in[1]);
2306         pipe_out[0] = -1;
2307         pipe_in[1] = -1;
2308
2309         /* Parent. */
2310         ret = read(pipe_in[0], &c, 1);
2311         if (ret != 1) {
2312                 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2313                         strerror(errno));
2314                 return false;
2315         }
2316
2317         if (!torture_open_connection(&cli1, 0)) {
2318                 return false;
2319         }
2320
2321         cli_sockopt(cli1, sockops);
2322
2323         status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2324                           &fnum);
2325         if (!NT_STATUS_IS_OK(status)) {
2326                 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2327                 return false;
2328         }
2329
2330         /* Ensure the child has the lock. */
2331         if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2332                 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2333                 goto fail;
2334         } else {
2335                 d_printf("Child has the lock.\n");
2336         }
2337
2338         /* Tell the child to wait 5 seconds then exit. */
2339         ret = write(pipe_out[1], &c, 1);
2340         if (ret != 1) {
2341                 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2342                         strerror(errno));
2343                 goto fail;
2344         }
2345
2346         /* Wait 20 seconds for the lock. */
2347         alarm_fd = cli1->fd;
2348         CatchSignal(SIGALRM, alarm_handler_parent);
2349         alarm(20);
2350
2351         start = timeval_current();
2352
2353         if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2354                 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2355                        "%s\n", cli_errstr(cli1));
2356                 goto fail_nofd;
2357         }
2358         alarm(0);
2359
2360         seconds = timeval_elapsed(&start);
2361
2362         printf("Parent got the lock after %.2f seconds.\n",
2363                 seconds);
2364
2365         status = cli_close(cli1, fnum);
2366         if (!NT_STATUS_IS_OK(status)) {
2367                 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2368                 goto fail;
2369         }
2370
2371         correct = true;
2372
2373 fail:
2374         cli_close(cli1, fnum);
2375         torture_close_connection(cli1);
2376
2377 fail_nofd:
2378
2379         printf("finished locktest9\n");
2380         return correct;
2381 }
2382
2383 /*
2384 test whether fnums and tids open on one VC are available on another (a major
2385 security hole)
2386 */
2387 static bool run_fdpasstest(int dummy)
2388 {
2389         struct cli_state *cli1, *cli2;
2390         const char *fname = "\\fdpass.tst";
2391         uint16_t fnum1;
2392         char buf[1024];
2393
2394         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2395                 return False;
2396         }
2397         cli_sockopt(cli1, sockops);
2398         cli_sockopt(cli2, sockops);
2399
2400         printf("starting fdpasstest\n");
2401
2402         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2403
2404         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2405                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2406                 return False;
2407         }
2408
2409         if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2410                 printf("write failed (%s)\n", cli_errstr(cli1));
2411                 return False;
2412         }
2413
2414         cli2->vuid = cli1->vuid;
2415         cli2->cnum = cli1->cnum;
2416         cli2->pid = cli1->pid;
2417
2418         if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2419                 printf("read succeeded! nasty security hole [%s]\n",
2420                        buf);
2421                 return False;
2422         }
2423
2424         cli_close(cli1, fnum1);
2425         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2426
2427         torture_close_connection(cli1);
2428         torture_close_connection(cli2);
2429
2430         printf("finished fdpasstest\n");
2431         return True;
2432 }
2433
2434 static bool run_fdsesstest(int dummy)
2435 {
2436         struct cli_state *cli;
2437         uint16 new_vuid;
2438         uint16 saved_vuid;
2439         uint16 new_cnum;
2440         uint16 saved_cnum;
2441         const char *fname = "\\fdsess.tst";
2442         const char *fname1 = "\\fdsess1.tst";
2443         uint16_t fnum1;
2444         uint16_t fnum2;
2445         char buf[1024];
2446         bool ret = True;
2447
2448         if (!torture_open_connection(&cli, 0))
2449                 return False;
2450         cli_sockopt(cli, sockops);
2451
2452         if (!torture_cli_session_setup2(cli, &new_vuid))
2453                 return False;
2454
2455         saved_cnum = cli->cnum;
2456         if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2457                 return False;
2458         new_cnum = cli->cnum;
2459         cli->cnum = saved_cnum;
2460
2461         printf("starting fdsesstest\n");
2462
2463         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2464         cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2465
2466         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2467                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2468                 return False;
2469         }
2470
2471         if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2472                 printf("write failed (%s)\n", cli_errstr(cli));
2473                 return False;
2474         }
2475
2476         saved_vuid = cli->vuid;
2477         cli->vuid = new_vuid;
2478
2479         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2480                 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2481                        buf);
2482                 ret = False;
2483         }
2484         /* Try to open a file with different vuid, samba cnum. */
2485         if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2486                 printf("create with different vuid, same cnum succeeded.\n");
2487                 cli_close(cli, fnum2);
2488                 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2489         } else {
2490                 printf("create with different vuid, same cnum failed.\n");
2491                 printf("This will cause problems with service clients.\n");
2492                 ret = False;
2493         }
2494
2495         cli->vuid = saved_vuid;
2496
2497         /* Try with same vuid, different cnum. */
2498         cli->cnum = new_cnum;
2499
2500         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2501                 printf("read succeeded with different cnum![%s]\n",
2502                        buf);
2503                 ret = False;
2504         }
2505
2506         cli->cnum = saved_cnum;
2507         cli_close(cli, fnum1);
2508         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2509
2510         torture_close_connection(cli);
2511
2512         printf("finished fdsesstest\n");
2513         return ret;
2514 }
2515
2516 /*
2517   This test checks that 
2518
2519   1) the server does not allow an unlink on a file that is open
2520 */
2521 static bool run_unlinktest(int dummy)
2522 {
2523         struct cli_state *cli;
2524         const char *fname = "\\unlink.tst";
2525         uint16_t fnum;
2526         bool correct = True;
2527
2528         if (!torture_open_connection(&cli, 0)) {
2529                 return False;
2530         }
2531
2532         cli_sockopt(cli, sockops);
2533
2534         printf("starting unlink test\n");
2535
2536         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2537
2538         cli_setpid(cli, 1);
2539
2540         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2541                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2542                 return False;
2543         }
2544
2545         if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2546                 printf("error: server allowed unlink on an open file\n");
2547                 correct = False;
2548         } else {
2549                 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare, 
2550                                       NT_STATUS_SHARING_VIOLATION);
2551         }
2552
2553         cli_close(cli, fnum);
2554         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2555
2556         if (!torture_close_connection(cli)) {
2557                 correct = False;
2558         }
2559
2560         printf("unlink test finished\n");
2561
2562         return correct;
2563 }
2564
2565
2566 /*
2567 test how many open files this server supports on the one socket
2568 */
2569 static bool run_maxfidtest(int dummy)
2570 {
2571         struct cli_state *cli;
2572         const char *ftemplate = "\\maxfid.%d.%d";
2573         fstring fname;
2574         uint16_t fnums[0x11000];
2575         int i;
2576         int retries=4;
2577         bool correct = True;
2578
2579         cli = current_cli;
2580
2581         if (retries <= 0) {
2582                 printf("failed to connect\n");
2583                 return False;
2584         }
2585
2586         cli_sockopt(cli, sockops);
2587
2588         for (i=0; i<0x11000; i++) {
2589                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2590                 if (!NT_STATUS_IS_OK(cli_open(cli, fname, 
2591                                         O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2592                         printf("open of %s failed (%s)\n", 
2593                                fname, cli_errstr(cli));
2594                         printf("maximum fnum is %d\n", i);
2595                         break;
2596                 }
2597                 printf("%6d\r", i);
2598         }
2599         printf("%6d\n", i);
2600         i--;
2601
2602         printf("cleaning up\n");
2603         for (;i>=0;i--) {
2604                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2605                 cli_close(cli, fnums[i]);
2606                 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2607                         printf("unlink of %s failed (%s)\n", 
2608                                fname, cli_errstr(cli));
2609                         correct = False;
2610                 }
2611                 printf("%6d\r", i);
2612         }
2613         printf("%6d\n", 0);
2614
2615         printf("maxfid test finished\n");
2616         if (!torture_close_connection(cli)) {
2617                 correct = False;
2618         }
2619         return correct;
2620 }
2621
2622 /* generate a random buffer */
2623 static void rand_buf(char *buf, int len)
2624 {
2625         while (len--) {
2626                 *buf = (char)sys_random();
2627                 buf++;
2628         }
2629 }
2630
2631 /* send smb negprot commands, not reading the response */
2632 static bool run_negprot_nowait(int dummy)
2633 {
2634         int i;
2635         static struct cli_state *cli;
2636         bool correct = True;
2637
2638         printf("starting negprot nowait test\n");
2639
2640         if (!(cli = open_nbt_connection())) {
2641                 return False;
2642         }
2643
2644         for (i=0;i<50000;i++) {
2645                 cli_negprot_sendsync(cli);
2646         }
2647
2648         if (!torture_close_connection(cli)) {
2649                 correct = False;
2650         }
2651
2652         printf("finished negprot nowait test\n");
2653
2654         return correct;
2655 }
2656
2657
2658 /* send random IPC commands */
2659 static bool run_randomipc(int dummy)
2660 {
2661         char *rparam = NULL;
2662         char *rdata = NULL;
2663         unsigned int rdrcnt,rprcnt;
2664         char param[1024];
2665         int api, param_len, i;
2666         struct cli_state *cli;
2667         bool correct = True;
2668         int count = 50000;
2669
2670         printf("starting random ipc test\n");
2671
2672         if (!torture_open_connection(&cli, 0)) {
2673                 return False;
2674         }
2675
2676         for (i=0;i<count;i++) {
2677                 api = sys_random() % 500;
2678                 param_len = (sys_random() % 64);
2679
2680                 rand_buf(param, param_len);
2681
2682                 SSVAL(param,0,api); 
2683
2684                 cli_api(cli, 
2685                         param, param_len, 8,  
2686                         NULL, 0, BUFFER_SIZE, 
2687                         &rparam, &rprcnt,     
2688                         &rdata, &rdrcnt);
2689                 if (i % 100 == 0) {
2690                         printf("%d/%d\r", i,count);
2691                 }
2692         }
2693         printf("%d/%d\n", i, count);
2694
2695         if (!torture_close_connection(cli)) {
2696                 correct = False;
2697         }
2698
2699         printf("finished random ipc test\n");
2700
2701         return correct;
2702 }
2703
2704
2705
2706 static void browse_callback(const char *sname, uint32 stype, 
2707                             const char *comment, void *state)
2708 {
2709         printf("\t%20.20s %08x %s\n", sname, stype, comment);
2710 }
2711
2712
2713
2714 /*
2715   This test checks the browse list code
2716
2717 */
2718 static bool run_browsetest(int dummy)
2719 {
2720         static struct cli_state *cli;
2721         bool correct = True;
2722
2723         printf("starting browse test\n");
2724
2725         if (!torture_open_connection(&cli, 0)) {
2726                 return False;
2727         }
2728
2729         printf("domain list:\n");
2730         cli_NetServerEnum(cli, cli->server_domain, 
2731                           SV_TYPE_DOMAIN_ENUM,
2732                           browse_callback, NULL);
2733
2734         printf("machine list:\n");
2735         cli_NetServerEnum(cli, cli->server_domain, 
2736                           SV_TYPE_ALL,
2737                           browse_callback, NULL);
2738
2739         if (!torture_close_connection(cli)) {
2740                 correct = False;
2741         }
2742
2743         printf("browse test finished\n");
2744
2745         return correct;
2746
2747 }
2748
2749
2750 /*
2751   This checks how the getatr calls works
2752 */
2753 static bool run_attrtest(int dummy)
2754 {
2755         struct cli_state *cli;
2756         uint16_t fnum;
2757         time_t t, t2;
2758         const char *fname = "\\attrib123456789.tst";
2759         bool correct = True;
2760
2761         printf("starting attrib test\n");
2762
2763         if (!torture_open_connection(&cli, 0)) {
2764                 return False;
2765         }
2766
2767         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2768         cli_open(cli, fname, 
2769                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2770         cli_close(cli, fnum);
2771         if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2772                 printf("getatr failed (%s)\n", cli_errstr(cli));
2773                 correct = False;
2774         }
2775
2776         if (abs(t - time(NULL)) > 60*60*24*10) {
2777                 printf("ERROR: SMBgetatr bug. time is %s",
2778                        ctime(&t));
2779                 t = time(NULL);
2780                 correct = True;
2781         }
2782
2783         t2 = t-60*60*24; /* 1 day ago */
2784
2785         if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2786                 printf("setatr failed (%s)\n", cli_errstr(cli));
2787                 correct = True;
2788         }
2789
2790         if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2791                 printf("getatr failed (%s)\n", cli_errstr(cli));
2792                 correct = True;
2793         }
2794
2795         if (t != t2) {
2796                 printf("ERROR: getatr/setatr bug. times are\n%s",
2797                        ctime(&t));
2798                 printf("%s", ctime(&t2));
2799                 correct = True;
2800         }
2801
2802         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2803
2804         if (!torture_close_connection(cli)) {
2805                 correct = False;
2806         }
2807
2808         printf("attrib test finished\n");
2809
2810         return correct;
2811 }
2812
2813
2814 /*
2815   This checks a couple of trans2 calls
2816 */
2817 static bool run_trans2test(int dummy)
2818 {
2819         struct cli_state *cli;
2820         uint16_t fnum;
2821         SMB_OFF_T size;
2822         time_t c_time, a_time, m_time;
2823         struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2824         const char *fname = "\\trans2.tst";
2825         const char *dname = "\\trans2";
2826         const char *fname2 = "\\trans2\\trans2.tst";
2827         char pname[1024];
2828         bool correct = True;
2829         NTSTATUS status;
2830         uint32_t fs_attr;
2831
2832         printf("starting trans2 test\n");
2833
2834         if (!torture_open_connection(&cli, 0)) {
2835                 return False;
2836         }
2837
2838         status = cli_get_fs_attr_info(cli, &fs_attr);
2839         if (!NT_STATUS_IS_OK(status)) {
2840                 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2841                        nt_errstr(status));
2842                 correct = false;
2843         }
2844
2845         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2846         cli_open(cli, fname, 
2847                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2848         if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2849                            &m_time_ts, NULL)) {
2850                 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2851                 correct = False;
2852         }
2853
2854         if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2855                 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2856                 correct = False;
2857         }
2858
2859         if (strcmp(pname, fname)) {
2860                 printf("qfilename gave different name? [%s] [%s]\n",
2861                        fname, pname);
2862                 correct = False;
2863         }
2864
2865         cli_close(cli, fnum);
2866
2867         sleep(2);
2868
2869         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2870         if (!NT_STATUS_IS_OK(cli_open(cli, fname, 
2871                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
2872                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2873                 return False;
2874         }
2875         cli_close(cli, fnum);
2876
2877         status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
2878                                 NULL);
2879         if (!NT_STATUS_IS_OK(status)) {
2880                 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
2881                 correct = False;
2882         } else {
2883                 if (c_time != m_time) {
2884                         printf("create time=%s", ctime(&c_time));
2885                         printf("modify time=%s", ctime(&m_time));
2886                         printf("This system appears to have sticky create times\n");
2887                 }
2888                 if (a_time % (60*60) == 0) {
2889                         printf("access time=%s", ctime(&a_time));
2890                         printf("This system appears to set a midnight access time\n");
2891                         correct = False;
2892                 }
2893
2894                 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2895                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2896                         correct = False;
2897                 }
2898         }
2899
2900
2901         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2902         cli_open(cli, fname, 
2903                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2904         cli_close(cli, fnum);
2905         status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2906                                 &m_time_ts, &size, NULL, NULL);
2907         if (!NT_STATUS_IS_OK(status)) {
2908                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2909                 correct = False;
2910         } else {
2911                 if (w_time_ts.tv_sec < 60*60*24*2) {
2912                         printf("write time=%s", ctime(&w_time_ts.tv_sec));
2913                         printf("This system appears to set a initial 0 write time\n");
2914                         correct = False;
2915                 }
2916         }
2917
2918         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2919
2920
2921         /* check if the server updates the directory modification time
2922            when creating a new file */
2923         if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
2924                 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2925                 correct = False;
2926         }
2927         sleep(3);
2928         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
2929                                 &w_time_ts, &m_time_ts, &size, NULL, NULL);
2930         if (!NT_STATUS_IS_OK(status)) {
2931                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2932                 correct = False;
2933         }
2934
2935         cli_open(cli, fname2, 
2936                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2937         cli_write(cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
2938         cli_close(cli, fnum);
2939         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
2940                                 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
2941         if (!NT_STATUS_IS_OK(status)) {
2942                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2943                 correct = False;
2944         } else {
2945                 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2946                     == 0) {
2947                         printf("This system does not update directory modification times\n");
2948                         correct = False;
2949                 }
2950         }
2951         cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
2952         cli_rmdir(cli, dname);
2953
2954         if (!torture_close_connection(cli)) {
2955                 correct = False;
2956         }
2957
2958         printf("trans2 test finished\n");
2959
2960         return correct;
2961 }
2962
2963 /*
2964   This checks new W2K calls.
2965 */
2966
2967 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2968 {
2969         char *buf = NULL;
2970         uint32 len;
2971         bool correct = True;
2972
2973         if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2974                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2975                 correct = False;
2976         } else {
2977                 printf("qfileinfo: level %d, len = %u\n", level, len);
2978                 dump_data(0, (uint8 *)buf, len);
2979                 printf("\n");
2980         }
2981         SAFE_FREE(buf);
2982         return correct;
2983 }
2984
2985 static bool run_w2ktest(int dummy)
2986 {
2987         struct cli_state *cli;
2988         uint16_t fnum;
2989         const char *fname = "\\w2ktest\\w2k.tst";
2990         int level;
2991         bool correct = True;
2992
2993         printf("starting w2k test\n");
2994
2995         if (!torture_open_connection(&cli, 0)) {
2996                 return False;
2997         }
2998
2999         cli_open(cli, fname, 
3000                         O_RDWR | O_CREAT , DENY_NONE, &fnum);
3001
3002         for (level = 1004; level < 1040; level++) {
3003                 new_trans(cli, fnum, level);
3004         }
3005
3006         cli_close(cli, fnum);
3007
3008         if (!torture_close_connection(cli)) {
3009                 correct = False;
3010         }
3011
3012         printf("w2k test finished\n");
3013
3014         return correct;
3015 }
3016
3017
3018 /*
3019   this is a harness for some oplock tests
3020  */
3021 static bool run_oplock1(int dummy)
3022 {
3023         struct cli_state *cli1;
3024         const char *fname = "\\lockt1.lck";
3025         uint16_t fnum1;
3026         bool correct = True;
3027
3028         printf("starting oplock test 1\n");
3029
3030         if (!torture_open_connection(&cli1, 0)) {
3031                 return False;
3032         }
3033
3034         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3035
3036         cli_sockopt(cli1, sockops);
3037
3038         cli1->use_oplocks = True;
3039
3040         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3041                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3042                 return False;
3043         }
3044
3045         cli1->use_oplocks = False;
3046
3047         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3048         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3049
3050         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3051                 printf("close2 failed (%s)\n", cli_errstr(cli1));
3052                 return False;
3053         }
3054
3055         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3056                 printf("unlink failed (%s)\n", cli_errstr(cli1));
3057                 return False;
3058         }
3059
3060         if (!torture_close_connection(cli1)) {
3061                 correct = False;
3062         }
3063
3064         printf("finished oplock test 1\n");
3065
3066         return correct;
3067 }
3068
3069 static bool run_oplock2(int dummy)
3070 {
3071         struct cli_state *cli1, *cli2;
3072         const char *fname = "\\lockt2.lck";
3073         uint16_t fnum1, fnum2;
3074         int saved_use_oplocks = use_oplocks;
3075         char buf[4];
3076         bool correct = True;
3077         volatile bool *shared_correct;
3078
3079         shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3080         *shared_correct = True;
3081
3082         use_level_II_oplocks = True;
3083         use_oplocks = True;
3084
3085         printf("starting oplock test 2\n");
3086
3087         if (!torture_open_connection(&cli1, 0)) {
3088                 use_level_II_oplocks = False;
3089                 use_oplocks = saved_use_oplocks;
3090                 return False;
3091         }
3092
3093         cli1->use_oplocks = True;
3094         cli1->use_level_II_oplocks = True;
3095
3096         if (!torture_open_connection(&cli2, 1)) {
3097                 use_level_II_oplocks = False;
3098                 use_oplocks = saved_use_oplocks;
3099                 return False;
3100         }
3101
3102         cli2->use_oplocks = True;
3103         cli2->use_level_II_oplocks = True;
3104
3105         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3106
3107         cli_sockopt(cli1, sockops);
3108         cli_sockopt(cli2, sockops);
3109
3110         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3111                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3112                 return False;
3113         }
3114
3115         /* Don't need the globals any more. */
3116         use_level_II_oplocks = False;
3117         use_oplocks = saved_use_oplocks;
3118
3119         if (fork() == 0) {
3120                 /* Child code */
3121                 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3122                         printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3123                         *shared_correct = False;
3124                         exit(0);
3125                 }
3126
3127                 sleep(2);
3128
3129                 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3130                         printf("close2 failed (%s)\n", cli_errstr(cli1));
3131                         *shared_correct = False;
3132                 }
3133
3134                 exit(0);
3135         }
3136
3137         sleep(2);
3138
3139         /* Ensure cli1 processes the break. Empty file should always return 0
3140          * bytes.  */
3141
3142         if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3143                 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3144                 correct = False;
3145         }
3146
3147         /* Should now be at level II. */
3148         /* Test if sending a write locks causes a break to none. */
3149
3150         if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3151                 printf("lock failed (%s)\n", cli_errstr(cli1));
3152                 correct = False;
3153         }
3154
3155         cli_unlock(cli1, fnum1, 0, 4);
3156
3157         sleep(2);
3158
3159         if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3160                 printf("lock failed (%s)\n", cli_errstr(cli1));
3161                 correct = False;
3162         }
3163
3164         cli_unlock(cli1, fnum1, 0, 4);
3165
3166         sleep(2);
3167
3168         cli_read(cli1, fnum1, buf, 0, 4);
3169
3170 #if 0
3171         if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3172                 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3173                 correct = False;
3174         }
3175 #endif
3176
3177         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3178                 printf("close1 failed (%s)\n", cli_errstr(cli1));
3179                 correct = False;
3180         }
3181
3182         sleep(4);
3183
3184         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3185                 printf("unlink failed (%s)\n", cli_errstr(cli1));
3186                 correct = False;
3187         }
3188
3189         if (!torture_close_connection(cli1)) {
3190                 correct = False;
3191         }
3192
3193         if (!*shared_correct) {
3194                 correct = False;
3195         }
3196
3197         printf("finished oplock test 2\n");
3198
3199         return correct;
3200 }
3201
3202 /* handler for oplock 3 tests */
3203 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3204 {
3205         printf("got oplock break fnum=%d level=%d\n",
3206                fnum, level);
3207         return cli_oplock_ack(cli, fnum, level);
3208 }
3209
3210 static bool run_oplock3(int dummy)
3211 {
3212         struct cli_state *cli;
3213         const char *fname = "\\oplockt3.dat";
3214         uint16_t fnum;
3215         char buf[4] = "abcd";
3216         bool correct = True;
3217         volatile bool *shared_correct;
3218
3219         shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3220         *shared_correct = True;
3221
3222         printf("starting oplock test 3\n");
3223
3224         if (fork() == 0) {
3225                 /* Child code */
3226                 use_oplocks = True;
3227                 use_level_II_oplocks = True;
3228                 if (!torture_open_connection(&cli, 0)) {
3229                         *shared_correct = False;
3230                         exit(0);
3231                 } 
3232                 sleep(2);
3233                 /* try to trigger a oplock break in parent */
3234                 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3235                 cli_write(cli, fnum, 0, buf, 0, 4);
3236                 exit(0);
3237         }
3238
3239         /* parent code */
3240         use_oplocks = True;
3241         use_level_II_oplocks = True;
3242         if (!torture_open_connection(&cli, 1)) { /* other is forked */
3243                 return False;
3244         }
3245         cli_oplock_handler(cli, oplock3_handler);
3246         cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3247         cli_write(cli, fnum, 0, buf, 0, 4);
3248         cli_close(cli, fnum);
3249         cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3250         cli->timeout = 20000;
3251         cli_receive_smb(cli);
3252         printf("finished oplock test 3\n");
3253
3254         return (correct && *shared_correct);
3255
3256 /* What are we looking for here?  What's sucess and what's FAILURE? */
3257 }
3258
3259
3260
3261 /*
3262   Test delete on close semantics.
3263  */
3264 static bool run_deletetest(int dummy)
3265 {
3266         struct cli_state *cli1 = NULL;
3267         struct cli_state *cli2 = NULL;
3268         const char *fname = "\\delete.file";
3269         uint16_t fnum1 = (uint16_t)-1;
3270         uint16_t fnum2 = (uint16_t)-1;
3271         bool correct = True;
3272
3273         printf("starting delete test\n");
3274
3275         if (!torture_open_connection(&cli1, 0)) {
3276                 return False;
3277         }
3278
3279         cli_sockopt(cli1, sockops);
3280
3281         /* Test 1 - this should delete the file on close. */
3282
3283         cli_setatr(cli1, fname, 0, 0);
3284         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3285
3286         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3287                                    0, FILE_OVERWRITE_IF, 
3288                                    FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3289                 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3290                 correct = False;
3291                 goto fail;
3292         }
3293
3294 #if 0 /* JRATEST */
3295         {
3296                 uint32 *accinfo = NULL;
3297                 uint32 len;
3298                 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3299                 if (accinfo)
3300                         printf("access mode = 0x%lx\n", *accinfo);
3301                 SAFE_FREE(accinfo);
3302         }
3303 #endif
3304
3305         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3306                 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3307                 correct = False;
3308                 goto fail;
3309         }
3310
3311         if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3312                 printf("[1] open of %s succeeded (should fail)\n", fname);
3313                 correct = False;
3314                 goto fail;
3315         }
3316
3317         printf("first delete on close test succeeded.\n");
3318
3319         /* Test 2 - this should delete the file on close. */
3320
3321         cli_setatr(cli1, fname, 0, 0);
3322         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3323
3324         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3325                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, 
3326                                    FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3327                 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3328                 correct = False;
3329                 goto fail;
3330         }
3331
3332         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3333                 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3334                 correct = False;
3335                 goto fail;
3336         }
3337
3338         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3339                 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3340                 correct = False;
3341                 goto fail;
3342         }
3343
3344         if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3345                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3346                 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3347                         printf("[2] close failed (%s)\n", cli_errstr(cli1));
3348                         correct = False;
3349                         goto fail;
3350                 }
3351                 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3352         } else
3353                 printf("second delete on close test succeeded.\n");
3354
3355         /* Test 3 - ... */
3356         cli_setatr(cli1, fname, 0, 0);
3357         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3358
3359         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3360                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3361                 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3362                 correct = False;
3363                 goto fail;
3364         }
3365
3366         /* This should fail with a sharing violation - open for delete is only compatible
3367            with SHARE_DELETE. */
3368
3369         if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3370                         FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3371                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
3372                 correct = False;
3373                 goto fail;
3374         }
3375
3376         /* This should succeed. */
3377
3378         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3379                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3380                 printf("[3] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3381                 correct = False;
3382                 goto fail;
3383         }
3384
3385         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3386                 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3387                 correct = False;
3388                 goto fail;
3389         }
3390
3391         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3392                 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3393                 correct = False;
3394                 goto fail;
3395         }
3396
3397         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3398                 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3399                 correct = False;
3400                 goto fail;
3401         }
3402
3403         /* This should fail - file should no longer be there. */
3404
3405         if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3406                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3407                 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3408                         printf("[3] close failed (%s)\n", cli_errstr(cli1));
3409                 }
3410                 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3411                 correct = False;
3412                 goto fail;
3413         } else
3414                 printf("third delete on close test succeeded.\n");
3415
3416         /* Test 4 ... */
3417         cli_setatr(cli1, fname, 0, 0);
3418         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3419
3420         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3421                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3422                 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3423                 correct = False;
3424                 goto fail;
3425         }
3426
3427         /* This should succeed. */
3428         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3429                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3430                 printf("[4] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3431                 correct = False;
3432                 goto fail;
3433         }
3434
3435         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3436                 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3437                 correct = False;
3438                 goto fail;
3439         }
3440
3441         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3442                 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3443                 correct = False;
3444                 goto fail;
3445         }
3446
3447         /* This should fail - no more opens once delete on close set. */
3448         if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3449                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3450                                    FILE_OPEN, 0, 0, &fnum2))) {
3451                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
3452                 correct = False;
3453                 goto fail;
3454         } else
3455                 printf("fourth delete on close test succeeded.\n");
3456
3457         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3458                 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3459                 correct = False;
3460                 goto fail;
3461         }
3462
3463         /* Test 5 ... */
3464         cli_setatr(cli1, fname, 0, 0);
3465         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3466
3467         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3468                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3469                 correct = False;
3470                 goto fail;
3471         }
3472
3473         /* This should fail - only allowed on NT opens with DELETE access. */
3474
3475         if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3476                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3477                 correct = False;
3478                 goto fail;
3479         }
3480
3481         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3482                 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3483                 correct = False;
3484                 goto fail;
3485         }
3486
3487         printf("fifth delete on close test succeeded.\n");
3488
3489         /* Test 6 ... */
3490         cli_setatr(cli1, fname, 0, 0);
3491         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3492
3493         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3494                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3495                                    FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3496                 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3497                 correct = False;
3498                 goto fail;
3499         }
3500
3501         /* This should fail - only allowed on NT opens with DELETE access. */
3502
3503         if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3504                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3505                 correct = False;
3506                 goto fail;
3507         }
3508
3509         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3510                 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3511                 correct = False;
3512                 goto fail;
3513         }
3514
3515         printf("sixth delete on close test succeeded.\n");
3516
3517         /* Test 7 ... */
3518         cli_setatr(cli1, fname, 0, 0);
3519         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3520
3521         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3522                                    FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3523                 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3524                 correct = False;
3525                 goto fail;
3526         }
3527
3528         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3529                 printf("[7] setting delete_on_close on file failed !\n");
3530                 correct = False;
3531                 goto fail;
3532         }
3533
3534         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3535                 printf("[7] unsetting delete_on_close on file failed !\n");
3536                 correct = False;
3537                 goto fail;
3538         }
3539
3540         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3541                 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3542                 correct = False;
3543                 goto fail;
3544         }
3545
3546         /* This next open should succeed - we reset the flag. */
3547
3548         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3549                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3550                 correct = False;
3551                 goto fail;
3552         }
3553
3554         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3555                 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3556                 correct = False;
3557                 goto fail;
3558         }
3559
3560         printf("seventh delete on close test succeeded.\n");
3561
3562         /* Test 7 ... */
3563         cli_setatr(cli1, fname, 0, 0);
3564         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3565
3566         if (!torture_open_connection(&cli2, 1)) {
3567                 printf("[8] failed to open second connection.\n");
3568                 correct = False;
3569                 goto fail;
3570         }
3571
3572         cli_sockopt(cli1, sockops);
3573
3574         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3575                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3576                                    FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3577                 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3578                 correct = False;
3579                 goto fail;
3580         }
3581
3582         if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3583                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3584                                    FILE_OPEN, 0, 0, &fnum2))) {
3585                 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3586                 correct = False;
3587                 goto fail;
3588         }
3589
3590         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3591                 printf("[8] setting delete_on_close on file failed !\n");
3592                 correct = False;
3593                 goto fail;
3594         }
3595
3596         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3597                 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3598                 correct = False;
3599                 goto fail;
3600         }
3601
3602         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3603                 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3604                 correct = False;
3605                 goto fail;
3606         }
3607
3608         /* This should fail.. */
3609         if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3610                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3611                 goto fail;
3612                 correct = False;
3613         } else
3614                 printf("eighth delete on close test succeeded.\n");
3615