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