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