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