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