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