s3:torture:delete: simplify return code handling, fixing a couple of return codes...
[samba.git] / source3 / torture / torture.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB torture tester
4    Copyright (C) Andrew Tridgell 1997-1998
5    Copyright (C) Jeremy Allison 2009
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "system/shmem.h"
23 #include "wbc_async.h"
24 #include "torture/proto.h"
25 #include "libcli/security/security.h"
26 #include "tldap.h"
27 #include "tldap_util.h"
28 #include "../librpc/gen_ndr/svcctl.h"
29 #include "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 = false;
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                 goto fail;
3878         }
3879
3880         status = cli_close(cli1, fnum1);
3881         if (!NT_STATUS_IS_OK(status)) {
3882                 printf("[1] close failed (%s)\n", nt_errstr(status));
3883                 goto fail;
3884         }
3885
3886         status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3887         if (NT_STATUS_IS_OK(status)) {
3888                 printf("[1] open of %s succeeded (should fail)\n", fname);
3889                 goto fail;
3890         }
3891
3892         printf("first delete on close test succeeded.\n");
3893
3894         /* Test 2 - this should delete the file on close. */
3895
3896         cli_setatr(cli1, fname, 0, 0);
3897         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3898
3899         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3900                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3901                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
3902         if (!NT_STATUS_IS_OK(status)) {
3903                 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3904                 goto fail;
3905         }
3906
3907         status = cli_nt_delete_on_close(cli1, fnum1, true);
3908         if (!NT_STATUS_IS_OK(status)) {
3909                 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3910                 goto fail;
3911         }
3912
3913         status = cli_close(cli1, fnum1);
3914         if (!NT_STATUS_IS_OK(status)) {
3915                 printf("[2] close failed (%s)\n", nt_errstr(status));
3916                 goto fail;
3917         }
3918
3919         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
3920         if (NT_STATUS_IS_OK(status)) {
3921                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3922                 status = cli_close(cli1, fnum1);
3923                 if (!NT_STATUS_IS_OK(status)) {
3924                         printf("[2] close failed (%s)\n", nt_errstr(status));
3925                 }
3926                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3927                 goto fail;
3928         }
3929
3930         printf("second delete on close test succeeded.\n");
3931
3932         /* Test 3 - ... */
3933         cli_setatr(cli1, fname, 0, 0);
3934         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3935
3936         status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3937                               FILE_ATTRIBUTE_NORMAL,
3938                               FILE_SHARE_READ|FILE_SHARE_WRITE,
3939                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
3940         if (!NT_STATUS_IS_OK(status)) {
3941                 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3942                 goto fail;
3943         }
3944
3945         /* This should fail with a sharing violation - open for delete is only compatible
3946            with SHARE_DELETE. */
3947
3948         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3949                               FILE_ATTRIBUTE_NORMAL,
3950                               FILE_SHARE_READ|FILE_SHARE_WRITE,
3951                               FILE_OPEN, 0, 0, &fnum2);
3952         if (NT_STATUS_IS_OK(status)) {
3953                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
3954                 goto fail;
3955         }
3956
3957         /* This should succeed. */
3958         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3959                              FILE_ATTRIBUTE_NORMAL,
3960                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3961                              FILE_OPEN, 0, 0, &fnum2);
3962         if (!NT_STATUS_IS_OK(status)) {
3963                 printf("[3] open  - 3 of %s failed (%s)\n", fname, nt_errstr(status));
3964                 goto fail;
3965         }
3966
3967         status = cli_nt_delete_on_close(cli1, fnum1, true);
3968         if (!NT_STATUS_IS_OK(status)) {
3969                 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
3970                 goto fail;
3971         }
3972
3973         status = cli_close(cli1, fnum1);
3974         if (!NT_STATUS_IS_OK(status)) {
3975                 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
3976                 goto fail;
3977         }
3978
3979         status = cli_close(cli1, fnum2);
3980         if (!NT_STATUS_IS_OK(status)) {
3981                 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
3982                 goto fail;
3983         }
3984
3985         /* This should fail - file should no longer be there. */
3986
3987         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
3988         if (NT_STATUS_IS_OK(status)) {
3989                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3990                 status = cli_close(cli1, fnum1);
3991                 if (!NT_STATUS_IS_OK(status)) {
3992                         printf("[3] close failed (%s)\n", nt_errstr(status));
3993                 }
3994                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3995                 goto fail;
3996         }
3997
3998         printf("third delete on close test succeeded.\n");
3999
4000         /* Test 4 ... */
4001         cli_setatr(cli1, fname, 0, 0);
4002         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4003
4004         status = cli_ntcreate(cli1, fname, 0,
4005                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4006                               FILE_ATTRIBUTE_NORMAL,
4007                               FILE_SHARE_READ|FILE_SHARE_WRITE,
4008                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
4009         if (!NT_STATUS_IS_OK(status)) {
4010                 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
4011                 goto fail;
4012         }
4013
4014         /* This should succeed. */
4015         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4016                              FILE_ATTRIBUTE_NORMAL,
4017                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4018                              FILE_OPEN, 0, 0, &fnum2);
4019         if (!NT_STATUS_IS_OK(status)) {
4020                 printf("[4] open  - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4021                 goto fail;
4022         }
4023
4024         status = cli_close(cli1, fnum2);
4025         if (!NT_STATUS_IS_OK(status)) {
4026                 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
4027                 goto fail;
4028         }
4029
4030         status = cli_nt_delete_on_close(cli1, fnum1, true);
4031         if (!NT_STATUS_IS_OK(status)) {
4032                 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
4033                 goto fail;
4034         }
4035
4036         /* This should fail - no more opens once delete on close set. */
4037         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4038                               FILE_ATTRIBUTE_NORMAL,
4039                               FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4040                               FILE_OPEN, 0, 0, &fnum2);
4041         if (NT_STATUS_IS_OK(status)) {
4042                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
4043                 goto fail;
4044         }
4045
4046         status = cli_close(cli1, fnum1);
4047         if (!NT_STATUS_IS_OK(status)) {
4048                 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4049                 goto fail;
4050         }
4051
4052         printf("fourth delete on close test succeeded.\n");
4053
4054         /* Test 5 ... */
4055         cli_setatr(cli1, fname, 0, 0);
4056         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4057
4058         status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4059         if (!NT_STATUS_IS_OK(status)) {
4060                 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4061                 goto fail;
4062         }
4063
4064         /* This should fail - only allowed on NT opens with DELETE access. */
4065
4066         status = cli_nt_delete_on_close(cli1, fnum1, true);
4067         if (NT_STATUS_IS_OK(status)) {
4068                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4069                 goto fail;
4070         }
4071
4072         status = cli_close(cli1, fnum1);
4073         if (!NT_STATUS_IS_OK(status)) {
4074                 printf("[5] close failed (%s)\n", nt_errstr(status));
4075                 goto fail;
4076         }
4077
4078         printf("fifth delete on close test succeeded.\n");
4079
4080         /* Test 6 ... */
4081         cli_setatr(cli1, fname, 0, 0);
4082         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4083
4084         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4085                              FILE_ATTRIBUTE_NORMAL,
4086                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4087                              FILE_OVERWRITE_IF, 0, 0, &fnum1);
4088         if (!NT_STATUS_IS_OK(status)) {
4089                 printf("[6] open of %s failed (%s)\n", fname,
4090                        nt_errstr(status));
4091                 goto fail;
4092         }
4093
4094         /* This should fail - only allowed on NT opens with DELETE access. */
4095
4096         status = cli_nt_delete_on_close(cli1, fnum1, true);
4097         if (NT_STATUS_IS_OK(status)) {
4098                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4099                 goto fail;
4100         }
4101
4102         status = cli_close(cli1, fnum1);
4103         if (!NT_STATUS_IS_OK(status)) {
4104                 printf("[6] close failed (%s)\n", nt_errstr(status));
4105                 goto fail;
4106         }
4107
4108         printf("sixth delete on close test succeeded.\n");
4109
4110         /* Test 7 ... */
4111         cli_setatr(cli1, fname, 0, 0);
4112         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4113
4114         status = cli_ntcreate(cli1, fname, 0,
4115                               FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4116                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4117                               0, 0, &fnum1);
4118         if (!NT_STATUS_IS_OK(status)) {
4119                 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4120                 goto fail;
4121         }
4122
4123         status = cli_nt_delete_on_close(cli1, fnum1, true);
4124         if (!NT_STATUS_IS_OK(status)) {
4125                 printf("[7] setting delete_on_close on file failed !\n");
4126                 goto fail;
4127         }
4128
4129         status = cli_nt_delete_on_close(cli1, fnum1, false);
4130         if (!NT_STATUS_IS_OK(status)) {
4131                 printf("[7] unsetting delete_on_close on file failed !\n");
4132                 goto fail;
4133         }
4134
4135         status = cli_close(cli1, fnum1);
4136         if (!NT_STATUS_IS_OK(status)) {
4137                 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
4138                 goto fail;
4139         }
4140
4141         /* This next open should succeed - we reset the flag. */
4142         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4143         if (!NT_STATUS_IS_OK(status)) {
4144                 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4145                 goto fail;
4146         }
4147
4148         status = cli_close(cli1, fnum1);
4149         if (!NT_STATUS_IS_OK(status)) {
4150                 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4151                 goto fail;
4152         }
4153
4154         printf("seventh delete on close test succeeded.\n");
4155
4156         /* Test 8 ... */
4157         cli_setatr(cli1, fname, 0, 0);
4158         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4159
4160         if (!torture_open_connection(&cli2, 1)) {
4161                 printf("[8] failed to open second connection.\n");
4162                 goto fail;
4163         }
4164
4165         smbXcli_conn_set_sockopt(cli1->conn, sockops);
4166
4167         status = cli_ntcreate(cli1, fname, 0,
4168                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4169                              FILE_ATTRIBUTE_NORMAL,
4170                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4171                              FILE_OVERWRITE_IF, 0, 0, &fnum1);
4172         if (!NT_STATUS_IS_OK(status)) {
4173                 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4174                 goto fail;
4175         }
4176
4177         status = cli_ntcreate(cli2, fname, 0,
4178                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4179                              FILE_ATTRIBUTE_NORMAL,
4180                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4181                              FILE_OPEN, 0, 0, &fnum2);
4182         if (!NT_STATUS_IS_OK(status)) {
4183                 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4184                 goto fail;
4185         }
4186
4187         status = cli_nt_delete_on_close(cli1, fnum1, true);
4188         if (!NT_STATUS_IS_OK(status)) {
4189                 printf("[8] setting delete_on_close on file failed !\n");
4190                 goto fail;
4191         }
4192
4193         status = cli_close(cli1, fnum1);
4194         if (!NT_STATUS_IS_OK(status)) {
4195                 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4196                 goto fail;
4197         }
4198
4199         status = cli_close(cli2, fnum2);
4200         if (!NT_STATUS_IS_OK(status)) {
4201                 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4202                 goto fail;
4203         }
4204
4205         /* This should fail.. */
4206         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4207         if (NT_STATUS_IS_OK(status)) {
4208                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4209                 goto fail;
4210         }
4211
4212         printf("eighth delete on close test succeeded.\n");
4213
4214         /* Test 9 ... */
4215
4216         /* This should fail - we need to set DELETE_ACCESS. */
4217         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4218                               FILE_ATTRIBUTE_NORMAL,
4219                               FILE_SHARE_NONE,
4220                               FILE_OVERWRITE_IF,
4221                               FILE_DELETE_ON_CLOSE, 0, &fnum1);
4222         if (NT_STATUS_IS_OK(status)) {
4223                 printf("[9] open of %s succeeded should have failed!\n", fname);
4224                 goto fail;
4225         }
4226
4227         printf("ninth delete on close test succeeded.\n");
4228
4229         /* Test 10 ... */
4230
4231         status = cli_ntcreate(cli1, fname, 0,
4232                              FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4233                              FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4234                              FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4235                              0, &fnum1);
4236         if (!NT_STATUS_IS_OK(status)) {
4237                 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4238                 goto fail;
4239         }
4240
4241         /* This should delete the file. */
4242         status = cli_close(cli1, fnum1);
4243         if (!NT_STATUS_IS_OK(status)) {
4244                 printf("[10] close failed (%s)\n", nt_errstr(status));
4245                 goto fail;
4246         }
4247
4248         /* This should fail.. */
4249         status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4250         if (NT_STATUS_IS_OK(status)) {
4251                 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4252                 goto fail;
4253         }
4254
4255         printf("tenth delete on close test succeeded.\n");
4256
4257         /* Test 11 ... */
4258
4259         cli_setatr(cli1, fname, 0, 0);
4260         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4261
4262         /* What error do we get when attempting to open a read-only file with
4263            delete access ? */
4264
4265         /* Create a readonly file. */
4266         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4267                               FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4268                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
4269         if (!NT_STATUS_IS_OK(status)) {
4270                 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4271                 goto fail;
4272         }
4273
4274         status = cli_close(cli1, fnum1);
4275         if (!NT_STATUS_IS_OK(status)) {
4276                 printf("[11] close failed (%s)\n", nt_errstr(status));
4277                 goto fail;
4278         }
4279
4280         /* Now try open for delete access. */
4281         status = cli_ntcreate(cli1, fname, 0,
4282                              FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4283                              0,
4284                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4285                              FILE_OVERWRITE_IF, 0, 0, &fnum1);
4286         if (NT_STATUS_IS_OK(status)) {
4287                 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4288                 cli_close(cli1, fnum1);
4289                 goto fail;
4290         } else if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4291                 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(status));
4292                 goto fail;
4293         }
4294
4295         printf("eleventh delete on close test succeeded.\n");
4296
4297         printf("finished delete test\n");
4298
4299         correct = true;
4300
4301   fail:
4302         /* FIXME: This will crash if we aborted before cli2 got
4303          * intialized, because these functions don't handle
4304          * uninitialized connections. */
4305
4306         if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4307         if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4308         cli_setatr(cli1, fname, 0, 0);
4309         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4310
4311         if (cli1 && !torture_close_connection(cli1)) {
4312                 correct = False;
4313         }
4314         if (cli2 && !torture_close_connection(cli2)) {
4315                 correct = False;
4316         }
4317         return correct;
4318 }
4319
4320 static bool run_deletetest_ln(int dummy)
4321 {
4322         struct cli_state *cli;
4323         const char *fname = "\\delete1";
4324         const char *fname_ln = "\\delete1_ln";
4325         uint16_t fnum;
4326         uint16_t fnum1;
4327         NTSTATUS status;
4328         bool correct = true;
4329         time_t t;
4330
4331         printf("starting deletetest-ln\n");
4332
4333         if (!torture_open_connection(&cli, 0)) {
4334                 return false;
4335         }
4336
4337         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4338         cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4339
4340         smbXcli_conn_set_sockopt(cli->conn, sockops);
4341
4342         /* Create the file. */
4343         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4344         if (!NT_STATUS_IS_OK(status)) {
4345                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4346                 return false;
4347         }
4348
4349         status = cli_close(cli, fnum);
4350         if (!NT_STATUS_IS_OK(status)) {
4351                 printf("close1 failed (%s)\n", nt_errstr(status));
4352                 return false;
4353         }
4354
4355         /* Now create a hardlink. */
4356         status = cli_nt_hardlink(cli, fname, fname_ln);
4357         if (!NT_STATUS_IS_OK(status)) {
4358                 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4359                 return false;
4360         }
4361
4362         /* Open the original file. */
4363         status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4364                         FILE_ATTRIBUTE_NORMAL,
4365                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4366                         FILE_OPEN_IF, 0, 0, &fnum);
4367         if (!NT_STATUS_IS_OK(status)) {
4368                 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4369                 return false;
4370         }
4371
4372         /* Unlink the hard link path. */
4373         status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4374                         FILE_ATTRIBUTE_NORMAL,
4375                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4376                         FILE_OPEN_IF, 0, 0, &fnum1);
4377         if (!NT_STATUS_IS_OK(status)) {
4378                 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4379                 return false;
4380         }
4381         status = cli_nt_delete_on_close(cli, fnum1, true);
4382         if (!NT_STATUS_IS_OK(status)) {
4383                 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4384                         __location__, fname_ln, nt_errstr(status));
4385                 return false;
4386         }
4387
4388         status = cli_close(cli, fnum1);
4389         if (!NT_STATUS_IS_OK(status)) {
4390                 printf("close %s failed (%s)\n",
4391                         fname_ln, nt_errstr(status));
4392                 return false;
4393         }
4394
4395         status = cli_close(cli, fnum);
4396         if (!NT_STATUS_IS_OK(status)) {
4397                 printf("close %s failed (%s)\n",
4398                         fname, nt_errstr(status));
4399                 return false;
4400         }
4401
4402         /* Ensure the original file is still there. */
4403         status = cli_getatr(cli, fname, NULL, NULL, &t);
4404         if (!NT_STATUS_IS_OK(status)) {
4405                 printf("%s getatr on file %s failed (%s)\n",
4406                         __location__,
4407                         fname,
4408                         nt_errstr(status));
4409                 correct = False;
4410         }
4411
4412         /* Ensure the link path is gone. */
4413         status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4414         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4415                 printf("%s, getatr for file %s returned wrong error code %s "
4416                         "- should have been deleted\n",
4417                         __location__,
4418                         fname_ln, nt_errstr(status));
4419                 correct = False;
4420         }
4421
4422         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4423         cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4424
4425         if (!torture_close_connection(cli)) {
4426                 correct = false;
4427         }
4428
4429         printf("finished deletetest-ln\n");
4430
4431         return correct;
4432 }
4433
4434 /*
4435   print out server properties
4436  */
4437 static bool run_properties(int dummy)
4438 {
4439         struct cli_state *cli;
4440         bool correct = True;
4441
4442         printf("starting properties test\n");
4443
4444         ZERO_STRUCT(cli);
4445
4446         if (!torture_open_connection(&cli, 0)) {
4447                 return False;
4448         }
4449
4450         smbXcli_conn_set_sockopt(cli->conn, sockops);
4451
4452         d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
4453
4454         if (!torture_close_connection(cli)) {
4455                 correct = False;
4456         }
4457
4458         return correct;
4459 }
4460
4461
4462
4463 /* FIRST_DESIRED_ACCESS   0xf019f */
4464 #define FIRST_DESIRED_ACCESS   FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4465                                FILE_READ_EA|                           /* 0xf */ \
4466                                FILE_WRITE_EA|FILE_READ_ATTRIBUTES|     /* 0x90 */ \
4467                                FILE_WRITE_ATTRIBUTES|                  /* 0x100 */ \
4468                                DELETE_ACCESS|READ_CONTROL_ACCESS|\
4469                                WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS     /* 0xf0000 */
4470 /* SECOND_DESIRED_ACCESS  0xe0080 */
4471 #define SECOND_DESIRED_ACCESS  FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
4472                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4473                                WRITE_OWNER_ACCESS                      /* 0xe0000 */
4474
4475 #if 0
4476 #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
4477                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4478                                FILE_READ_DATA|\
4479                                WRITE_OWNER_ACCESS                      /* */
4480 #endif
4481
4482 /*
4483   Test ntcreate calls made by xcopy
4484  */
4485 static bool run_xcopy(int dummy)
4486 {
4487         static struct cli_state *cli1;
4488         const char *fname = "\\test.txt";
4489         bool correct = True;
4490         uint16_t fnum1, fnum2;
4491         NTSTATUS status;
4492
4493         printf("starting xcopy test\n");
4494
4495         if (!torture_open_connection(&cli1, 0)) {
4496                 return False;
4497         }
4498
4499         status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4500                               FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4501                               FILE_OVERWRITE_IF, 0x4044, 0, &fnum1);
4502         if (!NT_STATUS_IS_OK(status)) {
4503                 printf("First open failed - %s\n", nt_errstr(status));
4504                 return False;
4505         }
4506
4507         status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4508                              FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4509                              FILE_OPEN, 0x200000, 0, &fnum2);
4510         if (!NT_STATUS_IS_OK(status)) {
4511                 printf("second open failed - %s\n", nt_errstr(status));
4512                 return False;
4513         }
4514
4515         if (!torture_close_connection(cli1)) {
4516                 correct = False;
4517         }
4518
4519         return correct;
4520 }
4521
4522 /*
4523   Test rename on files open with share delete and no share delete.
4524  */
4525 static bool run_rename(int dummy)
4526 {
4527         static struct cli_state *cli1;
4528         const char *fname = "\\test.txt";
4529         const char *fname1 = "\\test1.txt";
4530         bool correct = True;
4531         uint16_t fnum1;
4532         uint16_t attr;
4533         NTSTATUS status;
4534
4535         printf("starting rename test\n");
4536
4537         if (!torture_open_connection(&cli1, 0)) {
4538                 return False;
4539         }
4540
4541         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4542         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4543
4544         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4545                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4546                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
4547         if (!NT_STATUS_IS_OK(status)) {
4548                 printf("First open failed - %s\n", nt_errstr(status));
4549                 return False;
4550         }
4551
4552         status = cli_rename(cli1, fname, fname1);
4553         if (!NT_STATUS_IS_OK(status)) {
4554                 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4555         } else {
4556                 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4557                 correct = False;
4558         }
4559
4560         status = cli_close(cli1, fnum1);
4561         if (!NT_STATUS_IS_OK(status)) {
4562                 printf("close - 1 failed (%s)\n", nt_errstr(status));
4563                 return False;
4564         }
4565
4566         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4567         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4568         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4569 #if 0
4570                               FILE_SHARE_DELETE|FILE_SHARE_NONE,
4571 #else
4572                               FILE_SHARE_DELETE|FILE_SHARE_READ,
4573 #endif
4574                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
4575         if (!NT_STATUS_IS_OK(status)) {
4576                 printf("Second open failed - %s\n", nt_errstr(status));
4577                 return False;
4578         }
4579
4580         status = cli_rename(cli1, fname, fname1);
4581         if (!NT_STATUS_IS_OK(status)) {
4582                 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4583                 correct = False;
4584         } else {
4585                 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4586         }
4587
4588         status = cli_close(cli1, fnum1);
4589         if (!NT_STATUS_IS_OK(status)) {
4590                 printf("close - 2 failed (%s)\n", nt_errstr(status));
4591                 return False;
4592         }
4593
4594         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4595         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4596
4597         status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4598                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4599                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
4600         if (!NT_STATUS_IS_OK(status)) {
4601                 printf("Third open failed - %s\n", nt_errstr(status));
4602                 return False;
4603         }
4604
4605
4606 #if 0
4607   {
4608         uint16_t fnum2;
4609
4610         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4611                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4612                 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4613                 return False;
4614         }
4615         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4616                 printf("[8] setting delete_on_close on file failed !\n");
4617                 return False;
4618         }
4619
4620         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4621                 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4622                 return False;
4623         }
4624   }
4625 #endif
4626
4627         status = cli_rename(cli1, fname, fname1);
4628         if (!NT_STATUS_IS_OK(status)) {
4629                 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4630                 correct = False;
4631         } else {
4632                 printf("Third rename succeeded (SHARE_NONE)\n");
4633         }
4634
4635         status = cli_close(cli1, fnum1);
4636         if (!NT_STATUS_IS_OK(status)) {
4637                 printf("close - 3 failed (%s)\n", nt_errstr(status));
4638                 return False;
4639         }
4640
4641         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4642         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4643
4644         /*----*/
4645
4646         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4647                               FILE_ATTRIBUTE_NORMAL,
4648                               FILE_SHARE_READ | FILE_SHARE_WRITE,
4649                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
4650         if (!NT_STATUS_IS_OK(status)) {
4651                 printf("Fourth open failed - %s\n", nt_errstr(status));
4652                 return False;
4653         }
4654
4655         status = cli_rename(cli1, fname, fname1);
4656         if (!NT_STATUS_IS_OK(status)) {
4657                 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4658         } else {
4659                 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4660                 correct = False;
4661         }
4662
4663         status = cli_close(cli1, fnum1);
4664         if (!NT_STATUS_IS_OK(status)) {
4665                 printf("close - 4 failed (%s)\n", nt_errstr(status));
4666                 return False;
4667         }
4668
4669         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4670         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4671
4672         /*--*/
4673
4674         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4675                          FILE_ATTRIBUTE_NORMAL,
4676                          FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4677                          FILE_OVERWRITE_IF, 0, 0, &fnum1);
4678         if (!NT_STATUS_IS_OK(status)) {
4679                 printf("Fifth open failed - %s\n", nt_errstr(status));
4680                 return False;
4681         }
4682
4683         status = cli_rename(cli1, fname, fname1);
4684         if (!NT_STATUS_IS_OK(status)) {
4685                 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4686                 correct = False;
4687         } else {
4688                 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4689         }
4690
4691         /*
4692          * Now check if the first name still exists ...
4693          */
4694
4695         /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4696                                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4697           printf("Opening original file after rename of open file fails: %s\n",
4698               cli_errstr(cli1));
4699         }
4700         else {
4701           printf("Opening original file after rename of open file works ...\n");
4702           (void)cli_close(cli1, fnum2);
4703           } */
4704
4705         /*--*/
4706         status = cli_close(cli1, fnum1);
4707         if (!NT_STATUS_IS_OK(status)) {
4708                 printf("close - 5 failed (%s)\n", nt_errstr(status));
4709                 return False;
4710         }
4711
4712         /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4713         status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4714         if (!NT_STATUS_IS_OK(status)) {
4715                 printf("getatr on file %s failed - %s ! \n",
4716                         fname1, nt_errstr(status));
4717                 correct = False;
4718         } else {
4719                 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4720                         printf("Renamed file %s has wrong attr 0x%x "
4721                                 "(should be 0x%x)\n",
4722                                 fname1,
4723                                 attr,
4724                                 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4725                         correct = False;
4726                 } else {
4727                         printf("Renamed file %s has archive bit set\n", fname1);
4728                 }
4729         }
4730
4731         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4732         cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4733
4734         if (!torture_close_connection(cli1)) {
4735                 correct = False;
4736         }
4737
4738         return correct;
4739 }
4740
4741 static bool run_pipe_number(int dummy)
4742 {
4743         struct cli_state *cli1;
4744         const char *pipe_name = "\\SPOOLSS";
4745         uint16_t fnum;
4746         int num_pipes = 0;
4747         NTSTATUS status;
4748
4749         printf("starting pipenumber test\n");
4750         if (!torture_open_connection(&cli1, 0)) {
4751                 return False;
4752         }
4753
4754         smbXcli_conn_set_sockopt(cli1->conn, sockops);
4755         while(1) {
4756                 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
4757                                       FILE_ATTRIBUTE_NORMAL,
4758                                       FILE_SHARE_READ|FILE_SHARE_WRITE,
4759                                       FILE_OPEN_IF, 0, 0, &fnum);
4760                 if (!NT_STATUS_IS_OK(status)) {
4761                         printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
4762                         break;
4763                 }
4764                 num_pipes++;
4765                 printf("\r%6d", num_pipes);
4766         }
4767
4768         printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4769         torture_close_connection(cli1);
4770         return True;
4771 }
4772
4773 /*
4774   Test open mode returns on read-only files.
4775  */
4776 static bool run_opentest(int dummy)
4777 {
4778         static struct cli_state *cli1;
4779         static struct cli_state *cli2;
4780         const char *fname = "\\readonly.file";
4781         uint16_t fnum1, fnum2;
4782         char buf[20];
4783         off_t fsize;
4784         bool correct = True;
4785         char *tmp_path;
4786         NTSTATUS status;
4787
4788         printf("starting open test\n");
4789
4790         if (!torture_open_connection(&cli1, 0)) {
4791                 return False;
4792         }
4793
4794         cli_setatr(cli1, fname, 0, 0);
4795         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4796
4797         smbXcli_conn_set_sockopt(cli1->conn, sockops);
4798
4799         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4800         if (!NT_STATUS_IS_OK(status)) {
4801                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4802                 return False;
4803         }
4804
4805         status = cli_close(cli1, fnum1);
4806         if (!NT_STATUS_IS_OK(status)) {
4807                 printf("close2 failed (%s)\n", nt_errstr(status));
4808                 return False;
4809         }
4810
4811         status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
4812         if (!NT_STATUS_IS_OK(status)) {
4813                 printf("cli_setatr failed (%s)\n", nt_errstr(status));
4814                 return False;
4815         }
4816
4817         status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4818         if (!NT_STATUS_IS_OK(status)) {
4819                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4820                 return False;
4821         }
4822
4823         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4824         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4825
4826         if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
4827                         NT_STATUS_ACCESS_DENIED)) {
4828                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4829         }
4830
4831         printf("finished open test 1\n");
4832
4833         cli_close(cli1, fnum1);
4834
4835         /* Now try not readonly and ensure ERRbadshare is returned. */
4836
4837         cli_setatr(cli1, fname, 0, 0);
4838
4839         status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4840         if (!NT_STATUS_IS_OK(status)) {
4841                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4842                 return False;
4843         }
4844
4845         /* This will fail - but the error should be ERRshare. */
4846         status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4847
4848         if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
4849                         NT_STATUS_SHARING_VIOLATION)) {
4850                 printf("correct error code ERRDOS/ERRbadshare returned\n");
4851         }
4852
4853         status = cli_close(cli1, fnum1);
4854         if (!NT_STATUS_IS_OK(status)) {
4855                 printf("close2 failed (%s)\n", nt_errstr(status));
4856                 return False;
4857         }
4858
4859         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4860
4861         printf("finished open test 2\n");
4862
4863         /* Test truncate open disposition on file opened for read. */
4864         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4865         if (!NT_STATUS_IS_OK(status)) {
4866                 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
4867                 return False;
4868         }
4869
4870         /* write 20 bytes. */
4871
4872         memset(buf, '\0', 20);
4873
4874         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4875         if (!NT_STATUS_IS_OK(status)) {
4876                 printf("write failed (%s)\n", nt_errstr(status));
4877                 correct = False;
4878         }
4879
4880         status = cli_close(cli1, fnum1);
4881         if (!NT_STATUS_IS_OK(status)) {
4882                 printf("(3) close1 failed (%s)\n", nt_errstr(status));
4883                 return False;
4884         }
4885
4886         /* Ensure size == 20. */
4887         status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4888         if (!NT_STATUS_IS_OK(status)) {
4889                 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4890                 return False;
4891         }
4892
4893         if (fsize != 20) {
4894                 printf("(3) file size != 20\n");
4895                 return False;
4896         }
4897
4898         /* Now test if we can truncate a file opened for readonly. */
4899         status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
4900         if (!NT_STATUS_IS_OK(status)) {
4901                 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
4902                 return False;
4903         }
4904
4905         status = cli_close(cli1, fnum1);
4906         if (!NT_STATUS_IS_OK(status)) {
4907                 printf("close2 failed (%s)\n", nt_errstr(status));
4908                 return False;
4909         }
4910
4911         /* Ensure size == 0. */
4912         status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4913         if (!NT_STATUS_IS_OK(status)) {
4914                 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4915                 return False;
4916         }
4917
4918         if (fsize != 0) {
4919                 printf("(3) file size != 0\n");
4920                 return False;
4921         }
4922         printf("finished open test 3\n");
4923
4924         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4925
4926         printf("Do ctemp tests\n");
4927         status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
4928         if (!NT_STATUS_IS_OK(status)) {
4929                 printf("ctemp failed (%s)\n", nt_errstr(status));
4930                 return False;
4931         }
4932
4933         printf("ctemp gave path %s\n", tmp_path);
4934         status = cli_close(cli1, fnum1);
4935         if (!NT_STATUS_IS_OK(status)) {
4936                 printf("close of temp failed (%s)\n", nt_errstr(status));
4937         }
4938
4939         status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4940         if (!NT_STATUS_IS_OK(status)) {
4941                 printf("unlink of temp failed (%s)\n", nt_errstr(status));
4942         }
4943
4944         /* Test the non-io opens... */
4945
4946         if (!torture_open_connection(&cli2, 1)) {
4947                 return False;
4948         }
4949
4950         cli_setatr(cli2, fname, 0, 0);
4951         cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4952
4953         smbXcli_conn_set_sockopt(cli2->conn, sockops);
4954
4955         printf("TEST #1 testing 2 non-io opens (no delete)\n");
4956         status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
4957                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4958                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
4959         if (!NT_STATUS_IS_OK(status)) {
4960                 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4961                 return False;
4962         }
4963
4964         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4965                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4966                               FILE_OPEN_IF, 0, 0, &fnum2);
4967         if (!NT_STATUS_IS_OK(status)) {
4968                 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4969                 return False;
4970         }
4971
4972         status = cli_close(cli1, fnum1);
4973         if (!NT_STATUS_IS_OK(status)) {
4974                 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4975                 return False;
4976         }
4977
4978         status = cli_close(cli2, fnum2);
4979         if (!NT_STATUS_IS_OK(status)) {
4980                 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4981                 return False;
4982         }
4983
4984         printf("non-io open test #1 passed.\n");
4985
4986         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4987
4988         printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4989
4990         status = cli_ntcreate(cli1, fname, 0,
4991                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4992                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4993                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
4994         if (!NT_STATUS_IS_OK(status)) {
4995                 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4996                 return False;
4997         }
4998
4999         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5000                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5001                               FILE_OPEN_IF, 0, 0, &fnum2);
5002         if (!NT_STATUS_IS_OK(status)) {
5003                 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5004                 return False;
5005         }
5006
5007         status = cli_close(cli1, fnum1);
5008         if (!NT_STATUS_IS_OK(status)) {
5009                 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5010                 return False;
5011         }
5012
5013         status = cli_close(cli2, fnum2);
5014         if (!NT_STATUS_IS_OK(status)) {
5015                 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5016                 return False;
5017         }
5018
5019         printf("non-io open test #2 passed.\n");
5020
5021         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5022
5023         printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5024
5025         status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5026                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5027                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
5028         if (!NT_STATUS_IS_OK(status)) {
5029                 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5030                 return False;
5031         }
5032
5033         status = cli_ntcreate(cli2, fname, 0,
5034                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5035                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5036                               FILE_OPEN_IF, 0, 0, &fnum2);
5037         if (!NT_STATUS_IS_OK(status)) {
5038                 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5039                 return False;
5040         }
5041
5042         status = cli_close(cli1, fnum1);
5043         if (!NT_STATUS_IS_OK(status)) {
5044                 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5045                 return False;
5046         }
5047
5048         status = cli_close(cli2, fnum2);
5049         if (!NT_STATUS_IS_OK(status)) {
5050                 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5051                 return False;
5052         }
5053
5054         printf("non-io open test #3 passed.\n");
5055
5056         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5057
5058         printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5059
5060         status = cli_ntcreate(cli1, fname, 0,
5061                                DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5062                                FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5063                                FILE_OVERWRITE_IF, 0, 0, &fnum1);
5064         if (!NT_STATUS_IS_OK(status)) {
5065                 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5066                 return False;
5067         }
5068
5069         status = cli_ntcreate(cli2, fname, 0,
5070                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5071                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5072                               FILE_OPEN_IF, 0, 0, &fnum2);
5073         if (NT_STATUS_IS_OK(status)) {
5074                 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5075                 return False;
5076         }
5077
5078         printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5079
5080         status = cli_close(cli1, fnum1);
5081         if (!NT_STATUS_IS_OK(status)) {
5082                 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5083                 return False;
5084         }
5085
5086         printf("non-io open test #4 passed.\n");
5087
5088         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5089
5090         printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5091
5092         status = cli_ntcreate(cli1, fname, 0,
5093                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5094                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5095                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
5096         if (!NT_STATUS_IS_OK(status)) {
5097                 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5098                 return False;
5099         }
5100
5101         status = cli_ntcreate(cli2, fname, 0,
5102                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5103                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5104                               FILE_OPEN_IF, 0, 0, &fnum2);
5105         if (!NT_STATUS_IS_OK(status)) {
5106                 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5107                 return False;
5108         }
5109
5110         status = cli_close(cli1, fnum1);
5111         if (!NT_STATUS_IS_OK(status)) {
5112                 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5113                 return False;
5114         }
5115
5116         status = cli_close(cli2, fnum2);
5117         if (!NT_STATUS_IS_OK(status)) {
5118                 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5119                 return False;
5120         }
5121
5122         printf("non-io open test #5 passed.\n");
5123
5124         printf("TEST #6 testing 1 non-io open, one io open\n");
5125
5126         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5127
5128         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5129                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5130                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
5131         if (!NT_STATUS_IS_OK(status)) {
5132                 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5133                 return False;
5134         }
5135
5136         status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5137                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5138                               FILE_OPEN_IF, 0, 0, &fnum2);
5139         if (!NT_STATUS_IS_OK(status)) {
5140                 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5141                 return False;
5142         }
5143
5144         status = cli_close(cli1, fnum1);
5145         if (!NT_STATUS_IS_OK(status)) {
5146                 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5147                 return False;
5148         }
5149
5150         status = cli_close(cli2, fnum2);
5151         if (!NT_STATUS_IS_OK(status)) {
5152                 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5153                 return False;
5154         }
5155
5156         printf("non-io open test #6 passed.\n");
5157
5158         printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5159
5160         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5161
5162         status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5163                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5164                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
5165         if (!NT_STATUS_IS_OK(status)) {
5166                 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5167                 return False;
5168         }
5169
5170         status = cli_ntcreate(cli2, fname, 0,
5171                               DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5172                               FILE_ATTRIBUTE_NORMAL,
5173                               FILE_SHARE_READ|FILE_SHARE_DELETE,
5174                               FILE_OPEN_IF, 0, 0, &fnum2);
5175         if (NT_STATUS_IS_OK(status)) {
5176                 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5177                 return False;
5178         }
5179
5180         printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5181
5182         status = cli_close(cli1, fnum1);
5183         if (!NT_STATUS_IS_OK(status)) {
5184                 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5185                 return False;
5186         }
5187
5188         printf("non-io open test #7 passed.\n");
5189
5190         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5191
5192         printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5193         status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5194                                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5195                                 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5196         if (!NT_STATUS_IS_OK(status)) {
5197                 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5198                 correct = false;
5199                 goto out;
5200         }
5201
5202         /* Write to ensure we have to update the file time. */
5203         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5204                               NULL);
5205         if (!NT_STATUS_IS_OK(status)) {
5206                 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5207                 correct = false;
5208                 goto out;
5209         }
5210
5211         status = cli_close(cli1, fnum1);
5212         if (!NT_STATUS_IS_OK(status)) {
5213                 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5214                 correct = false;
5215         }
5216
5217   out:
5218
5219         if (!torture_close_connection(cli1)) {
5220                 correct = False;
5221         }
5222         if (!torture_close_connection(cli2)) {
5223                 correct = False;
5224         }
5225
5226         return correct;
5227 }
5228
5229 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5230 {
5231         uint16 major, minor;
5232         uint32 caplow, caphigh;
5233         NTSTATUS status;
5234
5235         if (!SERVER_HAS_UNIX_CIFS(cli)) {
5236                 printf("Server doesn't support UNIX CIFS extensions.\n");
5237                 return NT_STATUS_NOT_SUPPORTED;
5238         }
5239
5240         status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5241                                              &caphigh);
5242         if (!NT_STATUS_IS_OK(status)) {
5243                 printf("Server didn't return UNIX CIFS extensions: %s\n",
5244                        nt_errstr(status));
5245                 return status;
5246         }
5247
5248         status = cli_set_unix_extensions_capabilities(cli, major, minor,
5249                                                       caplow, caphigh);
5250         if (!NT_STATUS_IS_OK(status)) {
5251                 printf("Server doesn't support setting UNIX CIFS extensions: "
5252                        "%s.\n", nt_errstr(status));
5253                 return status;
5254         }
5255
5256         return NT_STATUS_OK;
5257 }
5258
5259 /*
5260   Test POSIX open /mkdir calls.
5261  */
5262 static bool run_simple_posix_open_test(int dummy)
5263 {
5264         static struct cli_state *cli1;
5265         const char *fname = "posix:file";
5266         const char *hname = "posix:hlink";
5267         const char *sname = "posix:symlink";
5268         const char *dname = "posix:dir";
5269         char buf[10];
5270         char namebuf[11];
5271         uint16_t fnum1 = (uint16_t)-1;
5272         SMB_STRUCT_STAT sbuf;
5273         bool correct = false;
5274         NTSTATUS status;
5275         size_t nread;
5276
5277         printf("Starting simple POSIX open test\n");
5278
5279         if (!torture_open_connection(&cli1, 0)) {
5280                 return false;
5281         }
5282
5283         smbXcli_conn_set_sockopt(cli1->conn, sockops);
5284
5285         status = torture_setup_unix_extensions(cli1);
5286         if (!NT_STATUS_IS_OK(status)) {
5287                 return false;
5288         }
5289
5290         cli_setatr(cli1, fname, 0, 0);
5291         cli_posix_unlink(cli1, fname);
5292         cli_setatr(cli1, dname, 0, 0);
5293         cli_posix_rmdir(cli1, dname);
5294         cli_setatr(cli1, hname, 0, 0);
5295         cli_posix_unlink(cli1, hname);
5296         cli_setatr(cli1, sname, 0, 0);
5297         cli_posix_unlink(cli1, sname);
5298
5299         /* Create a directory. */
5300         status = cli_posix_mkdir(cli1, dname, 0777);
5301         if (!NT_STATUS_IS_OK(status)) {
5302                 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5303                 goto out;
5304         }
5305
5306         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5307                                 0600, &fnum1);
5308         if (!NT_STATUS_IS_OK(status)) {
5309                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5310                 goto out;
5311         }
5312
5313         /* Test ftruncate - set file size. */
5314         status = cli_ftruncate(cli1, fnum1, 1000);
5315         if (!NT_STATUS_IS_OK(status)) {
5316                 printf("ftruncate failed (%s)\n", nt_errstr(status));
5317                 goto out;
5318         }
5319
5320         /* Ensure st_size == 1000 */
5321         status = cli_posix_stat(cli1, fname, &sbuf);
5322         if (!NT_STATUS_IS_OK(status)) {
5323                 printf("stat failed (%s)\n", nt_errstr(status));
5324                 goto out;
5325         }
5326
5327         if (sbuf.st_ex_size != 1000) {
5328                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5329                 goto out;
5330         }
5331
5332         /* Ensure st_mode == 0600 */
5333         if ((sbuf.st_ex_mode & 07777) != 0600) {
5334                 printf("posix_open - bad permissions 0%o != 0600\n",
5335                                 (unsigned int)(sbuf.st_ex_mode & 07777));
5336                 goto out;
5337         }
5338
5339         /* Test ftruncate - set file size back to zero. */
5340         status = cli_ftruncate(cli1, fnum1, 0);
5341         if (!NT_STATUS_IS_OK(status)) {
5342                 printf("ftruncate failed (%s)\n", nt_errstr(status));
5343                 goto out;
5344         }
5345
5346         status = cli_close(cli1, fnum1);
5347         if (!NT_STATUS_IS_OK(status)) {
5348                 printf("close failed (%s)\n", nt_errstr(status));
5349                 goto out;
5350         }
5351
5352         /* Now open the file again for read only. */
5353         status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5354         if (!NT_STATUS_IS_OK(status)) {
5355                 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
5356                 goto out;
5357         }
5358
5359         /* Now unlink while open. */
5360         status = cli_posix_unlink(cli1, fname);
5361         if (!NT_STATUS_IS_OK(status)) {
5362                 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5363                 goto out;
5364         }
5365
5366         status = cli_close(cli1, fnum1);
5367         if (!NT_STATUS_IS_OK(status)) {
5368                 printf("close(2) failed (%s)\n", nt_errstr(status));
5369                 goto out;
5370         }
5371
5372         /* Ensure the file has gone. */
5373         status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5374         if (NT_STATUS_IS_OK(status)) {
5375                 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5376                 goto out;
5377         }
5378
5379         /* Create again to test open with O_TRUNC. */
5380         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
5381         if (!NT_STATUS_IS_OK(status)) {
5382                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5383                 goto out;
5384         }
5385
5386         /* Test ftruncate - set file size. */
5387         status = cli_ftruncate(cli1, fnum1, 1000);
5388         if (!NT_STATUS_IS_OK(status)) {
5389                 printf("ftruncate failed (%s)\n", nt_errstr(status));
5390                 goto out;
5391         }
5392
5393         /* Ensure st_size == 1000 */
5394         status = cli_posix_stat(cli1, fname, &sbuf);
5395         if (!NT_STATUS_IS_OK(status)) {
5396                 printf("stat failed (%s)\n", nt_errstr(status));
5397                 goto out;
5398         }
5399
5400         if (sbuf.st_ex_size != 1000) {
5401                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5402                 goto out;
5403         }
5404
5405         status = cli_close(cli1, fnum1);
5406         if (!NT_STATUS_IS_OK(status)) {
5407                 printf("close(2) failed (%s)\n", nt_errstr(status));
5408                 goto out;
5409         }
5410
5411         /* Re-open with O_TRUNC. */
5412         status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
5413         if (!NT_STATUS_IS_OK(status)) {
5414                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5415                 goto out;
5416         }
5417
5418         /* Ensure st_size == 0 */
5419         status = cli_posix_stat(cli1, fname, &sbuf);
5420         if (!NT_STATUS_IS_OK(status)) {
5421                 printf("stat failed (%s)\n", nt_errstr(status));
5422                 goto out;
5423         }
5424
5425         if (sbuf.st_ex_size != 0) {
5426                 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5427                 goto out;
5428         }
5429
5430         status = cli_close(cli1, fnum1);
5431         if (!NT_STATUS_IS_OK(status)) {
5432                 printf("close failed (%s)\n", nt_errstr(status));
5433                 goto out;
5434         }
5435
5436         status = cli_posix_unlink(cli1, fname);
5437         if (!NT_STATUS_IS_OK(status)) {
5438                 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5439                 goto out;
5440         }
5441
5442         status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
5443         if (!NT_STATUS_IS_OK(status)) {
5444                 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5445                         dname, nt_errstr(status));
5446                 goto out;
5447         }
5448
5449         cli_close(cli1, fnum1);
5450
5451         /* What happens when we try and POSIX open a directory for write ? */
5452         status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
5453         if (NT_STATUS_IS_OK(status)) {
5454                 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5455                 goto out;
5456         } else {
5457                 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
5458                                 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5459                         goto out;
5460                 }
5461         }
5462
5463         /* Create the file. */
5464         status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5465                                 0600, &fnum1);
5466         if (!NT_STATUS_IS_OK(status)) {
5467                 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5468                 goto out;
5469         }
5470
5471         /* Write some data into it. */
5472         status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5473                               NULL);
5474         if (!NT_STATUS_IS_OK(status)) {
5475                 printf("cli_write failed: %s\n", nt_errstr(status));
5476                 goto out;
5477         }
5478
5479         cli_close(cli1, fnum1);
5480
5481         /* Now create a hardlink. */
5482         status = cli_posix_hardlink(cli1, fname, hname);
5483         if (!NT_STATUS_IS_OK(status)) {
5484                 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5485                 goto out;
5486         }
5487
5488         /* Now create a symlink. */
5489         status = cli_posix_symlink(cli1, fname, sname);
5490         if (!NT_STATUS_IS_OK(status)) {
5491                 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5492                 goto out;
5493         }
5494
5495         /* Open the hardlink for read. */
5496         status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5497         if (!NT_STATUS_IS_OK(status)) {
5498                 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5499                 goto out;
5500         }
5501
5502         status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
5503         if (!NT_STATUS_IS_OK(status)) {
5504                 printf("POSIX read of %s failed (%s)\n", hname,
5505                        nt_errstr(status));
5506                 goto out;
5507         } else if (nread != 10) {
5508                 printf("POSIX read of %s failed. Received %ld, expected %d\n",
5509                        hname, (unsigned long)nread, 10);
5510                 goto out;
5511         }
5512
5513         if (memcmp(buf, "TEST DATA\n", 10)) {
5514                 printf("invalid data read from hardlink\n");
5515                 goto out;
5516         }
5517
5518         /* Do a POSIX lock/unlock. */
5519         status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5520         if (!NT_STATUS_IS_OK(status)) {
5521                 printf("POSIX lock failed %s\n", nt_errstr(status));
5522                 goto out;
5523         }
5524
5525         /* Punch a hole in the locked area. */
5526         status = cli_posix_unlock(cli1, fnum1, 10, 80);
5527         if (!NT_STATUS_IS_OK(status)) {
5528                 printf("POSIX unlock failed %s\n", nt_errstr(status));
5529                 goto out;
5530         }
5531
5532         cli_close(cli1, fnum1);
5533
5534         /* Open the symlink for read - this should fail. A POSIX
5535            client should not be doing opens on a symlink. */
5536         status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5537         if (NT_STATUS_IS_OK(status)) {
5538                 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5539                 goto out;
5540         } else {
5541                 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
5542                                 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5543                         printf("POSIX open of %s should have failed "
5544                                 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5545                                 "failed with %s instead.\n",
5546                                 sname, nt_errstr(status));
5547                         goto out;
5548                 }
5549         }
5550
5551         status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5552         if (!NT_STATUS_IS_OK(status)) {
5553                 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5554                 goto out;
5555         }
5556
5557         if (strcmp(namebuf, fname) != 0) {
5558                 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5559                         sname, fname, namebuf);
5560                 goto out;
5561         }
5562
5563         status = cli_posix_rmdir(cli1, dname);
5564         if (!NT_STATUS_IS_OK(status)) {
5565                 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5566                 goto out;
5567         }
5568
5569         /* Check directory opens with a specific permission. */
5570         status = cli_posix_mkdir(cli1, dname, 0700);
5571         if (!NT_STATUS_IS_OK(status)) {
5572                 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5573                 goto out;
5574         }
5575
5576         /* Ensure st_mode == 0700 */
5577         status = cli_posix_stat(cli1, dname, &sbuf);
5578         if (!NT_STATUS_IS_OK(status)) {
5579                 printf("stat failed (%s)\n", nt_errstr(status));
5580                 goto out;
5581         }
5582
5583         if ((sbuf.st_ex_mode & 07777) != 0700) {
5584                 printf("posix_mkdir - bad permissions 0%o != 0700\n",
5585                                 (unsigned int)(sbuf.st_ex_mode & 07777));
5586                 goto out;
5587         }
5588
5589         printf("Simple POSIX open test passed\n");
5590         correct = true;
5591
5592   out:
5593
5594         if (fnum1 != (uint16_t)-1) {
5595                 cli_close(cli1, fnum1);
5596                 fnum1 = (uint16_t)-1;
5597         }
5598
5599         cli_setatr(cli1, sname, 0, 0);
5600         cli_posix_unlink(cli1, sname);
5601         cli_setatr(cli1, hname, 0, 0);
5602         cli_posix_unlink(cli1, hname);
5603         cli_setatr(cli1, fname, 0, 0);
5604         cli_posix_unlink(cli1, fname);
5605         cli_setatr(cli1, dname, 0, 0);
5606         cli_posix_rmdir(cli1, dname);
5607
5608         if (!torture_close_connection(cli1)) {
5609                 correct = false;
5610         }
5611
5612         return correct;
5613 }
5614
5615
5616 static uint32 open_attrs_table[] = {
5617                 FILE_ATTRIBUTE_NORMAL,
5618                 FILE_ATTRIBUTE_ARCHIVE,
5619                 FILE_ATTRIBUTE_READONLY,
5620                 FILE_ATTRIBUTE_HIDDEN,
5621                 FILE_ATTRIBUTE_SYSTEM,
5622
5623                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5624                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5625                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5626                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5627                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5628                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5629
5630                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5631                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5632                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5633                 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5634 };
5635
5636 struct trunc_open_results {
5637         unsigned int num;
5638         uint32 init_attr;
5639         uint32 trunc_attr;
5640         uint32 result_attr;
5641 };
5642
5643 static struct trunc_open_results attr_results[] = {
5644         { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5645         { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5646         { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5647         { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5648         { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5649         { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5650         { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5651         { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5652         { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5653         { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5654         { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5655         { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5656         { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5657         { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5658         { 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 },
5659         { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5660         { 119,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5661         { 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 },
5662         { 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 },
5663         { 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 },
5664         { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5665         { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5666         { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5667         { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5668         { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5669         { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5670 };
5671
5672 static bool run_openattrtest(int dummy)
5673 {
5674         static struct cli_state *cli1;
5675         const char *fname = "\\openattr.file";
5676         uint16_t fnum1;
5677         bool correct = True;
5678         uint16 attr;
5679         unsigned int i, j, k, l;
5680         NTSTATUS status;
5681
5682         printf("starting open attr test\n");
5683
5684         if (!torture_open_connection(&cli1, 0)) {
5685                 return False;
5686         }
5687
5688         smbXcli_conn_set_sockopt(cli1->conn, sockops);
5689
5690         for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5691                 cli_setatr(cli1, fname, 0, 0);
5692                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5693
5694                 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
5695                                        open_attrs_table[i], FILE_SHARE_NONE,
5696                                        FILE_OVERWRITE_IF, 0, 0, &fnum1);
5697                 if (!NT_STATUS_IS_OK(status)) {
5698                         printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5699                         return False;
5700                 }
5701
5702                 status = cli_close(cli1, fnum1);
5703                 if (!NT_STATUS_IS_OK(status)) {
5704                         printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5705                         return False;
5706                 }
5707
5708                 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5709                         status = cli_ntcreate(cli1, fname, 0,
5710                                               FILE_READ_DATA|FILE_WRITE_DATA,
5711                                               open_attrs_table[j],
5712                                               FILE_SHARE_NONE, FILE_OVERWRITE,
5713                                               0, 0, &fnum1);
5714                         if (!NT_STATUS_IS_OK(status)) {
5715                                 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5716                                         if (attr_results[l].num == k) {
5717                                                 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5718                                                                 k, open_attrs_table[i],
5719                                                                 open_attrs_table[j],
5720                                                                 fname, NT_STATUS_V(status), nt_errstr(status));
5721                                                 correct = False;
5722                                         }
5723                                 }
5724
5725                                 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5726                                         printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5727                                                         k, open_attrs_table[i], open_attrs_table[j],
5728                                                         nt_errstr(status));
5729                                         correct = False;
5730                                 }
5731 #if 0
5732                                 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5733 #endif
5734                                 k++;
5735                                 continue;
5736                         }
5737
5738                         status = cli_close(cli1, fnum1);
5739                         if (!NT_STATUS_IS_OK(status)) {
5740                                 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
5741                                 return False;
5742                         }
5743
5744                         status = cli_getatr(cli1, fname, &attr, NULL, NULL);
5745                         if (!NT_STATUS_IS_OK(status)) {
5746                                 printf("getatr(2) failed (%s)\n", nt_errstr(status));
5747                                 return False;
5748                         }
5749
5750 #if 0
5751                         printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5752                                         k,  open_attrs_table[i],  open_attrs_table[j], attr );
5753 #endif
5754
5755                         for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5756                                 if (attr_results[l].num == k) {
5757                                         if (attr != attr_results[l].result_attr ||
5758                                                         open_attrs_table[i] != attr_results[l].init_attr ||
5759                                                         open_attrs_table[j] != attr_results[l].trunc_attr) {
5760                                                 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5761                                                 open_attrs_table[i],
5762                                                 open_attrs_table[j],
5763                                                 (unsigned int)attr,
5764                                                 attr_results[l].result_attr);
5765                                                 correct = False;
5766                                         }
5767                                         break;
5768                                 }
5769                         }
5770                         k++;
5771                 }
5772         }
5773
5774         cli_setatr(cli1, fname, 0, 0);
5775         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5776
5777         printf("open attr test %s.\n", correct ? "passed" : "failed");
5778
5779         if (!torture_close_connection(cli1)) {
5780                 correct = False;
5781         }
5782         return correct;
5783 }
5784
5785 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5786                     const char *name, void *state)
5787 {
5788         int *matched = (int *)state;
5789         if (matched != NULL) {
5790                 *matched += 1;
5791         }
5792         return NT_STATUS_OK;
5793 }
5794
5795 /*
5796   test directory listing speed
5797  */
5798 static bool run_dirtest(int dummy)
5799 {
5800         int i;
5801         static struct cli_state *cli;
5802         uint16_t fnum;
5803         struct timeval core_start;
5804         bool correct = True;
5805         int matched;
5806
5807         printf("starting directory test\n");
5808
5809         if (!torture_open_connection(&cli, 0)) {
5810                 return False;
5811         }
5812
5813         smbXcli_conn_set_sockopt(cli->conn, sockops);
5814
5815         srandom(0);
5816         for (i=0;i<torture_numops;i++) {
5817                 fstring fname;
5818                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5819                 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5820                         fprintf(stderr,"Failed to open %s\n", fname);
5821                         return False;
5822                 }
5823                 cli_close(cli, fnum);
5824         }
5825
5826         core_start = timeval_current();
5827
5828         matched = 0;
5829         cli_list(cli, "a*.*", 0, list_fn, &matched);
5830         printf("Matched %d\n", matched);
5831
5832         matched = 0;
5833         cli_list(cli, "b*.*", 0, list_fn, &matched);
5834         printf("Matched %d\n", matched);
5835
5836         matched = 0;
5837         cli_list(cli, "xyzabc", 0, list_fn, &matched);
5838         printf("Matched %d\n", matched);
5839
5840         printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5841
5842         srandom(0);
5843         for (i=0;i<torture_numops;i++) {
5844                 fstring fname;
5845                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5846                 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5847         }
5848
5849         if (!torture_close_connection(cli)) {
5850                 correct = False;
5851         }
5852
5853         printf("finished dirtest\n");
5854
5855         return correct;
5856 }
5857
5858 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5859                    void *state)
5860 {
5861         struct cli_state *pcli = (struct cli_state *)state;
5862         fstring fname;
5863         slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5864
5865         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5866                 return NT_STATUS_OK;
5867
5868         if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5869                 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5870                         printf("del_fn: failed to rmdir %s\n,", fname );
5871         } else {
5872                 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5873                         printf("del_fn: failed to unlink %s\n,", fname );
5874         }
5875         return NT_STATUS_OK;
5876 }
5877
5878
5879 /*
5880   sees what IOCTLs are supported
5881  */
5882 bool torture_ioctl_test(int dummy)
5883 {
5884         static struct cli_state *cli;
5885         uint16_t device, function;
5886         uint16_t fnum;
5887         const char *fname = "\\ioctl.dat";
5888         DATA_BLOB blob;
5889         NTSTATUS status;
5890
5891         if (!torture_open_connection(&cli, 0)) {
5892                 return False;
5893         }
5894
5895         printf("starting ioctl test\n");
5896
5897         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5898
5899         status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5900         if (!NT_STATUS_IS_OK(status)) {
5901                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5902                 return False;
5903         }
5904
5905         status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5906         printf("ioctl device info: %s\n", nt_errstr(status));
5907
5908         status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5909         printf("ioctl job info: %s\n", nt_errstr(status));
5910
5911         for (device=0;device<0x100;device++) {
5912                 printf("ioctl test with device = 0x%x\n", device);
5913                 for (function=0;function<0x100;function++) {
5914                         uint32 code = (device<<16) | function;
5915
5916                         status = cli_raw_ioctl(cli, fnum, code, &blob);
5917
5918                         if (NT_STATUS_IS_OK(status)) {
5919                                 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5920                                        (int)blob.length);
5921                                 data_blob_free(&blob);
5922                         }
5923                 }
5924         }
5925
5926         if (!torture_close_connection(cli)) {
5927                 return False;
5928         }
5929
5930         return True;
5931 }
5932
5933
5934 /*
5935   tries varients of chkpath
5936  */
5937 bool torture_chkpath_test(int dummy)
5938 {
5939         static struct cli_state *cli;
5940         uint16_t fnum;
5941         bool ret;
5942         NTSTATUS status;
5943
5944         if (!torture_open_connection(&cli, 0)) {
5945                 return False;
5946         }
5947
5948         printf("starting chkpath test\n");
5949
5950         /* cleanup from an old run */
5951         cli_rmdir(cli, "\\chkpath.dir\\dir2");
5952         cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5953         cli_rmdir(cli, "\\chkpath.dir");
5954
5955         status = cli_mkdir(cli, "\\chkpath.dir");
5956         if (!NT_STATUS_IS_OK(status)) {
5957                 printf("mkdir1 failed : %s\n", nt_errstr(status));
5958                 return False;
5959         }
5960
5961         status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
5962         if (!NT_STATUS_IS_OK(status)) {
5963                 printf("mkdir2 failed : %s\n", nt_errstr(status));
5964                 return False;
5965         }
5966
5967         status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
5968                           DENY_NONE, &fnum);
5969         if (!NT_STATUS_IS_OK(status)) {
5970                 printf("open1 failed (%s)\n", nt_errstr(status));
5971                 return False;
5972         }
5973         cli_close(cli, fnum);
5974
5975         status = cli_chkpath(cli, "\\chkpath.dir");
5976         if (!NT_STATUS_IS_OK(status)) {
5977                 printf("chkpath1 failed: %s\n", nt_errstr(status));
5978                 ret = False;
5979         }
5980
5981         status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
5982         if (!NT_STATUS_IS_OK(status)) {
5983                 printf("chkpath2 failed: %s\n", nt_errstr(status));
5984                 ret = False;
5985         }
5986
5987         status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
5988         if (!NT_STATUS_IS_OK(status)) {
5989                 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
5990                                   NT_STATUS_NOT_A_DIRECTORY);
5991         } else {
5992                 printf("* chkpath on a file should fail\n");
5993                 ret = False;
5994         }
5995
5996         status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
5997         if (!NT_STATUS_IS_OK(status)) {
5998                 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
5999                                   NT_STATUS_OBJECT_NAME_NOT_FOUND);
6000         } else {
6001                 printf("* chkpath on a non existent file should fail\n");
6002                 ret = False;
6003         }
6004
6005         status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
6006         if (!NT_STATUS_IS_OK(status)) {
6007                 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
6008                                   NT_STATUS_OBJECT_PATH_NOT_FOUND);
6009         } else {
6010                 printf("* chkpath on a non existent component should fail\n");
6011                 ret = False;
6012         }
6013
6014         cli_rmdir(cli, "\\chkpath.dir\\dir2");
6015         cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6016         cli_rmdir(cli, "\\chkpath.dir");
6017
6018         if (!torture_close_connection(cli)) {
6019                 return False;
6020         }
6021
6022         return ret;
6023 }
6024
6025 static bool run_eatest(int dummy)
6026 {
6027         static struct cli_state *cli;
6028         const char *fname = "\\eatest.txt";
6029         bool correct = True;
6030         uint16_t fnum;
6031         int i;
6032         size_t num_eas;
6033         struct ea_struct *ea_list = NULL;
6034         TALLOC_CTX *mem_ctx = talloc_init("eatest");
6035         NTSTATUS status;
6036
6037         printf("starting eatest\n");
6038
6039         if (!torture_open_connection(&cli, 0)) {
6040                 talloc_destroy(mem_ctx);
6041                 return False;
6042         }
6043
6044         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6045
6046         status = cli_ntcreate(cli, fname, 0,
6047                               FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6048                               FILE_SHARE_NONE, FILE_OVERWRITE_IF,
6049                               0x4044, 0, &fnum);
6050         if (!NT_STATUS_IS_OK(status)) {
6051                 printf("open failed - %s\n", nt_errstr(status));
6052                 talloc_destroy(mem_ctx);
6053                 return False;
6054         }
6055
6056         for (i = 0; i < 10; i++) {
6057                 fstring ea_name, ea_val;
6058
6059                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
6060                 memset(ea_val, (char)i+1, i+1);
6061                 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
6062                 if (!NT_STATUS_IS_OK(status)) {
6063                         printf("ea_set of name %s failed - %s\n", ea_name,
6064                                nt_errstr(status));
6065                         talloc_destroy(mem_ctx);
6066                         return False;
6067                 }
6068         }
6069
6070         cli_close(cli, fnum);
6071         for (i = 0; i < 10; i++) {
6072                 fstring ea_name, ea_val;
6073
6074                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
6075                 memset(ea_val, (char)i+1, i+1);
6076                 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
6077                 if (!NT_STATUS_IS_OK(status)) {
6078                         printf("ea_set of name %s failed - %s\n", ea_name,
6079                                nt_errstr(status));
6080                         talloc_destroy(mem_ctx);
6081                         return False;
6082                 }
6083         }
6084
6085         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6086         if (!NT_STATUS_IS_OK(status)) {
6087                 printf("ea_get list failed - %s\n", nt_errstr(status));
6088                 correct = False;
6089         }
6090
6091         printf("num_eas = %d\n", (int)num_eas);
6092
6093         if (num_eas != 20) {
6094                 printf("Should be 20 EA's stored... failing.\n");
6095                 correct = False;
6096         }
6097
6098         for (i = 0; i < num_eas; i++) {
6099                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6100                 dump_data(0, ea_list[i].value.data,
6101                           ea_list[i].value.length);
6102         }
6103
6104         /* Setting EA's to zero length deletes them. Test this */
6105         printf("Now deleting all EA's - case indepenent....\n");
6106
6107 #if 1
6108         cli_set_ea_path(cli, fname, "", "", 0);
6109 #else
6110         for (i = 0; i < 20; i++) {
6111                 fstring ea_name;
6112                 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
6113                 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
6114                 if (!NT_STATUS_IS_OK(status)) {
6115                         printf("ea_set of name %s failed - %s\n", ea_name,
6116                                nt_errstr(status));
6117                         talloc_destroy(mem_ctx);
6118                         return False;
6119                 }
6120         }
6121 #endif
6122
6123         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6124         if (!NT_STATUS_IS_OK(status)) {
6125                 printf("ea_get list failed - %s\n", nt_errstr(status));
6126                 correct = False;
6127         }
6128
6129         printf("num_eas = %d\n", (int)num_eas);
6130         for (i = 0; i < num_eas; i++) {
6131                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6132                 dump_data(0, ea_list[i].value.data,
6133                           ea_list[i].value.length);
6134         }
6135
6136         if (num_eas != 0) {
6137                 printf("deleting EA's failed.\n");
6138                 correct = False;
6139         }
6140
6141         /* Try and delete a non existent EA. */
6142         status = cli_set_ea_path(cli, fname, "foo", "", 0);
6143         if (!NT_STATUS_IS_OK(status)) {
6144                 printf("deleting non-existent EA 'foo' should succeed. %s\n",
6145                        nt_errstr(status));
6146                 correct = False;
6147         }
6148
6149         talloc_destroy(mem_ctx);
6150         if (!torture_close_connection(cli)) {
6151                 correct = False;
6152         }
6153
6154         return correct;
6155 }
6156
6157 static bool run_dirtest1(int dummy)
6158 {
6159         int i;
6160         static struct cli_state *cli;
6161         uint16_t fnum;
6162         int num_seen;
6163         bool correct = True;
6164
6165         printf("starting directory test\n");
6166
6167         if (!torture_open_connection(&cli, 0)) {
6168                 return False;
6169         }
6170
6171         smbXcli_conn_set_sockopt(cli->conn, sockops);
6172
6173         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6174         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6175         cli_rmdir(cli, "\\LISTDIR");
6176         cli_mkdir(cli, "\\LISTDIR");
6177
6178         /* Create 1000 files and 1000 directories. */
6179         for (i=0;i<1000;i++) {
6180                 fstring fname;
6181                 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
6182                 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6183                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6184                         fprintf(stderr,"Failed to open %s\n", fname);
6185                         return False;
6186                 }
6187                 cli_close(cli, fnum);
6188         }
6189         for (i=0;i<1000;i++) {
6190                 fstring fname;
6191                 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
6192                 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
6193                         fprintf(stderr,"Failed to open %s\n", fname);
6194                         return False;
6195                 }
6196         }
6197
6198         /* Now ensure that doing an old list sees both files and directories. */
6199         num_seen = 0;
6200         cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6201         printf("num_seen = %d\n", num_seen );
6202         /* We should see 100 files + 1000 directories + . and .. */
6203         if (num_seen != 2002)
6204                 correct = False;
6205
6206         /* Ensure if we have the "must have" bits we only see the
6207          * relevent entries.
6208          */
6209         num_seen = 0;
6210         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6211         printf("num_seen = %d\n", num_seen );
6212         if (num_seen != 1002)
6213                 correct = False;
6214
6215         num_seen = 0;
6216         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6217         printf("num_seen = %d\n", num_seen );
6218         if (num_seen != 1000)
6219                 correct = False;
6220
6221         /* Delete everything. */
6222         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6223         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6224         cli_rmdir(cli, "\\LISTDIR");
6225
6226 #if 0
6227         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
6228         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
6229         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
6230 #endif
6231
6232         if (!torture_close_connection(cli)) {
6233                 correct = False;
6234         }
6235
6236         printf("finished dirtest1\n");
6237
6238         return correct;
6239 }
6240
6241 static bool run_error_map_extract(int dummy) {
6242
6243         static struct cli_state *c_dos;
6244         static struct cli_state *c_nt;
6245         NTSTATUS status;
6246
6247         uint32 error;
6248
6249         uint32 errnum;
6250         uint8 errclass;
6251
6252         NTSTATUS nt_status;
6253
6254         fstring user;
6255
6256         /* NT-Error connection */
6257
6258         disable_spnego = true;
6259         if (!(c_nt = open_nbt_connection())) {
6260                 disable_spnego = false;
6261                 return False;
6262         }
6263         disable_spnego = false;
6264
6265         status = smbXcli_negprot(c_nt->conn, c_nt->timeout, PROTOCOL_CORE,
6266                                  PROTOCOL_NT1);
6267
6268         if (!NT_STATUS_IS_OK(status)) {
6269                 printf("%s rejected the NT-error negprot (%s)\n", host,
6270                        nt_errstr(status));
6271                 cli_shutdown(c_nt);
6272                 return False;
6273         }
6274
6275         status = cli_session_setup(c_nt, "", "", 0, "", 0, workgroup);
6276         if (!NT_STATUS_IS_OK(status)) {
6277                 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
6278                 return False;
6279         }
6280
6281         /* DOS-Error connection */
6282
6283         disable_spnego = true;
6284         force_dos_errors = true;
6285         if (!(c_dos = open_nbt_connection())) {
6286                 disable_spnego = false;
6287                 force_dos_errors = false;
6288                 return False;
6289         }
6290         disable_spnego = false;
6291         force_dos_errors = false;
6292
6293         status = smbXcli_negprot(c_dos->conn, c_dos->timeout, PROTOCOL_CORE,
6294                                  PROTOCOL_NT1);
6295         if (!NT_STATUS_IS_OK(status)) {
6296                 printf("%s rejected the DOS-error negprot (%s)\n", host,
6297                        nt_errstr(status));
6298                 cli_shutdown(c_dos);
6299                 return False;
6300         }
6301
6302         status = cli_session_setup(c_dos, "", "", 0, "", 0, workgroup);
6303         if (!NT_STATUS_IS_OK(status)) {
6304                 printf("%s rejected the DOS-error initial session setup (%s)\n",
6305                         host, nt_errstr(status));
6306                 return False;
6307         }
6308
6309         c_nt->map_dos_errors = false;
6310         c_dos->map_dos_errors = false;
6311
6312         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
6313                 fstr_sprintf(user, "%X", error);
6314
6315                 status = cli_session_setup(c_nt, user,
6316                                            password, strlen(password),
6317                                            password, strlen(password),
6318                                            workgroup);
6319                 if (NT_STATUS_IS_OK(status)) {
6320                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
6321                 }
6322
6323                 /* Case #1: 32-bit NT errors */
6324                 if (!NT_STATUS_IS_DOS(status)) {
6325                         nt_status = status;
6326                 } else {
6327                         printf("/** Dos error on NT connection! (%s) */\n", 
6328                                nt_errstr(status));
6329                         nt_status = NT_STATUS(0xc0000000);
6330                 }
6331
6332                 status = cli_session_setup(c_dos, user,
6333                                            password, strlen(password),
6334                                            password, strlen(password),
6335                                            workgroup);
6336                 if (NT_STATUS_IS_OK(status)) {
6337                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
6338                 }
6339
6340                 /* Case #1: 32-bit NT errors */
6341                 if (NT_STATUS_IS_DOS(status)) {
6342                         printf("/** NT error on DOS connection! (%s) */\n", 
6343                                nt_errstr(status));
6344                         errnum = errclass = 0;
6345                 } else {
6346                         errclass = NT_STATUS_DOS_CLASS(status);
6347                         errnum = NT_STATUS_DOS_CODE(status);
6348                 }
6349
6350                 if (NT_STATUS_V(nt_status) != error) { 
6351                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
6352                                get_nt_error_c_code(talloc_tos(), NT_STATUS(error)), 
6353                                get_nt_error_c_code(talloc_tos(), nt_status));
6354                 }
6355
6356                 printf("\t{%s,\t%s,\t%s},\n", 
6357                        smb_dos_err_class(errclass), 
6358                        smb_dos_err_name(errclass, errnum), 
6359                        get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
6360         }
6361         return True;
6362 }
6363
6364 static bool run_sesssetup_bench(int dummy)
6365 {
6366         static struct cli_state *c;
6367         const char *fname = "\\file.dat";
6368         uint16_t fnum;
6369         NTSTATUS status;
6370         int i;
6371
6372         if (!torture_open_connection(&c, 0)) {
6373                 return false;
6374         }
6375
6376         status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6377                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6378                               FILE_DELETE_ON_CLOSE, 0, &fnum);
6379         if (!NT_STATUS_IS_OK(status)) {
6380                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6381                 return false;
6382         }
6383
6384         for (i=0; i<torture_numops; i++) {
6385                 status = cli_session_setup(
6386                         c, username,
6387                         password, strlen(password),
6388                         password, strlen(password),
6389                         workgroup);
6390                 if (!NT_STATUS_IS_OK(status)) {
6391                         d_printf("(%s) cli_session_setup failed: %s\n",
6392                                  __location__, nt_errstr(status));
6393                         return false;
6394                 }
6395
6396                 d_printf("\r%d   ", (int)cli_state_get_uid(c));
6397
6398                 status = cli_ulogoff(c);
6399                 if (!NT_STATUS_IS_OK(status)) {
6400                         d_printf("(%s) cli_ulogoff failed: %s\n",
6401                                  __location__, nt_errstr(status));
6402                         return false;
6403                 }
6404         }
6405
6406         return true;
6407 }
6408
6409 static bool subst_test(const char *str, const char *user, const char *domain,
6410                        uid_t uid, gid_t gid, const char *expected)
6411 {
6412         char *subst;
6413         bool result = true;
6414
6415         subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
6416
6417         if (strcmp(subst, expected) != 0) {
6418                 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6419                        "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
6420                        expected);
6421                 result = false;
6422         }
6423
6424         TALLOC_FREE(subst);
6425         return result;
6426 }
6427
6428 static void chain1_open_completion(struct tevent_req *req)
6429 {
6430         uint16_t fnum;
6431         NTSTATUS status;
6432         status = cli_openx_recv(req, &fnum);
6433         TALLOC_FREE(req);
6434
6435         d_printf("cli_openx_recv returned %s: %d\n",
6436                  nt_errstr(status),
6437                  NT_STATUS_IS_OK(status) ? fnum : -1);
6438 }
6439
6440 static void chain1_write_completion(struct tevent_req *req)
6441 {
6442         size_t written;
6443         NTSTATUS status;
6444         status = cli_write_andx_recv(req, &written);
6445         TALLOC_FREE(req);
6446
6447         d_printf("cli_write_andx_recv returned %s: %d\n",
6448                  nt_errstr(status),
6449                  NT_STATUS_IS_OK(status) ? (int)written : -1);
6450 }
6451
6452 static void chain1_close_completion(struct tevent_req *req)
6453 {
6454         NTSTATUS status;
6455         bool *done = (bool *)tevent_req_callback_data_void(req);
6456
6457         status = cli_close_recv(req);
6458         *done = true;
6459
6460         TALLOC_FREE(req);
6461
6462         d_printf("cli_close returned %s\n", nt_errstr(status));
6463 }
6464
6465 static bool run_chain1(int dummy)
6466 {
6467         struct cli_state *cli1;
6468         struct event_context *evt = event_context_init(NULL);
6469         struct tevent_req *reqs[3], *smbreqs[3];
6470         bool done = false;
6471         const char *str = "foobar";
6472         NTSTATUS status;
6473
6474         printf("starting chain1 test\n");
6475         if (!torture_open_connection(&cli1, 0)) {
6476                 return False;
6477         }
6478
6479         smbXcli_conn_set_sockopt(cli1->conn, sockops);
6480
6481         reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, "\\test",
6482                                   O_CREAT|O_RDWR, 0, &smbreqs[0]);
6483         if (reqs[0] == NULL) return false;
6484         tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6485
6486
6487         reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6488                                         (const uint8_t *)str, 0, strlen(str)+1,
6489                                         smbreqs, 1, &smbreqs[1]);
6490         if (reqs[1] == NULL) return false;
6491         tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6492
6493         reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6494         if (reqs[2] == NULL) return false;
6495         tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6496
6497         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
6498         if (!NT_STATUS_IS_OK(status)) {
6499                 return false;
6500         }
6501
6502         while (!done) {
6503                 tevent_loop_once(evt);
6504         }
6505
6506         torture_close_connection(cli1);
6507         return True;
6508 }
6509
6510 static void chain2_sesssetup_completion(struct tevent_req *req)
6511 {
6512         NTSTATUS status;
6513         status = cli_session_setup_guest_recv(req);
6514         d_printf("sesssetup returned %s\n", nt_errstr(status));
6515 }
6516
6517 static void chain2_tcon_completion(struct tevent_req *req)
6518 {
6519         bool *done = (bool *)tevent_req_callback_data_void(req);
6520         NTSTATUS status;
6521         status = cli_tcon_andx_recv(req);
6522         d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6523         *done = true;
6524 }
6525
6526 static bool run_chain2(int dummy)
6527 {
6528         struct cli_state *cli1;
6529         struct event_context *evt = event_context_init(NULL);
6530         struct tevent_req *reqs[2], *smbreqs[2];
6531         bool done = false;
6532         NTSTATUS status;
6533
6534         printf("starting chain2 test\n");
6535         status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
6536                                       port_to_use, SMB_SIGNING_DEFAULT, 0);
6537         if (!NT_STATUS_IS_OK(status)) {
6538                 return False;
6539         }
6540
6541         smbXcli_conn_set_sockopt(cli1->conn, sockops);
6542
6543         reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6544                                                  &smbreqs[0]);
6545         if (reqs[0] == NULL) return false;
6546         tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6547
6548         reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6549                                        "?????", NULL, 0, &smbreqs[1]);
6550         if (reqs[1] == NULL) return false;
6551         tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6552
6553         status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
6554         if (!NT_STATUS_IS_OK(status)) {
6555                 return false;
6556         }
6557
6558         while (!done) {
6559                 tevent_loop_once(evt);
6560         }
6561
6562         torture_close_connection(cli1);
6563         return True;
6564 }
6565
6566
6567 struct torture_createdel_state {
6568         struct tevent_context *ev;
6569         struct cli_state *cli;
6570 };
6571
6572 static void torture_createdel_created(struct tevent_req *subreq);
6573 static void torture_createdel_closed(struct tevent_req *subreq);
6574
6575 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6576                                                  struct tevent_context *ev,
6577                                                  struct cli_state *cli,
6578                                                  const char *name)
6579 {
6580         struct tevent_req *req, *subreq;
6581         struct torture_createdel_state *state;
6582
6583         req = tevent_req_create(mem_ctx, &state,
6584                                 struct torture_createdel_state);
6585         if (req == NULL) {
6586                 return NULL;
6587         }
6588         state->ev = ev;
6589         state->cli = cli;
6590
6591         subreq = cli_ntcreate_send(
6592                 state, ev, cli, name, 0,
6593                 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6594                 FILE_ATTRIBUTE_NORMAL,
6595                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6596                 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6597
6598         if (tevent_req_nomem(subreq, req)) {
6599                 return tevent_req_post(req, ev);
6600         }
6601         tevent_req_set_callback(subreq, torture_createdel_created, req);
6602         return req;
6603 }
6604
6605 static void torture_createdel_created(struct tevent_req *subreq)
6606 {
6607         struct tevent_req *req = tevent_req_callback_data(
6608                 subreq, struct tevent_req);
6609         struct torture_createdel_state *state = tevent_req_data(
6610                 req, struct torture_createdel_state);
6611         NTSTATUS status;
6612         uint16_t fnum;
6613
6614         status = cli_ntcreate_recv(subreq, &fnum);
6615         TALLOC_FREE(subreq);
6616         if (!NT_STATUS_IS_OK(status)) {
6617                 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6618                            nt_errstr(status)));
6619                 tevent_req_nterror(req, status);
6620                 return;
6621         }
6622
6623         subreq = cli_close_send(state, state->ev, state->cli, fnum);
6624         if (tevent_req_nomem(subreq, req)) {
6625                 return;
6626         }
6627         tevent_req_set_callback(subreq, torture_createdel_closed, req);
6628 }
6629
6630 static void torture_createdel_closed(struct tevent_req *subreq)
6631 {
6632         struct tevent_req *req = tevent_req_callback_data(
6633                 subreq, struct tevent_req);
6634         NTSTATUS status;
6635
6636         status = cli_close_recv(subreq);
6637         if (!NT_STATUS_IS_OK(status)) {
6638                 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6639                 tevent_req_nterror(req, status);
6640                 return;
6641         }
6642         tevent_req_done(req);
6643 }
6644
6645 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6646 {
6647         return tevent_req_simple_recv_ntstatus(req);
6648 }
6649
6650 struct torture_createdels_state {
6651         struct tevent_context *ev;
6652         struct cli_state *cli;
6653         const char *base_name;
6654         int sent;
6655         int received;
6656         int num_files;
6657         struct tevent_req **reqs;
6658 };
6659
6660 static void torture_createdels_done(struct tevent_req *subreq);
6661
6662 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6663                                                   struct tevent_context *ev,
6664                                                   struct cli_state *cli,
6665                                                   const char *base_name,
6666                                                   int num_parallel,
6667                                                   int num_files)
6668 {
6669         struct tevent_req *req;
6670         struct torture_createdels_state *state;
6671         int i;
6672
6673         req = tevent_req_create(mem_ctx, &state,
6674                                 struct torture_createdels_state);
6675         if (req == NULL) {
6676                 return NULL;
6677         }
6678         state->ev = ev;
6679         state->cli = cli;
6680         state->base_name = talloc_strdup(state, base_name);
6681         if (tevent_req_nomem(state->base_name, req)) {
6682                 return tevent_req_post(req, ev);
6683         }
6684         state->num_files = MAX(num_parallel, num_files);
6685         state->sent = 0;
6686         state->received = 0;
6687
6688         state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6689         if (tevent_req_nomem(state->reqs, req)) {
6690                 return tevent_req_post(req, ev);
6691         }
6692
6693         for (i=0; i<num_parallel; i++) {
6694                 char *name;
6695
6696                 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6697                                        state->sent);
6698                 if (tevent_req_nomem(name, req)) {
6699                         return tevent_req_post(req, ev);
6700                 }
6701                 state->reqs[i] = torture_createdel_send(
6702                         state->reqs, state->ev, state->cli, name);
6703                 if (tevent_req_nomem(state->reqs[i], req)) {
6704                         return tevent_req_post(req, ev);
6705                 }
6706                 name = talloc_move(state->reqs[i], &name);
6707                 tevent_req_set_callback(state->reqs[i],
6708                                         torture_createdels_done, req);
6709                 state->sent += 1;
6710         }
6711         return req;
6712 }
6713
6714 static void torture_createdels_done(struct tevent_req *subreq)
6715 {
6716         struct tevent_req *req = tevent_req_callback_data(
6717                 subreq, struct tevent_req);
6718         struct torture_createdels_state *state = tevent_req_data(
6719                 req, struct torture_createdels_state);
6720         size_t num_parallel = talloc_array_length(state->reqs);
6721         NTSTATUS status;
6722         char *name;
6723         int i;
6724
6725         status = torture_createdel_recv(subreq);
6726         if (!NT_STATUS_IS_OK(status)){
6727                 DEBUG(10, ("torture_createdel_recv returned %s\n",
6728                            nt_errstr(status)));
6729                 TALLOC_FREE(subreq);
6730                 tevent_req_nterror(req, status);
6731                 return;
6732         }
6733
6734         for (i=0; i<num_parallel; i++) {
6735                 if (subreq == state->reqs[i]) {
6736                         break;
6737                 }
6738         }
6739         if (i == num_parallel) {
6740                 DEBUG(10, ("received something we did not send\n"));
6741                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6742                 return;
6743         }
6744         TALLOC_FREE(state->reqs[i]);
6745
6746         if (state->sent >= state->num_files) {
6747                 tevent_req_done(req);
6748                 return;
6749         }
6750
6751         name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6752                                state->sent);
6753         if (tevent_req_nomem(name, req)) {
6754                 return;
6755         }
6756         state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6757                                                 state->cli, name);
6758         if (tevent_req_nomem(state->reqs[i], req)) {
6759                 return;
6760         }
6761         name = talloc_move(state->reqs[i], &name);
6762         tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6763         state->sent += 1;
6764 }
6765
6766 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6767 {
6768         return tevent_req_simple_recv_ntstatus(req);
6769 }
6770
6771 struct swallow_notify_state {
6772         struct tevent_context *ev;
6773         struct cli_state *cli;
6774         uint16_t fnum;
6775         uint32_t completion_filter;
6776         bool recursive;
6777         bool (*fn)(uint32_t action, const char *name, void *priv);
6778         void *priv;
6779 };
6780
6781 static void swallow_notify_done(struct tevent_req *subreq);
6782
6783 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6784                                               struct tevent_context *ev,
6785                                               struct cli_state *cli,
6786                                               uint16_t fnum,
6787                                               uint32_t completion_filter,
6788                                               bool recursive,
6789                                               bool (*fn)(uint32_t action,
6790                                                          const char *name,
6791                                                          void *priv),
6792                                               void *priv)
6793 {
6794         struct tevent_req *req, *subreq;
6795         struct swallow_notify_state *state;
6796
6797         req = tevent_req_create(mem_ctx, &state,
6798                                 struct swallow_notify_state);
6799         if (req == NULL) {
6800                 return NULL;
6801         }
6802         state->ev = ev;
6803         state->cli = cli;
6804         state->fnum = fnum;
6805         state->completion_filter = completion_filter;
6806         state->recursive = recursive;
6807         state->fn = fn;
6808         state->priv = priv;
6809
6810         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6811                                  0xffff, state->completion_filter,
6812                                  state->recursive);
6813         if (tevent_req_nomem(subreq, req)) {
6814                 return tevent_req_post(req, ev);
6815         }
6816         tevent_req_set_callback(subreq, swallow_notify_done, req);
6817         return req;
6818 }
6819
6820 static void swallow_notify_done(struct tevent_req *subreq)
6821 {
6822         struct tevent_req *req = tevent_req_callback_data(
6823                 subreq, struct tevent_req);
6824         struct swallow_notify_state *state = tevent_req_data(
6825                 req, struct swallow_notify_state);
6826         NTSTATUS status;
6827         uint32_t i, num_changes;
6828         struct notify_change *changes;
6829
6830         status = cli_notify_recv(subreq, state, &num_changes, &changes);
6831         TALLOC_FREE(subreq);
6832         if (!NT_STATUS_IS_OK(status)) {
6833                 DEBUG(10, ("cli_notify_recv returned %s\n",
6834                            nt_errstr(status)));
6835                 tevent_req_nterror(req, status);
6836                 return;
6837         }
6838
6839         for (i=0; i<num_changes; i++) {
6840                 state->fn(changes[i].action, changes[i].name, state->priv);
6841         }
6842         TALLOC_FREE(changes);
6843
6844         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6845                                  0xffff, state->completion_filter,
6846                                  state->recursive);
6847         if (tevent_req_nomem(subreq, req)) {
6848                 return;
6849         }
6850         tevent_req_set_callback(subreq, swallow_notify_done, req);
6851 }
6852
6853 static bool print_notifies(uint32_t action, const char *name, void *priv)
6854 {
6855         if (DEBUGLEVEL > 5) {
6856                 d_printf("%d %s\n", (int)action, name);
6857         }
6858         return true;
6859 }
6860
6861 static void notify_bench_done(struct tevent_req *req)
6862 {
6863         int *num_finished = (int *)tevent_req_callback_data_void(req);
6864         *num_finished += 1;
6865 }
6866
6867 static bool run_notify_bench(int dummy)
6868 {
6869         const char *dname = "\\notify-bench";
6870         struct tevent_context *ev;
6871         NTSTATUS status;
6872         uint16_t dnum;
6873         struct tevent_req *req1;
6874         struct tevent_req *req2 = NULL;
6875         int i, num_unc_names;
6876         int num_finished = 0;
6877
6878         printf("starting notify-bench test\n");
6879
6880         if (use_multishare_conn) {
6881                 char **unc_list;
6882                 unc_list = file_lines_load(multishare_conn_fname,
6883                                            &num_unc_names, 0, NULL);
6884                 if (!unc_list || num_unc_names <= 0) {
6885                         d_printf("Failed to load unc names list from '%s'\n",
6886                                  multishare_conn_fname);
6887                         return false;
6888                 }
6889                 TALLOC_FREE(unc_list);
6890         } else {
6891                 num_unc_names = 1;
6892         }
6893
6894         ev = tevent_context_init(talloc_tos());
6895         if (ev == NULL) {
6896                 d_printf("tevent_context_init failed\n");
6897                 return false;
6898         }
6899
6900         for (i=0; i<num_unc_names; i++) {
6901                 struct cli_state *cli;
6902                 char *base_fname;
6903
6904                 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6905                                              dname, i);
6906                 if (base_fname == NULL) {
6907                         return false;
6908                 }
6909
6910                 if (!torture_open_connection(&cli, i)) {
6911                         return false;
6912                 }
6913
6914                 status = cli_ntcreate(cli, dname, 0,
6915                                       MAXIMUM_ALLOWED_ACCESS,
6916                                       0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6917                                       FILE_SHARE_DELETE,
6918                                       FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6919                                       &dnum);
6920
6921                 if (!NT_STATUS_IS_OK(status)) {
6922                         d_printf("Could not create %s: %s\n", dname,
6923                                  nt_errstr(status));
6924                         return false;
6925                 }
6926
6927                 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6928                                            FILE_NOTIFY_CHANGE_FILE_NAME |
6929                                            FILE_NOTIFY_CHANGE_DIR_NAME |
6930                                            FILE_NOTIFY_CHANGE_ATTRIBUTES |
6931                                            FILE_NOTIFY_CHANGE_LAST_WRITE,
6932                                            false, print_notifies, NULL);
6933                 if (req1 == NULL) {
6934                         d_printf("Could not create notify request\n");
6935                         return false;
6936                 }
6937
6938                 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6939                                                base_fname, 10, torture_numops);
6940                 if (req2 == NULL) {
6941                         d_printf("Could not create createdels request\n");
6942                         return false;
6943                 }
6944                 TALLOC_FREE(base_fname);
6945
6946                 tevent_req_set_callback(req2, notify_bench_done,
6947                                         &num_finished);
6948         }
6949
6950         while (num_finished < num_unc_names) {
6951                 int ret;
6952                 ret = tevent_loop_once(ev);
6953                 if (ret != 0) {
6954                         d_printf("tevent_loop_once failed\n");
6955                         return false;
6956                 }
6957         }
6958
6959         if (!tevent_req_poll(req2, ev)) {
6960                 d_printf("tevent_req_poll failed\n");
6961         }
6962
6963         status = torture_createdels_recv(req2);
6964         d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6965
6966         return true;
6967 }
6968
6969 static bool run_mangle1(int dummy)
6970 {
6971         struct cli_state *cli;
6972         const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6973         uint16_t fnum;
6974         fstring alt_name;
6975         NTSTATUS status;
6976         time_t change_time, access_time, write_time;
6977         off_t size;
6978         uint16_t mode;
6979
6980         printf("starting mangle1 test\n");
6981         if (!torture_open_connection(&cli, 0)) {
6982                 return False;
6983         }
6984
6985         smbXcli_conn_set_sockopt(cli->conn, sockops);
6986
6987         status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6988                               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6989                               0, 0, &fnum);
6990         if (!NT_STATUS_IS_OK(status)) {
6991                 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6992                 return false;
6993         }
6994         cli_close(cli, fnum);
6995
6996         status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6997         if (!NT_STATUS_IS_OK(status)) {
6998                 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6999                          nt_errstr(status));
7000                 return false;
7001         }
7002         d_printf("alt_name: %s\n", alt_name);
7003
7004         status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
7005         if (!NT_STATUS_IS_OK(status)) {
7006                 d_printf("cli_openx(%s) failed: %s\n", alt_name,
7007                          nt_errstr(status));
7008                 return false;
7009         }
7010         cli_close(cli, fnum);
7011
7012         status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
7013                                 &write_time, &size, &mode);
7014         if (!NT_STATUS_IS_OK(status)) {
7015                 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
7016                          nt_errstr(status));
7017                 return false;
7018         }
7019
7020         return true;
7021 }
7022
7023 static size_t null_source(uint8_t *buf, size_t n, void *priv)
7024 {
7025         size_t *to_pull = (size_t *)priv;
7026         size_t thistime = *to_pull;
7027
7028         thistime = MIN(thistime, n);
7029         if (thistime == 0) {
7030                 return 0;
7031         }
7032
7033         memset(buf, 0, thistime);
7034         *to_pull -= thistime;
7035         return thistime;
7036 }
7037
7038 static bool run_windows_write(int dummy)
7039 {
7040         struct cli_state *cli1;
7041         uint16_t fnum;
7042         int i;
7043         bool ret = false;
7044         const char *fname = "\\writetest.txt";
7045         struct timeval start_time;
7046         double seconds;
7047         double kbytes;
7048         NTSTATUS status;
7049
7050         printf("starting windows_write test\n");
7051         if (!torture_open_connection(&cli1, 0)) {
7052                 return False;
7053         }
7054
7055         status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7056         if (!NT_STATUS_IS_OK(status)) {
7057                 printf("open failed (%s)\n", nt_errstr(status));
7058                 return False;
7059         }
7060
7061         smbXcli_conn_set_sockopt(cli1->conn, sockops);
7062
7063         start_time = timeval_current();
7064
7065         for (i=0; i<torture_numops; i++) {
7066                 uint8_t c = 0;
7067                 off_t start = i * torture_blocksize;
7068                 size_t to_pull = torture_blocksize - 1;
7069
7070                 status = cli_writeall(cli1, fnum, 0, &c,
7071                                       start + torture_blocksize - 1, 1, NULL);
7072                 if (!NT_STATUS_IS_OK(status)) {
7073                         printf("cli_write failed: %s\n", nt_errstr(status));
7074                         goto fail;
7075                 }
7076
7077                 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
7078                                   null_source, &to_pull);
7079                 if (!NT_STATUS_IS_OK(status)) {
7080                         printf("cli_push returned: %s\n", nt_errstr(status));
7081                         goto fail;
7082                 }
7083         }
7084
7085         seconds = timeval_elapsed(&start_time);
7086         kbytes = (double)torture_blocksize * torture_numops;
7087         kbytes /= 1024;
7088
7089         printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
7090                (double)seconds, (int)(kbytes/seconds));
7091
7092         ret = true;
7093  fail:
7094         cli_close(cli1, fnum);
7095         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7096         torture_close_connection(cli1);
7097         return ret;
7098 }
7099
7100 static bool run_cli_echo(int dummy)
7101 {
7102         struct cli_state *cli;
7103         NTSTATUS status;
7104
7105         printf("starting cli_echo test\n");
7106         if (!torture_open_connection(&cli, 0)) {
7107                 return false;
7108         }
7109         smbXcli_conn_set_sockopt(cli->conn, sockops);
7110
7111         status = cli_echo(cli, 5, data_blob_const("hello", 5));
7112
7113         d_printf("cli_echo returned %s\n", nt_errstr(status));
7114
7115         torture_close_connection(cli);
7116         return NT_STATUS_IS_OK(status);
7117 }
7118
7119 static bool run_uid_regression_test(int dummy)
7120 {
7121         static struct cli_state *cli;
7122         int16_t old_vuid;
7123         int16_t old_cnum;
7124         bool correct = True;
7125         NTSTATUS status;
7126
7127         printf("starting uid regression test\n");
7128
7129         if (!torture_open_connection(&cli, 0)) {
7130                 return False;
7131         }
7132
7133         smbXcli_conn_set_sockopt(cli->conn, sockops);
7134
7135         /* Ok - now save then logoff our current user. */
7136         old_vuid = cli_state_get_uid(cli);
7137
7138         status = cli_ulogoff(cli);
7139         if (!NT_STATUS_IS_OK(status)) {
7140                 d_printf("(%s) cli_ulogoff failed: %s\n",
7141                          __location__, nt_errstr(status));
7142                 correct = false;
7143                 goto out;
7144         }
7145
7146         cli_state_set_uid(cli, old_vuid);
7147
7148         /* Try an operation. */
7149         status = cli_mkdir(cli, "\\uid_reg_test");
7150         if (NT_STATUS_IS_OK(status)) {
7151                 d_printf("(%s) cli_mkdir succeeded\n",
7152                          __location__);
7153                 correct = false;
7154                 goto out;
7155         } else {
7156                 /* Should be bad uid. */
7157                 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
7158                                  NT_STATUS_USER_SESSION_DELETED)) {
7159                         correct = false;
7160                         goto out;
7161                 }
7162         }
7163
7164         old_cnum = cli_state_get_tid(cli);
7165
7166         /* Now try a SMBtdis with the invald vuid set to zero. */
7167         cli_state_set_uid(cli, 0);
7168
7169         /* This should succeed. */
7170         status = cli_tdis(cli);
7171
7172         if (NT_STATUS_IS_OK(status)) {
7173                 d_printf("First tdis with invalid vuid should succeed.\n");
7174         } else {
7175                 d_printf("First tdis failed (%s)\n", nt_errstr(status));
7176                 correct = false;
7177                 goto out;
7178         }
7179
7180         cli_state_set_uid(cli, old_vuid);
7181         cli_state_set_tid(cli, old_cnum);
7182
7183         /* This should fail. */
7184         status = cli_tdis(cli);
7185         if (NT_STATUS_IS_OK(status)) {
7186                 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7187                 correct = false;
7188                 goto out;
7189         } else {
7190                 /* Should be bad tid. */
7191                 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
7192                                 NT_STATUS_NETWORK_NAME_DELETED)) {
7193                         correct = false;
7194                         goto out;
7195                 }
7196         }
7197
7198         cli_rmdir(cli, "\\uid_reg_test");
7199
7200   out:
7201
7202         cli_shutdown(cli);
7203         return correct;
7204 }
7205
7206
7207 static const char *illegal_chars = "*\\/?<>|\":";
7208 static char force_shortname_chars[] = " +,.[];=\177";
7209
7210 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
7211                              const char *mask, void *state)
7212 {
7213         struct cli_state *pcli = (struct cli_state *)state;
7214         fstring fname;
7215         NTSTATUS status = NT_STATUS_OK;
7216
7217         slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
7218
7219         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7220                 return NT_STATUS_OK;
7221
7222         if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7223                 status = cli_rmdir(pcli, fname);
7224                 if (!NT_STATUS_IS_OK(status)) {
7225                         printf("del_fn: failed to rmdir %s\n,", fname );
7226                 }
7227         } else {
7228                 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7229                 if (!NT_STATUS_IS_OK(status)) {
7230                         printf("del_fn: failed to unlink %s\n,", fname );
7231                 }
7232         }
7233         return status;
7234 }
7235
7236 struct sn_state {
7237         int matched;
7238         int i;
7239         bool val;
7240 };
7241
7242 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
7243                               const char *name, void *state)
7244 {
7245         struct sn_state *s = (struct sn_state  *)state;
7246         int i = s->i;
7247
7248 #if 0
7249         printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7250                 i, finfo->name, finfo->short_name);
7251 #endif
7252
7253         if (strchr(force_shortname_chars, i)) {
7254                 if (!finfo->short_name) {
7255                         /* Shortname not created when it should be. */
7256                         d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7257                                 __location__, finfo->name, i);
7258                         s->val = true;
7259                 }
7260         } else if (finfo->short_name){
7261                 /* Shortname created when it should not be. */
7262                 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7263                         __location__, finfo->short_name, finfo->name);
7264                 s->val = true;
7265         }
7266         s->matched += 1;
7267         return NT_STATUS_OK;
7268 }
7269
7270 static bool run_shortname_test(int dummy)
7271 {
7272         static struct cli_state *cli;
7273         bool correct = True;
7274         int i;
7275         struct sn_state s;
7276         char fname[40];
7277         NTSTATUS status;
7278
7279         printf("starting shortname test\n");
7280
7281         if (!torture_open_connection(&cli, 0)) {
7282                 return False;
7283         }
7284
7285         smbXcli_conn_set_sockopt(cli->conn, sockops);
7286
7287         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7288         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7289         cli_rmdir(cli, "\\shortname");
7290
7291         status = cli_mkdir(cli, "\\shortname");
7292         if (!NT_STATUS_IS_OK(status)) {
7293                 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7294                         __location__, nt_errstr(status));
7295                 correct = false;
7296                 goto out;
7297         }
7298
7299         if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
7300                 correct = false;
7301                 goto out;
7302         }
7303         if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
7304                 correct = false;
7305                 goto out;
7306         }
7307
7308         s.val = false;
7309
7310         for (i = 32; i < 128; i++) {
7311                 uint16_t fnum = (uint16_t)-1;
7312
7313                 s.i = i;
7314
7315                 if (strchr(illegal_chars, i)) {
7316                         continue;
7317                 }
7318                 fname[15] = i;
7319
7320                 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
7321                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
7322                 if (!NT_STATUS_IS_OK(status)) {
7323                         d_printf("(%s) cli_nt_create of %s failed: %s\n",
7324                                 __location__, fname, nt_errstr(status));
7325                         correct = false;
7326                         goto out;
7327                 }
7328                 cli_close(cli, fnum);
7329
7330                 s.matched = 0;
7331                 status = cli_list(cli, "\\shortname\\test*.*", 0,
7332                                   shortname_list_fn, &s);
7333                 if (s.matched != 1) {
7334                         d_printf("(%s) failed to list %s: %s\n",
7335                                 __location__, fname, nt_errstr(status));
7336                         correct = false;
7337                         goto out;
7338                 }
7339
7340                 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7341                 if (!NT_STATUS_IS_OK(status)) {
7342                         d_printf("(%s) failed to delete %s: %s\n",
7343                                 __location__, fname, nt_errstr(status));
7344                         correct = false;
7345                         goto out;
7346                 }
7347
7348                 if (s.val) {
7349                         correct = false;
7350                         goto out;
7351                 }
7352         }
7353
7354   out:
7355
7356         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7357         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7358         cli_rmdir(cli, "\\shortname");
7359         torture_close_connection(cli);
7360         return correct;
7361 }
7362
7363 static void pagedsearch_cb(struct tevent_req *req)
7364 {
7365         int rc;
7366         struct tldap_message *msg;
7367         char *dn;
7368
7369         rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
7370         if (rc != TLDAP_SUCCESS) {
7371                 d_printf("tldap_search_paged_recv failed: %s\n",
7372                          tldap_err2string(rc));
7373                 return;
7374         }
7375         if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
7376                 TALLOC_FREE(msg);
7377                 return;
7378         }
7379         if (!tldap_entry_dn(msg, &dn)) {
7380                 d_printf("tldap_entry_dn failed\n");
7381                 return;
7382         }
7383         d_printf("%s\n", dn);
7384         TALLOC_FREE(msg);
7385 }
7386
7387 static bool run_tldap(int dummy)
7388 {
7389         struct tldap_context *ld;
7390         int fd, rc;
7391         NTSTATUS status;
7392         struct sockaddr_storage addr;
7393         struct tevent_context *ev;
7394         struct tevent_req *req;
7395         char *basedn;
7396         const char *filter;
7397
7398         if (!resolve_name(host, &addr, 0, false)) {
7399                 d_printf("could not find host %s\n", host);
7400                 return false;
7401         }
7402         status = open_socket_out(&addr, 389, 9999, &fd);
7403         if (!NT_STATUS_IS_OK(status)) {
7404                 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
7405                 return false;
7406         }
7407
7408         ld = tldap_context_create(talloc_tos(), fd);
7409         if (ld == NULL) {
7410                 close(fd);
7411                 d_printf("tldap_context_create failed\n");
7412                 return false;
7413         }
7414
7415         rc = tldap_fetch_rootdse(ld);
7416         if (rc != TLDAP_SUCCESS) {
7417                 d_printf("tldap_fetch_rootdse failed: %s\n",
7418                          tldap_errstr(talloc_tos(), ld, rc));
7419                 return false;
7420         }
7421
7422         basedn = tldap_talloc_single_attribute(
7423                 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
7424         if (basedn == NULL) {
7425                 d_printf("no defaultNamingContext\n");
7426                 return false;
7427         }
7428         d_printf("defaultNamingContext: %s\n", basedn);
7429
7430         ev = tevent_context_init(talloc_tos());
7431         if (ev == NULL) {
7432                 d_printf("tevent_context_init failed\n");
7433                 return false;
7434         }
7435
7436         req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
7437                                       TLDAP_SCOPE_SUB, "(objectclass=*)",
7438                                       NULL, 0, 0,
7439                                       NULL, 0, NULL, 0, 0, 0, 0, 5);
7440         if (req == NULL) {
7441                 d_printf("tldap_search_paged_send failed\n");
7442                 return false;
7443         }
7444         tevent_req_set_callback(req, pagedsearch_cb, NULL);
7445
7446         tevent_req_poll(req, ev);
7447
7448         TALLOC_FREE(req);
7449
7450         /* test search filters against rootDSE */
7451         filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7452                    "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7453
7454         rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7455                           NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7456                           talloc_tos(), NULL, NULL);
7457         if (rc != TLDAP_SUCCESS) {
7458                 d_printf("tldap_search with complex filter failed: %s\n",
7459                          tldap_errstr(talloc_tos(), ld, rc));
7460                 return false;
7461         }
7462
7463         TALLOC_FREE(ld);
7464         return true;
7465 }
7466
7467 /* Torture test to ensure no regression of :
7468 https://bugzilla.samba.org/show_bug.cgi?id=7084
7469 */
7470
7471 static bool run_dir_createtime(int dummy)
7472 {
7473         struct cli_state *cli;
7474         const char *dname = "\\testdir";
7475         const char *fname = "\\testdir\\testfile";
7476         NTSTATUS status;
7477         struct timespec create_time;
7478         struct timespec create_time1;
7479         uint16_t fnum;
7480         bool ret = false;
7481
7482         if (!torture_open_connection(&cli, 0)) {
7483                 return false;
7484         }
7485
7486         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7487         cli_rmdir(cli, dname);
7488
7489         status = cli_mkdir(cli, dname);
7490         if (!NT_STATUS_IS_OK(status)) {
7491                 printf("mkdir failed: %s\n", nt_errstr(status));
7492                 goto out;
7493         }
7494
7495         status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7496                                 NULL, NULL, NULL);
7497         if (!NT_STATUS_IS_OK(status)) {
7498                 printf("cli_qpathinfo2 returned %s\n",
7499                        nt_errstr(status));
7500                 goto out;
7501         }
7502
7503         /* Sleep 3 seconds, then create a file. */
7504         sleep(3);
7505
7506         status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7507                          DENY_NONE, &fnum);
7508         if (!NT_STATUS_IS_OK(status)) {
7509                 printf("cli_openx failed: %s\n", nt_errstr(status));
7510                 goto out;
7511         }
7512
7513         status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7514                                 NULL, NULL, NULL);
7515         if (!NT_STATUS_IS_OK(status)) {
7516                 printf("cli_qpathinfo2 (2) returned %s\n",
7517                        nt_errstr(status));
7518                 goto out;
7519         }
7520
7521         if (timespec_compare(&create_time1, &create_time)) {
7522                 printf("run_dir_createtime: create time was updated (error)\n");
7523         } else {
7524                 printf("run_dir_createtime: create time was not updated (correct)\n");
7525                 ret = true;
7526         }
7527
7528   out:
7529
7530         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7531         cli_rmdir(cli, dname);
7532         if (!torture_close_connection(cli)) {
7533                 ret = false;
7534         }
7535         return ret;
7536 }
7537
7538
7539 static bool run_streamerror(int dummy)
7540 {
7541         struct cli_state *cli;
7542         const char *dname = "\\testdir";
7543         const char *streamname =
7544                 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7545         NTSTATUS status;
7546         time_t change_time, access_time, write_time;
7547         off_t size;
7548         uint16_t mode, fnum;
7549         bool ret = true;
7550
7551         if (!torture_open_connection(&cli, 0)) {
7552                 return false;
7553         }
7554
7555         cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7556         cli_rmdir(cli, dname);
7557
7558         status = cli_mkdir(cli, dname);
7559         if (!NT_STATUS_IS_OK(status)) {
7560                 printf("mkdir failed: %s\n", nt_errstr(status));
7561                 return false;
7562         }
7563
7564         status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
7565                                 &write_time, &size, &mode);
7566         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7567                 printf("pathinfo returned %s, expected "
7568                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7569                        nt_errstr(status));
7570                 ret = false;
7571         }
7572
7573         status = cli_ntcreate(cli, streamname, 0x16,
7574                               FILE_READ_DATA|FILE_READ_EA|
7575                               FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7576                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7577                               FILE_OPEN, 0, 0, &fnum);
7578
7579         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7580                 printf("ntcreate returned %s, expected "
7581                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7582                        nt_errstr(status));
7583                 ret = false;
7584         }
7585
7586
7587         cli_rmdir(cli, dname);
7588         return ret;
7589 }
7590
7591 static bool run_local_substitute(int dummy)
7592 {
7593         bool ok = true;
7594
7595         ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7596         ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7597         ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7598         ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7599         ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7600         ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7601         ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7602         ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7603
7604         /* Different captialization rules in sub_basic... */
7605
7606         ok &=  (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7607                        "blaDOM") == 0);
7608
7609         return ok;
7610 }
7611
7612 static bool run_local_base64(int dummy)
7613 {
7614         int i;
7615         bool ret = true;
7616
7617         for (i=1; i<2000; i++) {
7618                 DATA_BLOB blob1, blob2;
7619                 char *b64;
7620
7621                 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7622                 blob1.length = i;
7623                 generate_random_buffer(blob1.data, blob1.length);
7624
7625                 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7626                 if (b64 == NULL) {
7627                         d_fprintf(stderr, "base64_encode_data_blob failed "
7628                                   "for %d bytes\n", i);
7629                         ret = false;
7630                 }
7631                 blob2 = base64_decode_data_blob(b64);
7632                 TALLOC_FREE(b64);
7633
7634                 if (data_blob_cmp(&blob1, &blob2)) {
7635                         d_fprintf(stderr, "data_blob_cmp failed for %d "
7636                                   "bytes\n", i);
7637                         ret = false;
7638                 }
7639                 TALLOC_FREE(blob1.data);
7640                 data_blob_free(&blob2);
7641         }
7642         return ret;
7643 }
7644
7645 static bool run_local_gencache(int dummy)
7646 {
7647         char *val;
7648         time_t tm;
7649         DATA_BLOB blob;
7650
7651         if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7652                 d_printf("%s: gencache_set() failed\n", __location__);
7653                 return False;
7654         }
7655
7656         if (!gencache_get("foo", NULL, NULL)) {
7657                 d_printf("%s: gencache_get() failed\n", __location__);
7658                 return False;
7659         }
7660
7661         if (!gencache_get("foo", &val, &tm)) {
7662                 d_printf("%s: gencache_get() failed\n", __location__);
7663                 return False;
7664         }
7665
7666         if (strcmp(val, "bar") != 0) {
7667                 d_printf("%s: gencache_get() returned %s, expected %s\n",
7668                          __location__, val, "bar");
7669                 SAFE_FREE(val);
7670                 return False;
7671         }
7672
7673         SAFE_FREE(val);
7674
7675         if (!gencache_del("foo")) {
7676                 d_printf("%s: gencache_del() failed\n", __location__);
7677                 return False;
7678         }
7679         if (gencache_del("foo")) {
7680                 d_printf("%s: second gencache_del() succeeded\n",
7681                          __location__);
7682                 return False;
7683         }
7684
7685         if (gencache_get("foo", &val, &tm)) {
7686                 d_printf("%s: gencache_get() on deleted entry "
7687                          "succeeded\n", __location__);
7688                 return False;
7689         }
7690
7691         blob = data_blob_string_const_null("bar");
7692         tm = time(NULL) + 60;
7693
7694         if (!gencache_set_data_blob("foo", &blob, tm)) {
7695                 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7696                 return False;
7697         }
7698
7699         if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7700                 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7701                 return False;
7702         }
7703
7704         if (strcmp((const char *)blob.data, "bar") != 0) {
7705                 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7706                          __location__, (const char *)blob.data, "bar");
7707                 data_blob_free(&blob);
7708                 return False;
7709         }
7710
7711         data_blob_free(&blob);
7712
7713         if (!gencache_del("foo")) {
7714                 d_printf("%s: gencache_del() failed\n", __location__);
7715                 return False;
7716         }
7717         if (gencache_del("foo")) {
7718                 d_printf("%s: second gencache_del() succeeded\n",
7719                          __location__);
7720                 return False;
7721         }
7722
7723         if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7724                 d_printf("%s: gencache_get_data_blob() on deleted entry "
7725                          "succeeded\n", __location__);
7726                 return False;
7727         }
7728
7729         return True;
7730 }
7731
7732 static bool rbt_testval(struct db_context *db, const char *key,
7733                         const char *value)
7734 {
7735         struct db_record *rec;
7736         TDB_DATA data = string_tdb_data(value);
7737         bool ret = false;
7738         NTSTATUS status;
7739         TDB_DATA dbvalue;
7740
7741         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
7742         if (rec == NULL) {
7743                 d_fprintf(stderr, "fetch_locked failed\n");
7744                 goto done;
7745         }
7746         status = dbwrap_record_store(rec, data, 0);
7747         if (!NT_STATUS_IS_OK(status)) {
7748                 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7749                 goto done;
7750         }
7751         TALLOC_FREE(rec);
7752
7753         rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
7754         if (rec == NULL) {
7755                 d_fprintf(stderr, "second fetch_locked failed\n");
7756                 goto done;
7757         }
7758
7759         dbvalue = dbwrap_record_get_value(rec);
7760         if ((dbvalue.dsize != data.dsize)
7761             || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
7762                 d_fprintf(stderr, "Got wrong data back\n");
7763                 goto done;
7764         }
7765
7766         ret = true;
7767  done:
7768         TALLOC_FREE(rec);
7769         return ret;
7770 }
7771
7772 static bool run_local_rbtree(int dummy)
7773 {
7774         struct db_context *db;
7775         bool ret = false;
7776         int i;
7777
7778         db = db_open_rbt(NULL);
7779
7780         if (db == NULL) {
7781                 d_fprintf(stderr, "db_open_rbt failed\n");
7782                 return false;
7783         }
7784
7785         for (i=0; i<1000; i++) {
7786                 char *key, *value;
7787
7788                 if (asprintf(&key, "key%ld", random()) == -1) {
7789                         goto done;
7790                 }
7791                 if (asprintf(&value, "value%ld", random()) == -1) {
7792                         SAFE_FREE(key);
7793                         goto done;
7794                 }
7795
7796                 if (!rbt_testval(db, key, value)) {
7797                         SAFE_FREE(key);
7798                         SAFE_FREE(value);
7799                         goto done;
7800                 }
7801
7802                 SAFE_FREE(value);
7803                 if (asprintf(&value, "value%ld", random()) == -1) {
7804                         SAFE_FREE(key);
7805                         goto done;
7806                 }
7807
7808                 if (!rbt_testval(db, key, value)) {
7809                         SAFE_FREE(key);
7810                         SAFE_FREE(value);
7811                         goto done;
7812                 }
7813
7814                 SAFE_FREE(key);
7815                 SAFE_FREE(value);
7816         }
7817
7818         ret = true;
7819
7820  done:
7821         TALLOC_FREE(db);
7822         return ret;
7823 }
7824
7825
7826 /*
7827   local test for character set functions
7828
7829   This is a very simple test for the functionality in convert_string_error()
7830  */
7831 static bool run_local_convert_string(int dummy)
7832 {
7833         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7834         const char *test_strings[2] = { "March", "M\303\244rz" };
7835         char dst[7];
7836         int i;
7837
7838         for (i=0; i<2; i++) {
7839                 const char *str = test_strings[i];
7840                 int len = strlen(str);
7841                 size_t converted_size;
7842                 bool ret;
7843
7844                 memset(dst, 'X', sizeof(dst));
7845
7846                 /* first try with real source length */
7847                 ret = convert_string_error(CH_UNIX, CH_UTF8,
7848                                            str, len,
7849                                            dst, sizeof(dst),
7850                                            &converted_size);
7851                 if (ret != true) {
7852                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7853                         goto failed;
7854                 }
7855
7856                 if (converted_size != len) {
7857                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7858                                   str, len, (int)converted_size);
7859                         goto failed;
7860                 }
7861
7862                 if (strncmp(str, dst, converted_size) != 0) {
7863                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7864                         goto failed;
7865                 }
7866
7867                 if (strlen(str) != converted_size) {
7868                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7869                                   (int)strlen(str), (int)converted_size);
7870                         goto failed;
7871                 }
7872
7873                 if (dst[converted_size] != 'X') {
7874                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7875                         goto failed;
7876                 }
7877
7878                 /* now with srclen==-1, this causes the nul to be
7879                  * converted too */
7880                 ret = convert_string_error(CH_UNIX, CH_UTF8,
7881                                            str, -1,
7882                                            dst, sizeof(dst),
7883                                            &converted_size);
7884                 if (ret != true) {
7885                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7886                         goto failed;
7887                 }
7888
7889                 if (converted_size != len+1) {
7890                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7891                                   str, len, (int)converted_size);
7892                         goto failed;
7893                 }
7894
7895                 if (strncmp(str, dst, converted_size) != 0) {
7896                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7897                         goto failed;
7898                 }
7899
7900                 if (len+1 != converted_size) {
7901                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7902                                   len+1, (int)converted_size);
7903                         goto failed;
7904                 }
7905
7906                 if (dst[converted_size] != 'X') {
7907                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7908                         goto failed;
7909                 }
7910
7911         }
7912
7913
7914         TALLOC_FREE(tmp_ctx);
7915         return true;
7916 failed:
7917         TALLOC_FREE(tmp_ctx);
7918         return false;
7919 }
7920
7921
7922 struct talloc_dict_test {
7923         int content;
7924 };
7925
7926 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7927 {
7928         int *count = (int *)priv;
7929         *count += 1;
7930         return 0;
7931 }
7932
7933 static bool run_local_talloc_dict(int dummy)
7934 {
7935         struct talloc_dict *dict;
7936         struct talloc_dict_test *t;
7937         int key, count, res;
7938         bool ok;
7939
7940         dict = talloc_dict_init(talloc_tos());
7941         if (dict == NULL) {
7942                 return false;
7943         }
7944
7945         t = talloc(talloc_tos(), struct talloc_dict_test);
7946         if (t == NULL) {
7947                 return false;
7948         }
7949
7950         key = 1;
7951         t->content = 1;
7952         ok = talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), &t);
7953         if (!ok) {
7954                 return false;
7955         }
7956
7957         count = 0;
7958         res = talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count);
7959         if (res == -1) {
7960                 return false;
7961         }
7962
7963         if (count != 1) {
7964                 return false;
7965         }
7966
7967         if (count != res) {
7968                 return false;
7969         }
7970
7971         TALLOC_FREE(dict);
7972
7973         return true;
7974 }
7975
7976 static bool run_local_string_to_sid(int dummy) {
7977         struct dom_sid sid;
7978
7979         if (string_to_sid(&sid, "S--1-5-32-545")) {
7980                 printf("allowing S--1-5-32-545\n");
7981                 return false;
7982         }
7983         if (string_to_sid(&sid, "S-1-5-32-+545")) {
7984                 printf("allowing S-1-5-32-+545\n");
7985                 return false;
7986         }
7987         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")) {
7988                 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7989                 return false;
7990         }
7991         if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7992                 printf("allowing S-1-5-32-545-abc\n");
7993                 return false;
7994         }
7995         if (!string_to_sid(&sid, "S-1-5-32-545")) {
7996                 printf("could not parse S-1-5-32-545\n");
7997                 return false;
7998         }
7999         if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
8000                 printf("mis-parsed S-1-5-32-545 as %s\n",
8001                        sid_string_tos(&sid));
8002                 return false;
8003         }
8004         return true;
8005 }
8006
8007 static bool run_local_binary_to_sid(int dummy) {
8008         struct dom_sid *sid = talloc(NULL, struct dom_sid);
8009         static const char good_binary_sid[] = {
8010                 0x1, /* revision number */
8011                 15, /* num auths */
8012                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8013                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8014                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8015                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8016                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8017                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8018                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8019                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8020                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8021                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8022                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8023                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8024                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8025                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8026                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8027                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8028         };
8029
8030         static const char long_binary_sid[] = {
8031                 0x1, /* revision number */
8032                 15, /* num auths */
8033                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8034                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8035                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8036                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8037                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8038                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8039                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8040                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8041                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8042                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8043                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8044                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8045                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8046                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8047                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8048                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8049                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8050                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8051                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8052         };
8053
8054         static const char long_binary_sid2[] = {
8055                 0x1, /* revision number */
8056                 32, /* num auths */
8057                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8058                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8059                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8060                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8061                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8062                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8063                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8064                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8065                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8066                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8067                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8068                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8069                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8070                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8071                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8072                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8073                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8074                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8075                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8076                 0x1, 0x1, 0x1, 0x1, /* auth[18] */
8077                 0x1, 0x1, 0x1, 0x1, /* auth[19] */
8078                 0x1, 0x1, 0x1, 0x1, /* auth[20] */
8079                 0x1, 0x1, 0x1, 0x1, /* auth[21] */
8080                 0x1, 0x1, 0x1, 0x1, /* auth[22] */
8081                 0x1, 0x1, 0x1, 0x1, /* auth[23] */
8082                 0x1, 0x1, 0x1, 0x1, /* auth[24] */
8083                 0x1, 0x1, 0x1, 0x1, /* auth[25] */
8084                 0x1, 0x1, 0x1, 0x1, /* auth[26] */
8085                 0x1, 0x1, 0x1, 0x1, /* auth[27] */
8086                 0x1, 0x1, 0x1, 0x1, /* auth[28] */
8087                 0x1, 0x1, 0x1, 0x1, /* auth[29] */
8088                 0x1, 0x1, 0x1, 0x1, /* auth[30] */
8089                 0x1, 0x1, 0x1, 0x1, /* auth[31] */
8090         };
8091
8092         if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
8093                 return false;
8094         }
8095         if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
8096                 return false;
8097         }
8098         if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
8099                 return false;
8100         }
8101         return true;
8102 }
8103
8104 /* Split a path name into filename and stream name components. Canonicalise
8105  * such that an implicit $DATA token is always explicit.
8106  *
8107  * The "specification" of this function can be found in the
8108  * run_local_stream_name() function in torture.c, I've tried those
8109  * combinations against a W2k3 server.
8110  */
8111
8112 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
8113                                        char **pbase, char **pstream)
8114 {
8115         char *base = NULL;
8116         char *stream = NULL;
8117         char *sname; /* stream name */
8118         const char *stype; /* stream type */
8119
8120         DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
8121
8122         sname = strchr_m(fname, ':');
8123
8124         if (lp_posix_pathnames() || (sname == NULL)) {
8125                 if (pbase != NULL) {
8126                         base = talloc_strdup(mem_ctx, fname);
8127                         NT_STATUS_HAVE_NO_MEMORY(base);
8128                 }
8129                 goto done;
8130         }
8131
8132         if (pbase != NULL) {
8133                 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
8134                 NT_STATUS_HAVE_NO_MEMORY(base);
8135         }
8136
8137         sname += 1;
8138
8139         stype = strchr_m(sname, ':');
8140
8141         if (stype == NULL) {
8142                 sname = talloc_strdup(mem_ctx, sname);
8143                 stype = "$DATA";
8144         }
8145         else {
8146                 if (strcasecmp_m(stype, ":$DATA") != 0) {
8147                         /*
8148                          * If there is an explicit stream type, so far we only
8149                          * allow $DATA. Is there anything else allowed? -- vl
8150                          */
8151                         DEBUG(10, ("[%s] is an invalid stream type\n", stype));
8152                         TALLOC_FREE(base);
8153                         return NT_STATUS_OBJECT_NAME_INVALID;
8154                 }
8155                 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
8156                 stype += 1;
8157         }
8158
8159         if (sname == NULL) {
8160                 TALLOC_FREE(base);
8161                 return NT_STATUS_NO_MEMORY;
8162         }
8163
8164         if (sname[0] == '\0') {
8165                 /*
8166                  * no stream name, so no stream
8167                  */
8168                 goto done;
8169         }
8170
8171         if (pstream != NULL) {
8172                 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
8173                 if (stream == NULL) {
8174                         TALLOC_FREE(sname);
8175                         TALLOC_FREE(base);
8176                         return NT_STATUS_NO_MEMORY;
8177                 }
8178                 /*
8179                  * upper-case the type field
8180                  */
8181                 strupper_m(strchr_m(stream, ':')+1);
8182         }
8183
8184  done:
8185         if (pbase != NULL) {
8186                 *pbase = base;
8187         }
8188         if (pstream != NULL) {
8189                 *pstream = stream;
8190         }
8191         return NT_STATUS_OK;
8192 }
8193
8194 static bool test_stream_name(const char *fname, const char *expected_base,
8195                              const char *expected_stream,
8196                              NTSTATUS expected_status)
8197 {
8198         NTSTATUS status;
8199         char *base = NULL;
8200         char *stream = NULL;
8201
8202         status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
8203         if (!NT_STATUS_EQUAL(status, expected_status)) {
8204                 goto error;
8205         }
8206
8207         if (!NT_STATUS_IS_OK(status)) {
8208                 return true;
8209         }
8210
8211         if (base == NULL) goto error;
8212
8213         if (strcmp(expected_base, base) != 0) goto error;
8214
8215         if ((expected_stream != NULL) && (stream == NULL)) goto error;
8216         if ((expected_stream == NULL) && (stream != NULL)) goto error;
8217
8218         if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
8219                 goto error;
8220
8221         TALLOC_FREE(base);
8222         TALLOC_FREE(stream);
8223         return true;
8224
8225  error:
8226         d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
8227                   fname, expected_base ? expected_base : "<NULL>",
8228                   expected_stream ? expected_stream : "<NULL>",
8229                   nt_errstr(expected_status));
8230         d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
8231                   base ? base : "<NULL>", stream ? stream : "<NULL>",
8232                   nt_errstr(status));
8233         TALLOC_FREE(base);
8234         TALLOC_FREE(stream);
8235         return false;
8236 }
8237
8238 static bool run_local_stream_name(int dummy)
8239 {
8240         bool ret = true;
8241
8242         ret &= test_stream_name(
8243                 "bla", "bla", NULL, NT_STATUS_OK);
8244         ret &= test_stream_name(
8245                 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
8246         ret &= test_stream_name(
8247                 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8248         ret &= test_stream_name(
8249                 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
8250         ret &= test_stream_name(
8251                 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8252         ret &= test_stream_name(
8253                 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
8254         ret &= test_stream_name(
8255                 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
8256         ret &= test_stream_name(
8257                 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
8258
8259         return ret;
8260 }
8261
8262 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
8263 {
8264         if (a.length != b.length) {
8265                 printf("a.length=%d != b.length=%d\n",
8266                        (int)a.length, (int)b.length);
8267                 return false;
8268         }
8269         if (memcmp(a.data, b.data, a.length) != 0) {
8270                 printf("a.data and b.data differ\n");
8271                 return false;
8272         }
8273         return true;
8274 }
8275
8276 static bool run_local_memcache(int dummy)
8277 {
8278         struct memcache *cache;
8279         DATA_BLOB k1, k2;
8280         DATA_BLOB d1, d2, d3;
8281         DATA_BLOB v1, v2, v3;
8282
8283         TALLOC_CTX *mem_ctx;
8284         char *str1, *str2;
8285         size_t size1, size2;
8286         bool ret = false;
8287
8288         cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
8289
8290         if (cache == NULL) {
8291                 printf("memcache_init failed\n");
8292                 return false;
8293         }
8294
8295         d1 = data_blob_const("d1", 2);
8296         d2 = data_blob_const("d2", 2);
8297         d3 = data_blob_const("d3", 2);
8298
8299         k1 = data_blob_const("d1", 2);
8300         k2 = data_blob_const("d2", 2);
8301
8302         memcache_add(cache, STAT_CACHE, k1, d1);
8303         memcache_add(cache, GETWD_CACHE, k2, d2);
8304
8305         if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
8306                 printf("could not find k1\n");
8307                 return false;
8308         }
8309         if (!data_blob_equal(d1, v1)) {
8310                 return false;
8311         }
8312
8313         if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8314                 printf("could not find k2\n");
8315                 return false;
8316         }
8317         if (!data_blob_equal(d2, v2)) {
8318                 return false;
8319         }
8320
8321         memcache_add(cache, STAT_CACHE, k1, d3);
8322
8323         if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
8324                 printf("could not find replaced k1\n");
8325                 return false;
8326         }
8327         if (!data_blob_equal(d3, v3)) {
8328                 return false;
8329         }
8330
8331         memcache_add(cache, GETWD_CACHE, k1, d1);
8332
8333         if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8334                 printf("Did find k2, should have been purged\n");
8335                 return false;
8336         }
8337
8338         TALLOC_FREE(cache);
8339
8340         cache = memcache_init(NULL, 0);
8341
8342         mem_ctx = talloc_init("foo");
8343
8344         str1 = talloc_strdup(mem_ctx, "string1");
8345         str2 = talloc_strdup(mem_ctx, "string2");
8346
8347         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8348                             data_blob_string_const("torture"), &str1);
8349         size1 = talloc_total_size(cache);
8350
8351         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8352                             data_blob_string_const("torture"), &str2);
8353         size2 = talloc_total_size(cache);
8354
8355         printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
8356
8357         if (size2 > size1) {
8358                 printf("memcache leaks memory!\n");
8359                 goto fail;
8360         }
8361
8362         ret = true;
8363  fail:
8364         TALLOC_FREE(cache);
8365         return ret;
8366 }
8367
8368 static void wbclient_done(struct tevent_req *req)
8369 {
8370         wbcErr wbc_err;
8371         struct winbindd_response *wb_resp;
8372         int *i = (int *)tevent_req_callback_data_void(req);
8373
8374         wbc_err = wb_trans_recv(req, req, &wb_resp);
8375         TALLOC_FREE(req);
8376         *i += 1;
8377         d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
8378 }
8379
8380 static bool run_local_wbclient(int dummy)
8381 {
8382         struct event_context *ev;
8383         struct wb_context **wb_ctx;
8384         struct winbindd_request wb_req;
8385         bool result = false;
8386         int i, j;
8387
8388         BlockSignals(True, SIGPIPE);
8389
8390         ev = tevent_context_init_byname(talloc_tos(), "epoll");
8391         if (ev == NULL) {
8392                 goto fail;
8393         }
8394
8395         wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
8396         if (wb_ctx == NULL) {
8397                 goto fail;
8398         }
8399
8400         ZERO_STRUCT(wb_req);
8401         wb_req.cmd = WINBINDD_PING;
8402
8403         d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
8404
8405         for (i=0; i<torture_nprocs; i++) {
8406                 wb_ctx[i] = wb_context_init(ev, NULL);
8407                 if (wb_ctx[i] == NULL) {
8408                         goto fail;
8409                 }
8410                 for (j=0; j<torture_numops; j++) {
8411                         struct tevent_req *req;
8412                         req = wb_trans_send(ev, ev, wb_ctx[i],
8413                                             (j % 2) == 0, &wb_req);
8414                         if (req == NULL) {
8415                                 goto fail;
8416                         }
8417                         tevent_req_set_callback(req, wbclient_done, &i);
8418                 }
8419         }
8420
8421         i = 0;
8422
8423         while (i < torture_nprocs * torture_numops) {
8424                 tevent_loop_once(ev);
8425         }
8426
8427         result = true;
8428  fail:
8429         TALLOC_FREE(ev);
8430         return result;
8431 }
8432
8433 static void getaddrinfo_finished(struct tevent_req *req)
8434 {
8435         char *name = (char *)tevent_req_callback_data_void(req);
8436         struct addrinfo *ainfo;
8437         int res;
8438
8439         res = getaddrinfo_recv(req, &ainfo);
8440         if (res != 0) {
8441                 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
8442                 return;
8443         }
8444         d_printf("gai(%s) succeeded\n", name);
8445         freeaddrinfo(ainfo);
8446 }
8447
8448 static bool run_getaddrinfo_send(int dummy)
8449 {
8450         TALLOC_CTX *frame = talloc_stackframe();
8451         struct fncall_context *ctx;
8452         struct tevent_context *ev;
8453         bool result = false;
8454         const char *names[4] = { "www.samba.org", "notfound.samba.org",
8455                                  "www.slashdot.org", "heise.de" };
8456         struct tevent_req *reqs[4];
8457         int i;
8458
8459         ev = event_context_init(frame);
8460         if (ev == NULL) {
8461                 goto fail;
8462         }
8463
8464         ctx = fncall_context_init(frame, 4);
8465
8466         for (i=0; i<ARRAY_SIZE(names); i++) {
8467                 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8468                                            NULL);
8469                 if (reqs[i] == NULL) {
8470                         goto fail;
8471                 }
8472                 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8473                                         discard_const_p(void, names[i]));
8474         }
8475
8476         for (i=0; i<ARRAY_SIZE(reqs); i++) {
8477                 tevent_loop_once(ev);
8478         }
8479
8480         result = true;
8481 fail:
8482         TALLOC_FREE(frame);
8483         return result;
8484 }
8485
8486 static bool dbtrans_inc(struct db_context *db)
8487 {
8488         struct db_record *rec;
8489         uint32_t val;
8490         bool ret = false;
8491         NTSTATUS status;
8492         TDB_DATA value;
8493
8494         rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
8495         if (rec == NULL) {
8496                 printf(__location__ "fetch_lock failed\n");
8497                 return false;
8498         }
8499
8500         value = dbwrap_record_get_value(rec);
8501
8502         if (value.dsize != sizeof(uint32_t)) {
8503                 printf(__location__ "value.dsize = %d\n",
8504                        (int)value.dsize);
8505                 goto fail;
8506         }
8507
8508         memcpy(&val, value.dptr, sizeof(val));
8509         val += 1;
8510
8511         status = dbwrap_record_store(
8512                 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
8513         if (!NT_STATUS_IS_OK(status)) {
8514                 printf(__location__ "store failed: %s\n",
8515                        nt_errstr(status));
8516                 goto fail;
8517         }
8518
8519         ret = true;
8520 fail:
8521         TALLOC_FREE(rec);
8522         return ret;
8523 }
8524
8525 static bool run_local_dbtrans(int dummy)
8526 {
8527         struct db_context *db;
8528         struct db_record *rec;
8529         NTSTATUS status;
8530         uint32_t initial;
8531         int res;
8532         TDB_DATA value;
8533
8534         db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8535                      O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1);
8536         if (db == NULL) {
8537                 printf("Could not open transtest.db\n");
8538                 return false;
8539         }
8540
8541         res = dbwrap_transaction_start(db);
8542         if (res != 0) {
8543                 printf(__location__ "transaction_start failed\n");
8544                 return false;
8545         }
8546
8547         rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
8548         if (rec == NULL) {
8549                 printf(__location__ "fetch_lock failed\n");
8550                 return false;
8551         }
8552
8553         value = dbwrap_record_get_value(rec);
8554
8555         if (value.dptr == NULL) {
8556                 initial = 0;
8557                 status = dbwrap_record_store(
8558                         rec, make_tdb_data((uint8_t *)&initial,
8559                                            sizeof(initial)),
8560                         0);
8561                 if (!NT_STATUS_IS_OK(status)) {
8562                         printf(__location__ "store returned %s\n",
8563                                nt_errstr(status));
8564                         return false;
8565                 }
8566         }
8567
8568         TALLOC_FREE(rec);
8569
8570         res = dbwrap_transaction_commit(db);
8571         if (res != 0) {
8572                 printf(__location__ "transaction_commit failed\n");
8573                 return false;
8574         }
8575
8576         while (true) {
8577                 uint32_t val, val2;
8578                 int i;
8579
8580                 res = dbwrap_transaction_start(db);
8581                 if (res != 0) {
8582                         printf(__location__ "transaction_start failed\n");
8583                         break;
8584                 }
8585
8586                 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
8587                 if (!NT_STATUS_IS_OK(status)) {
8588                         printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
8589                                nt_errstr(status));
8590                         break;
8591                 }
8592
8593                 for (i=0; i<10; i++) {
8594                         if (!dbtrans_inc(db)) {
8595                                 return false;
8596                         }
8597                 }
8598
8599                 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
8600                 if (!NT_STATUS_IS_OK(status)) {
8601                         printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
8602                                nt_errstr(status));
8603                         break;
8604                 }
8605
8606                 if (val2 != val + 10) {
8607                         printf(__location__ "val=%d, val2=%d\n",
8608                                (int)val, (int)val2);
8609                         break;
8610                 }
8611
8612                 printf("val2=%d\r", val2);
8613
8614                 res = dbwrap_transaction_commit(db);
8615                 if (res != 0) {
8616                         printf(__location__ "transaction_commit failed\n");
8617                         break;
8618                 }
8619         }
8620
8621         TALLOC_FREE(db);
8622         return true;
8623 }
8624
8625 /*
8626  * Just a dummy test to be run under a debugger. There's no real way
8627  * to inspect the tevent_select specific function from outside of
8628  * tevent_select.c.
8629  */
8630
8631 static bool run_local_tevent_select(int dummy)
8632 {
8633         struct tevent_context *ev;
8634         struct tevent_fd *fd1, *fd2;
8635         bool result = false;
8636
8637         ev = tevent_context_init_byname(NULL, "select");
8638         if (ev == NULL) {
8639                 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8640                 goto fail;
8641         }
8642
8643         fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8644         if (fd1 == NULL) {
8645                 d_fprintf(stderr, "tevent_add_fd failed\n");
8646                 goto fail;
8647         }
8648         fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8649         if (fd2 == NULL) {
8650                 d_fprintf(stderr, "tevent_add_fd failed\n");
8651                 goto fail;
8652         }
8653         TALLOC_FREE(fd2);
8654
8655         fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8656         if (fd2 == NULL) {
8657                 d_fprintf(stderr, "tevent_add_fd failed\n");
8658                 goto fail;
8659         }
8660
8661         result = true;
8662 fail:
8663         TALLOC_FREE(ev);
8664         return result;
8665 }
8666
8667 static bool run_local_hex_encode_buf(int dummy)
8668 {
8669         char buf[17];
8670         uint8_t src[8];
8671         int i;
8672
8673         for (i=0; i<sizeof(src); i++) {
8674                 src[i] = i;
8675         }
8676         hex_encode_buf(buf, src, sizeof(src));
8677         if (strcmp(buf, "0001020304050607") != 0) {
8678                 return false;
8679         }
8680         hex_encode_buf(buf, NULL, 0);
8681         if (buf[0] != '\0') {
8682                 return false;
8683         }
8684         return true;
8685 }
8686
8687 static const char *remove_duplicate_addrs2_test_strings_vector[] = {
8688         "0.0.0.0",
8689         "::0",
8690         "1.2.3.1",
8691         "0.0.0.0",
8692         "0.0.0.0",
8693         "1.2.3.2",
8694         "1.2.3.3",
8695         "1.2.3.4",
8696         "1.2.3.5",
8697         "::0",
8698         "1.2.3.6",
8699         "1.2.3.7",
8700         "::0",
8701         "::0",
8702         "::0",
8703         "1.2.3.8",
8704         "1.2.3.9",
8705         "1.2.3.10",
8706         "1.2.3.11",
8707         "1.2.3.12",
8708         "1.2.3.13",
8709         "1001:1111:1111:1000:0:1111:1111:1111",
8710         "1.2.3.1",
8711         "1.2.3.2",
8712         "1.2.3.3",
8713         "1.2.3.12",
8714         "::0",
8715         "::0"
8716 };
8717
8718 static const char *remove_duplicate_addrs2_test_strings_result[] = {
8719         "1.2.3.1",
8720         "1.2.3.2",
8721         "1.2.3.3",
8722         "1.2.3.4",
8723         "1.2.3.5",
8724         "1.2.3.6",
8725         "1.2.3.7",
8726         "1.2.3.8",
8727         "1.2.3.9",
8728         "1.2.3.10",
8729         "1.2.3.11",
8730         "1.2.3.12",
8731         "1.2.3.13",
8732         "1001:1111:1111:1000:0:1111:1111:1111"
8733 };
8734
8735 static bool run_local_remove_duplicate_addrs2(int dummy)
8736 {
8737         struct ip_service test_vector[28];
8738         int count, i;
8739
8740         /* Construct the sockaddr_storage test vector. */
8741         for (i = 0; i < 28; i++) {
8742                 struct addrinfo hints;
8743                 struct addrinfo *res = NULL;
8744                 int ret;
8745
8746                 memset(&hints, '\0', sizeof(hints));
8747                 hints.ai_flags = AI_NUMERICHOST;
8748                 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
8749                                 NULL,
8750                                 &hints,
8751                                 &res);
8752                 if (ret) {
8753                         fprintf(stderr, "getaddrinfo failed on [%s]\n",
8754                                 remove_duplicate_addrs2_test_strings_vector[i]);
8755                         return false;
8756                 }
8757                 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
8758                 memcpy(&test_vector[i].ss,
8759                         res->ai_addr,
8760                         res->ai_addrlen);
8761                 freeaddrinfo(res);
8762         }
8763
8764         count = remove_duplicate_addrs2(test_vector, i);
8765
8766         if (count != 14) {
8767                 fprintf(stderr, "count wrong (%d) should be 14\n",
8768                         count);
8769                 return false;
8770         }
8771
8772         for (i = 0; i < count; i++) {
8773                 char addr[INET6_ADDRSTRLEN];
8774
8775                 print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
8776
8777                 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
8778                         fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
8779                                 i,
8780                                 addr,
8781                                 remove_duplicate_addrs2_test_strings_result[i]);
8782                         return false;
8783                 }
8784         }
8785
8786         printf("run_local_remove_duplicate_addrs2: success\n");
8787         return true;
8788 }
8789
8790 static double create_procs(bool (*fn)(int), bool *result)
8791 {
8792         int i, status;
8793         volatile pid_t *child_status;
8794         volatile bool *child_status_out;
8795         int synccount;
8796         int tries = 8;
8797         struct timeval start;
8798
8799         synccount = 0;
8800
8801         child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
8802         if (!child_status) {
8803                 printf("Failed to setup shared memory\n");
8804                 return -1;
8805         }
8806
8807         child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
8808         if (!child_status_out) {
8809                 printf("Failed to setup result status shared memory\n");
8810                 return -1;
8811         }
8812
8813         for (i = 0; i < torture_nprocs; i++) {
8814                 child_status[i] = 0;
8815                 child_status_out[i] = True;
8816         }
8817
8818         start = timeval_current();
8819
8820         for (i=0;i<torture_nprocs;i++) {
8821                 procnum = i;
8822                 if (fork() == 0) {
8823                         pid_t mypid = getpid();
8824                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8825
8826                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
8827
8828                         while (1) {
8829                                 if (torture_open_connection(&current_cli, i)) break;
8830                                 if (tries-- == 0) {
8831                                         printf("pid %d failed to start\n", (int)getpid());
8832                                         _exit(1);
8833                                 }
8834                                 smb_msleep(10); 
8835                         }
8836
8837                         child_status[i] = getpid();
8838
8839                         while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8840
8841                         child_status_out[i] = fn(i);
8842                         _exit(0);
8843                 }
8844         }
8845
8846         do {
8847                 synccount = 0;
8848                 for (i=0;i<torture_nprocs;i++) {
8849                         if (child_status[i]) synccount++;
8850                 }
8851                 if (synccount == torture_nprocs) break;
8852                 smb_msleep(10);
8853         } while (timeval_elapsed(&start) < 30);
8854
8855         if (synccount != torture_nprocs) {
8856                 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
8857                 *result = False;
8858                 return timeval_elapsed(&start);
8859         }
8860
8861         /* start the client load */
8862         start = timeval_current();
8863
8864         for (i=0;i<torture_nprocs;i++) {
8865                 child_status[i] = 0;
8866         }
8867
8868         printf("%d clients started\n", torture_nprocs);
8869
8870         for (i=0;i<torture_nprocs;i++) {
8871                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8872         }
8873
8874         printf("\n");
8875
8876         for (i=0;i<torture_nprocs;i++) {
8877                 if (!child_status_out[i]) {
8878                         *result = False;
8879                 }
8880         }
8881         return timeval_elapsed(&start);
8882 }
8883
8884 #define FLAG_MULTIPROC 1
8885
8886 static struct {
8887         const char *name;
8888         bool (*fn)(int);
8889         unsigned flags;
8890 } torture_ops[] = {
8891         {"FDPASS", run_fdpasstest, 0},
8892         {"LOCK1",  run_locktest1,  0},
8893         {"LOCK2",  run_locktest2,  0},
8894         {"LOCK3",  run_locktest3,  0},
8895         {"LOCK4",  run_locktest4,  0},
8896         {"LOCK5",  run_locktest5,  0},
8897         {"LOCK6",  run_locktest6,  0},
8898         {"LOCK7",  run_locktest7,  0},
8899         {"LOCK8",  run_locktest8,  0},
8900         {"LOCK9",  run_locktest9,  0},
8901         {"UNLINK", run_unlinktest, 0},
8902         {"BROWSE", run_browsetest, 0},
8903         {"ATTR",   run_attrtest,   0},
8904         {"TRANS2", run_trans2test, 0},
8905         {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8906         {"TORTURE",run_torture,    FLAG_MULTIPROC},
8907         {"RANDOMIPC", run_randomipc, 0},
8908         {"NEGNOWAIT", run_negprot_nowait, 0},
8909         {"NBENCH",  run_nbench, 0},
8910         {"NBENCH2", run_nbench2, 0},
8911         {"OPLOCK1",  run_oplock1, 0},
8912         {"OPLOCK2",  run_oplock2, 0},
8913         {"OPLOCK4",  run_oplock4, 0},
8914         {"DIR",  run_dirtest, 0},
8915         {"DIR1",  run_dirtest1, 0},
8916         {"DIR-CREATETIME",  run_dir_createtime, 0},
8917         {"DENY1",  torture_denytest1, 0},
8918         {"DENY2",  torture_denytest2, 0},
8919         {"TCON",  run_tcon_test, 0},
8920         {"TCONDEV",  run_tcon_devtype_test, 0},
8921         {"RW1",  run_readwritetest, 0},
8922         {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
8923         {"RW3",  run_readwritelarge, 0},
8924         {"RW-SIGNING",  run_readwritelarge_signtest, 0},
8925         {"OPEN", run_opentest, 0},
8926         {"POSIX", run_simple_posix_open_test, 0},
8927         {"POSIX-APPEND", run_posix_append, 0},
8928         {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8929         {"ASYNC-ECHO", run_async_echo, 0},
8930         { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8931         { "SHORTNAME-TEST", run_shortname_test, 0},
8932         { "ADDRCHANGE", run_addrchange, 0},
8933 #if 1
8934         {"OPENATTR", run_openattrtest, 0},
8935 #endif
8936         {"XCOPY", run_xcopy, 0},
8937         {"RENAME", run_rename, 0},
8938         {"DELETE", run_deletetest, 0},
8939         {"DELETE-LN", run_deletetest_ln, 0},
8940         {"PROPERTIES", run_properties, 0},
8941         {"MANGLE", torture_mangle, 0},
8942         {"MANGLE1", run_mangle1, 0},
8943         {"W2K", run_w2ktest, 0},
8944         {"TRANS2SCAN", torture_trans2_scan, 0},
8945         {"NTTRANSSCAN", torture_nttrans_scan, 0},
8946         {"UTABLE", torture_utable, 0},
8947         {"CASETABLE", torture_casetable, 0},
8948         {"ERRMAPEXTRACT", run_error_map_extract, 0},
8949         {"PIPE_NUMBER", run_pipe_number, 0},
8950         {"TCON2",  run_tcon2_test, 0},
8951         {"IOCTL",  torture_ioctl_test, 0},
8952         {"CHKPATH",  torture_chkpath_test, 0},
8953         {"FDSESS", run_fdsesstest, 0},
8954         { "EATEST", run_eatest, 0},
8955         { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8956         { "CHAIN1", run_chain1, 0},
8957         { "CHAIN2", run_chain2, 0},
8958         { "CHAIN3", run_chain3, 0},
8959         { "WINDOWS-WRITE", run_windows_write, 0},
8960         { "NTTRANS-CREATE", run_nttrans_create, 0},
8961         { "NTTRANS-FSCTL", run_nttrans_fsctl, 0},
8962         { "CLI_ECHO", run_cli_echo, 0},
8963         { "GETADDRINFO", run_getaddrinfo_send, 0},
8964         { "TLDAP", run_tldap },
8965         { "STREAMERROR", run_streamerror },
8966         { "NOTIFY-BENCH", run_notify_bench },
8967         { "NOTIFY-BENCH2", run_notify_bench2 },
8968         { "NOTIFY-BENCH3", run_notify_bench3 },
8969         { "BAD-NBT-SESSION", run_bad_nbt_session },
8970         { "SMB-ANY-CONNECT", run_smb_any_connect },
8971         { "NOTIFY-ONLINE", run_notify_online },
8972         { "SMB2-BASIC", run_smb2_basic },
8973         { "SMB2-NEGPROT", run_smb2_negprot },
8974         { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect },
8975         { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence },
8976         { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel },
8977         { "SMB2-SESSION-REAUTH", run_smb2_session_reauth },
8978         { "CLEANUP1", run_cleanup1 },
8979         { "CLEANUP2", run_cleanup2 },
8980         { "CLEANUP3", run_cleanup3 },
8981         { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8982         { "LOCAL-GENCACHE", run_local_gencache, 0},
8983         { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8984         { "LOCAL-CTDB-CONN", run_ctdb_conn, 0},
8985         { "LOCAL-MSG", run_msg_test, 0},
8986         { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1, 0 },
8987         { "LOCAL-BASE64", run_local_base64, 0},
8988         { "LOCAL-RBTREE", run_local_rbtree, 0},
8989         { "LOCAL-MEMCACHE", run_local_memcache, 0},
8990         { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8991         { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8992         { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8993         { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8994         { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8995         { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8996         { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8997         { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0},
8998         { "LOCAL-sprintf_append", run_local_sprintf_append, 0},
8999         { "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0},
9000         { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test, 0},
9001         { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2, 0},
9002         {NULL, NULL, 0}};
9003
9004
9005
9006 /****************************************************************************
9007 run a specified test or "ALL"
9008 ****************************************************************************/
9009 static bool run_test(const char *name)
9010 {
9011         bool ret = True;
9012         bool result = True;
9013         bool found = False;
9014         int i;
9015         double t;
9016         if (strequal(name,"ALL")) {
9017                 for (i=0;torture_ops[i].name;i++) {
9018                         run_test(torture_ops[i].name);
9019                 }
9020                 found = True;
9021         }
9022
9023         for (i=0;torture_ops[i].name;i++) {
9024                 fstr_sprintf(randomfname, "\\XX%x", 
9025                          (unsigned)random());
9026
9027                 if (strequal(name, torture_ops[i].name)) {
9028                         found = True;
9029                         printf("Running %s\n", name);
9030                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
9031                                 t = create_procs(torture_ops[i].fn, &result);
9032                                 if (!result) { 
9033                                         ret = False;
9034                                         printf("TEST %s FAILED!\n", name);
9035                                 }
9036                         } else {
9037                                 struct timeval start;
9038                                 start = timeval_current();
9039                                 if (!torture_ops[i].fn(0)) {
9040                                         ret = False;
9041                                         printf("TEST %s FAILED!\n", name);
9042                                 }
9043                                 t = timeval_elapsed(&start);
9044                         }
9045                         printf("%s took %g secs\n\n", name, t);
9046                 }
9047         }
9048
9049         if (!found) {
9050                 printf("Did not find a test named %s\n", name);
9051                 ret = False;
9052         }
9053
9054         return ret;
9055 }
9056
9057
9058 static void usage(void)
9059 {
9060         int i;
9061
9062         printf("WARNING samba4 test suite is much more complete nowadays.\n");
9063         printf("Please use samba4 torture.\n\n");
9064
9065         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
9066
9067         printf("\t-d debuglevel\n");
9068         printf("\t-U user%%pass\n");
9069         printf("\t-k               use kerberos\n");
9070         printf("\t-N numprocs\n");
9071         printf("\t-n my_netbios_name\n");
9072         printf("\t-W workgroup\n");
9073         printf("\t-o num_operations\n");
9074         printf("\t-O socket_options\n");
9075         printf("\t-m maximum protocol\n");
9076         printf("\t-L use oplocks\n");
9077         printf("\t-c CLIENT.TXT   specify client load file for NBENCH\n");
9078         printf("\t-A showall\n");
9079         printf("\t-p port\n");
9080         printf("\t-s seed\n");
9081         printf("\t-b unclist_filename   specify multiple shares for multiple connections\n");
9082         printf("\t-f filename   filename to test\n");
9083         printf("\n\n");
9084
9085         printf("tests are:");
9086         for (i=0;torture_ops[i].name;i++) {
9087                 printf(" %s", torture_ops[i].name);
9088         }
9089         printf("\n");
9090
9091         printf("default test is ALL\n");
9092
9093         exit(1);
9094 }
9095
9096 /****************************************************************************
9097   main program
9098 ****************************************************************************/
9099  int main(int argc,char *argv[])
9100 {
9101         int opt, i;
9102         char *p;
9103         int gotuser = 0;
9104         int gotpass = 0;
9105         bool correct = True;
9106         TALLOC_CTX *frame = talloc_stackframe();
9107         int seed = time(NULL);
9108
9109 #ifdef HAVE_SETBUFFER
9110         setbuffer(stdout, NULL, 0);
9111 #endif
9112
9113         setup_logging("smbtorture", DEBUG_STDOUT);
9114
9115         load_case_tables();
9116
9117         if (is_default_dyn_CONFIGFILE()) {
9118                 if(getenv("SMB_CONF_PATH")) {
9119                         set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
9120                 }
9121         }
9122         lp_load_global(get_dyn_CONFIGFILE());
9123         load_interfaces();
9124
9125         if (argc < 2) {
9126                 usage();
9127         }
9128
9129         for(p = argv[1]; *p; p++)
9130           if(*p == '\\')
9131             *p = '/';
9132
9133         if (strncmp(argv[1], "//", 2)) {
9134                 usage();
9135         }
9136
9137         fstrcpy(host, &argv[1][2]);
9138         p = strchr_m(&host[2],'/');
9139         if (!p) {
9140                 usage();
9141         }
9142         *p = 0;
9143         fstrcpy(share, p+1);
9144
9145         fstrcpy(myname, get_myname(talloc_tos()));
9146         if (!*myname) {
9147                 fprintf(stderr, "Failed to get my hostname.\n");
9148                 return 1;
9149         }
9150
9151         if (*username == 0 && getenv("LOGNAME")) {
9152           fstrcpy(username,getenv("LOGNAME"));
9153         }
9154
9155         argc--;
9156         argv++;
9157
9158         fstrcpy(workgroup, lp_workgroup());
9159
9160         while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
9161                != EOF) {
9162                 switch (opt) {
9163                 case 'p':
9164                         port_to_use = atoi(optarg);
9165                         break;
9166                 case 's':
9167                         seed = atoi(optarg);
9168                         break;
9169                 case 'W':
9170                         fstrcpy(workgroup,optarg);
9171                         break;
9172                 case 'm':
9173                         max_protocol = interpret_protocol(optarg, max_protocol);
9174                         break;
9175                 case 'N':
9176                         torture_nprocs = atoi(optarg);
9177                         break;
9178                 case 'o':
9179                         torture_numops = atoi(optarg);
9180                         break;
9181                 case 'd':
9182                         lp_set_cmdline("log level", optarg);
9183                         break;
9184                 case 'O':
9185                         sockops = optarg;
9186                         break;
9187                 case 'L':
9188                         use_oplocks = True;
9189                         break;
9190                 case 'l':
9191                         local_path = optarg;
9192                         break;
9193                 case 'A':
9194                         torture_showall = True;
9195                         break;
9196                 case 'n':
9197                         fstrcpy(myname, optarg);
9198                         break;
9199                 case 'c':
9200                         client_txt = optarg;
9201                         break;
9202                 case 'e':
9203                         do_encrypt = true;
9204                         break;
9205                 case 'k':
9206 #ifdef HAVE_KRB5
9207                         use_kerberos = True;
9208 #else
9209                         d_printf("No kerberos support compiled in\n");
9210                         exit(1);
9211 #endif
9212                         break;
9213                 case 'U':
9214                         gotuser = 1;
9215                         fstrcpy(username,optarg);
9216                         p = strchr_m(username,'%');
9217                         if (p) {
9218                                 *p = 0;
9219                                 fstrcpy(password, p+1);
9220                                 gotpass = 1;
9221                         }
9222                         break;
9223                 case 'b':
9224                         fstrcpy(multishare_conn_fname, optarg);
9225                         use_multishare_conn = True;
9226                         break;
9227                 case 'B':
9228                         torture_blocksize = atoi(optarg);
9229                         break;
9230                 case 'f':
9231                         test_filename = SMB_STRDUP(optarg);
9232                         break;
9233                 default:
9234                         printf("Unknown option %c (%d)\n", (char)opt, opt);
9235                         usage();
9236                 }
9237         }
9238
9239         d_printf("using seed %d\n", seed);
9240
9241         srandom(seed);
9242
9243         if(use_kerberos && !gotuser) gotpass = True;
9244
9245         while (!gotpass) {
9246                 p = getpass("Password:");
9247                 if (p) {
9248                         fstrcpy(password, p);
9249                         gotpass = 1;
9250                 }
9251         }
9252
9253         printf("host=%s share=%s user=%s myname=%s\n", 
9254                host, share, username, myname);
9255
9256         if (argc == optind) {
9257                 correct = run_test("ALL");
9258         } else {
9259                 for (i=optind;i<argc;i++) {
9260                         if (!run_test(argv[i])) {
9261                                 correct = False;
9262                         }
9263                 }
9264         }
9265
9266         TALLOC_FREE(frame);
9267
9268         if (correct) {
9269                 return(0);
9270         } else {
9271                 return(1);
9272         }
9273 }