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