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