s3:torture:delete: add a comment
[metze/samba/wip.git] / source3 / torture / torture.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB torture tester
4    Copyright (C) Andrew Tridgell 1997-1998
5    Copyright (C) Jeremy Allison 2009
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "system/shmem.h"
23 #include "wbc_async.h"
24 #include "torture/proto.h"
25 #include "libcli/security/security.h"
26 #include "tldap.h"
27 #include "tldap_util.h"
28 #include "../librpc/gen_ndr/svcctl.h"
29 #include "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 "talloc_dict.h"
35 #include "async_smb.h"
36 #include "libsmb/libsmb.h"
37 #include "libsmb/clirap.h"
38 #include "trans2.h"
39 #include "libsmb/nmblib.h"
40 #include "../lib/util/tevent_ntstatus.h"
41 #include "util_tdb.h"
42 #include "../libcli/smb/read_smb.h"
43 #include "../libcli/smb/smbXcli_base.h"
44
45 extern char *optarg;
46 extern int optind;
47
48 fstring host, workgroup, share, password, username, myname;
49 static int max_protocol = PROTOCOL_NT1;
50 static const char *sockops="TCP_NODELAY";
51 int torture_nprocs=1;
52 static int port_to_use=0;
53 int torture_numops=100;
54 int torture_blocksize=1024*1024;
55 static int procnum; /* records process count number when forking */
56 static struct cli_state *current_cli;
57 static fstring randomfname;
58 static bool use_oplocks;
59 static bool use_level_II_oplocks;
60 static const char *client_txt = "client_oplocks.txt";
61 static bool disable_spnego;
62 static bool use_kerberos;
63 static bool force_dos_errors;
64 static fstring multishare_conn_fname;
65 static bool use_multishare_conn = False;
66 static bool do_encrypt;
67 static const char *local_path = NULL;
68 static int signing_state = SMB_SIGNING_DEFAULT;
69 char *test_filename;
70
71 bool torture_showall = False;
72
73 static double create_procs(bool (*fn)(int), bool *result);
74
75 /********************************************************************
76  Ensure a connection is encrypted.
77 ********************************************************************/
78
79 static bool force_cli_encryption(struct cli_state *c,
80                         const char *sharename)
81 {
82         uint16 major, minor;
83         uint32 caplow, caphigh;
84         NTSTATUS status;
85
86         if (!SERVER_HAS_UNIX_CIFS(c)) {
87                 d_printf("Encryption required and "
88                         "server that doesn't support "
89                         "UNIX extensions - failing connect\n");
90                         return false;
91         }
92
93         status = cli_unix_extensions_version(c, &major, &minor, &caplow,
94                                              &caphigh);
95         if (!NT_STATUS_IS_OK(status)) {
96                 d_printf("Encryption required and "
97                         "can't get UNIX CIFS extensions "
98                         "version from server: %s\n", nt_errstr(status));
99                 return false;
100         }
101
102         if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
103                 d_printf("Encryption required and "
104                         "share %s doesn't support "
105                         "encryption.\n", sharename);
106                 return false;
107         }
108
109         if (c->use_kerberos) {
110                 status = cli_gss_smb_encryption_start(c);
111         } else {
112                 status = cli_raw_ntlm_smb_encryption_start(c,
113                                                 username,
114                                                 password,
115                                                 workgroup);
116         }
117
118         if (!NT_STATUS_IS_OK(status)) {
119                 d_printf("Encryption required and "
120                         "setup failed with error %s.\n",
121                         nt_errstr(status));
122                 return false;
123         }
124
125         return true;
126 }
127
128
129 static struct cli_state *open_nbt_connection(void)
130 {
131         struct cli_state *c;
132         NTSTATUS status;
133         int flags = 0;
134
135         if (disable_spnego) {
136                 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
137         }
138
139         if (use_oplocks) {
140                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
141         }
142
143         if (use_level_II_oplocks) {
144                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
145         }
146
147         if (use_kerberos) {
148                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
149         }
150
151         if (force_dos_errors) {
152                 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
153         }
154
155         status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
156                                 signing_state, flags, &c);
157         if (!NT_STATUS_IS_OK(status)) {
158                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
159                 return NULL;
160         }
161
162         cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
163
164         return c;
165 }
166
167 /****************************************************************************
168  Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
169 ****************************************************************************/
170
171 static bool cli_bad_session_request(int fd,
172                          struct nmb_name *calling, struct nmb_name *called)
173 {
174         TALLOC_CTX *frame;
175         uint8_t len_buf[4];
176         struct iovec iov[3];
177         ssize_t len;
178         uint8_t *inbuf;
179         int err;
180         bool ret = false;
181         uint8_t message_type;
182         uint8_t error;
183         struct event_context *ev;
184         struct tevent_req *req;
185
186         frame = talloc_stackframe();
187
188         iov[0].iov_base = len_buf;
189         iov[0].iov_len  = sizeof(len_buf);
190
191         /* put in the destination name */
192
193         iov[1].iov_base = name_mangle(talloc_tos(), called->name,
194                                       called->name_type);
195         if (iov[1].iov_base == NULL) {
196                 goto fail;
197         }
198         iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
199                                   talloc_get_size(iov[1].iov_base));
200
201         /* and my name */
202
203         iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
204                                       calling->name_type);
205         if (iov[2].iov_base == NULL) {
206                 goto fail;
207         }
208         iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
209                                   talloc_get_size(iov[2].iov_base));
210
211         /* Deliberately corrupt the name len (first byte) */
212         *((uint8_t *)iov[2].iov_base) = 100;
213
214         /* send a session request (RFC 1002) */
215         /* setup the packet length
216          * Remove four bytes from the length count, since the length
217          * field in the NBT Session Service header counts the number
218          * of bytes which follow.  The cli_send_smb() function knows
219          * about this and accounts for those four bytes.
220          * CRH.
221          */
222
223         _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
224         SCVAL(len_buf,0,0x81);
225
226         len = write_data_iov(fd, iov, 3);
227         if (len == -1) {
228                 goto fail;
229         }
230
231         ev = event_context_init(frame);
232         if (ev == NULL) {
233                 goto fail;
234         }
235         req = read_smb_send(frame, ev, fd);
236         if (req == NULL) {
237                 goto fail;
238         }
239         if (!tevent_req_poll(req, ev)) {
240                 goto fail;
241         }
242         len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
243         if (len == -1) {
244                 errno = err;
245                 goto fail;
246         }
247         TALLOC_FREE(ev);
248
249         message_type = CVAL(inbuf, 0);
250         if (message_type != 0x83) {
251                 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
252                           message_type);
253                 goto fail;
254         }
255
256         if (smb_len(inbuf) != 1) {
257                 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
258                           (int)smb_len(inbuf));
259                 goto fail;
260         }
261
262         error = CVAL(inbuf, 4);
263         if (error !=  0x82) {
264                 d_fprintf(stderr, "Expected error 0x82, got %d\n",
265                           (int)error);
266                 goto fail;
267         }
268
269         ret = true;
270 fail:
271         TALLOC_FREE(frame);
272         return ret;
273 }
274
275 /* Insert a NULL at the first separator of the given path and return a pointer
276  * to the remainder of the string.
277  */
278 static char *
279 terminate_path_at_separator(char * path)
280 {
281         char * p;
282
283         if (!path) {
284                 return NULL;
285         }
286
287         if ((p = strchr_m(path, '/'))) {
288                 *p = '\0';
289                 return p + 1;
290         }
291
292         if ((p = strchr_m(path, '\\'))) {
293                 *p = '\0';
294                 return p + 1;
295         }
296
297         /* No separator. */
298         return NULL;
299 }
300
301 /*
302   parse a //server/share type UNC name
303 */
304 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
305                       char **hostname, char **sharename)
306 {
307         char *p;
308
309         *hostname = *sharename = NULL;
310
311         if (strncmp(unc_name, "\\\\", 2) &&
312             strncmp(unc_name, "//", 2)) {
313                 return False;
314         }
315
316         *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
317         p = terminate_path_at_separator(*hostname);
318
319         if (p && *p) {
320                 *sharename = talloc_strdup(mem_ctx, p);
321                 terminate_path_at_separator(*sharename);
322         }
323
324         if (*hostname && *sharename) {
325                 return True;
326         }
327
328         TALLOC_FREE(*hostname);
329         TALLOC_FREE(*sharename);
330         return False;
331 }
332
333 static bool torture_open_connection_share(struct cli_state **c,
334                                    const char *hostname, 
335                                    const char *sharename)
336 {
337         int flags = 0;
338         NTSTATUS status;
339
340         if (use_kerberos)
341                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
342         if (use_oplocks)
343                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
344         if (use_level_II_oplocks)
345                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
346
347         status = cli_full_connection(c, myname,
348                                      hostname, NULL, port_to_use, 
349                                      sharename, "?????", 
350                                      username, workgroup, 
351                                      password, flags, signing_state);
352         if (!NT_STATUS_IS_OK(status)) {
353                 printf("failed to open share connection: //%s/%s port:%d - %s\n",
354                         hostname, sharename, port_to_use, nt_errstr(status));
355                 return False;
356         }
357
358         cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
359
360         if (do_encrypt) {
361                 return force_cli_encryption(*c,
362                                         sharename);
363         }
364         return True;
365 }
366
367 bool torture_open_connection(struct cli_state **c, int conn_index)
368 {
369         char **unc_list = NULL;
370         int num_unc_names = 0;
371         bool result;
372
373         if (use_multishare_conn==True) {
374                 char *h, *s;
375                 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
376                 if (!unc_list || num_unc_names <= 0) {
377                         printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
378                         exit(1);
379                 }
380
381                 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
382                                       NULL, &h, &s)) {
383                         printf("Failed to parse UNC name %s\n",
384                                unc_list[conn_index % num_unc_names]);
385                         TALLOC_FREE(unc_list);
386                         exit(1);
387                 }
388
389                 result = torture_open_connection_share(c, h, s);
390
391                 /* h, s were copied earlier */
392                 TALLOC_FREE(unc_list);
393                 return result;
394         }
395
396         return torture_open_connection_share(c, host, share);
397 }
398
399 bool torture_init_connection(struct cli_state **pcli)
400 {
401         struct cli_state *cli;
402
403         cli = open_nbt_connection();
404         if (cli == NULL) {
405                 return false;
406         }
407
408         *pcli = cli;
409         return true;
410 }
411
412 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
413 {
414         uint16_t old_vuid = cli_state_get_uid(cli);
415         fstring old_user_name;
416         size_t passlen = strlen(password);
417         NTSTATUS status;
418         bool ret;
419
420         fstrcpy(old_user_name, cli->user_name);
421         cli_state_set_uid(cli, 0);
422         ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
423                                                 password, passlen,
424                                                 password, passlen,
425                                                 workgroup));
426         *new_vuid = cli_state_get_uid(cli);
427         cli_state_set_uid(cli, old_vuid);
428         status = cli_set_username(cli, old_user_name);
429         if (!NT_STATUS_IS_OK(status)) {
430                 return false;
431         }
432         return ret;
433 }
434
435
436 bool torture_close_connection(struct cli_state *c)
437 {
438         bool ret = True;
439         NTSTATUS status;
440
441         status = cli_tdis(c);
442         if (!NT_STATUS_IS_OK(status)) {
443                 printf("tdis failed (%s)\n", nt_errstr(status));
444                 ret = False;
445         }
446
447         cli_shutdown(c);
448
449         return ret;
450 }
451
452
453 /* check if the server produced the expected dos or nt error code */
454 static bool check_both_error(int line, NTSTATUS status,
455                              uint8 eclass, uint32 ecode, NTSTATUS nterr)
456 {
457         if (NT_STATUS_IS_DOS(status)) {
458                 uint8 cclass;
459                 uint32 num;
460
461                 /* Check DOS error */
462                 cclass = NT_STATUS_DOS_CLASS(status);
463                 num = NT_STATUS_DOS_CODE(status);
464
465                 if (eclass != cclass || ecode != num) {
466                         printf("unexpected error code class=%d code=%d\n",
467                                (int)cclass, (int)num);
468                         printf(" expected %d/%d %s (line=%d)\n",
469                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
470                         return false;
471                 }
472         } else {
473                 /* Check NT error */
474                 if (!NT_STATUS_EQUAL(nterr, status)) {
475                         printf("unexpected error code %s\n",
476                                 nt_errstr(status));
477                         printf(" expected %s (line=%d)\n",
478                                 nt_errstr(nterr), line);
479                         return false;
480                 }
481         }
482
483         return true;
484 }
485
486
487 /* check if the server produced the expected error code */
488 static bool check_error(int line, NTSTATUS status,
489                         uint8 eclass, uint32 ecode, NTSTATUS nterr)
490 {
491         if (NT_STATUS_IS_DOS(status)) {
492                 uint8 cclass;
493                 uint32 num;
494
495                 /* Check DOS error */
496
497                 cclass = NT_STATUS_DOS_CLASS(status);
498                 num = NT_STATUS_DOS_CODE(status);
499
500                 if (eclass != cclass || ecode != num) {
501                         printf("unexpected error code class=%d code=%d\n", 
502                                (int)cclass, (int)num);
503                         printf(" expected %d/%d %s (line=%d)\n", 
504                                (int)eclass, (int)ecode, nt_errstr(nterr),
505                                line);
506                         return False;
507                 }
508
509         } else {
510                 /* Check NT error */
511
512                 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
513                         printf("unexpected error code %s\n",
514                                nt_errstr(status));
515                         printf(" expected %s (line=%d)\n", nt_errstr(nterr),
516                                line);
517                         return False;
518                 }
519         }
520
521         return True;
522 }
523
524
525 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
526 {
527         NTSTATUS status;
528
529         status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
530
531         while (!NT_STATUS_IS_OK(status)) {
532                 if (!check_both_error(__LINE__, status, ERRDOS,
533                                       ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
534                         return false;
535                 }
536
537                 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
538         }
539
540         return true;
541 }
542
543
544 static bool rw_torture(struct cli_state *c)
545 {
546         const char *lockfname = "\\torture.lck";
547         fstring fname;
548         uint16_t fnum;
549         uint16_t fnum2;
550         pid_t pid2, pid = getpid();
551         int i, j;
552         char buf[1024];
553         bool correct = True;
554         size_t nread = 0;
555         NTSTATUS status;
556
557         memset(buf, '\0', sizeof(buf));
558
559         status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
560                          DENY_NONE, &fnum2);
561         if (!NT_STATUS_IS_OK(status)) {
562                 status = cli_openx(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
563         }
564         if (!NT_STATUS_IS_OK(status)) {
565                 printf("open of %s failed (%s)\n",
566                        lockfname, nt_errstr(status));
567                 return False;
568         }
569
570         for (i=0;i<torture_numops;i++) {
571                 unsigned n = (unsigned)sys_random()%10;
572
573                 if (i % 10 == 0) {
574                         printf("%d\r", i); fflush(stdout);
575                 }
576                 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
577
578                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
579                         return False;
580                 }
581
582                 status = cli_openx(c, fname, O_RDWR | O_CREAT | O_TRUNC,
583                                   DENY_ALL, &fnum);
584                 if (!NT_STATUS_IS_OK(status)) {
585                         printf("open failed (%s)\n", nt_errstr(status));
586                         correct = False;
587                         break;
588                 }
589
590                 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
591                                       sizeof(pid), NULL);
592                 if (!NT_STATUS_IS_OK(status)) {
593                         printf("write failed (%s)\n", nt_errstr(status));
594                         correct = False;
595                 }
596
597                 for (j=0;j<50;j++) {
598                         status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
599                                               sizeof(pid)+(j*sizeof(buf)),
600                                               sizeof(buf), NULL);
601                         if (!NT_STATUS_IS_OK(status)) {
602                                 printf("write failed (%s)\n",
603                                        nt_errstr(status));
604                                 correct = False;
605                         }
606                 }
607
608                 pid2 = 0;
609
610                 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
611                                   &nread);
612                 if (!NT_STATUS_IS_OK(status)) {
613                         printf("read failed (%s)\n", nt_errstr(status));
614                         correct = false;
615                 } else if (nread != sizeof(pid)) {
616                         printf("read/write compare failed: "
617                                "recv %ld req %ld\n", (unsigned long)nread,
618                                (unsigned long)sizeof(pid));
619                         correct = false;
620                 }
621
622                 if (pid2 != pid) {
623                         printf("data corruption!\n");
624                         correct = False;
625                 }
626
627                 status = cli_close(c, fnum);
628                 if (!NT_STATUS_IS_OK(status)) {
629                         printf("close failed (%s)\n", nt_errstr(status));
630                         correct = False;
631                 }
632
633                 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
634                 if (!NT_STATUS_IS_OK(status)) {
635                         printf("unlink failed (%s)\n", nt_errstr(status));
636                         correct = False;
637                 }
638
639                 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
640                 if (!NT_STATUS_IS_OK(status)) {
641                         printf("unlock failed (%s)\n", nt_errstr(status));
642                         correct = False;
643                 }
644         }
645
646         cli_close(c, fnum2);
647         cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
648
649         printf("%d\n", i);
650
651         return correct;
652 }
653
654 static bool run_torture(int dummy)
655 {
656         struct cli_state *cli;
657         bool ret;
658
659         cli = current_cli;
660
661         smbXcli_conn_set_sockopt(cli->conn, sockops);
662
663         ret = rw_torture(cli);
664
665         if (!torture_close_connection(cli)) {
666                 ret = False;
667         }
668
669         return ret;
670 }
671
672 static bool rw_torture3(struct cli_state *c, char *lockfname)
673 {
674         uint16_t fnum = (uint16_t)-1;
675         unsigned int i = 0;
676         char buf[131072];
677         char buf_rd[131072];
678         unsigned count;
679         unsigned countprev = 0;
680         size_t sent = 0;
681         bool correct = True;
682         NTSTATUS status = NT_STATUS_OK;
683
684         srandom(1);
685         for (i = 0; i < sizeof(buf); i += sizeof(uint32))
686         {
687                 SIVAL(buf, i, sys_random());
688         }
689
690         if (procnum == 0)
691         {
692                 status = cli_unlink(
693                         c, lockfname,
694                         FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
695                 if (!NT_STATUS_IS_OK(status)) {
696                         printf("unlink failed (%s) (normal, this file should "
697                                "not exist)\n", nt_errstr(status));
698                 }
699
700                 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
701                                   DENY_NONE, &fnum);
702                 if (!NT_STATUS_IS_OK(status)) {
703                         printf("first open read/write of %s failed (%s)\n",
704                                         lockfname, nt_errstr(status));
705                         return False;
706                 }
707         }
708         else
709         {
710                 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
711                 {
712                         status = cli_openx(c, lockfname, O_RDONLY, 
713                                          DENY_NONE, &fnum);
714                         if (!NT_STATUS_IS_OK(status)) {
715                                 break;
716                         }
717                         smb_msleep(10);
718                 }
719                 if (!NT_STATUS_IS_OK(status)) {
720                         printf("second open read-only of %s failed (%s)\n",
721                                         lockfname, nt_errstr(status));
722                         return False;
723                 }
724         }
725
726         i = 0;
727         for (count = 0; count < sizeof(buf); count += sent)
728         {
729                 if (count >= countprev) {
730                         printf("%d %8d\r", i, count);
731                         fflush(stdout);
732                         i++;
733                         countprev += (sizeof(buf) / 20);
734                 }
735
736                 if (procnum == 0)
737                 {
738                         sent = ((unsigned)sys_random()%(20))+ 1;
739                         if (sent > sizeof(buf) - count)
740                         {
741                                 sent = sizeof(buf) - count;
742                         }
743
744                         status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
745                                               count, sent, NULL);
746                         if (!NT_STATUS_IS_OK(status)) {
747                                 printf("write failed (%s)\n",
748                                        nt_errstr(status));
749                                 correct = False;
750                         }
751                 }
752                 else
753                 {
754                         status = cli_read(c, fnum, buf_rd+count, count,
755                                           sizeof(buf)-count, &sent);
756                         if(!NT_STATUS_IS_OK(status)) {
757                                 printf("read failed offset:%d size:%ld (%s)\n",
758                                        count, (unsigned long)sizeof(buf)-count,
759                                        nt_errstr(status));
760                                 correct = False;
761                                 sent = 0;
762                         } else if (sent > 0) {
763                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
764                                 {
765                                         printf("read/write compare failed\n");
766                                         printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
767                                         correct = False;
768                                         break;
769                                 }
770                         }
771                 }
772
773         }
774
775         status = cli_close(c, fnum);
776         if (!NT_STATUS_IS_OK(status)) {
777                 printf("close failed (%s)\n", nt_errstr(status));
778                 correct = False;
779         }
780
781         return correct;
782 }
783
784 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
785 {
786         const char *lockfname = "\\torture2.lck";
787         uint16_t fnum1;
788         uint16_t fnum2;
789         int i;
790         char buf[131072];
791         char buf_rd[131072];
792         bool correct = True;
793         size_t bytes_read;
794         NTSTATUS status;
795
796         status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
797         if (!NT_STATUS_IS_OK(status)) {
798                 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
799         }
800
801         status = cli_openx(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
802                           DENY_NONE, &fnum1);
803         if (!NT_STATUS_IS_OK(status)) {
804                 printf("first open read/write of %s failed (%s)\n",
805                                 lockfname, nt_errstr(status));
806                 return False;
807         }
808
809         status = cli_openx(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
810         if (!NT_STATUS_IS_OK(status)) {
811                 printf("second open read-only of %s failed (%s)\n",
812                                 lockfname, nt_errstr(status));
813                 cli_close(c1, fnum1);
814                 return False;
815         }
816
817         for (i = 0; i < torture_numops; i++)
818         {
819                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
820                 if (i % 10 == 0) {
821                         printf("%d\r", i); fflush(stdout);
822                 }
823
824                 generate_random_buffer((unsigned char *)buf, buf_size);
825
826                 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
827                                       buf_size, NULL);
828                 if (!NT_STATUS_IS_OK(status)) {
829                         printf("write failed (%s)\n", nt_errstr(status));
830                         correct = False;
831                         break;
832                 }
833
834                 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
835                 if(!NT_STATUS_IS_OK(status)) {
836                         printf("read failed (%s)\n", nt_errstr(status));
837                         correct = false;
838                         break;
839                 } else if (bytes_read != buf_size) {
840                         printf("read failed\n");
841                         printf("read %ld, expected %ld\n",
842                                (unsigned long)bytes_read,
843                                (unsigned long)buf_size); 
844                         correct = False;
845                         break;
846                 }
847
848                 if (memcmp(buf_rd, buf, buf_size) != 0)
849                 {
850                         printf("read/write compare failed\n");
851                         correct = False;
852                         break;
853                 }
854         }
855
856         status = cli_close(c2, fnum2);
857         if (!NT_STATUS_IS_OK(status)) {
858                 printf("close failed (%s)\n", nt_errstr(status));
859                 correct = False;
860         }
861
862         status = cli_close(c1, fnum1);
863         if (!NT_STATUS_IS_OK(status)) {
864                 printf("close failed (%s)\n", nt_errstr(status));
865                 correct = False;
866         }
867
868         status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
869         if (!NT_STATUS_IS_OK(status)) {
870                 printf("unlink failed (%s)\n", nt_errstr(status));
871                 correct = False;
872         }
873
874         return correct;
875 }
876
877 static bool run_readwritetest(int dummy)
878 {
879         struct cli_state *cli1, *cli2;
880         bool test1, test2 = False;
881
882         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
883                 return False;
884         }
885         smbXcli_conn_set_sockopt(cli1->conn, sockops);
886         smbXcli_conn_set_sockopt(cli2->conn, sockops);
887
888         printf("starting readwritetest\n");
889
890         test1 = rw_torture2(cli1, cli2);
891         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
892
893         if (test1) {
894                 test2 = rw_torture2(cli1, cli1);
895                 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
896         }
897
898         if (!torture_close_connection(cli1)) {
899                 test1 = False;
900         }
901
902         if (!torture_close_connection(cli2)) {
903                 test2 = False;
904         }
905
906         return (test1 && test2);
907 }
908
909 static bool run_readwritemulti(int dummy)
910 {
911         struct cli_state *cli;
912         bool test;
913
914         cli = current_cli;
915
916         smbXcli_conn_set_sockopt(cli->conn, sockops);
917
918         printf("run_readwritemulti: fname %s\n", randomfname);
919         test = rw_torture3(cli, randomfname);
920
921         if (!torture_close_connection(cli)) {
922                 test = False;
923         }
924
925         return test;
926 }
927
928 static bool run_readwritelarge_internal(void)
929 {
930         static struct cli_state *cli1;
931         uint16_t fnum1;
932         const char *lockfname = "\\large.dat";
933         off_t fsize;
934         char buf[126*1024];
935         bool correct = True;
936         NTSTATUS status;
937
938         if (!torture_open_connection(&cli1, 0)) {
939                 return False;
940         }
941         smbXcli_conn_set_sockopt(cli1->conn, sockops);
942         memset(buf,'\0',sizeof(buf));
943
944         printf("starting readwritelarge_internal\n");
945
946         cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
947
948         status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
949                           DENY_NONE, &fnum1);
950         if (!NT_STATUS_IS_OK(status)) {
951                 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
952                 return False;
953         }
954
955         cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
956
957         status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
958                                      NULL, NULL, NULL);
959         if (!NT_STATUS_IS_OK(status)) {
960                 printf("qfileinfo failed (%s)\n", nt_errstr(status));
961                 correct = False;
962         }
963
964         if (fsize == sizeof(buf))
965                 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
966                        (unsigned long)fsize);
967         else {
968                 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
969                        (unsigned long)fsize);
970                 correct = False;
971         }
972
973         status = cli_close(cli1, fnum1);
974         if (!NT_STATUS_IS_OK(status)) {
975                 printf("close failed (%s)\n", nt_errstr(status));
976                 correct = False;
977         }
978
979         status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
980         if (!NT_STATUS_IS_OK(status)) {
981                 printf("unlink failed (%s)\n", nt_errstr(status));
982                 correct = False;
983         }
984
985         status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
986                           DENY_NONE, &fnum1);
987         if (!NT_STATUS_IS_OK(status)) {
988                 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
989                 return False;
990         }
991
992         cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
993
994         status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
995                                      NULL, NULL, NULL);
996         if (!NT_STATUS_IS_OK(status)) {
997                 printf("qfileinfo failed (%s)\n", nt_errstr(status));
998                 correct = False;
999         }
1000
1001         if (fsize == sizeof(buf))
1002                 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1003                        (unsigned long)fsize);
1004         else {
1005                 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1006                        (unsigned long)fsize);
1007                 correct = False;
1008         }
1009
1010 #if 0
1011         /* ToDo - set allocation. JRA */
1012         if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1013                 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1014                 return False;
1015         }
1016         if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1017                                  NULL, NULL)) {
1018                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1019                 correct = False;
1020         }
1021         if (fsize != 0)
1022                 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1023 #endif
1024
1025         status = cli_close(cli1, fnum1);
1026         if (!NT_STATUS_IS_OK(status)) {
1027                 printf("close failed (%s)\n", nt_errstr(status));
1028                 correct = False;
1029         }
1030
1031         if (!torture_close_connection(cli1)) {
1032                 correct = False;
1033         }
1034         return correct;
1035 }
1036
1037 static bool run_readwritelarge(int dummy)
1038 {
1039         return run_readwritelarge_internal();
1040 }
1041
1042 static bool run_readwritelarge_signtest(int dummy)
1043 {
1044         bool ret;
1045         signing_state = SMB_SIGNING_REQUIRED;
1046         ret = run_readwritelarge_internal();
1047         signing_state = SMB_SIGNING_DEFAULT;
1048         return ret;
1049 }
1050
1051 int line_count = 0;
1052 int nbio_id;
1053
1054 #define ival(s) strtol(s, NULL, 0)
1055
1056 /* run a test that simulates an approximate netbench client load */
1057 static bool run_netbench(int client)
1058 {
1059         struct cli_state *cli;
1060         int i;
1061         char line[1024];
1062         char cname[20];
1063         FILE *f;
1064         const char *params[20];
1065         bool correct = True;
1066
1067         cli = current_cli;
1068
1069         nbio_id = client;
1070
1071         smbXcli_conn_set_sockopt(cli->conn, sockops);
1072
1073         nb_setup(cli);
1074
1075         slprintf(cname,sizeof(cname)-1, "client%d", client);
1076
1077         f = fopen(client_txt, "r");
1078
1079         if (!f) {
1080                 perror(client_txt);
1081                 return False;
1082         }
1083
1084         while (fgets(line, sizeof(line)-1, f)) {
1085                 char *saveptr;
1086                 line_count++;
1087
1088                 line[strlen(line)-1] = 0;
1089
1090                 /* printf("[%d] %s\n", line_count, line); */
1091
1092                 all_string_sub(line,"client1", cname, sizeof(line));
1093
1094                 /* parse the command parameters */
1095                 params[0] = strtok_r(line, " ", &saveptr);
1096                 i = 0;
1097                 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1098
1099                 params[i] = "";
1100
1101                 if (i < 2) continue;
1102
1103                 if (!strncmp(params[0],"SMB", 3)) {
1104                         printf("ERROR: You are using a dbench 1 load file\n");
1105                         exit(1);
1106                 }
1107
1108                 if (!strcmp(params[0],"NTCreateX")) {
1109                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
1110                                    ival(params[4]));
1111                 } else if (!strcmp(params[0],"Close")) {
1112                         nb_close(ival(params[1]));
1113                 } else if (!strcmp(params[0],"Rename")) {
1114                         nb_rename(params[1], params[2]);
1115                 } else if (!strcmp(params[0],"Unlink")) {
1116                         nb_unlink(params[1]);
1117                 } else if (!strcmp(params[0],"Deltree")) {
1118                         nb_deltree(params[1]);
1119                 } else if (!strcmp(params[0],"Rmdir")) {
1120                         nb_rmdir(params[1]);
1121                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1122                         nb_qpathinfo(params[1]);
1123                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1124                         nb_qfileinfo(ival(params[1]));
1125                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1126                         nb_qfsinfo(ival(params[1]));
1127                 } else if (!strcmp(params[0],"FIND_FIRST")) {
1128                         nb_findfirst(params[1]);
1129                 } else if (!strcmp(params[0],"WriteX")) {
1130                         nb_writex(ival(params[1]), 
1131                                   ival(params[2]), ival(params[3]), ival(params[4]));
1132                 } else if (!strcmp(params[0],"ReadX")) {
1133                         nb_readx(ival(params[1]), 
1134                                   ival(params[2]), ival(params[3]), ival(params[4]));
1135                 } else if (!strcmp(params[0],"Flush")) {
1136                         nb_flush(ival(params[1]));
1137                 } else {
1138                         printf("Unknown operation %s\n", params[0]);
1139                         exit(1);
1140                 }
1141         }
1142         fclose(f);
1143
1144         nb_cleanup();
1145
1146         if (!torture_close_connection(cli)) {
1147                 correct = False;
1148         }
1149
1150         return correct;
1151 }
1152
1153
1154 /* run a test that simulates an approximate netbench client load */
1155 static bool run_nbench(int dummy)
1156 {
1157         double t;
1158         bool correct = True;
1159
1160         nbio_shmem(torture_nprocs);
1161
1162         nbio_id = -1;
1163
1164         signal(SIGALRM, nb_alarm);
1165         alarm(1);
1166         t = create_procs(run_netbench, &correct);
1167         alarm(0);
1168
1169         printf("\nThroughput %g MB/sec\n", 
1170                1.0e-6 * nbio_total() / t);
1171         return correct;
1172 }
1173
1174
1175 /*
1176   This test checks for two things:
1177
1178   1) correct support for retaining locks over a close (ie. the server
1179      must not use posix semantics)
1180   2) support for lock timeouts
1181  */
1182 static bool run_locktest1(int dummy)
1183 {
1184         struct cli_state *cli1, *cli2;
1185         const char *fname = "\\lockt1.lck";
1186         uint16_t fnum1, fnum2, fnum3;
1187         time_t t1, t2;
1188         unsigned lock_timeout;
1189         NTSTATUS status;
1190
1191         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1192                 return False;
1193         }
1194         smbXcli_conn_set_sockopt(cli1->conn, sockops);
1195         smbXcli_conn_set_sockopt(cli2->conn, sockops);
1196
1197         printf("starting locktest1\n");
1198
1199         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1200
1201         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1202                           &fnum1);
1203         if (!NT_STATUS_IS_OK(status)) {
1204                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1205                 return False;
1206         }
1207
1208         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1209         if (!NT_STATUS_IS_OK(status)) {
1210                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1211                 return False;
1212         }
1213
1214         status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1215         if (!NT_STATUS_IS_OK(status)) {
1216                 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1217                 return False;
1218         }
1219
1220         status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
1221         if (!NT_STATUS_IS_OK(status)) {
1222                 printf("lock1 failed (%s)\n", nt_errstr(status));
1223                 return false;
1224         }
1225
1226         status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1227         if (NT_STATUS_IS_OK(status)) {
1228                 printf("lock2 succeeded! This is a locking bug\n");
1229                 return false;
1230         } else {
1231                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1232                                       NT_STATUS_LOCK_NOT_GRANTED)) {
1233                         return false;
1234                 }
1235         }
1236
1237         lock_timeout = (1 + (random() % 20));
1238         printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1239         t1 = time(NULL);
1240         status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
1241         if (NT_STATUS_IS_OK(status)) {
1242                 printf("lock3 succeeded! This is a locking bug\n");
1243                 return false;
1244         } else {
1245                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1246                                       NT_STATUS_FILE_LOCK_CONFLICT)) {
1247                         return false;
1248                 }
1249         }
1250         t2 = time(NULL);
1251
1252         if (ABS(t2 - t1) < lock_timeout-1) {
1253                 printf("error: This server appears not to support timed lock requests\n");
1254         }
1255
1256         printf("server slept for %u seconds for a %u second timeout\n",
1257                (unsigned int)(t2-t1), lock_timeout);
1258
1259         status = cli_close(cli1, fnum2);
1260         if (!NT_STATUS_IS_OK(status)) {
1261                 printf("close1 failed (%s)\n", nt_errstr(status));
1262                 return False;
1263         }
1264
1265         status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1266         if (NT_STATUS_IS_OK(status)) {
1267                 printf("lock4 succeeded! This is a locking bug\n");
1268                 return false;
1269         } else {
1270                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1271                                       NT_STATUS_FILE_LOCK_CONFLICT)) {
1272                         return false;
1273                 }
1274         }
1275
1276         status = cli_close(cli1, fnum1);
1277         if (!NT_STATUS_IS_OK(status)) {
1278                 printf("close2 failed (%s)\n", nt_errstr(status));
1279                 return False;
1280         }
1281
1282         status = cli_close(cli2, fnum3);
1283         if (!NT_STATUS_IS_OK(status)) {
1284                 printf("close3 failed (%s)\n", nt_errstr(status));
1285                 return False;
1286         }
1287
1288         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1289         if (!NT_STATUS_IS_OK(status)) {
1290                 printf("unlink failed (%s)\n", nt_errstr(status));
1291                 return False;
1292         }
1293
1294
1295         if (!torture_close_connection(cli1)) {
1296                 return False;
1297         }
1298
1299         if (!torture_close_connection(cli2)) {
1300                 return False;
1301         }
1302
1303         printf("Passed locktest1\n");
1304         return True;
1305 }
1306
1307 /*
1308   this checks to see if a secondary tconx can use open files from an
1309   earlier tconx
1310  */
1311 static bool run_tcon_test(int dummy)
1312 {
1313         static struct cli_state *cli;
1314         const char *fname = "\\tcontest.tmp";
1315         uint16 fnum1;
1316         uint16 cnum1, cnum2, cnum3;
1317         uint16 vuid1, vuid2;
1318         char buf[4];
1319         bool ret = True;
1320         NTSTATUS status;
1321
1322         memset(buf, '\0', sizeof(buf));
1323
1324         if (!torture_open_connection(&cli, 0)) {
1325                 return False;
1326         }
1327         smbXcli_conn_set_sockopt(cli->conn, sockops);
1328
1329         printf("starting tcontest\n");
1330
1331         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1332
1333         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1334         if (!NT_STATUS_IS_OK(status)) {
1335                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1336                 return False;
1337         }
1338
1339         cnum1 = cli_state_get_tid(cli);
1340         vuid1 = cli_state_get_uid(cli);
1341
1342         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1343         if (!NT_STATUS_IS_OK(status)) {
1344                 printf("initial write failed (%s)", nt_errstr(status));
1345                 return False;
1346         }
1347
1348         status = cli_tree_connect(cli, share, "?????",
1349                                   password, strlen(password)+1);
1350         if (!NT_STATUS_IS_OK(status)) {
1351                 printf("%s refused 2nd tree connect (%s)\n", host,
1352                        nt_errstr(status));
1353                 cli_shutdown(cli);
1354                 return False;
1355         }
1356
1357         cnum2 = cli_state_get_tid(cli);
1358         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1359         vuid2 = cli_state_get_uid(cli) + 1;
1360
1361         /* try a write with the wrong tid */
1362         cli_state_set_tid(cli, cnum2);
1363
1364         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1365         if (NT_STATUS_IS_OK(status)) {
1366                 printf("* server allows write with wrong TID\n");
1367                 ret = False;
1368         } else {
1369                 printf("server fails write with wrong TID : %s\n",
1370                        nt_errstr(status));
1371         }
1372
1373
1374         /* try a write with an invalid tid */
1375         cli_state_set_tid(cli, cnum3);
1376
1377         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1378         if (NT_STATUS_IS_OK(status)) {
1379                 printf("* server allows write with invalid TID\n");
1380                 ret = False;
1381         } else {
1382                 printf("server fails write with invalid TID : %s\n",
1383                        nt_errstr(status));
1384         }
1385
1386         /* try a write with an invalid vuid */
1387         cli_state_set_uid(cli, vuid2);
1388         cli_state_set_tid(cli, cnum1);
1389
1390         status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1391         if (NT_STATUS_IS_OK(status)) {
1392                 printf("* server allows write with invalid VUID\n");
1393                 ret = False;
1394         } else {
1395                 printf("server fails write with invalid VUID : %s\n",
1396                        nt_errstr(status));
1397         }
1398
1399         cli_state_set_tid(cli, cnum1);
1400         cli_state_set_uid(cli, vuid1);
1401
1402         status = cli_close(cli, fnum1);
1403         if (!NT_STATUS_IS_OK(status)) {
1404                 printf("close failed (%s)\n", nt_errstr(status));
1405                 return False;
1406         }
1407
1408         cli_state_set_tid(cli, cnum2);
1409
1410         status = cli_tdis(cli);
1411         if (!NT_STATUS_IS_OK(status)) {
1412                 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1413                 return False;
1414         }
1415
1416         cli_state_set_tid(cli, cnum1);
1417
1418         if (!torture_close_connection(cli)) {
1419                 return False;
1420         }
1421
1422         return ret;
1423 }
1424
1425
1426 /*
1427  checks for old style tcon support
1428  */
1429 static bool run_tcon2_test(int dummy)
1430 {
1431         static struct cli_state *cli;
1432         uint16 cnum, max_xmit;
1433         char *service;
1434         NTSTATUS status;
1435
1436         if (!torture_open_connection(&cli, 0)) {
1437                 return False;
1438         }
1439         smbXcli_conn_set_sockopt(cli->conn, sockops);
1440
1441         printf("starting tcon2 test\n");
1442
1443         if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1444                 return false;
1445         }
1446
1447         status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1448
1449         SAFE_FREE(service);
1450
1451         if (!NT_STATUS_IS_OK(status)) {
1452                 printf("tcon2 failed : %s\n", nt_errstr(status));
1453         } else {
1454                 printf("tcon OK : max_xmit=%d cnum=%d\n",
1455                        (int)max_xmit, (int)cnum);
1456         }
1457
1458         if (!torture_close_connection(cli)) {
1459                 return False;
1460         }
1461
1462         printf("Passed tcon2 test\n");
1463         return True;
1464 }
1465
1466 static bool tcon_devtest(struct cli_state *cli,
1467                          const char *myshare, const char *devtype,
1468                          const char *return_devtype,
1469                          NTSTATUS expected_error)
1470 {
1471         NTSTATUS status;
1472         bool ret;
1473
1474         status = cli_tree_connect(cli, myshare, devtype,
1475                                   password, strlen(password)+1);
1476
1477         if (NT_STATUS_IS_OK(expected_error)) {
1478                 if (NT_STATUS_IS_OK(status)) {
1479                         if (strcmp(cli->dev, return_devtype) == 0) {
1480                                 ret = True;
1481                         } else { 
1482                                 printf("tconX to share %s with type %s "
1483                                        "succeeded but returned the wrong "
1484                                        "device type (got [%s] but should have got [%s])\n",
1485                                        myshare, devtype, cli->dev, return_devtype);
1486                                 ret = False;
1487                         }
1488                 } else {
1489                         printf("tconX to share %s with type %s "
1490                                "should have succeeded but failed\n",
1491                                myshare, devtype);
1492                         ret = False;
1493                 }
1494                 cli_tdis(cli);
1495         } else {
1496                 if (NT_STATUS_IS_OK(status)) {
1497                         printf("tconx to share %s with type %s "
1498                                "should have failed but succeeded\n",
1499                                myshare, devtype);
1500                         ret = False;
1501                 } else {
1502                         if (NT_STATUS_EQUAL(status, expected_error)) {
1503                                 ret = True;
1504                         } else {
1505                                 printf("Returned unexpected error\n");
1506                                 ret = False;
1507                         }
1508                 }
1509         }
1510         return ret;
1511 }
1512
1513 /*
1514  checks for correct tconX support
1515  */
1516 static bool run_tcon_devtype_test(int dummy)
1517 {
1518         static struct cli_state *cli1 = NULL;
1519         int flags = 0;
1520         NTSTATUS status;
1521         bool ret = True;
1522
1523         status = cli_full_connection(&cli1, myname,
1524                                      host, NULL, port_to_use,
1525                                      NULL, NULL,
1526                                      username, workgroup,
1527                                      password, flags, signing_state);
1528
1529         if (!NT_STATUS_IS_OK(status)) {
1530                 printf("could not open connection\n");
1531                 return False;
1532         }
1533
1534         if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1535                 ret = False;
1536
1537         if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1538                 ret = False;
1539
1540         if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1541                 ret = False;
1542
1543         if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1544                 ret = False;
1545
1546         if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1547                 ret = False;
1548
1549         if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1550                 ret = False;
1551
1552         if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1553                 ret = False;
1554
1555         if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1556                 ret = False;
1557
1558         if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1559                 ret = False;
1560
1561         if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1562                 ret = False;
1563
1564         cli_shutdown(cli1);
1565
1566         if (ret)
1567                 printf("Passed tcondevtest\n");
1568
1569         return ret;
1570 }
1571
1572
1573 /*
1574   This test checks that 
1575
1576   1) the server supports multiple locking contexts on the one SMB
1577   connection, distinguished by PID.  
1578
1579   2) the server correctly fails overlapping locks made by the same PID (this
1580      goes against POSIX behaviour, which is why it is tricky to implement)
1581
1582   3) the server denies unlock requests by an incorrect client PID
1583 */
1584 static bool run_locktest2(int dummy)
1585 {
1586         static struct cli_state *cli;
1587         const char *fname = "\\lockt2.lck";
1588         uint16_t fnum1, fnum2, fnum3;
1589         bool correct = True;
1590         NTSTATUS status;
1591
1592         if (!torture_open_connection(&cli, 0)) {
1593                 return False;
1594         }
1595
1596         smbXcli_conn_set_sockopt(cli->conn, sockops);
1597
1598         printf("starting locktest2\n");
1599
1600         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1601
1602         cli_setpid(cli, 1);
1603
1604         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1605         if (!NT_STATUS_IS_OK(status)) {
1606                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1607                 return False;
1608         }
1609
1610         status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1611         if (!NT_STATUS_IS_OK(status)) {
1612                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1613                 return False;
1614         }
1615
1616         cli_setpid(cli, 2);
1617
1618         status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1619         if (!NT_STATUS_IS_OK(status)) {
1620                 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1621                 return False;
1622         }
1623
1624         cli_setpid(cli, 1);
1625
1626         status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1627         if (!NT_STATUS_IS_OK(status)) {
1628                 printf("lock1 failed (%s)\n", nt_errstr(status));
1629                 return false;
1630         }
1631
1632         status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1633         if (NT_STATUS_IS_OK(status)) {
1634                 printf("WRITE lock1 succeeded! This is a locking bug\n");
1635                 correct = false;
1636         } else {
1637                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1638                                       NT_STATUS_LOCK_NOT_GRANTED)) {
1639                         return false;
1640                 }
1641         }
1642
1643         status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
1644         if (NT_STATUS_IS_OK(status)) {
1645                 printf("WRITE lock2 succeeded! This is a locking bug\n");
1646                 correct = false;
1647         } else {
1648                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1649                                       NT_STATUS_LOCK_NOT_GRANTED)) {
1650                         return false;
1651                 }
1652         }
1653
1654         status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1655         if (NT_STATUS_IS_OK(status)) {
1656                 printf("READ lock2 succeeded! This is a locking bug\n");
1657                 correct = false;
1658         } else {
1659                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1660                                  NT_STATUS_FILE_LOCK_CONFLICT)) {
1661                         return false;
1662                 }
1663         }
1664
1665         status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1666         if (!NT_STATUS_IS_OK(status)) {
1667                 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1668         }
1669         cli_setpid(cli, 2);
1670         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1671                 printf("unlock at 100 succeeded! This is a locking bug\n");
1672                 correct = False;
1673         }
1674
1675         status = cli_unlock(cli, fnum1, 0, 4);
1676         if (NT_STATUS_IS_OK(status)) {
1677                 printf("unlock1 succeeded! This is a locking bug\n");
1678                 correct = false;
1679         } else {
1680                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1681                                       NT_STATUS_RANGE_NOT_LOCKED)) {
1682                         return false;
1683                 }
1684         }
1685
1686         status = cli_unlock(cli, fnum1, 0, 8);
1687         if (NT_STATUS_IS_OK(status)) {
1688                 printf("unlock2 succeeded! This is a locking bug\n");
1689                 correct = false;
1690         } else {
1691                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1692                                       NT_STATUS_RANGE_NOT_LOCKED)) {
1693                         return false;
1694                 }
1695         }
1696
1697         status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1698         if (NT_STATUS_IS_OK(status)) {
1699                 printf("lock3 succeeded! This is a locking bug\n");
1700                 correct = false;
1701         } else {
1702                 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1703                                       NT_STATUS_LOCK_NOT_GRANTED)) {
1704                         return false;
1705                 }
1706         }
1707
1708         cli_setpid(cli, 1);
1709
1710         status = cli_close(cli, fnum1);
1711         if (!NT_STATUS_IS_OK(status)) {
1712                 printf("close1 failed (%s)\n", nt_errstr(status));
1713                 return False;
1714         }
1715
1716         status = cli_close(cli, fnum2);
1717         if (!NT_STATUS_IS_OK(status)) {
1718                 printf("close2 failed (%s)\n", nt_errstr(status));
1719                 return False;
1720         }
1721
1722         status = cli_close(cli, fnum3);
1723         if (!NT_STATUS_IS_OK(status)) {
1724                 printf("close3 failed (%s)\n", nt_errstr(status));
1725                 return False;
1726         }
1727
1728         if (!torture_close_connection(cli)) {
1729                 correct = False;
1730         }
1731
1732         printf("locktest2 finished\n");
1733
1734         return correct;
1735 }
1736
1737
1738 /*
1739   This test checks that 
1740
1741   1) the server supports the full offset range in lock requests
1742 */
1743 static bool run_locktest3(int dummy)
1744 {
1745         static struct cli_state *cli1, *cli2;
1746         const char *fname = "\\lockt3.lck";
1747         uint16_t fnum1, fnum2;
1748         int i;
1749         uint32 offset;
1750         bool correct = True;
1751         NTSTATUS status;
1752
1753 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1754
1755         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1756                 return False;
1757         }
1758         smbXcli_conn_set_sockopt(cli1->conn, sockops);
1759         smbXcli_conn_set_sockopt(cli2->conn, sockops);
1760
1761         printf("starting locktest3\n");
1762
1763         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1764
1765         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1766                          &fnum1);
1767         if (!NT_STATUS_IS_OK(status)) {
1768                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1769                 return False;
1770         }
1771
1772         status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1773         if (!NT_STATUS_IS_OK(status)) {
1774                 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1775                 return False;
1776         }
1777
1778         for (offset=i=0;i<torture_numops;i++) {
1779                 NEXT_OFFSET;
1780
1781                 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1782                 if (!NT_STATUS_IS_OK(status)) {
1783                         printf("lock1 %d failed (%s)\n", 
1784                                i,
1785                                nt_errstr(status));
1786                         return False;
1787                 }
1788
1789                 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1790                 if (!NT_STATUS_IS_OK(status)) {
1791                         printf("lock2 %d failed (%s)\n", 
1792                                i,
1793                                nt_errstr(status));
1794                         return False;
1795                 }
1796         }
1797
1798         for (offset=i=0;i<torture_numops;i++) {
1799                 NEXT_OFFSET;
1800
1801                 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
1802                 if (NT_STATUS_IS_OK(status)) {
1803                         printf("error: lock1 %d succeeded!\n", i);
1804                         return False;
1805                 }
1806
1807                 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
1808                 if (NT_STATUS_IS_OK(status)) {
1809                         printf("error: lock2 %d succeeded!\n", i);
1810                         return False;
1811                 }
1812
1813                 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1814                 if (NT_STATUS_IS_OK(status)) {
1815                         printf("error: lock3 %d succeeded!\n", i);
1816                         return False;
1817                 }
1818
1819                 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1820                 if (NT_STATUS_IS_OK(status)) {
1821                         printf("error: lock4 %d succeeded!\n", i);
1822                         return False;
1823                 }
1824         }
1825
1826         for (offset=i=0;i<torture_numops;i++) {
1827                 NEXT_OFFSET;
1828
1829                 status = cli_unlock(cli1, fnum1, offset-1, 1);
1830                 if (!NT_STATUS_IS_OK(status)) {
1831                         printf("unlock1 %d failed (%s)\n", 
1832                                i,
1833                                nt_errstr(status));
1834                         return False;
1835                 }
1836
1837                 status = cli_unlock(cli2, fnum2, offset-2, 1);
1838                 if (!NT_STATUS_IS_OK(status)) {
1839                         printf("unlock2 %d failed (%s)\n", 
1840                                i,
1841                                nt_errstr(status));
1842                         return False;
1843                 }
1844         }
1845
1846         status = cli_close(cli1, fnum1);
1847         if (!NT_STATUS_IS_OK(status)) {
1848                 printf("close1 failed (%s)\n", nt_errstr(status));
1849                 return False;
1850         }
1851
1852         status = cli_close(cli2, fnum2);
1853         if (!NT_STATUS_IS_OK(status)) {
1854                 printf("close2 failed (%s)\n", nt_errstr(status));
1855                 return False;
1856         }
1857
1858         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1859         if (!NT_STATUS_IS_OK(status)) {
1860                 printf("unlink failed (%s)\n", nt_errstr(status));
1861                 return False;
1862         }
1863
1864         if (!torture_close_connection(cli1)) {
1865                 correct = False;
1866         }
1867
1868         if (!torture_close_connection(cli2)) {
1869                 correct = False;
1870         }
1871
1872         printf("finished locktest3\n");
1873
1874         return correct;
1875 }
1876
1877 static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
1878                            char *buf, off_t offset, size_t size,
1879                            size_t *nread, size_t expect)
1880 {
1881         NTSTATUS status;
1882         size_t l_nread;
1883
1884         status = cli_read(cli, fnum, buf, offset, size, &l_nread);
1885
1886         if(!NT_STATUS_IS_OK(status)) {
1887                 return false;
1888         } else if (l_nread != expect) {
1889                 return false;
1890         }
1891
1892         if (nread) {
1893                 *nread = l_nread;
1894         }
1895
1896         return true;
1897 }
1898
1899 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1900         printf("** "); correct = False; \
1901         }
1902
1903 /*
1904   looks at overlapping locks
1905 */
1906 static bool run_locktest4(int dummy)
1907 {
1908         static struct cli_state *cli1, *cli2;
1909         const char *fname = "\\lockt4.lck";
1910         uint16_t fnum1, fnum2, f;
1911         bool ret;
1912         char buf[1000];
1913         bool correct = True;
1914         NTSTATUS status;
1915
1916         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1917                 return False;
1918         }
1919
1920         smbXcli_conn_set_sockopt(cli1->conn, sockops);
1921         smbXcli_conn_set_sockopt(cli2->conn, sockops);
1922
1923         printf("starting locktest4\n");
1924
1925         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1926
1927         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1928         cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1929
1930         memset(buf, 0, sizeof(buf));
1931
1932         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1933                               NULL);
1934         if (!NT_STATUS_IS_OK(status)) {
1935                 printf("Failed to create file: %s\n", nt_errstr(status));
1936                 correct = False;
1937                 goto fail;
1938         }
1939
1940         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1941               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
1942         EXPECTED(ret, False);
1943         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1944
1945         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
1946               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
1947         EXPECTED(ret, True);
1948         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1949
1950         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1951               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
1952         EXPECTED(ret, False);
1953         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1954
1955         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
1956               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
1957         EXPECTED(ret, True);
1958         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1959
1960         ret = (cli_setpid(cli1, 1),
1961               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1962               (cli_setpid(cli1, 2),
1963               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
1964         EXPECTED(ret, False);
1965         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1966
1967         ret = (cli_setpid(cli1, 1),
1968               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
1969               (cli_setpid(cli1, 2),
1970               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
1971         EXPECTED(ret, True);
1972         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1973
1974         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
1975               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
1976         EXPECTED(ret, True);
1977         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1978
1979         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1980               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
1981         EXPECTED(ret, False);
1982         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1983
1984         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
1985               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
1986         EXPECTED(ret, False);
1987         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1988
1989         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
1990               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
1991         EXPECTED(ret, True);
1992         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1993
1994         ret = (cli_setpid(cli1, 1),
1995              NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
1996              (cli_setpid(cli1, 2),
1997              NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
1998         EXPECTED(ret, False);
1999         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2000
2001         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
2002               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
2003               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
2004         EXPECTED(ret, False);
2005         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
2006
2007
2008         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
2009               test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
2010         EXPECTED(ret, False);
2011         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
2012
2013         status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2014         ret = NT_STATUS_IS_OK(status);
2015         if (ret) {
2016                 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
2017                                       NULL);
2018                 ret = NT_STATUS_IS_OK(status);
2019         }
2020         EXPECTED(ret, False);
2021         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2022
2023
2024         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2025               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2026               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2027               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2028         EXPECTED(ret, True);
2029         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2030
2031
2032         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
2033               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
2034               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2035               test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
2036               !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2037                                              150, 4, NULL))) &&
2038               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2039         EXPECTED(ret, True);
2040         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2041
2042         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
2043               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2044               NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2045                                            160, 4, NULL)) &&
2046               test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
2047         EXPECTED(ret, True);
2048         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2049
2050         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
2051               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2052               NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2053                                            170, 4, NULL)) &&
2054               test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
2055         EXPECTED(ret, True);
2056         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2057
2058         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
2059               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
2060               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2061               !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2062                                             190, 4, NULL)) &&
2063               test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
2064         EXPECTED(ret, True);
2065         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2066
2067         cli_close(cli1, fnum1);
2068         cli_close(cli2, fnum2);
2069         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2070         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
2071         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2072               NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
2073               NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2074               NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2075               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
2076         cli_close(cli1, f);
2077         cli_close(cli1, fnum1);
2078         EXPECTED(ret, True);
2079         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2080
2081  fail:
2082         cli_close(cli1, fnum1);
2083         cli_close(cli2, fnum2);
2084         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2085         torture_close_connection(cli1);
2086         torture_close_connection(cli2);
2087
2088         printf("finished locktest4\n");
2089         return correct;
2090 }
2091
2092 /*
2093   looks at lock upgrade/downgrade.
2094 */
2095 static bool run_locktest5(int dummy)
2096 {
2097         static struct cli_state *cli1, *cli2;
2098         const char *fname = "\\lockt5.lck";
2099         uint16_t fnum1, fnum2, fnum3;
2100         bool ret;
2101         char buf[1000];
2102         bool correct = True;
2103         NTSTATUS status;
2104
2105         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2106                 return False;
2107         }
2108
2109         smbXcli_conn_set_sockopt(cli1->conn, sockops);
2110         smbXcli_conn_set_sockopt(cli2->conn, sockops);
2111
2112         printf("starting locktest5\n");
2113
2114         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2115
2116         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2117         cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2118         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2119
2120         memset(buf, 0, sizeof(buf));
2121
2122         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2123                               NULL);
2124         if (!NT_STATUS_IS_OK(status)) {
2125                 printf("Failed to create file: %s\n", nt_errstr(status));
2126                 correct = False;
2127                 goto fail;
2128         }
2129
2130         /* Check for NT bug... */
2131         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2132               NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
2133         cli_close(cli1, fnum1);
2134         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2135         status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2136         ret = NT_STATUS_IS_OK(status);
2137         EXPECTED(ret, True);
2138         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2139         cli_close(cli1, fnum1);
2140         cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2141         cli_unlock(cli1, fnum3, 0, 1);
2142
2143         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
2144               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
2145         EXPECTED(ret, True);
2146         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2147
2148         status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
2149         ret = NT_STATUS_IS_OK(status);
2150         EXPECTED(ret, False);
2151
2152         printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2153
2154         /* Unlock the process 2 lock. */
2155         cli_unlock(cli2, fnum2, 0, 4);
2156
2157         status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
2158         ret = NT_STATUS_IS_OK(status);
2159         EXPECTED(ret, False);
2160
2161         printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2162
2163         /* Unlock the process 1 fnum3 lock. */
2164         cli_unlock(cli1, fnum3, 0, 4);
2165
2166         /* Stack 2 more locks here. */
2167         ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
2168               NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
2169
2170         EXPECTED(ret, True);
2171         printf("the same process %s stack read locks\n", ret?"can":"cannot");
2172
2173         /* Unlock the first process lock, then check this was the WRITE lock that was
2174                 removed. */
2175
2176         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2177               NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
2178
2179         EXPECTED(ret, True);
2180         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2181
2182         /* Unlock the process 2 lock. */
2183         cli_unlock(cli2, fnum2, 0, 4);
2184
2185         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2186
2187         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2188                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2189                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2190
2191         EXPECTED(ret, True);
2192         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
2193
2194         /* Ensure the next unlock fails. */
2195         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2196         EXPECTED(ret, False);
2197         printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
2198
2199         /* Ensure connection 2 can get a write lock. */
2200         status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2201         ret = NT_STATUS_IS_OK(status);
2202         EXPECTED(ret, True);
2203
2204         printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2205
2206
2207  fail:
2208         cli_close(cli1, fnum1);
2209         cli_close(cli2, fnum2);
2210         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2211         if (!torture_close_connection(cli1)) {
2212                 correct = False;
2213         }
2214         if (!torture_close_connection(cli2)) {
2215                 correct = False;
2216         }
2217
2218         printf("finished locktest5\n");
2219
2220         return correct;
2221 }
2222
2223 /*
2224   tries the unusual lockingX locktype bits
2225 */
2226 static bool run_locktest6(int dummy)
2227 {
2228         static struct cli_state *cli;
2229         const char *fname[1] = { "\\lock6.txt" };
2230         int i;
2231         uint16_t fnum;
2232         NTSTATUS status;
2233
2234         if (!torture_open_connection(&cli, 0)) {
2235                 return False;
2236         }
2237
2238         smbXcli_conn_set_sockopt(cli->conn, sockops);
2239
2240         printf("starting locktest6\n");
2241
2242         for (i=0;i<1;i++) {
2243                 printf("Testing %s\n", fname[i]);
2244
2245                 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2246
2247                 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2248                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2249                 cli_close(cli, fnum);
2250                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2251
2252                 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2253                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2254                 cli_close(cli, fnum);
2255                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2256
2257                 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2258         }
2259
2260         torture_close_connection(cli);
2261
2262         printf("finished locktest6\n");
2263         return True;
2264 }
2265
2266 static bool run_locktest7(int dummy)
2267 {
2268         struct cli_state *cli1;
2269         const char *fname = "\\lockt7.lck";
2270         uint16_t fnum1;
2271         char buf[200];
2272         bool correct = False;
2273         size_t nread;
2274         NTSTATUS status;
2275
2276         if (!torture_open_connection(&cli1, 0)) {
2277                 return False;
2278         }
2279
2280         smbXcli_conn_set_sockopt(cli1->conn, sockops);
2281
2282         printf("starting locktest7\n");
2283
2284         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2285
2286         cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2287
2288         memset(buf, 0, sizeof(buf));
2289
2290         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2291                               NULL);
2292         if (!NT_STATUS_IS_OK(status)) {
2293                 printf("Failed to create file: %s\n", nt_errstr(status));
2294                 goto fail;
2295         }
2296
2297         cli_setpid(cli1, 1);
2298
2299         status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2300         if (!NT_STATUS_IS_OK(status)) {
2301                 printf("Unable to apply read lock on range 130:4, "
2302                        "error was %s\n", nt_errstr(status));
2303                 goto fail;
2304         } else {
2305                 printf("pid1 successfully locked range 130:4 for READ\n");
2306         }
2307
2308         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2309         if (!NT_STATUS_IS_OK(status)) {
2310                 printf("pid1 unable to read the range 130:4, error was %s\n",
2311                       nt_errstr(status));
2312                 goto fail;
2313         } else if (nread != 4) {
2314                 printf("pid1 unable to read the range 130:4, "
2315                        "recv %ld req %d\n", (unsigned long)nread, 4);
2316                 goto fail;
2317         } else {
2318                 printf("pid1 successfully read the range 130:4\n");
2319         }
2320
2321         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2322         if (!NT_STATUS_IS_OK(status)) {
2323                 printf("pid1 unable to write to the range 130:4, error was "
2324                        "%s\n", nt_errstr(status));
2325                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2326                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2327                         goto fail;
2328                 }
2329         } else {
2330                 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2331                 goto fail;
2332         }
2333
2334         cli_setpid(cli1, 2);
2335
2336         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2337         if (!NT_STATUS_IS_OK(status)) {
2338                 printf("pid2 unable to read the range 130:4, error was %s\n",
2339                       nt_errstr(status));
2340                 goto fail;
2341         } else if (nread != 4) {
2342                 printf("pid2 unable to read the range 130:4, "
2343                        "recv %ld req %d\n", (unsigned long)nread, 4);
2344                 goto fail;
2345         } else {
2346                 printf("pid2 successfully read the range 130:4\n");
2347         }
2348
2349         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2350         if (!NT_STATUS_IS_OK(status)) {
2351                 printf("pid2 unable to write to the range 130:4, error was "
2352                        "%s\n", nt_errstr(status));
2353                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2354                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2355                         goto fail;
2356                 }
2357         } else {
2358                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2359                 goto fail;
2360         }
2361
2362         cli_setpid(cli1, 1);
2363         cli_unlock(cli1, fnum1, 130, 4);
2364
2365         status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
2366         if (!NT_STATUS_IS_OK(status)) {
2367                 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
2368                 goto fail;
2369         } else {
2370                 printf("pid1 successfully locked range 130:4 for WRITE\n");
2371         }
2372
2373         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2374         if (!NT_STATUS_IS_OK(status)) {
2375                 printf("pid1 unable to read the range 130:4, error was %s\n",
2376                       nt_errstr(status));
2377                 goto fail;
2378         } else if (nread != 4) {
2379                 printf("pid1 unable to read the range 130:4, "
2380                        "recv %ld req %d\n", (unsigned long)nread, 4);
2381                 goto fail;
2382         } else {
2383                 printf("pid1 successfully read the range 130:4\n");
2384         }
2385
2386         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2387         if (!NT_STATUS_IS_OK(status)) {
2388                 printf("pid1 unable to write to the range 130:4, error was "
2389                        "%s\n", nt_errstr(status));
2390                 goto fail;
2391         } else {
2392                 printf("pid1 successfully wrote to the range 130:4\n");
2393         }
2394
2395         cli_setpid(cli1, 2);
2396
2397         status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2398         if (!NT_STATUS_IS_OK(status)) {
2399                 printf("pid2 unable to read the range 130:4, error was "
2400                        "%s\n", nt_errstr(status));
2401                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2402                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2403                         goto fail;
2404                 }
2405         } else {
2406                 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2407                        (unsigned long)nread);
2408                 goto fail;
2409         }
2410
2411         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2412         if (!NT_STATUS_IS_OK(status)) {
2413                 printf("pid2 unable to write to the range 130:4, error was "
2414                        "%s\n", nt_errstr(status));
2415                 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2416                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2417                         goto fail;
2418                 }
2419         } else {
2420                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2421                 goto fail;
2422         }
2423
2424         cli_unlock(cli1, fnum1, 130, 0);
2425         correct = True;
2426
2427 fail:
2428         cli_close(cli1, fnum1);
2429         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2430         torture_close_connection(cli1);
2431
2432         printf("finished locktest7\n");
2433         return correct;
2434 }
2435
2436 /*
2437  * This demonstrates a problem with our use of GPFS share modes: A file
2438  * descriptor sitting in the pending close queue holding a GPFS share mode
2439  * blocks opening a file another time. Happens with Word 2007 temp files.
2440  * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2441  * open is denied with NT_STATUS_SHARING_VIOLATION.
2442  */
2443
2444 static bool run_locktest8(int dummy)
2445 {
2446         struct cli_state *cli1;
2447         const char *fname = "\\lockt8.lck";
2448         uint16_t fnum1, fnum2;
2449         char buf[200];
2450         bool correct = False;
2451         NTSTATUS status;
2452
2453         if (!torture_open_connection(&cli1, 0)) {
2454                 return False;
2455         }
2456
2457         smbXcli_conn_set_sockopt(cli1->conn, sockops);
2458
2459         printf("starting locktest8\n");
2460
2461         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2462
2463         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2464                           &fnum1);
2465         if (!NT_STATUS_IS_OK(status)) {
2466                 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2467                 return false;
2468         }
2469
2470         memset(buf, 0, sizeof(buf));
2471
2472         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2473         if (!NT_STATUS_IS_OK(status)) {
2474                 d_fprintf(stderr, "cli_openx second time returned %s\n",
2475                           nt_errstr(status));
2476                 goto fail;
2477         }
2478
2479         status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
2480         if (!NT_STATUS_IS_OK(status)) {
2481                 printf("Unable to apply read lock on range 1:1, error was "
2482                        "%s\n", nt_errstr(status));
2483                 goto fail;
2484         }
2485
2486         status = cli_close(cli1, fnum1);
2487         if (!NT_STATUS_IS_OK(status)) {
2488                 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2489                 goto fail;
2490         }
2491
2492         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2493         if (!NT_STATUS_IS_OK(status)) {
2494                 d_fprintf(stderr, "cli_openx third time returned %s\n",
2495                           nt_errstr(status));
2496                 goto fail;
2497         }
2498
2499         correct = true;
2500
2501 fail:
2502         cli_close(cli1, fnum1);
2503         cli_close(cli1, fnum2);
2504         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2505         torture_close_connection(cli1);
2506
2507         printf("finished locktest8\n");
2508         return correct;
2509 }
2510
2511 /*
2512  * This test is designed to be run in conjunction with
2513  * external NFS or POSIX locks taken in the filesystem.
2514  * It checks that the smbd server will block until the
2515  * lock is released and then acquire it. JRA.
2516  */
2517
2518 static bool got_alarm;
2519 static struct cli_state *alarm_cli;
2520
2521 static void alarm_handler(int dummy)
2522 {
2523         got_alarm = True;
2524 }
2525
2526 static void alarm_handler_parent(int dummy)
2527 {
2528         smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_OK);
2529 }
2530
2531 static void do_local_lock(int read_fd, int write_fd)
2532 {
2533         int fd;
2534         char c = '\0';
2535         struct flock lock;
2536         const char *local_pathname = NULL;
2537         int ret;
2538
2539         local_pathname = talloc_asprintf(talloc_tos(),
2540                         "%s/lockt9.lck", local_path);
2541         if (!local_pathname) {
2542                 printf("child: alloc fail\n");
2543                 exit(1);
2544         }
2545
2546         unlink(local_pathname);
2547         fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2548         if (fd == -1) {
2549                 printf("child: open of %s failed %s.\n",
2550                         local_pathname, strerror(errno));
2551                 exit(1);
2552         }
2553
2554         /* Now take a fcntl lock. */
2555         lock.l_type = F_WRLCK;
2556         lock.l_whence = SEEK_SET;
2557         lock.l_start = 0;
2558         lock.l_len = 4;
2559         lock.l_pid = getpid();
2560
2561         ret = fcntl(fd,F_SETLK,&lock);
2562         if (ret == -1) {
2563                 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2564                         local_pathname, strerror(errno));
2565                 exit(1);
2566         } else {
2567                 printf("child: got lock 0:4 on file %s.\n",
2568                         local_pathname );
2569                 fflush(stdout);
2570         }
2571
2572         CatchSignal(SIGALRM, alarm_handler);
2573         alarm(5);
2574         /* Signal the parent. */
2575         if (write(write_fd, &c, 1) != 1) {
2576                 printf("child: start signal fail %s.\n",
2577                         strerror(errno));
2578                 exit(1);
2579         }
2580         alarm(0);
2581
2582         alarm(10);
2583         /* Wait for the parent to be ready. */
2584         if (read(read_fd, &c, 1) != 1) {
2585                 printf("child: reply signal fail %s.\n",
2586                         strerror(errno));
2587                 exit(1);
2588         }
2589         alarm(0);
2590
2591         sleep(5);
2592         close(fd);
2593         printf("child: released lock 0:4 on file %s.\n",
2594                 local_pathname );
2595         fflush(stdout);
2596         exit(0);
2597 }
2598
2599 static bool run_locktest9(int dummy)
2600 {
2601         struct cli_state *cli1;
2602         const char *fname = "\\lockt9.lck";
2603         uint16_t fnum;
2604         bool correct = False;
2605         int pipe_in[2], pipe_out[2];
2606         pid_t child_pid;
2607         char c = '\0';
2608         int ret;
2609         struct timeval start;
2610         double seconds;
2611         NTSTATUS status;
2612
2613         printf("starting locktest9\n");
2614
2615         if (local_path == NULL) {
2616                 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2617                 return false;
2618         }
2619
2620         if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2621                 return false;
2622         }
2623
2624         child_pid = fork();
2625         if (child_pid == -1) {
2626                 return false;
2627         }
2628
2629         if (child_pid == 0) {
2630                 /* Child. */
2631                 do_local_lock(pipe_out[0], pipe_in[1]);
2632                 exit(0);
2633         }
2634
2635         close(pipe_out[0]);
2636         close(pipe_in[1]);
2637         pipe_out[0] = -1;
2638         pipe_in[1] = -1;
2639
2640         /* Parent. */
2641         ret = read(pipe_in[0], &c, 1);
2642         if (ret != 1) {
2643                 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2644                         strerror(errno));
2645                 return false;
2646         }
2647
2648         if (!torture_open_connection(&cli1, 0)) {
2649                 return false;
2650         }
2651
2652         smbXcli_conn_set_sockopt(cli1->conn, sockops);
2653
2654         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE,
2655                           &fnum);
2656         if (!NT_STATUS_IS_OK(status)) {
2657                 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2658                 return false;
2659         }
2660
2661         /* Ensure the child has the lock. */
2662         status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
2663         if (NT_STATUS_IS_OK(status)) {
2664                 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2665                 goto fail;
2666         } else {
2667                 d_printf("Child has the lock.\n");
2668         }
2669
2670         /* Tell the child to wait 5 seconds then exit. */
2671         ret = write(pipe_out[1], &c, 1);
2672         if (ret != 1) {
2673                 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2674                         strerror(errno));
2675                 goto fail;
2676         }
2677
2678         /* Wait 20 seconds for the lock. */
2679         alarm_cli = cli1;
2680         CatchSignal(SIGALRM, alarm_handler_parent);
2681         alarm(20);
2682
2683         start = timeval_current();
2684
2685         status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK);
2686         if (!NT_STATUS_IS_OK(status)) {
2687                 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2688                        "%s\n", nt_errstr(status));
2689                 goto fail_nofd;
2690         }
2691         alarm(0);
2692
2693         seconds = timeval_elapsed(&start);
2694
2695         printf("Parent got the lock after %.2f seconds.\n",
2696                 seconds);
2697
2698         status = cli_close(cli1, fnum);
2699         if (!NT_STATUS_IS_OK(status)) {
2700                 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2701                 goto fail;
2702         }
2703
2704         correct = true;
2705
2706 fail:
2707         cli_close(cli1, fnum);
2708         torture_close_connection(cli1);
2709
2710 fail_nofd:
2711
2712         printf("finished locktest9\n");
2713         return correct;
2714 }
2715
2716 /*
2717 test whether fnums and tids open on one VC are available on another (a major
2718 security hole)
2719 */
2720 static bool run_fdpasstest(int dummy)
2721 {
2722         struct cli_state *cli1, *cli2;
2723         const char *fname = "\\fdpass.tst";
2724         uint16_t fnum1;
2725         char buf[1024];
2726         NTSTATUS status;
2727
2728         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2729                 return False;
2730         }
2731         smbXcli_conn_set_sockopt(cli1->conn, sockops);
2732         smbXcli_conn_set_sockopt(cli2->conn, sockops);
2733
2734         printf("starting fdpasstest\n");
2735
2736         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2737
2738         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2739                           &fnum1);
2740         if (!NT_STATUS_IS_OK(status)) {
2741                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2742                 return False;
2743         }
2744
2745         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2746                               13, NULL);
2747         if (!NT_STATUS_IS_OK(status)) {
2748                 printf("write failed (%s)\n", nt_errstr(status));
2749                 return False;
2750         }
2751
2752         cli_state_set_uid(cli2, cli_state_get_uid(cli1));
2753         cli_state_set_tid(cli2, cli_state_get_tid(cli1));
2754         cli_setpid(cli2, cli_getpid(cli1));
2755
2756         if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
2757                 printf("read succeeded! nasty security hole [%s]\n", buf);
2758                 return false;
2759         }
2760
2761         cli_close(cli1, fnum1);
2762         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2763
2764         torture_close_connection(cli1);
2765         torture_close_connection(cli2);
2766
2767         printf("finished fdpasstest\n");
2768         return True;
2769 }
2770
2771 static bool run_fdsesstest(int dummy)
2772 {
2773         struct cli_state *cli;
2774         uint16 new_vuid;
2775         uint16 saved_vuid;
2776         uint16 new_cnum;
2777         uint16 saved_cnum;
2778         const char *fname = "\\fdsess.tst";
2779         const char *fname1 = "\\fdsess1.tst";
2780         uint16_t fnum1;
2781         uint16_t fnum2;
2782         char buf[1024];
2783         bool ret = True;
2784         NTSTATUS status;
2785
2786         if (!torture_open_connection(&cli, 0))
2787                 return False;
2788         smbXcli_conn_set_sockopt(cli->conn, sockops);
2789
2790         if (!torture_cli_session_setup2(cli, &new_vuid))
2791                 return False;
2792
2793         saved_cnum = cli_state_get_tid(cli);
2794         if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", "", 1)))
2795                 return False;
2796         new_cnum = cli_state_get_tid(cli);
2797         cli_state_set_tid(cli, saved_cnum);
2798
2799         printf("starting fdsesstest\n");
2800
2801         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2802         cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2803
2804         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2805         if (!NT_STATUS_IS_OK(status)) {
2806                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2807                 return False;
2808         }
2809
2810         status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2811                               NULL);
2812         if (!NT_STATUS_IS_OK(status)) {
2813                 printf("write failed (%s)\n", nt_errstr(status));
2814                 return False;
2815         }
2816
2817         saved_vuid = cli_state_get_uid(cli);
2818         cli_state_set_uid(cli, new_vuid);
2819
2820         if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2821                 printf("read succeeded with different vuid! "
2822                        "nasty security hole [%s]\n", buf);
2823                 ret = false;
2824         }
2825         /* Try to open a file with different vuid, samba cnum. */
2826         if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2827                 printf("create with different vuid, same cnum succeeded.\n");
2828                 cli_close(cli, fnum2);
2829                 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2830         } else {
2831                 printf("create with different vuid, same cnum failed.\n");
2832                 printf("This will cause problems with service clients.\n");
2833                 ret = False;
2834         }
2835
2836         cli_state_set_uid(cli, saved_vuid);
2837
2838         /* Try with same vuid, different cnum. */
2839         cli_state_set_tid(cli, new_cnum);
2840
2841         if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2842                 printf("read succeeded with different cnum![%s]\n", buf);
2843                 ret = false;
2844         }
2845
2846         cli_state_set_tid(cli, saved_cnum);
2847         cli_close(cli, fnum1);
2848         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2849
2850         torture_close_connection(cli);
2851
2852         printf("finished fdsesstest\n");
2853         return ret;
2854 }
2855
2856 /*
2857   This test checks that 
2858
2859   1) the server does not allow an unlink on a file that is open
2860 */
2861 static bool run_unlinktest(int dummy)
2862 {
2863         struct cli_state *cli;
2864         const char *fname = "\\unlink.tst";
2865         uint16_t fnum;
2866         bool correct = True;
2867         NTSTATUS status;
2868
2869         if (!torture_open_connection(&cli, 0)) {
2870                 return False;
2871         }
2872
2873         smbXcli_conn_set_sockopt(cli->conn, sockops);
2874
2875         printf("starting unlink test\n");
2876
2877         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2878
2879         cli_setpid(cli, 1);
2880
2881         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2882         if (!NT_STATUS_IS_OK(status)) {
2883                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2884                 return False;
2885         }
2886
2887         status = cli_unlink(cli, fname,
2888                             FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2889         if (NT_STATUS_IS_OK(status)) {
2890                 printf("error: server allowed unlink on an open file\n");
2891                 correct = False;
2892         } else {
2893                 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
2894                                       NT_STATUS_SHARING_VIOLATION);
2895         }
2896
2897         cli_close(cli, fnum);
2898         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2899
2900         if (!torture_close_connection(cli)) {
2901                 correct = False;
2902         }
2903
2904         printf("unlink test finished\n");
2905
2906         return correct;
2907 }
2908
2909
2910 /*
2911 test how many open files this server supports on the one socket
2912 */
2913 static bool run_maxfidtest(int dummy)
2914 {
2915         struct cli_state *cli;
2916         fstring fname;
2917         uint16_t fnums[0x11000];
2918         int i;
2919         int retries=4;
2920         bool correct = True;
2921         NTSTATUS status;
2922
2923         cli = current_cli;
2924
2925         if (retries <= 0) {
2926                 printf("failed to connect\n");
2927                 return False;
2928         }
2929
2930         smbXcli_conn_set_sockopt(cli->conn, sockops);
2931
2932         for (i=0; i<0x11000; i++) {
2933                 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2934                 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2935                                   &fnums[i]);
2936                 if (!NT_STATUS_IS_OK(status)) {
2937                         printf("open of %s failed (%s)\n", 
2938                                fname, nt_errstr(status));
2939                         printf("maximum fnum is %d\n", i);
2940                         break;
2941                 }
2942                 printf("%6d\r", i);
2943         }
2944         printf("%6d\n", i);
2945         i--;
2946
2947         printf("cleaning up\n");
2948         for (;i>=0;i--) {
2949                 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2950                 cli_close(cli, fnums[i]);
2951
2952                 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2953                 if (!NT_STATUS_IS_OK(status)) {
2954                         printf("unlink of %s failed (%s)\n", 
2955                                fname, nt_errstr(status));
2956                         correct = False;
2957                 }
2958                 printf("%6d\r", i);
2959         }
2960         printf("%6d\n", 0);
2961
2962         printf("maxfid test finished\n");
2963         if (!torture_close_connection(cli)) {
2964                 correct = False;
2965         }
2966         return correct;
2967 }
2968
2969 /* generate a random buffer */
2970 static void rand_buf(char *buf, int len)
2971 {
2972         while (len--) {
2973                 *buf = (char)sys_random();
2974                 buf++;
2975         }
2976 }
2977
2978 /* send smb negprot commands, not reading the response */
2979 static bool run_negprot_nowait(int dummy)
2980 {
2981         struct tevent_context *ev;
2982         int i;
2983         struct cli_state *cli;
2984         bool correct = True;
2985
2986         printf("starting negprot nowait test\n");
2987
2988         ev = tevent_context_init(talloc_tos());
2989         if (ev == NULL) {
2990                 return false;
2991         }
2992
2993         if (!(cli = open_nbt_connection())) {
2994                 TALLOC_FREE(ev);
2995                 return False;
2996         }
2997
2998         for (i=0;i<50000;i++) {
2999                 struct tevent_req *req;
3000
3001                 req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout,
3002                                            PROTOCOL_CORE, PROTOCOL_NT1);
3003                 if (req == NULL) {
3004                         TALLOC_FREE(ev);
3005                         return false;
3006                 }
3007                 if (!tevent_req_poll(req, ev)) {
3008                         d_fprintf(stderr, "tevent_req_poll failed: %s\n",
3009                                   strerror(errno));
3010                         TALLOC_FREE(ev);
3011                         return false;
3012                 }
3013                 TALLOC_FREE(req);
3014         }
3015
3016         if (torture_close_connection(cli)) {
3017                 correct = False;
3018         }
3019
3020         printf("finished negprot nowait test\n");
3021
3022         return correct;
3023 }
3024
3025 /* send smb negprot commands, not reading the response */
3026 static bool run_bad_nbt_session(int dummy)
3027 {
3028         struct nmb_name called, calling;
3029         struct sockaddr_storage ss;
3030         NTSTATUS status;
3031         int fd;
3032         bool ret;
3033
3034         printf("starting bad nbt session test\n");
3035
3036         make_nmb_name(&calling, myname, 0x0);
3037         make_nmb_name(&called , host, 0x20);
3038
3039         if (!resolve_name(host, &ss, 0x20, true)) {
3040                 d_fprintf(stderr, "Could not resolve name %s\n", host);
3041                 return false;
3042         }
3043
3044         status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
3045         if (!NT_STATUS_IS_OK(status)) {
3046                 d_fprintf(stderr, "open_socket_out failed: %s\n",
3047                           nt_errstr(status));
3048                 return false;
3049         }
3050
3051         ret = cli_bad_session_request(fd, &calling, &called);
3052         close(fd);
3053         if (!ret) {
3054                 d_fprintf(stderr, "open_socket_out failed: %s\n",
3055                           nt_errstr(status));
3056                 return false;
3057         }
3058
3059         printf("finished bad nbt session test\n");
3060         return true;
3061 }
3062
3063 /* send random IPC commands */
3064 static bool run_randomipc(int dummy)
3065 {
3066         char *rparam = NULL;
3067         char *rdata = NULL;
3068         unsigned int rdrcnt,rprcnt;
3069         char param[1024];
3070         int api, param_len, i;
3071         struct cli_state *cli;
3072         bool correct = True;
3073         int count = 50000;
3074
3075         printf("starting random ipc test\n");
3076
3077         if (!torture_open_connection(&cli, 0)) {
3078                 return False;
3079         }
3080
3081         for (i=0;i<count;i++) {
3082                 api = sys_random() % 500;
3083                 param_len = (sys_random() % 64);
3084
3085                 rand_buf(param, param_len);
3086
3087                 SSVAL(param,0,api); 
3088
3089                 cli_api(cli, 
3090                         param, param_len, 8,  
3091                         NULL, 0, BUFFER_SIZE, 
3092                         &rparam, &rprcnt,     
3093                         &rdata, &rdrcnt);
3094                 if (i % 100 == 0) {
3095                         printf("%d/%d\r", i,count);
3096                 }
3097         }
3098         printf("%d/%d\n", i, count);
3099
3100         if (!torture_close_connection(cli)) {
3101                 correct = False;
3102         }
3103
3104         printf("finished random ipc test\n");
3105
3106         return correct;
3107 }
3108
3109
3110
3111 static void browse_callback(const char *sname, uint32 stype, 
3112                             const char *comment, void *state)
3113 {
3114         printf("\t%20.20s %08x %s\n", sname, stype, comment);
3115 }
3116
3117
3118
3119 /*
3120   This test checks the browse list code
3121
3122 */
3123 static bool run_browsetest(int dummy)
3124 {
3125         static struct cli_state *cli;
3126         bool correct = True;
3127
3128         printf("starting browse test\n");
3129
3130         if (!torture_open_connection(&cli, 0)) {
3131                 return False;
3132         }
3133
3134         printf("domain list:\n");
3135         cli_NetServerEnum(cli, cli->server_domain, 
3136                           SV_TYPE_DOMAIN_ENUM,
3137                           browse_callback, NULL);
3138
3139         printf("machine list:\n");
3140         cli_NetServerEnum(cli, cli->server_domain, 
3141                           SV_TYPE_ALL,
3142                           browse_callback, NULL);
3143
3144         if (!torture_close_connection(cli)) {
3145                 correct = False;
3146         }
3147
3148         printf("browse test finished\n");
3149
3150         return correct;
3151
3152 }
3153
3154
3155 /*
3156   This checks how the getatr calls works
3157 */
3158 static bool run_attrtest(int dummy)
3159 {
3160         struct cli_state *cli;
3161         uint16_t fnum;
3162         time_t t, t2;
3163         const char *fname = "\\attrib123456789.tst";
3164         bool correct = True;
3165         NTSTATUS status;
3166
3167         printf("starting attrib test\n");
3168
3169         if (!torture_open_connection(&cli, 0)) {
3170                 return False;
3171         }
3172
3173         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3174         cli_openx(cli, fname, 
3175                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3176         cli_close(cli, fnum);
3177
3178         status = cli_getatr(cli, fname, NULL, NULL, &t);
3179         if (!NT_STATUS_IS_OK(status)) {
3180                 printf("getatr failed (%s)\n", nt_errstr(status));
3181                 correct = False;
3182         }
3183
3184         if (abs(t - time(NULL)) > 60*60*24*10) {
3185                 printf("ERROR: SMBgetatr bug. time is %s",
3186                        ctime(&t));
3187                 t = time(NULL);
3188                 correct = True;
3189         }
3190
3191         t2 = t-60*60*24; /* 1 day ago */
3192
3193         status = cli_setatr(cli, fname, 0, t2);
3194         if (!NT_STATUS_IS_OK(status)) {
3195                 printf("setatr failed (%s)\n", nt_errstr(status));
3196                 correct = True;
3197         }
3198
3199         status = cli_getatr(cli, fname, NULL, NULL, &t);
3200         if (!NT_STATUS_IS_OK(status)) {
3201                 printf("getatr failed (%s)\n", nt_errstr(status));
3202                 correct = True;
3203         }
3204
3205         if (t != t2) {
3206                 printf("ERROR: getatr/setatr bug. times are\n%s",
3207                        ctime(&t));
3208                 printf("%s", ctime(&t2));
3209                 correct = True;
3210         }
3211
3212         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3213
3214         if (!torture_close_connection(cli)) {
3215                 correct = False;
3216         }
3217
3218         printf("attrib test finished\n");
3219
3220         return correct;
3221 }
3222
3223
3224 /*
3225   This checks a couple of trans2 calls
3226 */
3227 static bool run_trans2test(int dummy)
3228 {
3229         struct cli_state *cli;
3230         uint16_t fnum;
3231         off_t size;
3232         time_t c_time, a_time, m_time;
3233         struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3234         const char *fname = "\\trans2.tst";
3235         const char *dname = "\\trans2";
3236         const char *fname2 = "\\trans2\\trans2.tst";
3237         char *pname;
3238         bool correct = True;
3239         NTSTATUS status;
3240         uint32_t fs_attr;
3241
3242         printf("starting trans2 test\n");
3243
3244         if (!torture_open_connection(&cli, 0)) {
3245                 return False;
3246         }
3247
3248         status = cli_get_fs_attr_info(cli, &fs_attr);
3249         if (!NT_STATUS_IS_OK(status)) {
3250                 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3251                        nt_errstr(status));
3252                 correct = false;
3253         }
3254
3255         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3256         cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3257         status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3258                                      &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3259         if (!NT_STATUS_IS_OK(status)) {
3260                 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3261                 correct = False;
3262         }
3263
3264         status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3265         if (!NT_STATUS_IS_OK(status)) {
3266                 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3267                 correct = False;
3268         }
3269
3270         if (strcmp(pname, fname)) {
3271                 printf("qfilename gave different name? [%s] [%s]\n",
3272                        fname, pname);
3273                 correct = False;
3274         }
3275
3276         cli_close(cli, fnum);
3277
3278         sleep(2);
3279
3280         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3281         status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3282                           &fnum);
3283         if (!NT_STATUS_IS_OK(status)) {
3284                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3285                 return False;
3286         }
3287         cli_close(cli, fnum);
3288
3289         status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3290                                 NULL);
3291         if (!NT_STATUS_IS_OK(status)) {
3292                 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3293                 correct = False;
3294         } else {
3295                 time_t t = time(NULL);
3296
3297                 if (c_time != m_time) {
3298                         printf("create time=%s", ctime(&c_time));
3299                         printf("modify time=%s", ctime(&m_time));
3300                         printf("This system appears to have sticky create times\n");
3301                 }
3302                 if ((abs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
3303                         printf("access time=%s", ctime(&a_time));
3304                         printf("This system appears to set a midnight access time\n");
3305                         correct = False;
3306                 }
3307
3308                 if (abs(m_time - t) > 60*60*24*7) {
3309                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3310                         correct = False;
3311                 }
3312         }
3313
3314
3315         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3316         cli_openx(cli, fname, 
3317                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3318         cli_close(cli, fnum);
3319         status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3320                                 &m_time_ts, &size, NULL, NULL);
3321         if (!NT_STATUS_IS_OK(status)) {
3322                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3323                 correct = False;
3324         } else {
3325                 if (w_time_ts.tv_sec < 60*60*24*2) {
3326                         printf("write time=%s", ctime(&w_time_ts.tv_sec));
3327                         printf("This system appears to set a initial 0 write time\n");
3328                         correct = False;
3329                 }
3330         }
3331
3332         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3333
3334
3335         /* check if the server updates the directory modification time
3336            when creating a new file */
3337         status = cli_mkdir(cli, dname);
3338         if (!NT_STATUS_IS_OK(status)) {
3339                 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3340                 correct = False;
3341         }
3342         sleep(3);
3343         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3344                                 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3345         if (!NT_STATUS_IS_OK(status)) {
3346                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3347                 correct = False;
3348         }
3349
3350         cli_openx(cli, fname2, 
3351                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3352         cli_writeall(cli, fnum,  0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3353         cli_close(cli, fnum);
3354         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3355                                 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3356         if (!NT_STATUS_IS_OK(status)) {
3357                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3358                 correct = False;
3359         } else {
3360                 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3361                     == 0) {
3362                         printf("This system does not update directory modification times\n");
3363                         correct = False;
3364                 }
3365         }
3366         cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3367         cli_rmdir(cli, dname);
3368
3369         if (!torture_close_connection(cli)) {
3370                 correct = False;
3371         }
3372
3373         printf("trans2 test finished\n");
3374
3375         return correct;
3376 }
3377
3378 /*
3379   This checks new W2K calls.
3380 */
3381
3382 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3383 {
3384         uint8_t *buf = NULL;
3385         uint32 len;
3386         NTSTATUS status;
3387
3388         status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3389                                CLI_BUFFER_SIZE, NULL, &buf, &len);
3390         if (!NT_STATUS_IS_OK(status)) {
3391                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3392                        nt_errstr(status));
3393         } else {
3394                 printf("qfileinfo: level %d, len = %u\n", level, len);
3395                 dump_data(0, (uint8 *)buf, len);
3396                 printf("\n");
3397         }
3398         TALLOC_FREE(buf);
3399         return status;
3400 }
3401
3402 static bool run_w2ktest(int dummy)
3403 {
3404         struct cli_state *cli;
3405         uint16_t fnum;
3406         const char *fname = "\\w2ktest\\w2k.tst";
3407         int level;
3408         bool correct = True;
3409
3410         printf("starting w2k test\n");
3411
3412         if (!torture_open_connection(&cli, 0)) {
3413                 return False;
3414         }
3415
3416         cli_openx(cli, fname, 
3417                         O_RDWR | O_CREAT , DENY_NONE, &fnum);
3418
3419         for (level = 1004; level < 1040; level++) {
3420                 new_trans(cli, fnum, level);
3421         }
3422
3423         cli_close(cli, fnum);
3424
3425         if (!torture_close_connection(cli)) {
3426                 correct = False;
3427         }
3428
3429         printf("w2k test finished\n");
3430
3431         return correct;
3432 }
3433
3434
3435 /*
3436   this is a harness for some oplock tests
3437  */
3438 static bool run_oplock1(int dummy)
3439 {
3440         struct cli_state *cli1;
3441         const char *fname = "\\lockt1.lck";
3442         uint16_t fnum1;
3443         bool correct = True;
3444         NTSTATUS status;
3445
3446         printf("starting oplock test 1\n");
3447
3448         if (!torture_open_connection(&cli1, 0)) {
3449                 return False;
3450         }
3451
3452         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3453
3454         smbXcli_conn_set_sockopt(cli1->conn, sockops);
3455
3456         cli1->use_oplocks = True;
3457
3458         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3459                           &fnum1);
3460         if (!NT_STATUS_IS_OK(status)) {
3461                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3462                 return False;
3463         }
3464
3465         cli1->use_oplocks = False;
3466
3467         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3468         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3469
3470         status = cli_close(cli1, fnum1);
3471         if (!NT_STATUS_IS_OK(status)) {
3472                 printf("close2 failed (%s)\n", nt_errstr(status));
3473                 return False;
3474         }
3475
3476         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3477         if (!NT_STATUS_IS_OK(status)) {
3478                 printf("unlink failed (%s)\n", nt_errstr(status));
3479                 return False;
3480         }
3481
3482         if (!torture_close_connection(cli1)) {
3483                 correct = False;
3484         }
3485
3486         printf("finished oplock test 1\n");
3487
3488         return correct;
3489 }
3490
3491 static bool run_oplock2(int dummy)
3492 {
3493         struct cli_state *cli1, *cli2;
3494         const char *fname = "\\lockt2.lck";
3495         uint16_t fnum1, fnum2;
3496         int saved_use_oplocks = use_oplocks;
3497         char buf[4];
3498         bool correct = True;
3499         volatile bool *shared_correct;
3500         size_t nread;
3501         NTSTATUS status;
3502
3503         shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
3504         *shared_correct = True;
3505
3506         use_level_II_oplocks = True;
3507         use_oplocks = True;
3508
3509         printf("starting oplock test 2\n");
3510
3511         if (!torture_open_connection(&cli1, 0)) {
3512                 use_level_II_oplocks = False;
3513                 use_oplocks = saved_use_oplocks;
3514                 return False;
3515         }
3516
3517         if (!torture_open_connection(&cli2, 1)) {
3518                 use_level_II_oplocks = False;
3519                 use_oplocks = saved_use_oplocks;
3520                 return False;
3521         }
3522
3523         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3524
3525         smbXcli_conn_set_sockopt(cli1->conn, sockops);
3526         smbXcli_conn_set_sockopt(cli2->conn, sockops);
3527
3528         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3529                           &fnum1);
3530         if (!NT_STATUS_IS_OK(status)) {
3531                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3532                 return False;
3533         }
3534
3535         /* Don't need the globals any more. */
3536         use_level_II_oplocks = False;
3537         use_oplocks = saved_use_oplocks;
3538
3539         if (fork() == 0) {
3540                 /* Child code */
3541                 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3542                 if (!NT_STATUS_IS_OK(status)) {
3543                         printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3544                         *shared_correct = False;
3545                         exit(0);
3546                 }
3547
3548                 sleep(2);
3549
3550                 status = cli_close(cli2, fnum2);
3551                 if (!NT_STATUS_IS_OK(status)) {
3552                         printf("close2 failed (%s)\n", nt_errstr(status));
3553                         *shared_correct = False;
3554                 }
3555
3556                 exit(0);
3557         }
3558
3559         sleep(2);
3560
3561         /* Ensure cli1 processes the break. Empty file should always return 0
3562          * bytes.  */
3563         status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
3564         if (!NT_STATUS_IS_OK(status)) {
3565                 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
3566                 correct = false;
3567         } else if (nread != 0) {
3568                 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3569                       (unsigned long)nread, 0);
3570                 correct = false;
3571         }
3572
3573         /* Should now be at level II. */
3574         /* Test if sending a write locks causes a break to none. */
3575         status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
3576         if (!NT_STATUS_IS_OK(status)) {
3577                 printf("lock failed (%s)\n", nt_errstr(status));
3578                 correct = False;
3579         }
3580
3581         cli_unlock(cli1, fnum1, 0, 4);
3582
3583         sleep(2);
3584
3585         status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
3586         if (!NT_STATUS_IS_OK(status)) {
3587                 printf("lock failed (%s)\n", nt_errstr(status));
3588                 correct = False;
3589         }
3590
3591         cli_unlock(cli1, fnum1, 0, 4);
3592
3593         sleep(2);
3594
3595         cli_read(cli1, fnum1, buf, 0, 4, NULL);
3596
3597         status = cli_close(cli1, fnum1);
3598         if (!NT_STATUS_IS_OK(status)) {
3599                 printf("close1 failed (%s)\n", nt_errstr(status));
3600                 correct = False;
3601         }
3602
3603         sleep(4);
3604
3605         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3606         if (!NT_STATUS_IS_OK(status)) {
3607                 printf("unlink failed (%s)\n", nt_errstr(status));
3608                 correct = False;
3609         }
3610
3611         if (!torture_close_connection(cli1)) {
3612                 correct = False;
3613         }
3614
3615         if (!*shared_correct) {
3616                 correct = False;
3617         }
3618
3619         printf("finished oplock test 2\n");
3620
3621         return correct;
3622 }
3623
3624 struct oplock4_state {
3625         struct tevent_context *ev;
3626         struct cli_state *cli;
3627         bool *got_break;
3628         uint16_t *fnum2;
3629 };
3630
3631 static void oplock4_got_break(struct tevent_req *req);
3632 static void oplock4_got_open(struct tevent_req *req);
3633
3634 static bool run_oplock4(int dummy)
3635 {
3636         struct tevent_context *ev;
3637         struct cli_state *cli1, *cli2;
3638         struct tevent_req *oplock_req, *open_req;
3639         const char *fname = "\\lockt4.lck";
3640         const char *fname_ln = "\\lockt4_ln.lck";
3641         uint16_t fnum1, fnum2;
3642         int saved_use_oplocks = use_oplocks;
3643         NTSTATUS status;
3644         bool correct = true;
3645
3646         bool got_break;
3647
3648         struct oplock4_state *state;
3649
3650         printf("starting oplock test 4\n");
3651
3652         if (!torture_open_connection(&cli1, 0)) {
3653                 use_level_II_oplocks = false;
3654                 use_oplocks = saved_use_oplocks;
3655                 return false;
3656         }
3657
3658         if (!torture_open_connection(&cli2, 1)) {
3659                 use_level_II_oplocks = false;
3660                 use_oplocks = saved_use_oplocks;
3661                 return false;
3662         }
3663
3664         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3665         cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3666
3667         smbXcli_conn_set_sockopt(cli1->conn, sockops);
3668         smbXcli_conn_set_sockopt(cli2->conn, sockops);
3669
3670         /* Create the file. */
3671         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3672                           &fnum1);
3673         if (!NT_STATUS_IS_OK(status)) {
3674                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3675                 return false;
3676         }
3677
3678         status = cli_close(cli1, fnum1);
3679         if (!NT_STATUS_IS_OK(status)) {
3680                 printf("close1 failed (%s)\n", nt_errstr(status));
3681                 return false;
3682         }
3683
3684         /* Now create a hardlink. */
3685         status = cli_nt_hardlink(cli1, fname, fname_ln);
3686         if (!NT_STATUS_IS_OK(status)) {
3687                 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3688                 return false;
3689         }
3690
3691         /* Prove that opening hardlinks cause deny modes to conflict. */
3692         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3693         if (!NT_STATUS_IS_OK(status)) {
3694                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3695                 return false;
3696         }
3697
3698         status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3699         if (NT_STATUS_IS_OK(status)) {
3700                 printf("open of %s succeeded - should fail with sharing violation.\n",
3701                         fname_ln);
3702                 return false;
3703         }
3704
3705         if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3706                 printf("open of %s should fail with sharing violation. Got %s\n",
3707                         fname_ln, nt_errstr(status));
3708                 return false;
3709         }
3710
3711         status = cli_close(cli1, fnum1);
3712         if (!NT_STATUS_IS_OK(status)) {
3713                 printf("close1 failed (%s)\n", nt_errstr(status));
3714                 return false;
3715         }
3716
3717         cli1->use_oplocks = true;
3718         cli2->use_oplocks = true;
3719
3720         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3721         if (!NT_STATUS_IS_OK(status)) {
3722                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3723                 return false;
3724         }
3725
3726         ev = tevent_context_init(talloc_tos());
3727         if (ev == NULL) {
3728                 printf("tevent_context_init failed\n");
3729                 return false;
3730         }
3731
3732         state = talloc(ev, struct oplock4_state);
3733         if (state == NULL) {
3734                 printf("talloc failed\n");
3735                 return false;
3736         }
3737         state->ev = ev;
3738         state->cli = cli1;
3739         state->got_break = &got_break;
3740         state->fnum2 = &fnum2;
3741
3742         oplock_req = cli_smb_oplock_break_waiter_send(
3743                 talloc_tos(), ev, cli1);
3744         if (oplock_req == NULL) {
3745                 printf("cli_smb_oplock_break_waiter_send failed\n");
3746                 return false;
3747         }
3748         tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3749
3750         open_req = cli_openx_send(
3751                 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3752         if (open_req == NULL) {
3753                 printf("cli_openx_send failed\n");
3754                 return false;
3755         }
3756         tevent_req_set_callback(open_req, oplock4_got_open, state);
3757
3758         got_break = false;
3759         fnum2 = 0xffff;
3760
3761         while (!got_break || fnum2 == 0xffff) {
3762                 int ret;
3763                 ret = tevent_loop_once(ev);
3764                 if (ret == -1) {
3765                         printf("tevent_loop_once failed: %s\n",
3766                                strerror(errno));
3767                         return false;
3768                 }
3769         }
3770
3771         status = cli_close(cli2, fnum2);
3772         if (!NT_STATUS_IS_OK(status)) {
3773                 printf("close2 failed (%s)\n", nt_errstr(status));
3774                 correct = false;
3775         }
3776
3777         status = cli_close(cli1, fnum1);
3778         if (!NT_STATUS_IS_OK(status)) {
3779                 printf("close1 failed (%s)\n", nt_errstr(status));
3780                 correct = false;
3781         }
3782
3783         status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3784         if (!NT_STATUS_IS_OK(status)) {
3785                 printf("unlink failed (%s)\n", nt_errstr(status));
3786                 correct = false;
3787         }
3788
3789         status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3790         if (!NT_STATUS_IS_OK(status)) {
3791                 printf("unlink failed (%s)\n", nt_errstr(status));
3792                 correct = false;
3793         }
3794
3795         if (!torture_close_connection(cli1)) {
3796                 correct = false;
3797         }
3798
3799         if (!got_break) {
3800                 correct = false;
3801         }
3802
3803         printf("finished oplock test 4\n");
3804
3805         return correct;
3806 }
3807
3808 static void oplock4_got_break(struct tevent_req *req)
3809 {
3810         struct oplock4_state *state = tevent_req_callback_data(
3811                 req, struct oplock4_state);
3812         uint16_t fnum;
3813         uint8_t level;
3814         NTSTATUS status;
3815
3816         status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3817         TALLOC_FREE(req);
3818         if (!NT_STATUS_IS_OK(status)) {
3819                 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3820                        nt_errstr(status));
3821                 return;
3822         }
3823         *state->got_break = true;
3824
3825         req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3826                                   NO_OPLOCK);
3827         if (req == NULL) {
3828                 printf("cli_oplock_ack_send failed\n");
3829                 return;
3830         }
3831 }
3832
3833 static void oplock4_got_open(struct tevent_req *req)
3834 {
3835         struct oplock4_state *state = tevent_req_callback_data(
3836                 req, struct oplock4_state);
3837         NTSTATUS status;
3838
3839         status = cli_openx_recv(req, state->fnum2);
3840         if (!NT_STATUS_IS_OK(status)) {
3841                 printf("cli_openx_recv returned %s\n", nt_errstr(status));
3842                 *state->fnum2 = 0xffff;
3843         }
3844 }
3845
3846 /*
3847   Test delete on close semantics.
3848  */
3849 static bool run_deletetest(int dummy)
3850 {
3851         struct cli_state *cli1 = NULL;
3852         struct cli_state *cli2 = NULL;
3853         const char *fname = "\\delete.file";
3854         uint16_t fnum1 = (uint16_t)-1;
3855         uint16_t fnum2 = (uint16_t)-1;
3856         bool correct = True;
3857         NTSTATUS status;
3858
3859         printf("starting delete test\n");
3860
3861         if (!torture_open_connection(&cli1, 0)) {
3862                 return False;
3863         }
3864
3865         smbXcli_conn_set_sockopt(cli1->conn, sockops);
3866
3867         /* Test 1 - this should delete the file on close. */
3868
3869         cli_setatr(cli1, fname, 0, 0);
3870         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3871
3872         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3873                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3874                               FILE_DELETE_ON_CLOSE, 0, &fnum1);
3875         if (!NT_STATUS_IS_OK(status)) {
3876                 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3877                 correct = False;
3878                 goto fail;
3879         }
3880
3881         status = cli_close(cli1, fnum1);
3882         if (!NT_STATUS_IS_OK(status)) {
3883                 printf("[1] close failed (%s)\n", nt_errstr(status));
3884                 correct = False;
3885                 goto fail;
3886         }
3887
3888         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3889         if (NT_STATUS_IS_OK(status)) {
3890                 printf("[1] open of %s succeeded (should fail)\n", fname);
3891                 correct = False;
3892                 goto fail;
3893         }
3894
3895         printf("first delete on close test succeeded.\n");
3896
3897         /* Test 2 - this should delete the file on close. */
3898
3899         cli_setatr(cli1, fname, 0, 0);
3900         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3901
3902         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3903                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3904                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
3905         if (!NT_STATUS_IS_OK(status)) {
3906                 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3907                 correct = False;
3908                 goto fail;
3909         }
3910
3911         status = cli_nt_delete_on_close(cli1, fnum1, true);
3912         if (!NT_STATUS_IS_OK(status)) {
3913                 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3914                 correct = False;
3915                 goto fail;
3916         }
3917
3918         status = cli_close(cli1, fnum1);
3919         if (!NT_STATUS_IS_OK(status)) {
3920                 printf("[2] close failed (%s)\n", nt_errstr(status));
3921                 correct = False;
3922                 goto fail;
3923         }
3924
3925         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
3926         if (NT_STATUS_IS_OK(status)) {
3927                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3928                 status = cli_close(cli1, fnum1);
3929                 if (!NT_STATUS_IS_OK(status)) {
3930                         printf("[2] close failed (%s)\n", nt_errstr(status));
3931                 }
3932                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3933                 correct = False;
3934                 goto fail;
3935         }
3936
3937         printf("second delete on close test succeeded.\n");
3938
3939         /* Test 3 - ... */
3940         cli_setatr(cli1, fname, 0, 0);
3941         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3942
3943         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3944                               FILE_ATTRIBUTE_NORMAL,
3945                               FILE_SHARE_READ|FILE_SHARE_WRITE,
3946                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
3947         if (!NT_STATUS_IS_OK(status)) {
3948                 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3949                 correct = False;
3950                 goto fail;
3951         }
3952
3953         /* This should fail with a sharing violation - open for delete is only compatible
3954            with SHARE_DELETE. */
3955
3956         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3957                               FILE_ATTRIBUTE_NORMAL,
3958                               FILE_SHARE_READ|FILE_SHARE_WRITE,
3959                               FILE_OPEN, 0, 0, &fnum2);
3960         if (NT_STATUS_IS_OK(status)) {
3961                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
3962                 correct = False;
3963                 goto fail;
3964         }
3965
3966         /* This should succeed. */
3967         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3968                              FILE_ATTRIBUTE_NORMAL,
3969                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3970                              FILE_OPEN, 0, 0, &fnum2);
3971         if (!NT_STATUS_IS_OK(status)) {
3972                 printf("[3] open  - 3 of %s failed (%s)\n", fname, nt_errstr(status));
3973                 correct = False;
3974                 goto fail;
3975         }
3976
3977         status = cli_nt_delete_on_close(cli1, fnum1, true);
3978         if (!NT_STATUS_IS_OK(status)) {
3979                 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
3980                 correct = False;
3981                 goto fail;
3982         }
3983
3984         status = cli_close(cli1, fnum1);
3985         if (!NT_STATUS_IS_OK(status)) {
3986                 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
3987                 correct = False;
3988                 goto fail;
3989         }
3990
3991         status = cli_close(cli1, fnum2);
3992         if (!NT_STATUS_IS_OK(status)) {
3993                 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
3994                 correct = False;
3995                 goto fail;
3996         }
3997
3998         /* This should fail - file should no longer be there. */
3999
4000         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4001         if (NT_STATUS_IS_OK(status)) {
4002                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
4003                 status = cli_close(cli1, fnum1);
4004                 if (!NT_STATUS_IS_OK(status)) {
4005                         printf("[3] close failed (%s)\n", nt_errstr(status));
4006                 }
4007                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4008                 correct = False;
4009                 goto fail;
4010         }
4011
4012         printf("third delete on close test succeeded.\n");
4013
4014         /* Test 4 ... */
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,
4019                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4020                               FILE_ATTRIBUTE_NORMAL,
4021                               FILE_SHARE_READ|FILE_SHARE_WRITE,
4022                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
4023         if (!NT_STATUS_IS_OK(status)) {
4024                 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
4025                 correct = False;
4026                 goto fail;
4027         }
4028
4029         /* This should succeed. */
4030         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4031                              FILE_ATTRIBUTE_NORMAL,
4032                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4033                              FILE_OPEN, 0, 0, &fnum2);
4034         if (!NT_STATUS_IS_OK(status)) {
4035                 printf("[4] open  - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4036                 correct = False;
4037                 goto fail;
4038         }
4039
4040         status = cli_close(cli1, fnum2);
4041         if (!NT_STATUS_IS_OK(status)) {
4042                 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
4043                 correct = False;
4044                 goto fail;
4045         }
4046
4047         status = cli_nt_delete_on_close(cli1, fnum1, true);
4048         if (!NT_STATUS_IS_OK(status)) {
4049                 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
4050                 correct = False;
4051                 goto fail;
4052         }
4053
4054         /* This should fail - no more opens once delete on close set. */
4055         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4056                               FILE_ATTRIBUTE_NORMAL,
4057                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4058                               FILE_OPEN, 0, 0, &fnum2);
4059         if (NT_STATUS_IS_OK(status)) {
4060                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
4061                 correct = False;
4062                 goto fail;
4063         }
4064
4065         status = cli_close(cli1, fnum1);
4066         if (!NT_STATUS_IS_OK(status)) {
4067                 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4068                 correct = False;
4069                 goto fail;
4070         }
4071
4072         printf("fourth delete on close test succeeded.\n");
4073
4074         /* Test 5 ... */
4075         cli_setatr(cli1, fname, 0, 0);
4076         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4077
4078         status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4079         if (!NT_STATUS_IS_OK(status)) {
4080                 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4081                 correct = False;
4082                 goto fail;
4083         }
4084
4085         /* This should fail - only allowed on NT opens with DELETE access. */
4086
4087         status = cli_nt_delete_on_close(cli1, fnum1, true);
4088         if (NT_STATUS_IS_OK(status)) {
4089                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4090                 correct = False;
4091                 goto fail;
4092         }
4093
4094         status = cli_close(cli1, fnum1);
4095         if (!NT_STATUS_IS_OK(status)) {
4096                 printf("[5] close failed (%s)\n", nt_errstr(status));
4097                 correct = False;
4098                 goto fail;
4099         }
4100
4101         printf("fifth delete on close test succeeded.\n");
4102
4103         /* Test 6 ... */
4104         cli_setatr(cli1, fname, 0, 0);
4105         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4106
4107         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4108                              FILE_ATTRIBUTE_NORMAL,
4109                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4110                              FILE_OVERWRITE_IF, 0, 0, &fnum1);
4111         if (!NT_STATUS_IS_OK(status)) {
4112                 printf("[6] open of %s failed (%s)\n", fname,
4113                        nt_errstr(status));
4114                 correct = False;
4115                 goto fail;
4116         }
4117
4118         /* This should fail - only allowed on NT opens with DELETE access. */
4119
4120         status = cli_nt_delete_on_close(cli1, fnum1, true);
4121         if (NT_STATUS_IS_OK(status)) {
4122                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4123                 correct = False;
4124                 goto fail;
4125         }
4126
4127         status = cli_close(cli1, fnum1);
4128         if (!NT_STATUS_IS_OK(status)) {
4129                 printf("[6] close failed (%s)\n", nt_errstr(status));
4130                 correct = False;
4131                 goto fail;
4132         }
4133
4134         printf("sixth delete on close test succeeded.\n");
4135
4136         /* Test 7 ... */
4137         cli_setatr(cli1, fname, 0, 0);
4138         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4139
4140         status = cli_ntcreate(cli1, fname, 0,
4141                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4142                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4143                               0, 0, &fnum1);
4144         if (!NT_STATUS_IS_OK(status)) {
4145                 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4146                 correct = False;
4147                 goto fail;
4148         }
4149
4150         status = cli_nt_delete_on_close(cli1, fnum1, true);
4151         if (!NT_STATUS_IS_OK(status)) {
4152                 printf("[7] setting delete_on_close on file failed !\n");
4153                 correct = False;
4154                 goto fail;
4155         }
4156
4157         status = cli_nt_delete_on_close(cli1, fnum1, false);
4158         if (!NT_STATUS_IS_OK(status)) {
4159                 printf("[7] unsetting delete_on_close on file failed !\n");
4160                 correct = False;
4161                 goto fail;
4162         }
4163
4164         status = cli_close(cli1, fnum1);
4165         if (!NT_STATUS_IS_OK(status)) {
4166                 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
4167                 correct = False;
4168                 goto fail;
4169         }
4170
4171         /* This next open should succeed - we reset the flag. */
4172         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4173         if (!NT_STATUS_IS_OK(status)) {
4174                 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4175                 correct = False;
4176                 goto fail;
4177         }
4178
4179         status = cli_close(cli1, fnum1);
4180         if (!NT_STATUS_IS_OK(status)) {
4181                 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4182                 correct = False;
4183                 goto fail;
4184         }
4185
4186         printf("seventh delete on close test succeeded.\n");
4187
4188         /* Test 8 ... */
4189         cli_setatr(cli1, fname, 0, 0);
4190         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4191
4192         if (!torture_open_connection(&cli2, 1)) {
4193                 printf("[8] failed to open second connection.\n");
4194                 correct = False;
4195                 goto fail;
4196         }
4197
4198         smbXcli_conn_set_sockopt(cli1->conn, sockops);
4199
4200         status = cli_ntcreate(cli1, fname, 0,
4201                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4202                              FILE_ATTRIBUTE_NORMAL,
4203                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4204                              FILE_OVERWRITE_IF, 0, 0, &fnum1);
4205         if (!NT_STATUS_IS_OK(status)) {
4206                 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4207                 correct = False;
4208                 goto fail;
4209         }
4210
4211         status = cli_ntcreate(cli2, fname, 0,
4212                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4213                              FILE_ATTRIBUTE_NORMAL,
4214                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4215                              FILE_OPEN, 0, 0, &fnum2);
4216         if (!NT_STATUS_IS_OK(status)) {
4217                 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4218                 correct = False;
4219                 goto fail;
4220         }
4221
4222         status = cli_nt_delete_on_close(cli1, fnum1, true);
4223         if (!NT_STATUS_IS_OK(status)) {
4224                 printf("[8] setting delete_on_close on file failed !\n");
4225                 correct = False;
4226                 goto fail;
4227         }
4228
4229         status = cli_close(cli1, fnum1);
4230         if (!NT_STATUS_IS_OK(status)) {
4231                 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4232                 correct = False;
4233                 goto fail;
4234         }
4235
4236         status = cli_close(cli2, fnum2);
4237         if (!NT_STATUS_IS_OK(status)) {
4238                 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4239                 correct = False;
4240                 goto fail;
4241         }
4242
4243         /* This should fail.. */
4244         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4245         if (NT_STATUS_IS_OK(status)) {
4246                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4247                 goto fail;
4248                 correct = False;
4249         }
4250
4251         printf("eighth delete on close test succeeded.\n");
4252
4253         /* Test 9 ... */
4254
4255         /* This should fail - we need to set DELETE_ACCESS. */
4256         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4257                               FILE_ATTRIBUTE_NORMAL,
4258                               FILE_SHARE_NONE,
4259                               FILE_OVERWRITE_IF,
4260                               FILE_DELETE_ON_CLOSE, 0, &fnum1);
4261         if (NT_STATUS_IS_OK(status)) {
4262                 printf("[9] open of %s succeeded should have failed!\n", fname);
4263                 correct = False;
4264                 goto fail;
4265         }
4266
4267         printf("ninth delete on close test succeeded.\n");
4268
4269         status = cli_ntcreate(cli1, fname, 0,
4270                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4271                              FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4272                              FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4273                              0, &fnum1);
4274         if (!NT_STATUS_IS_OK(status)) {
4275                 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4276                 correct = False;
4277                 goto fail;
4278         }
4279
4280         /* This should delete the file. */
4281         status = cli_close(cli1, fnum1);
4282         if (!NT_STATUS_IS_OK(status)) {
4283                 printf("[10] close failed (%s)\n", nt_errstr(status));
4284                 correct = False;
4285                 goto fail;
4286         }
4287
4288         /* This should fail.. */
4289         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4290         if (NT_STATUS_IS_OK(status)) {
4291                 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4292                 goto fail;
4293                 correct = False;
4294         }
4295
4296         printf("tenth delete on close test succeeded.\n");
4297
4298         cli_setatr(cli1, fname, 0, 0);
4299         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4300
4301         /* What error do we get when attempting to open a read-only file with
4302            delete access ? */
4303
4304         /* Create a readonly file. */
4305         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4306                               FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4307                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
4308         if (!NT_STATUS_IS_OK(status)) {
4309                 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4310                 correct = False;
4311                 goto fail;
4312         }
4313
4314         status = cli_close(cli1, fnum1);
4315         if (!NT_STATUS_IS_OK(status)) {
4316                 printf("[11] close failed (%s)\n", nt_errstr(status));
4317                 correct = False;
4318                 goto fail;
4319         }
4320
4321         /* Now try open for delete access. */
4322         status = cli_ntcreate(cli1, fname, 0,
4323                              FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4324                              0,
4325                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4326                              FILE_OVERWRITE_IF, 0, 0, &fnum1);
4327         if (NT_STATUS_IS_OK(status)) {
4328                 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4329                 cli_close(cli1, fnum1);
4330                 goto fail;
4331                 correct = False;
4332         } else {
4333                 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4334                         printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(status));
4335                         goto fail;
4336                         correct = False;
4337                 } else {
4338                         printf("eleventh delete on close test succeeded.\n");
4339                 }
4340         }
4341
4342         printf("finished delete test\n");
4343
4344   fail:
4345         /* FIXME: This will crash if we aborted before cli2 got
4346          * intialized, because these functions don't handle
4347          * uninitialized connections. */
4348
4349         if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4350         if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4351         cli_setatr(cli1, fname, 0, 0);
4352         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4353
4354         if (cli1 && !torture_close_connection(cli1)) {
4355                 correct = False;
4356         }
4357         if (cli2 && !torture_close_connection(cli2)) {
4358                 correct = False;
4359         }
4360         return correct;
4361 }
4362
4363 static bool run_deletetest_ln(int dummy)
4364 {
4365         struct cli_state *cli;
4366         const char *fname = "\\delete1";
4367         const char *fname_ln = "\\delete1_ln";
4368         uint16_t fnum;
4369         uint16_t fnum1;
4370         NTSTATUS status;
4371         bool correct = true;
4372         time_t t;
4373
4374         printf("starting deletetest-ln\n");
4375
4376         if (!torture_open_connection(&cli, 0)) {
4377                 return false;
4378         }
4379
4380         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4381         cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4382
4383         smbXcli_conn_set_sockopt(cli->conn, sockops);
4384
4385         /* Create the file. */
4386         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4387         if (!NT_STATUS_IS_OK(status)) {
4388                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4389                 return false;
4390         }
4391
4392         status = cli_close(cli, fnum);
4393         if (!NT_STATUS_IS_OK(status)) {
4394                 printf("close1 failed (%s)\n", nt_errstr(status));
4395                 return false;
4396         }
4397
4398         /* Now create a hardlink. */
4399         status = cli_nt_hardlink(cli, fname, fname_ln);
4400         if (!NT_STATUS_IS_OK(status)) {
4401                 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4402                 return false;
4403         }
4404
4405         /* Open the original file. */
4406         status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4407                         FILE_ATTRIBUTE_NORMAL,
4408                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4409                         FILE_OPEN_IF, 0, 0, &fnum);
4410         if (!NT_STATUS_IS_OK(status)) {
4411                 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4412                 return false;
4413         }
4414
4415         /* Unlink the hard link path. */
4416         status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4417                         FILE_ATTRIBUTE_NORMAL,
4418                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4419                         FILE_OPEN_IF, 0, 0, &fnum1);
4420         if (!NT_STATUS_IS_OK(status)) {
4421                 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4422                 return false;
4423         }
4424         status = cli_nt_delete_on_close(cli, fnum1, true);
4425         if (!NT_STATUS_IS_OK(status)) {
4426                 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4427                         __location__, fname_ln, nt_errstr(status));
4428                 return false;
4429         }
4430
4431         status = cli_close(cli, fnum1);
4432         if (!NT_STATUS_IS_OK(status)) {
4433                 printf("close %s failed (%s)\n",
4434                         fname_ln, nt_errstr(status));
4435                 return false;
4436         }
4437
4438         status = cli_close(cli, fnum);
4439         if (!NT_STATUS_IS_OK(status)) {
4440                 printf("close %s failed (%s)\n",
4441                         fname, nt_errstr(status));
4442                 return false;
4443         }
4444
4445         /* Ensure the original file is still there. */
4446         status = cli_getatr(cli, fname, NULL, NULL, &t);
4447         if (!NT_STATUS_IS_OK(status)) {
4448                 printf("%s getatr on file %s failed (%s)\n",
4449                         __location__,
4450                         fname,
4451                         nt_errstr(status));
4452                 correct = False;
4453         }
4454
4455         /* Ensure the link path is gone. */
4456         status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4457         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4458                 printf("%s, getatr for file %s returned wrong error code %s "
4459                         "- should have been deleted\n",
4460                         __location__,
4461                         fname_ln, nt_errstr(status));
4462                 correct = False;
4463         }
4464
4465         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4466         cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4467
4468         if (!torture_close_connection(cli)) {
4469                 correct = false;
4470         }
4471
4472         printf("finished deletetest-ln\n");
4473
4474         return correct;
4475 }
4476
4477 /*
4478   print out server properties
4479  */
4480 static bool run_properties(int dummy)
4481 {
4482         struct cli_state *cli;
4483         bool correct = True;
4484
4485         printf("starting properties test\n");
4486
4487         ZERO_STRUCT(cli);
4488
4489         if (!torture_open_connection(&cli, 0)) {
4490                 return False;
4491         }
4492
4493         smbXcli_conn_set_sockopt(cli->conn, sockops);
4494
4495         d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
4496
4497         if (!torture_close_connection(cli)) {
4498                 correct = False;
4499         }
4500
4501         return correct;
4502 }
4503
4504
4505
4506 /* FIRST_DESIRED_ACCESS   0xf019f */
4507 #define FIRST_DESIRED_ACCESS   FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4508                                FILE_READ_EA|                           /* 0xf */ \
4509                                FILE_WRITE_EA|FILE_READ_ATTRIBUTES|     /* 0x90 */ \
4510                                FILE_WRITE_ATTRIBUTES|                  /* 0x100 */ \
4511                                DELETE_ACCESS|READ_CONTROL_ACCESS|\
4512                                WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS     /* 0xf0000 */
4513 /* SECOND_DESIRED_ACCESS  0xe0080 */
4514 #define SECOND_DESIRED_ACCESS  FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
4515                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4516                                WRITE_OWNER_ACCESS                      /* 0xe0000 */
4517
4518 #if 0
4519 #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
4520                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4521                                FILE_READ_DATA|\
4522                                WRITE_OWNER_ACCESS                      /* */
4523 #endif
4524
4525 /*
4526   Test ntcreate calls made by xcopy
4527  */
4528 static bool run_xcopy(int dummy)
4529 {
4530         static struct cli_state *cli1;
4531         const char *fname = "\\test.txt";
4532         bool correct = True;
4533         uint16_t fnum1, fnum2;
4534         NTSTATUS status;
4535
4536         printf("starting xcopy test\n");
4537
4538         if (!torture_open_connection(&cli1, 0)) {
4539                 return False;
4540         }
4541
4542         status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4543                               FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4544                               FILE_OVERWRITE_IF, 0x4044, 0, &fnum1);
4545         if (!NT_STATUS_IS_OK(status)) {
4546                 printf("First open failed - %s\n", nt_errstr(status));
4547                 return False;
4548         }
4549
4550         status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4551                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4552                              FILE_OPEN, 0x200000, 0, &fnum2);
4553         if (!NT_STATUS_IS_OK(status)) {
4554                 printf("second open failed - %s\n", nt_errstr(status));
4555                 return False;
4556         }
4557
4558         if (!torture_close_connection(cli1)) {
4559                 correct = False;
4560         }
4561
4562         return correct;
4563 }
4564
4565 /*
4566   Test rename on files open with share delete and no share delete.
4567  */
4568 static bool run_rename(int dummy)
4569 {
4570         static struct cli_state *cli1;
4571         const char *fname = "\\test.txt";
4572         const char *fname1 = "\\test1.txt";
4573         bool correct = True;
4574         uint16_t fnum1;
4575         uint16_t attr;
4576         NTSTATUS status;
4577
4578         printf("starting rename test\n");
4579
4580         if (!torture_open_connection(&cli1, 0)) {
4581                 return False;
4582         }
4583
4584         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4585         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4586
4587         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4588                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4589                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
4590         if (!NT_STATUS_IS_OK(status)) {
4591                 printf("First open failed - %s\n", nt_errstr(status));
4592                 return False;
4593         }
4594
4595         status = cli_rename(cli1, fname, fname1);
4596         if (!NT_STATUS_IS_OK(status)) {
4597                 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4598         } else {
4599                 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4600                 correct = False;
4601         }
4602
4603         status = cli_close(cli1, fnum1);
4604         if (!NT_STATUS_IS_OK(status)) {
4605                 printf("close - 1 failed (%s)\n", nt_errstr(status));
4606                 return False;
4607         }
4608
4609         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4610         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4611         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4612 #if 0
4613                               FILE_SHARE_DELETE|FILE_SHARE_NONE,
4614 #else
4615                               FILE_SHARE_DELETE|FILE_SHARE_READ,
4616 #endif
4617                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
4618         if (!NT_STATUS_IS_OK(status)) {
4619                 printf("Second open failed - %s\n", nt_errstr(status));
4620                 return False;
4621         }
4622
4623         status = cli_rename(cli1, fname, fname1);
4624         if (!NT_STATUS_IS_OK(status)) {
4625                 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4626                 correct = False;
4627         } else {
4628                 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4629         }
4630
4631         status = cli_close(cli1, fnum1);
4632         if (!NT_STATUS_IS_OK(status)) {
4633                 printf("close - 2 failed (%s)\n", nt_errstr(status));
4634                 return False;
4635         }
4636
4637         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4638         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4639
4640         status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4641                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4642                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
4643         if (!NT_STATUS_IS_OK(status)) {
4644                 printf("Third open failed - %s\n", nt_errstr(status));
4645                 return False;
4646         }
4647
4648
4649 #if 0
4650   {
4651         uint16_t fnum2;
4652
4653         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4654                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4655                 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4656                 return False;
4657         }
4658         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4659                 printf("[8] setting delete_on_close on file failed !\n");
4660                 return False;
4661         }
4662
4663         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4664                 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4665                 return False;
4666         }
4667   }
4668 #endif
4669
4670         status = cli_rename(cli1, fname, fname1);
4671         if (!NT_STATUS_IS_OK(status)) {
4672                 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4673                 correct = False;
4674         } else {
4675                 printf("Third rename succeeded (SHARE_NONE)\n");
4676         }
4677
4678         status = cli_close(cli1, fnum1);
4679         if (!NT_STATUS_IS_OK(status)) {
4680                 printf("close - 3 failed (%s)\n", nt_errstr(status));
4681                 return False;
4682         }
4683
4684         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4685         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4686
4687         /*----*/
4688
4689         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4690                               FILE_ATTRIBUTE_NORMAL,
4691                               FILE_SHARE_READ | FILE_SHARE_WRITE,
4692                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
4693         if (!NT_STATUS_IS_OK(status)) {
4694                 printf("Fourth open failed - %s\n", nt_errstr(status));
4695                 return False;
4696         }
4697
4698         status = cli_rename(cli1, fname, fname1);
4699         if (!NT_STATUS_IS_OK(status)) {
4700                 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4701         } else {
4702                 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4703                 correct = False;
4704         }
4705
4706         status = cli_close(cli1, fnum1);
4707         if (!NT_STATUS_IS_OK(status)) {
4708                 printf("close - 4 failed (%s)\n", nt_errstr(status));
4709                 return False;
4710         }
4711
4712         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4713         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4714
4715         /*--*/
4716
4717         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4718                          FILE_ATTRIBUTE_NORMAL,
4719                          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4720                          FILE_OVERWRITE_IF, 0, 0, &fnum1);
4721         if (!NT_STATUS_IS_OK(status)) {
4722                 printf("Fifth open failed - %s\n", nt_errstr(status));
4723                 return False;
4724         }
4725
4726         status = cli_rename(cli1, fname, fname1);
4727         if (!NT_STATUS_IS_OK(status)) {
4728                 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4729                 correct = False;
4730         } else {
4731                 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4732         }
4733
4734         /*
4735          * Now check if the first name still exists ...
4736          */
4737
4738         /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4739                                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4740           printf("Opening original file after rename of open file fails: %s\n",
4741               cli_errstr(cli1));
4742         }
4743         else {
4744           printf("Opening original file after rename of open file works ...\n");
4745           (void)cli_close(cli1, fnum2);
4746           } */
4747
4748         /*--*/
4749         status = cli_close(cli1, fnum1);
4750         if (!NT_STATUS_IS_OK(status)) {
4751                 printf("close - 5 failed (%s)\n", nt_errstr(status));
4752                 return False;
4753         }
4754
4755         /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4756         status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4757         if (!NT_STATUS_IS_OK(status)) {
4758                 printf("getatr on file %s failed - %s ! \n",
4759                         fname1, nt_errstr(status));
4760                 correct = False;
4761         } else {
4762                 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4763                         printf("Renamed file %s has wrong attr 0x%x "
4764                                 "(should be 0x%x)\n",
4765                                 fname1,
4766                                 attr,
4767                                 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4768                         correct = False;
4769                 } else {
4770                         printf("Renamed file %s has archive bit set\n", fname1);
4771                 }
4772         }
4773
4774         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4775         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4776
4777         if (!torture_close_connection(cli1)) {
4778                 correct = False;
4779         }
4780
4781         return correct;
4782 }
4783
4784 static bool run_pipe_number(int dummy)
4785 {
4786         struct cli_state *cli1;
4787         const char *pipe_name = "\\SPOOLSS";
4788         uint16_t fnum;
4789         int num_pipes = 0;
4790         NTSTATUS status;
4791
4792         printf("starting pipenumber test\n");
4793         if (!torture_open_connection(&cli1, 0)) {
4794                 return False;
4795         }
4796
4797         smbXcli_conn_set_sockopt(cli1->conn, sockops);
4798         while(1) {
4799                 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
4800                                       FILE_ATTRIBUTE_NORMAL,
4801                                       FILE_SHARE_READ|FILE_SHARE_WRITE,
4802                                       FILE_OPEN_IF, 0, 0, &fnum);
4803                 if (!NT_STATUS_IS_OK(status)) {
4804                         printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
4805                         break;
4806                 }
4807                 num_pipes++;
4808                 printf("\r%6d", num_pipes);
4809         }
4810
4811         printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4812         torture_close_connection(cli1);
4813         return True;
4814 }
4815
4816 /*
4817   Test open mode returns on read-only files.
4818  */
4819 static bool run_opentest(int dummy)
4820 {
4821         static struct cli_state *cli1;
4822         static struct cli_state *cli2;
4823         const char *fname = "\\readonly.file";
4824         uint16_t fnum1, fnum2;
4825         char buf[20];
4826         off_t fsize;
4827         bool correct = True;
4828         char *tmp_path;
4829         NTSTATUS status;
4830
4831         printf("starting open test\n");
4832
4833         if (!torture_open_connection(&cli1, 0)) {
4834                 return False;
4835         }
4836
4837         cli_setatr(cli1, fname, 0, 0);
4838         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4839
4840         smbXcli_conn_set_sockopt(cli1->conn, sockops);
4841
4842         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4843         if (!NT_STATUS_IS_OK(status)) {
4844                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4845                 return False;
4846         }
4847
4848         status = cli_close(cli1, fnum1);
4849         if (!NT_STATUS_IS_OK(status)) {
4850                 printf("close2 failed (%s)\n", nt_errstr(status));
4851                 return False;
4852         }
4853
4854         status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
4855         if (!NT_STATUS_IS_OK(status)) {
4856                 printf("cli_setatr failed (%s)\n", nt_errstr(status));
4857                 return False;
4858         }
4859
4860         status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4861         if (!NT_STATUS_IS_OK(status)) {
4862                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4863                 return False;
4864         }
4865
4866         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4867         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4868
4869         if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
4870                         NT_STATUS_ACCESS_DENIED)) {
4871                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4872         }
4873
4874         printf("finished open test 1\n");
4875
4876         cli_close(cli1, fnum1);
4877
4878         /* Now try not readonly and ensure ERRbadshare is returned. */
4879
4880         cli_setatr(cli1, fname, 0, 0);
4881
4882         status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4883         if (!NT_STATUS_IS_OK(status)) {
4884                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4885                 return False;
4886         }
4887
4888         /* This will fail - but the error should be ERRshare. */
4889         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4890
4891         if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
4892                         NT_STATUS_SHARING_VIOLATION)) {
4893                 printf("correct error code ERRDOS/ERRbadshare returned\n");
4894         }
4895
4896         status = cli_close(cli1, fnum1);
4897         if (!NT_STATUS_IS_OK(status)) {
4898                 printf("close2 failed (%s)\n", nt_errstr(status));
4899                 return False;
4900         }
4901
4902         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4903
4904         printf("finished open test 2\n");
4905
4906         /* Test truncate open disposition on file opened for read. */
4907         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4908         if (!NT_STATUS_IS_OK(status)) {
4909                 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
4910                 return False;
4911         }
4912
4913         /* write 20 bytes. */
4914
4915         memset(buf, '\0', 20);
4916
4917         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4918         if (!NT_STATUS_IS_OK(status)) {
4919                 printf("write failed (%s)\n", nt_errstr(status));
4920                 correct = False;
4921         }
4922
4923         status = cli_close(cli1, fnum1);
4924         if (!NT_STATUS_IS_OK(status)) {
4925                 printf("(3) close1 failed (%s)\n", nt_errstr(status));
4926                 return False;
4927         }
4928
4929         /* Ensure size == 20. */
4930         status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4931         if (!NT_STATUS_IS_OK(status)) {
4932                 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4933                 return False;
4934         }
4935
4936         if (fsize != 20) {
4937                 printf("(3) file size != 20\n");
4938                 return False;
4939         }
4940
4941         /* Now test if we can truncate a file opened for readonly. */
4942         status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
4943         if (!NT_STATUS_IS_OK(status)) {
4944                 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
4945                 return False;
4946         }
4947
4948         status = cli_close(cli1, fnum1);
4949         if (!NT_STATUS_IS_OK(status)) {
4950                 printf("close2 failed (%s)\n", nt_errstr(status));
4951                 return False;
4952         }
4953
4954         /* Ensure size == 0. */
4955         status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4956         if (!NT_STATUS_IS_OK(status)) {
4957                 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4958                 return False;
4959         }
4960
4961         if (fsize != 0) {
4962                 printf("(3) file size != 0\n");
4963                 return False;
4964         }
4965         printf("finished open test 3\n");
4966
4967         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4968
4969         printf("Do ctemp tests\n");
4970         status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
4971         if (!NT_STATUS_IS_OK(status)) {
4972                 printf("ctemp failed (%s)\n", nt_errstr(status));
4973                 return False;
4974         }
4975
4976         printf("ctemp gave path %s\n", tmp_path);
4977         status = cli_close(cli1, fnum1);
4978         if (!NT_STATUS_IS_OK(status)) {
4979                 printf("close of temp failed (%s)\n", nt_errstr(status));
4980         }
4981
4982         status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4983         if (!NT_STATUS_IS_OK(status)) {
4984                 printf("unlink of temp failed (%s)\n", nt_errstr(status));
4985         }
4986
4987         /* Test the non-io opens... */
4988
4989         if (!torture_open_connection(&cli2, 1)) {
4990                 return False;
4991         }
4992
4993         cli_setatr(cli2, fname, 0, 0);
4994         cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4995
4996         smbXcli_conn_set_sockopt(cli2->conn, sockops);
4997
4998         printf("TEST #1 testing 2 non-io opens (no delete)\n");
4999         status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5000                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5001                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
5002         if (!NT_STATUS_IS_OK(status)) {
5003                 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5004                 return False;
5005         }
5006
5007         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5008                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5009                               FILE_OPEN_IF, 0, 0, &fnum2);
5010         if (!NT_STATUS_IS_OK(status)) {
5011                 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5012                 return False;
5013         }
5014
5015         status = cli_close(cli1, fnum1);
5016         if (!NT_STATUS_IS_OK(status)) {
5017                 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5018                 return False;
5019         }
5020
5021         status = cli_close(cli2, fnum2);
5022         if (!NT_STATUS_IS_OK(status)) {
5023                 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5024                 return False;
5025         }
5026
5027         printf("non-io open test #1 passed.\n");
5028
5029         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5030
5031         printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5032
5033         status = cli_ntcreate(cli1, fname, 0,
5034                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5035                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5036                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
5037         if (!NT_STATUS_IS_OK(status)) {
5038                 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5039                 return False;
5040         }
5041
5042         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5043                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5044                               FILE_OPEN_IF, 0, 0, &fnum2);
5045         if (!NT_STATUS_IS_OK(status)) {
5046                 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5047                 return False;
5048         }
5049
5050         status = cli_close(cli1, fnum1);
5051         if (!NT_STATUS_IS_OK(status)) {
5052                 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5053                 return False;
5054         }
5055
5056         status = cli_close(cli2, fnum2);
5057         if (!NT_STATUS_IS_OK(status)) {
5058                 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5059                 return False;
5060         }
5061
5062         printf("non-io open test #2 passed.\n");
5063
5064         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5065
5066         printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5067
5068         status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5069                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5070                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
5071         if (!NT_STATUS_IS_OK(status)) {
5072                 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5073                 return False;
5074         }
5075
5076         status = cli_ntcreate(cli2, fname, 0,
5077                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5078                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5079                               FILE_OPEN_IF, 0, 0, &fnum2);
5080         if (!NT_STATUS_IS_OK(status)) {
5081                 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5082                 return False;
5083         }
5084
5085         status = cli_close(cli1, fnum1);
5086         if (!NT_STATUS_IS_OK(status)) {
5087                 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5088                 return False;
5089         }
5090
5091         status = cli_close(cli2, fnum2);
5092         if (!NT_STATUS_IS_OK(status)) {
5093                 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5094                 return False;
5095         }
5096
5097         printf("non-io open test #3 passed.\n");
5098
5099         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5100
5101         printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5102
5103         status = cli_ntcreate(cli1, fname, 0,
5104                                DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5105                                FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5106                                FILE_OVERWRITE_IF, 0, 0, &fnum1);
5107         if (!NT_STATUS_IS_OK(status)) {
5108                 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5109                 return False;
5110         }
5111
5112         status = cli_ntcreate(cli2, fname, 0,
5113                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5114                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5115                               FILE_OPEN_IF, 0, 0, &fnum2);
5116         if (NT_STATUS_IS_OK(status)) {
5117                 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5118                 return False;
5119         }
5120
5121         printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5122
5123         status = cli_close(cli1, fnum1);
5124         if (!NT_STATUS_IS_OK(status)) {
5125                 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5126                 return False;
5127         }
5128
5129         printf("non-io open test #4 passed.\n");
5130
5131         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5132
5133         printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5134
5135         status = cli_ntcreate(cli1, fname, 0,
5136                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5137                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5138                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
5139         if (!NT_STATUS_IS_OK(status)) {
5140                 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5141                 return False;
5142         }
5143
5144         status = cli_ntcreate(cli2, fname, 0,
5145                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5146                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5147                               FILE_OPEN_IF, 0, 0, &fnum2);
5148         if (!NT_STATUS_IS_OK(status)) {
5149                 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5150                 return False;
5151         }
5152
5153         status = cli_close(cli1, fnum1);
5154         if (!NT_STATUS_IS_OK(status)) {
5155                 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5156                 return False;
5157         }
5158
5159         status = cli_close(cli2, fnum2);
5160         if (!NT_STATUS_IS_OK(status)) {
5161                 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5162                 return False;
5163         }
5164
5165         printf("non-io open test #5 passed.\n");
5166
5167         printf("TEST #6 testing 1 non-io open, one io open\n");
5168
5169         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5170
5171         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5172                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5173                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
5174         if (!NT_STATUS_IS_OK(status)) {
5175                 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5176                 return False;
5177         }
5178
5179         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5180                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5181                               FILE_OPEN_IF, 0, 0, &fnum2);
5182         if (!NT_STATUS_IS_OK(status)) {
5183                 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5184                 return False;
5185         }
5186
5187         status = cli_close(cli1, fnum1);
5188         if (!NT_STATUS_IS_OK(status)) {
5189                 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5190                 return False;
5191         }
5192
5193         status = cli_close(cli2, fnum2);
5194         if (!NT_STATUS_IS_OK(status)) {
5195                 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5196                 return False;
5197         }
5198
5199         printf("non-io open test #6 passed.\n");
5200
5201         printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5202
5203         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5204
5205         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5206                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5207                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
5208         if (!NT_STATUS_IS_OK(status)) {
5209                 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5210                 return False;
5211         }
5212
5213         status = cli_ntcreate(cli2, fname, 0,
5214                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5215                               FILE_ATTRIBUTE_NORMAL,
5216                               FILE_SHARE_READ|FILE_SHARE_DELETE,
5217                               FILE_OPEN_IF, 0, 0, &fnum2);
5218         if (NT_STATUS_IS_OK(status)) {
5219                 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5220                 return False;
5221         }
5222
5223         printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5224
5225         status = cli_close(cli1, fnum1);
5226         if (!NT_STATUS_IS_OK(status)) {
5227                 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5228                 return False;
5229         }
5230
5231         printf("non-io open test #7 passed.\n");
5232
5233         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5234
5235         printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5236         status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5237                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5238                                 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5239         if (!NT_STATUS_IS_OK(status)) {
5240                 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5241                 correct = false;
5242                 goto out;
5243         }
5244
5245         /* Write to ensure we have to update the file time. */
5246         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5247                               NULL);
5248         if (!NT_STATUS_IS_OK(status)) {
5249                 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5250                 correct = false;
5251                 goto out;
5252         }
5253
5254         status = cli_close(cli1, fnum1);
5255         if (!NT_STATUS_IS_OK(status)) {
5256                 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5257                 correct = false;
5258         }
5259
5260   out:
5261
5262         if (!torture_close_connection(cli1)) {
5263                 correct = False;
5264         }
5265         if (!torture_close_connection(cli2)) {
5266                 correct = False;
5267         }
5268
5269         return correct;
5270 }
5271
5272 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5273 {
5274         uint16 major, minor;
5275         uint32 caplow, caphigh;
5276         NTSTATUS status;
5277
5278         if (!SERVER_HAS_UNIX_CIFS(cli)) {
5279                 printf("Server doesn't support UNIX CIFS extensions.\n");
5280                 return NT_STATUS_NOT_SUPPORTED;
5281         }
5282
5283         status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5284                                              &caphigh);
5285         if (!NT_STATUS_IS_OK(status)) {
5286                 printf("Server didn't return UNIX CIFS extensions: %s\n",
5287                        nt_errstr(status));
5288                 return status;
5289         }
5290
5291         status = cli_set_unix_extensions_capabilities(cli, major, minor,
5292                                                       caplow, caphigh);
5293         if (!NT_STATUS_IS_OK(status)) {
5294                 printf("Server doesn't support setting UNIX CIFS extensions: "
5295                        "%s.\n", nt_errstr(status));
5296                 return status;
5297         }
5298
5299         return NT_STATUS_OK;
5300 }
5301
5302 /*
5303   Test POSIX open /mkdir calls.
5304  */
5305 static bool run_simple_posix_open_test(int dummy)
5306 {
5307         static struct cli_state *cli1;
5308         const char *fname = "posix:file";
5309         const char *hname = "posix:hlink";
5310         const char *sname = "posix:symlink";
5311         const char *dname = "posix:dir";
5312         char buf[10];
5313         char namebuf[11];
5314         uint16_t fnum1 = (uint16_t)-1;
5315         SMB_STRUCT_STAT sbuf;
5316         bool correct = false;
5317         NTSTATUS status;
5318         size_t nread;
5319
5320         printf("Starting simple POSIX open test\n");
5321
5322         if (!torture_open_connection(&cli1, 0)) {
5323                 return false;
5324         }
5325
5326         smbXcli_conn_set_sockopt(cli1->conn, sockops);
5327
5328         status = torture_setup_unix_extensions(cli1);
5329         if (!NT_STATUS_IS_OK(status)) {
5330                 return false;
5331         }
5332
5333         cli_setatr(cli1, fname, 0, 0);
5334         cli_posix_unlink(cli1, fname);
5335         cli_setatr(cli1, dname, 0, 0);
5336         cli_posix_rmdir(cli1, dname);
5337         cli_setatr(cli1, hname, 0, 0);
5338         cli_posix_unlink(cli1, hname);
5339         cli_setatr(cli1, sname, 0, 0);
5340         cli_posix_unlink(cli1, sname);
5341
5342         /* Create a directory. */
5343         status = cli_posix_mkdir(cli1, dname, 0777);
5344         if (!NT_STATUS_IS_OK(status)) {
5345                 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5346                 goto out;
5347         }
5348
5349         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5350                                 0600, &fnum1);
5351         if (!NT_STATUS_IS_OK(status)) {
5352                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5353                 goto out;
5354         }
5355
5356         /* Test ftruncate - set file size. */
5357         status = cli_ftruncate(cli1, fnum1, 1000);
5358         if (!NT_STATUS_IS_OK(status)) {
5359                 printf("ftruncate failed (%s)\n", nt_errstr(status));
5360                 goto out;
5361         }
5362
5363         /* Ensure st_size == 1000 */
5364         status = cli_posix_stat(cli1, fname, &sbuf);
5365         if (!NT_STATUS_IS_OK(status)) {
5366                 printf("stat failed (%s)\n", nt_errstr(status));
5367                 goto out;
5368         }
5369
5370         if (sbuf.st_ex_size != 1000) {
5371                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5372                 goto out;
5373         }
5374
5375         /* Ensure st_mode == 0600 */
5376         if ((sbuf.st_ex_mode & 07777) != 0600) {
5377                 printf("posix_open - bad permissions 0%o != 0600\n",
5378                                 (unsigned int)(sbuf.st_ex_mode & 07777));
5379                 goto out;
5380         }
5381
5382         /* Test ftruncate - set file size back to zero. */
5383         status = cli_ftruncate(cli1, fnum1, 0);
5384         if (!NT_STATUS_IS_OK(status)) {
5385                 printf("ftruncate failed (%s)\n", nt_errstr(status));
5386                 goto out;
5387         }
5388
5389         status = cli_close(cli1, fnum1);
5390         if (!NT_STATUS_IS_OK(status)) {
5391                 printf("close failed (%s)\n", nt_errstr(status));
5392                 goto out;
5393         }
5394
5395         /* Now open the file again for read only. */
5396         status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5397         if (!NT_STATUS_IS_OK(status)) {
5398                 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
5399                 goto out;
5400         }
5401
5402         /* Now unlink while open. */
5403         status = cli_posix_unlink(cli1, fname);
5404         if (!NT_STATUS_IS_OK(status)) {
5405                 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5406                 goto out;
5407         }
5408
5409         status = cli_close(cli1, fnum1);
5410         if (!NT_STATUS_IS_OK(status)) {
5411                 printf("close(2) failed (%s)\n", nt_errstr(status));
5412                 goto out;
5413         }
5414
5415         /* Ensure the file has gone. */
5416         status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5417         if (NT_STATUS_IS_OK(status)) {
5418                 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5419                 goto out;
5420         }
5421
5422         /* Create again to test open with O_TRUNC. */
5423         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
5424         if (!NT_STATUS_IS_OK(status)) {
5425                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5426                 goto out;
5427         }
5428
5429         /* Test ftruncate - set file size. */
5430         status = cli_ftruncate(cli1, fnum1, 1000);
5431         if (!NT_STATUS_IS_OK(status)) {
5432                 printf("ftruncate failed (%s)\n", nt_errstr(status));
5433                 goto out;
5434         }
5435
5436         /* Ensure st_size == 1000 */
5437         status = cli_posix_stat(cli1, fname, &sbuf);
5438         if (!NT_STATUS_IS_OK(status)) {
5439                 printf("stat failed (%s)\n", nt_errstr(status));
5440                 goto out;
5441         }
5442
5443         if (sbuf.st_ex_size != 1000) {
5444                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5445                 goto out;
5446         }
5447
5448         status = cli_close(cli1, fnum1);
5449         if (!NT_STATUS_IS_OK(status)) {
5450                 printf("close(2) failed (%s)\n", nt_errstr(status));
5451                 goto out;
5452         }
5453
5454         /* Re-open with O_TRUNC. */
5455         status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
5456         if (!NT_STATUS_IS_OK(status)) {
5457                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5458                 goto out;
5459         }
5460
5461         /* Ensure st_size == 0 */
5462         status = cli_posix_stat(cli1, fname, &sbuf);
5463         if (!NT_STATUS_IS_OK(status)) {
5464                 printf("stat failed (%s)\n", nt_errstr(status));
5465                 goto out;
5466         }
5467
5468         if (sbuf.st_ex_size != 0) {
5469                 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5470                 goto out;
5471         }
5472
5473         status = cli_close(cli1, fnum1);
5474         if (!NT_STATUS_IS_OK(status)) {
5475                 printf("close failed (%s)\n", nt_errstr(status));
5476                 goto out;
5477         }
5478
5479         status = cli_posix_unlink(cli1, fname);
5480         if (!NT_STATUS_IS_OK(status)) {
5481                 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5482                 goto out;
5483         }
5484
5485         status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
5486         if (!NT_STATUS_IS_OK(status)) {
5487                 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5488                         dname, nt_errstr(status));
5489                 goto out;
5490         }
5491
5492         cli_close(cli1, fnum1);
5493
5494         /* What happens when we try and POSIX open a directory for write ? */
5495         status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
5496         if (NT_STATUS_IS_OK(status)) {
5497                 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5498                 goto out;
5499         } else {
5500                 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
5501                                 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5502                         goto out;
5503                 }
5504         }
5505
5506         /* Create the file. */
5507         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5508                                 0600, &fnum1);
5509         if (!NT_STATUS_IS_OK(status)) {
5510                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5511                 goto out;
5512         }
5513
5514         /* Write some data into it. */
5515         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5516                               NULL);
5517         if (!NT_STATUS_IS_OK(status)) {
5518                 printf("cli_write failed: %s\n", nt_errstr(status));
5519                 goto out;
5520         }
5521
5522         cli_close(cli1, fnum1);
5523
5524         /* Now create a hardlink. */
5525         status = cli_posix_hardlink(cli1, fname, hname);
5526         if (!NT_STATUS_IS_OK(status)) {
5527                 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5528                 goto out;
5529         }
5530
5531         /* Now create a symlink. */
5532         status = cli_posix_symlink(cli1, fname, sname);
5533         if (!NT_STATUS_IS_OK(status)) {
5534                 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5535                 goto out;
5536         }
5537
5538         /* Open the hardlink for read. */
5539         status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5540         if (!NT_STATUS_IS_OK(status)) {
5541                 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5542                 goto out;
5543         }
5544
5545         status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
5546         if (!NT_STATUS_IS_OK(status)) {
5547                 printf("POSIX read of %s failed (%s)\n", hname,
5548                        nt_errstr(status));
5549                 goto out;
5550         } else if (nread != 10) {
5551                 printf("POSIX read of %s failed. Received %ld, expected %d\n",
5552                        hname, (unsigned long)nread, 10);
5553                 goto out;
5554         }
5555
5556         if (memcmp(buf, "TEST DATA\n", 10)) {
5557                 printf("invalid data read from hardlink\n");
5558                 goto out;
5559         }
5560
5561         /* Do a POSIX lock/unlock. */
5562         status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5563         if (!NT_STATUS_IS_OK(status)) {
5564                 printf("POSIX lock failed %s\n", nt_errstr(status));
5565                 goto out;
5566         }
5567
5568         /* Punch a hole in the locked area. */
5569         status = cli_posix_unlock(cli1, fnum1, 10, 80);
5570         if (!NT_STATUS_IS_OK(status)) {
5571                 printf("POSIX unlock failed %s\n", nt_errstr(status));
5572                 goto out;
5573         }
5574
5575         cli_close(cli1, fnum1);
5576
5577         /* Open the symlink for read - this should fail. A POSIX
5578            client should not be doing opens on a symlink. */
5579         status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5580         if (NT_STATUS_IS_OK(status)) {
5581                 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5582                 goto out;
5583         } else {
5584                 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
5585                                 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5586                         printf("POSIX open of %s should have failed "
5587                                 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5588                                 "failed with %s instead.\n",
5589                                 sname, nt_errstr(status));
5590                         goto out;
5591                 }
5592         }
5593
5594         status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5595         if (!NT_STATUS_IS_OK(status)) {
5596                 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5597                 goto out;
5598         }
5599
5600         if (strcmp(namebuf, fname) != 0) {
5601                 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5602                         sname, fname, namebuf);
5603                 goto out;
5604         }
5605
5606         status = cli_posix_rmdir(cli1, dname);
5607         if (!NT_STATUS_IS_OK(status)) {
5608                 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5609                 goto out;
5610         }
5611
5612         /* Check directory opens with a specific permission. */
5613         status = cli_posix_mkdir(cli1, dname, 0700);
5614         if (!NT_STATUS_IS_OK(status)) {
5615                 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5616                 goto out;
5617         }
5618
5619         /* Ensure st_mode == 0700 */
5620         status = cli_posix_stat(cli1, dname, &sbuf);
5621         if (!NT_STATUS_IS_OK(status)) {
5622                 printf("stat failed (%s)\n", nt_errstr(status));
5623                 goto out;
5624         }
5625
5626         if ((sbuf.st_ex_mode & 07777) != 0700) {
5627                 printf("posix_mkdir - bad permissions 0%o != 0700\n",
5628                                 (unsigned int)(sbuf.st_ex_mode & 07777));
5629                 goto out;
5630         }
5631
5632         printf("Simple POSIX open test passed\n");
5633         correct = true;
5634
5635   out:
5636
5637         if (fnum1 != (uint16_t)-1) {
5638                 cli_close(cli1, fnum1);
5639                 fnum1 = (uint16_t)-1;
5640         }
5641
5642         cli_setatr(cli1, sname, 0, 0);
5643         cli_posix_unlink(cli1, sname);
5644         cli_setatr(cli1, hname, 0, 0);
5645         cli_posix_unlink(cli1, hname);
5646         cli_setatr(cli1, fname, 0, 0);
5647         cli_posix_unlink(cli1, fname);
5648         cli_setatr(cli1, dname, 0, 0);
5649         cli_posix_rmdir(cli1, dname);
5650
5651         if (!torture_close_connection(cli1)) {
5652                 correct = false;
5653         }
5654
5655         return correct;
5656 }
5657
5658
5659 static uint32 open_attrs_table[] = {
5660                 FILE_ATTRIBUTE_NORMAL,
5661                 FILE_ATTRIBUTE_ARCHIVE,
5662                 FILE_ATTRIBUTE_READONLY,
5663                 FILE_ATTRIBUTE_HIDDEN,
5664                 FILE_ATTRIBUTE_SYSTEM,
5665
5666                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5667                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5668                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5669                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5670                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5671                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5672
5673                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5674                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5675                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5676                 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5677 };
5678
5679 struct trunc_open_results {
5680         unsigned int num;
5681         uint32 init_attr;
5682         uint32 trunc_attr;
5683         uint32 result_attr;
5684 };
5685
5686 static struct trunc_open_results attr_results[] = {
5687         { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5688         { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5689         { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5690         { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5691         { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5692         { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5693         { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5694         { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5695         { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5696         { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5697         { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5698         { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5699         { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5700         { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5701         { 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 },
5702         { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5703         { 119,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5704         { 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 },
5705         { 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 },
5706         { 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 },
5707         { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5708         { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5709         { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5710         { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5711         { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5712         { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5713 };
5714
5715 static bool run_openattrtest(int dummy)
5716 {
5717         static struct cli_state *cli1;
5718         const char *fname = "\\openattr.file";
5719         uint16_t fnum1;
5720         bool correct = True;
5721         uint16 attr;
5722         unsigned int i, j, k, l;
5723         NTSTATUS status;
5724
5725         printf("starting open attr test\n");
5726
5727         if (!torture_open_connection(&cli1, 0)) {
5728                 return False;
5729         }
5730
5731         smbXcli_conn_set_sockopt(cli1->conn, sockops);
5732
5733         for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5734                 cli_setatr(cli1, fname, 0, 0);
5735                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5736
5737                 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
5738                                        open_attrs_table[i], FILE_SHARE_NONE,
5739                                        FILE_OVERWRITE_IF, 0, 0, &fnum1);
5740                 if (!NT_STATUS_IS_OK(status)) {
5741                         printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5742                         return False;
5743                 }
5744
5745                 status = cli_close(cli1, fnum1);
5746                 if (!NT_STATUS_IS_OK(status)) {
5747                         printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5748                         return False;
5749                 }
5750
5751                 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5752                         status = cli_ntcreate(cli1, fname, 0,
5753                                               FILE_READ_DATA|FILE_WRITE_DATA,
5754                                               open_attrs_table[j],
5755                                               FILE_SHARE_NONE, FILE_OVERWRITE,
5756                                               0, 0, &fnum1);
5757                         if (!NT_STATUS_IS_OK(status)) {
5758                                 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5759                                         if (attr_results[l].num == k) {
5760                                                 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5761                                                                 k, open_attrs_table[i],
5762                                                                 open_attrs_table[j],
5763                                                                 fname, NT_STATUS_V(status), nt_errstr(status));
5764                                                 correct = False;
5765                                         }
5766                                 }
5767
5768                                 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5769                                         printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5770                                                         k, open_attrs_table[i], open_attrs_table[j],
5771                                                         nt_errstr(status));
5772                                         correct = False;
5773                                 }
5774 #if 0
5775                                 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5776 #endif
5777                                 k++;
5778                                 continue;
5779                         }
5780
5781                         status = cli_close(cli1, fnum1);
5782                         if (!NT_STATUS_IS_OK(status)) {
5783                                 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
5784                                 return False;
5785                         }
5786
5787                         status = cli_getatr(cli1, fname, &attr, NULL, NULL);
5788                         if (!NT_STATUS_IS_OK(status)) {
5789                                 printf("getatr(2) failed (%s)\n", nt_errstr(status));
5790                                 return False;
5791                         }
5792
5793 #if 0
5794                         printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5795                                         k,  open_attrs_table[i],  open_attrs_table[j], attr );
5796 #endif
5797
5798                         for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5799                                 if (attr_results[l].num == k) {
5800                                         if (attr != attr_results[l].result_attr ||
5801                                                         open_attrs_table[i] != attr_results[l].init_attr ||
5802                                                         open_attrs_table[j] != attr_results[l].trunc_attr) {
5803                                                 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5804                                                 open_attrs_table[i],
5805                                                 open_attrs_table[j],
5806                                                 (unsigned int)attr,
5807                                                 attr_results[l].result_attr);
5808                                                 correct = False;
5809                                         }
5810                                         break;
5811                                 }
5812                         }
5813                         k++;
5814                 }
5815         }
5816
5817         cli_setatr(cli1, fname, 0, 0);
5818         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5819
5820         printf("open attr test %s.\n", correct ? "passed" : "failed");
5821
5822         if (!torture_close_connection(cli1)) {
5823                 correct = False;
5824         }
5825         return correct;
5826 }
5827
5828 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5829                     const char *name, void *state)
5830 {
5831         int *matched = (int *)state;
5832         if (matched != NULL) {
5833                 *matched += 1;
5834         }
5835         return NT_STATUS_OK;
5836 }
5837
5838 /*
5839   test directory listing speed
5840  */
5841 static bool run_dirtest(int dummy)
5842 {
5843         int i;
5844         static struct cli_state *cli;
5845         uint16_t fnum;
5846         struct timeval core_start;
5847         bool correct = True;
5848         int matched;
5849
5850         printf("starting directory test\n");
5851
5852         if (!torture_open_connection(&cli, 0)) {
5853                 return False;
5854         }
5855
5856         smbXcli_conn_set_sockopt(cli->conn, sockops);
5857
5858         srandom(0);
5859         for (i=0;i<torture_numops;i++) {
5860                 fstring fname;
5861                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5862                 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5863                         fprintf(stderr,"Failed to open %s\n", fname);
5864                         return False;
5865                 }
5866                 cli_close(cli, fnum);
5867         }
5868
5869         core_start = timeval_current();
5870
5871         matched = 0;
5872         cli_list(cli, "a*.*", 0, list_fn, &matched);
5873         printf("Matched %d\n", matched);
5874
5875         matched = 0;
5876         cli_list(cli, "b*.*", 0, list_fn, &matched);
5877         printf("Matched %d\n", matched);
5878
5879         matched = 0;
5880         cli_list(cli, "xyzabc", 0, list_fn, &matched);
5881         printf("Matched %d\n", matched);
5882
5883         printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5884
5885         srandom(0);
5886         for (i=0;i<torture_numops;i++) {
5887                 fstring fname;
5888                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5889                 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5890         }
5891
5892         if (!torture_close_connection(cli)) {
5893                 correct = False;
5894         }
5895
5896         printf("finished dirtest\n");
5897
5898         return correct;
5899 }
5900
5901 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5902                    void *state)
5903 {
5904         struct cli_state *pcli = (struct cli_state *)state;
5905         fstring fname;
5906         slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5907
5908         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5909                 return NT_STATUS_OK;
5910
5911         if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5912                 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5913                         printf("del_fn: failed to rmdir %s\n,", fname );
5914         } else {
5915                 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5916                         printf("del_fn: failed to unlink %s\n,", fname );
5917         }
5918         return NT_STATUS_OK;
5919 }
5920
5921
5922 /*
5923   sees what IOCTLs are supported
5924  */
5925 bool torture_ioctl_test(int dummy)
5926 {
5927         static struct cli_state *cli;
5928         uint16_t device, function;
5929         uint16_t fnum;
5930         const char *fname = "\\ioctl.dat";
5931         DATA_BLOB blob;
5932         NTSTATUS status;
5933
5934         if (!torture_open_connection(&cli, 0)) {
5935                 return False;
5936         }
5937
5938         printf("starting ioctl test\n");
5939
5940         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5941
5942         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5943         if (!NT_STATUS_IS_OK(status)) {
5944                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5945                 return False;
5946         }
5947
5948         status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5949         printf("ioctl device info: %s\n", nt_errstr(status));
5950
5951         status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5952         printf("ioctl job info: %s\n", nt_errstr(status));
5953
5954         for (device=0;device<0x100;device++) {
5955                 printf("ioctl test with device = 0x%x\n", device);
5956                 for (function=0;function<0x100;function++) {
5957                         uint32 code = (device<<16) | function;
5958
5959                         status = cli_raw_ioctl(cli, fnum, code, &blob);
5960
5961                         if (NT_STATUS_IS_OK(status)) {
5962                                 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5963                                        (int)blob.length);
5964                                 data_blob_free(&blob);
5965                         }
5966                 }
5967         }
5968
5969         if (!torture_close_connection(cli)) {
5970                 return False;
5971         }
5972
5973         return True;
5974 }
5975
5976
5977 /*
5978   tries varients of chkpath
5979  */
5980 bool torture_chkpath_test(int dummy)
5981 {
5982         static struct cli_state *cli;
5983         uint16_t fnum;
5984         bool ret;
5985         NTSTATUS status;
5986
5987         if (!torture_open_connection(&cli, 0)) {
5988                 return False;
5989         }
5990
5991         printf("starting chkpath test\n");
5992
5993         /* cleanup from an old run */
5994         cli_rmdir(cli, "\\chkpath.dir\\dir2");
5995         cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5996         cli_rmdir(cli, "\\chkpath.dir");
5997
5998         status = cli_mkdir(cli, "\\chkpath.dir");
5999         if (!NT_STATUS_IS_OK(status)) {
6000                 printf("mkdir1 failed : %s\n", nt_errstr(status));
6001                 return False;
6002         }
6003
6004         status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
6005         if (!NT_STATUS_IS_OK(status)) {
6006                 printf("mkdir2 failed : %s\n", nt_errstr(status));
6007                 return False;
6008         }
6009
6010         status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
6011                           DENY_NONE, &fnum);
6012         if (!NT_STATUS_IS_OK(status)) {
6013                 printf("open1 failed (%s)\n", nt_errstr(status));
6014                 return False;
6015         }
6016         cli_close(cli, fnum);
6017
6018         status = cli_chkpath(cli, "\\chkpath.dir");
6019         if (!NT_STATUS_IS_OK(status)) {
6020                 printf("chkpath1 failed: %s\n", nt_errstr(status));
6021                 ret = False;
6022         }
6023
6024         status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
6025         if (!NT_STATUS_IS_OK(status)) {
6026                 printf("chkpath2 failed: %s\n", nt_errstr(status));
6027                 ret = False;
6028         }
6029
6030         status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
6031         if (!NT_STATUS_IS_OK(status)) {
6032                 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
6033                                   NT_STATUS_NOT_A_DIRECTORY);
6034         } else {
6035                 printf("* chkpath on a file should fail\n");
6036                 ret = False;
6037         }
6038
6039         status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
6040         if (!NT_STATUS_IS_OK(status)) {
6041                 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
6042                                   NT_STATUS_OBJECT_NAME_NOT_FOUND);
6043         } else {
6044                 printf("* chkpath on a non existent file should fail\n");
6045                 ret = False;
6046         }
6047
6048         status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
6049         if (!NT_STATUS_IS_OK(status)) {
6050                 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
6051                                   NT_STATUS_OBJECT_PATH_NOT_FOUND);
6052         } else {
6053                 printf("* chkpath on a non existent component should fail\n");
6054                 ret = False;
6055         }
6056
6057         cli_rmdir(cli, "\\chkpath.dir\\dir2");
6058         cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6059         cli_rmdir(cli, "\\chkpath.dir");
6060
6061         if (!torture_close_connection(cli)) {
6062                 return False;
6063         }
6064
6065         return ret;
6066 }
6067
6068 static bool run_eatest(int dummy)
6069 {
6070         static struct cli_state *cli;
6071         const char *fname = "\\eatest.txt";
6072         bool correct = True;
6073         uint16_t fnum;
6074         int i;
6075         size_t num_eas;
6076         struct ea_struct *ea_list = NULL;
6077         TALLOC_CTX *mem_ctx = talloc_init("eatest");
6078         NTSTATUS status;
6079
6080         printf("starting eatest\n");
6081
6082         if (!torture_open_connection(&cli, 0)) {
6083                 talloc_destroy(mem_ctx);
6084                 return False;
6085         }
6086
6087         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6088
6089         status = cli_ntcreate(cli, fname, 0,
6090                               FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6091                               FILE_SHARE_NONE, FILE_OVERWRITE_IF,
6092                               0x4044, 0, &fnum);
6093         if (!NT_STATUS_IS_OK(status)) {
6094                 printf("open failed - %s\n", nt_errstr(status));
6095                 talloc_destroy(mem_ctx);
6096                 return False;
6097         }
6098
6099         for (i = 0; i < 10; i++) {
6100                 fstring ea_name, ea_val;
6101
6102                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
6103                 memset(ea_val, (char)i+1, i+1);
6104                 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
6105                 if (!NT_STATUS_IS_OK(status)) {
6106                         printf("ea_set of name %s failed - %s\n", ea_name,
6107                                nt_errstr(status));
6108                         talloc_destroy(mem_ctx);
6109                         return False;
6110                 }
6111         }
6112
6113         cli_close(cli, fnum);
6114         for (i = 0; i < 10; i++) {
6115                 fstring ea_name, ea_val;
6116
6117                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
6118                 memset(ea_val, (char)i+1, i+1);
6119                 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
6120                 if (!NT_STATUS_IS_OK(status)) {
6121                         printf("ea_set of name %s failed - %s\n", ea_name,
6122                                nt_errstr(status));
6123                         talloc_destroy(mem_ctx);
6124                         return False;
6125                 }
6126         }
6127
6128         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6129         if (!NT_STATUS_IS_OK(status)) {
6130                 printf("ea_get list failed - %s\n", nt_errstr(status));
6131                 correct = False;
6132         }
6133
6134         printf("num_eas = %d\n", (int)num_eas);
6135
6136         if (num_eas != 20) {
6137                 printf("Should be 20 EA's stored... failing.\n");
6138                 correct = False;
6139         }
6140
6141         for (i = 0; i < num_eas; i++) {
6142                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6143                 dump_data(0, ea_list[i].value.data,
6144                           ea_list[i].value.length);
6145         }
6146
6147         /* Setting EA's to zero length deletes them. Test this */
6148         printf("Now deleting all EA's - case indepenent....\n");
6149
6150 #if 1
6151         cli_set_ea_path(cli, fname, "", "", 0);
6152 #else
6153         for (i = 0; i < 20; i++) {
6154                 fstring ea_name;
6155                 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
6156                 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
6157                 if (!NT_STATUS_IS_OK(status)) {
6158                         printf("ea_set of name %s failed - %s\n", ea_name,
6159                                nt_errstr(status));
6160                         talloc_destroy(mem_ctx);
6161                         return False;
6162                 }
6163         }
6164 #endif
6165
6166         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6167         if (!NT_STATUS_IS_OK(status)) {
6168                 printf("ea_get list failed - %s\n", nt_errstr(status));
6169                 correct = False;
6170         }
6171
6172         printf("num_eas = %d\n", (int)num_eas);
6173         for (i = 0; i < num_eas; i++) {
6174                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6175                 dump_data(0, ea_list[i].value.data,
6176                           ea_list[i].value.length);
6177         }
6178
6179         if (num_eas != 0) {
6180                 printf("deleting EA's failed.\n");
6181                 correct = False;
6182         }
6183
6184         /* Try and delete a non existent EA. */
6185         status = cli_set_ea_path(cli, fname, "foo", "", 0);
6186         if (!NT_STATUS_IS_OK(status)) {
6187                 printf("deleting non-existent EA 'foo' should succeed. %s\n",
6188                        nt_errstr(status));
6189                 correct = False;
6190         }
6191
6192         talloc_destroy(mem_ctx);
6193         if (!torture_close_connection(cli)) {
6194                 correct = False;
6195         }
6196
6197         return correct;
6198 }
6199
6200 static bool run_dirtest1(int dummy)
6201 {
6202         int i;
6203         static struct cli_state *cli;
6204         uint16_t fnum;
6205         int num_seen;
6206         bool correct = True;
6207
6208         printf("starting directory test\n");
6209
6210         if (!torture_open_connection(&cli, 0)) {
6211                 return False;
6212         }
6213
6214         smbXcli_conn_set_sockopt(cli->conn, sockops);
6215
6216         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6217         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6218         cli_rmdir(cli, "\\LISTDIR");
6219         cli_mkdir(cli, "\\LISTDIR");
6220
6221         /* Create 1000 files and 1000 directories. */
6222         for (i=0;i<1000;i++) {
6223                 fstring fname;
6224                 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
6225                 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6226                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6227                         fprintf(stderr,"Failed to open %s\n", fname);
6228                         return False;
6229                 }
6230                 cli_close(cli, fnum);
6231         }
6232         for (i=0;i<1000;i++) {
6233                 fstring fname;
6234                 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
6235                 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
6236                         fprintf(stderr,"Failed to open %s\n", fname);
6237                         return False;
6238                 }
6239         }
6240
6241         /* Now ensure that doing an old list sees both files and directories. */
6242         num_seen = 0;
6243         cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6244         printf("num_seen = %d\n", num_seen );
6245         /* We should see 100 files + 1000 directories + . and .. */
6246         if (num_seen != 2002)
6247                 correct = False;
6248
6249         /* Ensure if we have the "must have" bits we only see the
6250          * relevent entries.
6251          */
6252         num_seen = 0;
6253         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6254         printf("num_seen = %d\n", num_seen );
6255         if (num_seen != 1002)
6256                 correct = False;
6257
6258         num_seen = 0;
6259         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6260         printf("num_seen = %d\n", num_seen );
6261         if (num_seen != 1000)
6262                 correct = False;
6263
6264         /* Delete everything. */
6265         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6266         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6267         cli_rmdir(cli, "\\LISTDIR");
6268
6269 #if 0
6270         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
6271         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
6272         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
6273 #endif
6274
6275         if (!torture_close_connection(cli)) {
6276                 correct = False;
6277         }
6278
6279         printf("finished dirtest1\n");
6280
6281         return correct;
6282 }
6283
6284 static bool run_error_map_extract(int dummy) {
6285
6286         static struct cli_state *c_dos;
6287         static struct cli_state *c_nt;
6288         NTSTATUS status;
6289
6290         uint32 error;
6291
6292         uint32 errnum;
6293         uint8 errclass;
6294
6295         NTSTATUS nt_status;
6296
6297         fstring user;
6298
6299         /* NT-Error connection */
6300
6301         disable_spnego = true;
6302         if (!(c_nt = open_nbt_connection())) {
6303                 disable_spnego = false;
6304                 return False;
6305         }
6306         disable_spnego = false;
6307
6308         status = smbXcli_negprot(c_nt->conn, c_nt->timeout, PROTOCOL_CORE,
6309                                  PROTOCOL_NT1);
6310
6311         if (!NT_STATUS_IS_OK(status)) {
6312                 printf("%s rejected the NT-error negprot (%s)\n", host,
6313                        nt_errstr(status));
6314                 cli_shutdown(c_nt);
6315                 return False;
6316         }
6317
6318         status = cli_session_setup(c_nt, "", "", 0, "", 0, workgroup);
6319         if (!NT_STATUS_IS_OK(status)) {
6320                 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
6321                 return False;
6322         }
6323
6324         /* DOS-Error connection */
6325
6326         disable_spnego = true;
6327         force_dos_errors = true;
6328         if (!(c_dos = open_nbt_connection())) {
6329                 disable_spnego = false;
6330                 force_dos_errors = false;
6331                 return False;
6332         }
6333         disable_spnego = false;
6334         force_dos_errors = false;
6335
6336         status = smbXcli_negprot(c_dos->conn, c_dos->timeout, PROTOCOL_CORE,
6337                                  PROTOCOL_NT1);
6338         if (!NT_STATUS_IS_OK(status)) {
6339                 printf("%s rejected the DOS-error negprot (%s)\n", host,
6340                        nt_errstr(status));
6341                 cli_shutdown(c_dos);
6342                 return False;
6343         }
6344
6345         status = cli_session_setup(c_dos, "", "", 0, "", 0, workgroup);
6346         if (!NT_STATUS_IS_OK(status)) {
6347                 printf("%s rejected the DOS-error initial session setup (%s)\n",
6348                         host, nt_errstr(status));
6349                 return False;
6350         }
6351
6352         c_nt->map_dos_errors = false;
6353         c_dos->map_dos_errors = false;
6354
6355         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
6356                 fstr_sprintf(user, "%X", error);
6357
6358                 status = cli_session_setup(c_nt, user,
6359                                            password, strlen(password),
6360                                            password, strlen(password),
6361                                            workgroup);
6362                 if (NT_STATUS_IS_OK(status)) {
6363                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
6364                 }
6365
6366                 /* Case #1: 32-bit NT errors */
6367                 if (!NT_STATUS_IS_DOS(status)) {
6368                         nt_status = status;
6369                 } else {
6370                         printf("/** Dos error on NT connection! (%s) */\n", 
6371                                nt_errstr(status));
6372                         nt_status = NT_STATUS(0xc0000000);
6373                 }
6374
6375                 status = cli_session_setup(c_dos, user,
6376                                            password, strlen(password),
6377                                            password, strlen(password),
6378                                            workgroup);
6379                 if (NT_STATUS_IS_OK(status)) {
6380                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
6381                 }
6382
6383                 /* Case #1: 32-bit NT errors */
6384                 if (NT_STATUS_IS_DOS(status)) {
6385                         printf("/** NT error on DOS connection! (%s) */\n", 
6386                                nt_errstr(status));
6387                         errnum = errclass = 0;
6388                 } else {
6389                         errclass = NT_STATUS_DOS_CLASS(status);
6390                         errnum = NT_STATUS_DOS_CODE(status);
6391                 }
6392
6393                 if (NT_STATUS_V(nt_status) != error) { 
6394                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
6395                                get_nt_error_c_code(talloc_tos(), NT_STATUS(error)), 
6396                                get_nt_error_c_code(talloc_tos(), nt_status));
6397                 }
6398
6399                 printf("\t{%s,\t%s,\t%s},\n", 
6400                        smb_dos_err_class(errclass), 
6401                        smb_dos_err_name(errclass, errnum), 
6402                        get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
6403         }
6404         return True;
6405 }
6406
6407 static bool run_sesssetup_bench(int dummy)
6408 {
6409         static struct cli_state *c;
6410         const char *fname = "\\file.dat";
6411         uint16_t fnum;
6412         NTSTATUS status;
6413         int i;
6414
6415         if (!torture_open_connection(&c, 0)) {
6416                 return false;
6417         }
6418
6419         status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6420                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6421                               FILE_DELETE_ON_CLOSE, 0, &fnum);
6422         if (!NT_STATUS_IS_OK(status)) {
6423                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6424                 return false;
6425         }
6426
6427         for (i=0; i<torture_numops; i++) {
6428                 status = cli_session_setup(
6429                         c, username,
6430                         password, strlen(password),
6431                         password, strlen(password),
6432                         workgroup);
6433                 if (!NT_STATUS_IS_OK(status)) {
6434                         d_printf("(%s) cli_session_setup failed: %s\n",
6435                                  __location__, nt_errstr(status));
6436                         return false;
6437                 }
6438
6439                 d_printf("\r%d   ", (int)cli_state_get_uid(c));
6440
6441                 status = cli_ulogoff(c);
6442                 if (!NT_STATUS_IS_OK(status)) {
6443                         d_printf("(%s) cli_ulogoff failed: %s\n",
6444                                  __location__, nt_errstr(status));
6445                         return false;
6446                 }
6447         }
6448
6449         return true;
6450 }
6451
6452 static bool subst_test(const char *str, const char *user, const char *domain,
6453                        uid_t uid, gid_t gid, const char *expected)
6454 {
6455         char *subst;
6456         bool result = true;
6457
6458         subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
6459
6460         if (strcmp(subst, expected) != 0) {
6461                 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6462                        "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
6463                        expected);
6464                 result = false;
6465         }
6466
6467         TALLOC_FREE(subst);
6468         return result;
6469 }
6470
6471 static void chain1_open_completion(struct tevent_req *req)
6472 {
6473         uint16_t fnum;
6474         NTSTATUS status;
6475         status = cli_openx_recv(req, &fnum);
6476         TALLOC_FREE(req);
6477
6478         d_printf("cli_openx_recv returned %s: %d\n",
6479                  nt_errstr(status),
6480                  NT_STATUS_IS_OK(status) ? fnum : -1);
6481 }
6482
6483 static void chain1_write_completion(struct tevent_req *req)
6484 {
6485         size_t written;
6486         NTSTATUS status;
6487         status = cli_write_andx_recv(req, &written);
6488         TALLOC_FREE(req);
6489
6490         d_printf("cli_write_andx_recv returned %s: %d\n",
6491                  nt_errstr(status),
6492                  NT_STATUS_IS_OK(status) ? (int)written : -1);
6493 }
6494
6495 static void chain1_close_completion(struct tevent_req *req)
6496 {
6497         NTSTATUS status;
6498         bool *done = (bool *)tevent_req_callback_data_void(req);
6499
6500         status = cli_close_recv(req);
6501         *done = true;
6502
6503         TALLOC_FREE(req);
6504
6505         d_printf("cli_close returned %s\n", nt_errstr(status));
6506 }
6507
6508 static bool run_chain1(int dummy)
6509 {
6510         struct cli_state *cli1;
6511         struct event_context *evt = event_context_init(NULL);
6512         struct tevent_req *reqs[3], *smbreqs[3];
6513         bool done = false;
6514         const char *str = "foobar";
6515         NTSTATUS status;
6516
6517         printf("starting chain1 test\n");
6518         if (!torture_open_connection(&cli1, 0)) {
6519                 return False;
6520         }
6521
6522         smbXcli_conn_set_sockopt(cli1->conn, sockops);
6523
6524         reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, "\\test",
6525                                   O_CREAT|O_RDWR, 0, &smbreqs[0]);
6526         if (reqs[0] == NULL) return false;
6527         tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6528
6529
6530         reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6531                                         (const uint8_t *)str, 0, strlen(str)+1,
6532                                         smbreqs, 1, &smbreqs[1]);
6533         if (reqs[1] == NULL) return false;
6534         tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6535
6536         reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6537         if (reqs[2] == NULL) return false;
6538         tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6539
6540         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
6541         if (!NT_STATUS_IS_OK(status)) {
6542                 return false;
6543         }
6544
6545         while (!done) {
6546                 tevent_loop_once(evt);
6547         }
6548
6549         torture_close_connection(cli1);
6550         return True;
6551 }
6552
6553 static void chain2_sesssetup_completion(struct tevent_req *req)
6554 {
6555         NTSTATUS status;
6556         status = cli_session_setup_guest_recv(req);
6557         d_printf("sesssetup returned %s\n", nt_errstr(status));
6558 }
6559
6560 static void chain2_tcon_completion(struct tevent_req *req)
6561 {
6562         bool *done = (bool *)tevent_req_callback_data_void(req);
6563         NTSTATUS status;
6564         status = cli_tcon_andx_recv(req);
6565         d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6566         *done = true;
6567 }
6568
6569 static bool run_chain2(int dummy)
6570 {
6571         struct cli_state *cli1;
6572         struct event_context *evt = event_context_init(NULL);
6573         struct tevent_req *reqs[2], *smbreqs[2];
6574         bool done = false;
6575         NTSTATUS status;
6576
6577         printf("starting chain2 test\n");
6578         status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
6579                                       port_to_use, SMB_SIGNING_DEFAULT, 0);
6580         if (!NT_STATUS_IS_OK(status)) {
6581                 return False;
6582         }
6583
6584         smbXcli_conn_set_sockopt(cli1->conn, sockops);
6585
6586         reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6587                                                  &smbreqs[0]);
6588         if (reqs[0] == NULL) return false;
6589         tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6590
6591         reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6592                                        "?????", NULL, 0, &smbreqs[1]);
6593         if (reqs[1] == NULL) return false;
6594         tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6595
6596         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
6597         if (!NT_STATUS_IS_OK(status)) {
6598                 return false;
6599         }
6600
6601         while (!done) {
6602                 tevent_loop_once(evt);
6603         }
6604
6605         torture_close_connection(cli1);
6606         return True;
6607 }
6608
6609
6610 struct torture_createdel_state {
6611         struct tevent_context *ev;
6612         struct cli_state *cli;
6613 };
6614
6615 static void torture_createdel_created(struct tevent_req *subreq);
6616 static void torture_createdel_closed(struct tevent_req *subreq);
6617
6618 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6619                                                  struct tevent_context *ev,
6620                                                  struct cli_state *cli,
6621                                                  const char *name)
6622 {
6623         struct tevent_req *req, *subreq;
6624         struct torture_createdel_state *state;
6625
6626         req = tevent_req_create(mem_ctx, &state,
6627                                 struct torture_createdel_state);
6628         if (req == NULL) {
6629                 return NULL;
6630         }
6631         state->ev = ev;
6632         state->cli = cli;
6633
6634         subreq = cli_ntcreate_send(
6635                 state, ev, cli, name, 0,
6636                 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6637                 FILE_ATTRIBUTE_NORMAL,
6638                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6639                 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6640
6641         if (tevent_req_nomem(subreq, req)) {
6642                 return tevent_req_post(req, ev);
6643         }
6644         tevent_req_set_callback(subreq, torture_createdel_created, req);
6645         return req;
6646 }
6647
6648 static void torture_createdel_created(struct tevent_req *subreq)
6649 {
6650         struct tevent_req *req = tevent_req_callback_data(
6651                 subreq, struct tevent_req);
6652         struct torture_createdel_state *state = tevent_req_data(
6653                 req, struct torture_createdel_state);
6654         NTSTATUS status;
6655         uint16_t fnum;
6656
6657         status = cli_ntcreate_recv(subreq, &fnum);
6658         TALLOC_FREE(subreq);
6659         if (!NT_STATUS_IS_OK(status)) {
6660                 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6661                            nt_errstr(status)));
6662                 tevent_req_nterror(req, status);
6663                 return;
6664         }
6665
6666         subreq = cli_close_send(state, state->ev, state->cli, fnum);
6667         if (tevent_req_nomem(subreq, req)) {
6668                 return;
6669         }
6670         tevent_req_set_callback(subreq, torture_createdel_closed, req);
6671 }
6672
6673 static void torture_createdel_closed(struct tevent_req *subreq)
6674 {
6675         struct tevent_req *req = tevent_req_callback_data(
6676                 subreq, struct tevent_req);
6677         NTSTATUS status;
6678
6679         status = cli_close_recv(subreq);
6680         if (!NT_STATUS_IS_OK(status)) {
6681                 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6682                 tevent_req_nterror(req, status);
6683                 return;
6684         }
6685         tevent_req_done(req);
6686 }
6687
6688 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6689 {
6690         return tevent_req_simple_recv_ntstatus(req);
6691 }
6692
6693 struct torture_createdels_state {
6694         struct tevent_context *ev;
6695         struct cli_state *cli;
6696         const char *base_name;
6697         int sent;
6698         int received;
6699         int num_files;
6700         struct tevent_req **reqs;
6701 };
6702
6703 static void torture_createdels_done(struct tevent_req *subreq);
6704
6705 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6706                                                   struct tevent_context *ev,
6707                                                   struct cli_state *cli,
6708                                                   const char *base_name,
6709                                                   int num_parallel,
6710                                                   int num_files)
6711 {
6712         struct tevent_req *req;
6713         struct torture_createdels_state *state;
6714         int i;
6715
6716         req = tevent_req_create(mem_ctx, &state,
6717                                 struct torture_createdels_state);
6718         if (req == NULL) {
6719                 return NULL;
6720         }
6721         state->ev = ev;
6722         state->cli = cli;
6723         state->base_name = talloc_strdup(state, base_name);
6724         if (tevent_req_nomem(state->base_name, req)) {
6725                 return tevent_req_post(req, ev);
6726         }
6727         state->num_files = MAX(num_parallel, num_files);
6728         state->sent = 0;
6729         state->received = 0;
6730
6731         state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6732         if (tevent_req_nomem(state->reqs, req)) {
6733                 return tevent_req_post(req, ev);
6734         }
6735
6736         for (i=0; i<num_parallel; i++) {
6737                 char *name;
6738
6739                 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6740                                        state->sent);
6741                 if (tevent_req_nomem(name, req)) {
6742                         return tevent_req_post(req, ev);
6743                 }
6744                 state->reqs[i] = torture_createdel_send(
6745                         state->reqs, state->ev, state->cli, name);
6746                 if (tevent_req_nomem(state->reqs[i], req)) {
6747                         return tevent_req_post(req, ev);
6748                 }
6749                 name = talloc_move(state->reqs[i], &name);
6750                 tevent_req_set_callback(state->reqs[i],
6751                                         torture_createdels_done, req);
6752                 state->sent += 1;
6753         }
6754         return req;
6755 }
6756
6757 static void torture_createdels_done(struct tevent_req *subreq)
6758 {
6759         struct tevent_req *req = tevent_req_callback_data(
6760                 subreq, struct tevent_req);
6761         struct torture_createdels_state *state = tevent_req_data(
6762                 req, struct torture_createdels_state);
6763         size_t num_parallel = talloc_array_length(state->reqs);
6764         NTSTATUS status;
6765         char *name;
6766         int i;
6767
6768         status = torture_createdel_recv(subreq);
6769         if (!NT_STATUS_IS_OK(status)){
6770                 DEBUG(10, ("torture_createdel_recv returned %s\n",
6771                            nt_errstr(status)));
6772                 TALLOC_FREE(subreq);
6773                 tevent_req_nterror(req, status);
6774                 return;
6775         }
6776
6777         for (i=0; i<num_parallel; i++) {
6778                 if (subreq == state->reqs[i]) {
6779                         break;
6780                 }
6781         }
6782         if (i == num_parallel) {
6783                 DEBUG(10, ("received something we did not send\n"));
6784                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6785                 return;
6786         }
6787         TALLOC_FREE(state->reqs[i]);
6788
6789         if (state->sent >= state->num_files) {
6790                 tevent_req_done(req);
6791                 return;
6792         }
6793
6794         name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6795                                state->sent);
6796         if (tevent_req_nomem(name, req)) {
6797                 return;
6798         }
6799         state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6800                                                 state->cli, name);
6801         if (tevent_req_nomem(state->reqs[i], req)) {
6802                 return;
6803         }
6804         name = talloc_move(state->reqs[i], &name);
6805         tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6806         state->sent += 1;
6807 }
6808
6809 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6810 {
6811         return tevent_req_simple_recv_ntstatus(req);
6812 }
6813
6814 struct swallow_notify_state {
6815         struct tevent_context *ev;
6816         struct cli_state *cli;
6817         uint16_t fnum;
6818         uint32_t completion_filter;
6819         bool recursive;
6820         bool (*fn)(uint32_t action, const char *name, void *priv);
6821         void *priv;
6822 };
6823
6824 static void swallow_notify_done(struct tevent_req *subreq);
6825
6826 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6827                                               struct tevent_context *ev,
6828                                               struct cli_state *cli,
6829                                               uint16_t fnum,
6830                                               uint32_t completion_filter,
6831                                               bool recursive,
6832                                               bool (*fn)(uint32_t action,
6833                                                          const char *name,
6834                                                          void *priv),
6835                                               void *priv)
6836 {
6837         struct tevent_req *req, *subreq;
6838         struct swallow_notify_state *state;
6839
6840         req = tevent_req_create(mem_ctx, &state,
6841                                 struct swallow_notify_state);
6842         if (req == NULL) {
6843                 return NULL;
6844         }
6845         state->ev = ev;
6846         state->cli = cli;
6847         state->fnum = fnum;
6848         state->completion_filter = completion_filter;
6849         state->recursive = recursive;
6850         state->fn = fn;
6851         state->priv = priv;
6852
6853         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6854                                  0xffff, state->completion_filter,
6855                                  state->recursive);
6856         if (tevent_req_nomem(subreq, req)) {
6857                 return tevent_req_post(req, ev);
6858         }
6859         tevent_req_set_callback(subreq, swallow_notify_done, req);
6860         return req;
6861 }
6862
6863 static void swallow_notify_done(struct tevent_req *subreq)
6864 {
6865         struct tevent_req *req = tevent_req_callback_data(
6866                 subreq, struct tevent_req);
6867         struct swallow_notify_state *state = tevent_req_data(
6868                 req, struct swallow_notify_state);
6869         NTSTATUS status;
6870         uint32_t i, num_changes;
6871         struct notify_change *changes;
6872
6873         status = cli_notify_recv(subreq, state, &num_changes, &changes);
6874         TALLOC_FREE(subreq);
6875         if (!NT_STATUS_IS_OK(status)) {
6876                 DEBUG(10, ("cli_notify_recv returned %s\n",
6877                            nt_errstr(status)));
6878                 tevent_req_nterror(req, status);
6879                 return;
6880         }
6881
6882         for (i=0; i<num_changes; i++) {
6883                 state->fn(changes[i].action, changes[i].name, state->priv);
6884         }
6885         TALLOC_FREE(changes);
6886
6887         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6888                                  0xffff, state->completion_filter,
6889                                  state->recursive);
6890         if (tevent_req_nomem(subreq, req)) {
6891                 return;
6892         }
6893         tevent_req_set_callback(subreq, swallow_notify_done, req);
6894 }
6895
6896 static bool print_notifies(uint32_t action, const char *name, void *priv)
6897 {
6898         if (DEBUGLEVEL > 5) {
6899                 d_printf("%d %s\n", (int)action, name);
6900         }
6901         return true;
6902 }
6903
6904 static void notify_bench_done(struct tevent_req *req)
6905 {
6906         int *num_finished = (int *)tevent_req_callback_data_void(req);
6907         *num_finished += 1;
6908 }
6909
6910 static bool run_notify_bench(int dummy)
6911 {
6912         const char *dname = "\\notify-bench";
6913         struct tevent_context *ev;
6914         NTSTATUS status;
6915         uint16_t dnum;
6916         struct tevent_req *req1;
6917         struct tevent_req *req2 = NULL;
6918         int i, num_unc_names;
6919         int num_finished = 0;
6920
6921         printf("starting notify-bench test\n");
6922
6923         if (use_multishare_conn) {
6924                 char **unc_list;
6925                 unc_list = file_lines_load(multishare_conn_fname,
6926                                            &num_unc_names, 0, NULL);
6927                 if (!unc_list || num_unc_names <= 0) {
6928                         d_printf("Failed to load unc names list from '%s'\n",
6929                                  multishare_conn_fname);
6930                         return false;
6931                 }
6932                 TALLOC_FREE(unc_list);
6933         } else {
6934                 num_unc_names = 1;
6935         }
6936
6937         ev = tevent_context_init(talloc_tos());
6938         if (ev == NULL) {
6939                 d_printf("tevent_context_init failed\n");
6940                 return false;
6941         }
6942
6943         for (i=0; i<num_unc_names; i++) {
6944                 struct cli_state *cli;
6945                 char *base_fname;
6946
6947                 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6948                                              dname, i);
6949                 if (base_fname == NULL) {
6950                         return false;
6951                 }
6952
6953                 if (!torture_open_connection(&cli, i)) {
6954                         return false;
6955                 }
6956
6957                 status = cli_ntcreate(cli, dname, 0,
6958                                       MAXIMUM_ALLOWED_ACCESS,
6959                                       0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6960                                       FILE_SHARE_DELETE,
6961                                       FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6962                                       &dnum);
6963
6964                 if (!NT_STATUS_IS_OK(status)) {
6965                         d_printf("Could not create %s: %s\n", dname,
6966                                  nt_errstr(status));
6967                         return false;
6968                 }
6969
6970                 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6971                                            FILE_NOTIFY_CHANGE_FILE_NAME |
6972                                            FILE_NOTIFY_CHANGE_DIR_NAME |
6973                                            FILE_NOTIFY_CHANGE_ATTRIBUTES |
6974                                            FILE_NOTIFY_CHANGE_LAST_WRITE,
6975                                            false, print_notifies, NULL);
6976                 if (req1 == NULL) {
6977                         d_printf("Could not create notify request\n");
6978                         return false;
6979                 }
6980
6981                 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6982                                                base_fname, 10, torture_numops);
6983                 if (req2 == NULL) {
6984                         d_printf("Could not create createdels request\n");
6985                         return false;
6986                 }
6987                 TALLOC_FREE(base_fname);
6988
6989                 tevent_req_set_callback(req2, notify_bench_done,
6990                                         &num_finished);
6991         }
6992
6993         while (num_finished < num_unc_names) {
6994                 int ret;
6995                 ret = tevent_loop_once(ev);
6996                 if (ret != 0) {
6997                         d_printf("tevent_loop_once failed\n");
6998                         return false;
6999                 }
7000         }
7001
7002         if (!tevent_req_poll(req2, ev)) {
7003                 d_printf("tevent_req_poll failed\n");
7004         }
7005
7006         status = torture_createdels_recv(req2);
7007         d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
7008
7009         return true;
7010 }
7011
7012 static bool run_mangle1(int dummy)
7013 {
7014         struct cli_state *cli;
7015         const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
7016         uint16_t fnum;
7017         fstring alt_name;
7018         NTSTATUS status;
7019         time_t change_time, access_time, write_time;
7020         off_t size;
7021         uint16_t mode;
7022
7023         printf("starting mangle1 test\n");
7024         if (!torture_open_connection(&cli, 0)) {
7025                 return False;
7026         }
7027
7028         smbXcli_conn_set_sockopt(cli->conn, sockops);
7029
7030         status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
7031                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7032                               0, 0, &fnum);
7033         if (!NT_STATUS_IS_OK(status)) {
7034                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7035                 return false;
7036         }
7037         cli_close(cli, fnum);
7038
7039         status = cli_qpathinfo_alt_name(cli, fname, alt_name);
7040         if (!NT_STATUS_IS_OK(status)) {
7041                 d_printf("cli_qpathinfo_alt_name failed: %s\n",
7042                          nt_errstr(status));
7043                 return false;
7044         }
7045         d_printf("alt_name: %s\n", alt_name);
7046
7047         status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
7048         if (!NT_STATUS_IS_OK(status)) {
7049                 d_printf("cli_openx(%s) failed: %s\n", alt_name,
7050                          nt_errstr(status));
7051                 return false;
7052         }
7053         cli_close(cli, fnum);
7054
7055         status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
7056                                 &write_time, &size, &mode);
7057         if (!NT_STATUS_IS_OK(status)) {
7058                 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
7059                          nt_errstr(status));
7060                 return false;
7061         }
7062
7063         return true;
7064 }
7065
7066 static size_t null_source(uint8_t *buf, size_t n, void *priv)
7067 {
7068         size_t *to_pull = (size_t *)priv;
7069         size_t thistime = *to_pull;
7070
7071         thistime = MIN(thistime, n);
7072         if (thistime == 0) {
7073                 return 0;
7074         }
7075
7076         memset(buf, 0, thistime);
7077         *to_pull -= thistime;
7078         return thistime;
7079 }
7080
7081 static bool run_windows_write(int dummy)
7082 {
7083         struct cli_state *cli1;
7084         uint16_t fnum;
7085         int i;
7086         bool ret = false;
7087         const char *fname = "\\writetest.txt";
7088         struct timeval start_time;
7089         double seconds;
7090         double kbytes;
7091         NTSTATUS status;
7092
7093         printf("starting windows_write test\n");
7094         if (!torture_open_connection(&cli1, 0)) {
7095                 return False;
7096         }
7097
7098         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7099         if (!NT_STATUS_IS_OK(status)) {
7100                 printf("open failed (%s)\n", nt_errstr(status));
7101                 return False;
7102         }
7103
7104         smbXcli_conn_set_sockopt(cli1->conn, sockops);
7105
7106         start_time = timeval_current();
7107
7108         for (i=0; i<torture_numops; i++) {
7109                 uint8_t c = 0;
7110                 off_t start = i * torture_blocksize;
7111                 size_t to_pull = torture_blocksize - 1;
7112
7113                 status = cli_writeall(cli1, fnum, 0, &c,
7114                                       start + torture_blocksize - 1, 1, NULL);
7115                 if (!NT_STATUS_IS_OK(status)) {
7116                         printf("cli_write failed: %s\n", nt_errstr(status));
7117                         goto fail;
7118                 }
7119
7120                 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
7121                                   null_source, &to_pull);
7122                 if (!NT_STATUS_IS_OK(status)) {
7123                         printf("cli_push returned: %s\n", nt_errstr(status));
7124                         goto fail;
7125                 }
7126         }
7127
7128         seconds = timeval_elapsed(&start_time);
7129         kbytes = (double)torture_blocksize * torture_numops;
7130         kbytes /= 1024;
7131
7132         printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
7133                (double)seconds, (int)(kbytes/seconds));
7134
7135         ret = true;
7136  fail:
7137         cli_close(cli1, fnum);
7138         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7139         torture_close_connection(cli1);
7140         return ret;
7141 }
7142
7143 static bool run_cli_echo(int dummy)
7144 {
7145         struct cli_state *cli;
7146         NTSTATUS status;
7147
7148         printf("starting cli_echo test\n");
7149         if (!torture_open_connection(&cli, 0)) {
7150                 return false;
7151         }
7152         smbXcli_conn_set_sockopt(cli->conn, sockops);
7153
7154         status = cli_echo(cli, 5, data_blob_const("hello", 5));
7155
7156         d_printf("cli_echo returned %s\n", nt_errstr(status));
7157
7158         torture_close_connection(cli);
7159         return NT_STATUS_IS_OK(status);
7160 }
7161
7162 static bool run_uid_regression_test(int dummy)
7163 {
7164         static struct cli_state *cli;
7165         int16_t old_vuid;
7166         int16_t old_cnum;
7167         bool correct = True;
7168         NTSTATUS status;
7169
7170         printf("starting uid regression test\n");
7171
7172         if (!torture_open_connection(&cli, 0)) {
7173                 return False;
7174         }
7175
7176         smbXcli_conn_set_sockopt(cli->conn, sockops);
7177
7178         /* Ok - now save then logoff our current user. */
7179         old_vuid = cli_state_get_uid(cli);
7180
7181         status = cli_ulogoff(cli);
7182         if (!NT_STATUS_IS_OK(status)) {
7183                 d_printf("(%s) cli_ulogoff failed: %s\n",
7184                          __location__, nt_errstr(status));
7185                 correct = false;
7186                 goto out;
7187         }
7188
7189         cli_state_set_uid(cli, old_vuid);
7190
7191         /* Try an operation. */
7192         status = cli_mkdir(cli, "\\uid_reg_test");
7193         if (NT_STATUS_IS_OK(status)) {
7194                 d_printf("(%s) cli_mkdir succeeded\n",
7195                          __location__);
7196                 correct = false;
7197                 goto out;
7198         } else {
7199                 /* Should be bad uid. */
7200                 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
7201                                  NT_STATUS_USER_SESSION_DELETED)) {
7202                         correct = false;
7203                         goto out;
7204                 }
7205         }
7206
7207         old_cnum = cli_state_get_tid(cli);
7208
7209         /* Now try a SMBtdis with the invald vuid set to zero. */
7210         cli_state_set_uid(cli, 0);
7211
7212         /* This should succeed. */
7213         status = cli_tdis(cli);
7214
7215         if (NT_STATUS_IS_OK(status)) {
7216                 d_printf("First tdis with invalid vuid should succeed.\n");
7217         } else {
7218                 d_printf("First tdis failed (%s)\n", nt_errstr(status));
7219                 correct = false;
7220                 goto out;
7221         }
7222
7223         cli_state_set_uid(cli, old_vuid);
7224         cli_state_set_tid(cli, old_cnum);
7225
7226         /* This should fail. */
7227         status = cli_tdis(cli);
7228         if (NT_STATUS_IS_OK(status)) {
7229                 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7230                 correct = false;
7231                 goto out;
7232         } else {
7233                 /* Should be bad tid. */
7234                 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
7235                                 NT_STATUS_NETWORK_NAME_DELETED)) {
7236                         correct = false;
7237                         goto out;
7238                 }
7239         }
7240
7241         cli_rmdir(cli, "\\uid_reg_test");
7242
7243   out:
7244
7245         cli_shutdown(cli);
7246         return correct;
7247 }
7248
7249
7250 static const char *illegal_chars = "*\\/?<>|\":";
7251 static char force_shortname_chars[] = " +,.[];=\177";
7252
7253 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
7254                              const char *mask, void *state)
7255 {
7256         struct cli_state *pcli = (struct cli_state *)state;
7257         fstring fname;
7258         NTSTATUS status = NT_STATUS_OK;
7259
7260         slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
7261
7262         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7263                 return NT_STATUS_OK;
7264
7265         if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7266                 status = cli_rmdir(pcli, fname);
7267                 if (!NT_STATUS_IS_OK(status)) {
7268                         printf("del_fn: failed to rmdir %s\n,", fname );
7269                 }
7270         } else {
7271                 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7272                 if (!NT_STATUS_IS_OK(status)) {
7273                         printf("del_fn: failed to unlink %s\n,", fname );
7274                 }
7275         }
7276         return status;
7277 }
7278
7279 struct sn_state {
7280         int matched;
7281         int i;
7282         bool val;
7283 };
7284
7285 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
7286                               const char *name, void *state)
7287 {
7288         struct sn_state *s = (struct sn_state  *)state;
7289         int i = s->i;
7290
7291 #if 0
7292         printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7293                 i, finfo->name, finfo->short_name);
7294 #endif
7295
7296         if (strchr(force_shortname_chars, i)) {
7297                 if (!finfo->short_name) {
7298                         /* Shortname not created when it should be. */
7299                         d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7300                                 __location__, finfo->name, i);
7301                         s->val = true;
7302                 }
7303         } else if (finfo->short_name){
7304                 /* Shortname created when it should not be. */
7305                 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7306                         __location__, finfo->short_name, finfo->name);
7307                 s->val = true;
7308         }
7309         s->matched += 1;
7310         return NT_STATUS_OK;
7311 }
7312
7313 static bool run_shortname_test(int dummy)
7314 {
7315         static struct cli_state *cli;
7316         bool correct = True;
7317         int i;
7318         struct sn_state s;
7319         char fname[40];
7320         NTSTATUS status;
7321
7322         printf("starting shortname test\n");
7323
7324         if (!torture_open_connection(&cli, 0)) {
7325                 return False;
7326         }
7327
7328         smbXcli_conn_set_sockopt(cli->conn, sockops);
7329
7330         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7331         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7332         cli_rmdir(cli, "\\shortname");
7333
7334         status = cli_mkdir(cli, "\\shortname");
7335         if (!NT_STATUS_IS_OK(status)) {
7336                 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7337                         __location__, nt_errstr(status));
7338                 correct = false;
7339                 goto out;
7340         }
7341
7342         if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
7343                 correct = false;
7344                 goto out;
7345         }
7346         if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
7347                 correct = false;
7348                 goto out;
7349         }
7350
7351         s.val = false;
7352
7353         for (i = 32; i < 128; i++) {
7354                 uint16_t fnum = (uint16_t)-1;
7355
7356                 s.i = i;
7357
7358                 if (strchr(illegal_chars, i)) {
7359                         continue;
7360                 }
7361                 fname[15] = i;
7362
7363                 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
7364                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
7365                 if (!NT_STATUS_IS_OK(status)) {
7366                         d_printf("(%s) cli_nt_create of %s failed: %s\n",
7367                                 __location__, fname, nt_errstr(status));
7368                         correct = false;
7369                         goto out;
7370                 }
7371                 cli_close(cli, fnum);
7372
7373                 s.matched = 0;
7374                 status = cli_list(cli, "\\shortname\\test*.*", 0,
7375                                   shortname_list_fn, &s);
7376                 if (s.matched != 1) {
7377                         d_printf("(%s) failed to list %s: %s\n",
7378                                 __location__, fname, nt_errstr(status));
7379                         correct = false;
7380                         goto out;
7381                 }
7382
7383                 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7384                 if (!NT_STATUS_IS_OK(status)) {
7385                         d_printf("(%s) failed to delete %s: %s\n",
7386                                 __location__, fname, nt_errstr(status));
7387                         correct = false;
7388                         goto out;
7389                 }
7390
7391                 if (s.val) {
7392                         correct = false;
7393                         goto out;
7394                 }
7395         }
7396
7397   out:
7398
7399         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7400         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7401         cli_rmdir(cli, "\\shortname");
7402         torture_close_connection(cli);
7403         return correct;
7404 }
7405
7406 static void pagedsearch_cb(struct tevent_req *req)
7407 {
7408         int rc;
7409         struct tldap_message *msg;
7410         char *dn;
7411
7412         rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
7413         if (rc != TLDAP_SUCCESS) {
7414                 d_printf("tldap_search_paged_recv failed: %s\n",
7415                          tldap_err2string(rc));
7416                 return;
7417         }
7418         if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
7419                 TALLOC_FREE(msg);
7420                 return;
7421         }
7422         if (!tldap_entry_dn(msg, &dn)) {
7423                 d_printf("tldap_entry_dn failed\n");
7424                 return;
7425         }
7426         d_printf("%s\n", dn);
7427         TALLOC_FREE(msg);
7428 }
7429
7430 static bool run_tldap(int dummy)
7431 {
7432         struct tldap_context *ld;
7433         int fd, rc;
7434         NTSTATUS status;
7435         struct sockaddr_storage addr;
7436         struct tevent_context *ev;
7437         struct tevent_req *req;
7438         char *basedn;
7439         const char *filter;
7440
7441         if (!resolve_name(host, &addr, 0, false)) {
7442                 d_printf("could not find host %s\n", host);
7443                 return false;
7444         }
7445         status = open_socket_out(&addr, 389, 9999, &fd);
7446         if (!NT_STATUS_IS_OK(status)) {
7447                 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
7448                 return false;
7449         }
7450
7451         ld = tldap_context_create(talloc_tos(), fd);
7452         if (ld == NULL) {
7453                 close(fd);
7454                 d_printf("tldap_context_create failed\n");
7455                 return false;
7456         }
7457
7458         rc = tldap_fetch_rootdse(ld);
7459         if (rc != TLDAP_SUCCESS) {
7460                 d_printf("tldap_fetch_rootdse failed: %s\n",
7461                          tldap_errstr(talloc_tos(), ld, rc));
7462                 return false;
7463         }
7464
7465         basedn = tldap_talloc_single_attribute(
7466                 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
7467         if (basedn == NULL) {
7468                 d_printf("no defaultNamingContext\n");
7469                 return false;
7470         }
7471         d_printf("defaultNamingContext: %s\n", basedn);
7472
7473         ev = tevent_context_init(talloc_tos());
7474         if (ev == NULL) {
7475                 d_printf("tevent_context_init failed\n");
7476                 return false;
7477         }
7478
7479         req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
7480                                       TLDAP_SCOPE_SUB, "(objectclass=*)",
7481                                       NULL, 0, 0,
7482                                       NULL, 0, NULL, 0, 0, 0, 0, 5);
7483         if (req == NULL) {
7484                 d_printf("tldap_search_paged_send failed\n");
7485                 return false;
7486         }
7487         tevent_req_set_callback(req, pagedsearch_cb, NULL);
7488
7489         tevent_req_poll(req, ev);
7490
7491         TALLOC_FREE(req);
7492
7493         /* test search filters against rootDSE */
7494         filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7495                    "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7496
7497         rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7498                           NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7499                           talloc_tos(), NULL, NULL);
7500         if (rc != TLDAP_SUCCESS) {
7501                 d_printf("tldap_search with complex filter failed: %s\n",
7502                          tldap_errstr(talloc_tos(), ld, rc));
7503                 return false;
7504         }
7505
7506         TALLOC_FREE(ld);
7507         return true;
7508 }
7509
7510 /* Torture test to ensure no regression of :
7511 https://bugzilla.samba.org/show_bug.cgi?id=7084
7512 */
7513
7514 static bool run_dir_createtime(int dummy)
7515 {
7516         struct cli_state *cli;
7517         const char *dname = "\\testdir";
7518         const char *fname = "\\testdir\\testfile";
7519         NTSTATUS status;
7520         struct timespec create_time;
7521         struct timespec create_time1;
7522         uint16_t fnum;
7523         bool ret = false;
7524
7525         if (!torture_open_connection(&cli, 0)) {
7526                 return false;
7527         }
7528
7529         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7530         cli_rmdir(cli, dname);
7531
7532         status = cli_mkdir(cli, dname);
7533         if (!NT_STATUS_IS_OK(status)) {
7534                 printf("mkdir failed: %s\n", nt_errstr(status));
7535                 goto out;
7536         }
7537
7538         status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7539                                 NULL, NULL, NULL);
7540         if (!NT_STATUS_IS_OK(status)) {
7541                 printf("cli_qpathinfo2 returned %s\n",
7542                        nt_errstr(status));
7543                 goto out;
7544         }
7545
7546         /* Sleep 3 seconds, then create a file. */
7547         sleep(3);
7548
7549         status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7550                          DENY_NONE, &fnum);
7551         if (!NT_STATUS_IS_OK(status)) {
7552                 printf("cli_openx failed: %s\n", nt_errstr(status));
7553                 goto out;
7554         }
7555
7556         status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7557                                 NULL, NULL, NULL);
7558         if (!NT_STATUS_IS_OK(status)) {
7559                 printf("cli_qpathinfo2 (2) returned %s\n",
7560                        nt_errstr(status));
7561                 goto out;
7562         }
7563
7564         if (timespec_compare(&create_time1, &create_time)) {
7565                 printf("run_dir_createtime: create time was updated (error)\n");
7566         } else {
7567                 printf("run_dir_createtime: create time was not updated (correct)\n");
7568                 ret = true;
7569         }
7570
7571   out:
7572
7573         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7574         cli_rmdir(cli, dname);
7575         if (!torture_close_connection(cli)) {
7576                 ret = false;
7577         }
7578         return ret;
7579 }
7580
7581
7582 static bool run_streamerror(int dummy)
7583 {
7584         struct cli_state *cli;
7585         const char *dname = "\\testdir";
7586         const char *streamname =
7587                 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7588         NTSTATUS status;
7589         time_t change_time, access_time, write_time;
7590         off_t size;
7591         uint16_t mode, fnum;
7592         bool ret = true;
7593
7594         if (!torture_open_connection(&cli, 0)) {
7595                 return false;
7596         }
7597
7598         cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7599         cli_rmdir(cli, dname);
7600
7601         status = cli_mkdir(cli, dname);
7602         if (!NT_STATUS_IS_OK(status)) {
7603                 printf("mkdir failed: %s\n", nt_errstr(status));
7604                 return false;
7605         }
7606
7607         status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
7608                                 &write_time, &size, &mode);
7609         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7610                 printf("pathinfo returned %s, expected "
7611                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7612                        nt_errstr(status));
7613                 ret = false;
7614         }
7615
7616         status = cli_ntcreate(cli, streamname, 0x16,
7617                               FILE_READ_DATA|FILE_READ_EA|
7618                               FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7619                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7620                               FILE_OPEN, 0, 0, &fnum);
7621
7622         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7623                 printf("ntcreate returned %s, expected "
7624                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7625                        nt_errstr(status));
7626                 ret = false;
7627         }
7628
7629
7630         cli_rmdir(cli, dname);
7631         return ret;
7632 }
7633
7634 static bool run_local_substitute(int dummy)
7635 {
7636         bool ok = true;
7637
7638         ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7639         ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7640         ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7641         ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7642         ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7643         ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7644         ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7645         ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7646
7647         /* Different captialization rules in sub_basic... */
7648
7649         ok &=  (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7650                        "blaDOM") == 0);
7651
7652         return ok;
7653 }
7654
7655 static bool run_local_base64(int dummy)
7656 {
7657         int i;
7658         bool ret = true;
7659
7660         for (i=1; i<2000; i++) {
7661                 DATA_BLOB blob1, blob2;
7662                 char *b64;
7663
7664                 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7665                 blob1.length = i;
7666                 generate_random_buffer(blob1.data, blob1.length);
7667
7668                 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7669                 if (b64 == NULL) {
7670                         d_fprintf(stderr, "base64_encode_data_blob failed "
7671                                   "for %d bytes\n", i);
7672                         ret = false;
7673                 }
7674                 blob2 = base64_decode_data_blob(b64);
7675                 TALLOC_FREE(b64);
7676
7677                 if (data_blob_cmp(&blob1, &blob2)) {
7678                         d_fprintf(stderr, "data_blob_cmp failed for %d "
7679                                   "bytes\n", i);
7680                         ret = false;
7681                 }
7682                 TALLOC_FREE(blob1.data);
7683                 data_blob_free(&blob2);
7684         }
7685         return ret;
7686 }
7687
7688 static bool run_local_gencache(int dummy)
7689 {
7690         char *val;
7691         time_t tm;
7692         DATA_BLOB blob;
7693
7694         if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7695                 d_printf("%s: gencache_set() failed\n", __location__);
7696                 return False;
7697         }
7698
7699         if (!gencache_get("foo", NULL, NULL)) {
7700                 d_printf("%s: gencache_get() failed\n", __location__);
7701                 return False;
7702         }
7703
7704         if (!gencache_get("foo", &val, &tm)) {
7705                 d_printf("%s: gencache_get() failed\n", __location__);
7706                 return False;
7707         }
7708
7709         if (strcmp(val, "bar") != 0) {
7710                 d_printf("%s: gencache_get() returned %s, expected %s\n",
7711                          __location__, val, "bar");
7712                 SAFE_FREE(val);
7713                 return False;
7714         }
7715
7716         SAFE_FREE(val);
7717
7718         if (!gencache_del("foo")) {
7719                 d_printf("%s: gencache_del() failed\n", __location__);
7720                 return False;
7721         }
7722         if (gencache_del("foo")) {
7723                 d_printf("%s: second gencache_del() succeeded\n",
7724                          __location__);
7725                 return False;
7726         }
7727
7728         if (gencache_get("foo", &val, &tm)) {
7729                 d_printf("%s: gencache_get() on deleted entry "
7730                          "succeeded\n", __location__);
7731                 return False;
7732         }
7733
7734         blob = data_blob_string_const_null("bar");
7735         tm = time(NULL) + 60;
7736
7737         if (!gencache_set_data_blob("foo", &blob, tm)) {
7738                 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7739                 return False;
7740         }
7741
7742         if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7743                 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7744                 return False;
7745         }
7746
7747         if (strcmp((const char *)blob.data, "bar") != 0) {
7748                 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7749                          __location__, (const char *)blob.data, "bar");
7750                 data_blob_free(&blob);
7751                 return False;
7752         }
7753
7754         data_blob_free(&blob);
7755
7756         if (!gencache_del("foo")) {
7757                 d_printf("%s: gencache_del() failed\n", __location__);
7758                 return False;
7759         }
7760         if (gencache_del("foo")) {
7761                 d_printf("%s: second gencache_del() succeeded\n",
7762                          __location__);
7763                 return False;
7764         }
7765
7766         if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7767                 d_printf("%s: gencache_get_data_blob() on deleted entry "
7768                          "succeeded\n", __location__);
7769                 return False;
7770         }
7771
7772         return True;
7773 }
7774
7775 static bool rbt_testval(struct db_context *db, const char *key,
7776                         const char *value)
7777 {
7778         struct db_record *rec;
7779         TDB_DATA data = string_tdb_data(value);
7780         bool ret = false;
7781         NTSTATUS status;
7782         TDB_DATA dbvalue;
7783
7784         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
7785         if (rec == NULL) {
7786                 d_fprintf(stderr, "fetch_locked failed\n");
7787                 goto done;
7788         }
7789         status = dbwrap_record_store(rec, data, 0);
7790         if (!NT_STATUS_IS_OK(status)) {
7791                 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7792                 goto done;
7793         }
7794         TALLOC_FREE(rec);
7795
7796         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
7797         if (rec == NULL) {
7798                 d_fprintf(stderr, "second fetch_locked failed\n");
7799                 goto done;
7800         }
7801
7802         dbvalue = dbwrap_record_get_value(rec);
7803         if ((dbvalue.dsize != data.dsize)
7804             || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
7805                 d_fprintf(stderr, "Got wrong data back\n");
7806                 goto done;
7807         }
7808
7809         ret = true;
7810  done:
7811         TALLOC_FREE(rec);
7812         return ret;
7813 }
7814
7815 static bool run_local_rbtree(int dummy)
7816 {
7817         struct db_context *db;
7818         bool ret = false;
7819         int i;
7820
7821         db = db_open_rbt(NULL);
7822
7823         if (db == NULL) {
7824                 d_fprintf(stderr, "db_open_rbt failed\n");
7825                 return false;
7826         }
7827
7828         for (i=0; i<1000; i++) {
7829                 char *key, *value;
7830
7831                 if (asprintf(&key, "key%ld", random()) == -1) {
7832                         goto done;
7833                 }
7834                 if (asprintf(&value, "value%ld", random()) == -1) {
7835                         SAFE_FREE(key);
7836                         goto done;
7837                 }
7838
7839                 if (!rbt_testval(db, key, value)) {
7840                         SAFE_FREE(key);
7841                         SAFE_FREE(value);
7842                         goto done;
7843                 }
7844
7845                 SAFE_FREE(value);
7846                 if (asprintf(&value, "value%ld", random()) == -1) {
7847                         SAFE_FREE(key);
7848                         goto done;
7849                 }
7850
7851                 if (!rbt_testval(db, key, value)) {
7852                         SAFE_FREE(key);
7853                         SAFE_FREE(value);
7854                         goto done;
7855                 }
7856
7857                 SAFE_FREE(key);
7858                 SAFE_FREE(value);
7859         }
7860
7861         ret = true;
7862
7863  done:
7864         TALLOC_FREE(db);
7865         return ret;
7866 }
7867
7868
7869 /*
7870   local test for character set functions
7871
7872   This is a very simple test for the functionality in convert_string_error()
7873  */
7874 static bool run_local_convert_string(int dummy)
7875 {
7876         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7877         const char *test_strings[2] = { "March", "M\303\244rz" };
7878         char dst[7];
7879         int i;
7880
7881         for (i=0; i<2; i++) {
7882                 const char *str = test_strings[i];
7883                 int len = strlen(str);
7884                 size_t converted_size;
7885                 bool ret;
7886
7887                 memset(dst, 'X', sizeof(dst));
7888
7889                 /* first try with real source length */
7890                 ret = convert_string_error(CH_UNIX, CH_UTF8,
7891                                            str, len,
7892                                            dst, sizeof(dst),
7893                                            &converted_size);
7894                 if (ret != true) {
7895                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7896                         goto failed;
7897                 }
7898
7899                 if (converted_size != len) {
7900                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7901                                   str, len, (int)converted_size);
7902                         goto failed;
7903                 }
7904
7905                 if (strncmp(str, dst, converted_size) != 0) {
7906                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7907                         goto failed;
7908                 }
7909
7910                 if (strlen(str) != converted_size) {
7911                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7912                                   (int)strlen(str), (int)converted_size);
7913                         goto failed;
7914                 }
7915
7916                 if (dst[converted_size] != 'X') {
7917                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7918                         goto failed;
7919                 }
7920
7921                 /* now with srclen==-1, this causes the nul to be
7922                  * converted too */
7923                 ret = convert_string_error(CH_UNIX, CH_UTF8,
7924                                            str, -1,
7925                                            dst, sizeof(dst),
7926                                            &converted_size);
7927                 if (ret != true) {
7928                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7929                         goto failed;
7930                 }
7931
7932                 if (converted_size != len+1) {
7933                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7934                                   str, len, (int)converted_size);
7935                         goto failed;
7936                 }
7937
7938                 if (strncmp(str, dst, converted_size) != 0) {
7939                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7940                         goto failed;
7941                 }
7942
7943                 if (len+1 != converted_size) {
7944                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7945                                   len+1, (int)converted_size);
7946                         goto failed;
7947                 }
7948
7949                 if (dst[converted_size] != 'X') {
7950                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7951                         goto failed;
7952                 }
7953
7954         }
7955
7956
7957         TALLOC_FREE(tmp_ctx);
7958         return true;
7959 failed:
7960         TALLOC_FREE(tmp_ctx);
7961         return false;
7962 }
7963
7964
7965 struct talloc_dict_test {
7966         int content;
7967 };
7968
7969 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7970 {
7971         int *count = (int *)priv;
7972         *count += 1;
7973         return 0;
7974 }
7975
7976 static bool run_local_talloc_dict(int dummy)
7977 {
7978         struct talloc_dict *dict;
7979         struct talloc_dict_test *t;
7980         int key, count, res;
7981         bool ok;
7982
7983         dict = talloc_dict_init(talloc_tos());
7984         if (dict == NULL) {
7985                 return false;
7986         }
7987
7988         t = talloc(talloc_tos(), struct talloc_dict_test);
7989         if (t == NULL) {
7990                 return false;
7991         }
7992
7993         key = 1;
7994         t->content = 1;
7995         ok = talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), &t);
7996         if (!ok) {
7997                 return false;
7998         }
7999
8000         count = 0;
8001         res = talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count);
8002         if (res == -1) {
8003                 return false;
8004         }
8005
8006         if (count != 1) {
8007                 return false;
8008         }
8009
8010         if (count != res) {
8011                 return false;
8012         }
8013
8014         TALLOC_FREE(dict);
8015
8016         return true;
8017 }
8018
8019 static bool run_local_string_to_sid(int dummy) {
8020         struct dom_sid sid;
8021
8022         if (string_to_sid(&sid, "S--1-5-32-545")) {
8023                 printf("allowing S--1-5-32-545\n");
8024                 return false;
8025         }
8026         if (string_to_sid(&sid, "S-1-5-32-+545")) {
8027                 printf("allowing S-1-5-32-+545\n");
8028                 return false;
8029         }
8030         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")) {
8031                 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
8032                 return false;
8033         }
8034         if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
8035                 printf("allowing S-1-5-32-545-abc\n");
8036                 return false;
8037         }
8038         if (!string_to_sid(&sid, "S-1-5-32-545")) {
8039                 printf("could not parse S-1-5-32-545\n");
8040                 return false;
8041         }
8042         if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
8043                 printf("mis-parsed S-1-5-32-545 as %s\n",
8044                        sid_string_tos(&sid));
8045                 return false;
8046         }
8047         return true;
8048 }
8049
8050 static bool run_local_binary_to_sid(int dummy) {
8051         struct dom_sid *sid = talloc(NULL, struct dom_sid);
8052         static const char good_binary_sid[] = {
8053                 0x1, /* revision number */
8054                 15, /* num auths */
8055                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8056                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8057                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8058                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8059                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8060                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8061                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8062                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8063                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8064                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8065                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8066                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8067                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8068                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8069                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8070                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8071         };
8072
8073         static const char long_binary_sid[] = {
8074                 0x1, /* revision number */
8075                 15, /* num auths */
8076                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8077                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8078                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8079                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8080                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8081                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8082                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8083                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8084                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8085                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8086                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8087                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8088                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8089                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8090                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8091                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8092                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8093                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8094                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8095         };
8096
8097         static const char long_binary_sid2[] = {
8098                 0x1, /* revision number */
8099                 32, /* num auths */
8100                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8101                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8102                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8103                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8104                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8105                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8106                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8107                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8108                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8109                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8110                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8111                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8112                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8113                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8114                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8115                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8116                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8117                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8118                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8119                 0x1, 0x1, 0x1, 0x1, /* auth[18] */
8120                 0x1, 0x1, 0x1, 0x1, /* auth[19] */
8121                 0x1, 0x1, 0x1, 0x1, /* auth[20] */
8122                 0x1, 0x1, 0x1, 0x1, /* auth[21] */
8123                 0x1, 0x1, 0x1, 0x1, /* auth[22] */
8124                 0x1, 0x1, 0x1, 0x1, /* auth[23] */
8125                 0x1, 0x1, 0x1, 0x1, /* auth[24] */
8126                 0x1, 0x1, 0x1, 0x1, /* auth[25] */
8127                 0x1, 0x1, 0x1, 0x1, /* auth[26] */
8128                 0x1, 0x1, 0x1, 0x1, /* auth[27] */
8129                 0x1, 0x1, 0x1, 0x1, /* auth[28] */
8130                 0x1, 0x1, 0x1, 0x1, /* auth[29] */
8131                 0x1, 0x1, 0x1, 0x1, /* auth[30] */
8132                 0x1, 0x1, 0x1, 0x1, /* auth[31] */
8133         };
8134
8135         if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
8136                 return false;
8137         }
8138         if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
8139                 return false;
8140         }
8141         if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
8142                 return false;
8143         }
8144         return true;
8145 }
8146
8147 /* Split a path name into filename and stream name components. Canonicalise
8148  * such that an implicit $DATA token is always explicit.
8149  *
8150  * The "specification" of this function can be found in the
8151  * run_local_stream_name() function in torture.c, I've tried those
8152  * combinations against a W2k3 server.
8153  */
8154
8155 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
8156                                        char **pbase, char **pstream)
8157 {
8158         char *base = NULL;
8159         char *stream = NULL;
8160         char *sname; /* stream name */
8161         const char *stype; /* stream type */
8162
8163         DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
8164
8165         sname = strchr_m(fname, ':');
8166
8167         if (lp_posix_pathnames() || (sname == NULL)) {
8168                 if (pbase != NULL) {
8169                         base = talloc_strdup(mem_ctx, fname);
8170                         NT_STATUS_HAVE_NO_MEMORY(base);
8171                 }
8172                 goto done;
8173         }
8174
8175         if (pbase != NULL) {
8176                 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
8177                 NT_STATUS_HAVE_NO_MEMORY(base);
8178         }
8179
8180         sname += 1;
8181
8182         stype = strchr_m(sname, ':');
8183
8184         if (stype == NULL) {
8185                 sname = talloc_strdup(mem_ctx, sname);
8186                 stype = "$DATA";
8187         }
8188         else {
8189                 if (strcasecmp_m(stype, ":$DATA") != 0) {
8190                         /*
8191                          * If there is an explicit stream type, so far we only
8192                          * allow $DATA. Is there anything else allowed? -- vl
8193                          */
8194                         DEBUG(10, ("[%s] is an invalid stream type\n", stype));
8195                         TALLOC_FREE(base);
8196                         return NT_STATUS_OBJECT_NAME_INVALID;
8197                 }
8198                 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
8199                 stype += 1;
8200         }
8201
8202         if (sname == NULL) {
8203                 TALLOC_FREE(base);
8204                 return NT_STATUS_NO_MEMORY;
8205         }
8206
8207         if (sname[0] == '\0') {
8208                 /*
8209                  * no stream name, so no stream
8210                  */
8211                 goto done;
8212         }
8213
8214         if (pstream != NULL) {
8215                 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
8216                 if (stream == NULL) {
8217                         TALLOC_FREE(sname);
8218                         TALLOC_FREE(base);
8219                         return NT_STATUS_NO_MEMORY;
8220                 }
8221                 /*
8222                  * upper-case the type field
8223                  */
8224                 strupper_m(strchr_m(stream, ':')+1);
8225         }
8226
8227  done:
8228         if (pbase != NULL) {
8229                 *pbase = base;
8230         }
8231         if (pstream != NULL) {
8232                 *pstream = stream;
8233         }
8234         return NT_STATUS_OK;
8235 }
8236
8237 static bool test_stream_name(const char *fname, const char *expected_base,
8238                              const char *expected_stream,
8239                              NTSTATUS expected_status)
8240 {
8241         NTSTATUS status;
8242         char *base = NULL;
8243         char *stream = NULL;
8244
8245         status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
8246         if (!NT_STATUS_EQUAL(status, expected_status)) {
8247                 goto error;
8248         }
8249
8250         if (!NT_STATUS_IS_OK(status)) {
8251                 return true;
8252         }
8253
8254         if (base == NULL) goto error;
8255
8256         if (strcmp(expected_base, base) != 0) goto error;
8257
8258         if ((expected_stream != NULL) && (stream == NULL)) goto error;
8259         if ((expected_stream == NULL) && (stream != NULL)) goto error;
8260
8261         if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
8262                 goto error;
8263
8264         TALLOC_FREE(base);
8265         TALLOC_FREE(stream);
8266         return true;
8267
8268  error:
8269         d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
8270                   fname, expected_base ? expected_base : "<NULL>",
8271                   expected_stream ? expected_stream : "<NULL>",
8272                   nt_errstr(expected_status));
8273         d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
8274                   base ? base : "<NULL>", stream ? stream : "<NULL>",
8275                   nt_errstr(status));
8276         TALLOC_FREE(base);
8277         TALLOC_FREE(stream);
8278         return false;
8279 }
8280
8281 static bool run_local_stream_name(int dummy)
8282 {
8283         bool ret = true;
8284
8285         ret &= test_stream_name(
8286                 "bla", "bla", NULL, NT_STATUS_OK);
8287         ret &= test_stream_name(
8288                 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
8289         ret &= test_stream_name(
8290                 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8291         ret &= test_stream_name(
8292                 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
8293         ret &= test_stream_name(
8294                 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8295         ret &= test_stream_name(
8296                 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
8297         ret &= test_stream_name(
8298                 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
8299         ret &= test_stream_name(
8300                 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
8301
8302         return ret;
8303 }
8304
8305 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
8306 {
8307         if (a.length != b.length) {
8308                 printf("a.length=%d != b.length=%d\n",
8309                        (int)a.length, (int)b.length);
8310                 return false;
8311         }
8312         if (memcmp(a.data, b.data, a.length) != 0) {
8313                 printf("a.data and b.data differ\n");
8314                 return false;
8315         }
8316         return true;
8317 }
8318
8319 static bool run_local_memcache(int dummy)
8320 {
8321         struct memcache *cache;
8322         DATA_BLOB k1, k2;
8323         DATA_BLOB d1, d2, d3;
8324         DATA_BLOB v1, v2, v3;
8325
8326         TALLOC_CTX *mem_ctx;
8327         char *str1, *str2;
8328         size_t size1, size2;
8329         bool ret = false;
8330
8331         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
8332
8333         if (cache == NULL) {
8334                 printf("memcache_init failed\n");
8335                 return false;
8336         }
8337
8338         d1 = data_blob_const("d1", 2);
8339         d2 = data_blob_const("d2", 2);
8340         d3 = data_blob_const("d3", 2);
8341
8342         k1 = data_blob_const("d1", 2);
8343         k2 = data_blob_const("d2", 2);
8344
8345         memcache_add(cache, STAT_CACHE, k1, d1);
8346         memcache_add(cache, GETWD_CACHE, k2, d2);
8347
8348         if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
8349                 printf("could not find k1\n");
8350                 return false;
8351         }
8352         if (!data_blob_equal(d1, v1)) {
8353                 return false;
8354         }
8355
8356         if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8357                 printf("could not find k2\n");
8358                 return false;
8359         }
8360         if (!data_blob_equal(d2, v2)) {
8361                 return false;
8362         }
8363
8364         memcache_add(cache, STAT_CACHE, k1, d3);
8365
8366         if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
8367                 printf("could not find replaced k1\n");
8368                 return false;
8369         }
8370         if (!data_blob_equal(d3, v3)) {
8371                 return false;
8372         }
8373
8374         memcache_add(cache, GETWD_CACHE, k1, d1);
8375
8376         if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8377                 printf("Did find k2, should have been purged\n");
8378                 return false;
8379         }
8380
8381         TALLOC_FREE(cache);
8382
8383         cache = memcache_init(NULL, 0);
8384
8385         mem_ctx = talloc_init("foo");
8386
8387         str1 = talloc_strdup(mem_ctx, "string1");
8388         str2 = talloc_strdup(mem_ctx, "string2");
8389
8390         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8391                             data_blob_string_const("torture"), &str1);
8392         size1 = talloc_total_size(cache);
8393
8394         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8395                             data_blob_string_const("torture"), &str2);
8396         size2 = talloc_total_size(cache);
8397
8398         printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
8399
8400         if (size2 > size1) {
8401                 printf("memcache leaks memory!\n");
8402                 goto fail;
8403         }
8404
8405         ret = true;
8406  fail:
8407         TALLOC_FREE(cache);
8408         return ret;
8409 }
8410
8411 static void wbclient_done(struct tevent_req *req)
8412 {
8413         wbcErr wbc_err;
8414         struct winbindd_response *wb_resp;
8415         int *i = (int *)tevent_req_callback_data_void(req);
8416
8417         wbc_err = wb_trans_recv(req, req, &wb_resp);
8418         TALLOC_FREE(req);
8419         *i += 1;
8420         d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
8421 }
8422
8423 static bool run_local_wbclient(int dummy)
8424 {
8425         struct event_context *ev;
8426         struct wb_context **wb_ctx;
8427         struct winbindd_request wb_req;
8428         bool result = false;
8429         int i, j;
8430
8431         BlockSignals(True, SIGPIPE);
8432
8433         ev = tevent_context_init_byname(talloc_tos(), "epoll");
8434         if (ev == NULL) {
8435                 goto fail;
8436         }
8437
8438         wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
8439         if (wb_ctx == NULL) {
8440                 goto fail;
8441         }
8442
8443         ZERO_STRUCT(wb_req);
8444         wb_req.cmd = WINBINDD_PING;
8445
8446         d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
8447
8448         for (i=0; i<torture_nprocs; i++) {
8449                 wb_ctx[i] = wb_context_init(ev, NULL);
8450                 if (wb_ctx[i] == NULL) {
8451                         goto fail;
8452                 }
8453                 for (j=0; j<torture_numops; j++) {
8454                         struct tevent_req *req;
8455                         req = wb_trans_send(ev, ev, wb_ctx[i],
8456                                             (j % 2) == 0, &wb_req);
8457                         if (req == NULL) {
8458                                 goto fail;
8459                         }
8460                         tevent_req_set_callback(req, wbclient_done, &i);
8461                 }
8462         }
8463
8464         i = 0;
8465
8466         while (i < torture_nprocs * torture_numops) {
8467                 tevent_loop_once(ev);
8468         }
8469
8470         result = true;
8471  fail:
8472         TALLOC_FREE(ev);
8473         return result;
8474 }
8475
8476 static void getaddrinfo_finished(struct tevent_req *req)
8477 {
8478         char *name = (char *)tevent_req_callback_data_void(req);
8479         struct addrinfo *ainfo;
8480         int res;
8481
8482         res = getaddrinfo_recv(req, &ainfo);
8483         if (res != 0) {
8484                 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
8485                 return;
8486         }
8487         d_printf("gai(%s) succeeded\n", name);
8488         freeaddrinfo(ainfo);
8489 }
8490
8491 static bool run_getaddrinfo_send(int dummy)
8492 {
8493         TALLOC_CTX *frame = talloc_stackframe();
8494         struct fncall_context *ctx;
8495         struct tevent_context *ev;
8496         bool result = false;
8497         const char *names[4] = { "www.samba.org", "notfound.samba.org",
8498                                  "www.slashdot.org", "heise.de" };
8499         struct tevent_req *reqs[4];
8500         int i;
8501
8502         ev = event_context_init(frame);
8503         if (ev == NULL) {
8504                 goto fail;
8505         }
8506
8507         ctx = fncall_context_init(frame, 4);
8508
8509         for (i=0; i<ARRAY_SIZE(names); i++) {
8510                 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8511                                            NULL);
8512                 if (reqs[i] == NULL) {
8513                         goto fail;
8514                 }
8515                 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8516                                         discard_const_p(void, names[i]));
8517         }
8518
8519         for (i=0; i<ARRAY_SIZE(reqs); i++) {
8520                 tevent_loop_once(ev);
8521         }
8522
8523         result = true;
8524 fail:
8525         TALLOC_FREE(frame);
8526         return result;
8527 }
8528
8529 static bool dbtrans_inc(struct db_context *db)
8530 {
8531         struct db_record *rec;
8532         uint32_t val;
8533         bool ret = false;
8534         NTSTATUS status;
8535         TDB_DATA value;
8536
8537         rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
8538         if (rec == NULL) {
8539                 printf(__location__ "fetch_lock failed\n");
8540                 return false;
8541         }
8542
8543         value = dbwrap_record_get_value(rec);
8544
8545         if (value.dsize != sizeof(uint32_t)) {
8546                 printf(__location__ "value.dsize = %d\n",
8547                        (int)value.dsize);
8548                 goto fail;
8549         }
8550
8551         memcpy(&val, value.dptr, sizeof(val));
8552         val += 1;
8553
8554         status = dbwrap_record_store(
8555                 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
8556         if (!NT_STATUS_IS_OK(status)) {
8557                 printf(__location__ "store failed: %s\n",
8558                        nt_errstr(status));
8559                 goto fail;
8560         }
8561
8562         ret = true;
8563 fail:
8564         TALLOC_FREE(rec);
8565         return ret;
8566 }
8567
8568 static bool run_local_dbtrans(int dummy)
8569 {
8570         struct db_context *db;
8571         struct db_record *rec;
8572         NTSTATUS status;
8573         uint32_t initial;
8574         int res;
8575         TDB_DATA value;
8576
8577         db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8578                      O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1);
8579         if (db == NULL) {
8580                 printf("Could not open transtest.db\n");
8581                 return false;
8582         }
8583
8584         res = dbwrap_transaction_start(db);
8585         if (res != 0) {
8586                 printf(__location__ "transaction_start failed\n");
8587                 return false;
8588         }
8589
8590         rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
8591         if (rec == NULL) {
8592                 printf(__location__ "fetch_lock failed\n");
8593                 return false;
8594         }
8595
8596         value = dbwrap_record_get_value(rec);
8597
8598         if (value.dptr == NULL) {
8599                 initial = 0;
8600                 status = dbwrap_record_store(
8601                         rec, make_tdb_data((uint8_t *)&initial,
8602                                            sizeof(initial)),
8603                         0);
8604                 if (!NT_STATUS_IS_OK(status)) {
8605                         printf(__location__ "store returned %s\n",
8606                                nt_errstr(status));
8607                         return false;
8608                 }
8609         }
8610
8611         TALLOC_FREE(rec);
8612
8613         res = dbwrap_transaction_commit(db);
8614         if (res != 0) {
8615                 printf(__location__ "transaction_commit failed\n");
8616                 return false;
8617         }
8618
8619         while (true) {
8620                 uint32_t val, val2;
8621                 int i;
8622
8623                 res = dbwrap_transaction_start(db);
8624                 if (res != 0) {
8625                         printf(__location__ "transaction_start failed\n");
8626                         break;
8627                 }
8628
8629                 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
8630                 if (!NT_STATUS_IS_OK(status)) {
8631                         printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
8632                                nt_errstr(status));
8633                         break;
8634                 }
8635
8636                 for (i=0; i<10; i++) {
8637                         if (!dbtrans_inc(db)) {
8638                                 return false;
8639                         }
8640                 }
8641
8642                 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
8643                 if (!NT_STATUS_IS_OK(status)) {
8644                         printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
8645                                nt_errstr(status));
8646                         break;
8647                 }
8648
8649                 if (val2 != val + 10) {
8650                         printf(__location__ "val=%d, val2=%d\n",
8651                                (int)val, (int)val2);
8652                         break;
8653                 }
8654
8655                 printf("val2=%d\r", val2);
8656
8657                 res = dbwrap_transaction_commit(db);
8658                 if (res != 0) {
8659                         printf(__location__ "transaction_commit failed\n");
8660                         break;
8661                 }
8662         }
8663
8664         TALLOC_FREE(db);
8665         return true;
8666 }
8667
8668 /*
8669  * Just a dummy test to be run under a debugger. There's no real way
8670  * to inspect the tevent_select specific function from outside of
8671  * tevent_select.c.
8672  */
8673
8674 static bool run_local_tevent_select(int dummy)
8675 {
8676         struct tevent_context *ev;
8677         struct tevent_fd *fd1, *fd2;
8678         bool result = false;
8679
8680         ev = tevent_context_init_byname(NULL, "select");
8681         if (ev == NULL) {
8682                 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8683                 goto fail;
8684         }
8685
8686         fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8687         if (fd1 == NULL) {
8688                 d_fprintf(stderr, "tevent_add_fd failed\n");
8689                 goto fail;
8690         }
8691         fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8692         if (fd2 == NULL) {
8693                 d_fprintf(stderr, "tevent_add_fd failed\n");
8694                 goto fail;
8695         }
8696         TALLOC_FREE(fd2);
8697
8698         fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8699         if (fd2 == NULL) {
8700                 d_fprintf(stderr, "tevent_add_fd failed\n");
8701                 goto fail;
8702         }
8703
8704         result = true;
8705 fail:
8706         TALLOC_FREE(ev);
8707         return result;
8708 }
8709
8710 static bool run_local_hex_encode_buf(int dummy)
8711 {
8712         char buf[17];
8713         uint8_t src[8];
8714         int i;
8715
8716         for (i=0; i<sizeof(src); i++) {
8717                 src[i] = i;
8718         }
8719         hex_encode_buf(buf, src, sizeof(src));
8720         if (strcmp(buf, "0001020304050607") != 0) {
8721                 return false;
8722         }
8723         hex_encode_buf(buf, NULL, 0);
8724         if (buf[0] != '\0') {
8725                 return false;
8726         }
8727         return true;
8728 }
8729
8730 static const char *remove_duplicate_addrs2_test_strings_vector[] = {
8731         "0.0.0.0",
8732         "::0",
8733         "1.2.3.1",
8734         "0.0.0.0",
8735         "0.0.0.0",
8736         "1.2.3.2",
8737         "1.2.3.3",
8738         "1.2.3.4",
8739         "1.2.3.5",
8740         "::0",
8741         "1.2.3.6",
8742         "1.2.3.7",
8743         "::0",
8744         "::0",
8745         "::0",
8746         "1.2.3.8",
8747         "1.2.3.9",
8748         "1.2.3.10",
8749         "1.2.3.11",
8750         "1.2.3.12",
8751         "1.2.3.13",
8752         "1001:1111:1111:1000:0:1111:1111:1111",
8753         "1.2.3.1",
8754         "1.2.3.2",
8755         "1.2.3.3",
8756         "1.2.3.12",
8757         "::0",
8758         "::0"
8759 };
8760
8761 static const char *remove_duplicate_addrs2_test_strings_result[] = {
8762         "1.2.3.1",
8763         "1.2.3.2",
8764         "1.2.3.3",
8765         "1.2.3.4",
8766         "1.2.3.5",
8767         "1.2.3.6",
8768         "1.2.3.7",
8769         "1.2.3.8",
8770         "1.2.3.9",
8771         "1.2.3.10",
8772         "1.2.3.11",
8773         "1.2.3.12",
8774         "1.2.3.13",
8775         "1001:1111:1111:1000:0:1111:1111:1111"
8776 };
8777
8778 static bool run_local_remove_duplicate_addrs2(int dummy)
8779 {
8780         struct ip_service test_vector[28];
8781         int count, i;
8782
8783         /* Construct the sockaddr_storage test vector. */
8784         for (i = 0; i < 28; i++) {
8785                 struct addrinfo hints;
8786                 struct addrinfo *res = NULL;
8787                 int ret;
8788
8789                 memset(&hints, '\0', sizeof(hints));
8790                 hints.ai_flags = AI_NUMERICHOST;
8791                 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
8792                                 NULL,
8793                                 &hints,
8794                                 &res);
8795                 if (ret) {
8796                         fprintf(stderr, "getaddrinfo failed on [%s]\n",
8797                                 remove_duplicate_addrs2_test_strings_vector[i]);
8798                         return false;
8799                 }
8800                 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
8801                 memcpy(&test_vector[i].ss,
8802                         res->ai_addr,
8803                         res->ai_addrlen);
8804                 freeaddrinfo(res);
8805         }
8806
8807         count = remove_duplicate_addrs2(test_vector, i);
8808
8809         if (count != 14) {
8810                 fprintf(stderr, "count wrong (%d) should be 14\n",
8811                         count);
8812                 return false;
8813         }
8814
8815         for (i = 0; i < count; i++) {
8816                 char addr[INET6_ADDRSTRLEN];
8817
8818                 print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
8819
8820                 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
8821                         fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
8822                                 i,
8823                                 addr,
8824                                 remove_duplicate_addrs2_test_strings_result[i]);
8825                         return false;
8826                 }
8827         }
8828
8829         printf("run_local_remove_duplicate_addrs2: success\n");
8830         return true;
8831 }
8832
8833 static double create_procs(bool (*fn)(int), bool *result)
8834 {
8835         int i, status;
8836         volatile pid_t *child_status;
8837         volatile bool *child_status_out;
8838         int synccount;
8839         int tries = 8;
8840         struct timeval start;
8841
8842         synccount = 0;
8843
8844         child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
8845         if (!child_status) {
8846                 printf("Failed to setup shared memory\n");
8847                 return -1;
8848         }
8849
8850         child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
8851         if (!child_status_out) {
8852                 printf("Failed to setup result status shared memory\n");
8853                 return -1;
8854         }
8855
8856         for (i = 0; i < torture_nprocs; i++) {
8857                 child_status[i] = 0;
8858                 child_status_out[i] = True;
8859         }
8860
8861         start = timeval_current();
8862
8863         for (i=0;i<torture_nprocs;i++) {
8864                 procnum = i;
8865                 if (fork() == 0) {
8866                         pid_t mypid = getpid();
8867                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8868
8869                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
8870
8871                         while (1) {
8872                                 if (torture_open_connection(&current_cli, i)) break;
8873                                 if (tries-- == 0) {
8874                                         printf("pid %d failed to start\n", (int)getpid());
8875                                         _exit(1);
8876                                 }
8877                                 smb_msleep(10); 
8878                         }
8879
8880                         child_status[i] = getpid();
8881
8882                         while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8883
8884                         child_status_out[i] = fn(i);
8885                         _exit(0);
8886                 }
8887         }
8888
8889         do {
8890                 synccount = 0;
8891                 for (i=0;i<torture_nprocs;i++) {
8892                         if (child_status[i]) synccount++;
8893                 }
8894                 if (synccount == torture_nprocs) break;
8895                 smb_msleep(10);
8896         } while (timeval_elapsed(&start) < 30);
8897
8898         if (synccount != torture_nprocs) {
8899                 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
8900                 *result = False;
8901                 return timeval_elapsed(&start);
8902         }
8903
8904         /* start the client load */
8905         start = timeval_current();
8906
8907         for (i=0;i<torture_nprocs;i++) {
8908                 child_status[i] = 0;
8909         }
8910
8911         printf("%d clients started\n", torture_nprocs);
8912
8913         for (i=0;i<torture_nprocs;i++) {
8914                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8915         }
8916
8917         printf("\n");
8918
8919         for (i=0;i<torture_nprocs;i++) {
8920                 if (!child_status_out[i]) {
8921                         *result = False;
8922                 }
8923         }
8924         return timeval_elapsed(&start);
8925 }
8926
8927 #define FLAG_MULTIPROC 1
8928
8929 static struct {
8930         const char *name;
8931         bool (*fn)(int);
8932         unsigned flags;
8933 } torture_ops[] = {
8934         {"FDPASS", run_fdpasstest, 0},
8935         {"LOCK1",  run_locktest1,  0},
8936         {"LOCK2",  run_locktest2,  0},
8937         {"LOCK3",  run_locktest3,  0},
8938         {"LOCK4",  run_locktest4,  0},
8939         {"LOCK5",  run_locktest5,  0},
8940         {"LOCK6",  run_locktest6,  0},
8941         {"LOCK7",  run_locktest7,  0},
8942         {"LOCK8",  run_locktest8,  0},
8943         {"LOCK9",  run_locktest9,  0},
8944         {"UNLINK", run_unlinktest, 0},
8945         {"BROWSE", run_browsetest, 0},
8946         {"ATTR",   run_attrtest,   0},
8947         {"TRANS2", run_trans2test, 0},
8948         {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8949         {"TORTURE",run_torture,    FLAG_MULTIPROC},
8950         {"RANDOMIPC", run_randomipc, 0},
8951         {"NEGNOWAIT", run_negprot_nowait, 0},
8952         {"NBENCH",  run_nbench, 0},
8953         {"NBENCH2", run_nbench2, 0},
8954         {"OPLOCK1",  run_oplock1, 0},
8955         {"OPLOCK2",  run_oplock2, 0},
8956         {"OPLOCK4",  run_oplock4, 0},
8957         {"DIR",  run_dirtest, 0},
8958         {"DIR1",  run_dirtest1, 0},
8959         {"DIR-CREATETIME",  run_dir_createtime, 0},
8960         {"DENY1",  torture_denytest1, 0},
8961         {"DENY2",  torture_denytest2, 0},
8962         {"TCON",  run_tcon_test, 0},
8963         {"TCONDEV",  run_tcon_devtype_test, 0},
8964         {"RW1",  run_readwritetest, 0},
8965         {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
8966         {"RW3",  run_readwritelarge, 0},
8967         {"RW-SIGNING",  run_readwritelarge_signtest, 0},
8968         {"OPEN", run_opentest, 0},
8969         {"POSIX", run_simple_posix_open_test, 0},
8970         {"POSIX-APPEND", run_posix_append, 0},
8971         {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8972         {"ASYNC-ECHO", run_async_echo, 0},
8973         { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8974         { "SHORTNAME-TEST", run_shortname_test, 0},
8975         { "ADDRCHANGE", run_addrchange, 0},
8976 #if 1
8977         {"OPENATTR", run_openattrtest, 0},
8978 #endif
8979         {"XCOPY", run_xcopy, 0},
8980         {"RENAME", run_rename, 0},
8981         {"DELETE", run_deletetest, 0},
8982         {"DELETE-LN", run_deletetest_ln, 0},
8983         {"PROPERTIES", run_properties, 0},
8984         {"MANGLE", torture_mangle, 0},
8985         {"MANGLE1", run_mangle1, 0},
8986         {"W2K", run_w2ktest, 0},
8987         {"TRANS2SCAN", torture_trans2_scan, 0},
8988         {"NTTRANSSCAN", torture_nttrans_scan, 0},
8989         {"UTABLE", torture_utable, 0},
8990         {"CASETABLE", torture_casetable, 0},
8991         {"ERRMAPEXTRACT", run_error_map_extract, 0},
8992         {"PIPE_NUMBER", run_pipe_number, 0},
8993         {"TCON2",  run_tcon2_test, 0},
8994         {"IOCTL",  torture_ioctl_test, 0},
8995         {"CHKPATH",  torture_chkpath_test, 0},
8996         {"FDSESS", run_fdsesstest, 0},
8997         { "EATEST", run_eatest, 0},
8998         { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8999         { "CHAIN1", run_chain1, 0},
9000         { "CHAIN2", run_chain2, 0},
9001         { "CHAIN3", run_chain3, 0},
9002         { "WINDOWS-WRITE", run_windows_write, 0},
9003         { "NTTRANS-CREATE", run_nttrans_create, 0},
9004         { "NTTRANS-FSCTL", run_nttrans_fsctl, 0},
9005         { "CLI_ECHO", run_cli_echo, 0},
9006         { "GETADDRINFO", run_getaddrinfo_send, 0},
9007         { "TLDAP", run_tldap },
9008         { "STREAMERROR", run_streamerror },
9009         { "NOTIFY-BENCH", run_notify_bench },
9010         { "NOTIFY-BENCH2", run_notify_bench2 },
9011         { "NOTIFY-BENCH3", run_notify_bench3 },
9012         { "BAD-NBT-SESSION", run_bad_nbt_session },
9013         { "SMB-ANY-CONNECT", run_smb_any_connect },
9014         { "NOTIFY-ONLINE", run_notify_online },
9015         { "SMB2-BASIC", run_smb2_basic },
9016         { "SMB2-NEGPROT", run_smb2_negprot },
9017         { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect },
9018         { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence },
9019         { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel },
9020         { "SMB2-SESSION-REAUTH", run_smb2_session_reauth },
9021         { "CLEANUP1", run_cleanup1 },
9022         { "CLEANUP2", run_cleanup2 },
9023         { "CLEANUP3", run_cleanup3 },
9024         { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
9025         { "LOCAL-GENCACHE", run_local_gencache, 0},
9026         { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
9027         { "LOCAL-CTDB-CONN", run_ctdb_conn, 0},
9028         { "LOCAL-MSG", run_msg_test, 0},
9029         { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1, 0 },
9030         { "LOCAL-BASE64", run_local_base64, 0},
9031         { "LOCAL-RBTREE", run_local_rbtree, 0},
9032         { "LOCAL-MEMCACHE", run_local_memcache, 0},
9033         { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
9034         { "LOCAL-WBCLIENT", run_local_wbclient, 0},
9035         { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
9036         { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
9037         { "LOCAL-DBTRANS", run_local_dbtrans, 0},
9038         { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
9039         { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
9040         { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0},
9041         { "LOCAL-sprintf_append", run_local_sprintf_append, 0},
9042         { "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0},
9043         { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test, 0},
9044         { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2, 0},
9045         {NULL, NULL, 0}};
9046
9047
9048
9049 /****************************************************************************
9050 run a specified test or "ALL"
9051 ****************************************************************************/
9052 static bool run_test(const char *name)
9053 {
9054         bool ret = True;
9055         bool result = True;
9056         bool found = False;
9057         int i;
9058         double t;
9059         if (strequal(name,"ALL")) {
9060                 for (i=0;torture_ops[i].name;i++) {
9061                         run_test(torture_ops[i].name);
9062                 }
9063                 found = True;
9064         }
9065
9066         for (i=0;torture_ops[i].name;i++) {
9067                 fstr_sprintf(randomfname, "\\XX%x", 
9068                          (unsigned)random());
9069
9070                 if (strequal(name, torture_ops[i].name)) {
9071                         found = True;
9072                         printf("Running %s\n", name);
9073                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
9074                                 t = create_procs(torture_ops[i].fn, &result);
9075                                 if (!result) { 
9076                                         ret = False;
9077                                         printf("TEST %s FAILED!\n", name);
9078                                 }
9079                         } else {
9080                                 struct timeval start;
9081                                 start = timeval_current();
9082                                 if (!torture_ops[i].fn(0)) {
9083                                         ret = False;
9084                                         printf("TEST %s FAILED!\n", name);
9085                                 }
9086                                 t = timeval_elapsed(&start);
9087                         }
9088                         printf("%s took %g secs\n\n", name, t);
9089                 }
9090         }
9091
9092         if (!found) {
9093                 printf("Did not find a test named %s\n", name);
9094                 ret = False;
9095         }
9096
9097         return ret;
9098 }
9099
9100
9101 static void usage(void)
9102 {
9103         int i;
9104
9105         printf("WARNING samba4 test suite is much more complete nowadays.\n");
9106         printf("Please use samba4 torture.\n\n");
9107
9108         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
9109
9110         printf("\t-d debuglevel\n");
9111         printf("\t-U user%%pass\n");
9112         printf("\t-k               use kerberos\n");
9113         printf("\t-N numprocs\n");
9114         printf("\t-n my_netbios_name\n");
9115         printf("\t-W workgroup\n");
9116         printf("\t-o num_operations\n");
9117         printf("\t-O socket_options\n");
9118         printf("\t-m maximum protocol\n");
9119         printf("\t-L use oplocks\n");
9120         printf("\t-c CLIENT.TXT   specify client load file for NBENCH\n");
9121         printf("\t-A showall\n");
9122         printf("\t-p port\n");
9123         printf("\t-s seed\n");
9124         printf("\t-b unclist_filename   specify multiple shares for multiple connections\n");
9125         printf("\t-f filename   filename to test\n");
9126         printf("\n\n");
9127
9128         printf("tests are:");
9129         for (i=0;torture_ops[i].name;i++) {
9130                 printf(" %s", torture_ops[i].name);
9131         }
9132         printf("\n");
9133
9134         printf("default test is ALL\n");
9135
9136         exit(1);
9137 }
9138
9139 /****************************************************************************
9140   main program
9141 ****************************************************************************/
9142  int main(int argc,char *argv[])
9143 {
9144         int opt, i;
9145         char *p;
9146         int gotuser = 0;
9147         int gotpass = 0;
9148         bool correct = True;
9149         TALLOC_CTX *frame = talloc_stackframe();
9150         int seed = time(NULL);
9151
9152 #ifdef HAVE_SETBUFFER
9153         setbuffer(stdout, NULL, 0);
9154 #endif
9155
9156         setup_logging("smbtorture", DEBUG_STDOUT);
9157
9158         load_case_tables();
9159
9160         if (is_default_dyn_CONFIGFILE()) {
9161                 if(getenv("SMB_CONF_PATH")) {
9162                         set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
9163                 }
9164         }
9165         lp_load_global(get_dyn_CONFIGFILE());
9166         load_interfaces();
9167
9168         if (argc < 2) {
9169                 usage();
9170         }
9171
9172         for(p = argv[1]; *p; p++)
9173           if(*p == '\\')
9174             *p = '/';
9175
9176         if (strncmp(argv[1], "//", 2)) {
9177                 usage();
9178         }
9179
9180         fstrcpy(host, &argv[1][2]);
9181         p = strchr_m(&host[2],'/');
9182         if (!p) {
9183                 usage();
9184         }
9185         *p = 0;
9186         fstrcpy(share, p+1);
9187
9188         fstrcpy(myname, get_myname(talloc_tos()));
9189         if (!*myname) {
9190                 fprintf(stderr, "Failed to get my hostname.\n");
9191                 return 1;
9192         }
9193
9194         if (*username == 0 && getenv("LOGNAME")) {
9195           fstrcpy(username,getenv("LOGNAME"));
9196         }
9197
9198         argc--;
9199         argv++;
9200
9201         fstrcpy(workgroup, lp_workgroup());
9202
9203         while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
9204                != EOF) {
9205                 switch (opt) {
9206                 case 'p':
9207                         port_to_use = atoi(optarg);
9208                         break;
9209                 case 's':
9210                         seed = atoi(optarg);
9211                         break;
9212                 case 'W':
9213                         fstrcpy(workgroup,optarg);
9214                         break;
9215                 case 'm':
9216                         max_protocol = interpret_protocol(optarg, max_protocol);
9217                         break;
9218                 case 'N':
9219                         torture_nprocs = atoi(optarg);
9220                         break;
9221                 case 'o':
9222                         torture_numops = atoi(optarg);
9223                         break;
9224                 case 'd':
9225                         lp_set_cmdline("log level", optarg);
9226                         break;
9227                 case 'O':
9228                         sockops = optarg;
9229                         break;
9230                 case 'L':
9231                         use_oplocks = True;
9232                         break;
9233                 case 'l':
9234                         local_path = optarg;
9235                         break;
9236                 case 'A':
9237                         torture_showall = True;
9238                         break;
9239                 case 'n':
9240                         fstrcpy(myname, optarg);
9241                         break;
9242                 case 'c':
9243                         client_txt = optarg;
9244                         break;
9245                 case 'e':
9246                         do_encrypt = true;
9247                         break;
9248                 case 'k':
9249 #ifdef HAVE_KRB5
9250                         use_kerberos = True;
9251 #else
9252                         d_printf("No kerberos support compiled in\n");
9253                         exit(1);
9254 #endif
9255                         break;
9256                 case 'U':
9257                         gotuser = 1;
9258                         fstrcpy(username,optarg);
9259                         p = strchr_m(username,'%');
9260                         if (p) {
9261                                 *p = 0;
9262                                 fstrcpy(password, p+1);
9263                                 gotpass = 1;
9264                         }
9265                         break;
9266                 case 'b':
9267                         fstrcpy(multishare_conn_fname, optarg);
9268                         use_multishare_conn = True;
9269                         break;
9270                 case 'B':
9271                         torture_blocksize = atoi(optarg);
9272                         break;
9273                 case 'f':
9274                         test_filename = SMB_STRDUP(optarg);
9275                         break;
9276                 default:
9277                         printf("Unknown option %c (%d)\n", (char)opt, opt);
9278                         usage();
9279                 }
9280         }
9281
9282         d_printf("using seed %d\n", seed);
9283
9284         srandom(seed);
9285
9286         if(use_kerberos && !gotuser) gotpass = True;
9287
9288         while (!gotpass) {
9289                 p = getpass("Password:");
9290                 if (p) {
9291                         fstrcpy(password, p);
9292                         gotpass = 1;
9293                 }
9294         }
9295
9296         printf("host=%s share=%s user=%s myname=%s\n", 
9297                host, share, username, myname);
9298
9299         if (argc == optind) {
9300                 correct = run_test("ALL");
9301         } else {
9302                 for (i=optind;i<argc;i++) {
9303                         if (!run_test(argv[i])) {
9304                                 correct = False;
9305                         }
9306                 }
9307         }
9308
9309         TALLOC_FREE(frame);
9310
9311         if (correct) {
9312                 return(0);
9313         } else {
9314                 return(1);
9315         }
9316 }