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