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