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