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