Add POSIX O_RDONLY test of a directory for bug #8112 - POSIX extension opens of a...
[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         /* Create again to test open with O_TRUNC. */
5022         if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
5023                 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5024                 goto out;
5025         }
5026
5027         /* Test ftruncate - set file size. */
5028         if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
5029                 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
5030                 goto out;
5031         }
5032
5033         /* Ensure st_size == 1000 */
5034         if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5035                 printf("stat failed (%s)\n", cli_errstr(cli1));
5036                 goto out;
5037         }
5038
5039         if (sbuf.st_ex_size != 1000) {
5040                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5041                 goto out;
5042         }
5043
5044         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5045                 printf("close(2) failed (%s)\n", cli_errstr(cli1));
5046                 goto out;
5047         }
5048
5049         /* Re-open with O_TRUNC. */
5050         if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1))) {
5051                 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5052                 goto out;
5053         }
5054
5055         /* Ensure st_size == 0 */
5056         if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5057                 printf("stat failed (%s)\n", cli_errstr(cli1));
5058                 goto out;
5059         }
5060
5061         if (sbuf.st_ex_size != 0) {
5062                 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5063                 goto out;
5064         }
5065
5066         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5067                 printf("close failed (%s)\n", cli_errstr(cli1));
5068                 goto out;
5069         }
5070
5071         if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
5072                 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
5073                 goto out;
5074         }
5075
5076         if (!NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
5077                 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5078                         dname, cli_errstr(cli1));
5079                 goto out;
5080         }
5081
5082         cli_close(cli1, fnum1);
5083
5084         /* What happens when we try and POSIX open a directory for write ? */
5085         if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1))) {
5086                 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5087                 goto out;
5088         } else {
5089                 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
5090                                 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5091                         goto out;
5092                 }
5093         }
5094
5095         /* Create the file. */
5096         if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
5097                 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5098                 goto out;
5099         }
5100
5101         /* Write some data into it. */
5102         status = cli_writeall(cli1, fnum1, 0, (uint8_t *)"TEST DATA\n", 0, 10,
5103                               NULL);
5104         if (!NT_STATUS_IS_OK(status)) {
5105                 printf("cli_write failed: %s\n", nt_errstr(status));
5106                 goto out;
5107         }
5108
5109         cli_close(cli1, fnum1);
5110
5111         /* Now create a hardlink. */
5112         if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
5113                 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
5114                 goto out;
5115         }
5116
5117         /* Now create a symlink. */
5118         if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
5119                 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
5120                 goto out;
5121         }
5122
5123         /* Open the hardlink for read. */
5124         if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
5125                 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
5126                 goto out;
5127         }
5128
5129         if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5130                 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5131                 goto out;
5132         }
5133
5134         if (memcmp(buf, "TEST DATA\n", 10)) {
5135                 printf("invalid data read from hardlink\n");
5136                 goto out;
5137         }
5138
5139         /* Do a POSIX lock/unlock. */
5140         if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
5141                 printf("POSIX lock failed %s\n", cli_errstr(cli1));
5142                 goto out;
5143         }
5144
5145         /* Punch a hole in the locked area. */
5146         if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
5147                 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
5148                 goto out;
5149         }
5150
5151         cli_close(cli1, fnum1);
5152
5153         /* Open the symlink for read - this should fail. A POSIX
5154            client should not be doing opens on a symlink. */
5155         if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
5156                 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5157                 goto out;
5158         } else {
5159                 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5160                                 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5161                         printf("POSIX open of %s should have failed "
5162                                 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5163                                 "failed with %s instead.\n",
5164                                 sname, cli_errstr(cli1));
5165                         goto out;
5166                 }
5167         }
5168
5169         if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
5170                 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
5171                 goto out;
5172         }
5173
5174         if (strcmp(namebuf, fname) != 0) {
5175                 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5176                         sname, fname, namebuf);
5177                 goto out;
5178         }
5179
5180         if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
5181                 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
5182                 goto out;
5183         }
5184
5185         printf("Simple POSIX open test passed\n");
5186         correct = true;
5187
5188   out:
5189
5190         if (fnum1 != (uint16_t)-1) {
5191                 cli_close(cli1, fnum1);
5192                 fnum1 = (uint16_t)-1;
5193         }
5194
5195         cli_setatr(cli1, sname, 0, 0);
5196         cli_posix_unlink(cli1, sname);
5197         cli_setatr(cli1, hname, 0, 0);
5198         cli_posix_unlink(cli1, hname);
5199         cli_setatr(cli1, fname, 0, 0);
5200         cli_posix_unlink(cli1, fname);
5201         cli_setatr(cli1, dname, 0, 0);
5202         cli_posix_rmdir(cli1, dname);
5203
5204         if (!torture_close_connection(cli1)) {
5205                 correct = false;
5206         }
5207
5208         return correct;
5209 }
5210
5211
5212 static uint32 open_attrs_table[] = {
5213                 FILE_ATTRIBUTE_NORMAL,
5214                 FILE_ATTRIBUTE_ARCHIVE,
5215                 FILE_ATTRIBUTE_READONLY,
5216                 FILE_ATTRIBUTE_HIDDEN,
5217                 FILE_ATTRIBUTE_SYSTEM,
5218
5219                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5220                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5221                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5222                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5223                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5224                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5225
5226                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5227                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5228                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5229                 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5230 };
5231
5232 struct trunc_open_results {
5233         unsigned int num;
5234         uint32 init_attr;
5235         uint32 trunc_attr;
5236         uint32 result_attr;
5237 };
5238
5239 static struct trunc_open_results attr_results[] = {
5240         { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5241         { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5242         { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5243         { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5244         { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5245         { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5246         { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5247         { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5248         { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5249         { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5250         { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5251         { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5252         { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5253         { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5254         { 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 },
5255         { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5256         { 119,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5257         { 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 },
5258         { 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 },
5259         { 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 },
5260         { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5261         { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5262         { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5263         { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5264         { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5265         { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5266 };
5267
5268 static bool run_openattrtest(int dummy)
5269 {
5270         static struct cli_state *cli1;
5271         const char *fname = "\\openattr.file";
5272         uint16_t fnum1;
5273         bool correct = True;
5274         uint16 attr;
5275         unsigned int i, j, k, l;
5276
5277         printf("starting open attr test\n");
5278
5279         if (!torture_open_connection(&cli1, 0)) {
5280                 return False;
5281         }
5282
5283         cli_sockopt(cli1, sockops);
5284
5285         for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5286                 cli_setatr(cli1, fname, 0, 0);
5287                 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5288                 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
5289                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
5290                         printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5291                         return False;
5292                 }
5293
5294                 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5295                         printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5296                         return False;
5297                 }
5298
5299                 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5300                         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
5301                                            FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
5302                                 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5303                                         if (attr_results[l].num == k) {
5304                                                 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5305                                                                 k, open_attrs_table[i],
5306                                                                 open_attrs_table[j],
5307                                                                 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
5308                                                 correct = False;
5309                                         }
5310                                 }
5311                                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
5312                                         printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5313                                                         k, open_attrs_table[i], open_attrs_table[j],
5314                                                         cli_errstr(cli1));
5315                                         correct = False;
5316                                 }
5317 #if 0
5318                                 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5319 #endif
5320                                 k++;
5321                                 continue;
5322                         }
5323
5324                         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5325                                 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
5326                                 return False;
5327                         }
5328
5329                         if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
5330                                 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
5331                                 return False;
5332                         }
5333
5334 #if 0
5335                         printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5336                                         k,  open_attrs_table[i],  open_attrs_table[j], attr );
5337 #endif
5338
5339                         for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5340                                 if (attr_results[l].num == k) {
5341                                         if (attr != attr_results[l].result_attr ||
5342                                                         open_attrs_table[i] != attr_results[l].init_attr ||
5343                                                         open_attrs_table[j] != attr_results[l].trunc_attr) {
5344                                                 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5345                                                 open_attrs_table[i],
5346                                                 open_attrs_table[j],
5347                                                 (unsigned int)attr,
5348                                                 attr_results[l].result_attr);
5349                                                 correct = False;
5350                                         }
5351                                         break;
5352                                 }
5353                         }
5354                         k++;
5355                 }
5356         }
5357
5358         cli_setatr(cli1, fname, 0, 0);
5359         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5360
5361         printf("open attr test %s.\n", correct ? "passed" : "failed");
5362
5363         if (!torture_close_connection(cli1)) {
5364                 correct = False;
5365         }
5366         return correct;
5367 }
5368
5369 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5370                     const char *name, void *state)
5371 {
5372         int *matched = (int *)state;
5373         if (matched != NULL) {
5374                 *matched += 1;
5375         }
5376         return NT_STATUS_OK;
5377 }
5378
5379 /*
5380   test directory listing speed
5381  */
5382 static bool run_dirtest(int dummy)
5383 {
5384         int i;
5385         static struct cli_state *cli;
5386         uint16_t fnum;
5387         struct timeval core_start;
5388         bool correct = True;
5389         int matched;
5390
5391         printf("starting directory test\n");
5392
5393         if (!torture_open_connection(&cli, 0)) {
5394                 return False;
5395         }
5396
5397         cli_sockopt(cli, sockops);
5398
5399         srandom(0);
5400         for (i=0;i<torture_numops;i++) {
5401                 fstring fname;
5402                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5403                 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5404                         fprintf(stderr,"Failed to open %s\n", fname);
5405                         return False;
5406                 }
5407                 cli_close(cli, fnum);
5408         }
5409
5410         core_start = timeval_current();
5411
5412         matched = 0;
5413         cli_list(cli, "a*.*", 0, list_fn, &matched);
5414         printf("Matched %d\n", matched);
5415
5416         matched = 0;
5417         cli_list(cli, "b*.*", 0, list_fn, &matched);
5418         printf("Matched %d\n", matched);
5419
5420         matched = 0;
5421         cli_list(cli, "xyzabc", 0, list_fn, &matched);
5422         printf("Matched %d\n", matched);
5423
5424         printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5425
5426         srandom(0);
5427         for (i=0;i<torture_numops;i++) {
5428                 fstring fname;
5429                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5430                 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5431         }
5432
5433         if (!torture_close_connection(cli)) {
5434                 correct = False;
5435         }
5436
5437         printf("finished dirtest\n");
5438
5439         return correct;
5440 }
5441
5442 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5443                    void *state)
5444 {
5445         struct cli_state *pcli = (struct cli_state *)state;
5446         fstring fname;
5447         slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5448
5449         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5450                 return NT_STATUS_OK;
5451
5452         if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5453                 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5454                         printf("del_fn: failed to rmdir %s\n,", fname );
5455         } else {
5456                 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5457                         printf("del_fn: failed to unlink %s\n,", fname );
5458         }
5459         return NT_STATUS_OK;
5460 }
5461
5462
5463 /*
5464   sees what IOCTLs are supported
5465  */
5466 bool torture_ioctl_test(int dummy)
5467 {
5468         static struct cli_state *cli;
5469         uint16_t device, function;
5470         uint16_t fnum;
5471         const char *fname = "\\ioctl.dat";
5472         DATA_BLOB blob;
5473         NTSTATUS status;
5474
5475         if (!torture_open_connection(&cli, 0)) {
5476                 return False;
5477         }
5478
5479         printf("starting ioctl test\n");
5480
5481         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5482
5483         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5484                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
5485                 return False;
5486         }
5487
5488         status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5489         printf("ioctl device info: %s\n", nt_errstr(status));
5490
5491         status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5492         printf("ioctl job info: %s\n", nt_errstr(status));
5493
5494         for (device=0;device<0x100;device++) {
5495                 printf("ioctl test with device = 0x%x\n", device);
5496                 for (function=0;function<0x100;function++) {
5497                         uint32 code = (device<<16) | function;
5498
5499                         status = cli_raw_ioctl(cli, fnum, code, &blob);
5500
5501                         if (NT_STATUS_IS_OK(status)) {
5502                                 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5503                                        (int)blob.length);
5504                                 data_blob_free(&blob);
5505                         }
5506                 }
5507         }
5508
5509         if (!torture_close_connection(cli)) {
5510                 return False;
5511         }
5512
5513         return True;
5514 }
5515
5516
5517 /*
5518   tries varients of chkpath
5519  */
5520 bool torture_chkpath_test(int dummy)
5521 {
5522         static struct cli_state *cli;
5523         uint16_t fnum;
5524         bool ret;
5525
5526         if (!torture_open_connection(&cli, 0)) {
5527                 return False;
5528         }
5529
5530         printf("starting chkpath test\n");
5531
5532         /* cleanup from an old run */
5533         cli_rmdir(cli, "\\chkpath.dir\\dir2");
5534         cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5535         cli_rmdir(cli, "\\chkpath.dir");
5536
5537         if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
5538                 printf("mkdir1 failed : %s\n", cli_errstr(cli));
5539                 return False;
5540         }
5541
5542         if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
5543                 printf("mkdir2 failed : %s\n", cli_errstr(cli));
5544                 return False;
5545         }
5546
5547         if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5548                 printf("open1 failed (%s)\n", cli_errstr(cli));
5549                 return False;
5550         }
5551         cli_close(cli, fnum);
5552
5553         if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
5554                 printf("chkpath1 failed: %s\n", cli_errstr(cli));
5555                 ret = False;
5556         }
5557
5558         if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
5559                 printf("chkpath2 failed: %s\n", cli_errstr(cli));
5560                 ret = False;
5561         }
5562
5563         if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
5564                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath, 
5565                                   NT_STATUS_NOT_A_DIRECTORY);
5566         } else {
5567                 printf("* chkpath on a file should fail\n");
5568                 ret = False;
5569         }
5570
5571         if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5572                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile, 
5573                                   NT_STATUS_OBJECT_NAME_NOT_FOUND);
5574         } else {
5575                 printf("* chkpath on a non existant file should fail\n");
5576                 ret = False;
5577         }
5578
5579         if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5580                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath, 
5581                                   NT_STATUS_OBJECT_PATH_NOT_FOUND);
5582         } else {
5583                 printf("* chkpath on a non existent component should fail\n");
5584                 ret = False;
5585         }
5586
5587         cli_rmdir(cli, "\\chkpath.dir\\dir2");
5588         cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5589         cli_rmdir(cli, "\\chkpath.dir");
5590
5591         if (!torture_close_connection(cli)) {
5592                 return False;
5593         }
5594
5595         return ret;
5596 }
5597
5598 static bool run_eatest(int dummy)
5599 {
5600         static struct cli_state *cli;
5601         const char *fname = "\\eatest.txt";
5602         bool correct = True;
5603         uint16_t fnum;
5604         int i;
5605         size_t num_eas;
5606         struct ea_struct *ea_list = NULL;
5607         TALLOC_CTX *mem_ctx = talloc_init("eatest");
5608         NTSTATUS status;
5609
5610         printf("starting eatest\n");
5611
5612         if (!torture_open_connection(&cli, 0)) {
5613                 talloc_destroy(mem_ctx);
5614                 return False;
5615         }
5616
5617         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5618         if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5619                                    FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5620                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 
5621                                    0x4044, 0, &fnum))) {
5622                 printf("open failed - %s\n", cli_errstr(cli));
5623                 talloc_destroy(mem_ctx);
5624                 return False;
5625         }
5626
5627         for (i = 0; i < 10; i++) {
5628                 fstring ea_name, ea_val;
5629
5630                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5631                 memset(ea_val, (char)i+1, i+1);
5632                 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5633                 if (!NT_STATUS_IS_OK(status)) {
5634                         printf("ea_set of name %s failed - %s\n", ea_name,
5635                                nt_errstr(status));
5636                         talloc_destroy(mem_ctx);
5637                         return False;
5638                 }
5639         }
5640
5641         cli_close(cli, fnum);
5642         for (i = 0; i < 10; i++) {
5643                 fstring ea_name, ea_val;
5644
5645                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5646                 memset(ea_val, (char)i+1, i+1);
5647                 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5648                 if (!NT_STATUS_IS_OK(status)) {
5649                         printf("ea_set of name %s failed - %s\n", ea_name,
5650                                nt_errstr(status));
5651                         talloc_destroy(mem_ctx);
5652                         return False;
5653                 }
5654         }
5655
5656         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5657         if (!NT_STATUS_IS_OK(status)) {
5658                 printf("ea_get list failed - %s\n", nt_errstr(status));
5659                 correct = False;
5660         }
5661
5662         printf("num_eas = %d\n", (int)num_eas);
5663
5664         if (num_eas != 20) {
5665                 printf("Should be 20 EA's stored... failing.\n");
5666                 correct = False;
5667         }
5668
5669         for (i = 0; i < num_eas; i++) {
5670                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5671                 dump_data(0, ea_list[i].value.data,
5672                           ea_list[i].value.length);
5673         }
5674
5675         /* Setting EA's to zero length deletes them. Test this */
5676         printf("Now deleting all EA's - case indepenent....\n");
5677
5678 #if 1
5679         cli_set_ea_path(cli, fname, "", "", 0);
5680 #else
5681         for (i = 0; i < 20; i++) {
5682                 fstring ea_name;
5683                 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5684                 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5685                 if (!NT_STATUS_IS_OK(status)) {
5686                         printf("ea_set of name %s failed - %s\n", ea_name,
5687                                nt_errstr(status));
5688                         talloc_destroy(mem_ctx);
5689                         return False;
5690                 }
5691         }
5692 #endif
5693
5694         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5695         if (!NT_STATUS_IS_OK(status)) {
5696                 printf("ea_get list failed - %s\n", nt_errstr(status));
5697                 correct = False;
5698         }
5699
5700         printf("num_eas = %d\n", (int)num_eas);
5701         for (i = 0; i < num_eas; i++) {
5702                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5703                 dump_data(0, ea_list[i].value.data,
5704                           ea_list[i].value.length);
5705         }
5706
5707         if (num_eas != 0) {
5708                 printf("deleting EA's failed.\n");
5709                 correct = False;
5710         }
5711
5712         /* Try and delete a non existant EA. */
5713         status = cli_set_ea_path(cli, fname, "foo", "", 0);
5714         if (!NT_STATUS_IS_OK(status)) {
5715                 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5716                        nt_errstr(status));
5717                 correct = False;
5718         }
5719
5720         talloc_destroy(mem_ctx);
5721         if (!torture_close_connection(cli)) {
5722                 correct = False;
5723         }
5724
5725         return correct;
5726 }
5727
5728 static bool run_dirtest1(int dummy)
5729 {
5730         int i;
5731         static struct cli_state *cli;
5732         uint16_t fnum;
5733         int num_seen;
5734         bool correct = True;
5735
5736         printf("starting directory test\n");
5737
5738         if (!torture_open_connection(&cli, 0)) {
5739                 return False;
5740         }
5741
5742         cli_sockopt(cli, sockops);
5743
5744         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5745         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
5746         cli_rmdir(cli, "\\LISTDIR");
5747         cli_mkdir(cli, "\\LISTDIR");
5748
5749         /* Create 1000 files and 1000 directories. */
5750         for (i=0;i<1000;i++) {
5751                 fstring fname;
5752                 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5753                 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5754                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5755                         fprintf(stderr,"Failed to open %s\n", fname);
5756                         return False;
5757                 }
5758                 cli_close(cli, fnum);
5759         }
5760         for (i=0;i<1000;i++) {
5761                 fstring fname;
5762                 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5763                 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5764                         fprintf(stderr,"Failed to open %s\n", fname);
5765                         return False;
5766                 }
5767         }
5768
5769         /* Now ensure that doing an old list sees both files and directories. */
5770         num_seen = 0;
5771         cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
5772         printf("num_seen = %d\n", num_seen );
5773         /* We should see 100 files + 1000 directories + . and .. */
5774         if (num_seen != 2002)
5775                 correct = False;
5776
5777         /* Ensure if we have the "must have" bits we only see the
5778          * relevent entries.
5779          */
5780         num_seen = 0;
5781         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
5782         printf("num_seen = %d\n", num_seen );
5783         if (num_seen != 1002)
5784                 correct = False;
5785
5786         num_seen = 0;
5787         cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
5788         printf("num_seen = %d\n", num_seen );
5789         if (num_seen != 1000)
5790                 correct = False;
5791
5792         /* Delete everything. */
5793         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5794         cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
5795         cli_rmdir(cli, "\\LISTDIR");
5796
5797 #if 0
5798         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5799         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5800         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5801 #endif
5802
5803         if (!torture_close_connection(cli)) {
5804                 correct = False;
5805         }
5806
5807         printf("finished dirtest1\n");
5808
5809         return correct;
5810 }
5811
5812 static bool run_error_map_extract(int dummy) {
5813
5814         static struct cli_state *c_dos;
5815         static struct cli_state *c_nt;
5816         NTSTATUS status;
5817
5818         uint32 error;
5819
5820         uint32 flgs2, errnum;
5821         uint8 errclass;
5822
5823         NTSTATUS nt_status;
5824
5825         fstring user;
5826
5827         /* NT-Error connection */
5828
5829         if (!(c_nt = open_nbt_connection())) {
5830                 return False;
5831         }
5832
5833         c_nt->use_spnego = False;
5834
5835         status = cli_negprot(c_nt);
5836
5837         if (!NT_STATUS_IS_OK(status)) {
5838                 printf("%s rejected the NT-error negprot (%s)\n", host,
5839                        nt_errstr(status));
5840                 cli_shutdown(c_nt);
5841                 return False;
5842         }
5843
5844         if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5845                                                workgroup))) {
5846                 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5847                 return False;
5848         }
5849
5850         /* DOS-Error connection */
5851
5852         if (!(c_dos = open_nbt_connection())) {
5853                 return False;
5854         }
5855
5856         c_dos->use_spnego = False;
5857         c_dos->force_dos_errors = True;
5858
5859         status = cli_negprot(c_dos);
5860         if (!NT_STATUS_IS_OK(status)) {
5861                 printf("%s rejected the DOS-error negprot (%s)\n", host,
5862                        nt_errstr(status));
5863                 cli_shutdown(c_dos);
5864                 return False;
5865         }
5866
5867         if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5868                                                workgroup))) {
5869                 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5870                 return False;
5871         }
5872
5873         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5874                 fstr_sprintf(user, "%X", error);
5875
5876                 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user, 
5877                                                       password, strlen(password),
5878                                                       password, strlen(password),
5879                                                       workgroup))) {
5880                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
5881                 }
5882
5883                 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5884
5885                 /* Case #1: 32-bit NT errors */
5886                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5887                         nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5888                 } else {
5889                         printf("/** Dos error on NT connection! (%s) */\n", 
5890                                cli_errstr(c_nt));
5891                         nt_status = NT_STATUS(0xc0000000);
5892                 }
5893
5894                 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user, 
5895                                                       password, strlen(password),
5896                                                       password, strlen(password),
5897                                                       workgroup))) {
5898                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
5899                 }
5900                 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5901
5902                 /* Case #1: 32-bit NT errors */
5903                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5904                         printf("/** NT error on DOS connection! (%s) */\n", 
5905                                cli_errstr(c_nt));
5906                         errnum = errclass = 0;
5907                 } else {
5908                         cli_dos_error(c_dos, &errclass, &errnum);
5909                 }
5910
5911                 if (NT_STATUS_V(nt_status) != error) { 
5912                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
5913                                get_nt_error_c_code(NT_STATUS(error)), 
5914                                get_nt_error_c_code(nt_status));
5915                 }
5916
5917                 printf("\t{%s,\t%s,\t%s},\n", 
5918                        smb_dos_err_class(errclass), 
5919                        smb_dos_err_name(errclass, errnum), 
5920                        get_nt_error_c_code(NT_STATUS(error)));
5921         }
5922         return True;
5923 }
5924
5925 static bool run_sesssetup_bench(int dummy)
5926 {
5927         static struct cli_state *c;
5928         const char *fname = "\\file.dat";
5929         uint16_t fnum;
5930         NTSTATUS status;
5931         int i;
5932
5933         if (!torture_open_connection(&c, 0)) {
5934                 return false;
5935         }
5936
5937         if (!NT_STATUS_IS_OK(cli_ntcreate(
5938                         c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5939                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5940                         FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5941                 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5942                 return false;
5943         }
5944
5945         for (i=0; i<torture_numops; i++) {
5946                 status = cli_session_setup(
5947                         c, username,
5948                         password, strlen(password),
5949                         password, strlen(password),
5950                         workgroup);
5951                 if (!NT_STATUS_IS_OK(status)) {
5952                         d_printf("(%s) cli_session_setup failed: %s\n",
5953                                  __location__, nt_errstr(status));
5954                         return false;
5955                 }
5956
5957                 d_printf("\r%d   ", (int)c->vuid);
5958
5959                 status = cli_ulogoff(c);
5960                 if (!NT_STATUS_IS_OK(status)) {
5961                         d_printf("(%s) cli_ulogoff failed: %s\n",
5962                                  __location__, nt_errstr(status));
5963                         return false;
5964                 }
5965                 c->vuid = 0;
5966         }
5967
5968         return true;
5969 }
5970
5971 static bool subst_test(const char *str, const char *user, const char *domain,
5972                        uid_t uid, gid_t gid, const char *expected)
5973 {
5974         char *subst;
5975         bool result = true;
5976
5977         subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5978
5979         if (strcmp(subst, expected) != 0) {
5980                 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5981                        "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5982                        expected);
5983                 result = false;
5984         }
5985
5986         TALLOC_FREE(subst);
5987         return result;
5988 }
5989
5990 static void chain1_open_completion(struct tevent_req *req)
5991 {
5992         uint16_t fnum;
5993         NTSTATUS status;
5994         status = cli_open_recv(req, &fnum);
5995         TALLOC_FREE(req);
5996
5997         d_printf("cli_open_recv returned %s: %d\n",
5998                  nt_errstr(status),
5999                  NT_STATUS_IS_OK(status) ? fnum : -1);
6000 }
6001
6002 static void chain1_write_completion(struct tevent_req *req)
6003 {
6004         size_t written;
6005         NTSTATUS status;
6006         status = cli_write_andx_recv(req, &written);
6007         TALLOC_FREE(req);
6008
6009         d_printf("cli_write_andx_recv returned %s: %d\n",
6010                  nt_errstr(status),
6011                  NT_STATUS_IS_OK(status) ? (int)written : -1);
6012 }
6013
6014 static void chain1_close_completion(struct tevent_req *req)
6015 {
6016         NTSTATUS status;
6017         bool *done = (bool *)tevent_req_callback_data_void(req);
6018
6019         status = cli_close_recv(req);
6020         *done = true;
6021
6022         TALLOC_FREE(req);
6023
6024         d_printf("cli_close returned %s\n", nt_errstr(status));
6025 }
6026
6027 static bool run_chain1(int dummy)
6028 {
6029         struct cli_state *cli1;
6030         struct event_context *evt = event_context_init(NULL);
6031         struct tevent_req *reqs[3], *smbreqs[3];
6032         bool done = false;
6033         const char *str = "foobar";
6034         NTSTATUS status;
6035
6036         printf("starting chain1 test\n");
6037         if (!torture_open_connection(&cli1, 0)) {
6038                 return False;
6039         }
6040
6041         cli_sockopt(cli1, sockops);
6042
6043         reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
6044                                   O_CREAT|O_RDWR, 0, &smbreqs[0]);
6045         if (reqs[0] == NULL) return false;
6046         tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6047
6048
6049         reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6050                                         (uint8_t *)str, 0, strlen(str)+1,
6051                                         smbreqs, 1, &smbreqs[1]);
6052         if (reqs[1] == NULL) return false;
6053         tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6054
6055         reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6056         if (reqs[2] == NULL) return false;
6057         tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6058
6059         status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6060         if (!NT_STATUS_IS_OK(status)) {
6061                 return false;
6062         }
6063
6064         while (!done) {
6065                 event_loop_once(evt);
6066         }
6067
6068         torture_close_connection(cli1);
6069         return True;
6070 }
6071
6072 static void chain2_sesssetup_completion(struct tevent_req *req)
6073 {
6074         NTSTATUS status;
6075         status = cli_session_setup_guest_recv(req);
6076         d_printf("sesssetup returned %s\n", nt_errstr(status));
6077 }
6078
6079 static void chain2_tcon_completion(struct tevent_req *req)
6080 {
6081         bool *done = (bool *)tevent_req_callback_data_void(req);
6082         NTSTATUS status;
6083         status = cli_tcon_andx_recv(req);
6084         d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6085         *done = true;
6086 }
6087
6088 static bool run_chain2(int dummy)
6089 {
6090         struct cli_state *cli1;
6091         struct event_context *evt = event_context_init(NULL);
6092         struct tevent_req *reqs[2], *smbreqs[2];
6093         bool done = false;
6094         NTSTATUS status;
6095
6096         printf("starting chain2 test\n");
6097         status = cli_start_connection(&cli1, global_myname(), host, NULL,
6098                                       port_to_use, Undefined, 0);
6099         if (!NT_STATUS_IS_OK(status)) {
6100                 return False;
6101         }
6102
6103         cli_sockopt(cli1, sockops);
6104
6105         reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6106                                                  &smbreqs[0]);
6107         if (reqs[0] == NULL) return false;
6108         tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6109
6110         reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6111                                        "?????", NULL, 0, &smbreqs[1]);
6112         if (reqs[1] == NULL) return false;
6113         tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6114
6115         status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6116         if (!NT_STATUS_IS_OK(status)) {
6117                 return false;
6118         }
6119
6120         while (!done) {
6121                 event_loop_once(evt);
6122         }
6123
6124         torture_close_connection(cli1);
6125         return True;
6126 }
6127
6128
6129 struct torture_createdel_state {
6130         struct tevent_context *ev;
6131         struct cli_state *cli;
6132 };
6133
6134 static void torture_createdel_created(struct tevent_req *subreq);
6135 static void torture_createdel_closed(struct tevent_req *subreq);
6136
6137 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6138                                                  struct tevent_context *ev,
6139                                                  struct cli_state *cli,
6140                                                  const char *name)
6141 {
6142         struct tevent_req *req, *subreq;
6143         struct torture_createdel_state *state;
6144
6145         req = tevent_req_create(mem_ctx, &state,
6146                                 struct torture_createdel_state);
6147         if (req == NULL) {
6148                 return NULL;
6149         }
6150         state->ev = ev;
6151         state->cli = cli;
6152
6153         subreq = cli_ntcreate_send(
6154                 state, ev, cli, name, 0,
6155                 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6156                 FILE_ATTRIBUTE_NORMAL,
6157                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6158                 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6159
6160         if (tevent_req_nomem(subreq, req)) {
6161                 return tevent_req_post(req, ev);
6162         }
6163         tevent_req_set_callback(subreq, torture_createdel_created, req);
6164         return req;
6165 }
6166
6167 static void torture_createdel_created(struct tevent_req *subreq)
6168 {
6169         struct tevent_req *req = tevent_req_callback_data(
6170                 subreq, struct tevent_req);
6171         struct torture_createdel_state *state = tevent_req_data(
6172                 req, struct torture_createdel_state);
6173         NTSTATUS status;
6174         uint16_t fnum;
6175
6176         status = cli_ntcreate_recv(subreq, &fnum);
6177         TALLOC_FREE(subreq);
6178         if (!NT_STATUS_IS_OK(status)) {
6179                 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6180                            nt_errstr(status)));
6181                 tevent_req_nterror(req, status);
6182                 return;
6183         }
6184
6185         subreq = cli_close_send(state, state->ev, state->cli, fnum);
6186         if (tevent_req_nomem(subreq, req)) {
6187                 return;
6188         }
6189         tevent_req_set_callback(subreq, torture_createdel_closed, req);
6190 }
6191
6192 static void torture_createdel_closed(struct tevent_req *subreq)
6193 {
6194         struct tevent_req *req = tevent_req_callback_data(
6195                 subreq, struct tevent_req);
6196         NTSTATUS status;
6197
6198         status = cli_close_recv(subreq);
6199         if (!NT_STATUS_IS_OK(status)) {
6200                 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6201                 tevent_req_nterror(req, status);
6202                 return;
6203         }
6204         tevent_req_done(req);
6205 }
6206
6207 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6208 {
6209         return tevent_req_simple_recv_ntstatus(req);
6210 }
6211
6212 struct torture_createdels_state {
6213         struct tevent_context *ev;
6214         struct cli_state *cli;
6215         const char *base_name;
6216         int sent;
6217         int received;
6218         int num_files;
6219         struct tevent_req **reqs;
6220 };
6221
6222 static void torture_createdels_done(struct tevent_req *subreq);
6223
6224 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6225                                                   struct tevent_context *ev,
6226                                                   struct cli_state *cli,
6227                                                   const char *base_name,
6228                                                   int num_parallel,
6229                                                   int num_files)
6230 {
6231         struct tevent_req *req;
6232         struct torture_createdels_state *state;
6233         int i;
6234
6235         req = tevent_req_create(mem_ctx, &state,
6236                                 struct torture_createdels_state);
6237         if (req == NULL) {
6238                 return NULL;
6239         }
6240         state->ev = ev;
6241         state->cli = cli;
6242         state->base_name = talloc_strdup(state, base_name);
6243         if (tevent_req_nomem(state->base_name, req)) {
6244                 return tevent_req_post(req, ev);
6245         }
6246         state->num_files = MAX(num_parallel, num_files);
6247         state->sent = 0;
6248         state->received = 0;
6249
6250         state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6251         if (tevent_req_nomem(state->reqs, req)) {
6252                 return tevent_req_post(req, ev);
6253         }
6254
6255         for (i=0; i<num_parallel; i++) {
6256                 char *name;
6257
6258                 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6259                                        state->sent);
6260                 if (tevent_req_nomem(name, req)) {
6261                         return tevent_req_post(req, ev);
6262                 }
6263                 state->reqs[i] = torture_createdel_send(
6264                         state->reqs, state->ev, state->cli, name);
6265                 if (tevent_req_nomem(state->reqs[i], req)) {
6266                         return tevent_req_post(req, ev);
6267                 }
6268                 name = talloc_move(state->reqs[i], &name);
6269                 tevent_req_set_callback(state->reqs[i],
6270                                         torture_createdels_done, req);
6271                 state->sent += 1;
6272         }
6273         return req;
6274 }
6275
6276 static void torture_createdels_done(struct tevent_req *subreq)
6277 {
6278         struct tevent_req *req = tevent_req_callback_data(
6279                 subreq, struct tevent_req);
6280         struct torture_createdels_state *state = tevent_req_data(
6281                 req, struct torture_createdels_state);
6282         size_t num_parallel = talloc_array_length(state->reqs);
6283         NTSTATUS status;
6284         char *name;
6285         int i;
6286
6287         status = torture_createdel_recv(subreq);
6288         if (!NT_STATUS_IS_OK(status)){
6289                 DEBUG(10, ("torture_createdel_recv returned %s\n",
6290                            nt_errstr(status)));
6291                 TALLOC_FREE(subreq);
6292                 tevent_req_nterror(req, status);
6293                 return;
6294         }
6295
6296         for (i=0; i<num_parallel; i++) {
6297                 if (subreq == state->reqs[i]) {
6298                         break;
6299                 }
6300         }
6301         if (i == num_parallel) {
6302                 DEBUG(10, ("received something we did not send\n"));
6303                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6304                 return;
6305         }
6306         TALLOC_FREE(state->reqs[i]);
6307
6308         if (state->sent >= state->num_files) {
6309                 tevent_req_done(req);
6310                 return;
6311         }
6312
6313         name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6314                                state->sent);
6315         if (tevent_req_nomem(name, req)) {
6316                 return;
6317         }
6318         state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6319                                                 state->cli, name);
6320         if (tevent_req_nomem(state->reqs[i], req)) {
6321                 return;
6322         }
6323         name = talloc_move(state->reqs[i], &name);
6324         tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6325         state->sent += 1;
6326 }
6327
6328 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6329 {
6330         return tevent_req_simple_recv_ntstatus(req);
6331 }
6332
6333 struct swallow_notify_state {
6334         struct tevent_context *ev;
6335         struct cli_state *cli;
6336         uint16_t fnum;
6337         uint32_t completion_filter;
6338         bool recursive;
6339         bool (*fn)(uint32_t action, const char *name, void *priv);
6340         void *priv;
6341 };
6342
6343 static void swallow_notify_done(struct tevent_req *subreq);
6344
6345 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6346                                               struct tevent_context *ev,
6347                                               struct cli_state *cli,
6348                                               uint16_t fnum,
6349                                               uint32_t completion_filter,
6350                                               bool recursive,
6351                                               bool (*fn)(uint32_t action,
6352                                                          const char *name,
6353                                                          void *priv),
6354                                               void *priv)
6355 {
6356         struct tevent_req *req, *subreq;
6357         struct swallow_notify_state *state;
6358
6359         req = tevent_req_create(mem_ctx, &state,
6360                                 struct swallow_notify_state);
6361         if (req == NULL) {
6362                 return NULL;
6363         }
6364         state->ev = ev;
6365         state->cli = cli;
6366         state->fnum = fnum;
6367         state->completion_filter = completion_filter;
6368         state->recursive = recursive;
6369         state->fn = fn;
6370         state->priv = priv;
6371
6372         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6373                                  0xffff, state->completion_filter,
6374                                  state->recursive);
6375         if (tevent_req_nomem(subreq, req)) {
6376                 return tevent_req_post(req, ev);
6377         }
6378         tevent_req_set_callback(subreq, swallow_notify_done, req);
6379         return req;
6380 }
6381
6382 static void swallow_notify_done(struct tevent_req *subreq)
6383 {
6384         struct tevent_req *req = tevent_req_callback_data(
6385                 subreq, struct tevent_req);
6386         struct swallow_notify_state *state = tevent_req_data(
6387                 req, struct swallow_notify_state);
6388         NTSTATUS status;
6389         uint32_t i, num_changes;
6390         struct notify_change *changes;
6391
6392         status = cli_notify_recv(subreq, state, &num_changes, &changes);
6393         TALLOC_FREE(subreq);
6394         if (!NT_STATUS_IS_OK(status)) {
6395                 DEBUG(10, ("cli_notify_recv returned %s\n",
6396                            nt_errstr(status)));
6397                 tevent_req_nterror(req, status);
6398                 return;
6399         }
6400
6401         for (i=0; i<num_changes; i++) {
6402                 state->fn(changes[i].action, changes[i].name, state->priv);
6403         }
6404         TALLOC_FREE(changes);
6405
6406         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6407                                  0xffff, state->completion_filter,
6408                                  state->recursive);
6409         if (tevent_req_nomem(subreq, req)) {
6410                 return;
6411         }
6412         tevent_req_set_callback(subreq, swallow_notify_done, req);
6413 }
6414
6415 static bool print_notifies(uint32_t action, const char *name, void *priv)
6416 {
6417         if (DEBUGLEVEL > 5) {
6418                 d_printf("%d %s\n", (int)action, name);
6419         }
6420         return true;
6421 }
6422
6423 static void notify_bench_done(struct tevent_req *req)
6424 {
6425         int *num_finished = (int *)tevent_req_callback_data_void(req);
6426         *num_finished += 1;
6427 }
6428
6429 static bool run_notify_bench(int dummy)
6430 {
6431         const char *dname = "\\notify-bench";
6432         struct tevent_context *ev;
6433         NTSTATUS status;
6434         uint16_t dnum;
6435         struct tevent_req *req1;
6436         struct tevent_req *req2 = NULL;
6437         int i, num_unc_names;
6438         int num_finished = 0;
6439
6440         printf("starting notify-bench test\n");
6441
6442         if (use_multishare_conn) {
6443                 char **unc_list;
6444                 unc_list = file_lines_load(multishare_conn_fname,
6445                                            &num_unc_names, 0, NULL);
6446                 if (!unc_list || num_unc_names <= 0) {
6447                         d_printf("Failed to load unc names list from '%s'\n",
6448                                  multishare_conn_fname);
6449                         return false;
6450                 }
6451                 TALLOC_FREE(unc_list);
6452         } else {
6453                 num_unc_names = 1;
6454         }
6455
6456         ev = tevent_context_init(talloc_tos());
6457         if (ev == NULL) {
6458                 d_printf("tevent_context_init failed\n");
6459                 return false;
6460         }
6461
6462         for (i=0; i<num_unc_names; i++) {
6463                 struct cli_state *cli;
6464                 char *base_fname;
6465
6466                 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6467                                              dname, i);
6468                 if (base_fname == NULL) {
6469                         return false;
6470                 }
6471
6472                 if (!torture_open_connection(&cli, i)) {
6473                         return false;
6474                 }
6475
6476                 status = cli_ntcreate(cli, dname, 0,
6477                                       MAXIMUM_ALLOWED_ACCESS,
6478                                       0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6479                                       FILE_SHARE_DELETE,
6480                                       FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6481                                       &dnum);
6482
6483                 if (!NT_STATUS_IS_OK(status)) {
6484                         d_printf("Could not create %s: %s\n", dname,
6485                                  nt_errstr(status));
6486                         return false;
6487                 }
6488
6489                 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6490                                            FILE_NOTIFY_CHANGE_FILE_NAME |
6491                                            FILE_NOTIFY_CHANGE_DIR_NAME |
6492                                            FILE_NOTIFY_CHANGE_ATTRIBUTES |
6493                                            FILE_NOTIFY_CHANGE_LAST_WRITE,
6494                                            false, print_notifies, NULL);
6495                 if (req1 == NULL) {
6496                         d_printf("Could not create notify request\n");
6497                         return false;
6498                 }
6499
6500                 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6501                                                base_fname, 10, torture_numops);
6502                 if (req2 == NULL) {
6503                         d_printf("Could not create createdels request\n");
6504                         return false;
6505                 }
6506                 TALLOC_FREE(base_fname);
6507
6508                 tevent_req_set_callback(req2, notify_bench_done,
6509                                         &num_finished);
6510         }
6511
6512         while (num_finished < num_unc_names) {
6513                 int ret;
6514                 ret = tevent_loop_once(ev);
6515                 if (ret != 0) {
6516                         d_printf("tevent_loop_once failed\n");
6517                         return false;
6518                 }
6519         }
6520
6521         if (!tevent_req_poll(req2, ev)) {
6522                 d_printf("tevent_req_poll failed\n");
6523         }
6524
6525         status = torture_createdels_recv(req2);
6526         d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6527
6528         return true;
6529 }
6530
6531 static bool run_mangle1(int dummy)
6532 {
6533         struct cli_state *cli;
6534         const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6535         uint16_t fnum;
6536         fstring alt_name;
6537         NTSTATUS status;
6538         time_t change_time, access_time, write_time;
6539         SMB_OFF_T size;
6540         uint16_t mode;
6541
6542         printf("starting mangle1 test\n");
6543         if (!torture_open_connection(&cli, 0)) {
6544                 return False;
6545         }
6546
6547         cli_sockopt(cli, sockops);
6548
6549         if (!NT_STATUS_IS_OK(cli_ntcreate(
6550                         cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6551                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6552                 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
6553                 return false;
6554         }
6555         cli_close(cli, fnum);
6556
6557         status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6558         if (!NT_STATUS_IS_OK(status)) {
6559                 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6560                          nt_errstr(status));
6561                 return false;
6562         }
6563         d_printf("alt_name: %s\n", alt_name);
6564
6565         if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
6566                 d_printf("cli_open(%s) failed: %s\n", alt_name,
6567                          cli_errstr(cli));
6568                 return false;
6569         }
6570         cli_close(cli, fnum);
6571
6572         status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6573                                 &write_time, &size, &mode);
6574         if (!NT_STATUS_IS_OK(status)) {
6575                 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6576                          nt_errstr(status));
6577                 return false;
6578         }
6579
6580         return true;
6581 }
6582
6583 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6584 {
6585         size_t *to_pull = (size_t *)priv;
6586         size_t thistime = *to_pull;
6587
6588         thistime = MIN(thistime, n);
6589         if (thistime == 0) {
6590                 return 0;
6591         }
6592
6593         memset(buf, 0, thistime);
6594         *to_pull -= thistime;
6595         return thistime;
6596 }
6597
6598 static bool run_windows_write(int dummy)
6599 {
6600         struct cli_state *cli1;
6601         uint16_t fnum;
6602         int i;
6603         bool ret = false;
6604         const char *fname = "\\writetest.txt";
6605         struct timeval start_time;
6606         double seconds;
6607         double kbytes;
6608
6609         printf("starting windows_write test\n");
6610         if (!torture_open_connection(&cli1, 0)) {
6611                 return False;
6612         }
6613
6614         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6615                 printf("open failed (%s)\n", cli_errstr(cli1));
6616                 return False;
6617         }
6618
6619         cli_sockopt(cli1, sockops);
6620
6621         start_time = timeval_current();
6622
6623         for (i=0; i<torture_numops; i++) {
6624                 uint8_t c = 0;
6625                 off_t start = i * torture_blocksize;
6626                 NTSTATUS status;
6627                 size_t to_pull = torture_blocksize - 1;
6628
6629                 status = cli_writeall(cli1, fnum, 0, &c,
6630                                       start + torture_blocksize - 1, 1, NULL);
6631                 if (!NT_STATUS_IS_OK(status)) {
6632                         printf("cli_write failed: %s\n", nt_errstr(status));
6633                         goto fail;
6634                 }
6635
6636                 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6637                                   null_source, &to_pull);
6638                 if (!NT_STATUS_IS_OK(status)) {
6639                         printf("cli_push returned: %s\n", nt_errstr(status));
6640                         goto fail;
6641                 }
6642         }
6643
6644         seconds = timeval_elapsed(&start_time);
6645         kbytes = (double)torture_blocksize * torture_numops;
6646         kbytes /= 1024;
6647
6648         printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6649                (double)seconds, (int)(kbytes/seconds));
6650
6651         ret = true;
6652  fail:
6653         cli_close(cli1, fnum);
6654         cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6655         torture_close_connection(cli1);
6656         return ret;
6657 }
6658
6659 static bool run_cli_echo(int dummy)
6660 {
6661         struct cli_state *cli;
6662         NTSTATUS status;
6663
6664         printf("starting cli_echo test\n");
6665         if (!torture_open_connection(&cli, 0)) {
6666                 return false;
6667         }
6668         cli_sockopt(cli, sockops);
6669
6670         status = cli_echo(cli, 5, data_blob_const("hello", 5));
6671
6672         d_printf("cli_echo returned %s\n", nt_errstr(status));
6673
6674         torture_close_connection(cli);
6675         return NT_STATUS_IS_OK(status);
6676 }
6677
6678 static bool run_uid_regression_test(int dummy)
6679 {
6680         static struct cli_state *cli;
6681         int16_t old_vuid;
6682         int16_t old_cnum;
6683         bool correct = True;
6684         NTSTATUS status;
6685
6686         printf("starting uid regression test\n");
6687
6688         if (!torture_open_connection(&cli, 0)) {
6689                 return False;
6690         }
6691
6692         cli_sockopt(cli, sockops);
6693
6694         /* Ok - now save then logoff our current user. */
6695         old_vuid = cli->vuid;
6696
6697         status = cli_ulogoff(cli);
6698         if (!NT_STATUS_IS_OK(status)) {
6699                 d_printf("(%s) cli_ulogoff failed: %s\n",
6700                          __location__, nt_errstr(status));
6701                 correct = false;
6702                 goto out;
6703         }
6704
6705         cli->vuid = old_vuid;
6706
6707         /* Try an operation. */
6708         status = cli_mkdir(cli, "\\uid_reg_test");
6709         if (NT_STATUS_IS_OK(status)) {
6710                 d_printf("(%s) cli_mkdir succeeded\n",
6711                          __location__);
6712                 correct = false;
6713                 goto out;
6714         } else {
6715                 /* Should be bad uid. */
6716                 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6717                                 NT_STATUS_USER_SESSION_DELETED)) {
6718                         correct = false;
6719                         goto out;
6720                 }
6721         }
6722
6723         old_cnum = cli->cnum;
6724
6725         /* Now try a SMBtdis with the invald vuid set to zero. */
6726         cli->vuid = 0;
6727
6728         /* This should succeed. */
6729         status = cli_tdis(cli);
6730
6731         if (NT_STATUS_IS_OK(status)) {
6732                 d_printf("First tdis with invalid vuid should succeed.\n");
6733         } else {
6734                 d_printf("First tdis failed (%s)\n", nt_errstr(status));
6735                 correct = false;
6736                 goto out;
6737         }
6738
6739         cli->vuid = old_vuid;
6740         cli->cnum = old_cnum;
6741
6742         /* This should fail. */
6743         status = cli_tdis(cli);
6744         if (NT_STATUS_IS_OK(status)) {
6745                 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6746                 correct = false;
6747                 goto out;
6748         } else {
6749                 /* Should be bad tid. */
6750                 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6751                                 NT_STATUS_NETWORK_NAME_DELETED)) {
6752                         correct = false;
6753                         goto out;
6754                 }
6755         }
6756
6757         cli_rmdir(cli, "\\uid_reg_test");
6758
6759   out:
6760
6761         cli_shutdown(cli);
6762         return correct;
6763 }
6764
6765
6766 static const char *illegal_chars = "*\\/?<>|\":";
6767 static char force_shortname_chars[] = " +,.[];=\177";
6768
6769 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
6770                              const char *mask, void *state)
6771 {
6772         struct cli_state *pcli = (struct cli_state *)state;
6773         fstring fname;
6774         NTSTATUS status = NT_STATUS_OK;
6775
6776         slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6777
6778         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6779                 return NT_STATUS_OK;
6780
6781         if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
6782                 status = cli_rmdir(pcli, fname);
6783                 if (!NT_STATUS_IS_OK(status)) {
6784                         printf("del_fn: failed to rmdir %s\n,", fname );
6785                 }
6786         } else {
6787                 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6788                 if (!NT_STATUS_IS_OK(status)) {
6789                         printf("del_fn: failed to unlink %s\n,", fname );
6790                 }
6791         }
6792         return status;
6793 }
6794
6795 struct sn_state {
6796         int matched;
6797         int i;
6798         bool val;
6799 };
6800
6801 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
6802                               const char *name, void *state)
6803 {
6804         struct sn_state *s = (struct sn_state  *)state;
6805         int i = s->i;
6806
6807 #if 0
6808         printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6809                 i, finfo->name, finfo->short_name);
6810 #endif
6811
6812         if (strchr(force_shortname_chars, i)) {
6813                 if (!finfo->short_name[0]) {
6814                         /* Shortname not created when it should be. */
6815                         d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6816                                 __location__, finfo->name, i);
6817                         s->val = true;
6818                 }
6819         } else if (finfo->short_name[0]){
6820                 /* Shortname created when it should not be. */
6821                 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6822                         __location__, finfo->short_name, finfo->name);
6823                 s->val = true;
6824         }
6825         s->matched += 1;
6826         return NT_STATUS_OK;
6827 }
6828
6829 static bool run_shortname_test(int dummy)
6830 {
6831         static struct cli_state *cli;
6832         bool correct = True;
6833         int i;
6834         struct sn_state s;
6835         char fname[20];
6836
6837         printf("starting shortname test\n");
6838
6839         if (!torture_open_connection(&cli, 0)) {
6840                 return False;
6841         }
6842
6843         cli_sockopt(cli, sockops);
6844
6845         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6846         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
6847         cli_rmdir(cli, "\\shortname");
6848
6849         if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6850                 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6851                         __location__, cli_errstr(cli));
6852                 correct = false;
6853                 goto out;
6854         }
6855
6856         strlcpy(fname, "\\shortname\\", sizeof(fname));
6857         strlcat(fname, "test .txt", sizeof(fname));
6858
6859         s.val = false;
6860
6861         for (i = 32; i < 128; i++) {
6862                 NTSTATUS status;
6863                 uint16_t fnum = (uint16_t)-1;
6864
6865                 s.i = i;
6866
6867                 if (strchr(illegal_chars, i)) {
6868                         continue;
6869                 }
6870                 fname[15] = i;
6871
6872                 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6873                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6874                 if (!NT_STATUS_IS_OK(status)) {
6875                         d_printf("(%s) cli_nt_create of %s failed: %s\n",
6876                                 __location__, fname, cli_errstr(cli));
6877                         correct = false;
6878                         goto out;
6879                 }
6880                 cli_close(cli, fnum);
6881
6882                 s.matched = 0;
6883                 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6884                          &s);
6885                 if (s.matched != 1) {
6886                         d_printf("(%s) failed to list %s: %s\n",
6887                                 __location__, fname, cli_errstr(cli));
6888                         correct = false;
6889                         goto out;
6890                 }
6891                 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
6892                         d_printf("(%s) failed to delete %s: %s\n",
6893                                 __location__, fname, cli_errstr(cli));
6894                         correct = false;
6895                         goto out;
6896                 }
6897
6898                 if (s.val) {
6899                         correct = false;
6900                         goto out;
6901                 }
6902         }
6903
6904   out:
6905
6906         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6907         cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
6908         cli_rmdir(cli, "\\shortname");
6909         torture_close_connection(cli);
6910         return correct;
6911 }
6912
6913 static void pagedsearch_cb(struct tevent_req *req)
6914 {
6915         int rc;
6916         struct tldap_message *msg;
6917         char *dn;
6918
6919         rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6920         if (rc != TLDAP_SUCCESS) {
6921                 d_printf("tldap_search_paged_recv failed: %s\n",
6922                          tldap_err2string(rc));
6923                 return;
6924         }
6925         if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6926                 TALLOC_FREE(msg);
6927                 return;
6928         }
6929         if (!tldap_entry_dn(msg, &dn)) {
6930                 d_printf("tldap_entry_dn failed\n");
6931                 return;
6932         }
6933         d_printf("%s\n", dn);
6934         TALLOC_FREE(msg);
6935 }
6936
6937 static bool run_tldap(int dummy)
6938 {
6939         struct tldap_context *ld;
6940         int fd, rc;
6941         NTSTATUS status;
6942         struct sockaddr_storage addr;
6943         struct tevent_context *ev;
6944         struct tevent_req *req;
6945         char *basedn;
6946         const char *filter;
6947
6948         if (!resolve_name(host, &addr, 0, false)) {
6949                 d_printf("could not find host %s\n", host);
6950                 return false;
6951         }
6952         status = open_socket_out(&addr, 389, 9999, &fd);
6953         if (!NT_STATUS_IS_OK(status)) {
6954                 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6955                 return false;
6956         }
6957
6958         ld = tldap_context_create(talloc_tos(), fd);
6959         if (ld == NULL) {
6960                 close(fd);
6961                 d_printf("tldap_context_create failed\n");
6962                 return false;
6963         }
6964
6965         rc = tldap_fetch_rootdse(ld);
6966         if (rc != TLDAP_SUCCESS) {
6967                 d_printf("tldap_fetch_rootdse failed: %s\n",
6968                          tldap_errstr(talloc_tos(), ld, rc));
6969                 return false;
6970         }
6971
6972         basedn = tldap_talloc_single_attribute(
6973                 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6974         if (basedn == NULL) {
6975                 d_printf("no defaultNamingContext\n");
6976                 return false;
6977         }
6978         d_printf("defaultNamingContext: %s\n", basedn);
6979
6980         ev = tevent_context_init(talloc_tos());
6981         if (ev == NULL) {
6982                 d_printf("tevent_context_init failed\n");
6983                 return false;
6984         }
6985
6986         req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6987                                       TLDAP_SCOPE_SUB, "(objectclass=*)",
6988                                       NULL, 0, 0,
6989                                       NULL, 0, NULL, 0, 0, 0, 0, 5);
6990         if (req == NULL) {
6991                 d_printf("tldap_search_paged_send failed\n");
6992                 return false;
6993         }
6994         tevent_req_set_callback(req, pagedsearch_cb, NULL);
6995
6996         tevent_req_poll(req, ev);
6997
6998         TALLOC_FREE(req);
6999
7000         /* test search filters against rootDSE */
7001         filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7002                    "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7003
7004         rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7005                           NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7006                           talloc_tos(), NULL, NULL);
7007         if (rc != TLDAP_SUCCESS) {
7008                 d_printf("tldap_search with complex filter failed: %s\n",
7009                          tldap_errstr(talloc_tos(), ld, rc));
7010                 return false;
7011         }
7012
7013         TALLOC_FREE(ld);
7014         return true;
7015 }
7016
7017 /* Torture test to ensure no regression of :
7018 https://bugzilla.samba.org/show_bug.cgi?id=7084
7019 */
7020
7021 static bool run_dir_createtime(int dummy)
7022 {
7023         struct cli_state *cli;
7024         const char *dname = "\\testdir";
7025         const char *fname = "\\testdir\\testfile";
7026         NTSTATUS status;
7027         struct timespec create_time;
7028         struct timespec create_time1;
7029         uint16_t fnum;
7030         bool ret = false;
7031
7032         if (!torture_open_connection(&cli, 0)) {
7033                 return false;
7034         }
7035
7036         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7037         cli_rmdir(cli, dname);
7038
7039         status = cli_mkdir(cli, dname);
7040         if (!NT_STATUS_IS_OK(status)) {
7041                 printf("mkdir failed: %s\n", nt_errstr(status));
7042                 goto out;
7043         }
7044
7045         status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7046                                 NULL, NULL, NULL);
7047         if (!NT_STATUS_IS_OK(status)) {
7048                 printf("cli_qpathinfo2 returned %s\n",
7049                        nt_errstr(status));
7050                 goto out;
7051         }
7052
7053         /* Sleep 3 seconds, then create a file. */
7054         sleep(3);
7055
7056         status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7057                          DENY_NONE, &fnum);
7058         if (!NT_STATUS_IS_OK(status)) {
7059                 printf("cli_open failed: %s\n", nt_errstr(status));
7060                 goto out;
7061         }
7062
7063         status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7064                                 NULL, NULL, NULL);
7065         if (!NT_STATUS_IS_OK(status)) {
7066                 printf("cli_qpathinfo2 (2) returned %s\n",
7067                        nt_errstr(status));
7068                 goto out;
7069         }
7070
7071         if (timespec_compare(&create_time1, &create_time)) {
7072                 printf("run_dir_createtime: create time was updated (error)\n");
7073         } else {
7074                 printf("run_dir_createtime: create time was not updated (correct)\n");
7075                 ret = true;
7076         }
7077
7078   out:
7079
7080         cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7081         cli_rmdir(cli, dname);
7082         if (!torture_close_connection(cli)) {
7083                 ret = false;
7084         }
7085         return ret;
7086 }
7087
7088
7089 static bool run_streamerror(int dummy)
7090 {
7091         struct cli_state *cli;
7092         const char *dname = "\\testdir";
7093         const char *streamname =
7094                 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7095         NTSTATUS status;
7096         time_t change_time, access_time, write_time;
7097         SMB_OFF_T size;
7098         uint16_t mode, fnum;
7099         bool ret = true;
7100
7101         if (!torture_open_connection(&cli, 0)) {
7102                 return false;
7103         }
7104
7105         cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7106         cli_rmdir(cli, dname);
7107
7108         status = cli_mkdir(cli, dname);
7109         if (!NT_STATUS_IS_OK(status)) {
7110                 printf("mkdir failed: %s\n", nt_errstr(status));
7111                 return false;
7112         }
7113
7114         cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7115                       &size, &mode);
7116         status = cli_nt_error(cli);
7117
7118         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7119                 printf("pathinfo returned %s, expected "
7120                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7121                        nt_errstr(status));
7122                 ret = false;
7123         }
7124
7125         status = cli_ntcreate(cli, streamname, 0x16,
7126                               FILE_READ_DATA|FILE_READ_EA|
7127                               FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7128                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7129                               FILE_OPEN, 0, 0, &fnum);
7130
7131         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7132                 printf("ntcreate returned %s, expected "
7133                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7134                        nt_errstr(status));
7135                 ret = false;
7136         }
7137
7138
7139         cli_rmdir(cli, dname);
7140         return ret;
7141 }
7142
7143 static bool run_local_substitute(int dummy)
7144 {
7145         bool ok = true;
7146
7147         ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7148         ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7149         ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7150         ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7151         ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7152         ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7153         ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7154         ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7155
7156         /* Different captialization rules in sub_basic... */
7157
7158         ok &=  (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7159                        "blaDOM") == 0);
7160
7161         return ok;
7162 }
7163
7164 static bool run_local_base64(int dummy)
7165 {
7166         int i;
7167         bool ret = true;
7168
7169         for (i=1; i<2000; i++) {
7170                 DATA_BLOB blob1, blob2;
7171                 char *b64;
7172
7173                 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7174                 blob1.length = i;
7175                 generate_random_buffer(blob1.data, blob1.length);
7176
7177                 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7178                 if (b64 == NULL) {
7179                         d_fprintf(stderr, "base64_encode_data_blob failed "
7180                                   "for %d bytes\n", i);
7181                         ret = false;
7182                 }
7183                 blob2 = base64_decode_data_blob(b64);
7184                 TALLOC_FREE(b64);
7185
7186                 if (data_blob_cmp(&blob1, &blob2)) {
7187                         d_fprintf(stderr, "data_blob_cmp failed for %d "
7188                                   "bytes\n", i);
7189                         ret = false;
7190                 }
7191                 TALLOC_FREE(blob1.data);
7192                 data_blob_free(&blob2);
7193         }
7194         return ret;
7195 }
7196
7197 static bool run_local_gencache(int dummy)
7198 {
7199         char *val;
7200         time_t tm;
7201         DATA_BLOB blob;
7202
7203         if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7204                 d_printf("%s: gencache_set() failed\n", __location__);
7205                 return False;
7206         }
7207
7208         if (!gencache_get("foo", NULL, NULL)) {
7209                 d_printf("%s: gencache_get() failed\n", __location__);
7210                 return False;
7211         }
7212
7213         if (!gencache_get("foo", &val, &tm)) {
7214                 d_printf("%s: gencache_get() failed\n", __location__);
7215                 return False;
7216         }
7217
7218         if (strcmp(val, "bar") != 0) {
7219                 d_printf("%s: gencache_get() returned %s, expected %s\n",
7220                          __location__, val, "bar");
7221                 SAFE_FREE(val);
7222                 return False;
7223         }
7224
7225         SAFE_FREE(val);
7226
7227         if (!gencache_del("foo")) {
7228                 d_printf("%s: gencache_del() failed\n", __location__);
7229                 return False;
7230         }
7231         if (gencache_del("foo")) {
7232                 d_printf("%s: second gencache_del() succeeded\n",
7233                          __location__);
7234                 return False;
7235         }
7236
7237         if (gencache_get("foo", &val, &tm)) {
7238                 d_printf("%s: gencache_get() on deleted entry "
7239                          "succeeded\n", __location__);
7240                 return False;
7241         }
7242
7243         blob = data_blob_string_const_null("bar");
7244         tm = time(NULL) + 60;
7245
7246         if (!gencache_set_data_blob("foo", &blob, tm)) {
7247                 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7248                 return False;
7249         }
7250
7251         if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7252                 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7253                 return False;
7254         }
7255
7256         if (strcmp((const char *)blob.data, "bar") != 0) {
7257                 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7258                          __location__, (const char *)blob.data, "bar");
7259                 data_blob_free(&blob);
7260                 return False;
7261         }
7262
7263         data_blob_free(&blob);
7264
7265         if (!gencache_del("foo")) {
7266                 d_printf("%s: gencache_del() failed\n", __location__);
7267                 return False;
7268         }
7269         if (gencache_del("foo")) {
7270                 d_printf("%s: second gencache_del() succeeded\n",
7271                          __location__);
7272                 return False;
7273         }
7274
7275         if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7276                 d_printf("%s: gencache_get_data_blob() on deleted entry "
7277                          "succeeded\n", __location__);
7278                 return False;
7279         }
7280
7281         return True;
7282 }
7283
7284 static bool rbt_testval(struct db_context *db, const char *key,
7285                         const char *value)
7286 {
7287         struct db_record *rec;
7288         TDB_DATA data = string_tdb_data(value);
7289         bool ret = false;
7290         NTSTATUS status;
7291
7292         rec = db->fetch_locked(db, db, string_tdb_data(key));
7293         if (rec == NULL) {
7294                 d_fprintf(stderr, "fetch_locked failed\n");
7295                 goto done;
7296         }
7297         status = rec->store(rec, data, 0);
7298         if (!NT_STATUS_IS_OK(status)) {
7299                 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7300                 goto done;
7301         }
7302         TALLOC_FREE(rec);
7303
7304         rec = db->fetch_locked(db, db, string_tdb_data(key));
7305         if (rec == NULL) {
7306                 d_fprintf(stderr, "second fetch_locked failed\n");
7307                 goto done;
7308         }
7309         if ((rec->value.dsize != data.dsize)
7310             || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7311                 d_fprintf(stderr, "Got wrong data back\n");
7312                 goto done;
7313         }
7314
7315         ret = true;
7316  done:
7317         TALLOC_FREE(rec);
7318         return ret;
7319 }
7320
7321 static bool run_local_rbtree(int dummy)
7322 {
7323         struct db_context *db;
7324         bool ret = false;
7325         int i;
7326
7327         db = db_open_rbt(NULL);
7328
7329         if (db == NULL) {
7330                 d_fprintf(stderr, "db_open_rbt failed\n");
7331                 return false;
7332         }
7333
7334         for (i=0; i<1000; i++) {
7335                 char *key, *value;
7336
7337                 if (asprintf(&key, "key%ld", random()) == -1) {
7338                         goto done;
7339                 }
7340                 if (asprintf(&value, "value%ld", random()) == -1) {
7341                         SAFE_FREE(key);
7342                         goto done;
7343                 }
7344
7345                 if (!rbt_testval(db, key, value)) {
7346                         SAFE_FREE(key);
7347                         SAFE_FREE(value);
7348                         goto done;
7349                 }
7350
7351                 SAFE_FREE(value);
7352                 if (asprintf(&value, "value%ld", random()) == -1) {
7353                         SAFE_FREE(key);
7354                         goto done;
7355                 }
7356
7357                 if (!rbt_testval(db, key, value)) {
7358                         SAFE_FREE(key);
7359                         SAFE_FREE(value);
7360                         goto done;
7361                 }
7362
7363                 SAFE_FREE(key);
7364                 SAFE_FREE(value);
7365         }
7366
7367         ret = true;
7368
7369  done:
7370         TALLOC_FREE(db);
7371         return ret;
7372 }
7373
7374
7375 /*
7376   local test for character set functions
7377
7378   This is a very simple test for the functionality in convert_string_error()
7379  */
7380 static bool run_local_convert_string(int dummy)
7381 {
7382         TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7383         const char *test_strings[2] = { "March", "M\303\244rz" };
7384         char dst[7];
7385         int i;
7386
7387         for (i=0; i<2; i++) {
7388                 const char *str = test_strings[i];
7389                 int len = strlen(str);
7390                 size_t converted_size;
7391                 bool ret;
7392
7393                 memset(dst, 'X', sizeof(dst));
7394
7395                 /* first try with real source length */
7396                 ret = convert_string_error(CH_UNIX, CH_UTF8,
7397                                            str, len,
7398                                            dst, sizeof(dst),
7399                                            &converted_size);
7400                 if (ret != true) {
7401                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7402                         goto failed;
7403                 }
7404
7405                 if (converted_size != len) {
7406                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7407                                   str, len, (int)converted_size);
7408                         goto failed;
7409                 }
7410
7411                 if (strncmp(str, dst, converted_size) != 0) {
7412                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7413                         goto failed;
7414                 }
7415
7416                 if (strlen(str) != converted_size) {
7417                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7418                                   (int)strlen(str), (int)converted_size);
7419                         goto failed;
7420                 }
7421
7422                 if (dst[converted_size] != 'X') {
7423                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7424                         goto failed;
7425                 }
7426
7427                 /* now with srclen==-1, this causes the nul to be
7428                  * converted too */
7429                 ret = convert_string_error(CH_UNIX, CH_UTF8,
7430                                            str, -1,
7431                                            dst, sizeof(dst),
7432                                            &converted_size);
7433                 if (ret != true) {
7434                         d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7435                         goto failed;
7436                 }
7437
7438                 if (converted_size != len+1) {
7439                         d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7440                                   str, len, (int)converted_size);
7441                         goto failed;
7442                 }
7443
7444                 if (strncmp(str, dst, converted_size) != 0) {
7445                         d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7446                         goto failed;
7447                 }
7448
7449                 if (len+1 != converted_size) {
7450                         d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7451                                   len+1, (int)converted_size);
7452                         goto failed;
7453                 }
7454
7455                 if (dst[converted_size] != 'X') {
7456                         d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7457                         goto failed;
7458                 }
7459
7460         }
7461
7462
7463         TALLOC_FREE(tmp_ctx);
7464         return true;
7465 failed:
7466         TALLOC_FREE(tmp_ctx);
7467         return false;
7468 }
7469
7470
7471 struct talloc_dict_test {
7472         int content;
7473 };
7474
7475 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7476 {
7477         int *count = (int *)priv;
7478         *count += 1;
7479         return 0;
7480 }
7481
7482 static bool run_local_talloc_dict(int dummy)
7483 {
7484         struct talloc_dict *dict;
7485         struct talloc_dict_test *t;
7486         int key, count;
7487
7488         dict = talloc_dict_init(talloc_tos());
7489         if (dict == NULL) {
7490                 return false;
7491         }
7492
7493         t = talloc(talloc_tos(), struct talloc_dict_test);
7494         if (t == NULL) {
7495                 return false;
7496         }
7497
7498         key = 1;
7499         t->content = 1;
7500         if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7501                 return false;
7502         }
7503
7504         count = 0;
7505         if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7506                 return false;
7507         }
7508
7509         if (count != 1) {
7510                 return false;
7511         }
7512
7513         TALLOC_FREE(dict);
7514
7515         return true;
7516 }
7517
7518 static bool run_local_string_to_sid(int dummy) {
7519         struct dom_sid sid;
7520
7521         if (string_to_sid(&sid, "S--1-5-32-545")) {
7522                 printf("allowing S--1-5-32-545\n");
7523                 return false;
7524         }
7525         if (string_to_sid(&sid, "S-1-5-32-+545")) {
7526                 printf("allowing S-1-5-32-+545\n");
7527                 return false;
7528         }
7529         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")) {
7530                 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7531                 return false;
7532         }
7533         if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7534                 printf("allowing S-1-5-32-545-abc\n");
7535                 return false;
7536         }
7537         if (!string_to_sid(&sid, "S-1-5-32-545")) {
7538                 printf("could not parse S-1-5-32-545\n");
7539                 return false;
7540         }
7541         if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7542                 printf("mis-parsed S-1-5-32-545 as %s\n",
7543                        sid_string_tos(&sid));
7544                 return false;
7545         }
7546         return true;
7547 }
7548
7549 static bool run_local_binary_to_sid(int dummy) {
7550         struct dom_sid *sid = talloc(NULL, struct dom_sid);
7551         static const char good_binary_sid[] = {
7552                 0x1, /* revision number */
7553                 15, /* num auths */
7554                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7555                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7556                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7557                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7558                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7559                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7560                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7561                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7562                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7563                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7564                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7565                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7566                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7567                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7568                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7569                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7570         };
7571
7572         static const char long_binary_sid[] = {
7573                 0x1, /* revision number */
7574                 15, /* num auths */
7575                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7576                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7577                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7578                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7579                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7580                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7581                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7582                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7583                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7584                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7585                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7586                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7587                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7588                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7589                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7590                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7591                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7592                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7593                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7594         };
7595
7596         static const char long_binary_sid2[] = {
7597                 0x1, /* revision number */
7598                 32, /* num auths */
7599                 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7600                 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7601                 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7602                 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7603                 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7604                 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7605                 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7606                 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7607                 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7608                 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7609                 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7610                 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7611                 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7612                 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7613                 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7614                 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7615                 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7616                 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7617                 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7618                 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7619                 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7620                 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7621                 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7622                 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7623                 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7624                 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7625                 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7626                 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7627                 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7628                 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7629                 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7630                 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7631                 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7632         };
7633
7634         if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7635                 return false;
7636         }
7637         if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7638                 return false;
7639         }
7640         if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7641                 return false;
7642         }
7643         return true;
7644 }
7645
7646 /* Split a path name into filename and stream name components. Canonicalise
7647  * such that an implicit $DATA token is always explicit.
7648  *
7649  * The "specification" of this function can be found in the
7650  * run_local_stream_name() function in torture.c, I've tried those
7651  * combinations against a W2k3 server.
7652  */
7653
7654 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7655                                        char **pbase, char **pstream)
7656 {
7657         char *base = NULL;
7658         char *stream = NULL;
7659         char *sname; /* stream name */
7660         const char *stype; /* stream type */
7661
7662         DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7663
7664         sname = strchr_m(fname, ':');
7665
7666         if (lp_posix_pathnames() || (sname == NULL)) {
7667                 if (pbase != NULL) {
7668                         base = talloc_strdup(mem_ctx, fname);
7669                         NT_STATUS_HAVE_NO_MEMORY(base);
7670                 }
7671                 goto done;
7672         }
7673
7674         if (pbase != NULL) {
7675                 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7676                 NT_STATUS_HAVE_NO_MEMORY(base);
7677         }
7678
7679         sname += 1;
7680
7681         stype = strchr_m(sname, ':');
7682
7683         if (stype == NULL) {
7684                 sname = talloc_strdup(mem_ctx, sname);
7685                 stype = "$DATA";
7686         }
7687         else {
7688                 if (StrCaseCmp(stype, ":$DATA") != 0) {
7689                         /*
7690                          * If there is an explicit stream type, so far we only
7691                          * allow $DATA. Is there anything else allowed? -- vl
7692                          */
7693                         DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7694                         TALLOC_FREE(base);
7695                         return NT_STATUS_OBJECT_NAME_INVALID;
7696                 }
7697                 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7698                 stype += 1;
7699         }
7700
7701         if (sname == NULL) {
7702                 TALLOC_FREE(base);
7703                 return NT_STATUS_NO_MEMORY;
7704         }
7705
7706         if (sname[0] == '\0') {
7707                 /*
7708                  * no stream name, so no stream
7709                  */
7710                 goto done;
7711         }
7712
7713         if (pstream != NULL) {
7714                 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7715                 if (stream == NULL) {
7716                         TALLOC_FREE(sname);
7717                         TALLOC_FREE(base);
7718                         return NT_STATUS_NO_MEMORY;
7719                 }
7720                 /*
7721                  * upper-case the type field
7722                  */
7723                 strupper_m(strchr_m(stream, ':')+1);
7724         }
7725
7726  done:
7727         if (pbase != NULL) {
7728                 *pbase = base;
7729         }
7730         if (pstream != NULL) {
7731                 *pstream = stream;
7732         }
7733         return NT_STATUS_OK;
7734 }
7735
7736 static bool test_stream_name(const char *fname, const char *expected_base,
7737                              const char *expected_stream,
7738                              NTSTATUS expected_status)
7739 {
7740         NTSTATUS status;
7741         char *base = NULL;
7742         char *stream = NULL;
7743
7744         status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
7745         if (!NT_STATUS_EQUAL(status, expected_status)) {
7746                 goto error;
7747         }
7748
7749         if (!NT_STATUS_IS_OK(status)) {
7750                 return true;
7751         }
7752
7753         if (base == NULL) goto error;
7754
7755         if (strcmp(expected_base, base) != 0) goto error;
7756
7757         if ((expected_stream != NULL) && (stream == NULL)) goto error;
7758         if ((expected_stream == NULL) && (stream != NULL)) goto error;
7759
7760         if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
7761                 goto error;
7762
7763         TALLOC_FREE(base);
7764         TALLOC_FREE(stream);
7765         return true;
7766
7767  error:
7768         d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
7769                   fname, expected_base ? expected_base : "<NULL>",
7770                   expected_stream ? expected_stream : "<NULL>",
7771                   nt_errstr(expected_status));
7772         d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
7773                   base ? base : "<NULL>", stream ? stream : "<NULL>",
7774                   nt_errstr(status));
7775         TALLOC_FREE(base);
7776         TALLOC_FREE(stream);
7777         return false;
7778 }
7779
7780 static bool run_local_stream_name(int dummy)
7781 {
7782         bool ret = true;
7783
7784         ret &= test_stream_name(
7785                 "bla", "bla", NULL, NT_STATUS_OK);
7786         ret &= test_stream_name(
7787                 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
7788         ret &= test_stream_name(
7789                 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7790         ret &= test_stream_name(
7791                 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
7792         ret &= test_stream_name(
7793                 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7794         ret &= test_stream_name(
7795                 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
7796         ret &= test_stream_name(
7797                 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7798         ret &= test_stream_name(
7799                 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7800
7801         return ret;
7802 }
7803
7804 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7805 {
7806         if (a.length != b.length) {
7807                 printf("a.length=%d != b.length=%d\n",
7808                        (int)a.length, (int)b.length);
7809                 return false;
7810         }
7811         if (memcmp(a.data, b.data, a.length) != 0) {
7812                 printf("a.data and b.data differ\n");
7813                 return false;
7814         }
7815         return true;
7816 }
7817
7818 static bool run_local_memcache(int dummy)
7819 {
7820         struct memcache *cache;
7821         DATA_BLOB k1, k2;
7822         DATA_BLOB d1, d2, d3;
7823         DATA_BLOB v1, v2, v3;
7824
7825         TALLOC_CTX *mem_ctx;
7826         char *str1, *str2;
7827         size_t size1, size2;
7828         bool ret = false;
7829
7830         cache = memcache_init(NULL, 100);
7831
7832         if (cache == NULL) {
7833                 printf("memcache_init failed\n");
7834                 return false;
7835         }
7836
7837         d1 = data_blob_const("d1", 2);
7838         d2 = data_blob_const("d2", 2);
7839         d3 = data_blob_const("d3", 2);
7840
7841         k1 = data_blob_const("d1", 2);
7842         k2 = data_blob_const("d2", 2);
7843
7844         memcache_add(cache, STAT_CACHE, k1, d1);
7845         memcache_add(cache, GETWD_CACHE, k2, d2);
7846
7847         if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7848                 printf("could not find k1\n");
7849                 return false;
7850         }
7851         if (!data_blob_equal(d1, v1)) {
7852                 return false;
7853         }
7854
7855         if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7856                 printf("could not find k2\n");
7857                 return false;
7858         }
7859         if (!data_blob_equal(d2, v2)) {
7860                 return false;
7861         }
7862
7863         memcache_add(cache, STAT_CACHE, k1, d3);
7864
7865         if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7866                 printf("could not find replaced k1\n");
7867                 return false;
7868         }
7869         if (!data_blob_equal(d3, v3)) {
7870                 return false;
7871         }
7872
7873         memcache_add(cache, GETWD_CACHE, k1, d1);
7874
7875         if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7876                 printf("Did find k2, should have been purged\n");
7877                 return false;
7878         }
7879
7880         TALLOC_FREE(cache);
7881
7882         cache = memcache_init(NULL, 0);
7883
7884         mem_ctx = talloc_init("foo");
7885
7886         str1 = talloc_strdup(mem_ctx, "string1");
7887         str2 = talloc_strdup(mem_ctx, "string2");
7888
7889         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7890                             data_blob_string_const("torture"), &str1);
7891         size1 = talloc_total_size(cache);
7892
7893         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7894                             data_blob_string_const("torture"), &str2);
7895         size2 = talloc_total_size(cache);
7896
7897         printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7898
7899         if (size2 > size1) {
7900                 printf("memcache leaks memory!\n");
7901                 goto fail;
7902         }
7903
7904         ret = true;
7905  fail:
7906         TALLOC_FREE(cache);
7907         return ret;
7908 }
7909
7910 static void wbclient_done(struct tevent_req *req)
7911 {
7912         wbcErr wbc_err;
7913         struct winbindd_response *wb_resp;
7914         int *i = (int *)tevent_req_callback_data_void(req);
7915
7916         wbc_err = wb_trans_recv(req, req, &wb_resp);
7917         TALLOC_FREE(req);
7918         *i += 1;
7919         d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7920 }
7921
7922 static bool run_local_wbclient(int dummy)
7923 {
7924         struct event_context *ev;
7925         struct wb_context **wb_ctx;
7926         struct winbindd_request wb_req;
7927         bool result = false;
7928         int i, j;
7929
7930         BlockSignals(True, SIGPIPE);
7931
7932         ev = tevent_context_init_byname(talloc_tos(), "epoll");
7933         if (ev == NULL) {
7934                 goto fail;
7935         }
7936
7937         wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7938         if (wb_ctx == NULL) {
7939                 goto fail;
7940         }
7941
7942         ZERO_STRUCT(wb_req);
7943         wb_req.cmd = WINBINDD_PING;
7944
7945         d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7946
7947         for (i=0; i<nprocs; i++) {
7948                 wb_ctx[i] = wb_context_init(ev, NULL);
7949                 if (wb_ctx[i] == NULL) {
7950                         goto fail;
7951                 }
7952                 for (j=0; j<torture_numops; j++) {
7953                         struct tevent_req *req;
7954                         req = wb_trans_send(ev, ev, wb_ctx[i],
7955                                             (j % 2) == 0, &wb_req);
7956                         if (req == NULL) {
7957                                 goto fail;
7958                         }
7959                         tevent_req_set_callback(req, wbclient_done, &i);
7960                 }
7961         }
7962
7963         i = 0;
7964
7965         while (i < nprocs * torture_numops) {
7966                 event_loop_once(ev);
7967         }
7968
7969         result = true;
7970  fail:
7971         TALLOC_FREE(ev);
7972         return result;
7973 }
7974
7975 static void getaddrinfo_finished(struct tevent_req *req)
7976 {
7977         char *name = (char *)tevent_req_callback_data_void(req);
7978         struct addrinfo *ainfo;
7979         int res;
7980
7981         res = getaddrinfo_recv(req, &ainfo);
7982         if (res != 0) {
7983                 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7984                 return;
7985         }
7986         d_printf("gai(%s) succeeded\n", name);
7987         freeaddrinfo(ainfo);
7988 }
7989
7990 static bool run_getaddrinfo_send(int dummy)
7991 {
7992         TALLOC_CTX *frame = talloc_stackframe();
7993         struct fncall_context *ctx;
7994         struct tevent_context *ev;
7995         bool result = false;
7996         const char *names[4] = { "www.samba.org", "notfound.samba.org",
7997                                  "www.slashdot.org", "heise.de" };
7998         struct tevent_req *reqs[4];
7999         int i;
8000
8001         ev = event_context_init(frame);
8002         if (ev == NULL) {
8003                 goto fail;
8004         }
8005
8006         ctx = fncall_context_init(frame, 4);
8007
8008         for (i=0; i<ARRAY_SIZE(names); i++) {
8009                 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8010                                            NULL);
8011                 if (reqs[i] == NULL) {
8012                         goto fail;
8013                 }
8014                 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8015                                         (void *)names[i]);
8016         }
8017
8018         for (i=0; i<ARRAY_SIZE(reqs); i++) {
8019                 tevent_loop_once(ev);
8020         }
8021
8022         result = true;
8023 fail:
8024         TALLOC_FREE(frame);
8025         return result;
8026 }
8027
8028 static bool dbtrans_inc(struct db_context *db)
8029 {
8030         struct db_record *rec;
8031         uint32_t *val;
8032         bool ret = false;
8033         NTSTATUS status;
8034
8035         rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8036         if (rec == NULL) {
8037                 printf(__location__ "fetch_lock failed\n");
8038                 return false;
8039         }
8040
8041         if (rec->value.dsize != sizeof(uint32_t)) {
8042                 printf(__location__ "value.dsize = %d\n",
8043                        (int)rec->value.dsize);
8044                 goto fail;
8045         }
8046
8047         val = (uint32_t *)rec->value.dptr;
8048         *val += 1;
8049
8050         status = rec->store(rec, make_tdb_data((uint8_t *)val,
8051                                                sizeof(uint32_t)),
8052                             0);
8053         if (!NT_STATUS_IS_OK(status)) {
8054                 printf(__location__ "store failed: %s\n",
8055                        nt_errstr(status));
8056                 goto fail;
8057         }
8058
8059         ret = true;
8060 fail:
8061         TALLOC_FREE(rec);
8062         return ret;
8063 }
8064
8065 static bool run_local_dbtrans(int dummy)
8066 {
8067         struct db_context *db;
8068         struct db_record *rec;
8069         NTSTATUS status;
8070         uint32_t initial;
8071         int res;
8072
8073         db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8074                      O_RDWR|O_CREAT, 0600);
8075         if (db == NULL) {
8076                 printf("Could not open transtest.db\n");
8077                 return false;
8078         }
8079
8080         res = db->transaction_start(db);
8081         if (res == -1) {
8082                 printf(__location__ "transaction_start failed\n");
8083                 return false;
8084         }
8085
8086         rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8087         if (rec == NULL) {
8088                 printf(__location__ "fetch_lock failed\n");
8089                 return false;
8090         }
8091
8092         if (rec->value.dptr == NULL) {
8093                 initial = 0;
8094                 status = rec->store(
8095                         rec, make_tdb_data((uint8_t *)&initial,
8096                                            sizeof(initial)),
8097                         0);
8098                 if (!NT_STATUS_IS_OK(status)) {
8099                         printf(__location__ "store returned %s\n",
8100                                nt_errstr(status));
8101                         return false;
8102                 }
8103         }
8104
8105         TALLOC_FREE(rec);
8106
8107         res = db->transaction_commit(db);
8108         if (res == -1) {
8109                 printf(__location__ "transaction_commit failed\n");
8110                 return false;
8111         }
8112
8113         while (true) {
8114                 uint32_t val, val2;
8115                 int i;
8116
8117                 res = db->transaction_start(db);
8118                 if (res == -1) {
8119                         printf(__location__ "transaction_start failed\n");
8120                         break;
8121                 }
8122
8123                 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
8124                         printf(__location__ "dbwrap_fetch_uint32 failed\n");
8125                         break;
8126                 }
8127
8128                 for (i=0; i<10; i++) {
8129                         if (!dbtrans_inc(db)) {
8130                                 return false;
8131                         }
8132                 }
8133
8134                 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
8135                         printf(__location__ "dbwrap_fetch_uint32 failed\n");
8136                         break;
8137                 }
8138
8139                 if (val2 != val + 10) {
8140                         printf(__location__ "val=%d, val2=%d\n",
8141                                (int)val, (int)val2);
8142                         break;
8143                 }
8144
8145                 printf("val2=%d\r", val2);
8146
8147                 res = db->transaction_commit(db);
8148                 if (res == -1) {
8149                         printf(__location__ "transaction_commit failed\n");
8150                         break;
8151                 }
8152         }
8153
8154         TALLOC_FREE(db);
8155         return true;
8156 }
8157
8158 /*
8159  * Just a dummy test to be run under a debugger. There's no real way
8160  * to inspect the tevent_select specific function from outside of
8161  * tevent_select.c.
8162  */
8163
8164 static bool run_local_tevent_select(int dummy)
8165 {
8166         struct tevent_context *ev;
8167         struct tevent_fd *fd1, *fd2;
8168         bool result = false;
8169
8170         ev = tevent_context_init_byname(NULL, "select");
8171         if (ev == NULL) {
8172                 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8173                 goto fail;
8174         }
8175
8176         fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8177         if (fd1 == NULL) {
8178                 d_fprintf(stderr, "tevent_add_fd failed\n");
8179                 goto fail;
8180         }
8181         fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8182         if (fd2 == NULL) {
8183                 d_fprintf(stderr, "tevent_add_fd failed\n");
8184                 goto fail;
8185         }
8186         TALLOC_FREE(fd2);
8187
8188         fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8189         if (fd2 == NULL) {
8190                 d_fprintf(stderr, "tevent_add_fd failed\n");
8191                 goto fail;
8192         }
8193
8194         result = true;
8195 fail:
8196         TALLOC_FREE(ev);
8197         return result;
8198 }
8199
8200 static double create_procs(bool (*fn)(int), bool *result)
8201 {
8202         int i, status;
8203         volatile pid_t *child_status;
8204         volatile bool *child_status_out;
8205         int synccount;
8206         int tries = 8;
8207         struct timeval start;
8208
8209         synccount = 0;
8210
8211         child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8212         if (!child_status) {
8213                 printf("Failed to setup shared memory\n");
8214                 return -1;
8215         }
8216
8217         child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8218         if (!child_status_out) {
8219                 printf("Failed to setup result status shared memory\n");
8220                 return -1;
8221         }
8222
8223         for (i = 0; i < nprocs; i++) {
8224                 child_status[i] = 0;
8225                 child_status_out[i] = True;
8226         }
8227
8228         start = timeval_current();
8229
8230         for (i=0;i<nprocs;i++) {
8231                 procnum = i;
8232                 if (fork() == 0) {
8233                         pid_t mypid = getpid();
8234                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8235
8236                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
8237
8238                         while (1) {
8239                                 if (torture_open_connection(&current_cli, i)) break;
8240                                 if (tries-- == 0) {
8241                                         printf("pid %d failed to start\n", (int)getpid());
8242                                         _exit(1);
8243                                 }
8244                                 smb_msleep(10); 
8245                         }
8246
8247                         child_status[i] = getpid();
8248
8249                         while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8250
8251                         child_status_out[i] = fn(i);
8252                         _exit(0);
8253                 }
8254         }
8255
8256         do {
8257                 synccount = 0;
8258                 for (i=0;i<nprocs;i++) {
8259                         if (child_status[i]) synccount++;
8260                 }
8261                 if (synccount == nprocs) break;
8262                 smb_msleep(10);
8263         } while (timeval_elapsed(&start) < 30);
8264
8265         if (synccount != nprocs) {
8266                 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8267                 *result = False;
8268                 return timeval_elapsed(&start);
8269         }
8270
8271         /* start the client load */
8272         start = timeval_current();
8273
8274         for (i=0;i<nprocs;i++) {
8275                 child_status[i] = 0;
8276         }
8277
8278         printf("%d clients started\n", nprocs);
8279
8280         for (i=0;i<nprocs;i++) {
8281                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8282         }
8283
8284         printf("\n");
8285
8286         for (i=0;i<nprocs;i++) {
8287                 if (!child_status_out[i]) {
8288                         *result = False;
8289                 }
8290         }
8291         return timeval_elapsed(&start);
8292 }
8293
8294 #define FLAG_MULTIPROC 1
8295
8296 static struct {
8297         const char *name;
8298         bool (*fn)(int);
8299         unsigned flags;
8300 } torture_ops[] = {
8301         {"FDPASS", run_fdpasstest, 0},
8302         {"LOCK1",  run_locktest1,  0},
8303         {"LOCK2",  run_locktest2,  0},
8304         {"LOCK3",  run_locktest3,  0},
8305         {"LOCK4",  run_locktest4,  0},
8306         {"LOCK5",  run_locktest5,  0},
8307         {"LOCK6",  run_locktest6,  0},
8308         {"LOCK7",  run_locktest7,  0},
8309         {"LOCK8",  run_locktest8,  0},
8310         {"LOCK9",  run_locktest9,  0},
8311         {"UNLINK", run_unlinktest, 0},
8312         {"BROWSE", run_browsetest, 0},
8313         {"ATTR",   run_attrtest,   0},
8314         {"TRANS2", run_trans2test, 0},
8315         {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8316         {"TORTURE",run_torture,    FLAG_MULTIPROC},
8317         {"RANDOMIPC", run_randomipc, 0},
8318         {"NEGNOWAIT", run_negprot_nowait, 0},
8319         {"NBENCH",  run_nbench, 0},
8320         {"NBENCH2", run_nbench2, 0},
8321         {"OPLOCK1",  run_oplock1, 0},
8322         {"OPLOCK2",  run_oplock2, 0},
8323         {"OPLOCK3",  run_oplock3, 0},
8324         {"OPLOCK4",  run_oplock4, 0},
8325         {"DIR",  run_dirtest, 0},
8326         {"DIR1",  run_dirtest1, 0},
8327         {"DIR-CREATETIME",  run_dir_createtime, 0},
8328         {"DENY1",  torture_denytest1, 0},
8329         {"DENY2",  torture_denytest2, 0},
8330         {"TCON",  run_tcon_test, 0},
8331         {"TCONDEV",  run_tcon_devtype_test, 0},
8332         {"RW1",  run_readwritetest, 0},
8333         {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
8334         {"RW3",  run_readwritelarge, 0},
8335         {"RW-SIGNING",  run_readwritelarge_signtest, 0},
8336         {"OPEN", run_opentest, 0},
8337         {"POSIX", run_simple_posix_open_test, 0},
8338         {"POSIX-APPEND", run_posix_append, 0},
8339         {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8340         {"ASYNC-ECHO", run_async_echo, 0},
8341         { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8342         { "SHORTNAME-TEST", run_shortname_test, 0},
8343         { "ADDRCHANGE", run_addrchange, 0},
8344 #if 1
8345         {"OPENATTR", run_openattrtest, 0},
8346 #endif
8347         {"XCOPY", run_xcopy, 0},
8348         {"RENAME", run_rename, 0},
8349         {"DELETE", run_deletetest, 0},
8350         {"DELETE-LN", run_deletetest_ln, 0},
8351         {"PROPERTIES", run_properties, 0},
8352         {"MANGLE", torture_mangle, 0},
8353         {"MANGLE1", run_mangle1, 0},
8354         {"W2K", run_w2ktest, 0},
8355         {"TRANS2SCAN", torture_trans2_scan, 0},
8356         {"NTTRANSSCAN", torture_nttrans_scan, 0},
8357         {"UTABLE", torture_utable, 0},
8358         {"CASETABLE", torture_casetable, 0},
8359         {"ERRMAPEXTRACT", run_error_map_extract, 0},
8360         {"PIPE_NUMBER", run_pipe_number, 0},
8361         {"TCON2",  run_tcon2_test, 0},
8362         {"IOCTL",  torture_ioctl_test, 0},
8363         {"CHKPATH",  torture_chkpath_test, 0},
8364         {"FDSESS", run_fdsesstest, 0},
8365         { "EATEST", run_eatest, 0},
8366         { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8367         { "CHAIN1", run_chain1, 0},
8368         { "CHAIN2", run_chain2, 0},
8369         { "WINDOWS-WRITE", run_windows_write, 0},
8370         { "CLI_ECHO", run_cli_echo, 0},
8371         { "GETADDRINFO", run_getaddrinfo_send, 0},
8372         { "TLDAP", run_tldap },
8373         { "STREAMERROR", run_streamerror },
8374         { "NOTIFY-BENCH", run_notify_bench },
8375         { "BAD-NBT-SESSION", run_bad_nbt_session },
8376         { "SMB-ANY-CONNECT", run_smb_any_connect },
8377         { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8378         { "LOCAL-GENCACHE", run_local_gencache, 0},
8379         { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8380         { "LOCAL-BASE64", run_local_base64, 0},
8381         { "LOCAL-RBTREE", run_local_rbtree, 0},
8382         { "LOCAL-MEMCACHE", run_local_memcache, 0},
8383         { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8384         { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8385         { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8386         { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8387         { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8388         { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8389         { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8390         {NULL, NULL, 0}};
8391
8392
8393
8394 /****************************************************************************
8395 run a specified test or "ALL"
8396 ****************************************************************************/
8397 static bool run_test(const char *name)
8398 {
8399         bool ret = True;
8400         bool result = True;
8401         bool found = False;
8402         int i;
8403         double t;
8404         if (strequal(name,"ALL")) {
8405                 for (i=0;torture_ops[i].name;i++) {
8406                         run_test(torture_ops[i].name);
8407                 }
8408                 found = True;
8409         }
8410
8411         for (i=0;torture_ops[i].name;i++) {
8412                 fstr_sprintf(randomfname, "\\XX%x", 
8413                          (unsigned)random());
8414
8415                 if (strequal(name, torture_ops[i].name)) {
8416                         found = True;
8417                         printf("Running %s\n", name);
8418                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
8419                                 t = create_procs(torture_ops[i].fn, &result);
8420                                 if (!result) { 
8421                                         ret = False;
8422                                         printf("TEST %s FAILED!\n", name);
8423                                 }
8424                         } else {
8425                                 struct timeval start;
8426                                 start = timeval_current();
8427                                 if (!torture_ops[i].fn(0)) {
8428                                         ret = False;
8429                                         printf("TEST %s FAILED!\n", name);
8430                                 }
8431                                 t = timeval_elapsed(&start);
8432                         }
8433                         printf("%s took %g secs\n\n", name, t);
8434                 }
8435         }
8436
8437         if (!found) {
8438                 printf("Did not find a test named %s\n", name);
8439                 ret = False;
8440         }
8441
8442         return ret;
8443 }
8444
8445
8446 static void usage(void)
8447 {
8448         int i;
8449
8450         printf("WARNING samba4 test suite is much more complete nowadays.\n");
8451         printf("Please use samba4 torture.\n\n");
8452
8453         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8454
8455         printf("\t-d debuglevel\n");
8456         printf("\t-U user%%pass\n");
8457         printf("\t-k               use kerberos\n");
8458         printf("\t-N numprocs\n");
8459         printf("\t-n my_netbios_name\n");
8460         printf("\t-W workgroup\n");
8461         printf("\t-o num_operations\n");
8462         printf("\t-O socket_options\n");
8463         printf("\t-m maximum protocol\n");
8464         printf("\t-L use oplocks\n");
8465         printf("\t-c CLIENT.TXT   specify client load file for NBENCH\n");
8466         printf("\t-A showall\n");
8467         printf("\t-p port\n");
8468         printf("\t-s seed\n");
8469         printf("\t-b unclist_filename   specify multiple shares for multiple connections\n");
8470         printf("\n\n");
8471
8472         printf("tests are:");
8473         for (i=0;torture_ops[i].name;i++) {
8474                 printf(" %s", torture_ops[i].name);
8475         }
8476         printf("\n");
8477
8478         printf("default test is ALL\n");
8479
8480         exit(1);
8481 }
8482
8483 /****************************************************************************
8484   main program
8485 ****************************************************************************/
8486  int main(int argc,char *argv[])
8487 {
8488         int opt, i;
8489         char *p;
8490         int gotuser = 0;
8491         int gotpass = 0;
8492         bool correct = True;
8493         TALLOC_CTX *frame = talloc_stackframe();
8494         int seed = time(NULL);
8495
8496 #ifdef HAVE_SETBUFFER
8497         setbuffer(stdout, NULL, 0);
8498 #endif
8499
8500         setup_logging("smbtorture", DEBUG_STDOUT);
8501
8502         load_case_tables();
8503
8504         if (is_default_dyn_CONFIGFILE()) {
8505                 if(getenv("SMB_CONF_PATH")) {
8506                         set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8507                 }
8508         }
8509         lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8510         load_interfaces();
8511
8512         if (argc < 2) {
8513                 usage();
8514         }
8515
8516         for(p = argv[1]; *p; p++)
8517           if(*p == '\\')
8518             *p = '/';
8519
8520         if (strncmp(argv[1], "//", 2)) {
8521                 usage();
8522         }
8523
8524         fstrcpy(host, &argv[1][2]);
8525         p = strchr_m(&host[2],'/');
8526         if (!p) {
8527                 usage();
8528         }
8529         *p = 0;
8530         fstrcpy(share, p+1);
8531
8532         fstrcpy(myname, get_myname(talloc_tos()));
8533         if (!*myname) {
8534                 fprintf(stderr, "Failed to get my hostname.\n");
8535                 return 1;
8536         }
8537
8538         if (*username == 0 && getenv("LOGNAME")) {
8539           fstrcpy(username,getenv("LOGNAME"));
8540         }
8541
8542         argc--;
8543         argv++;
8544
8545         fstrcpy(workgroup, lp_workgroup());
8546
8547         while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
8548                 switch (opt) {
8549                 case 'p':
8550                         port_to_use = atoi(optarg);
8551                         break;
8552                 case 's':
8553                         seed = atoi(optarg);
8554                         break;
8555                 case 'W':
8556                         fstrcpy(workgroup,optarg);
8557                         break;
8558                 case 'm':
8559                         max_protocol = interpret_protocol(optarg, max_protocol);
8560                         break;
8561                 case 'N':
8562                         nprocs = atoi(optarg);
8563                         break;
8564                 case 'o':
8565                         torture_numops = atoi(optarg);
8566                         break;
8567                 case 'd':
8568                         lp_set_cmdline("log level", optarg);
8569                         break;
8570                 case 'O':
8571                         sockops = optarg;
8572                         break;
8573                 case 'L':
8574                         use_oplocks = True;
8575                         break;
8576                 case 'l':
8577                         local_path = optarg;
8578                         break;
8579                 case 'A':
8580                         torture_showall = True;
8581                         break;
8582                 case 'n':
8583                         fstrcpy(myname, optarg);
8584                         break;
8585                 case 'c':
8586                         client_txt = optarg;
8587                         break;
8588                 case 'e':
8589                         do_encrypt = true;
8590                         break;
8591                 case 'k':
8592 #ifdef HAVE_KRB5
8593                         use_kerberos = True;
8594 #else
8595                         d_printf("No kerberos support compiled in\n");
8596                         exit(1);
8597 #endif
8598                         break;
8599                 case 'U':
8600                         gotuser = 1;
8601                         fstrcpy(username,optarg);
8602                         p = strchr_m(username,'%');
8603                         if (p) {
8604                                 *p = 0;
8605                                 fstrcpy(password, p+1);
8606                                 gotpass = 1;
8607                         }
8608                         break;
8609                 case 'b':
8610                         fstrcpy(multishare_conn_fname, optarg);
8611                         use_multishare_conn = True;
8612                         break;
8613                 case 'B':
8614                         torture_blocksize = atoi(optarg);
8615                         break;
8616                 default:
8617                         printf("Unknown option %c (%d)\n", (char)opt, opt);
8618                         usage();
8619                 }
8620         }
8621
8622         d_printf("using seed %d\n", seed);
8623
8624         srandom(seed);
8625
8626         if(use_kerberos && !gotuser) gotpass = True;
8627
8628         while (!gotpass) {
8629                 p = getpass("Password:");
8630                 if (p) {
8631                         fstrcpy(password, p);
8632                         gotpass = 1;
8633                 }
8634         }
8635
8636         printf("host=%s share=%s user=%s myname=%s\n", 
8637                host, share, username, myname);
8638
8639         if (argc == optind) {
8640                 correct = run_test("ALL");
8641         } else {
8642                 for (i=optind;i<argc;i++) {
8643                         if (!run_test(argv[i])) {
8644                                 correct = False;
8645                         }
8646                 }
8647         }
8648
8649         TALLOC_FREE(frame);
8650
8651         if (correct) {
8652                 return(0);
8653         } else {
8654                 return(1);
8655         }
8656 }