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