ae502f280feeafd13702167ec87aaaacd1fc6bf1
[metze/samba/wip.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 #include "lib/util/time.h"
46
47 extern char *optarg;
48 extern int optind;
49
50 fstring host, workgroup, share, password, username, myname;
51 struct cli_credentials *torture_creds;
52 static const char *sockops="TCP_NODELAY";
53 int torture_nprocs=1;
54 static int port_to_use=0;
55 int torture_numops=100;
56 int torture_blocksize=1024*1024;
57 static int procnum; /* records process count number when forking */
58 static struct cli_state *current_cli;
59 static fstring randomfname;
60 static bool use_oplocks;
61 static bool use_level_II_oplocks;
62 static const char *client_txt = "client_oplocks.txt";
63 static bool disable_spnego;
64 static bool use_kerberos;
65 static bool force_dos_errors;
66 static fstring multishare_conn_fname;
67 static bool use_multishare_conn = False;
68 static bool do_encrypt;
69 static const char *local_path = NULL;
70 static enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT;
71 char *test_filename;
72
73 bool torture_showall = False;
74
75 static double create_procs(bool (*fn)(int), bool *result);
76
77 /********************************************************************
78  Ensure a connection is encrypted.
79 ********************************************************************/
80
81 static bool force_cli_encryption(struct cli_state *c,
82                         const char *sharename)
83 {
84         uint16_t major, minor;
85         uint32_t caplow, caphigh;
86         NTSTATUS status;
87
88         if (!SERVER_HAS_UNIX_CIFS(c)) {
89                 d_printf("Encryption required and "
90                         "server that doesn't support "
91                         "UNIX extensions - failing connect\n");
92                         return false;
93         }
94
95         status = cli_unix_extensions_version(c, &major, &minor, &caplow,
96                                              &caphigh);
97         if (!NT_STATUS_IS_OK(status)) {
98                 d_printf("Encryption required and "
99                         "can't get UNIX CIFS extensions "
100                         "version from server: %s\n", nt_errstr(status));
101                 return false;
102         }
103
104         if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
105                 d_printf("Encryption required and "
106                         "share %s doesn't support "
107                         "encryption.\n", sharename);
108                 return false;
109         }
110
111         status = cli_smb1_setup_encryption(c, torture_creds);
112         if (!NT_STATUS_IS_OK(status)) {
113                 d_printf("Encryption required and "
114                         "setup failed with error %s.\n",
115                         nt_errstr(status));
116                 return false;
117         }
118
119         return true;
120 }
121
122
123 static struct cli_state *open_nbt_connection(void)
124 {
125         struct cli_state *c;
126         NTSTATUS status;
127         int flags = 0;
128
129         if (disable_spnego) {
130                 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
131         }
132
133         if (use_oplocks) {
134                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
135         }
136
137         if (use_level_II_oplocks) {
138                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
139         }
140
141         if (use_kerberos) {
142                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
143         }
144
145         if (force_dos_errors) {
146                 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
147         }
148
149         status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
150                                 signing_state, flags, &c);
151         if (!NT_STATUS_IS_OK(status)) {
152                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
153                 return NULL;
154         }
155
156         cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
157
158         return c;
159 }
160
161 /****************************************************************************
162  Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
163 ****************************************************************************/
164
165 static bool cli_bad_session_request(int fd,
166                          struct nmb_name *calling, struct nmb_name *called)
167 {
168         TALLOC_CTX *frame;
169         uint8_t len_buf[4];
170         struct iovec iov[3];
171         ssize_t len;
172         uint8_t *inbuf;
173         int err;
174         bool ret = false;
175         uint8_t message_type;
176         uint8_t error;
177         struct tevent_context *ev;
178         struct tevent_req *req;
179
180         frame = talloc_stackframe();
181
182         iov[0].iov_base = len_buf;
183         iov[0].iov_len  = sizeof(len_buf);
184
185         /* put in the destination name */
186
187         iov[1].iov_base = name_mangle(talloc_tos(), called->name,
188                                       called->name_type);
189         if (iov[1].iov_base == NULL) {
190                 goto fail;
191         }
192         iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
193                                   talloc_get_size(iov[1].iov_base));
194
195         /* and my name */
196
197         iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
198                                       calling->name_type);
199         if (iov[2].iov_base == NULL) {
200                 goto fail;
201         }
202         iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
203                                   talloc_get_size(iov[2].iov_base));
204
205         /* Deliberately corrupt the name len (first byte) */
206         *((uint8_t *)iov[2].iov_base) = 100;
207
208         /* send a session request (RFC 1002) */
209         /* setup the packet length
210          * Remove four bytes from the length count, since the length
211          * field in the NBT Session Service header counts the number
212          * of bytes which follow.  The cli_send_smb() function knows
213          * about this and accounts for those four bytes.
214          * CRH.
215          */
216
217         _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
218         SCVAL(len_buf,0,0x81);
219
220         len = write_data_iov(fd, iov, 3);
221         if (len == -1) {
222                 goto fail;
223         }
224
225         ev = samba_tevent_context_init(frame);
226         if (ev == NULL) {
227                 goto fail;
228         }
229         req = read_smb_send(frame, ev, fd);
230         if (req == NULL) {
231                 goto fail;
232         }
233         if (!tevent_req_poll(req, ev)) {
234                 goto fail;
235         }
236         len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
237         if (len == -1) {
238                 errno = err;
239                 goto fail;
240         }
241         TALLOC_FREE(ev);
242
243         message_type = CVAL(inbuf, 0);
244         if (message_type != 0x83) {
245                 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
246                           message_type);
247                 goto fail;
248         }
249
250         if (smb_len(inbuf) != 1) {
251                 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
252                           (int)smb_len(inbuf));
253                 goto fail;
254         }
255
256         error = CVAL(inbuf, 4);
257         if (error !=  0x82) {
258                 d_fprintf(stderr, "Expected error 0x82, got %d\n",
259                           (int)error);
260                 goto fail;
261         }
262
263         ret = true;
264 fail:
265         TALLOC_FREE(frame);
266         return ret;
267 }
268
269 /* Insert a NULL at the first separator of the given path and return a pointer
270  * to the remainder of the string.
271  */
272 static char *
273 terminate_path_at_separator(char * path)
274 {
275         char * p;
276
277         if (!path) {
278                 return NULL;
279         }
280
281         if ((p = strchr_m(path, '/'))) {
282                 *p = '\0';
283                 return p + 1;
284         }
285
286         if ((p = strchr_m(path, '\\'))) {
287                 *p = '\0';
288                 return p + 1;
289         }
290
291         /* No separator. */
292         return NULL;
293 }
294
295 /*
296   parse a //server/share type UNC name
297 */
298 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
299                       char **hostname, char **sharename)
300 {
301         char *p;
302
303         *hostname = *sharename = NULL;
304
305         if (strncmp(unc_name, "\\\\", 2) &&
306             strncmp(unc_name, "//", 2)) {
307                 return False;
308         }
309
310         *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
311         p = terminate_path_at_separator(*hostname);
312
313         if (p && *p) {
314                 *sharename = talloc_strdup(mem_ctx, p);
315                 terminate_path_at_separator(*sharename);
316         }
317
318         if (*hostname && *sharename) {
319                 return True;
320         }
321
322         TALLOC_FREE(*hostname);
323         TALLOC_FREE(*sharename);
324         return False;
325 }
326
327 static bool torture_open_connection_share(struct cli_state **c,
328                                    const char *hostname, 
329                                    const char *sharename,
330                                    int flags)
331 {
332         NTSTATUS status;
333
334         status = cli_full_connection_creds(c,
335                                            myname,
336                                            hostname,
337                                            NULL, /* dest_ss */
338                                            port_to_use,
339                                            sharename,
340                                            "?????",
341                                            torture_creds,
342                                            flags,
343                                            signing_state);
344         if (!NT_STATUS_IS_OK(status)) {
345                 printf("failed to open share connection: //%s/%s port:%d - %s\n",
346                         hostname, sharename, port_to_use, nt_errstr(status));
347                 return False;
348         }
349
350         cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
351
352         if (do_encrypt) {
353                 return force_cli_encryption(*c,
354                                         sharename);
355         }
356         return True;
357 }
358
359 bool torture_open_connection_flags(struct cli_state **c, int conn_index, int flags)
360 {
361         char **unc_list = NULL;
362         int num_unc_names = 0;
363         bool result;
364
365         if (use_multishare_conn==True) {
366                 char *h, *s;
367                 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
368                 if (!unc_list || num_unc_names <= 0) {
369                         printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
370                         exit(1);
371                 }
372
373                 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
374                                       NULL, &h, &s)) {
375                         printf("Failed to parse UNC name %s\n",
376                                unc_list[conn_index % num_unc_names]);
377                         TALLOC_FREE(unc_list);
378                         exit(1);
379                 }
380
381                 result = torture_open_connection_share(c, h, s, flags);
382
383                 /* h, s were copied earlier */
384                 TALLOC_FREE(unc_list);
385                 return result;
386         }
387
388         return torture_open_connection_share(c, host, share, flags);
389 }
390
391 bool torture_open_connection(struct cli_state **c, int conn_index)
392 {
393         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
394
395         if (use_oplocks) {
396                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
397         }
398         if (use_level_II_oplocks) {
399                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
400         }
401
402         return torture_open_connection_flags(c, conn_index, flags);
403 }
404
405 bool torture_init_connection(struct cli_state **pcli)
406 {
407         struct cli_state *cli;
408
409         cli = open_nbt_connection();
410         if (cli == NULL) {
411                 return false;
412         }
413
414         *pcli = cli;
415         return true;
416 }
417
418 bool torture_cli_session_setup2(struct cli_state *cli, uint16_t *new_vuid)
419 {
420         uint16_t old_vuid = cli_state_get_uid(cli);
421         NTSTATUS status;
422         bool ret;
423
424         cli_state_set_uid(cli, 0);
425         status = cli_session_setup_creds(cli, torture_creds);
426         ret = NT_STATUS_IS_OK(status);
427         *new_vuid = cli_state_get_uid(cli);
428         cli_state_set_uid(cli, old_vuid);
429         return ret;
430 }
431
432
433 bool torture_close_connection(struct cli_state *c)
434 {
435         bool ret = True;
436         NTSTATUS status;
437
438         status = cli_tdis(c);
439         if (!NT_STATUS_IS_OK(status)) {
440                 printf("tdis failed (%s)\n", nt_errstr(status));
441                 ret = False;
442         }
443
444         cli_shutdown(c);
445
446         return ret;
447 }
448
449
450 /* check if the server produced the expected dos or nt error code */
451 static bool check_both_error(int line, NTSTATUS status,
452                              uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
453 {
454         if (NT_STATUS_IS_DOS(status)) {
455                 uint8_t cclass;
456                 uint32_t num;
457
458                 /* Check DOS error */
459                 cclass = NT_STATUS_DOS_CLASS(status);
460                 num = NT_STATUS_DOS_CODE(status);
461
462                 if (eclass != cclass || ecode != num) {
463                         printf("unexpected error code class=%d code=%d\n",
464                                (int)cclass, (int)num);
465                         printf(" expected %d/%d %s (line=%d)\n",
466                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
467                         return false;
468                 }
469         } else {
470                 /* Check NT error */
471                 if (!NT_STATUS_EQUAL(nterr, status)) {
472                         printf("unexpected error code %s\n",
473                                 nt_errstr(status));
474                         printf(" expected %s (line=%d)\n",
475                                 nt_errstr(nterr), line);
476                         return false;
477                 }
478         }
479
480         return true;
481 }
482
483
484 /* check if the server produced the expected error code */
485 static bool check_error(int line, NTSTATUS status,
486                         uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
487 {
488         if (NT_STATUS_IS_DOS(status)) {
489                 uint8_t cclass;
490                 uint32_t num;
491
492                 /* Check DOS error */
493
494                 cclass = NT_STATUS_DOS_CLASS(status);
495                 num = NT_STATUS_DOS_CODE(status);
496
497                 if (eclass != cclass || ecode != num) {
498                         printf("unexpected error code class=%d code=%d\n", 
499                                (int)cclass, (int)num);
500                         printf(" expected %d/%d %s (line=%d)\n", 
501                                (int)eclass, (int)ecode, nt_errstr(nterr),
502                                line);
503                         return False;
504                 }
505
506         } else {
507                 /* Check NT error */
508
509                 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
510                         printf("unexpected error code %s\n",
511                                nt_errstr(status));
512                         printf(" expected %s (line=%d)\n", nt_errstr(nterr),
513                                line);
514                         return False;
515                 }
516         }
517
518         return True;
519 }
520
521
522 static bool wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
523 {
524         NTSTATUS status;
525
526         status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
527
528         while (!NT_STATUS_IS_OK(status)) {
529                 if (!check_both_error(__LINE__, status, ERRDOS,
530                                       ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
531                         return false;
532                 }
533
534                 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
535         }
536
537         return true;
538 }
539
540
541 static bool rw_torture(struct cli_state *c)
542 {
543         const char *lockfname = "\\torture.lck";
544         fstring fname;
545         uint16_t fnum;
546         uint16_t fnum2;
547         pid_t pid2, pid = getpid();
548         int i, j;
549         char buf[1024];
550         bool correct = True;
551         size_t nread = 0;
552         NTSTATUS status;
553
554         memset(buf, '\0', sizeof(buf));
555
556         status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
557                          DENY_NONE, &fnum2);
558         if (!NT_STATUS_IS_OK(status)) {
559                 status = cli_openx(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
560         }
561         if (!NT_STATUS_IS_OK(status)) {
562                 printf("open of %s failed (%s)\n",
563                        lockfname, nt_errstr(status));
564                 return False;
565         }
566
567         for (i=0;i<torture_numops;i++) {
568                 unsigned n = (unsigned)sys_random()%10;
569
570                 if (i % 10 == 0) {
571                         printf("%d\r", i); fflush(stdout);
572                 }
573                 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
574
575                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
576                         return False;
577                 }
578
579                 status = cli_openx(c, fname, O_RDWR | O_CREAT | O_TRUNC,
580                                   DENY_ALL, &fnum);
581                 if (!NT_STATUS_IS_OK(status)) {
582                         printf("open failed (%s)\n", nt_errstr(status));
583                         correct = False;
584                         break;
585                 }
586
587                 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
588                                       sizeof(pid), NULL);
589                 if (!NT_STATUS_IS_OK(status)) {
590                         printf("write failed (%s)\n", nt_errstr(status));
591                         correct = False;
592                 }
593
594                 for (j=0;j<50;j++) {
595                         status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
596                                               sizeof(pid)+(j*sizeof(buf)),
597                                               sizeof(buf), NULL);
598                         if (!NT_STATUS_IS_OK(status)) {
599                                 printf("write failed (%s)\n",
600                                        nt_errstr(status));
601                                 correct = False;
602                         }
603                 }
604
605                 pid2 = 0;
606
607                 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
608                                   &nread);
609                 if (!NT_STATUS_IS_OK(status)) {
610                         printf("read failed (%s)\n", nt_errstr(status));
611                         correct = false;
612                 } else if (nread != sizeof(pid)) {
613                         printf("read/write compare failed: "
614                                "recv %ld req %ld\n", (unsigned long)nread,
615                                (unsigned long)sizeof(pid));
616                         correct = false;
617                 }
618
619                 if (pid2 != pid) {
620                         printf("data corruption!\n");
621                         correct = False;
622                 }
623
624                 status = cli_close(c, fnum);
625                 if (!NT_STATUS_IS_OK(status)) {
626                         printf("close failed (%s)\n", nt_errstr(status));
627                         correct = False;
628                 }
629
630                 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
631                 if (!NT_STATUS_IS_OK(status)) {
632                         printf("unlink failed (%s)\n", nt_errstr(status));
633                         correct = False;
634                 }
635
636                 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
637                 if (!NT_STATUS_IS_OK(status)) {
638                         printf("unlock failed (%s)\n", nt_errstr(status));
639                         correct = False;
640                 }
641         }
642
643         cli_close(c, fnum2);
644         cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
645
646         printf("%d\n", i);
647
648         return correct;
649 }
650
651 static bool run_torture(int dummy)
652 {
653         struct cli_state *cli;
654         bool ret;
655
656         cli = current_cli;
657
658         smbXcli_conn_set_sockopt(cli->conn, sockops);
659
660         ret = rw_torture(cli);
661
662         if (!torture_close_connection(cli)) {
663                 ret = False;
664         }
665
666         return ret;
667 }
668
669 static bool rw_torture3(struct cli_state *c, char *lockfname)
670 {
671         uint16_t fnum = (uint16_t)-1;
672         unsigned int i = 0;
673         char buf[131072];
674         char buf_rd[131072];
675         unsigned count;
676         unsigned countprev = 0;
677         size_t sent = 0;
678         bool correct = True;
679         NTSTATUS status = NT_STATUS_OK;
680
681         srandom(1);
682         for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
683         {
684                 SIVAL(buf, i, sys_random());
685         }
686
687         if (procnum == 0)
688         {
689                 status = cli_unlink(
690                         c, lockfname,
691                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
692                 if (!NT_STATUS_IS_OK(status)) {
693                         printf("unlink failed (%s) (normal, this file should "
694                                "not exist)\n", nt_errstr(status));
695                 }
696
697                 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
698                                   DENY_NONE, &fnum);
699                 if (!NT_STATUS_IS_OK(status)) {
700                         printf("first open read/write of %s failed (%s)\n",
701                                         lockfname, nt_errstr(status));
702                         return False;
703                 }
704         }
705         else
706         {
707                 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
708                 {
709                         status = cli_openx(c, lockfname, O_RDONLY, 
710                                          DENY_NONE, &fnum);
711                         if (NT_STATUS_IS_OK(status)) {
712                                 break;
713                         }
714                         smb_msleep(10);
715                 }
716                 if (!NT_STATUS_IS_OK(status)) {
717                         printf("second open read-only of %s failed (%s)\n",
718                                         lockfname, nt_errstr(status));
719                         return False;
720                 }
721         }
722
723         i = 0;
724         for (count = 0; count < sizeof(buf); count += sent)
725         {
726                 if (count >= countprev) {
727                         printf("%d %8d\r", i, count);
728                         fflush(stdout);
729                         i++;
730                         countprev += (sizeof(buf) / 20);
731                 }
732
733                 if (procnum == 0)
734                 {
735                         sent = ((unsigned)sys_random()%(20))+ 1;
736                         if (sent > sizeof(buf) - count)
737                         {
738                                 sent = sizeof(buf) - count;
739                         }
740
741                         status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
742                                               count, sent, NULL);
743                         if (!NT_STATUS_IS_OK(status)) {
744                                 printf("write failed (%s)\n",
745                                        nt_errstr(status));
746                                 correct = False;
747                         }
748                 }
749                 else
750                 {
751                         status = cli_read(c, fnum, buf_rd+count, count,
752                                           sizeof(buf)-count, &sent);
753                         if(!NT_STATUS_IS_OK(status)) {
754                                 printf("read failed offset:%d size:%ld (%s)\n",
755                                        count, (unsigned long)sizeof(buf)-count,
756                                        nt_errstr(status));
757                                 correct = False;
758                                 sent = 0;
759                         } else if (sent > 0) {
760                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
761                                 {
762                                         printf("read/write compare failed\n");
763                                         printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
764                                         correct = False;
765                                         break;
766                                 }
767                         }
768                 }
769
770         }
771
772         status = cli_close(c, fnum);
773         if (!NT_STATUS_IS_OK(status)) {
774                 printf("close failed (%s)\n", nt_errstr(status));
775                 correct = False;
776         }
777
778         return correct;
779 }
780
781 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
782 {
783         const char *lockfname = "\\torture2.lck";
784         uint16_t fnum1;
785         uint16_t fnum2;
786         int i;
787         char buf[131072];
788         char buf_rd[131072];
789         bool correct = True;
790         size_t bytes_read;
791         NTSTATUS status;
792
793         status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
794         if (!NT_STATUS_IS_OK(status)) {
795                 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
796         }
797
798         status = cli_openx(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
799                           DENY_NONE, &fnum1);
800         if (!NT_STATUS_IS_OK(status)) {
801                 printf("first open read/write of %s failed (%s)\n",
802                                 lockfname, nt_errstr(status));
803                 return False;
804         }
805
806         status = cli_openx(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
807         if (!NT_STATUS_IS_OK(status)) {
808                 printf("second open read-only of %s failed (%s)\n",
809                                 lockfname, nt_errstr(status));
810                 cli_close(c1, fnum1);
811                 return False;
812         }
813
814         for (i = 0; i < torture_numops; i++)
815         {
816                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
817                 if (i % 10 == 0) {
818                         printf("%d\r", i); fflush(stdout);
819                 }
820
821                 generate_random_buffer((unsigned char *)buf, buf_size);
822
823                 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
824                                       buf_size, NULL);
825                 if (!NT_STATUS_IS_OK(status)) {
826                         printf("write failed (%s)\n", nt_errstr(status));
827                         correct = False;
828                         break;
829                 }
830
831                 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
832                 if(!NT_STATUS_IS_OK(status)) {
833                         printf("read failed (%s)\n", nt_errstr(status));
834                         correct = false;
835                         break;
836                 } else if (bytes_read != buf_size) {
837                         printf("read failed\n");
838                         printf("read %ld, expected %ld\n",
839                                (unsigned long)bytes_read,
840                                (unsigned long)buf_size); 
841                         correct = False;
842                         break;
843                 }
844
845                 if (memcmp(buf_rd, buf, buf_size) != 0)
846                 {
847                         printf("read/write compare failed\n");
848                         correct = False;
849                         break;
850                 }
851         }
852
853         status = cli_close(c2, fnum2);
854         if (!NT_STATUS_IS_OK(status)) {
855                 printf("close failed (%s)\n", nt_errstr(status));
856                 correct = False;
857         }
858
859         status = cli_close(c1, fnum1);
860         if (!NT_STATUS_IS_OK(status)) {
861                 printf("close failed (%s)\n", nt_errstr(status));
862                 correct = False;
863         }
864
865         status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
866         if (!NT_STATUS_IS_OK(status)) {
867                 printf("unlink failed (%s)\n", nt_errstr(status));
868                 correct = False;
869         }
870
871         return correct;
872 }
873
874 static bool run_readwritetest(int dummy)
875 {
876         struct cli_state *cli1, *cli2;
877         bool test1, test2 = False;
878
879         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
880                 return False;
881         }
882         smbXcli_conn_set_sockopt(cli1->conn, sockops);
883         smbXcli_conn_set_sockopt(cli2->conn, sockops);
884
885         printf("starting readwritetest\n");
886
887         test1 = rw_torture2(cli1, cli2);
888         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
889
890         if (test1) {
891                 test2 = rw_torture2(cli1, cli1);
892                 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
893         }
894
895         if (!torture_close_connection(cli1)) {
896                 test1 = False;
897         }
898
899         if (!torture_close_connection(cli2)) {
900                 test2 = False;
901         }
902
903         return (test1 && test2);
904 }
905
906 static bool run_readwritemulti(int dummy)
907 {
908         struct cli_state *cli;
909         bool test;
910
911         cli = current_cli;
912
913         smbXcli_conn_set_sockopt(cli->conn, sockops);
914
915         printf("run_readwritemulti: fname %s\n", randomfname);
916         test = rw_torture3(cli, randomfname);
917
918         if (!torture_close_connection(cli)) {
919                 test = False;
920         }
921
922         return test;
923 }
924
925 static bool run_readwritelarge_internal(void)
926 {
927         static struct cli_state *cli1;
928         uint16_t fnum1;
929         const char *lockfname = "\\large.dat";
930         off_t fsize;
931         char buf[126*1024];
932         bool correct = True;
933         NTSTATUS status;
934
935         if (!torture_open_connection(&cli1, 0)) {
936                 return False;
937         }
938         smbXcli_conn_set_sockopt(cli1->conn, sockops);
939         memset(buf,'\0',sizeof(buf));
940
941         printf("starting readwritelarge_internal\n");
942
943         cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
944
945         status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
946                           DENY_NONE, &fnum1);
947         if (!NT_STATUS_IS_OK(status)) {
948                 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
949                 return False;
950         }
951
952         cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
953
954         status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
955                                      NULL, NULL, NULL);
956         if (!NT_STATUS_IS_OK(status)) {
957                 printf("qfileinfo failed (%s)\n", nt_errstr(status));
958                 correct = False;
959         }
960
961         if (fsize == sizeof(buf))
962                 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
963                        (unsigned long)fsize);
964         else {
965                 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
966                        (unsigned long)fsize);
967                 correct = False;
968         }
969
970         status = cli_close(cli1, fnum1);
971         if (!NT_STATUS_IS_OK(status)) {
972                 printf("close failed (%s)\n", nt_errstr(status));
973                 correct = False;
974         }
975
976         status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
977         if (!NT_STATUS_IS_OK(status)) {
978                 printf("unlink failed (%s)\n", nt_errstr(status));
979                 correct = False;
980         }
981
982         status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
983                           DENY_NONE, &fnum1);
984         if (!NT_STATUS_IS_OK(status)) {
985                 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
986                 return False;
987         }
988
989         cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
990
991         status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
992                                      NULL, NULL, NULL);
993         if (!NT_STATUS_IS_OK(status)) {
994                 printf("qfileinfo failed (%s)\n", nt_errstr(status));
995                 correct = False;
996         }
997
998         if (fsize == sizeof(buf))
999                 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1000                        (unsigned long)fsize);
1001         else {
1002                 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1003                        (unsigned long)fsize);
1004                 correct = False;
1005         }
1006
1007 #if 0
1008         /* ToDo - set allocation. JRA */
1009         if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1010                 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1011                 return False;
1012         }
1013         if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1014                                  NULL, NULL)) {
1015                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1016                 correct = False;
1017         }
1018         if (fsize != 0)
1019                 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1020 #endif
1021
1022         status = cli_close(cli1, fnum1);
1023         if (!NT_STATUS_IS_OK(status)) {
1024                 printf("close failed (%s)\n", nt_errstr(status));
1025                 correct = False;
1026         }
1027
1028         if (!torture_close_connection(cli1)) {
1029                 correct = False;
1030         }
1031         return correct;
1032 }
1033
1034 static bool run_readwritelarge(int dummy)
1035 {
1036         return run_readwritelarge_internal();
1037 }
1038
1039 static bool run_readwritelarge_signtest(int dummy)
1040 {
1041         bool ret;
1042         signing_state = SMB_SIGNING_REQUIRED;
1043         ret = run_readwritelarge_internal();
1044         signing_state = SMB_SIGNING_DEFAULT;
1045         return ret;
1046 }
1047
1048 int line_count = 0;
1049 int nbio_id;
1050
1051 #define ival(s) strtol(s, NULL, 0)
1052
1053 /* run a test that simulates an approximate netbench client load */
1054 static bool run_netbench(int client)
1055 {
1056         struct cli_state *cli;
1057         int i;
1058         char line[1024];
1059         char cname[20];
1060         FILE *f;
1061         const char *params[20];
1062         bool correct = True;
1063
1064         cli = current_cli;
1065
1066         nbio_id = client;
1067
1068         smbXcli_conn_set_sockopt(cli->conn, sockops);
1069
1070         nb_setup(cli);
1071
1072         slprintf(cname,sizeof(cname)-1, "client%d", client);
1073
1074         f = fopen(client_txt, "r");
1075
1076         if (!f) {
1077                 perror(client_txt);
1078                 return False;
1079         }
1080
1081         while (fgets(line, sizeof(line)-1, f)) {
1082                 char *saveptr;
1083                 line_count++;
1084
1085                 line[strlen(line)-1] = 0;
1086
1087                 /* printf("[%d] %s\n", line_count, line); */
1088
1089                 all_string_sub(line,"client1", cname, sizeof(line));
1090
1091                 /* parse the command parameters */
1092                 params[0] = strtok_r(line, " ", &saveptr);
1093                 i = 0;
1094                 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1095
1096                 params[i] = "";
1097
1098                 if (i < 2) continue;
1099
1100                 if (!strncmp(params[0],"SMB", 3)) {
1101                         printf("ERROR: You are using a dbench 1 load file\n");
1102                         exit(1);
1103                 }
1104
1105                 if (!strcmp(params[0],"NTCreateX")) {
1106                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
1107                                    ival(params[4]));
1108                 } else if (!strcmp(params[0],"Close")) {
1109                         nb_close(ival(params[1]));
1110                 } else if (!strcmp(params[0],"Rename")) {
1111                         nb_rename(params[1], params[2]);
1112                 } else if (!strcmp(params[0],"Unlink")) {
1113                         nb_unlink(params[1]);
1114                 } else if (!strcmp(params[0],"Deltree")) {
1115                         nb_deltree(params[1]);
1116                 } else if (!strcmp(params[0],"Rmdir")) {
1117                         nb_rmdir(params[1]);
1118                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1119                         nb_qpathinfo(params[1]);
1120                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1121                         nb_qfileinfo(ival(params[1]));
1122                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1123                         nb_qfsinfo(ival(params[1]));
1124                 } else if (!strcmp(params[0],"FIND_FIRST")) {
1125                         nb_findfirst(params[1]);
1126                 } else if (!strcmp(params[0],"WriteX")) {
1127                         nb_writex(ival(params[1]), 
1128                                   ival(params[2]), ival(params[3]), ival(params[4]));
1129                 } else if (!strcmp(params[0],"ReadX")) {
1130                         nb_readx(ival(params[1]), 
1131                                   ival(params[2]), ival(params[3]), ival(params[4]));
1132                 } else if (!strcmp(params[0],"Flush")) {
1133                         nb_flush(ival(params[1]));
1134                 } else {
1135                         printf("Unknown operation %s\n", params[0]);
1136                         exit(1);
1137                 }
1138         }
1139         fclose(f);
1140
1141         nb_cleanup();
1142
1143         if (!torture_close_connection(cli)) {
1144                 correct = False;
1145         }
1146
1147         return correct;
1148 }
1149
1150
1151 /* run a test that simulates an approximate netbench client load */
1152 static bool run_nbench(int dummy)
1153 {
1154         double t;
1155         bool correct = True;
1156
1157         nbio_shmem(torture_nprocs);
1158
1159         nbio_id = -1;
1160
1161         signal(SIGALRM, nb_alarm);
1162         alarm(1);
1163         t = create_procs(run_netbench, &correct);
1164         alarm(0);
1165
1166         printf("\nThroughput %g MB/sec\n", 
1167                1.0e-6 * nbio_total() / t);
1168         return correct;
1169 }
1170
1171
1172 /*
1173   This test checks for two things:
1174
1175   1) correct support for retaining locks over a close (ie. the server
1176      must not use posix semantics)
1177   2) support for lock timeouts
1178  */
1179 static bool run_locktest1(int dummy)
1180 {
1181         struct cli_state *cli1, *cli2;
1182         const char *fname = "\\lockt1.lck";
1183         uint16_t fnum1, fnum2, fnum3;
1184         time_t t1, t2;
1185         unsigned lock_timeout;
1186         NTSTATUS status;
1187
1188         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1189                 return False;
1190         }
1191         smbXcli_conn_set_sockopt(cli1->conn, sockops);
1192         smbXcli_conn_set_sockopt(cli2->conn, sockops);
1193
1194         printf("starting locktest1\n");
1195
1196         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1197
1198         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1199                           &fnum1);
1200         if (!NT_STATUS_IS_OK(status)) {
1201                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1202                 return False;
1203         }
1204
1205         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1206         if (!NT_STATUS_IS_OK(status)) {
1207                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1208                 return False;
1209         }
1210
1211         status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1212         if (!NT_STATUS_IS_OK(status)) {
1213                 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1214                 return False;
1215         }
1216
1217         status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
1218         if (!NT_STATUS_IS_OK(status)) {
1219                 printf("lock1 failed (%s)\n", nt_errstr(status));
1220                 return false;
1221         }
1222
1223         status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1224         if (NT_STATUS_IS_OK(status)) {
1225                 printf("lock2 succeeded! This is a locking bug\n");
1226                 return false;
1227         } else {
1228                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1229                                       NT_STATUS_LOCK_NOT_GRANTED)) {
1230                         return false;
1231                 }
1232         }
1233
1234         lock_timeout = (1 + (random() % 20));
1235         printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1236         t1 = time(NULL);
1237         status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
1238         if (NT_STATUS_IS_OK(status)) {
1239                 printf("lock3 succeeded! This is a locking bug\n");
1240                 return false;
1241         } else {
1242                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1243                                       NT_STATUS_FILE_LOCK_CONFLICT)) {
1244                         return false;
1245                 }
1246         }
1247         t2 = time(NULL);
1248
1249         if (ABS(t2 - t1) < lock_timeout-1) {
1250                 printf("error: This server appears not to support timed lock requests\n");
1251         }
1252
1253         printf("server slept for %u seconds for a %u second timeout\n",
1254                (unsigned int)(t2-t1), lock_timeout);
1255
1256         status = cli_close(cli1, fnum2);
1257         if (!NT_STATUS_IS_OK(status)) {
1258                 printf("close1 failed (%s)\n", nt_errstr(status));
1259                 return False;
1260         }
1261
1262         status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1263         if (NT_STATUS_IS_OK(status)) {
1264                 printf("lock4 succeeded! This is a locking bug\n");
1265                 return false;
1266         } else {
1267                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1268                                       NT_STATUS_FILE_LOCK_CONFLICT)) {
1269                         return false;
1270                 }
1271         }
1272
1273         status = cli_close(cli1, fnum1);
1274         if (!NT_STATUS_IS_OK(status)) {
1275                 printf("close2 failed (%s)\n", nt_errstr(status));
1276                 return False;
1277         }
1278
1279         status = cli_close(cli2, fnum3);
1280         if (!NT_STATUS_IS_OK(status)) {
1281                 printf("close3 failed (%s)\n", nt_errstr(status));
1282                 return False;
1283         }
1284
1285         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1286         if (!NT_STATUS_IS_OK(status)) {
1287                 printf("unlink failed (%s)\n", nt_errstr(status));
1288                 return False;
1289         }
1290
1291
1292         if (!torture_close_connection(cli1)) {
1293                 return False;
1294         }
1295
1296         if (!torture_close_connection(cli2)) {
1297                 return False;
1298         }
1299
1300         printf("Passed locktest1\n");
1301         return True;
1302 }
1303
1304 /*
1305   this checks to see if a secondary tconx can use open files from an
1306   earlier tconx
1307  */
1308 static bool run_tcon_test(int dummy)
1309 {
1310         static struct cli_state *cli;
1311         const char *fname = "\\tcontest.tmp";
1312         uint16_t fnum1;
1313         uint32_t cnum1, cnum2, cnum3;
1314         struct smbXcli_tcon *orig_tcon = NULL;
1315         uint16_t vuid1, vuid2;
1316         char buf[4];
1317         bool ret = True;
1318         NTSTATUS status;
1319
1320         memset(buf, '\0', sizeof(buf));
1321
1322         if (!torture_open_connection(&cli, 0)) {
1323                 return False;
1324         }
1325         smbXcli_conn_set_sockopt(cli->conn, sockops);
1326
1327         printf("starting tcontest\n");
1328
1329         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1330
1331         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1332         if (!NT_STATUS_IS_OK(status)) {
1333                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1334                 return False;
1335         }
1336
1337         cnum1 = cli_state_get_tid(cli);
1338         vuid1 = cli_state_get_uid(cli);
1339
1340         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1341         if (!NT_STATUS_IS_OK(status)) {
1342                 printf("initial write failed (%s)", nt_errstr(status));
1343                 return False;
1344         }
1345
1346         orig_tcon = cli_state_save_tcon(cli);
1347         if (orig_tcon == NULL) {
1348                 return false;
1349         }
1350
1351         status = cli_tree_connect_creds(cli, share, "?????", torture_creds);
1352         if (!NT_STATUS_IS_OK(status)) {
1353                 printf("%s refused 2nd tree connect (%s)\n", host,
1354                        nt_errstr(status));
1355                 cli_shutdown(cli);
1356                 return False;
1357         }
1358
1359         cnum2 = cli_state_get_tid(cli);
1360         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1361         vuid2 = cli_state_get_uid(cli) + 1;
1362
1363         /* try a write with the wrong tid */
1364         cli_state_set_tid(cli, cnum2);
1365
1366         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1367         if (NT_STATUS_IS_OK(status)) {
1368                 printf("* server allows write with wrong TID\n");
1369                 ret = False;
1370         } else {
1371                 printf("server fails write with wrong TID : %s\n",
1372                        nt_errstr(status));
1373         }
1374
1375
1376         /* try a write with an invalid tid */
1377         cli_state_set_tid(cli, cnum3);
1378
1379         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1380         if (NT_STATUS_IS_OK(status)) {
1381                 printf("* server allows write with invalid TID\n");
1382                 ret = False;
1383         } else {
1384                 printf("server fails write with invalid TID : %s\n",
1385                        nt_errstr(status));
1386         }
1387
1388         /* try a write with an invalid vuid */
1389         cli_state_set_uid(cli, vuid2);
1390         cli_state_set_tid(cli, cnum1);
1391
1392         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1393         if (NT_STATUS_IS_OK(status)) {
1394                 printf("* server allows write with invalid VUID\n");
1395                 ret = False;
1396         } else {
1397                 printf("server fails write with invalid VUID : %s\n",
1398                        nt_errstr(status));
1399         }
1400
1401         cli_state_set_tid(cli, cnum1);
1402         cli_state_set_uid(cli, vuid1);
1403
1404         status = cli_close(cli, fnum1);
1405         if (!NT_STATUS_IS_OK(status)) {
1406                 printf("close failed (%s)\n", nt_errstr(status));
1407                 return False;
1408         }
1409
1410         cli_state_set_tid(cli, cnum2);
1411
1412         status = cli_tdis(cli);
1413         if (!NT_STATUS_IS_OK(status)) {
1414                 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1415                 return False;
1416         }
1417
1418         cli_state_restore_tcon(cli, orig_tcon);
1419
1420         cli_state_set_tid(cli, cnum1);
1421
1422         if (!torture_close_connection(cli)) {
1423                 return False;
1424         }
1425
1426         return ret;
1427 }
1428
1429
1430 /*
1431  checks for old style tcon support
1432  */
1433 static bool run_tcon2_test(int dummy)
1434 {
1435         static struct cli_state *cli;
1436         uint16_t cnum, max_xmit;
1437         char *service;
1438         NTSTATUS status;
1439
1440         if (!torture_open_connection(&cli, 0)) {
1441                 return False;
1442         }
1443         smbXcli_conn_set_sockopt(cli->conn, sockops);
1444
1445         printf("starting tcon2 test\n");
1446
1447         if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1448                 return false;
1449         }
1450
1451         status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1452
1453         SAFE_FREE(service);
1454
1455         if (!NT_STATUS_IS_OK(status)) {
1456                 printf("tcon2 failed : %s\n", nt_errstr(status));
1457         } else {
1458                 printf("tcon OK : max_xmit=%d cnum=%d\n",
1459                        (int)max_xmit, (int)cnum);
1460         }
1461
1462         if (!torture_close_connection(cli)) {
1463                 return False;
1464         }
1465
1466         printf("Passed tcon2 test\n");
1467         return True;
1468 }
1469
1470 static bool tcon_devtest(struct cli_state *cli,
1471                          const char *myshare, const char *devtype,
1472                          const char *return_devtype,
1473                          NTSTATUS expected_error)
1474 {
1475         NTSTATUS status;
1476         bool ret;
1477
1478         status = cli_tree_connect_creds(cli, myshare, devtype, torture_creds);
1479
1480         if (NT_STATUS_IS_OK(expected_error)) {
1481                 if (NT_STATUS_IS_OK(status)) {
1482                         if (return_devtype != NULL &&
1483                             strequal(cli->dev, return_devtype)) {
1484                                 ret = True;
1485                         } else { 
1486                                 printf("tconX to share %s with type %s "
1487                                        "succeeded but returned the wrong "
1488                                        "device type (got [%s] but should have got [%s])\n",
1489                                        myshare, devtype, cli->dev, return_devtype);
1490                                 ret = False;
1491                         }
1492                 } else {
1493                         printf("tconX to share %s with type %s "
1494                                "should have succeeded but failed\n",
1495                                myshare, devtype);
1496                         ret = False;
1497                 }
1498                 cli_tdis(cli);
1499         } else {
1500                 if (NT_STATUS_IS_OK(status)) {
1501                         printf("tconx to share %s with type %s "
1502                                "should have failed but succeeded\n",
1503                                myshare, devtype);
1504                         ret = False;
1505                 } else {
1506                         if (NT_STATUS_EQUAL(status, expected_error)) {
1507                                 ret = True;
1508                         } else {
1509                                 printf("Returned unexpected error\n");
1510                                 ret = False;
1511                         }
1512                 }
1513         }
1514         return ret;
1515 }
1516
1517 /*
1518  checks for correct tconX support
1519  */
1520 static bool run_tcon_devtype_test(int dummy)
1521 {
1522         static struct cli_state *cli1 = NULL;
1523         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
1524         NTSTATUS status;
1525         bool ret = True;
1526
1527         status = cli_full_connection_creds(&cli1,
1528                                            myname,
1529                                            host,
1530                                            NULL, /* dest_ss */
1531                                            port_to_use,
1532                                            NULL, /* service */
1533                                            NULL, /* service_type */
1534                                            torture_creds,
1535                                            flags,
1536                                            signing_state);
1537
1538         if (!NT_STATUS_IS_OK(status)) {
1539                 printf("could not open connection\n");
1540                 return False;
1541         }
1542
1543         if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1544                 ret = False;
1545
1546         if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1547                 ret = False;
1548
1549         if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1550                 ret = False;
1551
1552         if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1553                 ret = False;
1554
1555         if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1556                 ret = False;
1557
1558         if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1559                 ret = False;
1560
1561         if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1562                 ret = False;
1563
1564         if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1565                 ret = False;
1566
1567         if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1568                 ret = False;
1569
1570         if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1571                 ret = False;
1572
1573         cli_shutdown(cli1);
1574
1575         if (ret)
1576                 printf("Passed tcondevtest\n");
1577
1578         return ret;
1579 }
1580
1581
1582 /*
1583   This test checks that 
1584
1585   1) the server supports multiple locking contexts on the one SMB
1586   connection, distinguished by PID.  
1587
1588   2) the server correctly fails overlapping locks made by the same PID (this
1589      goes against POSIX behaviour, which is why it is tricky to implement)
1590
1591   3) the server denies unlock requests by an incorrect client PID
1592 */
1593 static bool run_locktest2(int dummy)
1594 {
1595         static struct cli_state *cli;
1596         const char *fname = "\\lockt2.lck";
1597         uint16_t fnum1, fnum2, fnum3;
1598         bool correct = True;
1599         NTSTATUS status;
1600
1601         if (!torture_open_connection(&cli, 0)) {
1602                 return False;
1603         }
1604
1605         smbXcli_conn_set_sockopt(cli->conn, sockops);
1606
1607         printf("starting locktest2\n");
1608
1609         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1610
1611         cli_setpid(cli, 1);
1612
1613         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1614         if (!NT_STATUS_IS_OK(status)) {
1615                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1616                 return False;
1617         }
1618
1619         status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1620         if (!NT_STATUS_IS_OK(status)) {
1621                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1622                 return False;
1623         }
1624
1625         cli_setpid(cli, 2);
1626
1627         status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1628         if (!NT_STATUS_IS_OK(status)) {
1629                 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1630                 return False;
1631         }
1632
1633         cli_setpid(cli, 1);
1634
1635         status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1636         if (!NT_STATUS_IS_OK(status)) {
1637                 printf("lock1 failed (%s)\n", nt_errstr(status));
1638                 return false;
1639         }
1640
1641         status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1642         if (NT_STATUS_IS_OK(status)) {
1643                 printf("WRITE lock1 succeeded! This is a locking bug\n");
1644                 correct = false;
1645         } else {
1646                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1647                                       NT_STATUS_LOCK_NOT_GRANTED)) {
1648                         return false;
1649                 }
1650         }
1651
1652         status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
1653         if (NT_STATUS_IS_OK(status)) {
1654                 printf("WRITE lock2 succeeded! This is a locking bug\n");
1655                 correct = false;
1656         } else {
1657                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1658                                       NT_STATUS_LOCK_NOT_GRANTED)) {
1659                         return false;
1660                 }
1661         }
1662
1663         status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1664         if (NT_STATUS_IS_OK(status)) {
1665                 printf("READ lock2 succeeded! This is a locking bug\n");
1666                 correct = false;
1667         } else {
1668                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1669                                  NT_STATUS_FILE_LOCK_CONFLICT)) {
1670                         return false;
1671                 }
1672         }
1673
1674         status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1675         if (!NT_STATUS_IS_OK(status)) {
1676                 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1677         }
1678         cli_setpid(cli, 2);
1679         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1680                 printf("unlock at 100 succeeded! This is a locking bug\n");
1681                 correct = False;
1682         }
1683
1684         status = cli_unlock(cli, fnum1, 0, 4);
1685         if (NT_STATUS_IS_OK(status)) {
1686                 printf("unlock1 succeeded! This is a locking bug\n");
1687                 correct = false;
1688         } else {
1689                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1690                                       NT_STATUS_RANGE_NOT_LOCKED)) {
1691                         return false;
1692                 }
1693         }
1694
1695         status = cli_unlock(cli, fnum1, 0, 8);
1696         if (NT_STATUS_IS_OK(status)) {
1697                 printf("unlock2 succeeded! This is a locking bug\n");
1698                 correct = false;
1699         } else {
1700                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1701                                       NT_STATUS_RANGE_NOT_LOCKED)) {
1702                         return false;
1703                 }
1704         }
1705
1706         status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1707         if (NT_STATUS_IS_OK(status)) {
1708                 printf("lock3 succeeded! This is a locking bug\n");
1709                 correct = false;
1710         } else {
1711                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1712                                       NT_STATUS_LOCK_NOT_GRANTED)) {
1713                         return false;
1714                 }
1715         }
1716
1717         cli_setpid(cli, 1);
1718
1719         status = cli_close(cli, fnum1);
1720         if (!NT_STATUS_IS_OK(status)) {
1721                 printf("close1 failed (%s)\n", nt_errstr(status));
1722                 return False;
1723         }
1724
1725         status = cli_close(cli, fnum2);
1726         if (!NT_STATUS_IS_OK(status)) {
1727                 printf("close2 failed (%s)\n", nt_errstr(status));
1728                 return False;
1729         }
1730
1731         status = cli_close(cli, fnum3);
1732         if (!NT_STATUS_IS_OK(status)) {
1733                 printf("close3 failed (%s)\n", nt_errstr(status));
1734                 return False;
1735         }
1736
1737         if (!torture_close_connection(cli)) {
1738                 correct = False;
1739         }
1740
1741         printf("locktest2 finished\n");
1742
1743         return correct;
1744 }
1745
1746
1747 /*
1748   This test checks that 
1749
1750   1) the server supports the full offset range in lock requests
1751 */
1752 static bool run_locktest3(int dummy)
1753 {
1754         static struct cli_state *cli1, *cli2;
1755         const char *fname = "\\lockt3.lck";
1756         uint16_t fnum1, fnum2;
1757         int i;
1758         uint32_t offset;
1759         bool correct = True;
1760         NTSTATUS status;
1761
1762 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1763
1764         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1765                 return False;
1766         }
1767         smbXcli_conn_set_sockopt(cli1->conn, sockops);
1768         smbXcli_conn_set_sockopt(cli2->conn, sockops);
1769
1770         printf("starting locktest3\n");
1771
1772         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1773
1774         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1775                          &fnum1);
1776         if (!NT_STATUS_IS_OK(status)) {
1777                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1778                 return False;
1779         }
1780
1781         status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1782         if (!NT_STATUS_IS_OK(status)) {
1783                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1784                 return False;
1785         }
1786
1787         for (offset=i=0;i<torture_numops;i++) {
1788                 NEXT_OFFSET;
1789
1790                 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1791                 if (!NT_STATUS_IS_OK(status)) {
1792                         printf("lock1 %d failed (%s)\n", 
1793                                i,
1794                                nt_errstr(status));
1795                         return False;
1796                 }
1797
1798                 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1799                 if (!NT_STATUS_IS_OK(status)) {
1800                         printf("lock2 %d failed (%s)\n", 
1801                                i,
1802                                nt_errstr(status));
1803                         return False;
1804                 }
1805         }
1806
1807         for (offset=i=0;i<torture_numops;i++) {
1808                 NEXT_OFFSET;
1809
1810                 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
1811                 if (NT_STATUS_IS_OK(status)) {
1812                         printf("error: lock1 %d succeeded!\n", i);
1813                         return False;
1814                 }
1815
1816                 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
1817                 if (NT_STATUS_IS_OK(status)) {
1818                         printf("error: lock2 %d succeeded!\n", i);
1819                         return False;
1820                 }
1821
1822                 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1823                 if (NT_STATUS_IS_OK(status)) {
1824                         printf("error: lock3 %d succeeded!\n", i);
1825                         return False;
1826                 }
1827
1828                 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1829                 if (NT_STATUS_IS_OK(status)) {
1830                         printf("error: lock4 %d succeeded!\n", i);
1831                         return False;
1832                 }
1833         }
1834
1835         for (offset=i=0;i<torture_numops;i++) {
1836                 NEXT_OFFSET;
1837
1838                 status = cli_unlock(cli1, fnum1, offset-1, 1);
1839                 if (!NT_STATUS_IS_OK(status)) {
1840                         printf("unlock1 %d failed (%s)\n", 
1841                                i,
1842                                nt_errstr(status));
1843                         return False;
1844                 }
1845
1846                 status = cli_unlock(cli2, fnum2, offset-2, 1);
1847                 if (!NT_STATUS_IS_OK(status)) {
1848                         printf("unlock2 %d failed (%s)\n", 
1849                                i,
1850                                nt_errstr(status));
1851                         return False;
1852                 }
1853         }
1854
1855         status = cli_close(cli1, fnum1);
1856         if (!NT_STATUS_IS_OK(status)) {
1857                 printf("close1 failed (%s)\n", nt_errstr(status));
1858                 return False;
1859         }
1860
1861         status = cli_close(cli2, fnum2);
1862         if (!NT_STATUS_IS_OK(status)) {
1863                 printf("close2 failed (%s)\n", nt_errstr(status));
1864                 return False;
1865         }
1866
1867         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1868         if (!NT_STATUS_IS_OK(status)) {
1869                 printf("unlink failed (%s)\n", nt_errstr(status));
1870                 return False;
1871         }
1872
1873         if (!torture_close_connection(cli1)) {
1874                 correct = False;
1875         }
1876
1877         if (!torture_close_connection(cli2)) {
1878                 correct = False;
1879         }
1880
1881         printf("finished locktest3\n");
1882
1883         return correct;
1884 }
1885
1886 static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
1887                            char *buf, off_t offset, size_t size,
1888                            size_t *nread, size_t expect)
1889 {
1890         NTSTATUS status;
1891         size_t l_nread;
1892
1893         status = cli_read(cli, fnum, buf, offset, size, &l_nread);
1894
1895         if(!NT_STATUS_IS_OK(status)) {
1896                 return false;
1897         } else if (l_nread != expect) {
1898                 return false;
1899         }
1900
1901         if (nread) {
1902                 *nread = l_nread;
1903         }
1904
1905         return true;
1906 }
1907
1908 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1909         printf("** "); correct = False; \
1910         }
1911
1912 /*
1913   looks at overlapping locks
1914 */
1915 static bool run_locktest4(int dummy)
1916 {
1917         static struct cli_state *cli1, *cli2;
1918         const char *fname = "\\lockt4.lck";
1919         uint16_t fnum1, fnum2, f;
1920         bool ret;
1921         char buf[1000];
1922         bool correct = True;
1923         NTSTATUS status;
1924
1925         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1926                 return False;
1927         }
1928
1929         smbXcli_conn_set_sockopt(cli1->conn, sockops);
1930         smbXcli_conn_set_sockopt(cli2->conn, sockops);
1931
1932         printf("starting locktest4\n");
1933
1934         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1935
1936         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1937         cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1938
1939         memset(buf, 0, sizeof(buf));
1940
1941         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1942                               NULL);
1943         if (!NT_STATUS_IS_OK(status)) {
1944                 printf("Failed to create file: %s\n", nt_errstr(status));
1945                 correct = False;
1946                 goto fail;
1947         }
1948
1949         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1950               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
1951         EXPECTED(ret, False);
1952         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1953
1954         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
1955               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
1956         EXPECTED(ret, True);
1957         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1958
1959         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1960               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
1961         EXPECTED(ret, False);
1962         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1963
1964         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
1965               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
1966         EXPECTED(ret, True);
1967         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1968
1969         ret = (cli_setpid(cli1, 1),
1970               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1971               (cli_setpid(cli1, 2),
1972               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
1973         EXPECTED(ret, False);
1974         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1975
1976         ret = (cli_setpid(cli1, 1),
1977               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
1978               (cli_setpid(cli1, 2),
1979               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
1980         EXPECTED(ret, True);
1981         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1982
1983         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
1984               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
1985         EXPECTED(ret, True);
1986         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1987
1988         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1989               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
1990         EXPECTED(ret, False);
1991         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1992
1993         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
1994               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
1995         EXPECTED(ret, False);
1996         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1997
1998         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
1999               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
2000         EXPECTED(ret, True);
2001         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2002
2003         ret = (cli_setpid(cli1, 1),
2004              NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
2005              (cli_setpid(cli1, 2),
2006              NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
2007         EXPECTED(ret, False);
2008         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2009
2010         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
2011               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
2012               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
2013         EXPECTED(ret, False);
2014         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
2015
2016
2017         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
2018               test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
2019         EXPECTED(ret, False);
2020         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
2021
2022         status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2023         ret = NT_STATUS_IS_OK(status);
2024         if (ret) {
2025                 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
2026                                       NULL);
2027                 ret = NT_STATUS_IS_OK(status);
2028         }
2029         EXPECTED(ret, False);
2030         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2031
2032
2033         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2034               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2035               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2036               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2037         EXPECTED(ret, True);
2038         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2039
2040
2041         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
2042               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
2043               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2044               test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
2045               !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2046                                              150, 4, NULL))) &&
2047               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2048         EXPECTED(ret, True);
2049         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2050
2051         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
2052               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2053               NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2054                                            160, 4, NULL)) &&
2055               test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
2056         EXPECTED(ret, True);
2057         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2058
2059         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
2060               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2061               NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2062                                            170, 4, NULL)) &&
2063               test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
2064         EXPECTED(ret, True);
2065         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2066
2067         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
2068               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
2069               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2070               !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2071                                             190, 4, NULL)) &&
2072               test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
2073         EXPECTED(ret, True);
2074         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2075
2076         cli_close(cli1, fnum1);
2077         cli_close(cli2, fnum2);
2078         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2079         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
2080         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2081               NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
2082               NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2083               NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2084               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
2085         cli_close(cli1, f);
2086         cli_close(cli1, fnum1);
2087         EXPECTED(ret, True);
2088         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2089
2090  fail:
2091         cli_close(cli1, fnum1);
2092         cli_close(cli2, fnum2);
2093         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2094         torture_close_connection(cli1);
2095         torture_close_connection(cli2);
2096
2097         printf("finished locktest4\n");
2098         return correct;
2099 }
2100
2101 /*
2102   looks at lock upgrade/downgrade.
2103 */
2104 static bool run_locktest5(int dummy)
2105 {
2106         static struct cli_state *cli1, *cli2;
2107         const char *fname = "\\lockt5.lck";
2108         uint16_t fnum1, fnum2, fnum3;
2109         bool ret;
2110         char buf[1000];
2111         bool correct = True;
2112         NTSTATUS status;
2113
2114         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2115                 return False;
2116         }
2117
2118         smbXcli_conn_set_sockopt(cli1->conn, sockops);
2119         smbXcli_conn_set_sockopt(cli2->conn, sockops);
2120
2121         printf("starting locktest5\n");
2122
2123         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2124
2125         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2126         cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2127         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2128
2129         memset(buf, 0, sizeof(buf));
2130
2131         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2132                               NULL);
2133         if (!NT_STATUS_IS_OK(status)) {
2134                 printf("Failed to create file: %s\n", nt_errstr(status));
2135                 correct = False;
2136                 goto fail;
2137         }
2138
2139         /* Check for NT bug... */
2140         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2141               NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
2142         cli_close(cli1, fnum1);
2143         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2144         status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2145         ret = NT_STATUS_IS_OK(status);
2146         EXPECTED(ret, True);
2147         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2148         cli_close(cli1, fnum1);
2149         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2150         cli_unlock(cli1, fnum3, 0, 1);
2151
2152         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
2153               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
2154         EXPECTED(ret, True);
2155         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2156
2157         status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
2158         ret = NT_STATUS_IS_OK(status);
2159         EXPECTED(ret, False);
2160
2161         printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2162
2163         /* Unlock the process 2 lock. */
2164         cli_unlock(cli2, fnum2, 0, 4);
2165
2166         status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
2167         ret = NT_STATUS_IS_OK(status);
2168         EXPECTED(ret, False);
2169
2170         printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2171
2172         /* Unlock the process 1 fnum3 lock. */
2173         cli_unlock(cli1, fnum3, 0, 4);
2174
2175         /* Stack 2 more locks here. */
2176         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
2177               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
2178
2179         EXPECTED(ret, True);
2180         printf("the same process %s stack read locks\n", ret?"can":"cannot");
2181
2182         /* Unlock the first process lock, then check this was the WRITE lock that was
2183                 removed. */
2184
2185         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2186               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
2187
2188         EXPECTED(ret, True);
2189         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2190
2191         /* Unlock the process 2 lock. */
2192         cli_unlock(cli2, fnum2, 0, 4);
2193
2194         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2195
2196         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2197                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2198                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2199
2200         EXPECTED(ret, True);
2201         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
2202
2203         /* Ensure the next unlock fails. */
2204         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2205         EXPECTED(ret, False);
2206         printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
2207
2208         /* Ensure connection 2 can get a write lock. */
2209         status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2210         ret = NT_STATUS_IS_OK(status);
2211         EXPECTED(ret, True);
2212
2213         printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2214
2215
2216  fail:
2217         cli_close(cli1, fnum1);
2218         cli_close(cli2, fnum2);
2219         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2220         if (!torture_close_connection(cli1)) {
2221                 correct = False;
2222         }
2223         if (!torture_close_connection(cli2)) {
2224                 correct = False;
2225         }
2226
2227         printf("finished locktest5\n");
2228
2229         return correct;
2230 }
2231
2232 /*
2233   tries the unusual lockingX locktype bits
2234 */
2235 static bool run_locktest6(int dummy)
2236 {
2237         static struct cli_state *cli;
2238         const char *fname[1] = { "\\lock6.txt" };
2239         int i;
2240         uint16_t fnum;
2241         NTSTATUS status;
2242
2243         if (!torture_open_connection(&cli, 0)) {
2244                 return False;
2245         }
2246
2247         smbXcli_conn_set_sockopt(cli->conn, sockops);
2248
2249         printf("starting locktest6\n");
2250
2251         for (i=0;i<1;i++) {
2252                 printf("Testing %s\n", fname[i]);
2253
2254                 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2255
2256                 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2257                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2258                 cli_close(cli, fnum);
2259                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2260
2261                 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2262                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2263                 cli_close(cli, fnum);
2264                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2265
2266                 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2267         }
2268
2269         torture_close_connection(cli);
2270
2271         printf("finished locktest6\n");
2272         return True;
2273 }
2274
2275 static bool run_locktest7(int dummy)
2276 {
2277         struct cli_state *cli1;
2278         const char *fname = "\\lockt7.lck";
2279         uint16_t fnum1;
2280         char buf[200];
2281         bool correct = False;
2282         size_t nread;
2283         NTSTATUS status;
2284
2285         if (!torture_open_connection(&cli1, 0)) {
2286                 return False;
2287         }
2288
2289         smbXcli_conn_set_sockopt(cli1->conn, sockops);
2290
2291         printf("starting locktest7\n");
2292
2293         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2294
2295         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2296
2297         memset(buf, 0, sizeof(buf));
2298
2299         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2300                               NULL);
2301         if (!NT_STATUS_IS_OK(status)) {
2302                 printf("Failed to create file: %s\n", nt_errstr(status));
2303                 goto fail;
2304         }
2305
2306         cli_setpid(cli1, 1);
2307
2308         status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2309         if (!NT_STATUS_IS_OK(status)) {
2310                 printf("Unable to apply read lock on range 130:4, "
2311                        "error was %s\n", nt_errstr(status));
2312                 goto fail;
2313         } else {
2314                 printf("pid1 successfully locked range 130:4 for READ\n");
2315         }
2316
2317         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2318         if (!NT_STATUS_IS_OK(status)) {
2319                 printf("pid1 unable to read the range 130:4, error was %s\n",
2320                       nt_errstr(status));
2321                 goto fail;
2322         } else if (nread != 4) {
2323                 printf("pid1 unable to read the range 130:4, "
2324                        "recv %ld req %d\n", (unsigned long)nread, 4);
2325                 goto fail;
2326         } else {
2327                 printf("pid1 successfully read the range 130:4\n");
2328         }
2329
2330         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2331         if (!NT_STATUS_IS_OK(status)) {
2332                 printf("pid1 unable to write to the range 130:4, error was "
2333                        "%s\n", nt_errstr(status));
2334                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2335                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2336                         goto fail;
2337                 }
2338         } else {
2339                 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2340                 goto fail;
2341         }
2342
2343         cli_setpid(cli1, 2);
2344
2345         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2346         if (!NT_STATUS_IS_OK(status)) {
2347                 printf("pid2 unable to read the range 130:4, error was %s\n",
2348                       nt_errstr(status));
2349                 goto fail;
2350         } else if (nread != 4) {
2351                 printf("pid2 unable to read the range 130:4, "
2352                        "recv %ld req %d\n", (unsigned long)nread, 4);
2353                 goto fail;
2354         } else {
2355                 printf("pid2 successfully read the range 130:4\n");
2356         }
2357
2358         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2359         if (!NT_STATUS_IS_OK(status)) {
2360                 printf("pid2 unable to write to the range 130:4, error was "
2361                        "%s\n", nt_errstr(status));
2362                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2363                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2364                         goto fail;
2365                 }
2366         } else {
2367                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2368                 goto fail;
2369         }
2370
2371         cli_setpid(cli1, 1);
2372         cli_unlock(cli1, fnum1, 130, 4);
2373
2374         status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
2375         if (!NT_STATUS_IS_OK(status)) {
2376                 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
2377                 goto fail;
2378         } else {
2379                 printf("pid1 successfully locked range 130:4 for WRITE\n");
2380         }
2381
2382         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2383         if (!NT_STATUS_IS_OK(status)) {
2384                 printf("pid1 unable to read the range 130:4, error was %s\n",
2385                       nt_errstr(status));
2386                 goto fail;
2387         } else if (nread != 4) {
2388                 printf("pid1 unable to read the range 130:4, "
2389                        "recv %ld req %d\n", (unsigned long)nread, 4);
2390                 goto fail;
2391         } else {
2392                 printf("pid1 successfully read the range 130:4\n");
2393         }
2394
2395         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2396         if (!NT_STATUS_IS_OK(status)) {
2397                 printf("pid1 unable to write to the range 130:4, error was "
2398                        "%s\n", nt_errstr(status));
2399                 goto fail;
2400         } else {
2401                 printf("pid1 successfully wrote to the range 130:4\n");
2402         }
2403
2404         cli_setpid(cli1, 2);
2405
2406         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2407         if (!NT_STATUS_IS_OK(status)) {
2408                 printf("pid2 unable to read the range 130:4, error was "
2409                        "%s\n", nt_errstr(status));
2410                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2411                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2412                         goto fail;
2413                 }
2414         } else {
2415                 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2416                        (unsigned long)nread);
2417                 goto fail;
2418         }
2419
2420         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2421         if (!NT_STATUS_IS_OK(status)) {
2422                 printf("pid2 unable to write to the range 130:4, error was "
2423                        "%s\n", nt_errstr(status));
2424                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2425                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2426                         goto fail;
2427                 }
2428         } else {
2429                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2430                 goto fail;
2431         }
2432
2433         cli_unlock(cli1, fnum1, 130, 0);
2434         correct = True;
2435
2436 fail:
2437         cli_close(cli1, fnum1);
2438         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2439         torture_close_connection(cli1);
2440
2441         printf("finished locktest7\n");
2442         return correct;
2443 }
2444
2445 /*
2446  * This demonstrates a problem with our use of GPFS share modes: A file
2447  * descriptor sitting in the pending close queue holding a GPFS share mode
2448  * blocks opening a file another time. Happens with Word 2007 temp files.
2449  * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2450  * open is denied with NT_STATUS_SHARING_VIOLATION.
2451  */
2452
2453 static bool run_locktest8(int dummy)
2454 {
2455         struct cli_state *cli1;
2456         const char *fname = "\\lockt8.lck";
2457         uint16_t fnum1, fnum2;
2458         char buf[200];
2459         bool correct = False;
2460         NTSTATUS status;
2461
2462         if (!torture_open_connection(&cli1, 0)) {
2463                 return False;
2464         }
2465
2466         smbXcli_conn_set_sockopt(cli1->conn, sockops);
2467
2468         printf("starting locktest8\n");
2469
2470         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2471
2472         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2473                           &fnum1);
2474         if (!NT_STATUS_IS_OK(status)) {
2475                 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2476                 return false;
2477         }
2478
2479         memset(buf, 0, sizeof(buf));
2480
2481         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2482         if (!NT_STATUS_IS_OK(status)) {
2483                 d_fprintf(stderr, "cli_openx second time returned %s\n",
2484                           nt_errstr(status));
2485                 goto fail;
2486         }
2487
2488         status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
2489         if (!NT_STATUS_IS_OK(status)) {
2490                 printf("Unable to apply read lock on range 1:1, error was "
2491                        "%s\n", nt_errstr(status));
2492                 goto fail;
2493         }
2494
2495         status = cli_close(cli1, fnum1);
2496         if (!NT_STATUS_IS_OK(status)) {
2497                 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2498                 goto fail;
2499         }
2500
2501         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2502         if (!NT_STATUS_IS_OK(status)) {
2503                 d_fprintf(stderr, "cli_openx third time returned %s\n",
2504                           nt_errstr(status));
2505                 goto fail;
2506         }
2507
2508         correct = true;
2509
2510 fail:
2511         cli_close(cli1, fnum1);
2512         cli_close(cli1, fnum2);
2513         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2514         torture_close_connection(cli1);
2515
2516         printf("finished locktest8\n");
2517         return correct;
2518 }
2519
2520 /*
2521  * This test is designed to be run in conjunction with
2522  * external NFS or POSIX locks taken in the filesystem.
2523  * It checks that the smbd server will block until the
2524  * lock is released and then acquire it. JRA.
2525  */
2526
2527 static bool got_alarm;
2528 static struct cli_state *alarm_cli;
2529
2530 static void alarm_handler(int dummy)
2531 {
2532         got_alarm = True;
2533 }
2534
2535 static void alarm_handler_parent(int dummy)
2536 {
2537         smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_OK);
2538 }
2539
2540 static void do_local_lock(int read_fd, int write_fd)
2541 {
2542         int fd;
2543         char c = '\0';
2544         struct flock lock;
2545         const char *local_pathname = NULL;
2546         int ret;
2547
2548         local_pathname = talloc_asprintf(talloc_tos(),
2549                         "%s/lockt9.lck", local_path);
2550         if (!local_pathname) {
2551                 printf("child: alloc fail\n");
2552                 exit(1);
2553         }
2554
2555         unlink(local_pathname);
2556         fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2557         if (fd == -1) {
2558                 printf("child: open of %s failed %s.\n",
2559                         local_pathname, strerror(errno));
2560                 exit(1);
2561         }
2562
2563         /* Now take a fcntl lock. */
2564         lock.l_type = F_WRLCK;
2565         lock.l_whence = SEEK_SET;
2566         lock.l_start = 0;
2567         lock.l_len = 4;
2568         lock.l_pid = getpid();
2569
2570         ret = fcntl(fd,F_SETLK,&lock);
2571         if (ret == -1) {
2572                 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2573                         local_pathname, strerror(errno));
2574                 exit(1);
2575         } else {
2576                 printf("child: got lock 0:4 on file %s.\n",
2577                         local_pathname );
2578                 fflush(stdout);
2579         }
2580
2581         CatchSignal(SIGALRM, alarm_handler);
2582         alarm(5);
2583         /* Signal the parent. */
2584         if (write(write_fd, &c, 1) != 1) {
2585                 printf("child: start signal fail %s.\n",
2586                         strerror(errno));
2587                 exit(1);
2588         }
2589         alarm(0);
2590
2591         alarm(10);
2592         /* Wait for the parent to be ready. */
2593         if (read(read_fd, &c, 1) != 1) {
2594                 printf("child: reply signal fail %s.\n",
2595                         strerror(errno));
2596                 exit(1);
2597         }
2598         alarm(0);
2599
2600         sleep(5);
2601         close(fd);
2602         printf("child: released lock 0:4 on file %s.\n",
2603                 local_pathname );
2604         fflush(stdout);
2605         exit(0);
2606 }
2607
2608 static bool run_locktest9(int dummy)
2609 {
2610         struct cli_state *cli1;
2611         const char *fname = "\\lockt9.lck";
2612         uint16_t fnum;
2613         bool correct = False;
2614         int pipe_in[2], pipe_out[2];
2615         pid_t child_pid;
2616         char c = '\0';
2617         int ret;
2618         struct timeval start;
2619         double seconds;
2620         NTSTATUS status;
2621
2622         printf("starting locktest9\n");
2623
2624         if (local_path == NULL) {
2625                 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2626                 return false;
2627         }
2628
2629         if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2630                 return false;
2631         }
2632
2633         child_pid = fork();
2634         if (child_pid == -1) {
2635                 return false;
2636         }
2637
2638         if (child_pid == 0) {
2639                 /* Child. */
2640                 do_local_lock(pipe_out[0], pipe_in[1]);
2641                 exit(0);
2642         }
2643
2644         close(pipe_out[0]);
2645         close(pipe_in[1]);
2646         pipe_out[0] = -1;
2647         pipe_in[1] = -1;
2648
2649         /* Parent. */
2650         ret = read(pipe_in[0], &c, 1);
2651         if (ret != 1) {
2652                 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2653                         strerror(errno));
2654                 return false;
2655         }
2656
2657         if (!torture_open_connection(&cli1, 0)) {
2658                 return false;
2659         }
2660
2661         smbXcli_conn_set_sockopt(cli1->conn, sockops);
2662
2663         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE,
2664                           &fnum);
2665         if (!NT_STATUS_IS_OK(status)) {
2666                 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2667                 return false;
2668         }
2669
2670         /* Ensure the child has the lock. */
2671         status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
2672         if (NT_STATUS_IS_OK(status)) {
2673                 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2674                 goto fail;
2675         } else {
2676                 d_printf("Child has the lock.\n");
2677         }
2678
2679         /* Tell the child to wait 5 seconds then exit. */
2680         ret = write(pipe_out[1], &c, 1);
2681         if (ret != 1) {
2682                 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2683                         strerror(errno));
2684                 goto fail;
2685         }
2686
2687         /* Wait 20 seconds for the lock. */
2688         alarm_cli = cli1;
2689         CatchSignal(SIGALRM, alarm_handler_parent);
2690         alarm(20);
2691
2692         start = timeval_current();
2693
2694         status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK);
2695         if (!NT_STATUS_IS_OK(status)) {
2696                 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2697                        "%s\n", nt_errstr(status));
2698                 goto fail_nofd;
2699         }
2700         alarm(0);
2701
2702         seconds = timeval_elapsed(&start);
2703
2704         printf("Parent got the lock after %.2f seconds.\n",
2705                 seconds);
2706
2707         status = cli_close(cli1, fnum);
2708         if (!NT_STATUS_IS_OK(status)) {
2709                 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2710                 goto fail;
2711         }
2712
2713         correct = true;
2714
2715 fail:
2716         cli_close(cli1, fnum);
2717         torture_close_connection(cli1);
2718
2719 fail_nofd:
2720
2721         printf("finished locktest9\n");
2722         return correct;
2723 }
2724
2725 /*
2726 test whether fnums and tids open on one VC are available on another (a major
2727 security hole)
2728 */
2729 static bool run_fdpasstest(int dummy)
2730 {
2731         struct cli_state *cli1, *cli2;
2732         const char *fname = "\\fdpass.tst";
2733         uint16_t fnum1;
2734         char buf[1024];
2735         NTSTATUS status;
2736
2737         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2738                 return False;
2739         }
2740         smbXcli_conn_set_sockopt(cli1->conn, sockops);
2741         smbXcli_conn_set_sockopt(cli2->conn, sockops);
2742
2743         printf("starting fdpasstest\n");
2744
2745         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2746
2747         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2748                           &fnum1);
2749         if (!NT_STATUS_IS_OK(status)) {
2750                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2751                 return False;
2752         }
2753
2754         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2755                               13, NULL);
2756         if (!NT_STATUS_IS_OK(status)) {
2757                 printf("write failed (%s)\n", nt_errstr(status));
2758                 return False;
2759         }
2760
2761         cli_state_set_uid(cli2, cli_state_get_uid(cli1));
2762         cli_state_set_tid(cli2, cli_state_get_tid(cli1));
2763         cli_setpid(cli2, cli_getpid(cli1));
2764
2765         if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
2766                 printf("read succeeded! nasty security hole [%s]\n", buf);
2767                 return false;
2768         }
2769
2770         cli_close(cli1, fnum1);
2771         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2772
2773         torture_close_connection(cli1);
2774         torture_close_connection(cli2);
2775
2776         printf("finished fdpasstest\n");
2777         return True;
2778 }
2779
2780 static bool run_fdsesstest(int dummy)
2781 {
2782         struct cli_state *cli;
2783         uint16_t new_vuid;
2784         uint16_t saved_vuid;
2785         uint32_t new_cnum;
2786         uint32_t saved_cnum;
2787         const char *fname = "\\fdsess.tst";
2788         const char *fname1 = "\\fdsess1.tst";
2789         uint16_t fnum1;
2790         uint16_t fnum2;
2791         char buf[1024];
2792         bool ret = True;
2793         NTSTATUS status;
2794
2795         if (!torture_open_connection(&cli, 0))
2796                 return False;
2797         smbXcli_conn_set_sockopt(cli->conn, sockops);
2798
2799         if (!torture_cli_session_setup2(cli, &new_vuid))
2800                 return False;
2801
2802         saved_cnum = cli_state_get_tid(cli);
2803         if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", NULL)))
2804                 return False;
2805         new_cnum = cli_state_get_tid(cli);
2806         cli_state_set_tid(cli, saved_cnum);
2807
2808         printf("starting fdsesstest\n");
2809
2810         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2811         cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2812
2813         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2814         if (!NT_STATUS_IS_OK(status)) {
2815                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2816                 return False;
2817         }
2818
2819         status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2820                               NULL);
2821         if (!NT_STATUS_IS_OK(status)) {
2822                 printf("write failed (%s)\n", nt_errstr(status));
2823                 return False;
2824         }
2825
2826         saved_vuid = cli_state_get_uid(cli);
2827         cli_state_set_uid(cli, new_vuid);
2828
2829         if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2830                 printf("read succeeded with different vuid! "
2831                        "nasty security hole [%s]\n", buf);
2832                 ret = false;
2833         }
2834         /* Try to open a file with different vuid, samba cnum. */
2835         if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2836                 printf("create with different vuid, same cnum succeeded.\n");
2837                 cli_close(cli, fnum2);
2838                 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2839         } else {
2840                 printf("create with different vuid, same cnum failed.\n");
2841                 printf("This will cause problems with service clients.\n");
2842                 ret = False;
2843         }
2844
2845         cli_state_set_uid(cli, saved_vuid);
2846
2847         /* Try with same vuid, different cnum. */
2848         cli_state_set_tid(cli, new_cnum);
2849
2850         if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2851                 printf("read succeeded with different cnum![%s]\n", buf);
2852                 ret = false;
2853         }
2854
2855         cli_state_set_tid(cli, saved_cnum);
2856         cli_close(cli, fnum1);
2857         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2858
2859         torture_close_connection(cli);
2860
2861         printf("finished fdsesstest\n");
2862         return ret;
2863 }
2864
2865 /*
2866   This test checks that 
2867
2868   1) the server does not allow an unlink on a file that is open
2869 */
2870 static bool run_unlinktest(int dummy)
2871 {
2872         struct cli_state *cli;
2873         const char *fname = "\\unlink.tst";
2874         uint16_t fnum;
2875         bool correct = True;
2876         NTSTATUS status;
2877
2878         if (!torture_open_connection(&cli, 0)) {
2879                 return False;
2880         }
2881
2882         smbXcli_conn_set_sockopt(cli->conn, sockops);
2883
2884         printf("starting unlink test\n");
2885
2886         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2887
2888         cli_setpid(cli, 1);
2889
2890         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2891         if (!NT_STATUS_IS_OK(status)) {
2892                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2893                 return False;
2894         }
2895
2896         status = cli_unlink(cli, fname,
2897                             FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2898         if (NT_STATUS_IS_OK(status)) {
2899                 printf("error: server allowed unlink on an open file\n");
2900                 correct = False;
2901         } else {
2902                 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
2903                                       NT_STATUS_SHARING_VIOLATION);
2904         }
2905
2906         cli_close(cli, fnum);
2907         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2908
2909         if (!torture_close_connection(cli)) {
2910                 correct = False;
2911         }
2912
2913         printf("unlink test finished\n");
2914
2915         return correct;
2916 }
2917
2918
2919 /*
2920 test how many open files this server supports on the one socket
2921 */
2922 static bool run_maxfidtest(int dummy)
2923 {
2924         struct cli_state *cli;
2925         fstring fname;
2926         uint16_t fnums[0x11000];
2927         int i;
2928         int retries=4;
2929         bool correct = True;
2930         NTSTATUS status;
2931
2932         cli = current_cli;
2933
2934         if (retries <= 0) {
2935                 printf("failed to connect\n");
2936                 return False;
2937         }
2938
2939         smbXcli_conn_set_sockopt(cli->conn, sockops);
2940
2941         for (i=0; i<0x11000; i++) {
2942                 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2943                 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2944                                   &fnums[i]);
2945                 if (!NT_STATUS_IS_OK(status)) {
2946                         printf("open of %s failed (%s)\n", 
2947                                fname, nt_errstr(status));
2948                         printf("maximum fnum is %d\n", i);
2949                         break;
2950                 }
2951                 printf("%6d\r", i);
2952         }
2953         printf("%6d\n", i);
2954         i--;
2955
2956         printf("cleaning up\n");
2957         for (;i>=0;i--) {
2958                 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2959                 cli_close(cli, fnums[i]);
2960
2961                 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2962                 if (!NT_STATUS_IS_OK(status)) {
2963                         printf("unlink of %s failed (%s)\n", 
2964                                fname, nt_errstr(status));
2965                         correct = False;
2966                 }
2967                 printf("%6d\r", i);
2968         }
2969         printf("%6d\n", 0);
2970
2971         printf("maxfid test finished\n");
2972         if (!torture_close_connection(cli)) {
2973                 correct = False;
2974         }
2975         return correct;
2976 }
2977
2978 /* generate a random buffer */
2979 static void rand_buf(char *buf, int len)
2980 {
2981         while (len--) {
2982                 *buf = (char)sys_random();
2983                 buf++;
2984         }
2985 }
2986
2987 /* send smb negprot commands, not reading the response */
2988 static bool run_negprot_nowait(int dummy)
2989 {
2990         struct tevent_context *ev;
2991         int i;
2992         struct cli_state *cli;
2993         bool correct = True;
2994
2995         printf("starting negprot nowait test\n");
2996
2997         ev = samba_tevent_context_init(talloc_tos());
2998         if (ev == NULL) {
2999                 return false;
3000         }
3001
3002         if (!(cli = open_nbt_connection())) {
3003                 TALLOC_FREE(ev);
3004                 return False;
3005         }
3006
3007         for (i=0;i<50000;i++) {
3008                 struct tevent_req *req;
3009
3010                 req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout,
3011                                            PROTOCOL_CORE, PROTOCOL_NT1, 0);
3012                 if (req == NULL) {
3013                         TALLOC_FREE(ev);
3014                         return false;
3015                 }
3016                 if (!tevent_req_poll(req, ev)) {
3017                         d_fprintf(stderr, "tevent_req_poll failed: %s\n",
3018                                   strerror(errno));
3019                         TALLOC_FREE(ev);
3020                         return false;
3021                 }
3022                 TALLOC_FREE(req);
3023         }
3024
3025         if (torture_close_connection(cli)) {
3026                 correct = False;
3027         }
3028
3029         printf("finished negprot nowait test\n");
3030
3031         return correct;
3032 }
3033
3034 /* send smb negprot commands, not reading the response */
3035 static bool run_bad_nbt_session(int dummy)
3036 {
3037         struct nmb_name called, calling;
3038         struct sockaddr_storage ss;
3039         NTSTATUS status;
3040         int fd;
3041         bool ret;
3042
3043         printf("starting bad nbt session test\n");
3044
3045         make_nmb_name(&calling, myname, 0x0);
3046         make_nmb_name(&called , host, 0x20);
3047
3048         if (!resolve_name(host, &ss, 0x20, true)) {
3049                 d_fprintf(stderr, "Could not resolve name %s\n", host);
3050                 return false;
3051         }
3052
3053         status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
3054         if (!NT_STATUS_IS_OK(status)) {
3055                 d_fprintf(stderr, "open_socket_out failed: %s\n",
3056                           nt_errstr(status));
3057                 return false;
3058         }
3059
3060         ret = cli_bad_session_request(fd, &calling, &called);
3061         close(fd);
3062         if (!ret) {
3063                 d_fprintf(stderr, "open_socket_out failed: %s\n",
3064                           nt_errstr(status));
3065                 return false;
3066         }
3067
3068         printf("finished bad nbt session test\n");
3069         return true;
3070 }
3071
3072 /* send random IPC commands */
3073 static bool run_randomipc(int dummy)
3074 {
3075         char *rparam = NULL;
3076         char *rdata = NULL;
3077         unsigned int rdrcnt,rprcnt;
3078         char param[1024];
3079         int api, param_len, i;
3080         struct cli_state *cli;
3081         bool correct = True;
3082         int count = 50000;
3083
3084         printf("starting random ipc test\n");
3085
3086         if (!torture_open_connection(&cli, 0)) {
3087                 return False;
3088         }
3089
3090         for (i=0;i<count;i++) {
3091                 api = sys_random() % 500;
3092                 param_len = (sys_random() % 64);
3093
3094                 rand_buf(param, param_len);
3095
3096                 SSVAL(param,0,api); 
3097
3098                 cli_api(cli, 
3099                         param, param_len, 8,  
3100                         NULL, 0, CLI_BUFFER_SIZE,
3101                         &rparam, &rprcnt,     
3102                         &rdata, &rdrcnt);
3103                 if (i % 100 == 0) {
3104                         printf("%d/%d\r", i,count);
3105                 }
3106         }
3107         printf("%d/%d\n", i, count);
3108
3109         if (!torture_close_connection(cli)) {
3110                 correct = False;
3111         }
3112
3113         SAFE_FREE(rparam);
3114         SAFE_FREE(rdata);
3115
3116         printf("finished random ipc test\n");
3117
3118         return correct;
3119 }
3120
3121
3122
3123 static void browse_callback(const char *sname, uint32_t stype,
3124                             const char *comment, void *state)
3125 {
3126         printf("\t%20.20s %08x %s\n", sname, stype, comment);
3127 }
3128
3129
3130
3131 /*
3132   This test checks the browse list code
3133
3134 */
3135 static bool run_browsetest(int dummy)
3136 {
3137         static struct cli_state *cli;
3138         bool correct = True;
3139
3140         printf("starting browse test\n");
3141
3142         if (!torture_open_connection(&cli, 0)) {
3143                 return False;
3144         }
3145
3146         printf("domain list:\n");
3147         cli_NetServerEnum(cli, cli->server_domain, 
3148                           SV_TYPE_DOMAIN_ENUM,
3149                           browse_callback, NULL);
3150
3151         printf("machine list:\n");
3152         cli_NetServerEnum(cli, cli->server_domain, 
3153                           SV_TYPE_ALL,
3154                           browse_callback, NULL);
3155
3156         if (!torture_close_connection(cli)) {
3157                 correct = False;
3158         }
3159
3160         printf("browse test finished\n");
3161
3162         return correct;
3163
3164 }
3165
3166 static bool check_attributes(struct cli_state *cli,
3167                                 const char *fname,
3168                                 uint16_t expected_attrs)
3169 {
3170         uint16_t attrs = 0;
3171         NTSTATUS status = cli_getatr(cli,
3172                                 fname,
3173                                 &attrs,
3174                                 NULL,
3175                                 NULL);
3176         if (!NT_STATUS_IS_OK(status)) {
3177                 printf("cli_getatr failed with %s\n",
3178                         nt_errstr(status));
3179                 return false;
3180         }
3181         if (attrs != expected_attrs) {
3182                 printf("Attributes incorrect 0x%x, should be 0x%x\n",
3183                         (unsigned int)attrs,
3184                         (unsigned int)expected_attrs);
3185                 return false;
3186         }
3187         return true;
3188 }
3189
3190 /*
3191   This checks how the getatr calls works
3192 */
3193 static bool run_attrtest(int dummy)
3194 {
3195         struct cli_state *cli;
3196         uint16_t fnum;
3197         time_t t, t2;
3198         const char *fname = "\\attrib123456789.tst";
3199         bool correct = True;
3200         NTSTATUS status;
3201
3202         printf("starting attrib test\n");
3203
3204         if (!torture_open_connection(&cli, 0)) {
3205                 return False;
3206         }
3207
3208         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3209         cli_openx(cli, fname, 
3210                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3211         cli_close(cli, fnum);
3212
3213         status = cli_getatr(cli, fname, NULL, NULL, &t);
3214         if (!NT_STATUS_IS_OK(status)) {
3215                 printf("getatr failed (%s)\n", nt_errstr(status));
3216                 correct = False;
3217         }
3218
3219         if (labs(t - time(NULL)) > 60*60*24*10) {
3220                 printf("ERROR: SMBgetatr bug. time is %s",
3221                        ctime(&t));
3222                 t = time(NULL);
3223                 correct = True;
3224         }
3225
3226         t2 = t-60*60*24; /* 1 day ago */
3227
3228         status = cli_setatr(cli, fname, 0, t2);
3229         if (!NT_STATUS_IS_OK(status)) {
3230                 printf("setatr failed (%s)\n", nt_errstr(status));
3231                 correct = True;
3232         }
3233
3234         status = cli_getatr(cli, fname, NULL, NULL, &t);
3235         if (!NT_STATUS_IS_OK(status)) {
3236                 printf("getatr failed (%s)\n", nt_errstr(status));
3237                 correct = True;
3238         }
3239
3240         if (t != t2) {
3241                 printf("ERROR: getatr/setatr bug. times are\n%s",
3242                        ctime(&t));
3243                 printf("%s", ctime(&t2));
3244                 correct = True;
3245         }
3246
3247         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3248
3249         /* Check cli_setpathinfo_basic() */
3250         /* Re-create the file. */
3251         status = cli_openx(cli, fname,
3252                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3253         if (!NT_STATUS_IS_OK(status)) {
3254                 printf("Failed to recreate %s (%s)\n",
3255                         fname, nt_errstr(status));
3256                 correct = false;
3257         }
3258         cli_close(cli, fnum);
3259
3260         status = cli_setpathinfo_basic(cli,
3261                                         fname,
3262                                         0, /* create */
3263                                         0, /* access */
3264                                         0, /* write */
3265                                         0, /* change */
3266                                         FILE_ATTRIBUTE_SYSTEM |
3267                                         FILE_ATTRIBUTE_HIDDEN |
3268                                         FILE_ATTRIBUTE_READONLY);
3269         if (!NT_STATUS_IS_OK(status)) {
3270                 printf("cli_setpathinfo_basic failed with %s\n",
3271                         nt_errstr(status));
3272                 correct = false;
3273         }
3274
3275         /* Check attributes are correct. */
3276         correct = check_attributes(cli,
3277                         fname,
3278                         FILE_ATTRIBUTE_SYSTEM |
3279                         FILE_ATTRIBUTE_HIDDEN |
3280                         FILE_ATTRIBUTE_READONLY);
3281         if (correct == false) {
3282                 goto out;
3283         }
3284
3285         /* Setting to FILE_ATTRIBUTE_NORMAL should be ignored. */
3286         status = cli_setpathinfo_basic(cli,
3287                                         fname,
3288                                         0, /* create */
3289                                         0, /* access */
3290                                         0, /* write */
3291                                         0, /* change */
3292                                         FILE_ATTRIBUTE_NORMAL);
3293         if (!NT_STATUS_IS_OK(status)) {
3294                 printf("cli_setpathinfo_basic failed with %s\n",
3295                         nt_errstr(status));
3296                 correct = false;
3297         }
3298
3299         /* Check attributes are correct. */
3300         correct = check_attributes(cli,
3301                         fname,
3302                         FILE_ATTRIBUTE_SYSTEM |
3303                         FILE_ATTRIBUTE_HIDDEN |
3304                         FILE_ATTRIBUTE_READONLY);
3305         if (correct == false) {
3306                 goto out;
3307         }
3308
3309         /* Setting to (uint16_t)-1 should also be ignored. */
3310         status = cli_setpathinfo_basic(cli,
3311                                         fname,
3312                                         0, /* create */
3313                                         0, /* access */
3314                                         0, /* write */
3315                                         0, /* change */
3316                                         (uint16_t)-1);
3317         if (!NT_STATUS_IS_OK(status)) {
3318                 printf("cli_setpathinfo_basic failed with %s\n",
3319                         nt_errstr(status));
3320                 correct = false;
3321         }
3322
3323         /* Check attributes are correct. */
3324         correct = check_attributes(cli,
3325                         fname,
3326                         FILE_ATTRIBUTE_SYSTEM |
3327                         FILE_ATTRIBUTE_HIDDEN |
3328                         FILE_ATTRIBUTE_READONLY);
3329         if (correct == false) {
3330                 goto out;
3331         }
3332
3333         /* Setting to 0 should clear them all. */
3334         status = cli_setpathinfo_basic(cli,
3335                                         fname,
3336                                         0, /* create */
3337                                         0, /* access */
3338                                         0, /* write */
3339                                         0, /* change */
3340                                         0);
3341         if (!NT_STATUS_IS_OK(status)) {
3342                 printf("cli_setpathinfo_basic failed with %s\n",
3343                         nt_errstr(status));
3344                 correct = false;
3345         }
3346
3347         /* Check attributes are correct. */
3348         correct = check_attributes(cli,
3349                         fname,
3350                         FILE_ATTRIBUTE_NORMAL);
3351         if (correct == false) {
3352                 goto out;
3353         }
3354
3355   out:
3356
3357         cli_unlink(cli,
3358                 fname,
3359                 FILE_ATTRIBUTE_SYSTEM |
3360                 FILE_ATTRIBUTE_HIDDEN|
3361                 FILE_ATTRIBUTE_READONLY);
3362
3363         if (!torture_close_connection(cli)) {
3364                 correct = False;
3365         }
3366
3367         printf("attrib test finished\n");
3368
3369         return correct;
3370 }
3371
3372
3373 /*
3374   This checks a couple of trans2 calls
3375 */
3376 static bool run_trans2test(int dummy)
3377 {
3378         struct cli_state *cli;
3379         uint16_t fnum;
3380         off_t size;
3381         time_t c_time, a_time, m_time;
3382         struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3383         const char *fname = "\\trans2.tst";
3384         const char *dname = "\\trans2";
3385         const char *fname2 = "\\trans2\\trans2.tst";
3386         char *pname;
3387         bool correct = True;
3388         NTSTATUS status;
3389         uint32_t fs_attr;
3390
3391         printf("starting trans2 test\n");
3392
3393         if (!torture_open_connection(&cli, 0)) {
3394                 return False;
3395         }
3396
3397         status = cli_get_fs_attr_info(cli, &fs_attr);
3398         if (!NT_STATUS_IS_OK(status)) {
3399                 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3400                        nt_errstr(status));
3401                 correct = false;
3402         }
3403
3404         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3405         cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3406         status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3407                                      &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3408         if (!NT_STATUS_IS_OK(status)) {
3409                 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3410                 correct = False;
3411         }
3412
3413         status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3414         if (!NT_STATUS_IS_OK(status)) {
3415                 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3416                 correct = False;
3417         }
3418         else if (strcmp(pname, fname)) {
3419                 printf("qfilename gave different name? [%s] [%s]\n",
3420                        fname, pname);
3421                 correct = False;
3422         }
3423
3424         cli_close(cli, fnum);
3425
3426         sleep(2);
3427
3428         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3429         status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3430                           &fnum);
3431         if (!NT_STATUS_IS_OK(status)) {
3432                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3433                 return False;
3434         }
3435         cli_close(cli, fnum);
3436
3437         status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3438                                 NULL);
3439         if (!NT_STATUS_IS_OK(status)) {
3440                 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3441                 correct = False;
3442         } else {
3443                 time_t t = time(NULL);
3444
3445                 if (c_time != m_time) {
3446                         printf("create time=%s", ctime(&c_time));
3447                         printf("modify time=%s", ctime(&m_time));
3448                         printf("This system appears to have sticky create times\n");
3449                 }
3450                 if ((labs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
3451                         printf("access time=%s", ctime(&a_time));
3452                         printf("This system appears to set a midnight access time\n");
3453                         correct = False;
3454                 }
3455
3456                 if (labs(m_time - t) > 60*60*24*7) {
3457                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3458                         correct = False;
3459                 }
3460         }
3461
3462
3463         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3464         cli_openx(cli, fname, 
3465                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3466         cli_close(cli, fnum);
3467         status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3468                                 &m_time_ts, &size, NULL, NULL);
3469         if (!NT_STATUS_IS_OK(status)) {
3470                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3471                 correct = False;
3472         } else {
3473                 if (w_time_ts.tv_sec < 60*60*24*2) {
3474                         printf("write time=%s", ctime(&w_time_ts.tv_sec));
3475                         printf("This system appears to set a initial 0 write time\n");
3476                         correct = False;
3477                 }
3478         }
3479
3480         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3481
3482
3483         /* check if the server updates the directory modification time
3484            when creating a new file */
3485         status = cli_mkdir(cli, dname);
3486         if (!NT_STATUS_IS_OK(status)) {
3487                 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3488                 correct = False;
3489         }
3490         sleep(3);
3491         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3492                                 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3493         if (!NT_STATUS_IS_OK(status)) {
3494                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3495                 correct = False;
3496         }
3497
3498         cli_openx(cli, fname2, 
3499                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3500         cli_writeall(cli, fnum,  0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3501         cli_close(cli, fnum);
3502         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3503                                 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3504         if (!NT_STATUS_IS_OK(status)) {
3505                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3506                 correct = False;
3507         } else {
3508                 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3509                     == 0) {
3510                         printf("This system does not update directory modification times\n");
3511                         correct = False;
3512                 }
3513         }
3514         cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3515         cli_rmdir(cli, dname);
3516
3517         if (!torture_close_connection(cli)) {
3518                 correct = False;
3519         }
3520
3521         printf("trans2 test finished\n");
3522
3523         return correct;
3524 }
3525
3526 /*
3527   This checks new W2K calls.
3528 */
3529
3530 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3531 {
3532         uint8_t *buf = NULL;
3533         uint32_t len;
3534         NTSTATUS status;
3535
3536         status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3537                                CLI_BUFFER_SIZE, NULL, &buf, &len);
3538         if (!NT_STATUS_IS_OK(status)) {
3539                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3540                        nt_errstr(status));
3541         } else {
3542                 printf("qfileinfo: level %d, len = %u\n", level, len);
3543                 dump_data(0, (uint8_t *)buf, len);
3544                 printf("\n");
3545         }
3546         TALLOC_FREE(buf);
3547         return status;
3548 }
3549
3550 static bool run_w2ktest(int dummy)
3551 {
3552         struct cli_state *cli;
3553         uint16_t fnum;
3554         const char *fname = "\\w2ktest\\w2k.tst";
3555         int level;
3556         bool correct = True;
3557
3558         printf("starting w2k test\n");
3559
3560         if (!torture_open_connection(&cli, 0)) {
3561                 return False;
3562         }
3563
3564         cli_openx(cli, fname, 
3565                         O_RDWR | O_CREAT , DENY_NONE, &fnum);
3566
3567         for (level = 1004; level < 1040; level++) {
3568                 new_trans(cli, fnum, level);
3569         }
3570
3571         cli_close(cli, fnum);
3572
3573         if (!torture_close_connection(cli)) {
3574                 correct = False;
3575         }
3576
3577         printf("w2k test finished\n");
3578
3579         return correct;
3580 }
3581
3582
3583 /*
3584   this is a harness for some oplock tests
3585  */
3586 static bool run_oplock1(int dummy)
3587 {
3588         struct cli_state *cli1;
3589         const char *fname = "\\lockt1.lck";
3590         uint16_t fnum1;
3591         bool correct = True;
3592         NTSTATUS status;
3593
3594         printf("starting oplock test 1\n");
3595
3596         if (!torture_open_connection(&cli1, 0)) {
3597                 return False;
3598         }
3599
3600         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3601
3602         smbXcli_conn_set_sockopt(cli1->conn, sockops);
3603
3604         cli1->use_oplocks = True;
3605
3606         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3607                           &fnum1);
3608         if (!NT_STATUS_IS_OK(status)) {
3609                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3610                 return False;
3611         }
3612
3613         cli1->use_oplocks = False;
3614
3615         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3616         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3617
3618         status = cli_close(cli1, fnum1);
3619         if (!NT_STATUS_IS_OK(status)) {
3620                 printf("close2 failed (%s)\n", nt_errstr(status));
3621                 return False;
3622         }
3623
3624         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3625         if (!NT_STATUS_IS_OK(status)) {
3626                 printf("unlink failed (%s)\n", nt_errstr(status));
3627                 return False;
3628         }
3629
3630         if (!torture_close_connection(cli1)) {
3631                 correct = False;
3632         }
3633
3634         printf("finished oplock test 1\n");
3635
3636         return correct;
3637 }
3638
3639 static bool run_oplock2(int dummy)
3640 {
3641         struct cli_state *cli1, *cli2;
3642         const char *fname = "\\lockt2.lck";
3643         uint16_t fnum1, fnum2;
3644         int saved_use_oplocks = use_oplocks;
3645         char buf[4];
3646         bool correct = True;
3647         volatile bool *shared_correct;
3648         size_t nread;
3649         NTSTATUS status;
3650
3651         shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
3652         *shared_correct = True;
3653
3654         use_level_II_oplocks = True;
3655         use_oplocks = True;
3656
3657         printf("starting oplock test 2\n");
3658
3659         if (!torture_open_connection(&cli1, 0)) {
3660                 use_level_II_oplocks = False;
3661                 use_oplocks = saved_use_oplocks;
3662                 return False;
3663         }
3664
3665         if (!torture_open_connection(&cli2, 1)) {
3666                 use_level_II_oplocks = False;
3667                 use_oplocks = saved_use_oplocks;
3668                 return False;
3669         }
3670
3671         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3672
3673         smbXcli_conn_set_sockopt(cli1->conn, sockops);
3674         smbXcli_conn_set_sockopt(cli2->conn, sockops);
3675
3676         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3677                           &fnum1);
3678         if (!NT_STATUS_IS_OK(status)) {
3679                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3680                 return False;
3681         }
3682
3683         /* Don't need the globals any more. */
3684         use_level_II_oplocks = False;
3685         use_oplocks = saved_use_oplocks;
3686
3687         if (fork() == 0) {
3688                 /* Child code */
3689                 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3690                 if (!NT_STATUS_IS_OK(status)) {
3691                         printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3692                         *shared_correct = False;
3693                         exit(0);
3694                 }
3695
3696                 sleep(2);
3697
3698                 status = cli_close(cli2, fnum2);
3699                 if (!NT_STATUS_IS_OK(status)) {
3700                         printf("close2 failed (%s)\n", nt_errstr(status));
3701                         *shared_correct = False;
3702                 }
3703
3704                 exit(0);
3705         }
3706
3707         sleep(2);
3708
3709         /* Ensure cli1 processes the break. Empty file should always return 0
3710          * bytes.  */
3711         status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
3712         if (!NT_STATUS_IS_OK(status)) {
3713                 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
3714                 correct = false;
3715         } else if (nread != 0) {
3716                 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3717                       (unsigned long)nread, 0);
3718                 correct = false;
3719         }
3720
3721         /* Should now be at level II. */
3722         /* Test if sending a write locks causes a break to none. */
3723         status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
3724         if (!NT_STATUS_IS_OK(status)) {
3725                 printf("lock failed (%s)\n", nt_errstr(status));
3726                 correct = False;
3727         }
3728
3729         cli_unlock(cli1, fnum1, 0, 4);
3730
3731         sleep(2);
3732
3733         status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
3734         if (!NT_STATUS_IS_OK(status)) {
3735                 printf("lock failed (%s)\n", nt_errstr(status));
3736                 correct = False;
3737         }
3738
3739         cli_unlock(cli1, fnum1, 0, 4);
3740
3741         sleep(2);
3742
3743         cli_read(cli1, fnum1, buf, 0, 4, NULL);
3744
3745         status = cli_close(cli1, fnum1);
3746         if (!NT_STATUS_IS_OK(status)) {
3747                 printf("close1 failed (%s)\n", nt_errstr(status));
3748                 correct = False;
3749         }
3750
3751         sleep(4);
3752
3753         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3754         if (!NT_STATUS_IS_OK(status)) {
3755                 printf("unlink failed (%s)\n", nt_errstr(status));
3756                 correct = False;
3757         }
3758
3759         if (!torture_close_connection(cli1)) {
3760                 correct = False;
3761         }
3762
3763         if (!*shared_correct) {
3764                 correct = False;
3765         }
3766
3767         printf("finished oplock test 2\n");
3768
3769         return correct;
3770 }
3771
3772 struct oplock4_state {
3773         struct tevent_context *ev;
3774         struct cli_state *cli;
3775         bool *got_break;
3776         uint16_t *fnum2;
3777 };
3778
3779 static void oplock4_got_break(struct tevent_req *req);
3780 static void oplock4_got_open(struct tevent_req *req);
3781
3782 static bool run_oplock4(int dummy)
3783 {
3784         struct tevent_context *ev;
3785         struct cli_state *cli1, *cli2;
3786         struct tevent_req *oplock_req, *open_req;
3787         const char *fname = "\\lockt4.lck";
3788         const char *fname_ln = "\\lockt4_ln.lck";
3789         uint16_t fnum1, fnum2;
3790         int saved_use_oplocks = use_oplocks;
3791         NTSTATUS status;
3792         bool correct = true;
3793
3794         bool got_break;
3795
3796         struct oplock4_state *state;
3797
3798         printf("starting oplock test 4\n");
3799
3800         if (!torture_open_connection(&cli1, 0)) {
3801                 use_level_II_oplocks = false;
3802                 use_oplocks = saved_use_oplocks;
3803                 return false;
3804         }
3805
3806         if (!torture_open_connection(&cli2, 1)) {
3807                 use_level_II_oplocks = false;
3808                 use_oplocks = saved_use_oplocks;
3809                 return false;
3810         }
3811
3812         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3813         cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3814
3815         smbXcli_conn_set_sockopt(cli1->conn, sockops);
3816         smbXcli_conn_set_sockopt(cli2->conn, sockops);
3817
3818         /* Create the file. */
3819         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3820                           &fnum1);
3821         if (!NT_STATUS_IS_OK(status)) {
3822                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3823                 return false;
3824         }
3825
3826         status = cli_close(cli1, fnum1);
3827         if (!NT_STATUS_IS_OK(status)) {
3828                 printf("close1 failed (%s)\n", nt_errstr(status));
3829                 return false;
3830         }
3831
3832         /* Now create a hardlink. */
3833         status = cli_nt_hardlink(cli1, fname, fname_ln);
3834         if (!NT_STATUS_IS_OK(status)) {
3835                 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3836                 return false;
3837         }
3838
3839         /* Prove that opening hardlinks cause deny modes to conflict. */
3840         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3841         if (!NT_STATUS_IS_OK(status)) {
3842                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3843                 return false;
3844         }
3845
3846         status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3847         if (NT_STATUS_IS_OK(status)) {
3848                 printf("open of %s succeeded - should fail with sharing violation.\n",
3849                         fname_ln);
3850                 return false;
3851         }
3852
3853         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3854                 printf("open of %s should fail with sharing violation. Got %s\n",
3855                         fname_ln, nt_errstr(status));
3856                 return false;
3857         }
3858
3859         status = cli_close(cli1, fnum1);
3860         if (!NT_STATUS_IS_OK(status)) {
3861                 printf("close1 failed (%s)\n", nt_errstr(status));
3862                 return false;
3863         }
3864
3865         cli1->use_oplocks = true;
3866         cli2->use_oplocks = true;
3867
3868         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3869         if (!NT_STATUS_IS_OK(status)) {
3870                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3871                 return false;
3872         }
3873
3874         ev = samba_tevent_context_init(talloc_tos());
3875         if (ev == NULL) {
3876                 printf("tevent_context_init failed\n");
3877                 return false;
3878         }
3879
3880         state = talloc(ev, struct oplock4_state);
3881         if (state == NULL) {
3882                 printf("talloc failed\n");
3883                 return false;
3884         }
3885         state->ev = ev;
3886         state->cli = cli1;
3887         state->got_break = &got_break;
3888         state->fnum2 = &fnum2;
3889
3890         oplock_req = cli_smb_oplock_break_waiter_send(
3891                 talloc_tos(), ev, cli1);
3892         if (oplock_req == NULL) {
3893                 printf("cli_smb_oplock_break_waiter_send failed\n");
3894                 return false;
3895         }
3896         tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3897
3898         open_req = cli_openx_send(
3899                 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3900         if (open_req == NULL) {
3901                 printf("cli_openx_send failed\n");
3902                 return false;
3903         }
3904         tevent_req_set_callback(open_req, oplock4_got_open, state);
3905
3906         got_break = false;
3907         fnum2 = 0xffff;
3908
3909         while (!got_break || fnum2 == 0xffff) {
3910                 int ret;
3911                 ret = tevent_loop_once(ev);
3912                 if (ret == -1) {
3913                         printf("tevent_loop_once failed: %s\n",
3914                                strerror(errno));
3915                         return false;
3916                 }
3917         }
3918
3919         status = cli_close(cli2, fnum2);
3920         if (!NT_STATUS_IS_OK(status)) {
3921                 printf("close2 failed (%s)\n", nt_errstr(status));
3922                 correct = false;
3923         }
3924
3925         status = cli_close(cli1, fnum1);
3926         if (!NT_STATUS_IS_OK(status)) {
3927                 printf("close1 failed (%s)\n", nt_errstr(status));
3928                 correct = false;
3929         }
3930
3931         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3932         if (!NT_STATUS_IS_OK(status)) {
3933                 printf("unlink failed (%s)\n", nt_errstr(status));
3934                 correct = false;
3935         }
3936
3937         status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3938         if (!NT_STATUS_IS_OK(status)) {
3939                 printf("unlink failed (%s)\n", nt_errstr(status));
3940                 correct = false;
3941         }
3942
3943         if (!torture_close_connection(cli1)) {
3944                 correct = false;
3945         }
3946
3947         if (!got_break) {
3948                 correct = false;
3949         }
3950
3951         printf("finished oplock test 4\n");
3952
3953         return correct;
3954 }
3955
3956 static void oplock4_got_break(struct tevent_req *req)
3957 {
3958         struct oplock4_state *state = tevent_req_callback_data(
3959                 req, struct oplock4_state);
3960         uint16_t fnum;
3961         uint8_t level;
3962         NTSTATUS status;
3963
3964         status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3965         TALLOC_FREE(req);
3966         if (!NT_STATUS_IS_OK(status)) {
3967                 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3968                        nt_errstr(status));
3969                 return;
3970         }
3971         *state->got_break = true;
3972
3973         req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3974                                   NO_OPLOCK);
3975         if (req == NULL) {
3976                 printf("cli_oplock_ack_send failed\n");
3977                 return;
3978         }
3979 }
3980
3981 static void oplock4_got_open(struct tevent_req *req)
3982 {
3983         struct oplock4_state *state = tevent_req_callback_data(
3984                 req, struct oplock4_state);
3985         NTSTATUS status;
3986
3987         status = cli_openx_recv(req, state->fnum2);
3988         if (!NT_STATUS_IS_OK(status)) {
3989                 printf("cli_openx_recv returned %s\n", nt_errstr(status));
3990                 *state->fnum2 = 0xffff;
3991         }
3992 }
3993
3994 /*
3995   Test delete on close semantics.
3996  */
3997 static bool run_deletetest(int dummy)
3998 {
3999         struct cli_state *cli1 = NULL;
4000         struct cli_state *cli2 = NULL;
4001         const char *fname = "\\delete.file";
4002         uint16_t fnum1 = (uint16_t)-1;
4003         uint16_t fnum2 = (uint16_t)-1;
4004         bool correct = false;
4005         NTSTATUS status;
4006
4007         printf("starting delete test\n");
4008
4009         if (!torture_open_connection(&cli1, 0)) {
4010                 return False;
4011         }
4012
4013         smbXcli_conn_set_sockopt(cli1->conn, sockops);
4014
4015         /* Test 1 - this should delete the file on close. */
4016
4017         cli_setatr(cli1, fname, 0, 0);
4018         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4019
4020         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
4021                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4022                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4023         if (!NT_STATUS_IS_OK(status)) {
4024                 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
4025                 goto fail;
4026         }
4027
4028         status = cli_close(cli1, fnum1);
4029         if (!NT_STATUS_IS_OK(status)) {
4030                 printf("[1] close failed (%s)\n", nt_errstr(status));
4031                 goto fail;
4032         }
4033
4034         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
4035         if (NT_STATUS_IS_OK(status)) {
4036                 printf("[1] open of %s succeeded (should fail)\n", fname);
4037                 goto fail;
4038         }
4039
4040         printf("first delete on close test succeeded.\n");
4041
4042         /* Test 2 - this should delete the file on close. */
4043
4044         cli_setatr(cli1, fname, 0, 0);
4045         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4046
4047         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
4048                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4049                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4050         if (!NT_STATUS_IS_OK(status)) {
4051                 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
4052                 goto fail;
4053         }
4054
4055         status = cli_nt_delete_on_close(cli1, fnum1, true);
4056         if (!NT_STATUS_IS_OK(status)) {
4057                 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
4058                 goto fail;
4059         }
4060
4061         status = cli_close(cli1, fnum1);
4062         if (!NT_STATUS_IS_OK(status)) {
4063                 printf("[2] close failed (%s)\n", nt_errstr(status));
4064                 goto fail;
4065         }
4066
4067         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4068         if (NT_STATUS_IS_OK(status)) {
4069                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
4070                 status = cli_close(cli1, fnum1);
4071                 if (!NT_STATUS_IS_OK(status)) {
4072                         printf("[2] close failed (%s)\n", nt_errstr(status));
4073                 }
4074                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4075                 goto fail;
4076         }
4077
4078         printf("second delete on close test succeeded.\n");
4079
4080         /* Test 3 - ... */
4081         cli_setatr(cli1, fname, 0, 0);
4082         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4083
4084         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
4085                               FILE_ATTRIBUTE_NORMAL,
4086                               FILE_SHARE_READ|FILE_SHARE_WRITE,
4087                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4088         if (!NT_STATUS_IS_OK(status)) {
4089                 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
4090                 goto fail;
4091         }
4092
4093         /* This should fail with a sharing violation - open for delete is only compatible
4094            with SHARE_DELETE. */
4095
4096         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4097                               FILE_ATTRIBUTE_NORMAL,
4098                               FILE_SHARE_READ|FILE_SHARE_WRITE,
4099                               FILE_OPEN, 0, 0, &fnum2, NULL);
4100         if (NT_STATUS_IS_OK(status)) {
4101                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
4102                 goto fail;
4103         }
4104
4105         /* This should succeed. */
4106         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4107                              FILE_ATTRIBUTE_NORMAL,
4108                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4109                              FILE_OPEN, 0, 0, &fnum2, NULL);
4110         if (!NT_STATUS_IS_OK(status)) {
4111                 printf("[3] open  - 3 of %s failed (%s)\n", fname, nt_errstr(status));
4112                 goto fail;
4113         }
4114
4115         status = cli_nt_delete_on_close(cli1, fnum1, true);
4116         if (!NT_STATUS_IS_OK(status)) {
4117                 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
4118                 goto fail;
4119         }
4120
4121         status = cli_close(cli1, fnum1);
4122         if (!NT_STATUS_IS_OK(status)) {
4123                 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
4124                 goto fail;
4125         }
4126
4127         status = cli_close(cli1, fnum2);
4128         if (!NT_STATUS_IS_OK(status)) {
4129                 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
4130                 goto fail;
4131         }
4132
4133         /* This should fail - file should no longer be there. */
4134
4135         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4136         if (NT_STATUS_IS_OK(status)) {
4137                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
4138                 status = cli_close(cli1, fnum1);
4139                 if (!NT_STATUS_IS_OK(status)) {
4140                         printf("[3] close failed (%s)\n", nt_errstr(status));
4141                 }
4142                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4143                 goto fail;
4144         }
4145
4146         printf("third delete on close test succeeded.\n");
4147
4148         /* Test 4 ... */
4149         cli_setatr(cli1, fname, 0, 0);
4150         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4151
4152         status = cli_ntcreate(cli1, fname, 0,
4153                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4154                               FILE_ATTRIBUTE_NORMAL,
4155                               FILE_SHARE_READ|FILE_SHARE_WRITE,
4156                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4157         if (!NT_STATUS_IS_OK(status)) {
4158                 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
4159                 goto fail;
4160         }
4161
4162         /* This should succeed. */
4163         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4164                              FILE_ATTRIBUTE_NORMAL,
4165                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4166                              FILE_OPEN, 0, 0, &fnum2, NULL);
4167         if (!NT_STATUS_IS_OK(status)) {
4168                 printf("[4] open  - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4169                 goto fail;
4170         }
4171
4172         status = cli_close(cli1, fnum2);
4173         if (!NT_STATUS_IS_OK(status)) {
4174                 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
4175                 goto fail;
4176         }
4177
4178         status = cli_nt_delete_on_close(cli1, fnum1, true);
4179         if (!NT_STATUS_IS_OK(status)) {
4180                 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
4181                 goto fail;
4182         }
4183
4184         /* This should fail - no more opens once delete on close set. */
4185         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4186                               FILE_ATTRIBUTE_NORMAL,
4187                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4188                               FILE_OPEN, 0, 0, &fnum2, NULL);
4189         if (NT_STATUS_IS_OK(status)) {
4190                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
4191                 goto fail;
4192         }
4193
4194         status = cli_close(cli1, fnum1);
4195         if (!NT_STATUS_IS_OK(status)) {
4196                 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4197                 goto fail;
4198         }
4199
4200         printf("fourth delete on close test succeeded.\n");
4201
4202         /* Test 5 ... */
4203         cli_setatr(cli1, fname, 0, 0);
4204         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4205
4206         status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4207         if (!NT_STATUS_IS_OK(status)) {
4208                 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4209                 goto fail;
4210         }
4211
4212         /* This should fail - only allowed on NT opens with DELETE access. */
4213
4214         status = cli_nt_delete_on_close(cli1, fnum1, true);
4215         if (NT_STATUS_IS_OK(status)) {
4216                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4217                 goto fail;
4218         }
4219
4220         status = cli_close(cli1, fnum1);
4221         if (!NT_STATUS_IS_OK(status)) {
4222                 printf("[5] close failed (%s)\n", nt_errstr(status));
4223                 goto fail;
4224         }
4225
4226         printf("fifth delete on close test succeeded.\n");
4227
4228         /* Test 6 ... */
4229         cli_setatr(cli1, fname, 0, 0);
4230         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4231
4232         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4233                              FILE_ATTRIBUTE_NORMAL,
4234                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4235                              FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4236         if (!NT_STATUS_IS_OK(status)) {
4237                 printf("[6] open of %s failed (%s)\n", fname,
4238                        nt_errstr(status));
4239                 goto fail;
4240         }
4241
4242         /* This should fail - only allowed on NT opens with DELETE access. */
4243
4244         status = cli_nt_delete_on_close(cli1, fnum1, true);
4245         if (NT_STATUS_IS_OK(status)) {
4246                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4247                 goto fail;
4248         }
4249
4250         status = cli_close(cli1, fnum1);
4251         if (!NT_STATUS_IS_OK(status)) {
4252                 printf("[6] close failed (%s)\n", nt_errstr(status));
4253                 goto fail;
4254         }
4255
4256         printf("sixth delete on close test succeeded.\n");
4257
4258         /* Test 7 ... */
4259         cli_setatr(cli1, fname, 0, 0);
4260         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4261
4262         status = cli_ntcreate(cli1, fname, 0,
4263                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4264                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4265                               0, 0, &fnum1, NULL);
4266         if (!NT_STATUS_IS_OK(status)) {
4267                 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4268                 goto fail;
4269         }
4270
4271         status = cli_nt_delete_on_close(cli1, fnum1, true);
4272         if (!NT_STATUS_IS_OK(status)) {
4273                 printf("[7] setting delete_on_close on file failed !\n");
4274                 goto fail;
4275         }
4276
4277         status = cli_nt_delete_on_close(cli1, fnum1, false);
4278         if (!NT_STATUS_IS_OK(status)) {
4279                 printf("[7] unsetting delete_on_close on file failed !\n");
4280                 goto fail;
4281         }
4282
4283         status = cli_close(cli1, fnum1);
4284         if (!NT_STATUS_IS_OK(status)) {
4285                 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
4286                 goto fail;
4287         }
4288
4289         /* This next open should succeed - we reset the flag. */
4290         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4291         if (!NT_STATUS_IS_OK(status)) {
4292                 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4293                 goto fail;
4294         }
4295
4296         status = cli_close(cli1, fnum1);
4297         if (!NT_STATUS_IS_OK(status)) {
4298                 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4299                 goto fail;
4300         }
4301
4302         printf("seventh delete on close test succeeded.\n");
4303
4304         /* Test 8 ... */
4305         cli_setatr(cli1, fname, 0, 0);
4306         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4307
4308         if (!torture_open_connection(&cli2, 1)) {
4309                 printf("[8] failed to open second connection.\n");
4310                 goto fail;
4311         }
4312
4313         smbXcli_conn_set_sockopt(cli1->conn, sockops);
4314
4315         status = cli_ntcreate(cli1, fname, 0,
4316                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4317                              FILE_ATTRIBUTE_NORMAL,
4318                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4319                              FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4320         if (!NT_STATUS_IS_OK(status)) {
4321                 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4322                 goto fail;
4323         }
4324
4325         status = cli_ntcreate(cli2, fname, 0,
4326                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4327                              FILE_ATTRIBUTE_NORMAL,
4328                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4329                              FILE_OPEN, 0, 0, &fnum2, NULL);
4330         if (!NT_STATUS_IS_OK(status)) {
4331                 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4332                 goto fail;
4333         }
4334
4335         status = cli_nt_delete_on_close(cli1, fnum1, true);
4336         if (!NT_STATUS_IS_OK(status)) {
4337                 printf("[8] setting delete_on_close on file failed !\n");
4338                 goto fail;
4339         }
4340
4341         status = cli_close(cli1, fnum1);
4342         if (!NT_STATUS_IS_OK(status)) {
4343                 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4344                 goto fail;
4345         }
4346
4347         status = cli_close(cli2, fnum2);
4348         if (!NT_STATUS_IS_OK(status)) {
4349                 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4350                 goto fail;
4351         }
4352
4353         /* This should fail.. */
4354         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4355         if (NT_STATUS_IS_OK(status)) {
4356                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4357                 goto fail;
4358         }
4359
4360         printf("eighth delete on close test succeeded.\n");
4361
4362         /* Test 9 ... */
4363
4364         /* This should fail - we need to set DELETE_ACCESS. */
4365         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4366                               FILE_ATTRIBUTE_NORMAL,
4367                               FILE_SHARE_NONE,
4368                               FILE_OVERWRITE_IF,
4369                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4370         if (NT_STATUS_IS_OK(status)) {
4371                 printf("[9] open of %s succeeded should have failed!\n", fname);
4372                 goto fail;
4373         }
4374
4375         printf("ninth delete on close test succeeded.\n");
4376
4377         /* Test 10 ... */
4378
4379         status = cli_ntcreate(cli1, fname, 0,
4380                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4381                              FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4382                              FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4383                              0, &fnum1, NULL);
4384         if (!NT_STATUS_IS_OK(status)) {
4385                 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4386                 goto fail;
4387         }
4388
4389         /* This should delete the file. */
4390         status = cli_close(cli1, fnum1);
4391         if (!NT_STATUS_IS_OK(status)) {
4392                 printf("[10] close failed (%s)\n", nt_errstr(status));
4393                 goto fail;
4394         }
4395
4396         /* This should fail.. */
4397         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4398         if (NT_STATUS_IS_OK(status)) {
4399                 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4400                 goto fail;
4401         }
4402
4403         printf("tenth delete on close test succeeded.\n");
4404
4405         /* Test 11 ... */
4406
4407         cli_setatr(cli1, fname, 0, 0);
4408         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4409
4410         /* Can we open a read-only file with delete access? */
4411
4412         /* Create a readonly file. */
4413         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4414                               FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4415                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4416         if (!NT_STATUS_IS_OK(status)) {
4417                 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4418                 goto fail;
4419         }
4420
4421         status = cli_close(cli1, fnum1);
4422         if (!NT_STATUS_IS_OK(status)) {
4423                 printf("[11] close failed (%s)\n", nt_errstr(status));
4424                 goto fail;
4425         }
4426
4427         /* Now try open for delete access. */
4428         status = cli_ntcreate(cli1, fname, 0,
4429                              FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4430                              0,
4431                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4432                              FILE_OPEN, 0, 0, &fnum1, NULL);
4433         if (!NT_STATUS_IS_OK(status)) {
4434                 printf("[11] open of %s failed: %s\n", fname, nt_errstr(status));
4435                 goto fail;
4436         }
4437
4438         cli_close(cli1, fnum1);
4439
4440         printf("eleventh delete on close test succeeded.\n");
4441
4442         /*
4443          * Test 12
4444          * like test 4 but with initial delete on close
4445          */
4446
4447         cli_setatr(cli1, fname, 0, 0);
4448         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4449
4450         status = cli_ntcreate(cli1, fname, 0,
4451                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4452                               FILE_ATTRIBUTE_NORMAL,
4453                               FILE_SHARE_READ|FILE_SHARE_WRITE,
4454                               FILE_OVERWRITE_IF,
4455                               FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4456         if (!NT_STATUS_IS_OK(status)) {
4457                 printf("[12] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4458                 goto fail;
4459         }
4460
4461         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4462                               FILE_ATTRIBUTE_NORMAL,
4463                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4464                               FILE_OPEN, 0, 0, &fnum2, NULL);
4465         if (!NT_STATUS_IS_OK(status)) {
4466                 printf("[12] open 2 of %s failed(%s).\n", fname, nt_errstr(status));
4467                 goto fail;
4468         }
4469
4470         status = cli_close(cli1, fnum2);
4471         if (!NT_STATUS_IS_OK(status)) {
4472                 printf("[12] close 1 failed (%s)\n", nt_errstr(status));
4473                 goto fail;
4474         }
4475
4476         status = cli_nt_delete_on_close(cli1, fnum1, true);
4477         if (!NT_STATUS_IS_OK(status)) {
4478                 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status));
4479                 goto fail;
4480         }
4481
4482         /* This should fail - no more opens once delete on close set. */
4483         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4484                               FILE_ATTRIBUTE_NORMAL,
4485                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4486                               FILE_OPEN, 0, 0, &fnum2, NULL);
4487         if (NT_STATUS_IS_OK(status)) {
4488                 printf("[12] open 3 of %s succeeded - should fail).\n", fname);
4489                 goto fail;
4490         }
4491
4492         status = cli_nt_delete_on_close(cli1, fnum1, false);
4493         if (!NT_STATUS_IS_OK(status)) {
4494                 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status));
4495                 goto fail;
4496         }
4497
4498         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4499                               FILE_ATTRIBUTE_NORMAL,
4500                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4501                               FILE_OPEN, 0, 0, &fnum2, NULL);
4502         if (!NT_STATUS_IS_OK(status)) {
4503                 printf("[12] open 4 of %s failed (%s)\n", fname, nt_errstr(status));
4504                 goto fail;
4505         }
4506
4507         status = cli_close(cli1, fnum2);
4508         if (!NT_STATUS_IS_OK(status)) {
4509                 printf("[12] close 2 failed (%s)\n", nt_errstr(status));
4510                 goto fail;
4511         }
4512
4513         status = cli_close(cli1, fnum1);
4514         if (!NT_STATUS_IS_OK(status)) {
4515                 printf("[12] close 3 failed (%s)\n", nt_errstr(status));
4516                 goto fail;
4517         }
4518
4519         /*
4520          * setting delete on close on the handle does
4521          * not unset the initial delete on close...
4522          */
4523         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4524                               FILE_ATTRIBUTE_NORMAL,
4525                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4526                               FILE_OPEN, 0, 0, &fnum2, NULL);
4527         if (NT_STATUS_IS_OK(status)) {
4528                 printf("[12] open 5 of %s succeeded - should fail).\n", fname);
4529                 goto fail;
4530         } else if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4531                 printf("ntcreate returned %s, expected "
4532                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
4533                        nt_errstr(status));
4534                 goto fail;
4535         }
4536
4537         printf("twelfth delete on close test succeeded.\n");
4538
4539
4540         printf("finished delete test\n");
4541
4542         correct = true;
4543
4544   fail:
4545         /* FIXME: This will crash if we aborted before cli2 got
4546          * intialized, because these functions don't handle
4547          * uninitialized connections. */
4548
4549         if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4550         if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4551         cli_setatr(cli1, fname, 0, 0);
4552         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4553
4554         if (cli1 && !torture_close_connection(cli1)) {
4555                 correct = False;
4556         }
4557         if (cli2 && !torture_close_connection(cli2)) {
4558                 correct = False;
4559         }
4560         return correct;
4561 }
4562
4563
4564 /*
4565   Test wildcard delete.
4566  */
4567 static bool run_wild_deletetest(int dummy)
4568 {
4569         struct cli_state *cli = NULL;
4570         const char *dname = "\\WTEST";
4571         const char *fname = "\\WTEST\\A";
4572         const char *wunlink_name = "\\WTEST\\*";
4573         uint16_t fnum1 = (uint16_t)-1;
4574         bool correct = false;
4575         NTSTATUS status;
4576
4577         printf("starting wildcard delete test\n");
4578
4579         if (!torture_open_connection(&cli, 0)) {
4580                 return false;
4581         }
4582
4583         smbXcli_conn_set_sockopt(cli->conn, sockops);
4584
4585         cli_unlink(cli, fname, 0);
4586         cli_rmdir(cli, dname);
4587         status = cli_mkdir(cli, dname);
4588         if (!NT_STATUS_IS_OK(status)) {
4589                 printf("mkdir of %s failed %s!\n", dname, nt_errstr(status));
4590                 goto fail;
4591         }
4592         status = cli_openx(cli, fname, O_CREAT|O_RDONLY, DENY_NONE, &fnum1);
4593         if (!NT_STATUS_IS_OK(status)) {
4594                 printf("open of %s failed %s!\n", fname, nt_errstr(status));
4595                 goto fail;
4596         }
4597         status = cli_close(cli, fnum1);
4598         fnum1 = -1;
4599
4600         /*
4601          * Note the unlink attribute-type of zero. This should
4602          * map into FILE_ATTRIBUTE_NORMAL at the server even
4603          * on a wildcard delete.
4604          */
4605
4606         status = cli_unlink(cli, wunlink_name, 0);
4607         if (!NT_STATUS_IS_OK(status)) {
4608                 printf("unlink of %s failed %s!\n",
4609                         wunlink_name, nt_errstr(status));
4610                 goto fail;
4611         }
4612
4613         printf("finished wildcard delete test\n");
4614
4615         correct = true;
4616
4617   fail:
4618
4619         if (fnum1 != (uint16_t)-1) cli_close(cli, fnum1);
4620         cli_unlink(cli, fname, 0);
4621         cli_rmdir(cli, dname);
4622
4623         if (cli && !torture_close_connection(cli)) {
4624                 correct = false;
4625         }
4626         return correct;
4627 }
4628
4629 static bool run_deletetest_ln(int dummy)
4630 {
4631         struct cli_state *cli;
4632         const char *fname = "\\delete1";
4633         const char *fname_ln = "\\delete1_ln";
4634         uint16_t fnum;
4635         uint16_t fnum1;
4636         NTSTATUS status;
4637         bool correct = true;
4638         time_t t;
4639
4640         printf("starting deletetest-ln\n");
4641
4642         if (!torture_open_connection(&cli, 0)) {
4643                 return false;
4644         }
4645
4646         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4647         cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4648
4649         smbXcli_conn_set_sockopt(cli->conn, sockops);
4650
4651         /* Create the file. */
4652         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4653         if (!NT_STATUS_IS_OK(status)) {
4654                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4655                 return false;
4656         }
4657
4658         status = cli_close(cli, fnum);
4659         if (!NT_STATUS_IS_OK(status)) {
4660                 printf("close1 failed (%s)\n", nt_errstr(status));
4661                 return false;
4662         }
4663
4664         /* Now create a hardlink. */
4665         status = cli_nt_hardlink(cli, fname, fname_ln);
4666         if (!NT_STATUS_IS_OK(status)) {
4667                 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4668                 return false;
4669         }
4670
4671         /* Open the original file. */
4672         status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4673                         FILE_ATTRIBUTE_NORMAL,
4674                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4675                         FILE_OPEN_IF, 0, 0, &fnum, NULL);
4676         if (!NT_STATUS_IS_OK(status)) {
4677                 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4678                 return false;
4679         }
4680
4681         /* Unlink the hard link path. */
4682         status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4683                         FILE_ATTRIBUTE_NORMAL,
4684                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4685                         FILE_OPEN_IF, 0, 0, &fnum1, NULL);
4686         if (!NT_STATUS_IS_OK(status)) {
4687                 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4688                 return false;
4689         }
4690         status = cli_nt_delete_on_close(cli, fnum1, true);
4691         if (!NT_STATUS_IS_OK(status)) {
4692                 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4693                         __location__, fname_ln, nt_errstr(status));
4694                 return false;
4695         }
4696
4697         status = cli_close(cli, fnum1);
4698         if (!NT_STATUS_IS_OK(status)) {
4699                 printf("close %s failed (%s)\n",
4700                         fname_ln, nt_errstr(status));
4701                 return false;
4702         }
4703
4704         status = cli_close(cli, fnum);
4705         if (!NT_STATUS_IS_OK(status)) {
4706                 printf("close %s failed (%s)\n",
4707                         fname, nt_errstr(status));
4708                 return false;
4709         }
4710
4711         /* Ensure the original file is still there. */
4712         status = cli_getatr(cli, fname, NULL, NULL, &t);
4713         if (!NT_STATUS_IS_OK(status)) {
4714                 printf("%s getatr on file %s failed (%s)\n",
4715                         __location__,
4716                         fname,
4717                         nt_errstr(status));
4718                 correct = False;
4719         }
4720
4721         /* Ensure the link path is gone. */
4722         status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4723         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4724                 printf("%s, getatr for file %s returned wrong error code %s "
4725                         "- should have been deleted\n",
4726                         __location__,
4727                         fname_ln, nt_errstr(status));
4728                 correct = False;
4729         }
4730
4731         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4732         cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4733
4734         if (!torture_close_connection(cli)) {
4735                 correct = false;
4736         }
4737
4738         printf("finished deletetest-ln\n");
4739
4740         return correct;
4741 }
4742
4743 /*
4744   print out server properties
4745  */
4746 static bool run_properties(int dummy)
4747 {
4748         struct cli_state *cli;
4749         bool correct = True;
4750
4751         printf("starting properties test\n");
4752
4753         ZERO_STRUCT(cli);
4754
4755         if (!torture_open_connection(&cli, 0)) {
4756                 return False;
4757         }
4758
4759         smbXcli_conn_set_sockopt(cli->conn, sockops);
4760
4761         d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
4762
4763         if (!torture_close_connection(cli)) {
4764                 correct = False;
4765         }
4766
4767         return correct;
4768 }
4769
4770
4771
4772 /* FIRST_DESIRED_ACCESS   0xf019f */
4773 #define FIRST_DESIRED_ACCESS   FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4774                                FILE_READ_EA|                           /* 0xf */ \
4775                                FILE_WRITE_EA|FILE_READ_ATTRIBUTES|     /* 0x90 */ \
4776                                FILE_WRITE_ATTRIBUTES|                  /* 0x100 */ \
4777                                DELETE_ACCESS|READ_CONTROL_ACCESS|\
4778                                WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS     /* 0xf0000 */
4779 /* SECOND_DESIRED_ACCESS  0xe0080 */
4780 #define SECOND_DESIRED_ACCESS  FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
4781                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4782                                WRITE_OWNER_ACCESS                      /* 0xe0000 */
4783
4784 #if 0
4785 #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
4786                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4787                                FILE_READ_DATA|\
4788                                WRITE_OWNER_ACCESS                      /* */
4789 #endif
4790
4791 /*
4792   Test ntcreate calls made by xcopy
4793  */
4794 static bool run_xcopy(int dummy)
4795 {
4796         static struct cli_state *cli1;
4797         const char *fname = "\\test.txt";
4798         bool correct = True;
4799         uint16_t fnum1, fnum2;
4800         NTSTATUS status;
4801
4802         printf("starting xcopy test\n");
4803
4804         if (!torture_open_connection(&cli1, 0)) {
4805                 return False;
4806         }
4807
4808         status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4809                               FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4810                               FILE_OVERWRITE_IF, 0x4044, 0, &fnum1, NULL);
4811         if (!NT_STATUS_IS_OK(status)) {
4812                 printf("First open failed - %s\n", nt_errstr(status));
4813                 return False;
4814         }
4815
4816         status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4817                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4818                              FILE_OPEN, 0x200000, 0, &fnum2, NULL);
4819         if (!NT_STATUS_IS_OK(status)) {
4820                 printf("second open failed - %s\n", nt_errstr(status));
4821                 return False;
4822         }
4823
4824         if (!torture_close_connection(cli1)) {
4825                 correct = False;
4826         }
4827
4828         return correct;
4829 }
4830
4831 /*
4832   Test rename on files open with share delete and no share delete.
4833  */
4834 static bool run_rename(int dummy)
4835 {
4836         static struct cli_state *cli1;
4837         const char *fname = "\\test.txt";
4838         const char *fname1 = "\\test1.txt";
4839         bool correct = True;
4840         uint16_t fnum1;
4841         uint16_t attr;
4842         NTSTATUS status;
4843
4844         printf("starting rename test\n");
4845
4846         if (!torture_open_connection(&cli1, 0)) {
4847                 return False;
4848         }
4849
4850         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4851         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4852
4853         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4854                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4855                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4856         if (!NT_STATUS_IS_OK(status)) {
4857                 printf("First open failed - %s\n", nt_errstr(status));
4858                 return False;
4859         }
4860
4861         status = cli_rename(cli1, fname, fname1, false);
4862         if (!NT_STATUS_IS_OK(status)) {
4863                 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4864         } else {
4865                 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4866                 correct = False;
4867         }
4868
4869         status = cli_close(cli1, fnum1);
4870         if (!NT_STATUS_IS_OK(status)) {
4871                 printf("close - 1 failed (%s)\n", nt_errstr(status));
4872                 return False;
4873         }
4874
4875         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4876         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4877         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4878 #if 0
4879                               FILE_SHARE_DELETE|FILE_SHARE_NONE,
4880 #else
4881                               FILE_SHARE_DELETE|FILE_SHARE_READ,
4882 #endif
4883                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4884         if (!NT_STATUS_IS_OK(status)) {
4885                 printf("Second open failed - %s\n", nt_errstr(status));
4886                 return False;
4887         }
4888
4889         status = cli_rename(cli1, fname, fname1, false);
4890         if (!NT_STATUS_IS_OK(status)) {
4891                 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4892                 correct = False;
4893         } else {
4894                 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4895         }
4896
4897         status = cli_close(cli1, fnum1);
4898         if (!NT_STATUS_IS_OK(status)) {
4899                 printf("close - 2 failed (%s)\n", nt_errstr(status));
4900                 return False;
4901         }
4902
4903         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4904         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4905
4906         status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4907                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4908                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4909         if (!NT_STATUS_IS_OK(status)) {
4910                 printf("Third open failed - %s\n", nt_errstr(status));
4911                 return False;
4912         }
4913
4914
4915 #if 0
4916   {
4917         uint16_t fnum2;
4918
4919         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4920                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4921                 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4922                 return False;
4923         }
4924         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4925                 printf("[8] setting delete_on_close on file failed !\n");
4926                 return False;
4927         }
4928
4929         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4930                 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4931                 return False;
4932         }
4933   }
4934 #endif
4935
4936         status = cli_rename(cli1, fname, fname1, false);
4937         if (!NT_STATUS_IS_OK(status)) {
4938                 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4939                 correct = False;
4940         } else {
4941                 printf("Third rename succeeded (SHARE_NONE)\n");
4942         }
4943
4944         status = cli_close(cli1, fnum1);
4945         if (!NT_STATUS_IS_OK(status)) {
4946                 printf("close - 3 failed (%s)\n", nt_errstr(status));
4947                 return False;
4948         }
4949
4950         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4951         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4952
4953         /*----*/
4954
4955         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4956                               FILE_ATTRIBUTE_NORMAL,
4957                               FILE_SHARE_READ | FILE_SHARE_WRITE,
4958                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4959         if (!NT_STATUS_IS_OK(status)) {
4960                 printf("Fourth open failed - %s\n", nt_errstr(status));
4961                 return False;
4962         }
4963
4964         status = cli_rename(cli1, fname, fname1, false);
4965         if (!NT_STATUS_IS_OK(status)) {
4966                 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4967         } else {
4968                 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4969                 correct = False;
4970         }
4971
4972         status = cli_close(cli1, fnum1);
4973         if (!NT_STATUS_IS_OK(status)) {
4974                 printf("close - 4 failed (%s)\n", nt_errstr(status));
4975                 return False;
4976         }
4977
4978         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4979         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4980
4981         /*--*/
4982
4983         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4984                          FILE_ATTRIBUTE_NORMAL,
4985                          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4986                          FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4987         if (!NT_STATUS_IS_OK(status)) {
4988                 printf("Fifth open failed - %s\n", nt_errstr(status));
4989                 return False;
4990         }
4991
4992         status = cli_rename(cli1, fname, fname1, false);
4993         if (!NT_STATUS_IS_OK(status)) {
4994                 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4995                 correct = False;
4996         } else {
4997                 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4998         }
4999
5000         /*
5001          * Now check if the first name still exists ...
5002          */
5003
5004         /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
5005                                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
5006                                    FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
5007           printf("Opening original file after rename of open file fails: %s\n",
5008               cli_errstr(cli1));
5009         }
5010         else {
5011           printf("Opening original file after rename of open file works ...\n");
5012           (void)cli_close(cli1, fnum2);
5013           } */
5014
5015         /*--*/
5016         status = cli_close(cli1, fnum1);
5017         if (!NT_STATUS_IS_OK(status)) {
5018                 printf("close - 5 failed (%s)\n", nt_errstr(status));
5019                 return False;
5020         }
5021
5022         /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
5023         status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
5024         if (!NT_STATUS_IS_OK(status)) {
5025                 printf("getatr on file %s failed - %s ! \n",
5026                         fname1, nt_errstr(status));
5027                 correct = False;
5028         } else {
5029                 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
5030                         printf("Renamed file %s has wrong attr 0x%x "
5031                                 "(should be 0x%x)\n",
5032                                 fname1,
5033                                 attr,
5034                                 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
5035                         correct = False;
5036                 } else {
5037                         printf("Renamed file %s has archive bit set\n", fname1);
5038                 }
5039         }
5040
5041         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5042         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5043
5044         if (!torture_close_connection(cli1)) {
5045                 correct = False;
5046         }
5047
5048         return correct;
5049 }
5050
5051 /*
5052   Test rename into a directory with an ACL denying it.
5053  */
5054 static bool run_rename_access(int dummy)
5055 {
5056         static struct cli_state *cli = NULL;
5057         static struct cli_state *posix_cli = NULL;
5058         const char *src = "test.txt";
5059         const char *dname = "dir";
5060         const char *dst = "dir\\test.txt";
5061         const char *dsrc = "test.dir";
5062         const char *ddst = "dir\\test.dir";
5063         uint16_t fnum = (uint16_t)-1;
5064         struct security_descriptor *sd = NULL;
5065         struct security_descriptor *newsd = NULL;
5066         NTSTATUS status;
5067         TALLOC_CTX *frame = NULL;
5068
5069         frame = talloc_stackframe();
5070         printf("starting rename access test\n");
5071
5072         /* Windows connection. */
5073         if (!torture_open_connection(&cli, 0)) {
5074                 goto fail;
5075         }
5076
5077         smbXcli_conn_set_sockopt(cli->conn, sockops);
5078
5079         /* Posix connection. */
5080         if (!torture_open_connection(&posix_cli, 0)) {
5081                 goto fail;
5082         }
5083
5084         smbXcli_conn_set_sockopt(posix_cli->conn, sockops);
5085
5086         status = torture_setup_unix_extensions(posix_cli);
5087         if (!NT_STATUS_IS_OK(status)) {
5088                 goto fail;
5089         }
5090
5091         /* Start with a clean slate. */
5092         cli_unlink(cli, src, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5093         cli_unlink(cli, dst, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5094         cli_rmdir(cli, dsrc);
5095         cli_rmdir(cli, ddst);
5096         cli_rmdir(cli, dname);
5097
5098         /*
5099          * Setup the destination directory with a DENY ACE to
5100          * prevent new files within it.
5101          */
5102         status = cli_ntcreate(cli,
5103                                 dname,
5104                                 0,
5105                                 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS|
5106                                         WRITE_DAC_ACCESS|FILE_READ_DATA|
5107                                         WRITE_OWNER_ACCESS,
5108                                 FILE_ATTRIBUTE_DIRECTORY,
5109                                 FILE_SHARE_READ|FILE_SHARE_WRITE,
5110                                 FILE_CREATE,
5111                                 FILE_DIRECTORY_FILE,
5112                                 0,
5113                                 &fnum,
5114                                 NULL);
5115         if (!NT_STATUS_IS_OK(status)) {
5116                 printf("Create of %s - %s\n", dname, nt_errstr(status));
5117                 goto fail;
5118         }
5119
5120         status = cli_query_secdesc(cli,
5121                                 fnum,
5122                                 frame,
5123                                 &sd);
5124         if (!NT_STATUS_IS_OK(status)) {
5125                 printf("cli_query_secdesc failed for %s (%s)\n",
5126                         dname, nt_errstr(status));
5127                 goto fail;
5128         }
5129
5130         newsd = security_descriptor_dacl_create(frame,
5131                                         0,
5132                                         NULL,
5133                                         NULL,
5134                                         SID_WORLD,
5135                                         SEC_ACE_TYPE_ACCESS_DENIED,
5136                                         SEC_DIR_ADD_FILE|SEC_DIR_ADD_SUBDIR,
5137                                         0,
5138                                         NULL);
5139         if (newsd == NULL) {
5140                 goto fail;
5141         }
5142         sd->dacl = security_acl_concatenate(frame,
5143                                         newsd->dacl,
5144                                         sd->dacl);
5145         if (sd->dacl == NULL) {
5146                 goto fail;
5147         }
5148         status = cli_set_secdesc(cli, fnum, sd);
5149         if (!NT_STATUS_IS_OK(status)) {
5150                 printf("cli_set_secdesc failed for %s (%s)\n",
5151                         dname, nt_errstr(status));
5152                 goto fail;
5153         }
5154         status = cli_close(cli, fnum);
5155         if (!NT_STATUS_IS_OK(status)) {
5156                 printf("close failed for %s (%s)\n",
5157                         dname, nt_errstr(status));
5158                 goto fail;
5159         }
5160         /* Now go around the back and chmod to 777 via POSIX. */
5161         status = cli_posix_chmod(posix_cli, dname, 0777);
5162         if (!NT_STATUS_IS_OK(status)) {
5163                 printf("cli_posix_chmod failed for %s (%s)\n",
5164                         dname, nt_errstr(status));
5165                 goto fail;
5166         }
5167
5168         /* Check we can't create a file within dname via Windows. */
5169         status = cli_openx(cli, dst, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5170         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5171                 cli_close(posix_cli, fnum);
5172                 printf("Create of %s should be ACCESS denied, was %s\n",
5173                         dst, nt_errstr(status));
5174                 goto fail;
5175         }
5176
5177         /* Make the sample file/directory. */
5178         status = cli_openx(cli, src, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5179         if (!NT_STATUS_IS_OK(status)) {
5180                 printf("open of %s failed (%s)\n", src, nt_errstr(status));
5181                 goto fail;
5182         }
5183         status = cli_close(cli, fnum);
5184         if (!NT_STATUS_IS_OK(status)) {
5185                 printf("cli_close failed (%s)\n", nt_errstr(status));
5186                 goto fail;
5187         }
5188
5189         status = cli_mkdir(cli, dsrc);
5190         if (!NT_STATUS_IS_OK(status)) {
5191                 printf("cli_mkdir of %s failed (%s)\n",
5192                         dsrc, nt_errstr(status));
5193                 goto fail;
5194         }
5195
5196         /*
5197          * OK - renames of the new file and directory into the
5198          * dst directory should fail.
5199          */
5200
5201         status = cli_rename(cli, src, dst, false);
5202         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5203                 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5204                         src, dst, nt_errstr(status));
5205                 goto fail;
5206         }
5207         status = cli_rename(cli, dsrc, ddst, false);
5208         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5209                 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5210                         src, dst, nt_errstr(status));
5211                 goto fail;
5212         }
5213
5214         TALLOC_FREE(frame);
5215         return true;
5216
5217   fail:
5218
5219         if (posix_cli) {
5220                 torture_close_connection(posix_cli);
5221         }
5222
5223         if (cli) {
5224                 if (fnum != (uint16_t)-1) {
5225                         cli_close(cli, fnum);
5226                 }
5227                 cli_unlink(cli, src,
5228                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5229                 cli_unlink(cli, dst,
5230                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5231                 cli_rmdir(cli, dsrc);
5232                 cli_rmdir(cli, ddst);
5233                 cli_rmdir(cli, dname);
5234
5235                 torture_close_connection(cli);
5236         }
5237
5238         TALLOC_FREE(frame);
5239         return false;
5240 }
5241
5242 /*
5243   Test owner rights ACE.
5244  */
5245 static bool run_owner_rights(int dummy)
5246 {
5247         static struct cli_state *cli = NULL;
5248         const char *fname = "owner_rights.txt";
5249         uint16_t fnum = (uint16_t)-1;
5250         struct security_descriptor *sd = NULL;
5251         struct security_descriptor *newsd = NULL;
5252         NTSTATUS status;
5253         TALLOC_CTX *frame = NULL;
5254
5255         frame = talloc_stackframe();
5256         printf("starting owner rights test\n");
5257
5258         /* Windows connection. */
5259         if (!torture_open_connection(&cli, 0)) {
5260                 goto fail;
5261         }
5262
5263         smbXcli_conn_set_sockopt(cli->conn, sockops);
5264
5265         /* Start with a clean slate. */
5266         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5267
5268         /* Create the test file. */
5269         /* Now try and open for read and write-dac. */
5270         status = cli_ntcreate(cli,
5271                                 fname,
5272                                 0,
5273                                 GENERIC_ALL_ACCESS,
5274                                 FILE_ATTRIBUTE_NORMAL,
5275                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
5276                                         FILE_SHARE_DELETE,
5277                                 FILE_CREATE,
5278                                 0,
5279                                 0,
5280                                 &fnum,
5281                                 NULL);
5282         if (!NT_STATUS_IS_OK(status)) {
5283                 printf("Create of %s - %s\n", fname, nt_errstr(status));
5284                 goto fail;
5285         }
5286
5287         /* Get the original SD. */
5288         status = cli_query_secdesc(cli,
5289                                 fnum,
5290                                 frame,
5291                                 &sd);
5292         if (!NT_STATUS_IS_OK(status)) {
5293                 printf("cli_query_secdesc failed for %s (%s)\n",
5294                         fname, nt_errstr(status));
5295                 goto fail;
5296         }
5297
5298         /*
5299          * Add an "owner-rights" ACE denying WRITE_DATA,
5300          * and an "owner-rights" ACE allowing READ_DATA.
5301          */
5302
5303         newsd = security_descriptor_dacl_create(frame,
5304                                         0,
5305                                         NULL,
5306                                         NULL,
5307                                         SID_OWNER_RIGHTS,
5308                                         SEC_ACE_TYPE_ACCESS_DENIED,
5309                                         FILE_WRITE_DATA,
5310                                         0,
5311                                         SID_OWNER_RIGHTS,
5312                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
5313                                         FILE_READ_DATA,
5314                                         0,
5315                                         NULL);
5316         if (newsd == NULL) {
5317                 goto fail;
5318         }
5319         sd->dacl = security_acl_concatenate(frame,
5320                                         newsd->dacl,
5321                                         sd->dacl);
5322         if (sd->dacl == NULL) {
5323                 goto fail;
5324         }
5325         status = cli_set_secdesc(cli, fnum, sd);
5326         if (!NT_STATUS_IS_OK(status)) {
5327                 printf("cli_set_secdesc failed for %s (%s)\n",
5328                         fname, nt_errstr(status));
5329                 goto fail;
5330         }
5331         status = cli_close(cli, fnum);
5332         if (!NT_STATUS_IS_OK(status)) {
5333                 printf("close failed for %s (%s)\n",
5334                         fname, nt_errstr(status));
5335                 goto fail;
5336         }
5337         fnum = (uint16_t)-1;
5338
5339         /* Try and open for FILE_WRITE_DATA */
5340         status = cli_ntcreate(cli,
5341                                 fname,
5342                                 0,
5343                                 FILE_WRITE_DATA,
5344                                 FILE_ATTRIBUTE_NORMAL,
5345                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
5346                                         FILE_SHARE_DELETE,
5347                                 FILE_OPEN,
5348                                 0,
5349                                 0,
5350                                 &fnum,
5351                                 NULL);
5352         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5353                 printf("Open of %s - %s\n", fname, nt_errstr(status));
5354                 goto fail;
5355         }
5356
5357         /* Now try and open for FILE_READ_DATA */
5358         status = cli_ntcreate(cli,
5359                                 fname,
5360                                 0,
5361                                 FILE_READ_DATA,
5362                                 FILE_ATTRIBUTE_NORMAL,
5363                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
5364                                         FILE_SHARE_DELETE,
5365                                 FILE_OPEN,
5366                                 0,
5367                                 0,
5368                                 &fnum,
5369                                 NULL);
5370         if (!NT_STATUS_IS_OK(status)) {
5371                 printf("Open of %s - %s\n", fname, nt_errstr(status));
5372                 goto fail;
5373         }
5374
5375         status = cli_close(cli, fnum);
5376         if (!NT_STATUS_IS_OK(status)) {
5377                 printf("close failed for %s (%s)\n",
5378                         fname, nt_errstr(status));
5379                 goto fail;
5380         }
5381
5382         /* Restore clean slate. */
5383         TALLOC_FREE(sd);
5384         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5385
5386         /* Create the test file. */
5387         status = cli_ntcreate(cli,
5388                                 fname,
5389                                 0,
5390                                 GENERIC_ALL_ACCESS,
5391                                 FILE_ATTRIBUTE_NORMAL,
5392                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
5393                                         FILE_SHARE_DELETE,
5394                                 FILE_CREATE,
5395                                 0,
5396                                 0,
5397                                 &fnum,
5398                                 NULL);
5399         if (!NT_STATUS_IS_OK(status)) {
5400                 printf("Create of %s - %s\n", fname, nt_errstr(status));
5401                 goto fail;
5402         }
5403
5404         /* Get the original SD. */
5405         status = cli_query_secdesc(cli,
5406                                 fnum,
5407                                 frame,
5408                                 &sd);
5409         if (!NT_STATUS_IS_OK(status)) {
5410                 printf("cli_query_secdesc failed for %s (%s)\n",
5411                         fname, nt_errstr(status));
5412                 goto fail;
5413         }
5414
5415         /*
5416          * Add an "owner-rights ACE denying WRITE_DATA,
5417          * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
5418          */
5419
5420         newsd = security_descriptor_dacl_create(frame,
5421                                         0,
5422                                         NULL,
5423                                         NULL,
5424                                         SID_OWNER_RIGHTS,
5425                                         SEC_ACE_TYPE_ACCESS_DENIED,
5426                                         FILE_WRITE_DATA,
5427                                         0,
5428                                         SID_OWNER_RIGHTS,
5429                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
5430                                         FILE_READ_DATA|FILE_WRITE_DATA,
5431                                         0,
5432                                         NULL);
5433         if (newsd == NULL) {
5434                 goto fail;
5435         }
5436         sd->dacl = security_acl_concatenate(frame,
5437                                         newsd->dacl,
5438                                         sd->dacl);
5439         if (sd->dacl == NULL) {
5440                 goto fail;
5441         }
5442         status = cli_set_secdesc(cli, fnum, sd);
5443         if (!NT_STATUS_IS_OK(status)) {
5444                 printf("cli_set_secdesc failed for %s (%s)\n",
5445                         fname, nt_errstr(status));
5446                 goto fail;
5447         }
5448         status = cli_close(cli, fnum);
5449         if (!NT_STATUS_IS_OK(status)) {
5450                 printf("close failed for %s (%s)\n",
5451                         fname, nt_errstr(status));
5452                 goto fail;
5453         }
5454         fnum = (uint16_t)-1;
5455
5456         /* Try and open for FILE_WRITE_DATA */
5457         status = cli_ntcreate(cli,
5458                                 fname,
5459                                 0,
5460                                 FILE_WRITE_DATA,
5461                                 FILE_ATTRIBUTE_NORMAL,
5462                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
5463                                         FILE_SHARE_DELETE,
5464                                 FILE_OPEN,
5465                                 0,
5466                                 0,
5467                                 &fnum,
5468                                 NULL);
5469         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5470                 printf("Open of %s - %s\n", fname, nt_errstr(status));
5471                 goto fail;
5472         }
5473
5474         /* Now try and open for FILE_READ_DATA */
5475         status = cli_ntcreate(cli,
5476                                 fname,
5477                                 0,
5478                                 FILE_READ_DATA,
5479                                 FILE_ATTRIBUTE_NORMAL,
5480                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
5481                                         FILE_SHARE_DELETE,
5482                                 FILE_OPEN,
5483                                 0,
5484                                 0,
5485                                 &fnum,
5486                                 NULL);
5487         if (!NT_STATUS_IS_OK(status)) {
5488                 printf("Open of %s - %s\n", fname, nt_errstr(status));
5489                 goto fail;
5490         }
5491
5492         status = cli_close(cli, fnum);
5493         if (!NT_STATUS_IS_OK(status)) {
5494                 printf("close failed for %s (%s)\n",
5495                         fname, nt_errstr(status));
5496                 goto fail;
5497         }
5498
5499         /* Restore clean slate. */
5500         TALLOC_FREE(sd);
5501         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5502
5503
5504         /* Create the test file. */
5505         status = cli_ntcreate(cli,
5506                                 fname,
5507                                 0,
5508                                 GENERIC_ALL_ACCESS,
5509                                 FILE_ATTRIBUTE_NORMAL,
5510                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
5511                                         FILE_SHARE_DELETE,
5512                                 FILE_CREATE,
5513                                 0,
5514                                 0,
5515                                 &fnum,
5516                                 NULL);
5517         if (!NT_STATUS_IS_OK(status)) {
5518                 printf("Create of %s - %s\n", fname, nt_errstr(status));
5519                 goto fail;
5520         }
5521
5522         /* Get the original SD. */
5523         status = cli_query_secdesc(cli,
5524                                 fnum,
5525                                 frame,
5526                                 &sd);
5527         if (!NT_STATUS_IS_OK(status)) {
5528                 printf("cli_query_secdesc failed for %s (%s)\n",
5529                         fname, nt_errstr(status));
5530                 goto fail;
5531         }
5532
5533         /*
5534          * Add an "authenticated users" ACE allowing READ_DATA,
5535          * add an "owner-rights" denying READ_DATA,
5536          * and an "authenticated users" ACE allowing WRITE_DATA.
5537          */
5538
5539         newsd = security_descriptor_dacl_create(frame,
5540                                         0,
5541                                         NULL,
5542                                         NULL,
5543                                         SID_NT_AUTHENTICATED_USERS,
5544                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
5545                                         FILE_READ_DATA,
5546                                         0,
5547                                         SID_OWNER_RIGHTS,
5548                                         SEC_ACE_TYPE_ACCESS_DENIED,
5549                                         FILE_READ_DATA,
5550                                         0,
5551                                         SID_NT_AUTHENTICATED_USERS,
5552                                         SEC_ACE_TYPE_ACCESS_ALLOWED,
5553                                         FILE_WRITE_DATA,
5554                                         0,
5555                                         NULL);
5556         if (newsd == NULL) {
5557                 printf("newsd == NULL\n");
5558                 goto fail;
5559         }
5560         sd->dacl = security_acl_concatenate(frame,
5561                                         newsd->dacl,
5562                                         sd->dacl);
5563         if (sd->dacl == NULL) {
5564                 printf("sd->dacl == NULL\n");
5565                 goto fail;
5566         }
5567         status = cli_set_secdesc(cli, fnum, sd);
5568         if (!NT_STATUS_IS_OK(status)) {
5569                 printf("cli_set_secdesc failed for %s (%s)\n",
5570                         fname, nt_errstr(status));
5571                 goto fail;
5572         }
5573         status = cli_close(cli, fnum);
5574         if (!NT_STATUS_IS_OK(status)) {
5575                 printf("close failed for %s (%s)\n",
5576                         fname, nt_errstr(status));
5577                 goto fail;
5578         }
5579         fnum = (uint16_t)-1;
5580
5581         /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
5582         status = cli_ntcreate(cli,
5583                                 fname,
5584                                 0,
5585                                 FILE_READ_DATA|FILE_WRITE_DATA,
5586                                 FILE_ATTRIBUTE_NORMAL,
5587                                 FILE_SHARE_READ|FILE_SHARE_WRITE|
5588                                         FILE_SHARE_DELETE,
5589                                 FILE_OPEN,
5590                                 0,
5591                                 0,
5592                                 &fnum,
5593                                 NULL);
5594         if (!NT_STATUS_IS_OK(status)) {
5595                 printf("Open of %s - %s\n", fname, nt_errstr(status));
5596                 goto fail;
5597         }
5598
5599         status = cli_close(cli, fnum);
5600         if (!NT_STATUS_IS_OK(status)) {
5601                 printf("close failed for %s (%s)\n",
5602                         fname, nt_errstr(status));
5603                 goto fail;
5604         }
5605
5606         cli_unlink(cli, fname,
5607                 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5608
5609         TALLOC_FREE(frame);
5610         return true;
5611
5612   fail:
5613
5614         if (cli) {
5615                 if (fnum != (uint16_t)-1) {
5616                         cli_close(cli, fnum);
5617                 }
5618                 cli_unlink(cli, fname,
5619                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5620                 torture_close_connection(cli);
5621         }
5622
5623         TALLOC_FREE(frame);
5624         return false;
5625 }
5626
5627 static bool run_pipe_number(int dummy)
5628 {
5629         struct cli_state *cli1;
5630         const char *pipe_name = "\\SPOOLSS";
5631         uint16_t fnum;
5632         int num_pipes = 0;
5633         NTSTATUS status;
5634
5635         printf("starting pipenumber test\n");
5636         if (!torture_open_connection(&cli1, 0)) {
5637                 return False;
5638         }
5639
5640         smbXcli_conn_set_sockopt(cli1->conn, sockops);
5641         while(1) {
5642                 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
5643                                       FILE_ATTRIBUTE_NORMAL,
5644                                       FILE_SHARE_READ|FILE_SHARE_WRITE,
5645                                       FILE_OPEN_IF, 0, 0, &fnum, NULL);
5646                 if (!NT_STATUS_IS_OK(status)) {
5647                         printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
5648                         break;
5649                 }
5650                 num_pipes++;
5651                 printf("\r%6d", num_pipes);
5652         }
5653
5654         printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
5655         torture_close_connection(cli1);
5656         return True;
5657 }
5658
5659 /*
5660   Test open mode returns on read-only files.
5661  */
5662 static bool run_opentest(int dummy)
5663 {
5664         static struct cli_state *cli1;
5665         static struct cli_state *cli2;
5666         const char *fname = "\\readonly.file";
5667         uint16_t fnum1, fnum2;
5668         char buf[20];
5669         off_t fsize;
5670         bool correct = True;
5671         char *tmp_path;
5672         NTSTATUS status;
5673
5674         printf("starting open test\n");
5675
5676         if (!torture_open_connection(&cli1, 0)) {
5677                 return False;
5678         }
5679
5680         cli_setatr(cli1, fname, 0, 0);
5681         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5682
5683         smbXcli_conn_set_sockopt(cli1->conn, sockops);
5684
5685         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5686         if (!NT_STATUS_IS_OK(status)) {
5687                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5688                 return False;
5689         }
5690
5691         status = cli_close(cli1, fnum1);
5692         if (!NT_STATUS_IS_OK(status)) {
5693                 printf("close2 failed (%s)\n", nt_errstr(status));
5694                 return False;
5695         }
5696
5697         status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
5698         if (!NT_STATUS_IS_OK(status)) {
5699                 printf("cli_setatr failed (%s)\n", nt_errstr(status));
5700                 return False;
5701         }
5702
5703         status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
5704         if (!NT_STATUS_IS_OK(status)) {
5705                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5706                 return False;
5707         }
5708
5709         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
5710         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5711
5712         if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
5713                         NT_STATUS_ACCESS_DENIED)) {
5714                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
5715         }
5716
5717         printf("finished open test 1\n");
5718
5719         cli_close(cli1, fnum1);
5720
5721         /* Now try not readonly and ensure ERRbadshare is returned. */
5722
5723         cli_setatr(cli1, fname, 0, 0);
5724
5725         status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
5726         if (!NT_STATUS_IS_OK(status)) {
5727                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5728                 return False;
5729         }
5730
5731         /* This will fail - but the error should be ERRshare. */
5732         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5733
5734         if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
5735                         NT_STATUS_SHARING_VIOLATION)) {
5736                 printf("correct error code ERRDOS/ERRbadshare returned\n");
5737         }
5738
5739         status = cli_close(cli1, fnum1);
5740         if (!NT_STATUS_IS_OK(status)) {
5741                 printf("close2 failed (%s)\n", nt_errstr(status));
5742                 return False;
5743         }
5744
5745         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5746
5747         printf("finished open test 2\n");
5748
5749         /* Test truncate open disposition on file opened for read. */
5750         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5751         if (!NT_STATUS_IS_OK(status)) {
5752                 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
5753                 return False;
5754         }
5755
5756         /* write 20 bytes. */
5757
5758         memset(buf, '\0', 20);
5759
5760         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
5761         if (!NT_STATUS_IS_OK(status)) {
5762                 printf("write failed (%s)\n", nt_errstr(status));
5763                 correct = False;
5764         }
5765
5766         status = cli_close(cli1, fnum1);
5767         if (!NT_STATUS_IS_OK(status)) {
5768                 printf("(3) close1 failed (%s)\n", nt_errstr(status));
5769                 return False;
5770         }
5771
5772         /* Ensure size == 20. */
5773         status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5774         if (!NT_STATUS_IS_OK(status)) {
5775                 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5776                 return False;
5777         }
5778
5779         if (fsize != 20) {
5780                 printf("(3) file size != 20\n");
5781                 return False;
5782         }
5783
5784         /* Now test if we can truncate a file opened for readonly. */
5785         status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
5786         if (!NT_STATUS_IS_OK(status)) {
5787                 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
5788                 return False;
5789         }
5790
5791         status = cli_close(cli1, fnum1);
5792         if (!NT_STATUS_IS_OK(status)) {
5793                 printf("close2 failed (%s)\n", nt_errstr(status));
5794                 return False;
5795         }
5796
5797         /* Ensure size == 0. */
5798         status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5799         if (!NT_STATUS_IS_OK(status)) {
5800                 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5801                 return False;
5802         }
5803
5804         if (fsize != 0) {
5805                 printf("(3) file size != 0\n");
5806                 return False;
5807         }
5808         printf("finished open test 3\n");
5809
5810         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5811
5812         printf("Do ctemp tests\n");
5813         status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
5814         if (!NT_STATUS_IS_OK(status)) {
5815                 printf("ctemp failed (%s)\n", nt_errstr(status));
5816                 return False;
5817         }
5818
5819         printf("ctemp gave path %s\n", tmp_path);
5820         status = cli_close(cli1, fnum1);
5821         if (!NT_STATUS_IS_OK(status)) {
5822                 printf("close of temp failed (%s)\n", nt_errstr(status));
5823         }
5824
5825         status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5826         if (!NT_STATUS_IS_OK(status)) {
5827                 printf("unlink of temp failed (%s)\n", nt_errstr(status));
5828         }
5829
5830         /* Test the non-io opens... */
5831
5832         if (!torture_open_connection(&cli2, 1)) {
5833                 return False;
5834         }
5835
5836         cli_setatr(cli2, fname, 0, 0);
5837         cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5838
5839         smbXcli_conn_set_sockopt(cli2->conn, sockops);
5840
5841         printf("TEST #1 testing 2 non-io opens (no delete)\n");
5842         status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5843                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5844                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5845         if (!NT_STATUS_IS_OK(status)) {
5846                 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5847                 return False;
5848         }
5849
5850         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5851                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5852                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5853         if (!NT_STATUS_IS_OK(status)) {
5854                 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5855                 return False;
5856         }
5857
5858         status = cli_close(cli1, fnum1);
5859         if (!NT_STATUS_IS_OK(status)) {
5860                 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5861                 return False;
5862         }
5863
5864         status = cli_close(cli2, fnum2);
5865         if (!NT_STATUS_IS_OK(status)) {
5866                 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5867                 return False;
5868         }
5869
5870         printf("non-io open test #1 passed.\n");
5871
5872         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5873
5874         printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5875
5876         status = cli_ntcreate(cli1, fname, 0,
5877                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5878                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5879                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5880         if (!NT_STATUS_IS_OK(status)) {
5881                 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5882                 return False;
5883         }
5884
5885         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5886                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5887                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5888         if (!NT_STATUS_IS_OK(status)) {
5889                 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5890                 return False;
5891         }
5892
5893         status = cli_close(cli1, fnum1);
5894         if (!NT_STATUS_IS_OK(status)) {
5895                 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5896                 return False;
5897         }
5898
5899         status = cli_close(cli2, fnum2);
5900         if (!NT_STATUS_IS_OK(status)) {
5901                 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5902                 return False;
5903         }
5904
5905         printf("non-io open test #2 passed.\n");
5906
5907         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5908
5909         printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5910
5911         status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5912                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5913                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5914         if (!NT_STATUS_IS_OK(status)) {
5915                 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5916                 return False;
5917         }
5918
5919         status = cli_ntcreate(cli2, fname, 0,
5920                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5921                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5922                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5923         if (!NT_STATUS_IS_OK(status)) {
5924                 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5925                 return False;
5926         }
5927
5928         status = cli_close(cli1, fnum1);
5929         if (!NT_STATUS_IS_OK(status)) {
5930                 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5931                 return False;
5932         }
5933
5934         status = cli_close(cli2, fnum2);
5935         if (!NT_STATUS_IS_OK(status)) {
5936                 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5937                 return False;
5938         }
5939
5940         printf("non-io open test #3 passed.\n");
5941
5942         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5943
5944         printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5945
5946         status = cli_ntcreate(cli1, fname, 0,
5947                                DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5948                                FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5949                                FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5950         if (!NT_STATUS_IS_OK(status)) {
5951                 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5952                 return False;
5953         }
5954
5955         status = cli_ntcreate(cli2, fname, 0,
5956                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5957                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5958                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5959         if (NT_STATUS_IS_OK(status)) {
5960                 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5961                 return False;
5962         }
5963
5964         printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5965
5966         status = cli_close(cli1, fnum1);
5967         if (!NT_STATUS_IS_OK(status)) {
5968                 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5969                 return False;
5970         }
5971
5972         printf("non-io open test #4 passed.\n");
5973
5974         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5975
5976         printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5977
5978         status = cli_ntcreate(cli1, fname, 0,
5979                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5980                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5981                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5982         if (!NT_STATUS_IS_OK(status)) {
5983                 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5984                 return False;
5985         }
5986
5987         status = cli_ntcreate(cli2, fname, 0,
5988                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5989                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5990                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5991         if (!NT_STATUS_IS_OK(status)) {
5992                 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5993                 return False;
5994         }
5995
5996         status = cli_close(cli1, fnum1);
5997         if (!NT_STATUS_IS_OK(status)) {
5998                 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5999                 return False;
6000         }
6001
6002         status = cli_close(cli2, fnum2);
6003         if (!NT_STATUS_IS_OK(status)) {
6004                 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
6005                 return False;
6006         }
6007
6008         printf("non-io open test #5 passed.\n");
6009
6010         printf("TEST #6 testing 1 non-io open, one io open\n");
6011
6012         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6013
6014         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
6015                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6016                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6017         if (!NT_STATUS_IS_OK(status)) {
6018                 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
6019                 return False;
6020         }
6021
6022         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
6023                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6024                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
6025         if (!NT_STATUS_IS_OK(status)) {
6026                 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
6027                 return False;
6028         }
6029
6030         status = cli_close(cli1, fnum1);
6031         if (!NT_STATUS_IS_OK(status)) {
6032                 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6033                 return False;
6034         }
6035
6036         status = cli_close(cli2, fnum2);
6037         if (!NT_STATUS_IS_OK(status)) {
6038                 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
6039                 return False;
6040         }
6041
6042         printf("non-io open test #6 passed.\n");
6043
6044         printf("TEST #7 testing 1 non-io open, one io open with delete\n");
6045
6046         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6047
6048         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
6049                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6050                               FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6051         if (!NT_STATUS_IS_OK(status)) {
6052                 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
6053                 return False;
6054         }
6055
6056         status = cli_ntcreate(cli2, fname, 0,
6057                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
6058                               FILE_ATTRIBUTE_NORMAL,
6059                               FILE_SHARE_READ|FILE_SHARE_DELETE,
6060                               FILE_OPEN_IF, 0, 0, &fnum2, NULL);
6061         if (NT_STATUS_IS_OK(status)) {
6062                 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
6063                 return False;
6064         }
6065
6066         printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
6067
6068         status = cli_close(cli1, fnum1);
6069         if (!NT_STATUS_IS_OK(status)) {
6070                 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6071                 return False;
6072         }
6073
6074         printf("non-io open test #7 passed.\n");
6075
6076         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6077
6078         printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
6079         status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
6080                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6081                                 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6082         if (!NT_STATUS_IS_OK(status)) {
6083                 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
6084                 correct = false;
6085                 goto out;
6086         }
6087
6088         /* Write to ensure we have to update the file time. */
6089         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
6090                               NULL);
6091         if (!NT_STATUS_IS_OK(status)) {
6092                 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
6093                 correct = false;
6094                 goto out;
6095         }
6096
6097         status = cli_close(cli1, fnum1);
6098         if (!NT_STATUS_IS_OK(status)) {
6099                 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
6100                 correct = false;
6101         }
6102
6103   out:
6104
6105         if (!torture_close_connection(cli1)) {
6106                 correct = False;
6107         }
6108         if (!torture_close_connection(cli2)) {
6109                 correct = False;
6110         }
6111
6112         return correct;
6113 }
6114
6115 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
6116 {
6117         uint16_t major, minor;
6118         uint32_t caplow, caphigh;
6119         NTSTATUS status;
6120
6121         if (!SERVER_HAS_UNIX_CIFS(cli)) {
6122                 printf("Server doesn't support UNIX CIFS extensions.\n");
6123                 return NT_STATUS_NOT_SUPPORTED;
6124         }
6125
6126         status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
6127                                              &caphigh);
6128         if (!NT_STATUS_IS_OK(status)) {
6129                 printf("Server didn't return UNIX CIFS extensions: %s\n",
6130                        nt_errstr(status));
6131                 return status;
6132         }
6133
6134         status = cli_set_unix_extensions_capabilities(cli, major, minor,
6135                                                       caplow, caphigh);
6136         if (!NT_STATUS_IS_OK(status)) {
6137                 printf("Server doesn't support setting UNIX CIFS extensions: "
6138                        "%s.\n", nt_errstr(status));
6139                 return status;
6140         }
6141
6142         return NT_STATUS_OK;
6143 }
6144
6145 /*
6146   Test POSIX open /mkdir calls.
6147  */
6148 static bool run_simple_posix_open_test(int dummy)
6149 {
6150         static struct cli_state *cli1;
6151         const char *fname = "posix:file";
6152         const char *hname = "posix:hlink";
6153         const char *sname = "posix:symlink";
6154         const char *dname = "posix:dir";
6155         char buf[10];
6156         char namebuf[11];
6157         uint16_t fnum1 = (uint16_t)-1;
6158         SMB_STRUCT_STAT sbuf;
6159         bool correct = false;
6160         NTSTATUS status;
6161         size_t nread;
6162         const char *fname_windows = "windows_file";
6163         uint16_t fnum2 = (uint16_t)-1;
6164
6165         printf("Starting simple POSIX open test\n");
6166
6167         if (!torture_open_connection(&cli1, 0)) {
6168                 return false;
6169         }
6170
6171         smbXcli_conn_set_sockopt(cli1->conn, sockops);
6172
6173         status = torture_setup_unix_extensions(cli1);
6174         if (!NT_STATUS_IS_OK(status)) {
6175                 return false;
6176         }
6177
6178         cli_setatr(cli1, fname, 0, 0);
6179         cli_posix_unlink(cli1, fname);
6180         cli_setatr(cli1, dname, 0, 0);
6181         cli_posix_rmdir(cli1, dname);
6182         cli_setatr(cli1, hname, 0, 0);
6183         cli_posix_unlink(cli1, hname);
6184         cli_setatr(cli1, sname, 0, 0);
6185         cli_posix_unlink(cli1, sname);
6186         cli_setatr(cli1, fname_windows, 0, 0);
6187         cli_posix_unlink(cli1, fname_windows);
6188
6189         /* Create a directory. */
6190         status = cli_posix_mkdir(cli1, dname, 0777);
6191         if (!NT_STATUS_IS_OK(status)) {
6192                 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
6193                 goto out;
6194         }
6195
6196         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
6197                                 0600, &fnum1);
6198         if (!NT_STATUS_IS_OK(status)) {
6199                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6200                 goto out;
6201         }
6202
6203         /* Test ftruncate - set file size. */
6204         status = cli_ftruncate(cli1, fnum1, 1000);
6205         if (!NT_STATUS_IS_OK(status)) {
6206                 printf("ftruncate failed (%s)\n", nt_errstr(status));
6207                 goto out;
6208         }
6209
6210         /* Ensure st_size == 1000 */
6211         status = cli_posix_stat(cli1, fname, &sbuf);
6212         if (!NT_STATUS_IS_OK(status)) {
6213                 printf("stat failed (%s)\n", nt_errstr(status));
6214                 goto out;
6215         }
6216
6217         if (sbuf.st_ex_size != 1000) {
6218                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
6219                 goto out;
6220         }
6221
6222         /* Ensure st_mode == 0600 */
6223         if ((sbuf.st_ex_mode & 07777) != 0600) {
6224                 printf("posix_open - bad permissions 0%o != 0600\n",
6225                                 (unsigned int)(sbuf.st_ex_mode & 07777));
6226                 goto out;
6227         }
6228
6229         /* Test ftruncate - set file size back to zero. */
6230         status = cli_ftruncate(cli1, fnum1, 0);
6231         if (!NT_STATUS_IS_OK(status)) {
6232                 printf("ftruncate failed (%s)\n", nt_errstr(status));
6233                 goto out;
6234         }
6235
6236         status = cli_close(cli1, fnum1);
6237         if (!NT_STATUS_IS_OK(status)) {
6238                 printf("close failed (%s)\n", nt_errstr(status));
6239                 goto out;
6240         }
6241
6242         /* Now open the file again for read only. */
6243         status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
6244         if (!NT_STATUS_IS_OK(status)) {
6245                 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
6246                 goto out;
6247         }
6248
6249         /* Now unlink while open. */
6250         status = cli_posix_unlink(cli1, fname);
6251         if (!NT_STATUS_IS_OK(status)) {
6252                 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
6253                 goto out;
6254         }
6255
6256         status = cli_close(cli1, fnum1);
6257         if (!NT_STATUS_IS_OK(status)) {
6258                 printf("close(2) failed (%s)\n", nt_errstr(status));
6259                 goto out;
6260         }
6261
6262         /* Ensure the file has gone. */
6263         status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
6264         if (NT_STATUS_IS_OK(status)) {
6265                 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
6266                 goto out;
6267         }
6268
6269         /* Create again to test open with O_TRUNC. */
6270         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
6271         if (!NT_STATUS_IS_OK(status)) {
6272                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6273                 goto out;
6274         }
6275
6276         /* Test ftruncate - set file size. */
6277         status = cli_ftruncate(cli1, fnum1, 1000);
6278         if (!NT_STATUS_IS_OK(status)) {
6279                 printf("ftruncate failed (%s)\n", nt_errstr(status));
6280                 goto out;
6281         }
6282
6283         /* Ensure st_size == 1000 */
6284         status = cli_posix_stat(cli1, fname, &sbuf);
6285         if (!NT_STATUS_IS_OK(status)) {
6286                 printf("stat failed (%s)\n", nt_errstr(status));
6287                 goto out;
6288         }
6289
6290         if (sbuf.st_ex_size != 1000) {
6291                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
6292                 goto out;
6293         }
6294
6295         status = cli_close(cli1, fnum1);
6296         if (!NT_STATUS_IS_OK(status)) {
6297                 printf("close(2) failed (%s)\n", nt_errstr(status));
6298                 goto out;
6299         }
6300
6301         /* Re-open with O_TRUNC. */
6302         status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
6303         if (!NT_STATUS_IS_OK(status)) {
6304                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6305                 goto out;
6306         }
6307
6308         /* Ensure st_size == 0 */
6309         status = cli_posix_stat(cli1, fname, &sbuf);
6310         if (!NT_STATUS_IS_OK(status)) {
6311                 printf("stat failed (%s)\n", nt_errstr(status));
6312                 goto out;
6313         }
6314
6315         if (sbuf.st_ex_size != 0) {
6316                 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
6317                 goto out;
6318         }
6319
6320         status = cli_close(cli1, fnum1);
6321         if (!NT_STATUS_IS_OK(status)) {
6322                 printf("close failed (%s)\n", nt_errstr(status));
6323                 goto out;
6324         }
6325
6326         status = cli_posix_unlink(cli1, fname);
6327         if (!NT_STATUS_IS_OK(status)) {
6328                 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
6329                 goto out;
6330         }
6331
6332         status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
6333         if (!NT_STATUS_IS_OK(status)) {
6334                 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
6335                         dname, nt_errstr(status));
6336                 goto out;
6337         }
6338
6339         cli_close(cli1, fnum1);
6340
6341         /* What happens when we try and POSIX open a directory for write ? */
6342         status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
6343         if (NT_STATUS_IS_OK(status)) {
6344                 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
6345                 goto out;
6346         } else {
6347                 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
6348                                 NT_STATUS_FILE_IS_A_DIRECTORY)) {
6349                         goto out;
6350                 }
6351         }
6352
6353         /* Create the file. */
6354         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
6355                                 0600, &fnum1);
6356         if (!NT_STATUS_IS_OK(status)) {
6357                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6358                 goto out;
6359         }
6360
6361         /* Write some data into it. */
6362         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
6363                               NULL);
6364         if (!NT_STATUS_IS_OK(status)) {
6365                 printf("cli_write failed: %s\n", nt_errstr(status));
6366                 goto out;
6367         }
6368
6369         cli_close(cli1, fnum1);
6370
6371         /* Now create a hardlink. */
6372         status = cli_posix_hardlink(cli1, fname, hname);
6373         if (!NT_STATUS_IS_OK(status)) {
6374                 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
6375                 goto out;
6376         }
6377
6378         /* Now create a symlink. */
6379         status = cli_posix_symlink(cli1, fname, sname);
6380         if (!NT_STATUS_IS_OK(status)) {
6381                 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
6382                 goto out;
6383         }
6384
6385         /* Open the hardlink for read. */
6386         status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
6387         if (!NT_STATUS_IS_OK(status)) {
6388                 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
6389                 goto out;
6390         }
6391
6392         status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
6393         if (!NT_STATUS_IS_OK(status)) {
6394                 printf("POSIX read of %s failed (%s)\n", hname,
6395                        nt_errstr(status));
6396                 goto out;
6397         } else if (nread != 10) {
6398                 printf("POSIX read of %s failed. Received %ld, expected %d\n",
6399                        hname, (unsigned long)nread, 10);
6400                 goto out;
6401         }
6402
6403         if (memcmp(buf, "TEST DATA\n", 10)) {
6404                 printf("invalid data read from hardlink\n");
6405                 goto out;
6406         }
6407
6408         /* Do a POSIX lock/unlock. */
6409         status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
6410         if (!NT_STATUS_IS_OK(status)) {
6411                 printf("POSIX lock failed %s\n", nt_errstr(status));
6412                 goto out;
6413         }
6414
6415         /* Punch a hole in the locked area. */
6416         status = cli_posix_unlock(cli1, fnum1, 10, 80);
6417         if (!NT_STATUS_IS_OK(status)) {
6418                 printf("POSIX unlock failed %s\n", nt_errstr(status));
6419                 goto out;
6420         }
6421
6422         cli_close(cli1, fnum1);
6423
6424         /* Open the symlink for read - this should fail. A POSIX
6425            client should not be doing opens on a symlink. */
6426         status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
6427         if (NT_STATUS_IS_OK(status)) {
6428                 printf("POSIX open of %s succeeded (should have failed)\n", sname);
6429                 goto out;
6430         } else {
6431                 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
6432                                 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
6433                         printf("POSIX open of %s should have failed "
6434                                 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
6435                                 "failed with %s instead.\n",
6436                                 sname, nt_errstr(status));
6437                         goto out;
6438                 }
6439         }
6440
6441         status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
6442         if (!NT_STATUS_IS_OK(status)) {
6443                 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
6444                 goto out;
6445         }
6446
6447         if (strcmp(namebuf, fname) != 0) {
6448                 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
6449                         sname, fname, namebuf);
6450                 goto out;
6451         }
6452
6453         status = cli_posix_rmdir(cli1, dname);
6454         if (!NT_STATUS_IS_OK(status)) {
6455                 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
6456                 goto out;
6457         }
6458
6459         /* Check directory opens with a specific permission. */
6460         status = cli_posix_mkdir(cli1, dname, 0700);
6461         if (!NT_STATUS_IS_OK(status)) {
6462                 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
6463                 goto out;
6464         }
6465
6466         /* Ensure st_mode == 0700 */
6467         status = cli_posix_stat(cli1, dname, &sbuf);
6468         if (!NT_STATUS_IS_OK(status)) {
6469                 printf("stat failed (%s)\n", nt_errstr(status));
6470                 goto out;
6471         }
6472
6473         if ((sbuf.st_ex_mode & 07777) != 0700) {
6474                 printf("posix_mkdir - bad permissions 0%o != 0700\n",
6475                                 (unsigned int)(sbuf.st_ex_mode & 07777));
6476                 goto out;
6477         }
6478
6479         /*
6480          * Now create a Windows file, and attempt a POSIX unlink.
6481          * This should fail with a sharing violation but due to:
6482          *
6483          * [Bug 9571] Unlink after open causes smbd to panic
6484          *
6485          * ensure we've fixed the lock ordering violation.
6486          */
6487
6488         status = cli_ntcreate(cli1, fname_windows, 0,
6489                         FILE_READ_DATA|FILE_WRITE_DATA, 0,
6490                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6491                         FILE_CREATE,
6492                         0x0, 0x0, &fnum2, NULL);
6493         if (!NT_STATUS_IS_OK(status)) {
6494                 printf("Windows create of %s failed (%s)\n", fname_windows,
6495                         nt_errstr(status));
6496                 goto out;
6497         }
6498
6499         /* Now try posix_unlink. */
6500         status = cli_posix_unlink(cli1, fname_windows);
6501         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6502                 printf("POSIX unlink of %s should fail "
6503                         "with NT_STATUS_SHARING_VIOLATION "
6504                         "got %s instead !\n",
6505                         fname_windows,
6506                         nt_errstr(status));
6507                 goto out;
6508         }
6509
6510         cli_close(cli1, fnum2);
6511
6512         printf("Simple POSIX open test passed\n");
6513         correct = true;
6514
6515   out:
6516
6517         if (fnum1 != (uint16_t)-1) {
6518                 cli_close(cli1, fnum1);
6519                 fnum1 = (uint16_t)-1;
6520         }
6521
6522         if (fnum2 != (uint16_t)-1) {
6523                 cli_close(cli1, fnum2);
6524                 fnum2 = (uint16_t)-1;
6525         }
6526
6527         cli_setatr(cli1, sname, 0, 0);
6528         cli_posix_unlink(cli1, sname);
6529         cli_setatr(cli1, hname, 0, 0);
6530         cli_posix_unlink(cli1, hname);
6531         cli_setatr(cli1, fname, 0, 0);
6532         cli_posix_unlink(cli1, fname);
6533         cli_setatr(cli1, dname, 0, 0);
6534         cli_posix_rmdir(cli1, dname);
6535         cli_setatr(cli1, fname_windows, 0, 0);
6536         cli_posix_unlink(cli1, fname_windows);
6537
6538         if (!torture_close_connection(cli1)) {
6539                 correct = false;
6540         }
6541
6542         return correct;
6543 }
6544
6545 /*
6546   Test POSIX and Windows ACLs are rejected on symlinks.
6547  */
6548 static bool run_acl_symlink_test(int dummy)
6549 {
6550         static struct cli_state *cli;
6551         const char *fname = "posix_file";
6552         const char *sname = "posix_symlink";
6553         uint16_t fnum = (uint16_t)-1;
6554         bool correct = false;
6555         NTSTATUS status;
6556         char *posix_acl = NULL;
6557         size_t posix_acl_len = 0;
6558         char *posix_acl_sym = NULL;
6559         size_t posix_acl_len_sym = 0;
6560         struct security_descriptor *sd = NULL;
6561         struct security_descriptor *sd_sym = NULL;
6562         TALLOC_CTX *frame = NULL;
6563
6564         frame = talloc_stackframe();
6565
6566         printf("Starting acl symlink test\n");
6567
6568         if (!torture_open_connection(&cli, 0)) {
6569                 TALLOC_FREE(frame);
6570                 return false;
6571         }
6572
6573         smbXcli_conn_set_sockopt(cli->conn, sockops);
6574
6575         status = torture_setup_unix_extensions(cli);
6576         if (!NT_STATUS_IS_OK(status)) {
6577                 TALLOC_FREE(frame);
6578                 return false;
6579         }
6580
6581         cli_setatr(cli, fname, 0, 0);
6582         cli_posix_unlink(cli, fname);
6583         cli_setatr(cli, sname, 0, 0);
6584         cli_posix_unlink(cli, sname);
6585
6586         status = cli_ntcreate(cli,
6587                         fname,
6588                         0,
6589                         READ_CONTROL_ACCESS,
6590                         0,
6591                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6592                         FILE_CREATE,
6593                         0x0,
6594                         0x0,
6595                         &fnum,
6596                         NULL);
6597
6598         if (!NT_STATUS_IS_OK(status)) {
6599                 printf("cli_ntcreate of %s failed (%s)\n",
6600                         fname,
6601                         nt_errstr(status));
6602                 goto out;
6603         }
6604
6605         /* Get the Windows ACL on the file. */
6606         status = cli_query_secdesc(cli,
6607                                 fnum,
6608                                 frame,
6609                                 &sd);
6610         if (!NT_STATUS_IS_OK(status)) {
6611                 printf("cli_query_secdesc failed (%s)\n",
6612                         nt_errstr(status));
6613                 goto out;
6614         }
6615
6616         /* Get the POSIX ACL on the file. */
6617         status = cli_posix_getacl(cli,
6618                                 fname,
6619                                 frame,
6620                                 &posix_acl_len,
6621                                 &posix_acl);
6622
6623         if (!NT_STATUS_IS_OK(status)) {
6624                 printf("cli_posix_getacl failed (%s)\n",
6625                         nt_errstr(status));
6626                 goto out;
6627         }
6628
6629         status = cli_close(cli, fnum);
6630         if (!NT_STATUS_IS_OK(status)) {
6631                 printf("close failed (%s)\n", nt_errstr(status));
6632                 goto out;
6633         }
6634         fnum = (uint16_t)-1;
6635
6636         /* Now create a symlink. */
6637         status = cli_posix_symlink(cli, fname, sname);
6638         if (!NT_STATUS_IS_OK(status)) {
6639                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6640                         sname,
6641                         fname,
6642                         nt_errstr(status));
6643                 goto out;
6644         }
6645
6646         /* Open a handle on the symlink. */
6647         status = cli_ntcreate(cli,
6648                         sname,
6649                         0,
6650                         READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
6651                         0,
6652                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6653                         FILE_OPEN,
6654                         0x0,
6655                         0x0,
6656                         &fnum,
6657                         NULL);
6658
6659         if (!NT_STATUS_IS_OK(status)) {
6660                 printf("cli_posix_open of %s failed (%s)\n",
6661                         sname,
6662                         nt_errstr(status));
6663                 goto out;
6664         }
6665
6666         /* Get the Windows ACL on the symlink handle. Should fail */
6667         status = cli_query_secdesc(cli,
6668                                 fnum,
6669                                 frame,
6670                                 &sd_sym);
6671
6672         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6673                 printf("cli_query_secdesc on a symlink gave %s. "
6674                         "Should be NT_STATUS_ACCESS_DENIED.\n",
6675                         nt_errstr(status));
6676                 goto out;
6677         }
6678
6679         /* Get the POSIX ACL on the symlink pathname. Should fail. */
6680         status = cli_posix_getacl(cli,
6681                                 sname,
6682                                 frame,
6683                                 &posix_acl_len_sym,
6684                                 &posix_acl_sym);
6685
6686         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6687                 printf("cli_posix_getacl on a symlink gave %s. "
6688                         "Should be NT_STATUS_ACCESS_DENIED.\n",
6689                         nt_errstr(status));
6690                 goto out;
6691         }
6692
6693         /* Set the Windows ACL on the symlink handle. Should fail */
6694         status = cli_set_security_descriptor(cli,
6695                                 fnum,
6696                                 SECINFO_DACL,
6697                                 sd);
6698
6699         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6700                 printf("cli_query_secdesc on a symlink gave %s. "
6701                         "Should be NT_STATUS_ACCESS_DENIED.\n",
6702                         nt_errstr(status));
6703                 goto out;
6704         }
6705
6706         /* Set the POSIX ACL on the symlink pathname. Should fail. */
6707         status = cli_posix_setacl(cli,
6708                                 sname,
6709                                 posix_acl,
6710                                 posix_acl_len);
6711
6712         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6713                 printf("cli_posix_getacl on a symlink gave %s. "
6714                         "Should be NT_STATUS_ACCESS_DENIED.\n",
6715                         nt_errstr(status));
6716                 goto out;
6717         }
6718
6719         printf("ACL symlink test passed\n");
6720         correct = true;
6721
6722   out:
6723
6724         if (fnum != (uint16_t)-1) {
6725                 cli_close(cli, fnum);
6726                 fnum = (uint16_t)-1;
6727         }
6728
6729         cli_setatr(cli, sname, 0, 0);
6730         cli_posix_unlink(cli, sname);
6731         cli_setatr(cli, fname, 0, 0);
6732         cli_posix_unlink(cli, fname);
6733
6734         if (!torture_close_connection(cli)) {
6735                 correct = false;
6736         }
6737
6738         TALLOC_FREE(frame);
6739         return correct;
6740 }
6741
6742 /*
6743   Test POSIX can delete a file containing streams.
6744  */
6745 static bool run_posix_stream_delete(int dummy)
6746 {
6747         struct cli_state *cli1 = NULL;
6748         struct cli_state *cli2 = NULL;
6749         const char *fname = "streamfile";
6750         const char *stream_fname = "streamfile:Zone.Identifier:$DATA";
6751         uint16_t fnum1 = (uint16_t)-1;
6752         bool correct = false;
6753         NTSTATUS status;
6754         TALLOC_CTX *frame = NULL;
6755
6756         frame = talloc_stackframe();
6757
6758         printf("Starting POSIX stream delete test\n");
6759
6760         if (!torture_open_connection(&cli1, 0) ||
6761                         !torture_open_connection(&cli2, 1)) {
6762                 TALLOC_FREE(frame);
6763                 return false;
6764         }
6765
6766         smbXcli_conn_set_sockopt(cli1->conn, sockops);
6767         smbXcli_conn_set_sockopt(cli2->conn, sockops);
6768
6769         status = torture_setup_unix_extensions(cli2);
6770         if (!NT_STATUS_IS_OK(status)) {
6771                 goto out;
6772         }
6773
6774         cli_setatr(cli1, fname, 0, 0);
6775         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6776
6777         /* Create the file. */
6778         status = cli_ntcreate(cli1,
6779                         fname,
6780                         0,
6781                         READ_CONTROL_ACCESS,
6782                         0,
6783                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6784                         FILE_CREATE,
6785                         0x0,
6786                         0x0,
6787                         &fnum1,
6788                         NULL);
6789
6790         if (!NT_STATUS_IS_OK(status)) {
6791                 printf("cli_ntcreate of %s failed (%s)\n",
6792                         fname,
6793                         nt_errstr(status));
6794                 goto out;
6795         }
6796
6797         status = cli_close(cli1, fnum1);
6798         if (!NT_STATUS_IS_OK(status)) {
6799                 printf("cli_close of %s failed (%s)\n",
6800                         fname,
6801                         nt_errstr(status));
6802                 goto out;
6803         }
6804         fnum1 = (uint16_t)-1;
6805
6806         /* Now create the stream. */
6807         status = cli_ntcreate(cli1,
6808                         stream_fname,
6809                         0,
6810                         FILE_WRITE_DATA,
6811                         0,
6812                         FILE_SHARE_READ|FILE_SHARE_WRITE,
6813                         FILE_CREATE,
6814                         0x0,
6815                         0x0,
6816                         &fnum1,
6817                         NULL);
6818
6819         if (!NT_STATUS_IS_OK(status)) {
6820                 printf("cli_ntcreate of %s failed (%s)\n",
6821                         stream_fname,
6822                         nt_errstr(status));
6823                 goto out;
6824         }
6825
6826         /* Leave the stream handle open... */
6827
6828         /* POSIX unlink should fail. */
6829         status = cli_posix_unlink(cli2, fname);
6830         if (NT_STATUS_IS_OK(status)) {
6831                 printf("cli_posix_unlink of %s succeeded, should have failed\n",
6832                         fname);
6833                 goto out;
6834         }
6835
6836         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6837                 printf("cli_posix_unlink of %s failed with (%s) "
6838                         "should have been NT_STATUS_SHARING_VIOLATION\n",
6839                         fname,
6840                         nt_errstr(status));
6841                 goto out;
6842         }
6843
6844         /* Close the stream handle. */
6845         status = cli_close(cli1, fnum1);
6846         if (!NT_STATUS_IS_OK(status)) {
6847                 printf("cli_close of %s failed (%s)\n",
6848                         stream_fname,
6849                         nt_errstr(status));
6850                 goto out;
6851         }
6852         fnum1 = (uint16_t)-1;
6853
6854         /* POSIX unlink after stream handle closed should succeed. */
6855         status = cli_posix_unlink(cli2, fname);
6856         if (!NT_STATUS_IS_OK(status)) {
6857                 printf("cli_posix_unlink of %s failed (%s)\n",
6858                         fname,
6859                         nt_errstr(status));
6860                 goto out;
6861         }
6862
6863         printf("POSIX stream delete test passed\n");
6864         correct = true;
6865
6866   out:
6867
6868         if (fnum1 != (uint16_t)-1) {
6869                 cli_close(cli1, fnum1);
6870                 fnum1 = (uint16_t)-1;
6871         }
6872
6873         cli_setatr(cli1, fname, 0, 0);
6874         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6875
6876         if (!torture_close_connection(cli1)) {
6877                 correct = false;
6878         }
6879         if (!torture_close_connection(cli2)) {
6880                 correct = false;
6881         }
6882
6883         TALLOC_FREE(frame);
6884         return correct;
6885 }
6886
6887 /*
6888   Test setting EA's are rejected on symlinks.
6889  */
6890 static bool run_ea_symlink_test(int dummy)
6891 {
6892         static struct cli_state *cli;
6893         const char *fname = "posix_file_ea";
6894         const char *sname = "posix_symlink_ea";
6895         const char *ea_name = "testea_name";
6896         const char *ea_value = "testea_value";
6897         uint16_t fnum = (uint16_t)-1;
6898         bool correct = false;
6899         NTSTATUS status;
6900         size_t i, num_eas;
6901         struct ea_struct *eas = NULL;
6902         TALLOC_CTX *frame = NULL;
6903
6904         frame = talloc_stackframe();
6905
6906         printf("Starting EA symlink test\n");
6907
6908         if (!torture_open_connection(&cli, 0)) {
6909                 TALLOC_FREE(frame);
6910                 return false;
6911         }
6912
6913         smbXcli_conn_set_sockopt(cli->conn, sockops);
6914
6915         status = torture_setup_unix_extensions(cli);
6916         if (!NT_STATUS_IS_OK(status)) {
6917                 TALLOC_FREE(frame);
6918                 return false;
6919         }
6920
6921         cli_setatr(cli, fname, 0, 0);
6922         cli_posix_unlink(cli, fname);
6923         cli_setatr(cli, sname, 0, 0);
6924         cli_posix_unlink(cli, sname);
6925
6926         status = cli_ntcreate(cli,
6927                         fname,
6928                         0,
6929                         READ_CONTROL_ACCESS,
6930                         0,
6931                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6932                         FILE_CREATE,
6933                         0x0,
6934                         0x0,
6935                         &fnum,
6936                         NULL);
6937
6938         if (!NT_STATUS_IS_OK(status)) {
6939                 printf("cli_ntcreate of %s failed (%s)\n",
6940                         fname,
6941                         nt_errstr(status));
6942                 goto out;
6943         }
6944
6945         status = cli_close(cli, fnum);
6946         if (!NT_STATUS_IS_OK(status)) {
6947                 printf("close failed (%s)\n",
6948                         nt_errstr(status));
6949                 goto out;
6950         }
6951         fnum = (uint16_t)-1;
6952
6953         /* Set an EA on the path. */
6954         status = cli_set_ea_path(cli,
6955                                 fname,
6956                                 ea_name,
6957                                 ea_value,
6958                                 strlen(ea_value)+1);
6959
6960         if (!NT_STATUS_IS_OK(status)) {
6961                 printf("cli_set_ea_path failed (%s)\n",
6962                         nt_errstr(status));
6963                 goto out;
6964         }
6965
6966         /* Now create a symlink. */
6967         status = cli_posix_symlink(cli, fname, sname);
6968         if (!NT_STATUS_IS_OK(status)) {
6969                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6970                         sname,
6971                         fname,
6972                         nt_errstr(status));
6973                 goto out;
6974         }
6975
6976         /* Get the EA list on the path. Should return value set. */
6977         status = cli_get_ea_list_path(cli,
6978                                 fname,
6979                                 frame,
6980                                 &num_eas,
6981                                 &eas);
6982
6983         if (!NT_STATUS_IS_OK(status)) {
6984                 printf("cli_get_ea_list_path failed (%s)\n",
6985                         nt_errstr(status));
6986                 goto out;
6987         }
6988
6989         /* Ensure the EA we set is there. */
6990         for (i=0; i<num_eas; i++) {
6991                 if (strcmp(eas[i].name, ea_name) == 0 &&
6992                                 eas[i].value.length == strlen(ea_value)+1 &&
6993                                 memcmp(eas[i].value.data,
6994                                         ea_value,
6995                                         eas[i].value.length) == 0) {
6996                         break;
6997                 }
6998         }
6999
7000         if (i == num_eas) {
7001                 printf("Didn't find EA on pathname %s\n",
7002                         fname);
7003                 goto out;
7004         }
7005
7006         num_eas = 0;
7007         TALLOC_FREE(eas);
7008
7009         /* Get the EA list on the symlink. Should return empty list. */
7010         status = cli_get_ea_list_path(cli,
7011                                 sname,
7012                                 frame,
7013                                 &num_eas,
7014                                 &eas);
7015
7016         if (!NT_STATUS_IS_OK(status)) {
7017                 printf("cli_get_ea_list_path failed (%s)\n",
7018                         nt_errstr(status));
7019                 goto out;
7020         }
7021
7022         if (num_eas != 0) {
7023                 printf("cli_get_ea_list_path failed (%s)\n",
7024                         nt_errstr(status));
7025                 goto out;
7026         }
7027
7028         /* Set an EA on the symlink. Should fail. */
7029         status = cli_set_ea_path(cli,
7030                                 sname,
7031                                 ea_name,
7032                                 ea_value,
7033                                 strlen(ea_value)+1);
7034
7035         if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7036                 printf("cli_set_ea_path on a symlink gave %s. "
7037                         "Should be NT_STATUS_ACCESS_DENIED.\n",
7038                         nt_errstr(status));
7039                 goto out;
7040         }
7041
7042         printf("EA symlink test passed\n");
7043         correct = true;
7044
7045   out:
7046
7047         if (fnum != (uint16_t)-1) {
7048                 cli_close(cli, fnum);
7049                 fnum = (uint16_t)-1;
7050         }
7051
7052         cli_setatr(cli, sname, 0, 0);
7053         cli_posix_unlink(cli, sname);
7054         cli_setatr(cli, fname, 0, 0);
7055         cli_posix_unlink(cli, fname);
7056
7057         if (!torture_close_connection(cli)) {
7058                 correct = false;
7059         }
7060
7061         TALLOC_FREE(frame);
7062         return correct;
7063 }
7064
7065 /*
7066   Test POSIX locks are OFD-locks.
7067  */
7068 static bool run_posix_ofd_lock_test(int dummy)
7069 {
7070         static struct cli_state *cli;
7071         const char *fname = "posix_file";
7072         uint16_t fnum1 = (uint16_t)-1;
7073         uint16_t fnum2 = (uint16_t)-1;
7074         bool correct = false;
7075         NTSTATUS status;
7076         TALLOC_CTX *frame = NULL;
7077
7078         frame = talloc_stackframe();
7079
7080         printf("Starting POSIX ofd-lock test\n");
7081
7082         if (!torture_open_connection(&cli, 0)) {
7083                 TALLOC_FREE(frame);
7084                 return false;
7085         }
7086
7087         smbXcli_conn_set_sockopt(cli->conn, sockops);
7088
7089         status = torture_setup_unix_extensions(cli);
7090         if (!NT_STATUS_IS_OK(status)) {
7091                 TALLOC_FREE(frame);
7092                 return false;
7093         }
7094
7095         cli_setatr(cli, fname, 0, 0);
7096         cli_posix_unlink(cli, fname);
7097
7098         /* Open the file twice. */
7099         status = cli_posix_open(cli, fname, O_RDWR|O_CREAT|O_EXCL,
7100                                 0600, &fnum1);
7101         if (!NT_STATUS_IS_OK(status)) {
7102                 printf("First POSIX open of %s failed\n", fname);
7103                 goto out;
7104         }
7105
7106         status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum2);
7107         if (!NT_STATUS_IS_OK(status)) {
7108                 printf("First POSIX open of %s failed\n", fname);
7109                 goto out;
7110         }
7111
7112         /* Set a 0-50 lock on fnum1. */
7113         status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
7114         if (!NT_STATUS_IS_OK(status)) {
7115                 printf("POSIX lock (1) failed %s\n", nt_errstr(status));
7116                 goto out;
7117         }
7118
7119         /* Set a 60-100 lock on fnum2. */
7120         status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK);
7121         if (!NT_STATUS_IS_OK(status)) {
7122                 printf("POSIX lock (2) failed %s\n", nt_errstr(status));
7123                 goto out;
7124         }
7125
7126         /* close fnum1 - 0-50 lock should go away. */
7127         status = cli_close(cli, fnum1);
7128         if (!NT_STATUS_IS_OK(status)) {
7129                 printf("close failed (%s)\n",
7130                         nt_errstr(status));
7131                 goto out;
7132         }
7133         fnum1 = (uint16_t)-1;
7134
7135         /* Change the lock context. */
7136         cli_setpid(cli, cli_getpid(cli) + 1);
7137
7138         /* Re-open fnum1. */
7139         status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1);
7140         if (!NT_STATUS_IS_OK(status)) {
7141                 printf("Third POSIX open of %s failed\n", fname);
7142                 goto out;
7143         }
7144
7145         /* 60-100 lock should still be there. */
7146         status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK);
7147         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
7148                 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status));
7149                 goto out;
7150         }
7151
7152         /* 0-50 lock should be gone. */
7153         status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
7154         if (!NT_STATUS_IS_OK(status)) {
7155                 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status));
7156                 goto out;
7157         }
7158
7159         printf("POSIX OFD lock test passed\n");
7160         correct = true;
7161
7162   out:
7163
7164         if (fnum1 != (uint16_t)-1) {
7165                 cli_close(cli, fnum1);
7166                 fnum1 = (uint16_t)-1;
7167         }
7168         if (fnum2 != (uint16_t)-1) {
7169                 cli_close(cli, fnum2);
7170                 fnum2 = (uint16_t)-1;
7171         }
7172
7173         cli_setatr(cli, fname, 0, 0);
7174         cli_posix_unlink(cli, fname);
7175
7176         if (!torture_close_connection(cli)) {
7177                 correct = false;
7178         }
7179
7180         TALLOC_FREE(frame);
7181         return correct;
7182 }
7183
7184 static uint32_t open_attrs_table[] = {
7185                 FILE_ATTRIBUTE_NORMAL,
7186                 FILE_ATTRIBUTE_ARCHIVE,
7187                 FILE_ATTRIBUTE_READONLY,
7188                 FILE_ATTRIBUTE_HIDDEN,
7189                 FILE_ATTRIBUTE_SYSTEM,
7190
7191                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
7192                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
7193                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
7194                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7195                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7196                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7197
7198                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7199                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7200                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7201                 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
7202 };
7203
7204 struct trunc_open_results {
7205         unsigned int num;
7206         uint32_t init_attr;
7207         uint32_t trunc_attr;
7208         uint32_t result_attr;
7209 };
7210
7211 static struct trunc_open_results attr_results[] = {
7212         { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7213         { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7214         { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7215         { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7216         { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7217         { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7218         { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7219         { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7220         { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7221         { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7222         { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7223         { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
7224         { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7225         { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7226         { 104, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7227         { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7228         { 119,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7229         { 121, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
7230         { 170, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN },
7231         { 173, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM },
7232         { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7233         { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7234         { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7235         { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7236         { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7237         { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
7238 };
7239
7240 static bool run_openattrtest(int dummy)
7241 {
7242         static struct cli_state *cli1;
7243         const char *fname = "\\openattr.file";
7244         uint16_t fnum1;
7245         bool correct = True;
7246         uint16_t attr;
7247         unsigned int i, j, k, l;
7248         NTSTATUS status;
7249
7250         printf("starting open attr test\n");
7251
7252         if (!torture_open_connection(&cli1, 0)) {
7253                 return False;
7254         }
7255
7256         smbXcli_conn_set_sockopt(cli1->conn, sockops);
7257
7258         for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
7259                 cli_setatr(cli1, fname, 0, 0);
7260                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7261
7262                 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
7263                                        open_attrs_table[i], FILE_SHARE_NONE,
7264                                        FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
7265                 if (!NT_STATUS_IS_OK(status)) {
7266                         printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7267                         return False;
7268                 }
7269
7270                 status = cli_close(cli1, fnum1);
7271                 if (!NT_STATUS_IS_OK(status)) {
7272                         printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7273                         return False;
7274                 }
7275
7276                 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
7277                         status = cli_ntcreate(cli1, fname, 0,
7278                                               FILE_READ_DATA|FILE_WRITE_DATA,
7279                                               open_attrs_table[j],
7280                                               FILE_SHARE_NONE, FILE_OVERWRITE,
7281                                               0, 0, &fnum1, NULL);
7282                         if (!NT_STATUS_IS_OK(status)) {
7283                                 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7284                                         if (attr_results[l].num == k) {
7285                                                 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
7286                                                                 k, open_attrs_table[i],
7287                                                                 open_attrs_table[j],
7288                                                                 fname, NT_STATUS_V(status), nt_errstr(status));
7289                                                 correct = False;
7290                                         }
7291                                 }
7292
7293                                 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7294                                         printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
7295                                                         k, open_attrs_table[i], open_attrs_table[j],
7296                                                         nt_errstr(status));
7297                                         correct = False;
7298                                 }
7299 #if 0
7300                                 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
7301 #endif
7302                                 k++;
7303                                 continue;
7304                         }
7305
7306                         status = cli_close(cli1, fnum1);
7307                         if (!NT_STATUS_IS_OK(status)) {
7308                                 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
7309                                 return False;
7310                         }
7311
7312                         status = cli_getatr(cli1, fname, &attr, NULL, NULL);
7313                         if (!NT_STATUS_IS_OK(status)) {
7314                                 printf("getatr(2) failed (%s)\n", nt_errstr(status));
7315                                 return False;
7316                         }
7317
7318 #if 0
7319                         printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
7320                                         k,  open_attrs_table[i],  open_attrs_table[j], attr );
7321 #endif
7322
7323                         for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7324                                 if (attr_results[l].num == k) {
7325                                         if (attr != attr_results[l].result_attr ||
7326                                                         open_attrs_table[i] != attr_results[l].init_attr ||
7327                                                         open_attrs_table[j] != attr_results[l].trunc_attr) {
7328                                                 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
7329                                                 open_attrs_table[i],
7330                                                 open_attrs_table[j],
7331                                                 (unsigned int)attr,
7332                                                 attr_results[l].result_attr);
7333                                                 correct = False;
7334                                         }
7335                                         break;
7336                                 }
7337                         }
7338                         k++;
7339                 }
7340         }
7341
7342         cli_setatr(cli1, fname, 0, 0);
7343         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7344
7345         printf("open attr test %s.\n", correct ? "passed" : "failed");
7346
7347         if (!torture_close_connection(cli1)) {
7348                 correct = False;
7349         }
7350         return correct;
7351 }
7352
7353 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
7354                     const char *name, void *state)
7355 {
7356         int *matched = (int *)state;
7357         if (matched != NULL) {
7358                 *matched += 1;
7359         }
7360         return NT_STATUS_OK;
7361 }
7362
7363 /*
7364   test directory listing speed
7365  */
7366 static bool run_dirtest(int dummy)
7367 {
7368         int i;
7369         static struct cli_state *cli;
7370         uint16_t fnum;
7371         struct timeval core_start;
7372         bool correct = True;
7373         int matched;
7374
7375         printf("starting directory test\n");
7376
7377         if (!torture_open_connection(&cli, 0)) {
7378                 return False;
7379         }
7380
7381         smbXcli_conn_set_sockopt(cli->conn, sockops);
7382
7383         srandom(0);
7384         for (i=0;i<torture_numops;i++) {
7385                 fstring fname;
7386                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7387                 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
7388                         fprintf(stderr,"Failed to open %s\n", fname);
7389                         return False;
7390                 }
7391                 cli_close(cli, fnum);
7392         }
7393
7394         core_start = timeval_current();
7395
7396         matched = 0;
7397         cli_list(cli, "a*.*", 0, list_fn, &matched);
7398         printf("Matched %d\n", matched);
7399
7400         matched = 0;
7401         cli_list(cli, "b*.*", 0, list_fn, &matched);
7402         printf("Matched %d\n", matched);
7403
7404         matched = 0;
7405         cli_list(cli, "xyzabc", 0, list_fn, &matched);
7406         printf("Matched %d\n", matched);
7407
7408         printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
7409
7410         srandom(0);
7411         for (i=0;i<torture_numops;i++) {
7412                 fstring fname;
7413                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7414                 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7415         }
7416
7417         if (!torture_close_connection(cli)) {
7418                 correct = False;
7419         }
7420
7421         printf("finished dirtest\n");
7422
7423         return correct;
7424 }
7425
7426 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
7427                    void *state)
7428 {
7429         struct cli_state *pcli = (struct cli_state *)state;
7430         fstring fname;
7431         slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
7432
7433         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7434                 return NT_STATUS_OK;
7435
7436         if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7437                 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
7438                         printf("del_fn: failed to rmdir %s\n,", fname );
7439         } else {
7440                 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
7441                         printf("del_fn: failed to unlink %s\n,", fname );
7442         }
7443         return NT_STATUS_OK;
7444 }
7445
7446
7447 /*
7448   sees what IOCTLs are supported
7449  */
7450 bool torture_ioctl_test(int dummy)
7451 {
7452         static struct cli_state *cli;
7453         uint16_t device, function;
7454         uint16_t fnum;
7455         const char *fname = "\\ioctl.dat";
7456         DATA_BLOB blob;
7457         NTSTATUS status;
7458
7459         if (!torture_open_connection(&cli, 0)) {
7460                 return False;
7461         }
7462
7463         printf("starting ioctl test\n");
7464
7465         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7466
7467         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7468         if (!NT_STATUS_IS_OK(status)) {
7469                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
7470                 return False;
7471         }
7472
7473         status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
7474         printf("ioctl device info: %s\n", nt_errstr(status));
7475
7476         status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
7477         printf("ioctl job info: %s\n", nt_errstr(status));
7478
7479         for (device=0;device<0x100;device++) {
7480                 printf("ioctl test with device = 0x%x\n", device);
7481                 for (function=0;function<0x100;function++) {
7482                         uint32_t code = (device<<16) | function;
7483
7484                         status = cli_raw_ioctl(cli, fnum, code, &blob);
7485
7486                         if (NT_STATUS_IS_OK(status)) {
7487                                 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
7488                                        (int)blob.length);
7489                                 data_blob_free(&blob);
7490                         }
7491                 }
7492         }
7493
7494         if (!torture_close_connection(cli)) {
7495                 return False;
7496         }
7497
7498         return True;
7499 }
7500
7501
7502 /*
7503   tries varients of chkpath
7504  */
7505 bool torture_chkpath_test(int dummy)
7506 {
7507         static struct cli_state *cli;
7508         uint16_t fnum;
7509         bool ret;
7510         NTSTATUS status;
7511
7512         if (!torture_open_connection(&cli, 0)) {
7513                 return False;
7514         }
7515
7516         printf("starting chkpath test\n");
7517
7518         /* cleanup from an old run */
7519         cli_rmdir(cli, "\\chkpath.dir\\dir2");
7520         cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7521         cli_rmdir(cli, "\\chkpath.dir");
7522
7523         status = cli_mkdir(cli, "\\chkpath.dir");
7524         if (!NT_STATUS_IS_OK(status)) {
7525                 printf("mkdir1 failed : %s\n", nt_errstr(status));
7526                 return False;
7527         }
7528
7529         status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
7530         if (!NT_STATUS_IS_OK(status)) {
7531                 printf("mkdir2 failed : %s\n", nt_errstr(status));
7532                 return False;
7533         }
7534
7535         status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
7536                           DENY_NONE, &fnum);
7537         if (!NT_STATUS_IS_OK(status)) {
7538                 printf("open1 failed (%s)\n", nt_errstr(status));
7539                 return False;
7540         }
7541         cli_close(cli, fnum);
7542
7543         status = cli_chkpath(cli, "\\chkpath.dir");
7544         if (!NT_STATUS_IS_OK(status)) {
7545                 printf("chkpath1 failed: %s\n", nt_errstr(status));
7546                 ret = False;
7547         }
7548
7549         status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
7550         if (!NT_STATUS_IS_OK(status)) {
7551                 printf("chkpath2 failed: %s\n", nt_errstr(status));
7552                 ret = False;
7553         }
7554
7555         status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
7556         if (!NT_STATUS_IS_OK(status)) {
7557                 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7558                                   NT_STATUS_NOT_A_DIRECTORY);
7559         } else {
7560                 printf("* chkpath on a file should fail\n");
7561                 ret = False;
7562         }
7563
7564         status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
7565         if (!NT_STATUS_IS_OK(status)) {
7566                 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
7567                                   NT_STATUS_OBJECT_NAME_NOT_FOUND);
7568         } else {
7569                 printf("* chkpath on a non existent file should fail\n");
7570                 ret = False;
7571         }
7572
7573         status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
7574         if (!NT_STATUS_IS_OK(status)) {
7575                 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7576                                   NT_STATUS_OBJECT_PATH_NOT_FOUND);
7577         } else {
7578                 printf("* chkpath on a non existent component should fail\n");
7579                 ret = False;
7580         }
7581
7582         cli_rmdir(cli, "\\chkpath.dir\\dir2");
7583         cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7584         cli_rmdir(cli, "\\chkpath.dir");
7585
7586         if (!torture_close_connection(cli)) {
7587                 return False;
7588         }
7589
7590         return ret;
7591 }
7592
7593 static bool run_eatest(int dummy)
7594 {
7595         static struct cli_state *cli;
7596         const char *fname = "\\eatest.txt";
7597         bool correct = True;
7598         uint16_t fnum;
7599         int i;
7600         size_t num_eas;
7601         struct ea_struct *ea_list = NULL;
7602         TALLOC_CTX *mem_ctx = talloc_init("eatest");
7603         NTSTATUS status;
7604
7605         printf("starting eatest\n");
7606
7607         if (!torture_open_connection(&cli, 0)) {
7608                 talloc_destroy(mem_ctx);
7609                 return False;
7610         }
7611
7612         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7613
7614         status = cli_ntcreate(cli, fname, 0,
7615                               FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7616                               FILE_SHARE_NONE, FILE_OVERWRITE_IF,
7617                               0x4044, 0, &fnum, NULL);
7618         if (!NT_STATUS_IS_OK(status)) {
7619                 printf("open failed - %s\n", nt_errstr(status));
7620                 talloc_destroy(mem_ctx);
7621                 return False;
7622         }
7623
7624         for (i = 0; i < 10; i++) {
7625                 fstring ea_name, ea_val;
7626
7627                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
7628                 memset(ea_val, (char)i+1, i+1);
7629                 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
7630                 if (!NT_STATUS_IS_OK(status)) {
7631                         printf("ea_set of name %s failed - %s\n", ea_name,
7632                                nt_errstr(status));
7633                         talloc_destroy(mem_ctx);
7634                         return False;
7635                 }
7636         }
7637
7638         cli_close(cli, fnum);
7639         for (i = 0; i < 10; i++) {
7640                 fstring ea_name, ea_val;
7641
7642                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
7643                 memset(ea_val, (char)i+1, i+1);
7644                 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
7645                 if (!NT_STATUS_IS_OK(status)) {
7646                         printf("ea_set of name %s failed - %s\n", ea_name,
7647                                nt_errstr(status));
7648                         talloc_destroy(mem_ctx);
7649                         return False;
7650                 }
7651         }
7652
7653         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7654         if (!NT_STATUS_IS_OK(status)) {
7655                 printf("ea_get list failed - %s\n", nt_errstr(status));
7656                 correct = False;
7657         }
7658
7659         printf("num_eas = %d\n", (int)num_eas);
7660
7661         if (num_eas != 20) {
7662                 printf("Should be 20 EA's stored... failing.\n");
7663                 correct = False;
7664         }
7665
7666         for (i = 0; i < num_eas; i++) {
7667                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7668                 dump_data(0, ea_list[i].value.data,
7669                           ea_list[i].value.length);
7670         }
7671
7672         /* Setting EA's to zero length deletes them. Test this */
7673         printf("Now deleting all EA's - case indepenent....\n");
7674
7675 #if 1
7676         cli_set_ea_path(cli, fname, "", "", 0);
7677 #else
7678         for (i = 0; i < 20; i++) {
7679                 fstring ea_name;
7680                 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
7681                 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
7682                 if (!NT_STATUS_IS_OK(status)) {
7683                         printf("ea_set of name %s failed - %s\n", ea_name,
7684                                nt_errstr(status));
7685                         talloc_destroy(mem_ctx);
7686                         return False;
7687                 }
7688         }
7689 #endif
7690
7691         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7692         if (!NT_STATUS_IS_OK(status)) {
7693                 printf("ea_get list failed - %s\n", nt_errstr(status));
7694                 correct = False;
7695         }
7696
7697         printf("num_eas = %d\n", (int)num_eas);
7698         for (i = 0; i < num_eas; i++) {
7699                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7700                 dump_data(0, ea_list[i].value.data,
7701                           ea_list[i].value.length);
7702         }
7703
7704         if (num_eas != 0) {
7705                 printf("deleting EA's failed.\n");
7706                 correct = False;
7707         }
7708
7709         /* Try and delete a non existent EA. */
7710         status = cli_set_ea_path(cli, fname, "foo", "", 0);
7711         if (!NT_STATUS_IS_OK(status)) {
7712                 printf("deleting non-existent EA 'foo' should succeed. %s\n",
7713                        nt_errstr(status));
7714                 correct = False;
7715         }
7716
7717         talloc_destroy(mem_ctx);
7718         if (!torture_close_connection(cli)) {
7719                 correct = False;
7720         }
7721
7722         return correct;
7723 }
7724
7725 static bool run_dirtest1(int dummy)
7726 {
7727         int i;
7728         static struct cli_state *cli;
7729         uint16_t fnum;
7730         int num_seen;
7731         bool correct = True;
7732
7733         printf("starting directory test\n");
7734
7735         if (!torture_open_connection(&cli, 0)) {
7736                 return False;
7737         }
7738
7739         smbXcli_conn_set_sockopt(cli->conn, sockops);
7740
7741         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7742         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7743         cli_rmdir(cli, "\\LISTDIR");
7744         cli_mkdir(cli, "\\LISTDIR");
7745
7746         /* Create 1000 files and 1000 directories. */
7747         for (i=0;i<1000;i++) {
7748                 fstring fname;
7749                 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
7750                 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7751                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
7752                                    0, 0, &fnum, NULL))) {
7753                         fprintf(stderr,"Failed to open %s\n", fname);
7754                         return False;
7755                 }
7756                 cli_close(cli, fnum);
7757         }
7758         for (i=0;i<1000;i++) {
7759                 fstring fname;
7760                 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
7761                 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
7762                         fprintf(stderr,"Failed to open %s\n", fname);
7763                         return False;
7764                 }
7765         }
7766
7767         /* Now ensure that doing an old list sees both files and directories. */
7768         num_seen = 0;
7769         cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7770         printf("num_seen = %d\n", num_seen );
7771         /* We should see 100 files + 1000 directories + . and .. */
7772         if (num_seen != 2002)
7773                 correct = False;
7774
7775         /* Ensure if we have the "must have" bits we only see the
7776          * relevent entries.
7777          */
7778         num_seen = 0;
7779         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7780         printf("num_seen = %d\n", num_seen );
7781         if (num_seen != 1002)
7782                 correct = False;
7783
7784         num_seen = 0;
7785         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7786         printf("num_seen = %d\n", num_seen );
7787         if (num_seen != 1000)
7788                 correct = False;
7789
7790         /* Delete everything. */
7791         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7792         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7793         cli_rmdir(cli, "\\LISTDIR");
7794
7795 #if 0
7796         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
7797         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
7798         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
7799 #endif
7800
7801         if (!torture_close_connection(cli)) {
7802                 correct = False;
7803         }
7804
7805         printf("finished dirtest1\n");
7806
7807         return correct;
7808 }
7809
7810 static bool run_error_map_extract(int dummy) {
7811
7812         static struct cli_state *c_dos;
7813         static struct cli_state *c_nt;
7814         NTSTATUS status;
7815
7816         uint32_t error;
7817
7818         uint32_t errnum;
7819         uint8_t errclass;
7820
7821         NTSTATUS nt_status;
7822
7823         fstring user;
7824
7825         /* NT-Error connection */
7826
7827         disable_spnego = true;
7828         if (!(c_nt = open_nbt_connection())) {
7829                 disable_spnego = false;
7830                 return False;
7831         }
7832         disable_spnego = false;
7833
7834         status = smbXcli_negprot(c_nt->conn, c_nt->timeout, PROTOCOL_CORE,
7835                                  PROTOCOL_NT1);
7836
7837         if (!NT_STATUS_IS_OK(status)) {
7838                 printf("%s rejected the NT-error negprot (%s)\n", host,
7839                        nt_errstr(status));
7840                 cli_shutdown(c_nt);
7841                 return False;
7842         }
7843
7844         status = cli_session_setup_anon(c_nt);
7845         if (!NT_STATUS_IS_OK(status)) {
7846                 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
7847                 return False;
7848         }
7849
7850         /* DOS-Error connection */
7851
7852         disable_spnego = true;
7853         force_dos_errors = true;
7854         if (!(c_dos = open_nbt_connection())) {
7855                 disable_spnego = false;
7856                 force_dos_errors = false;
7857                 return False;
7858         }
7859         disable_spnego = false;
7860         force_dos_errors = false;
7861
7862         status = smbXcli_negprot(c_dos->conn, c_dos->timeout, PROTOCOL_CORE,
7863                                  PROTOCOL_NT1);
7864         if (!NT_STATUS_IS_OK(status)) {
7865                 printf("%s rejected the DOS-error negprot (%s)\n", host,
7866                        nt_errstr(status));
7867                 cli_shutdown(c_dos);
7868                 return False;
7869         }
7870
7871         status = cli_session_setup_anon(c_dos);
7872         if (!NT_STATUS_IS_OK(status)) {
7873                 printf("%s rejected the DOS-error initial session setup (%s)\n",
7874                         host, nt_errstr(status));
7875                 return False;
7876         }
7877
7878         c_nt->map_dos_errors = false;
7879         c_dos->map_dos_errors = false;
7880
7881         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
7882                 struct cli_credentials *user_creds = NULL;
7883
7884                 fstr_sprintf(user, "%X", error);
7885
7886                 user_creds = cli_session_creds_init(talloc_tos(),
7887                                                     user,
7888                                                     workgroup,
7889                                                     NULL, /* realm */
7890                                                     password,
7891                                                     false, /* use_kerberos */
7892                                                     false, /* fallback_after_kerberos */
7893                                                     false, /* use_ccache */
7894                                                     false); /* password_is_nt_hash */
7895                 if (user_creds == NULL) {
7896                         printf("cli_session_creds_init(%s) failed\n", user);
7897                         return false;
7898                 }
7899
7900                 status = cli_session_setup_creds(c_nt, user_creds);
7901                 if (NT_STATUS_IS_OK(status)) {
7902                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
7903                 }
7904
7905                 /* Case #1: 32-bit NT errors */
7906                 if (!NT_STATUS_IS_DOS(status)) {
7907                         nt_status = status;
7908                 } else {
7909                         printf("/** Dos error on NT connection! (%s) */\n", 
7910                                nt_errstr(status));
7911                         nt_status = NT_STATUS(0xc0000000);
7912                 }
7913
7914                 status = cli_session_setup_creds(c_dos, user_creds);
7915                 if (NT_STATUS_IS_OK(status)) {
7916                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
7917                 }
7918
7919                 /* Case #1: 32-bit NT errors */
7920                 if (NT_STATUS_IS_DOS(status)) {
7921                         printf("/** NT error on DOS connection! (%s) */\n", 
7922                                nt_errstr(status));
7923                         errnum = errclass = 0;
7924                 } else {
7925                         errclass = NT_STATUS_DOS_CLASS(status);
7926                         errnum = NT_STATUS_DOS_CODE(status);
7927                 }
7928
7929                 if (NT_STATUS_V(nt_status) != error) { 
7930                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
7931                                get_nt_error_c_code(talloc_tos(), NT_STATUS(error)), 
7932                                get_nt_error_c_code(talloc_tos(), nt_status));
7933                 }
7934
7935                 printf("\t{%s,\t%s,\t%s},\n", 
7936                        smb_dos_err_class(errclass), 
7937                        smb_dos_err_name(errclass, errnum), 
7938                        get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
7939
7940                 TALLOC_FREE(user_creds);
7941         }
7942         return True;
7943 }
7944
7945 static bool run_sesssetup_bench(int dummy)
7946 {
7947         static struct cli_state *c;
7948         const char *fname = "\\file.dat";
7949         uint16_t fnum;
7950         NTSTATUS status;
7951         int i;
7952
7953         if (!torture_open_connection(&c, 0)) {
7954                 return false;
7955         }
7956
7957         status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
7958                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7959                               FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
7960         if (!NT_STATUS_IS_OK(status)) {
7961                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7962                 return false;
7963         }
7964
7965         for (i=0; i<torture_numops; i++) {
7966                 status = cli_session_setup_creds(c, torture_creds);
7967                 if (!NT_STATUS_IS_OK(status)) {
7968                         d_printf("(%s) cli_session_setup_creds failed: %s\n",
7969                                  __location__, nt_errstr(status));
7970                         return false;
7971                 }
7972
7973                 d_printf("\r%d   ", (int)cli_state_get_uid(c));
7974
7975                 status = cli_ulogoff(c);
7976                 if (!NT_STATUS_IS_OK(status)) {
7977                         d_printf("(%s) cli_ulogoff failed: %s\n",
7978                                  __location__, nt_errstr(status));
7979                         return false;
7980                 }
7981         }
7982
7983         return true;
7984 }
7985
7986 static bool subst_test(const char *str, const char *user, const char *domain,
7987                        uid_t uid, gid_t gid, const char *expected)
7988 {
7989         char *subst;
7990         bool result = true;
7991
7992         subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
7993
7994         if (strcmp(subst, expected) != 0) {
7995                 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
7996                        "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
7997                        expected);
7998                 result = false;
7999         }
8000
8001         TALLOC_FREE(subst);
8002         return result;
8003 }
8004
8005 static void chain1_open_completion(struct tevent_req *req)
8006 {
8007         uint16_t fnum;
8008         NTSTATUS status;
8009         status = cli_openx_recv(req, &fnum);
8010         TALLOC_FREE(req);
8011
8012         d_printf("cli_openx_recv returned %s: %d\n",
8013                  nt_errstr(status),
8014                  NT_STATUS_IS_OK(status) ? fnum : -1);
8015 }
8016
8017 static void chain1_write_completion(struct tevent_req *req)
8018 {
8019         size_t written;
8020         NTSTATUS status;
8021         status = cli_write_andx_recv(req, &written);
8022         TALLOC_FREE(req);
8023
8024         d_printf("cli_write_andx_recv returned %s: %d\n",
8025                  nt_errstr(status),
8026                  NT_STATUS_IS_OK(status) ? (int)written : -1);
8027 }
8028
8029 static void chain1_close_completion(struct tevent_req *req)
8030 {
8031         NTSTATUS status;
8032         bool *done = (bool *)tevent_req_callback_data_void(req);
8033
8034         status = cli_close_recv(req);
8035         *done = true;
8036
8037         TALLOC_FREE(req);
8038
8039         d_printf("cli_close returned %s\n", nt_errstr(status));
8040 }
8041
8042 static bool run_chain1(int dummy)
8043 {
8044         struct cli_state *cli1;
8045         struct tevent_context *evt = samba_tevent_context_init(NULL);
8046         struct tevent_req *reqs[3], *smbreqs[3];
8047         bool done = false;
8048         const char *str = "foobar";
8049         NTSTATUS status;
8050
8051         printf("starting chain1 test\n");
8052         if (!torture_open_connection(&cli1, 0)) {
8053                 return False;
8054         }
8055
8056         smbXcli_conn_set_sockopt(cli1->conn, sockops);
8057
8058         reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, "\\test",
8059                                   O_CREAT|O_RDWR, 0, &smbreqs[0]);
8060         if (reqs[0] == NULL) return false;
8061         tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
8062
8063
8064         reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
8065                                         (const uint8_t *)str, 0, strlen(str)+1,
8066                                         smbreqs, 1, &smbreqs[1]);
8067         if (reqs[1] == NULL) return false;
8068         tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
8069
8070         reqs[2] = cli_smb1_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
8071         if (reqs[2] == NULL) return false;
8072         tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
8073
8074         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
8075         if (!NT_STATUS_IS_OK(status)) {
8076                 return false;
8077         }
8078
8079         while (!done) {
8080                 tevent_loop_once(evt);
8081         }
8082
8083         torture_close_connection(cli1);
8084         return True;
8085 }
8086
8087 static void chain2_sesssetup_completion(struct tevent_req *req)
8088 {
8089         NTSTATUS status;
8090         status = cli_session_setup_guest_recv(req);
8091         d_printf("sesssetup returned %s\n", nt_errstr(status));
8092 }
8093
8094 static void chain2_tcon_completion(struct tevent_req *req)
8095 {
8096         bool *done = (bool *)tevent_req_callback_data_void(req);
8097         NTSTATUS status;
8098         status = cli_tcon_andx_recv(req);
8099         d_printf("tcon_and_x returned %s\n", nt_errstr(status));
8100         *done = true;
8101 }
8102
8103 static bool run_chain2(int dummy)
8104 {
8105         struct cli_state *cli1;
8106         struct tevent_context *evt = samba_tevent_context_init(NULL);
8107         struct tevent_req *reqs[2], *smbreqs[2];
8108         bool done = false;
8109         NTSTATUS status;
8110         int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
8111
8112         printf("starting chain2 test\n");
8113         status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
8114                                       port_to_use, SMB_SIGNING_DEFAULT, flags);
8115         if (!NT_STATUS_IS_OK(status)) {
8116                 return False;
8117         }
8118
8119         smbXcli_conn_set_sockopt(cli1->conn, sockops);
8120
8121         reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
8122                                                  &smbreqs[0]);
8123         if (reqs[0] == NULL) return false;
8124         tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
8125
8126         reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
8127                                        "?????", NULL, 0, &smbreqs[1]);
8128         if (reqs[1] == NULL) return false;
8129         tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
8130
8131         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
8132         if (!NT_STATUS_IS_OK(status)) {
8133                 return false;
8134         }
8135
8136         while (!done) {
8137                 tevent_loop_once(evt);
8138         }
8139
8140         torture_close_connection(cli1);
8141         return True;
8142 }
8143
8144
8145 struct torture_createdel_state {
8146         struct tevent_context *ev;
8147         struct cli_state *cli;
8148 };
8149
8150 static void torture_createdel_created(struct tevent_req *subreq);
8151 static void torture_createdel_closed(struct tevent_req *subreq);
8152
8153 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
8154                                                  struct tevent_context *ev,
8155                                                  struct cli_state *cli,
8156                                                  const char *name)
8157 {
8158         struct tevent_req *req, *subreq;
8159         struct torture_createdel_state *state;
8160
8161         req = tevent_req_create(mem_ctx, &state,
8162                                 struct torture_createdel_state);
8163         if (req == NULL) {
8164                 return NULL;
8165         }
8166         state->ev = ev;
8167         state->cli = cli;
8168
8169         subreq = cli_ntcreate_send(
8170                 state, ev, cli, name, 0,
8171                 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
8172                 FILE_ATTRIBUTE_NORMAL,
8173                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
8174                 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
8175
8176         if (tevent_req_nomem(subreq, req)) {
8177                 return tevent_req_post(req, ev);
8178         }
8179         tevent_req_set_callback(subreq, torture_createdel_created, req);
8180         return req;
8181 }
8182
8183 static void torture_createdel_created(struct tevent_req *subreq)
8184 {
8185         struct tevent_req *req = tevent_req_callback_data(
8186                 subreq, struct tevent_req);
8187         struct torture_createdel_state *state = tevent_req_data(
8188                 req, struct torture_createdel_state);
8189         NTSTATUS status;
8190         uint16_t fnum;
8191
8192         status = cli_ntcreate_recv(subreq, &fnum, NULL);
8193         TALLOC_FREE(subreq);
8194         if (tevent_req_nterror(req, status)) {
8195                 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
8196                            nt_errstr(status)));
8197                 return;
8198         }
8199
8200         subreq = cli_close_send(state, state->ev, state->cli, fnum);
8201         if (tevent_req_nomem(subreq, req)) {
8202                 return;
8203         }
8204         tevent_req_set_callback(subreq, torture_createdel_closed, req);
8205 }
8206
8207 static void torture_createdel_closed(struct tevent_req *subreq)
8208 {
8209         struct tevent_req *req = tevent_req_callback_data(
8210                 subreq, struct tevent_req);
8211         NTSTATUS status;
8212
8213         status = cli_close_recv(subreq);
8214         if (tevent_req_nterror(req, status)) {
8215                 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
8216                 return;
8217         }
8218         tevent_req_done(req);
8219 }
8220
8221 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
8222 {
8223         return tevent_req_simple_recv_ntstatus(req);
8224 }
8225
8226 struct torture_createdels_state {
8227         struct tevent_context *ev;
8228         struct cli_state *cli;
8229         const char *base_name;
8230         int sent;
8231         int received;
8232         int num_files;
8233         struct tevent_req **reqs;
8234 };
8235
8236 static void torture_createdels_done(struct tevent_req *subreq);
8237
8238 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
8239                                                   struct tevent_context *ev,
8240                                                   struct cli_state *cli,
8241                                                   const char *base_name,
8242                                                   int num_parallel,
8243                                                   int num_files)
8244 {
8245         struct tevent_req *req;
8246         struct torture_createdels_state *state;
8247         int i;
8248
8249         req = tevent_req_create(mem_ctx, &state,
8250                                 struct torture_createdels_state);
8251         if (req == NULL) {
8252                 return NULL;
8253         }
8254         state->ev = ev;
8255         state->cli = cli;
8256         state->base_name = talloc_strdup(state, base_name);
8257         if (tevent_req_nomem(state->base_name, req)) {
8258                 return tevent_req_post(req, ev);
8259         }
8260         state->num_files = MAX(num_parallel, num_files);
8261         state->sent = 0;
8262         state->received = 0;
8263
8264         state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
8265         if (tevent_req_nomem(state->reqs, req)) {
8266                 return tevent_req_post(req, ev);
8267         }
8268
8269         for (i=0; i<num_parallel; i++) {
8270                 char *name;
8271
8272                 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8273                                        state->sent);
8274                 if (tevent_req_nomem(name, req)) {
8275                         return tevent_req_post(req, ev);
8276                 }
8277                 state->reqs[i] = torture_createdel_send(
8278                         state->reqs, state->ev, state->cli, name);
8279                 if (tevent_req_nomem(state->reqs[i], req)) {
8280                         return tevent_req_post(req, ev);
8281                 }
8282                 name = talloc_move(state->reqs[i], &name);
8283                 tevent_req_set_callback(state->reqs[i],
8284                                         torture_createdels_done, req);
8285                 state->sent += 1;
8286         }
8287         return req;
8288 }
8289
8290 static void torture_createdels_done(struct tevent_req *subreq)
8291 {
8292         struct tevent_req *req = tevent_req_callback_data(
8293                 subreq, struct tevent_req);
8294         struct torture_createdels_state *state = tevent_req_data(
8295                 req, struct torture_createdels_state);
8296         size_t num_parallel = talloc_array_length(state->reqs);
8297         NTSTATUS status;
8298         char *name;
8299         int i;
8300
8301         status = torture_createdel_recv(subreq);
8302         if (!NT_STATUS_IS_OK(status)){
8303                 DEBUG(10, ("torture_createdel_recv returned %s\n",
8304                            nt_errstr(status)));
8305                 TALLOC_FREE(subreq);
8306                 tevent_req_nterror(req, status);
8307                 return;
8308         }
8309
8310         for (i=0; i<num_parallel; i++) {
8311                 if (subreq == state->reqs[i]) {
8312                         break;
8313                 }
8314         }
8315         if (i == num_parallel) {
8316                 DEBUG(10, ("received something we did not send\n"));
8317                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
8318                 return;
8319         }
8320         TALLOC_FREE(state->reqs[i]);
8321
8322         if (state->sent >= state->num_files) {
8323                 tevent_req_done(req);
8324                 return;
8325         }
8326
8327         name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8328                                state->sent);
8329         if (tevent_req_nomem(name, req)) {
8330                 return;
8331         }
8332         state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
8333                                                 state->cli, name);
8334         if (tevent_req_nomem(state->reqs[i], req)) {
8335                 return;
8336         }
8337         name = talloc_move(state->reqs[i], &name);
8338         tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
8339         state->sent += 1;
8340 }
8341
8342 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
8343 {
8344         return tevent_req_simple_recv_ntstatus(req);
8345 }
8346
8347 struct swallow_notify_state {
8348         struct tevent_context *ev;
8349         struct cli_state *cli;
8350         uint16_t fnum;
8351         uint32_t completion_filter;
8352         bool recursive;
8353         bool (*fn)(uint32_t action, const char *name, void *priv);
8354         void *priv;
8355 };
8356
8357 static void swallow_notify_done(struct tevent_req *subreq);
8358
8359 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
8360                                               struct tevent_context *ev,
8361                                               struct cli_state *cli,
8362                                               uint16_t fnum,
8363                                               uint32_t completion_filter,
8364                                               bool recursive,
8365                                               bool (*fn)(uint32_t action,
8366                                                          const char *name,
8367                                                          void *priv),
8368                                               void *priv)
8369 {
8370         struct tevent_req *req, *subreq;
8371         struct swallow_notify_state *state;
8372
8373         req = tevent_req_create(mem_ctx, &state,
8374                                 struct swallow_notify_state);
8375         if (req == NULL) {
8376                 return NULL;
8377         }
8378         state->ev = ev;
8379         state->cli = cli;
8380         state->fnum = fnum;
8381         state->completion_filter = completion_filter;
8382         state->recursive = recursive;
8383         state->fn = fn;
8384         state->priv = priv;
8385
8386         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8387                                  0xffff, state->completion_filter,
8388                                  state->recursive);
8389         if (tevent_req_nomem(subreq, req)) {
8390                 return tevent_req_post(req, ev);
8391         }
8392         tevent_req_set_callback(subreq, swallow_notify_done, req);
8393         return req;
8394 }
8395
8396 static void swallow_notify_done(struct tevent_req *subreq)
8397 {
8398         struct tevent_req *req = tevent_req_callback_data(
8399                 subreq, struct tevent_req);
8400         struct swallow_notify_state *state = tevent_req_data(
8401                 req, struct swallow_notify_state);
8402         NTSTATUS status;
8403         uint32_t i, num_changes;
8404         struct notify_change *changes;
8405
8406         status = cli_notify_recv(subreq, state, &num_changes, &changes);
8407         TALLOC_FREE(subreq);
8408         if (!NT_STATUS_IS_OK(status)) {
8409                 DEBUG(10, ("cli_notify_recv returned %s\n",
8410                            nt_errstr(status)));
8411                 tevent_req_nterror(req, status);
8412                 return;
8413         }
8414
8415         for (i=0; i<num_changes; i++) {
8416                 state->fn(changes[i].action, changes[i].name, state->priv);
8417         }
8418         TALLOC_FREE(changes);
8419
8420         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8421                                  0xffff, state->completion_filter,
8422                                  state->recursive);
8423         if (tevent_req_nomem(subreq, req)) {
8424                 return;
8425         }
8426         tevent_req_set_callback(subreq, swallow_notify_done, req);
8427 }
8428
8429 static bool print_notifies(uint32_t action, const char *name, void *priv)
8430 {
8431         if (DEBUGLEVEL > 5) {
8432                 d_printf("%d %s\n", (int)action, name);
8433         }
8434         return true;
8435 }
8436
8437 static void notify_bench_done(struct tevent_req *req)
8438 {
8439         int *num_finished = (int *)tevent_req_callback_data_void(req);
8440         *num_finished += 1;
8441 }
8442
8443 static bool run_notify_bench(int dummy)
8444 {
8445         const char *dname = "\\notify-bench";
8446         struct tevent_context *ev;
8447         NTSTATUS status;
8448         uint16_t dnum;
8449         struct tevent_req *req1;
8450         struct tevent_req *req2 = NULL;
8451         int i, num_unc_names;
8452         int num_finished = 0;
8453
8454         printf("starting notify-bench test\n");
8455
8456         if (use_multishare_conn) {
8457                 char **unc_list;
8458                 unc_list = file_lines_load(multishare_conn_fname,
8459                                            &num_unc_names, 0, NULL);
8460                 if (!unc_list || num_unc_names <= 0) {
8461                         d_printf("Failed to load unc names list from '%s'\n",
8462                                  multishare_conn_fname);
8463                         return false;
8464                 }
8465                 TALLOC_FREE(unc_list);
8466         } else {
8467                 num_unc_names = 1;
8468         }
8469
8470         ev = samba_tevent_context_init(talloc_tos());
8471         if (ev == NULL) {
8472                 d_printf("tevent_context_init failed\n");
8473                 return false;
8474         }
8475
8476         for (i=0; i<num_unc_names; i++) {
8477                 struct cli_state *cli;
8478                 char *base_fname;
8479
8480                 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
8481                                              dname, i);
8482                 if (base_fname == NULL) {
8483                         return false;
8484                 }
8485
8486                 if (!torture_open_connection(&cli, i)) {
8487                         return false;
8488                 }
8489
8490                 status = cli_ntcreate(cli, dname, 0,
8491                                       MAXIMUM_ALLOWED_ACCESS,
8492                                       0, FILE_SHARE_READ|FILE_SHARE_WRITE|
8493                                       FILE_SHARE_DELETE,
8494                                       FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
8495                                       &dnum, NULL);
8496
8497                 if (!NT_STATUS_IS_OK(status)) {
8498                         d_printf("Could not create %s: %s\n", dname,
8499                                  nt_errstr(status));
8500                         return false;
8501                 }
8502
8503                 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
8504                                            FILE_NOTIFY_CHANGE_FILE_NAME |
8505                                            FILE_NOTIFY_CHANGE_DIR_NAME |
8506                                            FILE_NOTIFY_CHANGE_ATTRIBUTES |
8507                                            FILE_NOTIFY_CHANGE_LAST_WRITE,
8508                                            false, print_notifies, NULL);
8509                 if (req1 == NULL) {
8510                         d_printf("Could not create notify request\n");
8511                         return false;
8512                 }
8513
8514                 req2 = torture_createdels_send(talloc_tos(), ev, cli,
8515                                                base_fname, 10, torture_numops);
8516                 if (req2 == NULL) {
8517                         d_printf("Could not create createdels request\n");
8518                         return false;
8519                 }
8520                 TALLOC_FREE(base_fname);
8521
8522                 tevent_req_set_callback(req2, notify_bench_done,
8523                                         &num_finished);
8524         }
8525
8526         while (num_finished < num_unc_names) {
8527                 int ret;
8528                 ret = tevent_loop_once(ev);
8529                 if (ret != 0) {
8530                         d_printf("tevent_loop_once failed\n");
8531                         return false;
8532                 }
8533         }
8534
8535         if (!tevent_req_poll(req2, ev)) {
8536                 d_printf("tevent_req_poll failed\n");
8537         }
8538
8539         status = torture_createdels_recv(req2);
8540         d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
8541
8542         return true;
8543 }
8544
8545 static bool run_mangle1(int dummy)
8546 {
8547         struct cli_state *cli;
8548         const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
8549         uint16_t fnum;
8550         fstring alt_name;
8551         NTSTATUS status;
8552         time_t change_time, access_time, write_time;
8553         off_t size;
8554         uint16_t mode;
8555
8556         printf("starting mangle1 test\n");
8557         if (!torture_open_connection(&cli, 0)) {
8558                 return False;
8559         }
8560
8561         smbXcli_conn_set_sockopt(cli->conn, sockops);
8562
8563         status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8564                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8565                               0, 0, &fnum, NULL);
8566         if (!NT_STATUS_IS_OK(status)) {
8567                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8568                 return false;
8569         }
8570         cli_close(cli, fnum);
8571
8572         status = cli_qpathinfo_alt_name(cli, fname, alt_name);
8573         if (!NT_STATUS_IS_OK(status)) {
8574                 d_printf("cli_qpathinfo_alt_name failed: %s\n",
8575                          nt_errstr(status));
8576                 return false;
8577         }
8578         d_printf("alt_name: %s\n", alt_name);
8579
8580         status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
8581         if (!NT_STATUS_IS_OK(status)) {
8582                 d_printf("cli_openx(%s) failed: %s\n", alt_name,
8583                          nt_errstr(status));
8584                 return false;
8585         }
8586         cli_close(cli, fnum);
8587
8588         status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
8589                                 &write_time, &size, &mode);
8590         if (!NT_STATUS_IS_OK(status)) {
8591                 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
8592                          nt_errstr(status));
8593                 return false;
8594         }
8595
8596         return true;
8597 }
8598
8599 static NTSTATUS mangle_illegal_list_shortname_fn(const char *mntpoint,
8600                                                  struct file_info *f,
8601                                                  const char *mask,
8602                                                  void *state)
8603 {
8604         if (f->short_name == NULL) {
8605                 return NT_STATUS_OK;
8606         }
8607
8608         if (strlen(f->short_name) == 0) {
8609                 return NT_STATUS_OK;
8610         }
8611
8612         printf("unexpected shortname: %s\n", f->short_name);
8613
8614         return NT_STATUS_OBJECT_NAME_INVALID;
8615 }
8616
8617 static NTSTATUS mangle_illegal_list_name_fn(const char *mntpoint,
8618                                             struct file_info *f,
8619                                             const char *mask,
8620                                             void *state)
8621 {
8622         char *name = state;
8623
8624         printf("name: %s\n", f->name);
8625         fstrcpy(name, f->name);
8626         return NT_STATUS_OK;
8627 }
8628
8629 static bool run_mangle_illegal(int dummy)
8630 {
8631         struct cli_state *cli = NULL;
8632         struct cli_state *cli_posix = NULL;
8633         const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
8634         const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar";
8635         char *mangled_path = NULL;
8636         uint16_t fnum;
8637         fstring name;
8638         fstring alt_name;
8639         NTSTATUS status;
8640
8641         printf("starting mangle-illegal test\n");
8642
8643         if (!torture_open_connection(&cli, 0)) {
8644                 return False;
8645         }
8646
8647         smbXcli_conn_set_sockopt(cli->conn, sockops);
8648
8649         if (!torture_open_connection(&cli_posix, 0)) {
8650                 return false;
8651         }
8652
8653         smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
8654
8655         status = torture_setup_unix_extensions(cli_posix);
8656         if (!NT_STATUS_IS_OK(status)) {
8657                 return false;
8658         }
8659
8660         cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8661         status = cli_mkdir(cli, "\\MANGLE_ILLEGAL");
8662         if (!NT_STATUS_IS_OK(status)) {
8663                 printf("mkdir1 failed : %s\n", nt_errstr(status));
8664                 return False;
8665         }
8666
8667         /*
8668          * Create a file with illegal NTFS characters and test that we
8669          * get a usable mangled name
8670          */
8671
8672         cli_setatr(cli_posix, illegal_fname, 0, 0);
8673         cli_posix_unlink(cli_posix, illegal_fname);
8674
8675         status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL,
8676                                 0600, &fnum);
8677         if (!NT_STATUS_IS_OK(status)) {
8678                 printf("POSIX create of %s failed (%s)\n",
8679                        illegal_fname, nt_errstr(status));
8680                 return false;
8681         }
8682
8683         status = cli_close(cli_posix, fnum);
8684         if (!NT_STATUS_IS_OK(status)) {
8685                 printf("close failed (%s)\n", nt_errstr(status));
8686                 return false;
8687         }
8688
8689         status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name);
8690         if (!NT_STATUS_IS_OK(status)) {
8691                 d_printf("cli_list failed: %s\n", nt_errstr(status));
8692                 return false;
8693         }
8694
8695         mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name);
8696         if (mangled_path == NULL) {
8697                 return false;
8698         }
8699
8700         status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum);
8701         if (!NT_STATUS_IS_OK(status)) {
8702                 d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status));
8703                 TALLOC_FREE(mangled_path);
8704                 return false;
8705         }
8706         TALLOC_FREE(mangled_path);
8707         cli_close(cli, fnum);
8708
8709         cli_setatr(cli_posix, illegal_fname, 0, 0);
8710         cli_posix_unlink(cli_posix, illegal_fname);
8711
8712         /*
8713          * Create a file with a long name and check that we got *no* short name.
8714          */
8715
8716         status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8717                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8718                               0, 0, &fnum, NULL);
8719         if (!NT_STATUS_IS_OK(status)) {
8720                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8721                 return false;
8722         }
8723         cli_close(cli, fnum);
8724
8725         status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name);
8726         if (!NT_STATUS_IS_OK(status)) {
8727                 d_printf("cli_list failed\n");
8728                 return false;
8729         }
8730
8731         cli_unlink(cli, fname, 0);
8732         cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8733
8734         if (!torture_close_connection(cli_posix)) {
8735                 return false;
8736         }
8737
8738         if (!torture_close_connection(cli)) {
8739                 return false;
8740         }
8741
8742         return true;
8743 }
8744
8745 static size_t null_source(uint8_t *buf, size_t n, void *priv)
8746 {
8747         size_t *to_pull = (size_t *)priv;
8748         size_t thistime = *to_pull;
8749
8750         thistime = MIN(thistime, n);
8751         if (thistime == 0) {
8752                 return 0;
8753         }
8754
8755         memset(buf, 0, thistime);
8756         *to_pull -= thistime;
8757         return thistime;
8758 }
8759
8760 static bool run_windows_write(int dummy)
8761 {
8762         struct cli_state *cli1;
8763         uint16_t fnum;
8764         int i;
8765         bool ret = false;
8766         const char *fname = "\\writetest.txt";
8767         struct timeval start_time;
8768         double seconds;
8769         double kbytes;
8770         NTSTATUS status;
8771
8772         printf("starting windows_write test\n");
8773         if (!torture_open_connection(&cli1, 0)) {
8774                 return False;
8775         }
8776
8777         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
8778         if (!NT_STATUS_IS_OK(status)) {
8779                 printf("open failed (%s)\n", nt_errstr(status));
8780                 return False;
8781         }
8782
8783         smbXcli_conn_set_sockopt(cli1->conn, sockops);
8784
8785         start_time = timeval_current();
8786
8787         for (i=0; i<torture_numops; i++) {
8788                 uint8_t c = 0;
8789                 off_t start = i * torture_blocksize;
8790                 size_t to_pull = torture_blocksize - 1;
8791
8792                 status = cli_writeall(cli1, fnum, 0, &c,
8793                                       start + torture_blocksize - 1, 1, NULL);
8794                 if (!NT_STATUS_IS_OK(status)) {
8795                         printf("cli_write failed: %s\n", nt_errstr(status));
8796                         goto fail;
8797                 }
8798
8799                 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
8800                                   null_source, &to_pull);
8801                 if (!NT_STATUS_IS_OK(status)) {
8802                         printf("cli_push returned: %s\n", nt_errstr(status));
8803                         goto fail;
8804                 }
8805         }
8806
8807         seconds = timeval_elapsed(&start_time);
8808         kbytes = (double)torture_blocksize * torture_numops;
8809         kbytes /= 1024;
8810
8811         printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
8812                (double)seconds, (int)(kbytes/seconds));
8813
8814         ret = true;
8815  fail:
8816         cli_close(cli1, fnum);
8817         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8818         torture_close_connection(cli1);
8819         return ret;
8820 }
8821
8822 static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
8823 {
8824         size_t max_pdu = 0x1FFFF;
8825
8826         if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
8827                 max_pdu = 0xFFFFFF;
8828         }
8829
8830         if (smb1cli_conn_signing_is_active(cli->conn)) {
8831                 max_pdu = 0x1FFFF;
8832         }
8833
8834         if (smb1cli_conn_encryption_on(cli->conn)) {
8835                 max_pdu = CLI_BUFFER_SIZE;
8836         }
8837
8838         if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
8839                 len_requested &= 0xFFFF;
8840         }
8841
8842         return MIN(len_requested,
8843                    max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
8844 }
8845
8846 static bool check_read_call(struct cli_state *cli,
8847                             uint16_t fnum,
8848                             uint8_t *buf,
8849                             size_t len_requested)
8850 {
8851         NTSTATUS status;
8852         struct tevent_req *subreq = NULL;
8853         ssize_t len_read = 0;
8854         size_t len_expected = 0;
8855         struct tevent_context *ev = NULL;
8856
8857         ev = samba_tevent_context_init(talloc_tos());
8858         if (ev == NULL) {
8859                 return false;
8860         }
8861
8862         subreq = cli_read_andx_send(talloc_tos(),
8863                                     ev,
8864                                     cli,
8865                                     fnum,
8866                                     0,
8867                                     len_requested);
8868
8869         if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
8870                 return false;
8871         }
8872
8873         status = cli_read_andx_recv(subreq, &len_read, &buf);
8874         if (!NT_STATUS_IS_OK(status)) {
8875                 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
8876                 return false;
8877         }
8878
8879         TALLOC_FREE(subreq);
8880         TALLOC_FREE(ev);
8881
8882         len_expected = calc_expected_return(cli, len_requested);
8883
8884         if (len_expected > 0x10000 && len_read == 0x10000) {
8885                 /* Windows servers only return a max of 0x10000,
8886                    doesn't matter if you set CAP_LARGE_READX in
8887                    the client sessionsetupX call or not. */
8888                 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
8889                         (unsigned int)len_requested);
8890         } else if (len_read != len_expected) {
8891                 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
8892                         (unsigned int)len_requested,
8893                         (unsigned int)len_read,
8894                         (unsigned int)len_expected);
8895                 return false;
8896         } else {
8897                 d_printf("Correct read reply.\n");
8898         }
8899
8900         return true;
8901 }
8902
8903 /* Test large readX variants. */
8904 static bool large_readx_tests(struct cli_state *cli,
8905                                 uint16_t fnum,
8906                                 uint8_t *buf)
8907 {
8908         /* A read of 0xFFFF0001 should *always* return 1 byte. */
8909         if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
8910                 return false;
8911         }
8912         /* A read of 0x10000 should return 0x10000 bytes. */
8913         if (check_read_call(cli, fnum, buf,    0x10000) == false) {
8914                 return false;
8915         }
8916         /* A read of 0x10000 should return 0x10001 bytes. */
8917         if (check_read_call(cli, fnum, buf,    0x10001) == false) {
8918                 return false;
8919         }
8920         /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
8921            the requested number of bytes. */
8922         if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
8923                 return false;
8924         }
8925         /* A read of 1MB should return 1MB bytes (on Samba). */
8926         if (check_read_call(cli, fnum, buf,   0x100000) == false) {
8927                 return false;
8928         }
8929
8930         if (check_read_call(cli, fnum, buf,    0x20001) == false) {
8931                 return false;
8932         }
8933         if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
8934                 return false;
8935         }
8936         if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
8937                 return false;
8938         }
8939         return true;
8940 }
8941
8942 static bool run_large_readx(int dummy)
8943 {
8944         uint8_t *buf = NULL;
8945         struct cli_state *cli1 = NULL;
8946         struct cli_state *cli2 = NULL;
8947         bool correct = false;
8948         const char *fname = "\\large_readx.dat";
8949         NTSTATUS status;
8950         uint16_t fnum1 = UINT16_MAX;
8951         uint32_t normal_caps = 0;
8952         size_t file_size = 20*1024*1024;
8953         TALLOC_CTX *frame = talloc_stackframe();
8954         size_t i;
8955         struct {
8956                 const char *name;
8957                 enum smb_signing_setting signing_setting;
8958                 enum protocol_types protocol;
8959         } runs[] = {
8960                 {
8961                         .name = "NT1",
8962                         .signing_setting = SMB_SIGNING_IF_REQUIRED,
8963                         .protocol = PROTOCOL_NT1,
8964                 },{
8965                         .name = "NT1 - SIGNING_REQUIRED",
8966                         .signing_setting = SMB_SIGNING_REQUIRED,
8967                         .protocol = PROTOCOL_NT1,
8968                 },
8969         };
8970
8971         printf("starting large_readx test\n");
8972
8973         if (!torture_open_connection(&cli1, 0)) {
8974                 goto out;
8975         }
8976
8977         normal_caps = smb1cli_conn_capabilities(cli1->conn);
8978
8979         if (!(normal_caps & CAP_LARGE_READX)) {
8980                 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
8981                         (unsigned int)normal_caps);
8982                 goto out;
8983         }
8984
8985         /* Create a file of size 4MB. */
8986         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
8987                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8988                         0, 0, &fnum1, NULL);
8989
8990         if (!NT_STATUS_IS_OK(status)) {
8991                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8992                 goto out;
8993         }
8994
8995         /* Write file_size bytes. */
8996         buf = talloc_zero_array(frame, uint8_t, file_size);
8997         if (buf == NULL) {
8998                 goto out;
8999         }
9000
9001         status = cli_writeall(cli1,
9002                               fnum1,
9003                               0,
9004                               buf,
9005                               0,
9006                               file_size,
9007                               NULL);
9008         if (!NT_STATUS_IS_OK(status)) {
9009                 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
9010                 goto out;
9011         }
9012
9013         status = cli_close(cli1, fnum1);
9014         if (!NT_STATUS_IS_OK(status)) {
9015                 d_printf("cli_close failed: %s\n", nt_errstr(status));
9016                 goto out;
9017         }
9018
9019         fnum1 = UINT16_MAX;
9020
9021         for (i=0; i < ARRAY_SIZE(runs); i++) {
9022                 enum smb_signing_setting saved_signing_setting = signing_state;
9023                 uint16_t fnum2 = -1;
9024
9025                 if (do_encrypt &&
9026                     (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
9027                 {
9028                         d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
9029                         continue;
9030                 }
9031
9032                 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
9033
9034                 signing_state = runs[i].signing_setting;
9035                 cli2 = open_nbt_connection();
9036                 signing_state = saved_signing_setting;
9037                 if (cli2 == NULL) {
9038                         goto out;
9039                 }
9040
9041                 status = smbXcli_negprot(cli2->conn,
9042                                          cli2->timeout,
9043                                          runs[i].protocol,
9044                                          runs[i].protocol);
9045                 if (!NT_STATUS_IS_OK(status)) {
9046                         goto out;
9047                 }
9048
9049                 status = cli_session_setup_creds(cli2, torture_creds);
9050                 if (!NT_STATUS_IS_OK(status)) {
9051                         goto out;
9052                 }
9053
9054                 status = cli_tree_connect(cli2,
9055                                         share,
9056                                         "?????",
9057                                         password);
9058                 if (!NT_STATUS_IS_OK(status)) {
9059                         goto out;
9060                 }
9061
9062                 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
9063
9064                 normal_caps = smb1cli_conn_capabilities(cli2->conn);
9065
9066                 if (!(normal_caps & CAP_LARGE_READX)) {
9067                         d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
9068                                 (unsigned int)normal_caps);
9069                         goto out;
9070                 }
9071
9072                 if (do_encrypt) {
9073                         if (force_cli_encryption(cli2, share) == false) {
9074                                 goto out;
9075                         }
9076                 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
9077                         uint16_t major, minor;
9078                         uint32_t caplow, caphigh;
9079
9080                         status = cli_unix_extensions_version(cli2,
9081                                                              &major, &minor,
9082                                                              &caplow, &caphigh);
9083                         if (!NT_STATUS_IS_OK(status)) {
9084                                 goto out;
9085                         }
9086                 }
9087
9088                 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
9089                                 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
9090                                 0, 0, &fnum2, NULL);
9091                 if (!NT_STATUS_IS_OK(status)) {
9092                         d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
9093                         goto out;
9094                 }
9095
9096                 /* All reads must return less than file_size bytes. */
9097                 if (!large_readx_tests(cli2, fnum2, buf)) {
9098                         goto out;
9099                 }
9100
9101                 status = cli_close(cli2, fnum2);
9102                 if (!NT_STATUS_IS_OK(status)) {
9103                         d_printf("cli_close failed: %s\n", nt_errstr(status));
9104                         goto out;
9105                 }
9106                 fnum2 = -1;
9107
9108                 if (!torture_close_connection(cli2)) {
9109                         goto out;
9110                 }
9111                 cli2 = NULL;
9112         }
9113
9114         correct = true;
9115         printf("Success on large_readx test\n");
9116
9117   out:
9118
9119         if (cli2) {
9120                 if (!torture_close_connection(cli2)) {
9121                         correct = false;
9122                 }
9123         }
9124
9125         if (cli1) {
9126                 if (fnum1 != UINT16_MAX) {
9127                         status = cli_close(cli1, fnum1);
9128                         if (!NT_STATUS_IS_OK(status)) {
9129                                 d_printf("cli_close failed: %s\n", nt_errstr(status));
9130                         }
9131                         fnum1 = UINT16_MAX;
9132                 }
9133
9134                 status = cli_unlink(cli1, fname,
9135                                     FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9136                 if (!NT_STATUS_IS_OK(status)) {
9137                         printf("unlink failed (%s)\n", nt_errstr(status));
9138                 }
9139
9140                 if (!torture_close_connection(cli1)) {
9141                         correct = false;
9142                 }
9143         }
9144
9145         TALLOC_FREE(frame);
9146
9147         printf("finished large_readx test\n");
9148         return correct;
9149 }
9150
9151 static bool run_cli_echo(int dummy)
9152 {
9153         struct cli_state *cli;
9154         NTSTATUS status;
9155
9156         printf("starting cli_echo test\n");
9157         if (!torture_open_connection(&cli, 0)) {
9158                 return false;
9159         }
9160         smbXcli_conn_set_sockopt(cli->conn, sockops);
9161
9162         status = cli_echo(cli, 5, data_blob_const("hello", 5));
9163
9164         d_printf("cli_echo returned %s\n", nt_errstr(status));
9165
9166         torture_close_connection(cli);
9167         return NT_STATUS_IS_OK(status);
9168 }
9169
9170 static bool run_uid_regression_test(int dummy)
9171 {
9172         static struct cli_state *cli;
9173         int16_t old_vuid;
9174         int32_t old_cnum;
9175         bool correct = True;
9176         struct smbXcli_tcon *orig_tcon = NULL;
9177         NTSTATUS status;
9178
9179         printf("starting uid regression test\n");
9180
9181         if (!torture_open_connection(&cli, 0)) {
9182                 return False;
9183         }
9184
9185         smbXcli_conn_set_sockopt(cli->conn, sockops);
9186
9187         /* Ok - now save then logoff our current user. */
9188         old_vuid = cli_state_get_uid(cli);
9189
9190         status = cli_ulogoff(cli);
9191         if (!NT_STATUS_IS_OK(status)) {
9192                 d_printf("(%s) cli_ulogoff failed: %s\n",
9193                          __location__, nt_errstr(status));
9194                 correct = false;
9195                 goto out;
9196         }
9197
9198         cli_state_set_uid(cli, old_vuid);
9199
9200         /* Try an operation. */
9201         status = cli_mkdir(cli, "\\uid_reg_test");
9202         if (NT_STATUS_IS_OK(status)) {
9203                 d_printf("(%s) cli_mkdir succeeded\n",
9204                          __location__);
9205                 correct = false;
9206                 goto out;
9207         } else {
9208                 /* Should be bad uid. */
9209                 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
9210                                  NT_STATUS_USER_SESSION_DELETED)) {
9211                         correct = false;
9212                         goto out;
9213                 }
9214         }
9215
9216         old_cnum = cli_state_get_tid(cli);
9217         orig_tcon = cli_state_save_tcon(cli);
9218         if (orig_tcon == NULL) {
9219                 correct = false;
9220                 goto out;
9221         }
9222
9223         /* Now try a SMBtdis with the invald vuid set to zero. */
9224         cli_state_set_uid(cli, 0);
9225
9226         /* This should succeed. */
9227         status = cli_tdis(cli);
9228
9229         if (NT_STATUS_IS_OK(status)) {
9230                 d_printf("First tdis with invalid vuid should succeed.\n");
9231         } else {
9232                 d_printf("First tdis failed (%s)\n", nt_errstr(status));
9233                 correct = false;
9234                 cli_state_restore_tcon(cli, orig_tcon);
9235                 goto out;
9236         }
9237
9238         cli_state_restore_tcon(cli, orig_tcon);
9239         cli_state_set_uid(cli, old_vuid);
9240         cli_state_set_tid(cli, old_cnum);
9241
9242         /* This should fail. */
9243         status = cli_tdis(cli);
9244         if (NT_STATUS_IS_OK(status)) {
9245                 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
9246                 correct = false;
9247                 goto out;
9248         } else {
9249                 /* Should be bad tid. */
9250                 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
9251                                 NT_STATUS_NETWORK_NAME_DELETED)) {
9252                         correct = false;
9253                         goto out;
9254                 }
9255         }
9256
9257         cli_rmdir(cli, "\\uid_reg_test");
9258
9259   out:
9260
9261         cli_shutdown(cli);
9262         return correct;
9263 }
9264
9265
9266 static const char *illegal_chars = "*\\/?<>|\":";
9267 static char force_shortname_chars[] = " +,.[];=\177";
9268
9269 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
9270                              const char *mask, void *state)
9271 {
9272         struct cli_state *pcli = (struct cli_state *)state;
9273         fstring fname;
9274         NTSTATUS status = NT_STATUS_OK;
9275
9276         slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
9277
9278         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
9279                 return NT_STATUS_OK;
9280
9281         if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
9282                 status = cli_rmdir(pcli, fname);
9283                 if (!NT_STATUS_IS_OK(status)) {
9284                         printf("del_fn: failed to rmdir %s\n,", fname );
9285                 }
9286         } else {
9287                 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9288                 if (!NT_STATUS_IS_OK(status)) {
9289                         printf("del_fn: failed to unlink %s\n,", fname );
9290                 }
9291         }
9292         return status;
9293 }
9294
9295 struct sn_state {
9296         int matched;
9297         int i;
9298         bool val;
9299 };
9300
9301 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
9302                               const char *name, void *state)
9303 {
9304         struct sn_state *s = (struct sn_state  *)state;
9305         int i = s->i;
9306
9307 #if 0
9308         printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
9309                 i, finfo->name, finfo->short_name);
9310 #endif
9311
9312         if (strchr(force_shortname_chars, i)) {
9313                 if (!finfo->short_name) {
9314                         /* Shortname not created when it should be. */
9315                         d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
9316                                 __location__, finfo->name, i);
9317                         s->val = true;
9318                 }
9319         } else if (finfo->short_name){
9320                 /* Shortname created when it should not be. */
9321                 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
9322                         __location__, finfo->short_name, finfo->name);
9323                 s->val = true;
9324         }
9325         s->matched += 1;
9326         return NT_STATUS_OK;
9327 }
9328
9329 static bool run_shortname_test(int dummy)
9330 {
9331         static struct cli_state *cli;
9332         bool correct = True;
9333         int i;
9334         struct sn_state s;
9335         char fname[40];
9336         NTSTATUS status;
9337
9338         printf("starting shortname test\n");
9339
9340         if (!torture_open_connection(&cli, 0)) {
9341                 return False;
9342         }
9343
9344         smbXcli_conn_set_sockopt(cli->conn, sockops);
9345
9346         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9347         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9348         cli_rmdir(cli, "\\shortname");
9349
9350         status = cli_mkdir(cli, "\\shortname");
9351         if (!NT_STATUS_IS_OK(status)) {
9352                 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
9353                         __location__, nt_errstr(status));
9354                 correct = false;
9355                 goto out;
9356         }
9357
9358         if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
9359                 correct = false;
9360                 goto out;
9361         }
9362         if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
9363                 correct = false;
9364                 goto out;
9365         }
9366
9367         s.val = false;
9368
9369         for (i = 32; i < 128; i++) {
9370                 uint16_t fnum = (uint16_t)-1;
9371
9372                 s.i = i;
9373
9374                 if (strchr(illegal_chars, i)) {
9375                         continue;
9376                 }
9377                 fname[15] = i;
9378
9379                 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
9380                                    FILE_SHARE_READ|FILE_SHARE_WRITE,
9381                                    FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
9382                 if (!NT_STATUS_IS_OK(status)) {
9383                         d_printf("(%s) cli_nt_create of %s failed: %s\n",
9384                                 __location__, fname, nt_errstr(status));
9385                         correct = false;
9386                         goto out;
9387                 }
9388                 cli_close(cli, fnum);
9389
9390                 s.matched = 0;
9391                 status = cli_list(cli, "\\shortname\\test*.*", 0,
9392                                   shortname_list_fn, &s);
9393                 if (s.matched != 1) {
9394                         d_printf("(%s) failed to list %s: %s\n",
9395                                 __location__, fname, nt_errstr(status));
9396                         correct = false;
9397                         goto out;
9398                 }
9399
9400                 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9401                 if (!NT_STATUS_IS_OK(status)) {
9402                         d_printf("(%s) failed to delete %s: %s\n",
9403                                 __location__, fname, nt_errstr(status));
9404                         correct = false;
9405                         goto out;
9406                 }
9407
9408                 if (s.val) {
9409                         correct = false;
9410                         goto out;
9411                 }
9412         }
9413
9414   out:
9415
9416         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9417         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9418         cli_rmdir(cli, "\\shortname");
9419         torture_close_connection(cli);
9420         return correct;
9421 }
9422
9423 static void pagedsearch_cb(struct tevent_req *req)
9424 {
9425         TLDAPRC rc;
9426         struct tldap_message *msg;
9427         char *dn;
9428
9429         rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
9430         if (!TLDAP_RC_IS_SUCCESS(rc)) {
9431                 d_printf("tldap_search_paged_recv failed: %s\n",
9432                          tldap_rc2string(rc));
9433                 return;
9434         }
9435         if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
9436                 TALLOC_FREE(msg);
9437                 return;
9438         }
9439         if (!tldap_entry_dn(msg, &dn)) {
9440                 d_printf("tldap_entry_dn failed\n");
9441                 return;
9442         }
9443         d_printf("%s\n", dn);
9444         TALLOC_FREE(msg);
9445 }
9446
9447 static bool run_tldap(int dummy)
9448 {
9449         struct tldap_context *ld;
9450         int fd;
9451         TLDAPRC rc;
9452         NTSTATUS status;
9453         struct sockaddr_storage addr;
9454         struct tevent_context *ev;
9455         struct tevent_req *req;
9456         char *basedn;
9457         const char *filter;
9458
9459         if (!resolve_name(host, &addr, 0, false)) {
9460                 d_printf("could not find host %s\n", host);
9461                 return false;
9462         }
9463         status = open_socket_out(&addr, 389, 9999, &fd);
9464         if (!NT_STATUS_IS_OK(status)) {
9465                 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
9466                 return false;
9467         }
9468
9469         ld = tldap_context_create(talloc_tos(), fd);
9470         if (ld == NULL) {
9471                 close(fd);
9472                 d_printf("tldap_context_create failed\n");
9473                 return false;
9474         }
9475
9476         rc = tldap_fetch_rootdse(ld);
9477         if (!TLDAP_RC_IS_SUCCESS(rc)) {
9478                 d_printf("tldap_fetch_rootdse failed: %s\n",
9479                          tldap_errstr(talloc_tos(), ld, rc));
9480                 return false;
9481         }
9482
9483         basedn = tldap_talloc_single_attribute(
9484                 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
9485         if (basedn == NULL) {
9486                 d_printf("no defaultNamingContext\n");
9487                 return false;
9488         }
9489         d_printf("defaultNamingContext: %s\n", basedn);
9490
9491         ev = samba_tevent_context_init(talloc_tos());
9492         if (ev == NULL) {
9493                 d_printf("tevent_context_init failed\n");
9494                 return false;
9495         }
9496
9497         req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
9498                                       TLDAP_SCOPE_SUB, "(objectclass=*)",
9499                                       NULL, 0, 0,
9500                                       NULL, 0, NULL, 0, 0, 0, 0, 5);
9501         if (req == NULL) {
9502                 d_printf("tldap_search_paged_send failed\n");
9503                 return false;
9504         }
9505         tevent_req_set_callback(req, pagedsearch_cb, NULL);
9506
9507         tevent_req_poll(req, ev);
9508
9509         TALLOC_FREE(req);
9510
9511         /* test search filters against rootDSE */
9512         filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
9513                    "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
9514
9515         rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
9516                           NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
9517                           talloc_tos(), NULL);
9518         if (!TLDAP_RC_IS_SUCCESS(rc)) {
9519                 d_printf("tldap_search with complex filter failed: %s\n",
9520                          tldap_errstr(talloc_tos(), ld, rc));
9521                 return false;
9522         }
9523
9524         TALLOC_FREE(ld);
9525         return true;
9526 }
9527
9528 /* Torture test to ensure no regression of :
9529 https://bugzilla.samba.org/show_bug.cgi?id=7084
9530 */
9531
9532 static bool run_dir_createtime(int dummy)
9533 {
9534         struct cli_state *cli;
9535         const char *dname = "\\testdir";
9536         const char *fname = "\\testdir\\testfile";
9537         NTSTATUS status;
9538         struct timespec create_time;
9539         struct timespec create_time1;
9540         uint16_t fnum;
9541         bool ret = false;
9542
9543         if (!torture_open_connection(&cli, 0)) {
9544                 return false;
9545         }
9546
9547         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9548         cli_rmdir(cli, dname);
9549
9550         status = cli_mkdir(cli, dname);
9551         if (!NT_STATUS_IS_OK(status)) {
9552                 printf("mkdir failed: %s\n", nt_errstr(status));
9553                 goto out;
9554         }
9555
9556         status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
9557                                 NULL, NULL, NULL);
9558         if (!NT_STATUS_IS_OK(status)) {
9559                 printf("cli_qpathinfo2 returned %s\n",
9560                        nt_errstr(status));
9561                 goto out;
9562         }
9563
9564         /* Sleep 3 seconds, then create a file. */
9565         sleep(3);
9566
9567         status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
9568                          DENY_NONE, &fnum);
9569         if (!NT_STATUS_IS_OK(status)) {
9570                 printf("cli_openx failed: %s\n", nt_errstr(status));
9571                 goto out;
9572         }
9573
9574         status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
9575                                 NULL, NULL, NULL);
9576         if (!NT_STATUS_IS_OK(status)) {
9577                 printf("cli_qpathinfo2 (2) returned %s\n",
9578                        nt_errstr(status));
9579                 goto out;
9580         }
9581
9582         if (timespec_compare(&create_time1, &create_time)) {
9583                 printf("run_dir_createtime: create time was updated (error)\n");
9584         } else {
9585                 printf("run_dir_createtime: create time was not updated (correct)\n");
9586                 ret = true;
9587         }
9588
9589   out:
9590
9591         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9592         cli_rmdir(cli, dname);
9593         if (!torture_close_connection(cli)) {
9594                 ret = false;
9595         }
9596         return ret;
9597 }
9598
9599
9600 static bool run_streamerror(int dummy)
9601 {
9602         struct cli_state *cli;
9603         const char *dname = "\\testdir";
9604         const char *streamname =
9605                 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
9606         NTSTATUS status;
9607         time_t change_time, access_time, write_time;
9608         off_t size;
9609         uint16_t mode, fnum;
9610         bool ret = true;
9611
9612         if (!torture_open_connection(&cli, 0)) {
9613                 return false;
9614         }
9615
9616         cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9617         cli_rmdir(cli, dname);
9618
9619         status = cli_mkdir(cli, dname);
9620         if (!NT_STATUS_IS_OK(status)) {
9621                 printf("mkdir failed: %s\n", nt_errstr(status));
9622                 return false;
9623         }
9624
9625         status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
9626                                 &write_time, &size, &mode);
9627         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9628                 printf("pathinfo returned %s, expected "
9629                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9630                        nt_errstr(status));
9631                 ret = false;
9632         }
9633
9634         status = cli_ntcreate(cli, streamname, 0x16,
9635                               FILE_READ_DATA|FILE_READ_EA|
9636                               FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
9637                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
9638                               FILE_OPEN, 0, 0, &fnum, NULL);
9639
9640         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9641                 printf("ntcreate returned %s, expected "
9642                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9643                        nt_errstr(status));
9644                 ret = false;
9645         }
9646
9647
9648         cli_rmdir(cli, dname);
9649         return ret;
9650 }
9651
9652 struct pidtest_state {
9653         bool success;
9654         uint16_t vwv[1];
9655         DATA_BLOB data;
9656 };
9657
9658 static void pid_echo_done(struct tevent_req *subreq);
9659
9660 static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
9661                         struct tevent_context *ev,
9662                         struct cli_state *cli)
9663 {
9664         struct tevent_req *req, *subreq;
9665         struct pidtest_state *state;
9666
9667         req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
9668         if (req == NULL) {
9669                 return NULL;
9670         }
9671
9672         SSVAL(state->vwv, 0, 1);
9673         state->data = data_blob_const("hello", 5);
9674
9675         subreq = smb1cli_req_send(state,
9676                                 ev,
9677                                 cli->conn,
9678                                 SMBecho,
9679                                 0, 0, /* *_flags */
9680                                 0, 0, /* *_flags2 */
9681                                 cli->timeout,
9682                                 0xDEADBEEF, /* pid */
9683                                 NULL, /* tcon */
9684                                 NULL, /* session */
9685                                 ARRAY_SIZE(state->vwv), state->vwv,
9686                                 state->data.length, state->data.data);
9687
9688         if (tevent_req_nomem(subreq, req)) {
9689                 return tevent_req_post(req, ev);
9690         }
9691         tevent_req_set_callback(subreq, pid_echo_done, req);
9692         return req;
9693 }
9694
9695 static void pid_echo_done(struct tevent_req *subreq)
9696 {
9697         struct tevent_req *req = tevent_req_callback_data(
9698                 subreq, struct tevent_req);
9699         struct pidtest_state *state = tevent_req_data(
9700                 req, struct pidtest_state);
9701         NTSTATUS status;
9702         uint32_t num_bytes;
9703         uint8_t *bytes = NULL;
9704         struct iovec *recv_iov = NULL;
9705         uint8_t *phdr = NULL;
9706         uint16_t pidlow = 0;
9707         uint16_t pidhigh = 0;
9708         struct smb1cli_req_expected_response expected[] = {
9709         {
9710                 .status = NT_STATUS_OK,
9711                 .wct    = 1,
9712         },
9713         };
9714
9715         status = smb1cli_req_recv(subreq, state,
9716                                 &recv_iov,
9717                                 &phdr,
9718                                 NULL, /* pwct */
9719                                 NULL, /* pvwv */
9720                                 NULL, /* pvwv_offset */
9721                                 &num_bytes,
9722                                 &bytes,
9723                                 NULL, /* pbytes_offset */
9724                                 NULL, /* pinbuf */
9725                                 expected, ARRAY_SIZE(expected));
9726
9727         TALLOC_FREE(subreq);
9728
9729         if (!NT_STATUS_IS_OK(status)) {
9730                 tevent_req_nterror(req, status);
9731                 return;
9732         }
9733
9734         if (num_bytes != state->data.length) {
9735                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9736                 return;
9737         }
9738
9739         if (memcmp(bytes, state->data.data, num_bytes) != 0) {
9740                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9741                 return;
9742         }
9743
9744         /* Check pid low/high == DEADBEEF */
9745         pidlow = SVAL(phdr, HDR_PID);
9746         if (pidlow != 0xBEEF){
9747                 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
9748                         (unsigned int)pidlow);
9749                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9750                 return;
9751         }
9752         pidhigh = SVAL(phdr, HDR_PIDHIGH);
9753         if (pidhigh != 0xDEAD){
9754                 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
9755                         (unsigned int)pidhigh);
9756                 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9757                 return;
9758         }
9759
9760         tevent_req_done(req);
9761 }
9762
9763 static NTSTATUS pid_echo_recv(struct tevent_req *req)
9764 {
9765         return tevent_req_simple_recv_ntstatus(req);
9766 }
9767
9768 static bool run_pidhigh(int dummy)
9769 {
9770         bool success = false;
9771         struct cli_state *cli = NULL;
9772         NTSTATUS status;
9773         struct tevent_context *ev = NULL;
9774         struct tevent_req *req = NULL;
9775         TALLOC_CTX *frame = talloc_stackframe();
9776
9777         printf("starting pid high test\n");
9778         if (!torture_open_connection(&cli, 0)) {
9779                 return false;
9780         }
9781         smbXcli_conn_set_sockopt(cli->conn, sockops);
9782
9783         ev = samba_tevent_context_init(frame);
9784         if (ev == NULL) {
9785                 goto fail;
9786         }
9787
9788         req = pid_echo_send(frame, ev, cli);
9789         if (req == NULL) {
9790                 goto fail;
9791         }
9792
9793         if (!tevent_req_poll_ntstatus(req, ev, &status)) {
9794                 goto fail;
9795         }
9796
9797         status = pid_echo_recv(req);
9798         if (NT_STATUS_IS_OK(status)) {
9799                 printf("pid high test ok\n");
9800                 success = true;
9801         }
9802
9803  fail:
9804
9805         TALLOC_FREE(frame);
9806         torture_close_connection(cli);
9807         return success;
9808 }
9809
9810 /*
9811   Test Windows open on a bad POSIX symlink.
9812  */
9813 static bool run_symlink_open_test(int dummy)
9814 {
9815         static struct cli_state *cli;
9816         const char *fname = "non_existant_file";
9817         const char *sname = "dangling_symlink";
9818         uint16_t fnum = (uint16_t)-1;
9819         bool correct = false;
9820         NTSTATUS status;
9821         TALLOC_CTX *frame = NULL;
9822
9823         frame = talloc_stackframe();
9824
9825         printf("Starting Windows bad symlink open test\n");
9826
9827         if (!torture_open_connection(&cli, 0)) {
9828                 TALLOC_FREE(frame);
9829                 return false;
9830         }
9831
9832         smbXcli_conn_set_sockopt(cli->conn, sockops);
9833
9834         status = torture_setup_unix_extensions(cli);
9835         if (!NT_STATUS_IS_OK(status)) {
9836                 TALLOC_FREE(frame);
9837                 return false;
9838         }
9839
9840         /* Ensure nothing exists. */
9841         cli_setatr(cli, fname, 0, 0);
9842         cli_posix_unlink(cli, fname);
9843         cli_setatr(cli, sname, 0, 0);
9844         cli_posix_unlink(cli, sname);
9845
9846         /* Create a symlink pointing nowhere. */
9847         status = cli_posix_symlink(cli, fname, sname);
9848         if (!NT_STATUS_IS_OK(status)) {
9849                 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
9850                         sname,
9851                         fname,
9852                         nt_errstr(status));
9853                 goto out;
9854         }
9855
9856         /* Now ensure that a Windows open doesn't hang. */
9857         status = cli_ntcreate(cli,
9858                         sname,
9859                         0,
9860                         FILE_READ_DATA|FILE_WRITE_DATA,
9861                         0,
9862                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
9863                         FILE_OPEN_IF,
9864                         0x0,
9865                         0x0,
9866                         &fnum,
9867                         NULL);
9868
9869         /*
9870          * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
9871          * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
9872          * we use O_NOFOLLOW on the server or not.
9873          */
9874         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
9875             NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
9876         {
9877                 correct = true;
9878         } else {
9879                 printf("cli_ntcreate of %s returned %s - should return"
9880                                 " either (%s) or (%s)\n",
9881                         sname,
9882                         nt_errstr(status),
9883                         nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
9884                         nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
9885                 goto out;
9886         }
9887
9888         correct = true;
9889
9890   out:
9891
9892         if (fnum != (uint16_t)-1) {
9893                 cli_close(cli, fnum);
9894                 fnum = (uint16_t)-1;
9895         }
9896
9897         cli_setatr(cli, sname, 0, 0);
9898         cli_posix_unlink(cli, sname);
9899         cli_setatr(cli, fname, 0, 0);
9900         cli_posix_unlink(cli, fname);
9901
9902         if (!torture_close_connection(cli)) {
9903                 correct = false;
9904         }
9905
9906         TALLOC_FREE(frame);
9907         return correct;
9908 }
9909
9910 /*
9911  * Only testing minimal time strings, as the others
9912  * need (locale-dependent) guessing at what strftime does and
9913  * even may differ in builds.
9914  */
9915 static bool timesubst_test(void)
9916 {
9917         TALLOC_CTX *ctx = NULL;
9918         /* Sa 23. Dez 04:33:20 CET 2017 */
9919         const struct timeval tv = { 1514000000, 123 };
9920         const char* expect_minimal = "20171223_033320";
9921         const char* expect_minus   = "20171223_033320_000123";
9922         char *s;
9923         char *env_tz, *orig_tz = NULL;
9924         bool result = true;
9925
9926         ctx = talloc_new(NULL);
9927
9928         env_tz = getenv("TZ");
9929         if(env_tz) {
9930                 orig_tz = talloc_strdup(ctx, env_tz);
9931         }
9932         setenv("TZ", "UTC", 1);
9933
9934         s = minimal_timeval_string(ctx, &tv, false);
9935
9936         if(!s || strcmp(s, expect_minimal)) {
9937                 printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
9938                        "[%s]\n", s ? s : "<nil>", expect_minimal);
9939                 result = false;
9940         }
9941         TALLOC_FREE(s);
9942         s = minimal_timeval_string(ctx, &tv, true);
9943         if(!s || strcmp(s, expect_minus)) {
9944                 printf("minimal_timeval_string(ctx, tv, true) returned [%s], expected "
9945                        "[%s]\n", s ? s : "<nil>", expect_minus);
9946                 result = false;
9947         }
9948         TALLOC_FREE(s);
9949
9950         if(orig_tz) {
9951                 setenv("TZ", orig_tz, 1);
9952         }
9953
9954         TALLOC_FREE(ctx);
9955         return result;
9956 }
9957
9958 static bool run_local_substitute(int dummy)
9959 {
9960         bool ok = true;
9961
9962         ok &= subst_test("%U", "bla", "", -1, -1, "bla");
9963         ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
9964         ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
9965         ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
9966         ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
9967         ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
9968         ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
9969         ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
9970         ok &= subst_test("%j %J", "", "", -1, -1, "0_0_0_0 0_0_0_0");
9971         /* Substitution depends on current time, so better test the underlying
9972            formatting function. At least covers %t. */
9973         ok &= timesubst_test();
9974
9975         /* Different captialization rules in sub_basic... */
9976
9977         ok &=  (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
9978                        "blaDOM") == 0);
9979
9980         return ok;
9981 }
9982
9983 static bool run_local_base64(int dummy)
9984 {
9985         int i;
9986         bool ret = true;
9987
9988         for (i=1; i<2000; i++) {
9989                 DATA_BLOB blob1, blob2;
9990                 char *b64;
9991
9992                 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
9993                 blob1.length = i;
9994                 generate_random_buffer(blob1.data, blob1.length);
9995
9996                 b64 = base64_encode_data_blob(talloc_tos(), blob1);
9997                 if (b64 == NULL) {
9998                         d_fprintf(stderr, "base64_encode_data_blob failed "
9999                                   "for %d bytes\n", i);
10000                         ret = false;
10001                 }
10002                 blob2 = base64_decode_data_blob(b64);
10003                 TALLOC_FREE(b64);
10004
10005                 if (data_blob_cmp(&blob1, &blob2)) {
10006                         d_fprintf(stderr, "data_blob_cmp failed for %d "
10007                                   "bytes\n", i);
10008                         ret = false;
10009                 }
10010                 TALLOC_FREE(blob1.data);
10011                 data_blob_free(&blob2);
10012         }
10013         return ret;
10014 }
10015
10016 static void parse_fn(time_t timeout, DATA_BLOB blob, void *private_data)
10017 {
10018         return;
10019 }
10020
10021 static bool run_local_gencache(int dummy)
10022 {
10023         char *val;
10024         time_t tm;
10025         DATA_BLOB blob;
10026         char v;
10027         struct memcache *mem;
10028         int i;
10029
10030         mem = memcache_init(NULL, 0);
10031         if (mem == NULL) {
10032                 d_printf("%s: memcache_init failed\n", __location__);
10033                 return false;
10034         }
10035         memcache_set_global(mem);
10036
10037         if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
10038                 d_printf("%s: gencache_set() failed\n", __location__);
10039                 return False;
10040         }
10041
10042         if (!gencache_get("foo", NULL, NULL, NULL)) {
10043                 d_printf("%s: gencache_get() failed\n", __location__);
10044                 return False;
10045         }
10046
10047         for (i=0; i<1000000; i++) {
10048                 gencache_parse("foo", parse_fn, NULL);
10049         }
10050
10051         if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
10052                 d_printf("%s: gencache_get() failed\n", __location__);
10053                 return False;
10054         }
10055         TALLOC_FREE(val);
10056
10057         if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
10058                 d_printf("%s: gencache_get() failed\n", __location__);
10059                 return False;
10060         }
10061
10062         if (strcmp(val, "bar") != 0) {
10063                 d_printf("%s: gencache_get() returned %s, expected %s\n",
10064                          __location__, val, "bar");
10065                 TALLOC_FREE(val);
10066                 return False;
10067         }
10068
10069         TALLOC_FREE(val);
10070
10071         if (!gencache_del("foo")) {
10072                 d_printf("%s: gencache_del() failed\n", __location__);
10073                 return False;
10074         }
10075         if (gencache_del("foo")) {
10076                 d_printf("%s: second gencache_del() succeeded\n",
10077                          __location__);
10078                 return False;
10079         }
10080
10081         if (gencache_get("foo", talloc_tos(), &val, &tm)) {
10082                 d_printf("%s: gencache_get() on deleted entry "
10083                          "succeeded\n", __location__);
10084                 return False;
10085         }
10086
10087         blob = data_blob_string_const_null("bar");
10088         tm = time(NULL) + 60;
10089
10090         if (!gencache_set_data_blob("foo", blob, tm)) {
10091                 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
10092                 return False;
10093         }
10094
10095         if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
10096                 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
10097                 return False;
10098         }
10099
10100         if (strcmp((const char *)blob.data, "bar") != 0) {
10101                 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
10102                          __location__, (const char *)blob.data, "bar");
10103                 data_blob_free(&blob);
10104                 return False;
10105         }
10106
10107         data_blob_free(&blob);
10108
10109         if (!gencache_del("foo")) {
10110                 d_printf("%s: gencache_del() failed\n", __location__);
10111                 return False;
10112         }
10113         if (gencache_del("foo")) {
10114                 d_printf("%s: second gencache_del() succeeded\n",
10115                          __location__);
10116                 return False;
10117         }
10118
10119         if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
10120                 d_printf("%s: gencache_get_data_blob() on deleted entry "
10121                          "succeeded\n", __location__);
10122                 return False;
10123         }
10124
10125         v = 1;
10126         blob.data = (uint8_t *)&v;
10127         blob.length = sizeof(v);
10128
10129         if (!gencache_set_data_blob("blob", blob, tm)) {
10130                 d_printf("%s: gencache_set_data_blob() failed\n",
10131                          __location__);
10132                 return false;
10133         }
10134         if (gencache_get("blob", talloc_tos(), &val, &tm)) {
10135                 d_printf("%s: gencache_get succeeded\n", __location__);
10136                 return false;
10137         }
10138
10139         return True;
10140 }
10141
10142 static bool rbt_testval(struct db_context *db, const char *key,
10143                         const char *value)
10144 {
10145         struct db_record *rec;
10146         TDB_DATA data = string_tdb_data(value);
10147         bool ret = false;
10148         NTSTATUS status;
10149         TDB_DATA dbvalue;
10150
10151         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
10152         if (rec == NULL) {
10153                 d_fprintf(stderr, "fetch_locked failed\n");
10154                 goto done;
10155         }
10156         status = dbwrap_record_store(rec, data, 0);
10157         if (!NT_STATUS_IS_OK(status)) {
10158                 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
10159                 goto done;
10160         }
10161         TALLOC_FREE(rec);
10162
10163         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
10164         if (rec == NULL) {
10165                 d_fprintf(stderr, "second fetch_locked failed\n");
10166                 goto done;
10167         }
10168
10169         dbvalue = dbwrap_record_get_value(rec);
10170         if ((dbvalue.dsize != data.dsize)
10171             || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
10172                 d_fprintf(stderr, "Got wrong data back\n");
10173                 goto done;
10174         }
10175
10176         ret = true;
10177  done:
10178         TALLOC_FREE(rec);
10179         return ret;
10180 }
10181
10182 static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
10183 {
10184         int *count2 = (int *)private_data;
10185         (*count2)++;
10186         return 0;
10187 }
10188
10189 static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
10190 {
10191         int *count2 = (int *)private_data;
10192         (*count2)++;
10193         dbwrap_record_delete(rec);
10194         return 0;
10195 }
10196
10197 static bool run_local_rbtree(int dummy)
10198 {
10199         struct db_context *db;
10200         bool ret = false;
10201         int i;
10202         NTSTATUS status;
10203         int count = 0;
10204         int count2 = 0;
10205
10206         db = db_open_rbt(NULL);
10207
10208         if (db == NULL) {
10209                 d_fprintf(stderr, "db_open_rbt failed\n");
10210                 return false;
10211         }
10212
10213         for (i=0; i<1000; i++) {
10214                 char *key, *value;
10215
10216                 if (asprintf(&key, "key%ld", random()) == -1) {
10217                         goto done;
10218                 }
10219                 if (asprintf(&value, "value%ld", random()) == -1) {
10220                         SAFE_FREE(key);
10221                         goto done;
10222                 }
10223
10224                 if (!rbt_testval(db, key, value)) {
10225                         SAFE_FREE(key);
10226                         SAFE_FREE(value);
10227                         goto done;
10228                 }
10229
10230                 SAFE_FREE(value);
10231                 if (asprintf(&value, "value%ld", random()) == -1) {
10232                         SAFE_FREE(key);
10233                         goto done;
10234                 }
10235
10236                 if (!rbt_testval(db, key, value)) {
10237                         SAFE_FREE(key);
10238                         SAFE_FREE(value);
10239                         goto done;
10240                 }
10241
10242                 SAFE_FREE(key);
10243                 SAFE_FREE(value);
10244         }
10245
10246         ret = true;
10247         count = 0; count2 = 0;
10248         status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10249                                       &count2, &count);
10250         printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10251         if ((count != count2) || (count != 1000)) {
10252                 ret = false;
10253         }
10254         count = 0; count2 = 0;
10255         status = dbwrap_traverse(db, local_rbtree_traverse_delete,
10256                                  &count2, &count);
10257         printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10258         if ((count != count2) || (count != 1000)) {
10259                 ret = false;
10260         }
10261         count = 0; count2 = 0;
10262         status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10263                                       &count2, &count);
10264         printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10265         if ((count != count2) || (count != 0)) {
10266                 ret = false;
10267         }
10268
10269  done:
10270         TALLOC_FREE(db);
10271         return ret;
10272 }
10273
10274
10275 /*
10276   local test for character set functions
10277
10278   This is a very simple test for the functionality in convert_string_error()
10279  */
10280 static bool run_local_convert_string(int dummy)
10281 {
10282         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
10283         const char *test_strings[2] = { "March", "M\303\244rz" };
10284         char dst[7];
10285         int i;
10286
10287         for (i=0; i<2; i++) {
10288                 const char *str = test_strings[i];
10289                 int len = strlen(str);
10290                 size_t converted_size;
10291                 bool ret;
10292
10293                 memset(dst, 'X', sizeof(dst));
10294
10295                 /* first try with real source length */
10296                 ret = convert_string_error(CH_UNIX, CH_UTF8,
10297                                            str, len,
10298                                            dst, sizeof(dst),
10299                                            &converted_size);
10300                 if (ret != true) {
10301                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10302                         goto failed;
10303                 }
10304
10305                 if (converted_size != len) {
10306                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10307                                   str, len, (int)converted_size);
10308                         goto failed;
10309                 }
10310
10311                 if (strncmp(str, dst, converted_size) != 0) {
10312                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10313                         goto failed;
10314                 }
10315
10316                 if (strlen(str) != converted_size) {
10317                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10318                                   (int)strlen(str), (int)converted_size);
10319                         goto failed;
10320                 }
10321
10322                 if (dst[converted_size] != 'X') {
10323                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10324                         goto failed;
10325                 }
10326
10327                 /* now with srclen==-1, this causes the nul to be
10328                  * converted too */
10329                 ret = convert_string_error(CH_UNIX, CH_UTF8,
10330                                            str, -1,
10331                                            dst, sizeof(dst),
10332                                            &converted_size);
10333                 if (ret != true) {
10334                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10335                         goto failed;
10336                 }
10337
10338                 if (converted_size != len+1) {
10339                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10340                                   str, len, (int)converted_size);
10341                         goto failed;
10342                 }
10343
10344                 if (strncmp(str, dst, converted_size) != 0) {
10345                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10346                         goto failed;
10347                 }
10348
10349                 if (len+1 != converted_size) {
10350                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10351                                   len+1, (int)converted_size);
10352                         goto failed;
10353                 }
10354
10355                 if (dst[converted_size] != 'X') {
10356                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10357                         goto failed;
10358                 }
10359
10360         }
10361
10362
10363         TALLOC_FREE(tmp_ctx);
10364         return true;
10365 failed:
10366         TALLOC_FREE(tmp_ctx);
10367         return false;
10368 }
10369
10370 static bool run_local_string_to_sid(int dummy) {
10371         struct dom_sid sid;
10372
10373         if (string_to_sid(&sid, "S--1-5-32-545")) {
10374                 printf("allowing S--1-5-32-545\n");
10375                 return false;
10376         }
10377         if (string_to_sid(&sid, "S-1-5-32-+545")) {
10378                 printf("allowing S-1-5-32-+545\n");
10379                 return false;
10380         }
10381         if (string_to_sid(&sid, "S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0")) {
10382                 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
10383                 return false;
10384         }
10385         if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
10386                 printf("allowing S-1-5-32-545-abc\n");
10387                 return false;
10388         }
10389         if (string_to_sid(&sid, "S-300-5-32-545")) {
10390                 printf("allowing S-300-5-32-545\n");
10391                 return false;
10392         }
10393         if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
10394                 printf("allowing S-1-0xfffffffffffffe-32-545\n");
10395                 return false;
10396         }
10397         if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
10398                 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
10399                 return false;
10400         }
10401         if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
10402                 printf("could not parse S-1-0xfffffffffffe-32-545\n");
10403                 return false;
10404         }
10405         if (!string_to_sid(&sid, "S-1-5-32-545")) {
10406                 printf("could not parse S-1-5-32-545\n");
10407                 return false;
10408         }
10409         if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
10410                 printf("mis-parsed S-1-5-32-545 as %s\n",
10411                        sid_string_tos(&sid));
10412                 return false;
10413         }
10414         return true;
10415 }
10416
10417 static bool sid_to_string_test(const char *expected) {
10418         char *str;
10419         bool res = true;
10420         struct dom_sid sid;
10421
10422         if (!string_to_sid(&sid, expected)) {
10423                 printf("could not parse %s\n", expected);
10424                 return false;
10425         }
10426
10427         str = dom_sid_string(NULL, &sid);
10428         if (strcmp(str, expected)) {
10429                 printf("Comparison failed (%s != %s)\n", str, expected);
10430                 res = false;
10431         }
10432         TALLOC_FREE(str);
10433         return res;
10434 }
10435
10436 static bool run_local_sid_to_string(int dummy) {
10437         if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
10438                 return false;
10439         if (!sid_to_string_test("S-1-545"))
10440                 return false;
10441         if (!sid_to_string_test("S-255-3840-1-1-1-1"))
10442                 return false;
10443         return true;
10444 }
10445
10446 static bool run_local_binary_to_sid(int dummy) {
10447         struct dom_sid *sid = talloc(NULL, struct dom_sid);
10448         static const uint8_t good_binary_sid[] = {
10449                 0x1, /* revision number */
10450                 15, /* num auths */
10451                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10452                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10453                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10454                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10455                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10456                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10457                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10458                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10459                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10460                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10461                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10462                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10463                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10464                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10465                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10466                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10467         };
10468
10469         static const uint8_t long_binary_sid[] = {
10470                 0x1, /* revision number */
10471                 15, /* num auths */
10472                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10473                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10474                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10475                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10476                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10477                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10478                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10479                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10480                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10481                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10482                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10483                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10484                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10485                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10486                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10487                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10488                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10489                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10490                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10491         };
10492
10493         static const uint8_t long_binary_sid2[] = {
10494                 0x1, /* revision number */
10495                 32, /* num auths */
10496                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10497                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10498                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10499                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10500                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10501                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10502                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10503                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10504                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10505                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10506                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10507                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10508                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10509                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10510                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10511                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10512                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10513                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10514                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10515                 0x1, 0x1, 0x1, 0x1, /* auth[18] */
10516                 0x1, 0x1, 0x1, 0x1, /* auth[19] */
10517                 0x1, 0x1, 0x1, 0x1, /* auth[20] */
10518                 0x1, 0x1, 0x1, 0x1, /* auth[21] */
10519                 0x1, 0x1, 0x1, 0x1, /* auth[22] */
10520                 0x1, 0x1, 0x1, 0x1, /* auth[23] */
10521                 0x1, 0x1, 0x1, 0x1, /* auth[24] */
10522                 0x1, 0x1, 0x1, 0x1, /* auth[25] */
10523                 0x1, 0x1, 0x1, 0x1, /* auth[26] */
10524                 0x1, 0x1, 0x1, 0x1, /* auth[27] */
10525                 0x1, 0x1, 0x1, 0x1, /* auth[28] */
10526                 0x1, 0x1, 0x1, 0x1, /* auth[29] */
10527                 0x1, 0x1, 0x1, 0x1, /* auth[30] */
10528                 0x1, 0x1, 0x1, 0x1, /* auth[31] */
10529         };
10530
10531         if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
10532                 return false;
10533         }
10534         if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
10535                 return false;
10536         }
10537         if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
10538                 return false;
10539         }
10540         return true;
10541 }
10542
10543 /* Split a path name into filename and stream name components. Canonicalise
10544  * such that an implicit $DATA token is always explicit.
10545  *
10546  * The "specification" of this function can be found in the
10547  * run_local_stream_name() function in torture.c, I've tried those
10548  * combinations against a W2k3 server.
10549  */
10550
10551 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
10552                                        char **pbase, char **pstream)
10553 {
10554         char *base = NULL;
10555         char *stream = NULL;
10556         char *sname; /* stream name */
10557         const char *stype; /* stream type */
10558
10559         DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
10560
10561         sname = strchr_m(fname, ':');
10562
10563         if (sname == NULL) {
10564                 if (pbase != NULL) {
10565                         base = talloc_strdup(mem_ctx, fname);
10566                         NT_STATUS_HAVE_NO_MEMORY(base);
10567                 }
10568                 goto done;
10569         }
10570
10571         if (pbase != NULL) {
10572                 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
10573                 NT_STATUS_HAVE_NO_MEMORY(base);
10574         }
10575
10576         sname += 1;
10577
10578         stype = strchr_m(sname, ':');
10579
10580         if (stype == NULL) {
10581                 sname = talloc_strdup(mem_ctx, sname);
10582                 stype = "$DATA";
10583         }
10584         else {
10585                 if (strcasecmp_m(stype, ":$DATA") != 0) {
10586                         /*
10587                          * If there is an explicit stream type, so far we only
10588                          * allow $DATA. Is there anything else allowed? -- vl
10589                          */
10590                         DEBUG(10, ("[%s] is an invalid stream type\n", stype));
10591                         TALLOC_FREE(base);
10592                         return NT_STATUS_OBJECT_NAME_INVALID;
10593                 }
10594                 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
10595                 stype += 1;
10596         }
10597
10598         if (sname == NULL) {
10599                 TALLOC_FREE(base);
10600                 return NT_STATUS_NO_MEMORY;
10601         }
10602
10603         if (sname[0] == '\0') {
10604                 /*
10605                  * no stream name, so no stream
10606                  */
10607                 goto done;
10608         }
10609
10610         if (pstream != NULL) {
10611                 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
10612                 if (stream == NULL) {
10613                         TALLOC_FREE(sname);
10614                         TALLOC_FREE(base);
10615                         return NT_STATUS_NO_MEMORY;
10616                 }
10617                 /*
10618                  * upper-case the type field
10619                  */
10620                 (void)strupper_m(strchr_m(stream, ':')+1);
10621         }
10622
10623  done:
10624         if (pbase != NULL) {
10625                 *pbase = base;
10626         }
10627         if (pstream != NULL) {
10628                 *pstream = stream;
10629         }
10630         return NT_STATUS_OK;
10631 }
10632
10633 static bool test_stream_name(const char *fname, const char *expected_base,
10634                              const char *expected_stream,
10635                              NTSTATUS expected_status)
10636 {
10637         NTSTATUS status;
10638         char *base = NULL;
10639         char *stream = NULL;
10640
10641         status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
10642         if (!NT_STATUS_EQUAL(status, expected_status)) {
10643                 goto error;
10644         }
10645
10646         if (!NT_STATUS_IS_OK(status)) {
10647                 return true;
10648         }
10649
10650         if (base == NULL) goto error;
10651
10652         if (strcmp(expected_base, base) != 0) goto error;
10653
10654         if ((expected_stream != NULL) && (stream == NULL)) goto error;
10655         if ((expected_stream == NULL) && (stream != NULL)) goto error;
10656
10657         if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
10658                 goto error;
10659
10660         TALLOC_FREE(base);
10661         TALLOC_FREE(stream);
10662         return true;
10663
10664  error:
10665         d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
10666                   fname, expected_base ? expected_base : "<NULL>",
10667                   expected_stream ? expected_stream : "<NULL>",
10668                   nt_errstr(expected_status));
10669         d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
10670                   base ? base : "<NULL>", stream ? stream : "<NULL>",
10671                   nt_errstr(status));
10672         TALLOC_FREE(base);
10673         TALLOC_FREE(stream);
10674         return false;
10675 }
10676
10677 static bool run_local_stream_name(int dummy)
10678 {
10679         bool ret = true;
10680
10681         ret &= test_stream_name(
10682                 "bla", "bla", NULL, NT_STATUS_OK);
10683         ret &= test_stream_name(
10684                 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
10685         ret &= test_stream_name(
10686                 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10687         ret &= test_stream_name(
10688                 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
10689         ret &= test_stream_name(
10690                 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10691         ret &= test_stream_name(
10692                 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
10693         ret &= test_stream_name(
10694                 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
10695         ret &= test_stream_name(
10696                 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
10697
10698         return ret;
10699 }
10700
10701 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
10702 {
10703         if (a.length != b.length) {
10704                 printf("a.length=%d != b.length=%d\n",
10705                        (int)a.length, (int)b.length);
10706                 return false;
10707         }
10708         if (memcmp(a.data, b.data, a.length) != 0) {
10709                 printf("a.data and b.data differ\n");
10710                 return false;
10711         }
10712         return true;
10713 }
10714
10715 static bool run_local_memcache(int dummy)
10716 {
10717         struct memcache *cache;
10718         DATA_BLOB k1, k2, k3;
10719         DATA_BLOB d1, d3;
10720         DATA_BLOB v1, v3;
10721
10722         TALLOC_CTX *mem_ctx;
10723         char *ptr1 = NULL;
10724         char *ptr2 = NULL;
10725
10726         char *str1, *str2;
10727         size_t size1, size2;
10728         bool ret = false;
10729
10730         mem_ctx = talloc_init("foo");
10731         if (mem_ctx == NULL) {
10732                 return false;
10733         }
10734
10735         /* STAT_CACHE TESTS */
10736
10737         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
10738
10739         if (cache == NULL) {
10740                 printf("memcache_init failed\n");
10741                 return false;
10742         }
10743
10744         d1 = data_blob_const("d1", 2);
10745         d3 = data_blob_const("d3", 2);
10746
10747         k1 = data_blob_const("d1", 2);
10748         k2 = data_blob_const("d2", 2);
10749         k3 = data_blob_const("d3", 2);
10750
10751         memcache_add(cache, STAT_CACHE, k1, d1);
10752
10753         if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
10754                 printf("could not find k1\n");
10755                 return false;
10756         }
10757         if (!data_blob_equal(d1, v1)) {
10758                 return false;
10759         }
10760
10761         memcache_add(cache, STAT_CACHE, k1, d3);
10762
10763         if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
10764                 printf("could not find replaced k1\n");
10765                 return false;
10766         }
10767         if (!data_blob_equal(d3, v3)) {
10768                 return false;
10769         }
10770
10771         TALLOC_FREE(cache);
10772
10773         /* GETWD_CACHE TESTS */
10774         str1 = talloc_strdup(mem_ctx, "string1");
10775         if (str1 == NULL) {
10776                 return false;
10777         }
10778         ptr2 = str1; /* Keep an alias for comparison. */
10779
10780         str2 = talloc_strdup(mem_ctx, "string2");
10781         if (str2 == NULL) {
10782                 return false;
10783         }
10784
10785         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
10786         if (cache == NULL) {
10787                 printf("memcache_init failed\n");
10788                 return false;
10789         }
10790
10791         memcache_add_talloc(cache, GETWD_CACHE, k2, &str1);
10792         /* str1 == NULL now. */
10793         ptr1 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
10794         if (ptr1 == NULL) {
10795                 printf("could not find k2\n");
10796                 return false;
10797         }
10798         if (ptr1 != ptr2) {
10799                 printf("fetch of k2 got wrong string\n");
10800                 return false;
10801         }
10802
10803         /* Add a blob to ensure k2 gets purged. */
10804         d3 = data_blob_talloc_zero(mem_ctx, 180);
10805         memcache_add(cache, STAT_CACHE, k3, d3);
10806
10807         ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
10808         if (ptr2 != NULL) {
10809                 printf("Did find k2, should have been purged\n");
10810                 return false;
10811         }
10812
10813         TALLOC_FREE(cache);
10814         TALLOC_FREE(mem_ctx);
10815
10816         mem_ctx = talloc_init("foo");
10817         if (mem_ctx == NULL) {
10818                 return false;
10819         }
10820
10821         cache = memcache_init(NULL, 0);
10822         if (cache == NULL) {
10823                 return false;
10824         }
10825
10826         str1 = talloc_strdup(mem_ctx, "string1");
10827         if (str1 == NULL) {
10828                 return false;
10829         }
10830         str2 = talloc_strdup(mem_ctx, "string2");
10831         if (str2 == NULL) {
10832                 return false;
10833         }
10834         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
10835                             data_blob_string_const("torture"), &str1);
10836         size1 = talloc_total_size(cache);
10837
10838         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
10839                             data_blob_string_const("torture"), &str2);
10840         size2 = talloc_total_size(cache);
10841
10842         printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
10843
10844         if (size2 > size1) {
10845                 printf("memcache leaks memory!\n");
10846                 goto fail;
10847         }
10848
10849         ret = true;
10850  fail:
10851         TALLOC_FREE(cache);
10852         return ret;
10853 }
10854
10855 static void wbclient_done(struct tevent_req *req)
10856 {
10857         wbcErr wbc_err;
10858         struct winbindd_response *wb_resp;
10859         int *i = (int *)tevent_req_callback_data_void(req);
10860
10861         wbc_err = wb_trans_recv(req, req, &wb_resp);
10862         TALLOC_FREE(req);
10863         *i += 1;
10864         d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
10865 }
10866
10867 static bool run_wbclient_multi_ping(int dummy)
10868 {
10869         struct tevent_context *ev;
10870         struct wb_context **wb_ctx;
10871         struct winbindd_request wb_req;
10872         bool result = false;
10873         int i, j;
10874
10875         BlockSignals(True, SIGPIPE);
10876
10877         ev = tevent_context_init(talloc_tos());
10878         if (ev == NULL) {
10879                 goto fail;
10880         }
10881
10882         wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
10883         if (wb_ctx == NULL) {
10884                 goto fail;
10885         }
10886
10887         ZERO_STRUCT(wb_req);
10888         wb_req.cmd = WINBINDD_PING;
10889
10890         d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
10891
10892         for (i=0; i<torture_nprocs; i++) {
10893                 wb_ctx[i] = wb_context_init(ev, NULL);
10894                 if (wb_ctx[i] == NULL) {
10895                         goto fail;
10896                 }
10897                 for (j=0; j<torture_numops; j++) {
10898                         struct tevent_req *req;
10899                         req = wb_trans_send(ev, ev, wb_ctx[i],
10900                                             (j % 2) == 0, &wb_req);
10901                         if (req == NULL) {
10902                                 goto fail;
10903                         }
10904                         tevent_req_set_callback(req, wbclient_done, &i);
10905                 }
10906         }
10907
10908         i = 0;
10909
10910         while (i < torture_nprocs * torture_numops) {
10911                 tevent_loop_once(ev);
10912         }
10913
10914         result = true;
10915  fail:
10916         TALLOC_FREE(ev);
10917         return result;
10918 }
10919
10920 static bool dbtrans_inc(struct db_context *db)
10921 {
10922         struct db_record *rec;
10923         uint32_t val;
10924         bool ret = false;
10925         NTSTATUS status;
10926         TDB_DATA value;
10927
10928         rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
10929         if (rec == NULL) {
10930                 printf(__location__ "fetch_lock failed\n");
10931                 return false;
10932         }
10933
10934         value = dbwrap_record_get_value(rec);
10935
10936         if (value.dsize != sizeof(uint32_t)) {
10937                 printf(__location__ "value.dsize = %d\n",
10938                        (int)value.dsize);
10939                 goto fail;
10940         }
10941
10942         memcpy(&val, value.dptr, sizeof(val));
10943         val += 1;
10944
10945         status = dbwrap_record_store(
10946                 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
10947         if (!NT_STATUS_IS_OK(status)) {
10948                 printf(__location__ "store failed: %s\n",
10949                        nt_errstr(status));
10950                 goto fail;
10951         }
10952
10953         ret = true;
10954 fail:
10955         TALLOC_FREE(rec);
10956         return ret;
10957 }
10958
10959 static bool run_local_dbtrans(int dummy)
10960 {
10961         struct db_context *db;
10962         struct db_record *rec;
10963         NTSTATUS status;
10964         uint32_t initial;
10965         int res;
10966         TDB_DATA value;
10967
10968         db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
10969                      O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
10970                      DBWRAP_FLAG_NONE);
10971         if (db == NULL) {
10972                 printf("Could not open transtest.db\n");
10973                 return false;
10974         }
10975
10976         res = dbwrap_transaction_start(db);
10977         if (res != 0) {
10978                 printf(__location__ "transaction_start failed\n");
10979                 return false;
10980         }
10981
10982         rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
10983         if (rec == NULL) {
10984                 printf(__location__ "fetch_lock failed\n");
10985                 return false;
10986         }
10987
10988         value = dbwrap_record_get_value(rec);
10989
10990         if (value.dptr == NULL) {
10991                 initial = 0;
10992                 status = dbwrap_record_store(
10993                         rec, make_tdb_data((uint8_t *)&initial,
10994                                            sizeof(initial)),
10995                         0);
10996                 if (!NT_STATUS_IS_OK(status)) {
10997                         printf(__location__ "store returned %s\n",
10998                                nt_errstr(status));
10999                         return false;
11000                 }
11001         }
11002
11003         TALLOC_FREE(rec);
11004
11005         res = dbwrap_transaction_commit(db);
11006         if (res != 0) {
11007                 printf(__location__ "transaction_commit failed\n");
11008                 return false;
11009         }
11010
11011         while (true) {
11012                 uint32_t val, val2;
11013                 int i;
11014
11015                 res = dbwrap_transaction_start(db);
11016                 if (res != 0) {
11017                         printf(__location__ "transaction_start failed\n");
11018                         break;
11019                 }
11020
11021                 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
11022                 if (!NT_STATUS_IS_OK(status)) {
11023                         printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
11024                                nt_errstr(status));
11025                         break;
11026                 }
11027
11028                 for (i=0; i<10; i++) {
11029                         if (!dbtrans_inc(db)) {
11030                                 return false;
11031                         }
11032                 }
11033
11034                 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
11035                 if (!NT_STATUS_IS_OK(status)) {
11036                         printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
11037                                nt_errstr(status));
11038                         break;
11039                 }
11040
11041                 if (val2 != val + 10) {
11042                         printf(__location__ "val=%d, val2=%d\n",
11043                                (int)val, (int)val2);
11044                         break;
11045                 }
11046
11047                 printf("val2=%d\r", val2);
11048
11049                 res = dbwrap_transaction_commit(db);
11050                 if (res != 0) {
11051                         printf(__location__ "transaction_commit failed\n");
11052                         break;
11053                 }
11054         }
11055
11056         TALLOC_FREE(db);
11057         return true;
11058 }
11059
11060 /*
11061  * Just a dummy test to be run under a debugger. There's no real way
11062  * to inspect the tevent_poll specific function from outside of
11063  * tevent_poll.c.
11064  */
11065
11066 static bool run_local_tevent_poll(int dummy)
11067 {
11068         struct tevent_context *ev;
11069         struct tevent_fd *fd1, *fd2;
11070         bool result = false;
11071
11072         ev = tevent_context_init_byname(NULL, "poll");
11073         if (ev == NULL) {
11074                 d_fprintf(stderr, "tevent_context_init_byname failed\n");
11075                 goto fail;
11076         }
11077
11078         fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
11079         if (fd1 == NULL) {
11080                 d_fprintf(stderr, "tevent_add_fd failed\n");
11081                 goto fail;
11082         }
11083         fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
11084         if (fd2 == NULL) {
11085                 d_fprintf(stderr, "tevent_add_fd failed\n");
11086                 goto fail;
11087         }
11088         TALLOC_FREE(fd2);
11089
11090         fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
11091         if (fd2 == NULL) {
11092                 d_fprintf(stderr, "tevent_add_fd failed\n");
11093                 goto fail;
11094         }
11095
11096         result = true;
11097 fail:
11098         TALLOC_FREE(ev);
11099         return result;
11100 }
11101
11102 static bool run_local_hex_encode_buf(int dummy)
11103 {
11104         char buf[17];
11105         uint8_t src[8];
11106         int i;
11107
11108         for (i=0; i<sizeof(src); i++) {
11109                 src[i] = i;
11110         }
11111         hex_encode_buf(buf, src, sizeof(src));
11112         if (strcmp(buf, "0001020304050607") != 0) {
11113                 return false;
11114         }
11115         hex_encode_buf(buf, NULL, 0);
11116         if (buf[0] != '\0') {
11117                 return false;
11118         }
11119         return true;
11120 }
11121
11122 static const char *remove_duplicate_addrs2_test_strings_vector[] = {
11123         "0.0.0.0",
11124         "::0",
11125         "1.2.3.1",
11126         "0.0.0.0",
11127         "0.0.0.0",
11128         "1.2.3.2",
11129         "1.2.3.3",
11130         "1.2.3.4",
11131         "1.2.3.5",
11132         "::0",
11133         "1.2.3.6",
11134         "1.2.3.7",
11135         "::0",
11136         "::0",
11137         "::0",
11138         "1.2.3.8",
11139         "1.2.3.9",
11140         "1.2.3.10",
11141         "1.2.3.11",
11142         "1.2.3.12",
11143         "1.2.3.13",
11144         "1001:1111:1111:1000:0:1111:1111:1111",
11145         "1.2.3.1",
11146         "1.2.3.2",
11147         "1.2.3.3",
11148         "1.2.3.12",
11149         "::0",
11150         "::0"
11151 };
11152
11153 static const char *remove_duplicate_addrs2_test_strings_result[] = {
11154         "1.2.3.1",
11155         "1.2.3.2",
11156         "1.2.3.3",
11157         "1.2.3.4",
11158         "1.2.3.5",
11159         "1.2.3.6",
11160         "1.2.3.7",
11161         "1.2.3.8",
11162         "1.2.3.9",
11163         "1.2.3.10",
11164         "1.2.3.11",
11165         "1.2.3.12",
11166         "1.2.3.13",
11167         "1001:1111:1111:1000:0:1111:1111:1111"
11168 };
11169
11170 static bool run_local_remove_duplicate_addrs2(int dummy)
11171 {
11172         struct ip_service test_vector[28];
11173         int count, i;
11174
11175         /* Construct the sockaddr_storage test vector. */
11176         for (i = 0; i < 28; i++) {
11177                 struct addrinfo hints;
11178                 struct addrinfo *res = NULL;
11179                 int ret;
11180
11181                 memset(&hints, '\0', sizeof(hints));
11182                 hints.ai_flags = AI_NUMERICHOST;
11183                 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
11184                                 NULL,
11185                                 &hints,
11186                                 &res);
11187                 if (ret) {
11188                         fprintf(stderr, "getaddrinfo failed on [%s]\n",
11189                                 remove_duplicate_addrs2_test_strings_vector[i]);
11190                         return false;
11191                 }
11192                 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
11193                 memcpy(&test_vector[i].ss,
11194                         res->ai_addr,
11195                         res->ai_addrlen);
11196                 freeaddrinfo(res);
11197         }
11198
11199         count = remove_duplicate_addrs2(test_vector, i);
11200
11201         if (count != 14) {
11202                 fprintf(stderr, "count wrong (%d) should be 14\n",
11203                         count);
11204                 return false;
11205         }
11206
11207         for (i = 0; i < count; i++) {
11208                 char addr[INET6_ADDRSTRLEN];
11209
11210                 print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
11211
11212                 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
11213                         fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
11214                                 i,
11215                                 addr,
11216                                 remove_duplicate_addrs2_test_strings_result[i]);
11217                         return false;
11218                 }
11219         }
11220
11221         printf("run_local_remove_duplicate_addrs2: success\n");
11222         return true;
11223 }
11224
11225 static bool run_local_tdb_opener(int dummy)
11226 {
11227         TDB_CONTEXT *t;
11228         unsigned v = 0;
11229
11230         while (1) {
11231                 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
11232                              O_RDWR|O_CREAT, 0755);
11233                 if (t == NULL) {
11234                         perror("tdb_open failed");
11235                         return false;
11236                 }
11237                 tdb_close(t);
11238
11239                 v += 1;
11240                 printf("\r%u", v);
11241         }
11242         return true;
11243 }
11244
11245 static bool run_local_tdb_writer(int dummy)
11246 {
11247         TDB_CONTEXT *t;
11248         unsigned v = 0;
11249         TDB_DATA val;
11250
11251         t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
11252         if (t == 0) {
11253                 perror("tdb_open failed");
11254                 return 1;
11255         }
11256
11257         val.dptr = (uint8_t *)&v;
11258         val.dsize = sizeof(v);
11259
11260         while (1) {
11261                 TDB_DATA data;
11262                 int ret;
11263
11264                 ret = tdb_store(t, val, val, 0);
11265                 if (ret != 0) {
11266                         printf("%s\n", tdb_errorstr(t));
11267                 }
11268                 v += 1;
11269                 printf("\r%u", v);
11270
11271                 data = tdb_fetch(t, val);
11272                 if (data.dptr != NULL) {
11273                         SAFE_FREE(data.dptr);
11274                 }
11275         }
11276         return true;
11277 }
11278
11279 static bool run_local_canonicalize_path(int dummy)
11280 {
11281         const char *src[] = {
11282                         "/foo/..",
11283                         "/..",
11284                         "/foo/bar/../baz",
11285                         "/foo/././",
11286                         "/../foo",
11287                         ".././././",
11288                         ".././././../../../boo",
11289                         "./..",
11290                         NULL
11291                         };
11292         const char *dst[] = {
11293                         "/",
11294                         "/",
11295                         "/foo/baz",
11296                         "/foo",
11297                         "/foo",
11298                         "/",
11299                         "/boo",
11300                         "/",
11301                         NULL
11302                         };
11303         unsigned int i;
11304
11305         for (i = 0; src[i] != NULL; i++) {
11306                 char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
11307                 if (d == NULL) {
11308                         perror("talloc fail\n");
11309                         return false;
11310                 }
11311                 if (strcmp(d, dst[i]) != 0) {
11312                         d_fprintf(stderr,
11313                                 "canonicalize missmatch %s -> %s != %s",
11314                                 src[i], d, dst[i]);
11315                         return false;
11316                 }
11317                 talloc_free(d);
11318         }
11319         return true;
11320 }
11321
11322 static bool run_ign_bad_negprot(int dummy)
11323 {
11324         struct tevent_context *ev;
11325         struct tevent_req *req;
11326         struct smbXcli_conn *conn;
11327         struct sockaddr_storage ss;
11328         NTSTATUS status;
11329         int fd;
11330         bool ok;
11331
11332         printf("starting ignore bad negprot\n");
11333
11334         ok = resolve_name(host, &ss, 0x20, true);
11335         if (!ok) {
11336                 d_fprintf(stderr, "Could not resolve name %s\n", host);
11337                 return false;
11338         }
11339
11340         status = open_socket_out(&ss, 445, 10000, &fd);
11341         if (!NT_STATUS_IS_OK(status)) {
11342                 d_fprintf(stderr, "open_socket_out failed: %s\n",
11343                           nt_errstr(status));
11344                 return false;
11345         }
11346
11347         conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
11348                                    NULL, 0);
11349         if (conn == NULL) {
11350                 d_fprintf(stderr, "smbXcli_conn_create failed\n");
11351                 return false;
11352         }
11353
11354         status = smbXcli_negprot(conn, 0, PROTOCOL_CORE, PROTOCOL_CORE);
11355         if (NT_STATUS_IS_OK(status)) {
11356                 d_fprintf(stderr, "smbXcli_negprot succeeded!\n");
11357                 return false;
11358         }
11359
11360         ev = samba_tevent_context_init(talloc_tos());
11361         if (ev == NULL) {
11362                 d_fprintf(stderr, "samba_tevent_context_init failed\n");
11363                 return false;
11364         }
11365
11366         req = smb1cli_session_setup_nt1_send(
11367                 ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "",
11368                 data_blob_null, data_blob_null, 0x40,
11369                 "Windows 2000 2195", "Windows 2000 5.0");
11370         if (req == NULL) {
11371                 d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n");
11372                 return false;
11373         }
11374
11375         ok = tevent_req_poll_ntstatus(req, ev, &status);
11376         if (!ok) {
11377                 d_fprintf(stderr, "tevent_req_poll failed\n");
11378                 return false;
11379         }
11380
11381         status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL,
11382                                                 NULL, NULL);
11383         if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
11384                 d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned "
11385                           "%s, expected NT_STATUS_CONNECTION_RESET\n",
11386                           nt_errstr(status));
11387                 return false;
11388         }
11389
11390         TALLOC_FREE(conn);
11391
11392         printf("starting ignore bad negprot\n");
11393
11394         return true;
11395 }
11396
11397 static double create_procs(bool (*fn)(int), bool *result)
11398 {
11399         int i, status;
11400         volatile pid_t *child_status;
11401         volatile bool *child_status_out;
11402         int synccount;
11403         int tries = 8;
11404         struct timeval start;
11405
11406         synccount = 0;
11407
11408         child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
11409         if (!child_status) {
11410                 printf("Failed to setup shared memory\n");
11411                 return -1;
11412         }
11413
11414         child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
11415         if (!child_status_out) {
11416                 printf("Failed to setup result status shared memory\n");
11417                 return -1;
11418         }
11419
11420         for (i = 0; i < torture_nprocs; i++) {
11421                 child_status[i] = 0;
11422                 child_status_out[i] = True;
11423         }
11424
11425         start = timeval_current();
11426
11427         for (i=0;i<torture_nprocs;i++) {
11428                 procnum = i;
11429                 if (fork() == 0) {
11430                         pid_t mypid = getpid();
11431                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
11432
11433                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
11434
11435                         while (1) {
11436                                 if (torture_open_connection(&current_cli, i)) break;
11437                                 if (tries-- == 0) {
11438                                         printf("pid %d failed to start\n", (int)getpid());
11439                                         _exit(1);
11440                                 }
11441                                 smb_msleep(10); 
11442                         }
11443
11444                         child_status[i] = getpid();
11445
11446                         while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
11447
11448                         child_status_out[i] = fn(i);
11449                         _exit(0);
11450                 }
11451         }
11452
11453         do {
11454                 synccount = 0;
11455                 for (i=0;i<torture_nprocs;i++) {
11456                         if (child_status[i]) synccount++;
11457                 }
11458                 if (synccount == torture_nprocs) break;
11459                 smb_msleep(10);
11460         } while (timeval_elapsed(&start) < 30);
11461
11462         if (synccount != torture_nprocs) {
11463                 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
11464                 *result = False;
11465                 return timeval_elapsed(&start);
11466         }
11467
11468         /* start the client load */
11469         start = timeval_current();
11470
11471         for (i=0;i<torture_nprocs;i++) {
11472                 child_status[i] = 0;
11473         }
11474
11475         printf("%d clients started\n", torture_nprocs);
11476
11477         for (i=0;i<torture_nprocs;i++) {
11478                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
11479         }
11480
11481         printf("\n");
11482
11483         for (i=0;i<torture_nprocs;i++) {
11484                 if (!child_status_out[i]) {
11485                         *result = False;
11486                 }
11487         }
11488         return timeval_elapsed(&start);
11489 }
11490
11491 #define FLAG_MULTIPROC 1
11492
11493 static struct {
11494         const char *name;
11495         bool (*fn)(int);
11496         unsigned flags;
11497 } torture_ops[] = {
11498         {"FDPASS", run_fdpasstest, 0},
11499         {"LOCK1",  run_locktest1,  0},
11500         {"LOCK2",  run_locktest2,  0},
11501         {"LOCK3",  run_locktest3,  0},
11502         {"LOCK4",  run_locktest4,  0},
11503         {"LOCK5",  run_locktest5,  0},
11504         {"LOCK6",  run_locktest6,  0},
11505         {"LOCK7",  run_locktest7,  0},
11506         {"LOCK8",  run_locktest8,  0},
11507         {"LOCK9",  run_locktest9,  0},
11508         {"UNLINK", run_unlinktest, 0},
11509         {"BROWSE", run_browsetest, 0},
11510         {"ATTR",   run_attrtest,   0},
11511         {"TRANS2", run_trans2test, 0},
11512         {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
11513         {"TORTURE",run_torture,    FLAG_MULTIPROC},
11514         {"RANDOMIPC", run_randomipc, 0},
11515         {"NEGNOWAIT", run_negprot_nowait, 0},
11516         {"NBENCH",  run_nbench, 0},
11517         {"NBENCH2", run_nbench2, 0},
11518         {"OPLOCK1",  run_oplock1, 0},
11519         {"OPLOCK2",  run_oplock2, 0},
11520         {"OPLOCK4",  run_oplock4, 0},
11521         {"DIR",  run_dirtest, 0},
11522         {"DIR1",  run_dirtest1, 0},
11523         {"DIR-CREATETIME",  run_dir_createtime, 0},
11524         {"DENY1",  torture_denytest1, 0},
11525         {"DENY2",  torture_denytest2, 0},
11526         {"TCON",  run_tcon_test, 0},
11527         {"TCONDEV",  run_tcon_devtype_test, 0},
11528         {"RW1",  run_readwritetest, 0},
11529         {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
11530         {"RW3",  run_readwritelarge, 0},
11531         {"RW-SIGNING",  run_readwritelarge_signtest, 0},
11532         {"OPEN", run_opentest, 0},
11533         {"POSIX", run_simple_posix_open_test, 0},
11534         {"POSIX-APPEND", run_posix_append, 0},
11535         {"POSIX-SYMLINK-ACL", run_acl_symlink_test, 0},
11536         {"POSIX-SYMLINK-EA", run_ea_symlink_test, 0},
11537         {"POSIX-STREAM-DELETE", run_posix_stream_delete, 0},
11538         {"POSIX-OFD-LOCK", run_posix_ofd_lock_test, 0},
11539         {"WINDOWS-BAD-SYMLINK", run_symlink_open_test, 0},
11540         {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
11541         {"ASYNC-ECHO", run_async_echo, 0},
11542         { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
11543         { "SHORTNAME-TEST", run_shortname_test, 0},
11544         { "ADDRCHANGE", run_addrchange, 0},
11545 #if 1
11546         {"OPENATTR", run_openattrtest, 0},
11547 #endif
11548         {"XCOPY", run_xcopy, 0},
11549         {"RENAME", run_rename, 0},
11550         {"RENAME-ACCESS", run_rename_access, 0},
11551         {"OWNER-RIGHTS", run_owner_rights, 0},
11552         {"DELETE", run_deletetest, 0},
11553         {"WILDDELETE", run_wild_deletetest, 0},
11554         {"DELETE-LN", run_deletetest_ln, 0},
11555         {"PROPERTIES", run_properties, 0},
11556         {"MANGLE", torture_mangle, 0},
11557         {"MANGLE1", run_mangle1, 0},
11558         {"MANGLE-ILLEGAL", run_mangle_illegal, 0},
11559         {"W2K", run_w2ktest, 0},
11560         {"TRANS2SCAN", torture_trans2_scan, 0},
11561         {"NTTRANSSCAN", torture_nttrans_scan, 0},
11562         {"UTABLE", torture_utable, 0},
11563         {"CASETABLE", torture_casetable, 0},
11564         {"ERRMAPEXTRACT", run_error_map_extract, 0},
11565         {"PIPE_NUMBER", run_pipe_number, 0},
11566         {"TCON2",  run_tcon2_test, 0},
11567         {"IOCTL",  torture_ioctl_test, 0},
11568         {"CHKPATH",  torture_chkpath_test, 0},
11569         {"FDSESS", run_fdsesstest, 0},
11570         { "EATEST", run_eatest, 0},
11571         { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
11572         { "CHAIN1", run_chain1, 0},
11573         { "CHAIN2", run_chain2, 0},
11574         { "CHAIN3", run_chain3, 0},
11575         { "WINDOWS-WRITE", run_windows_write, 0},
11576         { "LARGE_READX", run_large_readx, 0},
11577         { "NTTRANS-CREATE", run_nttrans_create, 0},
11578         { "NTTRANS-FSCTL", run_nttrans_fsctl, 0},
11579         { "CLI_ECHO", run_cli_echo, 0},
11580         { "TLDAP", run_tldap },
11581         { "STREAMERROR", run_streamerror },
11582         { "NOTIFY-BENCH", run_notify_bench },
11583         { "NOTIFY-BENCH2", run_notify_bench2 },
11584         { "NOTIFY-BENCH3", run_notify_bench3 },
11585         { "BAD-NBT-SESSION", run_bad_nbt_session },
11586         { "IGN-BAD-NEGPROT", run_ign_bad_negprot },
11587         { "SMB-ANY-CONNECT", run_smb_any_connect },
11588         { "NOTIFY-ONLINE", run_notify_online },
11589         { "SMB2-BASIC", run_smb2_basic },
11590         { "SMB2-NEGPROT", run_smb2_negprot },
11591         { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect },
11592         { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence },
11593         { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel },
11594         { "SMB2-SESSION-REAUTH", run_smb2_session_reauth },
11595         { "SMB2-FTRUNCATE", run_smb2_ftruncate },
11596         { "CLEANUP1", run_cleanup1 },
11597         { "CLEANUP2", run_cleanup2 },
11598         { "CLEANUP3", run_cleanup3 },
11599         { "CLEANUP4", run_cleanup4 },
11600         { "OPLOCK-CANCEL", run_oplock_cancel },
11601         { "PIDHIGH", run_pidhigh },
11602         { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
11603         { "LOCAL-GENCACHE", run_local_gencache, 0},
11604         { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1, 0 },
11605         { "LOCAL-DBWRAP-WATCH2", run_dbwrap_watch2, 0 },
11606         { "LOCAL-DBWRAP-DO-LOCKED1", run_dbwrap_do_locked1, 0 },
11607         { "LOCAL-MESSAGING-READ1", run_messaging_read1, 0 },
11608         { "LOCAL-MESSAGING-READ2", run_messaging_read2, 0 },
11609         { "LOCAL-MESSAGING-READ3", run_messaging_read3, 0 },
11610         { "LOCAL-MESSAGING-READ4", run_messaging_read4, 0 },
11611         { "LOCAL-MESSAGING-FDPASS1", run_messaging_fdpass1, 0 },
11612         { "LOCAL-MESSAGING-FDPASS2", run_messaging_fdpass2, 0 },
11613         { "LOCAL-MESSAGING-FDPASS2a", run_messaging_fdpass2a, 0 },
11614         { "LOCAL-MESSAGING-FDPASS2b", run_messaging_fdpass2b, 0 },
11615         { "LOCAL-MESSAGING-SEND-ALL", run_messaging_send_all, 0 },
11616         { "LOCAL-BASE64", run_local_base64, 0},
11617         { "LOCAL-RBTREE", run_local_rbtree, 0},
11618         { "LOCAL-MEMCACHE", run_local_memcache, 0},
11619         { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
11620         { "WBCLIENT-MULTI-PING", run_wbclient_multi_ping, 0},
11621         { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
11622         { "LOCAL-sid_to_string", run_local_sid_to_string, 0},
11623         { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
11624         { "LOCAL-DBTRANS", run_local_dbtrans, 0},
11625         { "LOCAL-TEVENT-POLL", run_local_tevent_poll, 0},
11626         { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
11627         { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0},
11628         { "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0},
11629         { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test, 0},
11630         { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2, 0},
11631         { "local-tdb-opener", run_local_tdb_opener, 0 },
11632         { "local-tdb-writer", run_local_tdb_writer, 0 },
11633         { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb, 0 },
11634         { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool, 0 },
11635         { "LOCAL-PTHREADPOOL-TEVENT", run_pthreadpool_tevent, 0 },
11636         { "LOCAL-G-LOCK1", run_g_lock1, 0 },
11637         { "LOCAL-G-LOCK2", run_g_lock2, 0 },
11638         { "LOCAL-G-LOCK3", run_g_lock3, 0 },
11639         { "LOCAL-G-LOCK4", run_g_lock4, 0 },
11640         { "LOCAL-G-LOCK5", run_g_lock5, 0 },
11641         { "LOCAL-G-LOCK6", run_g_lock6, 0 },
11642         { "LOCAL-G-LOCK-PING-PONG", run_g_lock_ping_pong, 0 },
11643         { "LOCAL-CANONICALIZE-PATH", run_local_canonicalize_path, 0 },
11644         { "LOCAL-NAMEMAP-CACHE1", run_local_namemap_cache1, 0 },
11645         { "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 },
11646         {NULL, NULL, 0}};
11647
11648 /****************************************************************************
11649 run a specified test or "ALL"
11650 ****************************************************************************/
11651 static bool run_test(const char *name)
11652 {
11653         bool ret = True;
11654         bool result = True;
11655         bool found = False;
11656         int i;
11657         double t;
11658         if (strequal(name,"ALL")) {
11659                 for (i=0;torture_ops[i].name;i++) {
11660                         run_test(torture_ops[i].name);
11661                 }
11662                 found = True;
11663         }
11664
11665         for (i=0;torture_ops[i].name;i++) {
11666                 fstr_sprintf(randomfname, "\\XX%x", 
11667                          (unsigned)random());
11668
11669                 if (strequal(name, torture_ops[i].name)) {
11670                         found = True;
11671                         printf("Running %s\n", name);
11672                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
11673                                 t = create_procs(torture_ops[i].fn, &result);
11674                                 if (!result) { 
11675                                         ret = False;
11676                                         printf("TEST %s FAILED!\n", name);
11677                                 }
11678                         } else {
11679                                 struct timeval start;
11680                                 start = timeval_current();
11681                                 if (!torture_ops[i].fn(0)) {
11682                                         ret = False;
11683                                         printf("TEST %s FAILED!\n", name);
11684                                 }
11685                                 t = timeval_elapsed(&start);
11686                         }
11687                         printf("%s took %g secs\n\n", name, t);
11688                 }
11689         }
11690
11691         if (!found) {
11692                 printf("Did not find a test named %s\n", name);
11693                 ret = False;
11694         }
11695
11696         return ret;
11697 }
11698
11699
11700 static void usage(void)
11701 {
11702         int i;
11703
11704         printf("WARNING samba4 test suite is much more complete nowadays.\n");
11705         printf("Please use samba4 torture.\n\n");
11706
11707         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
11708
11709         printf("\t-d debuglevel\n");
11710         printf("\t-U user%%pass\n");
11711         printf("\t-k                    use kerberos\n");
11712         printf("\t-N numprocs\n");
11713         printf("\t-n my_netbios_name\n");
11714         printf("\t-W workgroup\n");
11715         printf("\t-o num_operations\n");
11716         printf("\t-O socket_options\n");
11717         printf("\t-m maximum protocol\n");
11718         printf("\t-L use oplocks\n");
11719         printf("\t-c CLIENT.TXT         specify client load file for NBENCH\n");
11720         printf("\t-A showall\n");
11721         printf("\t-p port\n");
11722         printf("\t-s seed\n");
11723         printf("\t-b unclist_filename   specify multiple shares for multiple connections\n");
11724         printf("\t-f filename           filename to test\n");
11725         printf("\t-e                    encrypt\n");
11726         printf("\n\n");
11727
11728         printf("tests are:");
11729         for (i=0;torture_ops[i].name;i++) {
11730                 printf(" %s", torture_ops[i].name);
11731         }
11732         printf("\n");
11733
11734         printf("default test is ALL\n");
11735
11736         exit(1);
11737 }
11738
11739 /****************************************************************************
11740   main program
11741 ****************************************************************************/
11742  int main(int argc,char *argv[])
11743 {
11744         int opt, i;
11745         char *p;
11746         int gotuser = 0;
11747         int gotpass = 0;
11748         bool correct = True;
11749         TALLOC_CTX *frame = talloc_stackframe();
11750         int seed = time(NULL);
11751
11752 #ifdef HAVE_SETBUFFER
11753         setbuffer(stdout, NULL, 0);
11754 #endif
11755
11756         setup_logging("smbtorture", DEBUG_STDOUT);
11757
11758         smb_init_locale();
11759         fault_setup();
11760
11761         if (is_default_dyn_CONFIGFILE()) {
11762                 if(getenv("SMB_CONF_PATH")) {
11763                         set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
11764                 }
11765         }
11766         lp_load_global(get_dyn_CONFIGFILE());
11767         load_interfaces();
11768
11769         if (argc < 2) {
11770                 usage();
11771         }
11772
11773         for(p = argv[1]; *p; p++)
11774           if(*p == '\\')
11775             *p = '/';
11776
11777         if (strncmp(argv[1], "//", 2)) {
11778                 usage();
11779         }
11780
11781         fstrcpy(host, &argv[1][2]);
11782         p = strchr_m(&host[2],'/');
11783         if (!p) {
11784                 usage();
11785         }
11786         *p = 0;
11787         fstrcpy(share, p+1);
11788
11789         fstrcpy(myname, get_myname(talloc_tos()));
11790         if (!*myname) {
11791                 fprintf(stderr, "Failed to get my hostname.\n");
11792                 return 1;
11793         }
11794
11795         if (*username == 0 && getenv("LOGNAME")) {
11796           fstrcpy(username,getenv("LOGNAME"));
11797         }
11798
11799         argc--;
11800         argv++;
11801
11802         fstrcpy(workgroup, lp_workgroup());
11803
11804         while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
11805                != EOF) {
11806                 switch (opt) {
11807                 case 'p':
11808                         port_to_use = atoi(optarg);
11809                         break;
11810                 case 's':
11811                         seed = atoi(optarg);
11812                         break;
11813                 case 'W':
11814                         fstrcpy(workgroup,optarg);
11815                         break;
11816                 case 'm':
11817                         lp_set_cmdline("client max protocol", optarg);
11818                         break;
11819                 case 'N':
11820                         torture_nprocs = atoi(optarg);
11821                         break;
11822                 case 'o':
11823                         torture_numops = atoi(optarg);
11824                         break;
11825                 case 'd':
11826                         lp_set_cmdline("log level", optarg);
11827                         break;
11828                 case 'O':
11829                         sockops = optarg;
11830                         break;
11831                 case 'L':
11832                         use_oplocks = True;
11833                         break;
11834                 case 'l':
11835                         local_path = optarg;
11836                         break;
11837                 case 'A':
11838                         torture_showall = True;
11839                         break;
11840                 case 'n':
11841                         fstrcpy(myname, optarg);
11842                         break;
11843                 case 'c':
11844                         client_txt = optarg;
11845                         break;
11846                 case 'e':
11847                         do_encrypt = true;
11848                         break;
11849                 case 'k':
11850 #ifdef HAVE_KRB5
11851                         use_kerberos = True;
11852 #else
11853                         d_printf("No kerberos support compiled in\n");
11854                         exit(1);
11855 #endif
11856                         break;
11857                 case 'U':
11858                         gotuser = 1;
11859                         fstrcpy(username,optarg);
11860                         p = strchr_m(username,'%');
11861                         if (p) {
11862                                 *p = 0;
11863                                 fstrcpy(password, p+1);
11864                                 gotpass = 1;
11865                         }
11866                         break;
11867                 case 'b':
11868                         fstrcpy(multishare_conn_fname, optarg);
11869                         use_multishare_conn = True;
11870                         break;
11871                 case 'B':
11872                         torture_blocksize = atoi(optarg);
11873                         break;
11874                 case 'f':
11875                         test_filename = SMB_STRDUP(optarg);
11876                         break;
11877                 default:
11878                         printf("Unknown option %c (%d)\n", (char)opt, opt);
11879                         usage();
11880                 }
11881         }
11882
11883         d_printf("using seed %d\n", seed);
11884
11885         srandom(seed);
11886
11887         if(use_kerberos && !gotuser) gotpass = True;
11888
11889         while (!gotpass) {
11890                 char pwd[256] = {0};
11891                 int rc;
11892
11893                 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
11894                 if (rc == 0) {
11895                         fstrcpy(password, pwd);
11896                         gotpass = 1;
11897                 }
11898         }
11899
11900         printf("host=%s share=%s user=%s myname=%s\n", 
11901                host, share, username, myname);
11902
11903         torture_creds = cli_session_creds_init(frame,
11904                                                username,
11905                                                workgroup,
11906                                                NULL, /* realm */
11907                                                password,
11908                                                use_kerberos,
11909                                                false, /* fallback_after_kerberos */
11910                                                false, /* use_ccache */
11911                                                false); /* password_is_nt_hash */
11912         if (torture_creds == NULL) {
11913                 d_printf("cli_session_creds_init() failed.\n");
11914                 exit(1);
11915         }
11916
11917         if (argc == optind) {
11918                 correct = run_test("ALL");
11919         } else {
11920                 for (i=optind;i<argc;i++) {
11921                         if (!run_test(argv[i])) {
11922                                 correct = False;
11923                         }
11924                 }
11925         }
11926
11927         TALLOC_FREE(frame);
11928
11929         if (correct) {
11930                 return(0);
11931         } else {
11932                 return(1);
11933         }
11934 }