s3: Rename cli_fileinfo() to cli_fileinfo_basic()
[nivanova/samba-autobuild/.git] / source3 / torture / torture.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB torture tester
4    Copyright (C) Andrew Tridgell 1997-1998
5    Copyright (C) Jeremy Allison 2009
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "nsswitch/libwbclient/wbc_async.h"
23 #include "torture/proto.h"
24 #include "libcli/security/security.h"
25 #include "tldap.h"
26 #include "tldap_util.h"
27 #include "../librpc/gen_ndr/svcctl.h"
28 #include "memcache.h"
29 #include "nsswitch/winbind_client.h"
30 #include "dbwrap.h"
31 #include "talloc_dict.h"
32 #include "async_smb.h"
33
34 extern char *optarg;
35 extern int optind;
36
37 static fstring host, workgroup, share, password, username, myname;
38 static int max_protocol = PROTOCOL_NT1;
39 static const char *sockops="TCP_NODELAY";
40 static int nprocs=1;
41 static int port_to_use=0;
42 int torture_numops=100;
43 int torture_blocksize=1024*1024;
44 static int procnum; /* records process count number when forking */
45 static struct cli_state *current_cli;
46 static fstring randomfname;
47 static bool use_oplocks;
48 static bool use_level_II_oplocks;
49 static const char *client_txt = "client_oplocks.txt";
50 static bool use_kerberos;
51 static fstring multishare_conn_fname;
52 static bool use_multishare_conn = False;
53 static bool do_encrypt;
54 static const char *local_path = NULL;
55
56 bool torture_showall = False;
57
58 static double create_procs(bool (*fn)(int), bool *result);
59
60
61 /* return a pointer to a anonymous shared memory segment of size "size"
62    which will persist across fork() but will disappear when all processes
63    exit 
64
65    The memory is not zeroed 
66
67    This function uses system5 shared memory. It takes advantage of a property
68    that the memory is not destroyed if it is attached when the id is removed
69    */
70 void *shm_setup(int size)
71 {
72         int shmid;
73         void *ret;
74
75 #ifdef __QNXNTO__
76         shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
77         if (shmid == -1) {
78                 printf("can't get shared memory\n");
79                 exit(1);
80         }
81         shm_unlink("private");
82         if (ftruncate(shmid, size) == -1) {
83                 printf("can't set shared memory size\n");
84                 exit(1);
85         }
86         ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
87         if (ret == MAP_FAILED) {
88                 printf("can't map shared memory\n");
89                 exit(1);
90         }
91 #else
92         shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
93         if (shmid == -1) {
94                 printf("can't get shared memory\n");
95                 exit(1);
96         }
97         ret = (void *)shmat(shmid, 0, 0);
98         if (!ret || ret == (void *)-1) {
99                 printf("can't attach to shared memory\n");
100                 return NULL;
101         }
102         /* the following releases the ipc, but note that this process
103            and all its children will still have access to the memory, its
104            just that the shmid is no longer valid for other shm calls. This
105            means we don't leave behind lots of shm segments after we exit 
106
107            See Stevens "advanced programming in unix env" for details
108            */
109         shmctl(shmid, IPC_RMID, 0);
110 #endif
111
112         return ret;
113 }
114
115 /********************************************************************
116  Ensure a connection is encrypted.
117 ********************************************************************/
118
119 static bool force_cli_encryption(struct cli_state *c,
120                         const char *sharename)
121 {
122         uint16 major, minor;
123         uint32 caplow, caphigh;
124         NTSTATUS status;
125
126         if (!SERVER_HAS_UNIX_CIFS(c)) {
127                 d_printf("Encryption required and "
128                         "server that doesn't support "
129                         "UNIX extensions - failing connect\n");
130                         return false;
131         }
132
133         status = cli_unix_extensions_version(c, &major, &minor, &caplow,
134                                              &caphigh);
135         if (!NT_STATUS_IS_OK(status)) {
136                 d_printf("Encryption required and "
137                         "can't get UNIX CIFS extensions "
138                         "version from server: %s\n", nt_errstr(status));
139                 return false;
140         }
141
142         if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
143                 d_printf("Encryption required and "
144                         "share %s doesn't support "
145                         "encryption.\n", sharename);
146                 return false;
147         }
148
149         if (c->use_kerberos) {
150                 status = cli_gss_smb_encryption_start(c);
151         } else {
152                 status = cli_raw_ntlm_smb_encryption_start(c,
153                                                 username,
154                                                 password,
155                                                 workgroup);
156         }
157
158         if (!NT_STATUS_IS_OK(status)) {
159                 d_printf("Encryption required and "
160                         "setup failed with error %s.\n",
161                         nt_errstr(status));
162                 return false;
163         }
164
165         return true;
166 }
167
168
169 static struct cli_state *open_nbt_connection(void)
170 {
171         struct nmb_name called, calling;
172         struct sockaddr_storage ss;
173         struct cli_state *c;
174         NTSTATUS status;
175
176         make_nmb_name(&calling, myname, 0x0);
177         make_nmb_name(&called , host, 0x20);
178
179         zero_sockaddr(&ss);
180
181         if (!(c = cli_initialise())) {
182                 printf("Failed initialize cli_struct to connect with %s\n", host);
183                 return NULL;
184         }
185
186         c->port = port_to_use;
187
188         status = cli_connect(c, host, &ss);
189         if (!NT_STATUS_IS_OK(status)) {
190                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
191                 return NULL;
192         }
193
194         c->use_kerberos = use_kerberos;
195
196         c->timeout = 120000; /* set a really long timeout (2 minutes) */
197         if (use_oplocks) c->use_oplocks = True;
198         if (use_level_II_oplocks) c->use_level_II_oplocks = True;
199
200         if (!cli_session_request(c, &calling, &called)) {
201                 /*
202                  * Well, that failed, try *SMBSERVER ...
203                  * However, we must reconnect as well ...
204                  */
205                 status = cli_connect(c, host, &ss);
206                 if (!NT_STATUS_IS_OK(status)) {
207                         printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
208                         return NULL;
209                 }
210
211                 make_nmb_name(&called, "*SMBSERVER", 0x20);
212                 if (!cli_session_request(c, &calling, &called)) {
213                         printf("%s rejected the session\n",host);
214                         printf("We tried with a called name of %s & %s\n",
215                                 host, "*SMBSERVER");
216                         cli_shutdown(c);
217                         return NULL;
218                 }
219         }
220
221         return c;
222 }
223
224 /****************************************************************************
225  Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
226 ****************************************************************************/
227
228 static bool cli_bad_session_request(struct cli_state *cli,
229                          struct nmb_name *calling, struct nmb_name *called)
230 {
231         char *p;
232         int len = 4;
233         int namelen = 0;
234         char *tmp;
235
236         memcpy(&(cli->calling), calling, sizeof(*calling));
237         memcpy(&(cli->called ), called , sizeof(*called ));
238
239         /* put in the destination name */
240
241         tmp = name_mangle(talloc_tos(), cli->called.name,
242                           cli->called.name_type);
243         if (tmp == NULL) {
244                 return false;
245         }
246
247         p = cli->outbuf+len;
248         namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
249         if (namelen > 0) {
250                 memcpy(p, tmp, namelen);
251                 len += namelen;
252         }
253         TALLOC_FREE(tmp);
254
255         /* Deliberately corrupt the name len (first byte) */
256         *p = 100;
257
258         /* and my name */
259
260         tmp = name_mangle(talloc_tos(), cli->calling.name,
261                           cli->calling.name_type);
262         if (tmp == NULL) {
263                 return false;
264         }
265
266         p = cli->outbuf+len;
267         namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
268         if (namelen > 0) {
269                 memcpy(p, tmp, namelen);
270                 len += namelen;
271         }
272         TALLOC_FREE(tmp);
273         /* Deliberately corrupt the name len (first byte) */
274         *p = 100;
275
276         /* send a session request (RFC 1002) */
277         /* setup the packet length
278          * Remove four bytes from the length count, since the length
279          * field in the NBT Session Service header counts the number
280          * of bytes which follow.  The cli_send_smb() function knows
281          * about this and accounts for those four bytes.
282          * CRH.
283          */
284         len -= 4;
285         _smb_setlen(cli->outbuf,len);
286         SCVAL(cli->outbuf,0,0x81);
287
288         cli_send_smb(cli);
289         DEBUG(5,("Sent session request\n"));
290
291         if (!cli_receive_smb(cli))
292                 return False;
293
294         if (CVAL(cli->inbuf,0) != 0x82) {
295                 /* This is the wrong place to put the error... JRA. */
296                 cli->rap_error = CVAL(cli->inbuf,4);
297                 return False;
298         }
299         return(True);
300 }
301
302 static struct cli_state *open_bad_nbt_connection(void)
303 {
304         struct nmb_name called, calling;
305         struct sockaddr_storage ss;
306         struct cli_state *c;
307         NTSTATUS status;
308
309         make_nmb_name(&calling, myname, 0x0);
310         make_nmb_name(&called , host, 0x20);
311
312         zero_sockaddr(&ss);
313
314         if (!(c = cli_initialise())) {
315                 printf("Failed initialize cli_struct to connect with %s\n", host);
316                 return NULL;
317         }
318
319         c->port = 139;
320
321         status = cli_connect(c, host, &ss);
322         if (!NT_STATUS_IS_OK(status)) {
323                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
324                 return NULL;
325         }
326
327         c->timeout = 4000; /* set a short timeout (4 seconds) */
328
329         if (!cli_bad_session_request(c, &calling, &called)) {
330                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
331                 return NULL;
332         }
333
334         return c;
335 }
336
337
338 /* Insert a NULL at the first separator of the given path and return a pointer
339  * to the remainder of the string.
340  */
341 static char *
342 terminate_path_at_separator(char * path)
343 {
344         char * p;
345
346         if (!path) {
347                 return NULL;
348         }
349
350         if ((p = strchr_m(path, '/'))) {
351                 *p = '\0';
352                 return p + 1;
353         }
354
355         if ((p = strchr_m(path, '\\'))) {
356                 *p = '\0';
357                 return p + 1;
358         }
359
360         /* No separator. */
361         return NULL;
362 }
363
364 /*
365   parse a //server/share type UNC name
366 */
367 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
368                       char **hostname, char **sharename)
369 {
370         char *p;
371
372         *hostname = *sharename = NULL;
373
374         if (strncmp(unc_name, "\\\\", 2) &&
375             strncmp(unc_name, "//", 2)) {
376                 return False;
377         }
378
379         *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
380         p = terminate_path_at_separator(*hostname);
381
382         if (p && *p) {
383                 *sharename = talloc_strdup(mem_ctx, p);
384                 terminate_path_at_separator(*sharename);
385         }
386
387         if (*hostname && *sharename) {
388                 return True;
389         }
390
391         TALLOC_FREE(*hostname);
392         TALLOC_FREE(*sharename);
393         return False;
394 }
395
396 static bool torture_open_connection_share(struct cli_state **c,
397                                    const char *hostname, 
398                                    const char *sharename)
399 {
400         bool retry;
401         int flags = 0;
402         NTSTATUS status;
403
404         if (use_kerberos)
405                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
406         if (use_oplocks)
407                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
408         if (use_level_II_oplocks)
409                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
410
411         status = cli_full_connection(c, myname,
412                                      hostname, NULL, port_to_use, 
413                                      sharename, "?????", 
414                                      username, workgroup, 
415                                      password, flags, Undefined, &retry);
416         if (!NT_STATUS_IS_OK(status)) {
417                 printf("failed to open share connection: //%s/%s port:%d - %s\n",
418                         hostname, sharename, port_to_use, nt_errstr(status));
419                 return False;
420         }
421
422         (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
423
424         if (do_encrypt) {
425                 return force_cli_encryption(*c,
426                                         sharename);
427         }
428         return True;
429 }
430
431 bool torture_open_connection(struct cli_state **c, int conn_index)
432 {
433         char **unc_list = NULL;
434         int num_unc_names = 0;
435         bool result;
436
437         if (use_multishare_conn==True) {
438                 char *h, *s;
439                 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
440                 if (!unc_list || num_unc_names <= 0) {
441                         printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
442                         exit(1);
443                 }
444
445                 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
446                                       NULL, &h, &s)) {
447                         printf("Failed to parse UNC name %s\n",
448                                unc_list[conn_index % num_unc_names]);
449                         TALLOC_FREE(unc_list);
450                         exit(1);
451                 }
452
453                 result = torture_open_connection_share(c, h, s);
454
455                 /* h, s were copied earlier */
456                 TALLOC_FREE(unc_list);
457                 return result;
458         }
459
460         return torture_open_connection_share(c, host, share);
461 }
462
463 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
464 {
465         uint16 old_vuid = cli->vuid;
466         fstring old_user_name;
467         size_t passlen = strlen(password);
468         NTSTATUS status;
469         bool ret;
470
471         fstrcpy(old_user_name, cli->user_name);
472         cli->vuid = 0;
473         ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
474                                                 password, passlen,
475                                                 password, passlen,
476                                                 workgroup));
477         *new_vuid = cli->vuid;
478         cli->vuid = old_vuid;
479         status = cli_set_username(cli, old_user_name);
480         if (!NT_STATUS_IS_OK(status)) {
481                 return false;
482         }
483         return ret;
484 }
485
486
487 bool torture_close_connection(struct cli_state *c)
488 {
489         bool ret = True;
490         NTSTATUS status;
491
492         status = cli_tdis(c);
493         if (!NT_STATUS_IS_OK(status)) {
494                 printf("tdis failed (%s)\n", nt_errstr(status));
495                 ret = False;
496         }
497
498         cli_shutdown(c);
499
500         return ret;
501 }
502
503
504 /* check if the server produced the expected error code */
505 static bool check_error(int line, struct cli_state *c, 
506                         uint8 eclass, uint32 ecode, NTSTATUS nterr)
507 {
508         if (cli_is_dos_error(c)) {
509                 uint8 cclass;
510                 uint32 num;
511
512                 /* Check DOS error */
513
514                 cli_dos_error(c, &cclass, &num);
515
516                 if (eclass != cclass || ecode != num) {
517                         printf("unexpected error code class=%d code=%d\n", 
518                                (int)cclass, (int)num);
519                         printf(" expected %d/%d %s (line=%d)\n", 
520                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
521                         return False;
522                 }
523
524         } else {
525                 NTSTATUS status;
526
527                 /* Check NT error */
528
529                 status = cli_nt_error(c);
530
531                 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
532                         printf("unexpected error code %s\n", nt_errstr(status));
533                         printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
534                         return False;
535                 }
536         }
537
538         return True;
539 }
540
541
542 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
543 {
544         while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
545                 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
546         }
547         return True;
548 }
549
550
551 static bool rw_torture(struct cli_state *c)
552 {
553         const char *lockfname = "\\torture.lck";
554         fstring fname;
555         uint16_t fnum;
556         uint16_t fnum2;
557         pid_t pid2, pid = getpid();
558         int i, j;
559         char buf[1024];
560         bool correct = True;
561         NTSTATUS status;
562
563         memset(buf, '\0', sizeof(buf));
564
565         status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
566                          DENY_NONE, &fnum2);
567         if (!NT_STATUS_IS_OK(status)) {
568                 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
569         }
570         if (!NT_STATUS_IS_OK(status)) {
571                 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
572                 return False;
573         }
574
575         for (i=0;i<torture_numops;i++) {
576                 unsigned n = (unsigned)sys_random()%10;
577                 if (i % 10 == 0) {
578                         printf("%d\r", i); fflush(stdout);
579                 }
580                 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
581
582                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
583                         return False;
584                 }
585
586                 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
587                         printf("open failed (%s)\n", cli_errstr(c));
588                         correct = False;
589                         break;
590                 }
591
592                 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
593                         printf("write failed (%s)\n", cli_errstr(c));
594                         correct = False;
595                 }
596
597                 for (j=0;j<50;j++) {
598                         if (cli_write(c, fnum, 0, (char *)buf, 
599                                       sizeof(pid)+(j*sizeof(buf)), 
600                                       sizeof(buf)) != sizeof(buf)) {
601                                 printf("write failed (%s)\n", cli_errstr(c));
602                                 correct = False;
603                         }
604                 }
605
606                 pid2 = 0;
607
608                 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
609                         printf("read failed (%s)\n", cli_errstr(c));
610                         correct = False;
611                 }
612
613                 if (pid2 != pid) {
614                         printf("data corruption!\n");
615                         correct = False;
616                 }
617
618                 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
619                         printf("close failed (%s)\n", cli_errstr(c));
620                         correct = False;
621                 }
622
623                 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
624                         printf("unlink failed (%s)\n", cli_errstr(c));
625                         correct = False;
626                 }
627
628                 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
629                         printf("unlock failed (%s)\n", cli_errstr(c));
630                         correct = False;
631                 }
632         }
633
634         cli_close(c, fnum2);
635         cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
636
637         printf("%d\n", i);
638
639         return correct;
640 }
641
642 static bool run_torture(int dummy)
643 {
644         struct cli_state *cli;
645         bool ret;
646
647         cli = current_cli;
648
649         cli_sockopt(cli, sockops);
650
651         ret = rw_torture(cli);
652
653         if (!torture_close_connection(cli)) {
654                 ret = False;
655         }
656
657         return ret;
658 }
659
660 static bool rw_torture3(struct cli_state *c, char *lockfname)
661 {
662         uint16_t fnum = (uint16_t)-1;
663         unsigned int i = 0;
664         char buf[131072];
665         char buf_rd[131072];
666         unsigned count;
667         unsigned countprev = 0;
668         ssize_t sent = 0;
669         bool correct = True;
670         NTSTATUS status;
671
672         srandom(1);
673         for (i = 0; i < sizeof(buf); i += sizeof(uint32))
674         {
675                 SIVAL(buf, i, sys_random());
676         }
677
678         if (procnum == 0)
679         {
680                 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
681                                  DENY_NONE, &fnum))) {
682                         printf("first open read/write of %s failed (%s)\n",
683                                         lockfname, cli_errstr(c));
684                         return False;
685                 }
686         }
687         else
688         {
689                 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
690                 {
691                         status = cli_open(c, lockfname, O_RDONLY, 
692                                          DENY_NONE, &fnum);
693                         if (!NT_STATUS_IS_OK(status)) {
694                                 break;
695                         }
696                         smb_msleep(10);
697                 }
698                 if (!NT_STATUS_IS_OK(status)) {
699                         printf("second open read-only of %s failed (%s)\n",
700                                         lockfname, cli_errstr(c));
701                         return False;
702                 }
703         }
704
705         i = 0;
706         for (count = 0; count < sizeof(buf); count += sent)
707         {
708                 if (count >= countprev) {
709                         printf("%d %8d\r", i, count);
710                         fflush(stdout);
711                         i++;
712                         countprev += (sizeof(buf) / 20);
713                 }
714
715                 if (procnum == 0)
716                 {
717                         sent = ((unsigned)sys_random()%(20))+ 1;
718                         if (sent > sizeof(buf) - count)
719                         {
720                                 sent = sizeof(buf) - count;
721                         }
722
723                         if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
724                                 printf("write failed (%s)\n", cli_errstr(c));
725                                 correct = False;
726                         }
727                 }
728                 else
729                 {
730                         sent = cli_read(c, fnum, buf_rd+count, count,
731                                                   sizeof(buf)-count);
732                         if (sent < 0)
733                         {
734                                 printf("read failed offset:%d size:%ld (%s)\n",
735                                        count, (unsigned long)sizeof(buf)-count,
736                                        cli_errstr(c));
737                                 correct = False;
738                                 sent = 0;
739                         }
740                         if (sent > 0)
741                         {
742                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
743                                 {
744                                         printf("read/write compare failed\n");
745                                         printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
746                                         correct = False;
747                                         break;
748                                 }
749                         }
750                 }
751
752         }
753
754         if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
755                 printf("close failed (%s)\n", cli_errstr(c));
756                 correct = False;
757         }
758
759         return correct;
760 }
761
762 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
763 {
764         const char *lockfname = "\\torture2.lck";
765         uint16_t fnum1;
766         uint16_t fnum2;
767         int i;
768         char buf[131072];
769         char buf_rd[131072];
770         bool correct = True;
771         ssize_t bytes_read;
772
773         if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
774                 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
775         }
776
777         if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL, 
778                          DENY_NONE, &fnum1))) {
779                 printf("first open read/write of %s failed (%s)\n",
780                                 lockfname, cli_errstr(c1));
781                 return False;
782         }
783         if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY, 
784                          DENY_NONE, &fnum2))) {
785                 printf("second open read-only of %s failed (%s)\n",
786                                 lockfname, cli_errstr(c2));
787                 cli_close(c1, fnum1);
788                 return False;
789         }
790
791         for (i=0;i<torture_numops;i++)
792         {
793                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
794                 if (i % 10 == 0) {
795                         printf("%d\r", i); fflush(stdout);
796                 }
797
798                 generate_random_buffer((unsigned char *)buf, buf_size);
799
800                 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
801                         printf("write failed (%s)\n", cli_errstr(c1));
802                         correct = False;
803                         break;
804                 }
805
806                 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
807                         printf("read failed (%s)\n", cli_errstr(c2));
808                         printf("read %d, expected %ld\n", (int)bytes_read, 
809                                (unsigned long)buf_size); 
810                         correct = False;
811                         break;
812                 }
813
814                 if (memcmp(buf_rd, buf, buf_size) != 0)
815                 {
816                         printf("read/write compare failed\n");
817                         correct = False;
818                         break;
819                 }
820         }
821
822         if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
823                 printf("close failed (%s)\n", cli_errstr(c2));
824                 correct = False;
825         }
826         if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
827                 printf("close failed (%s)\n", cli_errstr(c1));
828                 correct = False;
829         }
830
831         if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
832                 printf("unlink failed (%s)\n", cli_errstr(c1));
833                 correct = False;
834         }
835
836         return correct;
837 }
838
839 static bool run_readwritetest(int dummy)
840 {
841         struct cli_state *cli1, *cli2;
842         bool test1, test2 = False;
843
844         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
845                 return False;
846         }
847         cli_sockopt(cli1, sockops);
848         cli_sockopt(cli2, sockops);
849
850         printf("starting readwritetest\n");
851
852         test1 = rw_torture2(cli1, cli2);
853         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
854
855         if (test1) {
856                 test2 = rw_torture2(cli1, cli1);
857                 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
858         }
859
860         if (!torture_close_connection(cli1)) {
861                 test1 = False;
862         }
863
864         if (!torture_close_connection(cli2)) {
865                 test2 = False;
866         }
867
868         return (test1 && test2);
869 }
870
871 static bool run_readwritemulti(int dummy)
872 {
873         struct cli_state *cli;
874         bool test;
875
876         cli = current_cli;
877
878         cli_sockopt(cli, sockops);
879
880         printf("run_readwritemulti: fname %s\n", randomfname);
881         test = rw_torture3(cli, randomfname);
882
883         if (!torture_close_connection(cli)) {
884                 test = False;
885         }
886
887         return test;
888 }
889
890 static bool run_readwritelarge(int dummy)
891 {
892         static struct cli_state *cli1;
893         uint16_t fnum1;
894         const char *lockfname = "\\large.dat";
895         SMB_OFF_T fsize;
896         char buf[126*1024];
897         bool correct = True;
898
899         if (!torture_open_connection(&cli1, 0)) {
900                 return False;
901         }
902         cli_sockopt(cli1, sockops);
903         memset(buf,'\0',sizeof(buf));
904
905         cli1->max_xmit = 128*1024;
906
907         printf("starting readwritelarge\n");
908
909         cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
910
911         if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
912                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
913                 return False;
914         }
915
916         cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
917
918         if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
919                                  NULL, NULL)) {
920                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
921                 correct = False;
922         }
923
924         if (fsize == sizeof(buf))
925                 printf("readwritelarge test 1 succeeded (size = %lx)\n", 
926                        (unsigned long)fsize);
927         else {
928                 printf("readwritelarge test 1 failed (size = %lx)\n", 
929                        (unsigned long)fsize);
930                 correct = False;
931         }
932
933         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
934                 printf("close failed (%s)\n", cli_errstr(cli1));
935                 correct = False;
936         }
937
938         if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
939                 printf("unlink failed (%s)\n", cli_errstr(cli1));
940                 correct = False;
941         }
942
943         if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
944                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
945                 return False;
946         }
947
948         cli1->max_xmit = 4*1024;
949
950         cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
951
952         if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
953                                  NULL, NULL)) {
954                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
955                 correct = False;
956         }
957
958         if (fsize == sizeof(buf))
959                 printf("readwritelarge test 2 succeeded (size = %lx)\n", 
960                        (unsigned long)fsize);
961         else {
962                 printf("readwritelarge test 2 failed (size = %lx)\n", 
963                        (unsigned long)fsize);
964                 correct = False;
965         }
966
967 #if 0
968         /* ToDo - set allocation. JRA */
969         if(!cli_set_allocation_size(cli1, fnum1, 0)) {
970                 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
971                 return False;
972         }
973         if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
974                                  NULL, NULL)) {
975                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
976                 correct = False;
977         }
978         if (fsize != 0)
979                 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
980 #endif
981
982         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
983                 printf("close failed (%s)\n", cli_errstr(cli1));
984                 correct = False;
985         }
986
987         if (!torture_close_connection(cli1)) {
988                 correct = False;
989         }
990         return correct;
991 }
992
993 int line_count = 0;
994 int nbio_id;
995
996 #define ival(s) strtol(s, NULL, 0)
997
998 /* run a test that simulates an approximate netbench client load */
999 static bool run_netbench(int client)
1000 {
1001         struct cli_state *cli;
1002         int i;
1003         char line[1024];
1004         char cname[20];
1005         FILE *f;
1006         const char *params[20];
1007         bool correct = True;
1008
1009         cli = current_cli;
1010
1011         nbio_id = client;
1012
1013         cli_sockopt(cli, sockops);
1014
1015         nb_setup(cli);
1016
1017         slprintf(cname,sizeof(cname)-1, "client%d", client);
1018
1019         f = fopen(client_txt, "r");
1020
1021         if (!f) {
1022                 perror(client_txt);
1023                 return False;
1024         }
1025
1026         while (fgets(line, sizeof(line)-1, f)) {
1027                 char *saveptr;
1028                 line_count++;
1029
1030                 line[strlen(line)-1] = 0;
1031
1032                 /* printf("[%d] %s\n", line_count, line); */
1033
1034                 all_string_sub(line,"client1", cname, sizeof(line));
1035
1036                 /* parse the command parameters */
1037                 params[0] = strtok_r(line, " ", &saveptr);
1038                 i = 0;
1039                 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1040
1041                 params[i] = "";
1042
1043                 if (i < 2) continue;
1044
1045                 if (!strncmp(params[0],"SMB", 3)) {
1046                         printf("ERROR: You are using a dbench 1 load file\n");
1047                         exit(1);
1048                 }
1049
1050                 if (!strcmp(params[0],"NTCreateX")) {
1051                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
1052                                    ival(params[4]));
1053                 } else if (!strcmp(params[0],"Close")) {
1054                         nb_close(ival(params[1]));
1055                 } else if (!strcmp(params[0],"Rename")) {
1056                         nb_rename(params[1], params[2]);
1057                 } else if (!strcmp(params[0],"Unlink")) {
1058                         nb_unlink(params[1]);
1059                 } else if (!strcmp(params[0],"Deltree")) {
1060                         nb_deltree(params[1]);
1061                 } else if (!strcmp(params[0],"Rmdir")) {
1062                         nb_rmdir(params[1]);
1063                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1064                         nb_qpathinfo(params[1]);
1065                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1066                         nb_qfileinfo(ival(params[1]));
1067                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1068                         nb_qfsinfo(ival(params[1]));
1069                 } else if (!strcmp(params[0],"FIND_FIRST")) {
1070                         nb_findfirst(params[1]);
1071                 } else if (!strcmp(params[0],"WriteX")) {
1072                         nb_writex(ival(params[1]), 
1073                                   ival(params[2]), ival(params[3]), ival(params[4]));
1074                 } else if (!strcmp(params[0],"ReadX")) {
1075                         nb_readx(ival(params[1]), 
1076                                   ival(params[2]), ival(params[3]), ival(params[4]));
1077                 } else if (!strcmp(params[0],"Flush")) {
1078                         nb_flush(ival(params[1]));
1079                 } else {
1080                         printf("Unknown operation %s\n", params[0]);
1081                         exit(1);
1082                 }
1083         }
1084         fclose(f);
1085
1086         nb_cleanup();
1087
1088         if (!torture_close_connection(cli)) {
1089                 correct = False;
1090         }
1091
1092         return correct;
1093 }
1094
1095
1096 /* run a test that simulates an approximate netbench client load */
1097 static bool run_nbench(int dummy)
1098 {
1099         double t;
1100         bool correct = True;
1101
1102         nbio_shmem(nprocs);
1103
1104         nbio_id = -1;
1105
1106         signal(SIGALRM, nb_alarm);
1107         alarm(1);
1108         t = create_procs(run_netbench, &correct);
1109         alarm(0);
1110
1111         printf("\nThroughput %g MB/sec\n", 
1112                1.0e-6 * nbio_total() / t);
1113         return correct;
1114 }
1115
1116
1117 /*
1118   This test checks for two things:
1119
1120   1) correct support for retaining locks over a close (ie. the server
1121      must not use posix semantics)
1122   2) support for lock timeouts
1123  */
1124 static bool run_locktest1(int dummy)
1125 {
1126         struct cli_state *cli1, *cli2;
1127         const char *fname = "\\lockt1.lck";
1128         uint16_t fnum1, fnum2, fnum3;
1129         time_t t1, t2;
1130         unsigned lock_timeout;
1131
1132         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1133                 return False;
1134         }
1135         cli_sockopt(cli1, sockops);
1136         cli_sockopt(cli2, sockops);
1137
1138         printf("starting locktest1\n");
1139
1140         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1141
1142         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1143                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1144                 return False;
1145         }
1146         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1147                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1148                 return False;
1149         }
1150         if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1151                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1152                 return False;
1153         }
1154
1155         if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1156                 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1157                 return False;
1158         }
1159
1160
1161         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1162                 printf("lock2 succeeded! This is a locking bug\n");
1163                 return False;
1164         } else {
1165                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1166                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1167         }
1168
1169
1170         lock_timeout = (1 + (random() % 20));
1171         printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1172         t1 = time(NULL);
1173         if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1174                 printf("lock3 succeeded! This is a locking bug\n");
1175                 return False;
1176         } else {
1177                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1178                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1179         }
1180         t2 = time(NULL);
1181
1182         if (ABS(t2 - t1) < lock_timeout-1) {
1183                 printf("error: This server appears not to support timed lock requests\n");
1184         }
1185
1186         printf("server slept for %u seconds for a %u second timeout\n",
1187                (unsigned int)(t2-t1), lock_timeout);
1188
1189         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1190                 printf("close1 failed (%s)\n", cli_errstr(cli1));
1191                 return False;
1192         }
1193
1194         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1195                 printf("lock4 succeeded! This is a locking bug\n");
1196                 return False;
1197         } else {
1198                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1199                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1200         }
1201
1202         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1203                 printf("close2 failed (%s)\n", cli_errstr(cli1));
1204                 return False;
1205         }
1206
1207         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1208                 printf("close3 failed (%s)\n", cli_errstr(cli2));
1209                 return False;
1210         }
1211
1212         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1213                 printf("unlink failed (%s)\n", cli_errstr(cli1));
1214                 return False;
1215         }
1216
1217
1218         if (!torture_close_connection(cli1)) {
1219                 return False;
1220         }
1221
1222         if (!torture_close_connection(cli2)) {
1223                 return False;
1224         }
1225
1226         printf("Passed locktest1\n");
1227         return True;
1228 }
1229
1230 /*
1231   this checks to see if a secondary tconx can use open files from an
1232   earlier tconx
1233  */
1234 static bool run_tcon_test(int dummy)
1235 {
1236         static struct cli_state *cli;
1237         const char *fname = "\\tcontest.tmp";
1238         uint16 fnum1;
1239         uint16 cnum1, cnum2, cnum3;
1240         uint16 vuid1, vuid2;
1241         char buf[4];
1242         bool ret = True;
1243         NTSTATUS status;
1244
1245         memset(buf, '\0', sizeof(buf));
1246
1247         if (!torture_open_connection(&cli, 0)) {
1248                 return False;
1249         }
1250         cli_sockopt(cli, sockops);
1251
1252         printf("starting tcontest\n");
1253
1254         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1255
1256         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1257                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1258                 return False;
1259         }
1260
1261         cnum1 = cli->cnum;
1262         vuid1 = cli->vuid;
1263
1264         if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1265                 printf("initial write failed (%s)", cli_errstr(cli));
1266                 return False;
1267         }
1268
1269         status = cli_tcon_andx(cli, share, "?????",
1270                                password, strlen(password)+1);
1271         if (!NT_STATUS_IS_OK(status)) {
1272                 printf("%s refused 2nd tree connect (%s)\n", host,
1273                        nt_errstr(status));
1274                 cli_shutdown(cli);
1275                 return False;
1276         }
1277
1278         cnum2 = cli->cnum;
1279         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1280         vuid2 = cli->vuid + 1;
1281
1282         /* try a write with the wrong tid */
1283         cli->cnum = cnum2;
1284
1285         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1286                 printf("* server allows write with wrong TID\n");
1287                 ret = False;
1288         } else {
1289                 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1290         }
1291
1292
1293         /* try a write with an invalid tid */
1294         cli->cnum = cnum3;
1295
1296         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1297                 printf("* server allows write with invalid TID\n");
1298                 ret = False;
1299         } else {
1300                 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1301         }
1302
1303         /* try a write with an invalid vuid */
1304         cli->vuid = vuid2;
1305         cli->cnum = cnum1;
1306
1307         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1308                 printf("* server allows write with invalid VUID\n");
1309                 ret = False;
1310         } else {
1311                 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1312         }
1313
1314         cli->cnum = cnum1;
1315         cli->vuid = vuid1;
1316
1317         if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1318                 printf("close failed (%s)\n", cli_errstr(cli));
1319                 return False;
1320         }
1321
1322         cli->cnum = cnum2;
1323
1324         status = cli_tdis(cli);
1325         if (!NT_STATUS_IS_OK(status)) {
1326                 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1327                 return False;
1328         }
1329
1330         cli->cnum = cnum1;
1331
1332         if (!torture_close_connection(cli)) {
1333                 return False;
1334         }
1335
1336         return ret;
1337 }
1338
1339
1340 /*
1341  checks for old style tcon support
1342  */
1343 static bool run_tcon2_test(int dummy)
1344 {
1345         static struct cli_state *cli;
1346         uint16 cnum, max_xmit;
1347         char *service;
1348         NTSTATUS status;
1349
1350         if (!torture_open_connection(&cli, 0)) {
1351                 return False;
1352         }
1353         cli_sockopt(cli, sockops);
1354
1355         printf("starting tcon2 test\n");
1356
1357         if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1358                 return false;
1359         }
1360
1361         status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1362
1363         if (!NT_STATUS_IS_OK(status)) {
1364                 printf("tcon2 failed : %s\n", cli_errstr(cli));
1365         } else {
1366                 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n", 
1367                        (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1368         }
1369
1370         if (!torture_close_connection(cli)) {
1371                 return False;
1372         }
1373
1374         printf("Passed tcon2 test\n");
1375         return True;
1376 }
1377
1378 static bool tcon_devtest(struct cli_state *cli,
1379                          const char *myshare, const char *devtype,
1380                          const char *return_devtype,
1381                          NTSTATUS expected_error)
1382 {
1383         NTSTATUS status;
1384         bool ret;
1385
1386         status = cli_tcon_andx(cli, myshare, devtype,
1387                                password, strlen(password)+1);
1388
1389         if (NT_STATUS_IS_OK(expected_error)) {
1390                 if (NT_STATUS_IS_OK(status)) {
1391                         if (strcmp(cli->dev, return_devtype) == 0) {
1392                                 ret = True;
1393                         } else { 
1394                                 printf("tconX to share %s with type %s "
1395                                        "succeeded but returned the wrong "
1396                                        "device type (got [%s] but should have got [%s])\n",
1397                                        myshare, devtype, cli->dev, return_devtype);
1398                                 ret = False;
1399                         }
1400                 } else {
1401                         printf("tconX to share %s with type %s "
1402                                "should have succeeded but failed\n",
1403                                myshare, devtype);
1404                         ret = False;
1405                 }
1406                 cli_tdis(cli);
1407         } else {
1408                 if (NT_STATUS_IS_OK(status)) {
1409                         printf("tconx to share %s with type %s "
1410                                "should have failed but succeeded\n",
1411                                myshare, devtype);
1412                         ret = False;
1413                 } else {
1414                         if (NT_STATUS_EQUAL(cli_nt_error(cli),
1415                                             expected_error)) {
1416                                 ret = True;
1417                         } else {
1418                                 printf("Returned unexpected error\n");
1419                                 ret = False;
1420                         }
1421                 }
1422         }
1423         return ret;
1424 }
1425
1426 /*
1427  checks for correct tconX support
1428  */
1429 static bool run_tcon_devtype_test(int dummy)
1430 {
1431         static struct cli_state *cli1 = NULL;
1432         bool retry;
1433         int flags = 0;
1434         NTSTATUS status;
1435         bool ret = True;
1436
1437         status = cli_full_connection(&cli1, myname,
1438                                      host, NULL, port_to_use,
1439                                      NULL, NULL,
1440                                      username, workgroup,
1441                                      password, flags, Undefined, &retry);
1442
1443         if (!NT_STATUS_IS_OK(status)) {
1444                 printf("could not open connection\n");
1445                 return False;
1446         }
1447
1448         if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1449                 ret = False;
1450
1451         if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1452                 ret = False;
1453
1454         if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1455                 ret = False;
1456
1457         if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1458                 ret = False;
1459
1460         if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1461                 ret = False;
1462
1463         if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1464                 ret = False;
1465
1466         if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1467                 ret = False;
1468
1469         if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1470                 ret = False;
1471
1472         if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1473                 ret = False;
1474
1475         if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1476                 ret = False;
1477
1478         cli_shutdown(cli1);
1479
1480         if (ret)
1481                 printf("Passed tcondevtest\n");
1482
1483         return ret;
1484 }
1485
1486
1487 /*
1488   This test checks that 
1489
1490   1) the server supports multiple locking contexts on the one SMB
1491   connection, distinguished by PID.  
1492
1493   2) the server correctly fails overlapping locks made by the same PID (this
1494      goes against POSIX behaviour, which is why it is tricky to implement)
1495
1496   3) the server denies unlock requests by an incorrect client PID
1497 */
1498 static bool run_locktest2(int dummy)
1499 {
1500         static struct cli_state *cli;
1501         const char *fname = "\\lockt2.lck";
1502         uint16_t fnum1, fnum2, fnum3;
1503         bool correct = True;
1504
1505         if (!torture_open_connection(&cli, 0)) {
1506                 return False;
1507         }
1508
1509         cli_sockopt(cli, sockops);
1510
1511         printf("starting locktest2\n");
1512
1513         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1514
1515         cli_setpid(cli, 1);
1516
1517         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1518                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1519                 return False;
1520         }
1521
1522         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1523                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1524                 return False;
1525         }
1526
1527         cli_setpid(cli, 2);
1528
1529         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1530                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1531                 return False;
1532         }
1533
1534         cli_setpid(cli, 1);
1535
1536         if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1537                 printf("lock1 failed (%s)\n", cli_errstr(cli));
1538                 return False;
1539         }
1540
1541         if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1542                 printf("WRITE lock1 succeeded! This is a locking bug\n");
1543                 correct = False;
1544         } else {
1545                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1546                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1547         }
1548
1549         if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1550                 printf("WRITE lock2 succeeded! This is a locking bug\n");
1551                 correct = False;
1552         } else {
1553                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1554                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1555         }
1556
1557         if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1558                 printf("READ lock2 succeeded! This is a locking bug\n");
1559                 correct = False;
1560         } else {
1561                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1562                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1563         }
1564
1565         if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1566                 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1567         }
1568         cli_setpid(cli, 2);
1569         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1570                 printf("unlock at 100 succeeded! This is a locking bug\n");
1571                 correct = False;
1572         }
1573
1574         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1575                 printf("unlock1 succeeded! This is a locking bug\n");
1576                 correct = False;
1577         } else {
1578                 if (!check_error(__LINE__, cli, 
1579                                  ERRDOS, ERRlock, 
1580                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1581         }
1582
1583         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1584                 printf("unlock2 succeeded! This is a locking bug\n");
1585                 correct = False;
1586         } else {
1587                 if (!check_error(__LINE__, cli, 
1588                                  ERRDOS, ERRlock, 
1589                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1590         }
1591
1592         if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1593                 printf("lock3 succeeded! This is a locking bug\n");
1594                 correct = False;
1595         } else {
1596                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1597         }
1598
1599         cli_setpid(cli, 1);
1600
1601         if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1602                 printf("close1 failed (%s)\n", cli_errstr(cli));
1603                 return False;
1604         }
1605
1606         if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1607                 printf("close2 failed (%s)\n", cli_errstr(cli));
1608                 return False;
1609         }
1610
1611         if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1612                 printf("close3 failed (%s)\n", cli_errstr(cli));
1613                 return False;
1614         }
1615
1616         if (!torture_close_connection(cli)) {
1617                 correct = False;
1618         }
1619
1620         printf("locktest2 finished\n");
1621
1622         return correct;
1623 }
1624
1625
1626 /*
1627   This test checks that 
1628
1629   1) the server supports the full offset range in lock requests
1630 */
1631 static bool run_locktest3(int dummy)
1632 {
1633         static struct cli_state *cli1, *cli2;
1634         const char *fname = "\\lockt3.lck";
1635         uint16_t fnum1, fnum2;
1636         int i;
1637         uint32 offset;
1638         bool correct = True;
1639
1640 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1641
1642         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1643                 return False;
1644         }
1645         cli_sockopt(cli1, sockops);
1646         cli_sockopt(cli2, sockops);
1647
1648         printf("starting locktest3\n");
1649
1650         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1651
1652         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1653                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1654                 return False;
1655         }
1656         if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1657                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1658                 return False;
1659         }
1660
1661         for (offset=i=0;i<torture_numops;i++) {
1662                 NEXT_OFFSET;
1663                 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1664                         printf("lock1 %d failed (%s)\n", 
1665                                i,
1666                                cli_errstr(cli1));
1667                         return False;
1668                 }
1669
1670                 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1671                         printf("lock2 %d failed (%s)\n", 
1672                                i,
1673                                cli_errstr(cli1));
1674                         return False;
1675                 }
1676         }
1677
1678         for (offset=i=0;i<torture_numops;i++) {
1679                 NEXT_OFFSET;
1680
1681                 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1682                         printf("error: lock1 %d succeeded!\n", i);
1683                         return False;
1684                 }
1685
1686                 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1687                         printf("error: lock2 %d succeeded!\n", i);
1688                         return False;
1689                 }
1690
1691                 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1692                         printf("error: lock3 %d succeeded!\n", i);
1693                         return False;
1694                 }
1695
1696                 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1697                         printf("error: lock4 %d succeeded!\n", i);
1698                         return False;
1699                 }
1700         }
1701
1702         for (offset=i=0;i<torture_numops;i++) {
1703                 NEXT_OFFSET;
1704
1705                 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1706                         printf("unlock1 %d failed (%s)\n", 
1707                                i,
1708                                cli_errstr(cli1));
1709                         return False;
1710                 }
1711
1712                 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1713                         printf("unlock2 %d failed (%s)\n", 
1714                                i,
1715                                cli_errstr(cli1));
1716                         return False;
1717                 }
1718         }
1719
1720         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1721                 printf("close1 failed (%s)\n", cli_errstr(cli1));
1722                 return False;
1723         }
1724
1725         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1726                 printf("close2 failed (%s)\n", cli_errstr(cli2));
1727                 return False;
1728         }
1729
1730         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1731                 printf("unlink failed (%s)\n", cli_errstr(cli1));
1732                 return False;
1733         }
1734
1735         if (!torture_close_connection(cli1)) {
1736                 correct = False;
1737         }
1738
1739         if (!torture_close_connection(cli2)) {
1740                 correct = False;
1741         }
1742
1743         printf("finished locktest3\n");
1744
1745         return correct;
1746 }
1747
1748 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1749         printf("** "); correct = False; \
1750         }
1751
1752 /*
1753   looks at overlapping locks
1754 */
1755 static bool run_locktest4(int dummy)
1756 {
1757         static struct cli_state *cli1, *cli2;
1758         const char *fname = "\\lockt4.lck";
1759         uint16_t fnum1, fnum2, f;
1760         bool ret;
1761         char buf[1000];
1762         bool correct = True;
1763
1764         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1765                 return False;
1766         }
1767
1768         cli_sockopt(cli1, sockops);
1769         cli_sockopt(cli2, sockops);
1770
1771         printf("starting locktest4\n");
1772
1773         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1774
1775         cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1776         cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1777
1778         memset(buf, 0, sizeof(buf));
1779
1780         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1781                 printf("Failed to create file\n");
1782                 correct = False;
1783                 goto fail;
1784         }
1785
1786         ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1787               cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1788         EXPECTED(ret, False);
1789         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1790
1791         ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1792               cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1793         EXPECTED(ret, True);
1794         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1795
1796         ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1797               cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1798         EXPECTED(ret, False);
1799         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1800
1801         ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1802               cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1803         EXPECTED(ret, True);
1804         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1805
1806         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1807               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1808         EXPECTED(ret, False);
1809         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1810
1811         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1812               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1813         EXPECTED(ret, True);
1814         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1815
1816         ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1817               cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1818         EXPECTED(ret, True);
1819         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1820
1821         ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1822               cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1823         EXPECTED(ret, False);
1824         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1825
1826         ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1827               cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1828         EXPECTED(ret, False);
1829         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1830
1831         ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1832               cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1833         EXPECTED(ret, True);
1834         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1835
1836         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1837               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1838         EXPECTED(ret, False);
1839         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1840
1841         ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1842               cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1843               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1844         EXPECTED(ret, False);
1845         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1846
1847
1848         ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1849               (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1850         EXPECTED(ret, False);
1851         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1852
1853         ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1854               (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1855         EXPECTED(ret, False);
1856         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1857
1858
1859         ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1860               cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1861               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1862               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1863         EXPECTED(ret, True);
1864         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1865
1866
1867         ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1868               cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1869               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1870               (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1871               !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1872               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1873         EXPECTED(ret, True);
1874         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1875
1876         ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1877               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1878               (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&          
1879               (cli_read(cli2, fnum2, buf, 160, 4) == 4);                
1880         EXPECTED(ret, True);
1881         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1882
1883         ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1884               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1885               (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&          
1886               (cli_read(cli2, fnum2, buf, 170, 4) == 4);                
1887         EXPECTED(ret, True);
1888         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1889
1890         ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1891               cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1892               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1893               !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&         
1894               (cli_read(cli2, fnum2, buf, 190, 4) == 4);                
1895         EXPECTED(ret, True);
1896         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1897
1898         cli_close(cli1, fnum1);
1899         cli_close(cli2, fnum2);
1900         cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1901         cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1902         ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1903               cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1904               NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1905               NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1906               cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1907         cli_close(cli1, f);
1908         cli_close(cli1, fnum1);
1909         EXPECTED(ret, True);
1910         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1911
1912  fail:
1913         cli_close(cli1, fnum1);
1914         cli_close(cli2, fnum2);
1915         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1916         torture_close_connection(cli1);
1917         torture_close_connection(cli2);
1918
1919         printf("finished locktest4\n");
1920         return correct;
1921 }
1922
1923 /*
1924   looks at lock upgrade/downgrade.
1925 */
1926 static bool run_locktest5(int dummy)
1927 {
1928         static struct cli_state *cli1, *cli2;
1929         const char *fname = "\\lockt5.lck";
1930         uint16_t fnum1, fnum2, fnum3;
1931         bool ret;
1932         char buf[1000];
1933         bool correct = True;
1934
1935         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1936                 return False;
1937         }
1938
1939         cli_sockopt(cli1, sockops);
1940         cli_sockopt(cli2, sockops);
1941
1942         printf("starting locktest5\n");
1943
1944         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1945
1946         cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1947         cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1948         cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1949
1950         memset(buf, 0, sizeof(buf));
1951
1952         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1953                 printf("Failed to create file\n");
1954                 correct = False;
1955                 goto fail;
1956         }
1957
1958         /* Check for NT bug... */
1959         ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1960                   cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1961         cli_close(cli1, fnum1);
1962         cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1963         ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1964         EXPECTED(ret, True);
1965         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1966         cli_close(cli1, fnum1);
1967         cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1968         cli_unlock(cli1, fnum3, 0, 1);
1969
1970         ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1971               cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1972         EXPECTED(ret, True);
1973         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1974
1975         ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1976         EXPECTED(ret, False);
1977
1978         printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1979
1980         /* Unlock the process 2 lock. */
1981         cli_unlock(cli2, fnum2, 0, 4);
1982
1983         ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1984         EXPECTED(ret, False);
1985
1986         printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1987
1988         /* Unlock the process 1 fnum3 lock. */
1989         cli_unlock(cli1, fnum3, 0, 4);
1990
1991         /* Stack 2 more locks here. */
1992         ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1993                   cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1994
1995         EXPECTED(ret, True);
1996         printf("the same process %s stack read locks\n", ret?"can":"cannot");
1997
1998         /* Unlock the first process lock, then check this was the WRITE lock that was
1999                 removed. */
2000
2001         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2002                         cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2003
2004         EXPECTED(ret, True);
2005         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2006
2007         /* Unlock the process 2 lock. */
2008         cli_unlock(cli2, fnum2, 0, 4);
2009
2010         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2011
2012         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2013                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2014                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2015
2016         EXPECTED(ret, True);
2017         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
2018
2019         /* Ensure the next unlock fails. */
2020         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2021         EXPECTED(ret, False);
2022         printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
2023
2024         /* Ensure connection 2 can get a write lock. */
2025         ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2026         EXPECTED(ret, True);
2027
2028         printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2029
2030
2031  fail:
2032         cli_close(cli1, fnum1);
2033         cli_close(cli2, fnum2);
2034         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2035         if (!torture_close_connection(cli1)) {
2036                 correct = False;
2037         }
2038         if (!torture_close_connection(cli2)) {
2039                 correct = False;
2040         }
2041
2042         printf("finished locktest5\n");
2043
2044         return correct;
2045 }
2046
2047 /*
2048   tries the unusual lockingX locktype bits
2049 */
2050 static bool run_locktest6(int dummy)
2051 {
2052         static struct cli_state *cli;
2053         const char *fname[1] = { "\\lock6.txt" };
2054         int i;
2055         uint16_t fnum;
2056         NTSTATUS status;
2057
2058         if (!torture_open_connection(&cli, 0)) {
2059                 return False;
2060         }
2061
2062         cli_sockopt(cli, sockops);
2063
2064         printf("starting locktest6\n");
2065
2066         for (i=0;i<1;i++) {
2067                 printf("Testing %s\n", fname[i]);
2068
2069                 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2070
2071                 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2072                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2073                 cli_close(cli, fnum);
2074                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2075
2076                 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2077                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2078                 cli_close(cli, fnum);
2079                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2080
2081                 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2082         }
2083
2084         torture_close_connection(cli);
2085
2086         printf("finished locktest6\n");
2087         return True;
2088 }
2089
2090 static bool run_locktest7(int dummy)
2091 {
2092         struct cli_state *cli1;
2093         const char *fname = "\\lockt7.lck";
2094         uint16_t fnum1;
2095         char buf[200];
2096         bool correct = False;
2097
2098         if (!torture_open_connection(&cli1, 0)) {
2099                 return False;
2100         }
2101
2102         cli_sockopt(cli1, sockops);
2103
2104         printf("starting locktest7\n");
2105
2106         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2107
2108         cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2109
2110         memset(buf, 0, sizeof(buf));
2111
2112         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
2113                 printf("Failed to create file\n");
2114                 goto fail;
2115         }
2116
2117         cli_setpid(cli1, 1);
2118
2119         if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2120                 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2121                 goto fail;
2122         } else {
2123                 printf("pid1 successfully locked range 130:4 for READ\n");
2124         }
2125
2126         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2127                 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2128                 goto fail;
2129         } else {
2130                 printf("pid1 successfully read the range 130:4\n");
2131         }
2132
2133         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2134                 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2135                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2136                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2137                         goto fail;
2138                 }
2139         } else {
2140                 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2141                 goto fail;
2142         }
2143
2144         cli_setpid(cli1, 2);
2145
2146         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2147                 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2148         } else {
2149                 printf("pid2 successfully read the range 130:4\n");
2150         }
2151
2152         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2153                 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2154                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2155                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2156                         goto fail;
2157                 }
2158         } else {
2159                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2160                 goto fail;
2161         }
2162
2163         cli_setpid(cli1, 1);
2164         cli_unlock(cli1, fnum1, 130, 4);
2165
2166         if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2167                 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2168                 goto fail;
2169         } else {
2170                 printf("pid1 successfully locked range 130:4 for WRITE\n");
2171         }
2172
2173         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2174                 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2175                 goto fail;
2176         } else {
2177                 printf("pid1 successfully read the range 130:4\n");
2178         }
2179
2180         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2181                 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2182                 goto fail;
2183         } else {
2184                 printf("pid1 successfully wrote to the range 130:4\n");
2185         }
2186
2187         cli_setpid(cli1, 2);
2188
2189         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2190                 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2191                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2192                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2193                         goto fail;
2194                 }
2195         } else {
2196                 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2197                 goto fail;
2198         }
2199
2200         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2201                 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2202                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2203                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2204                         goto fail;
2205                 }
2206         } else {
2207                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2208                 goto fail;
2209         }
2210
2211         cli_unlock(cli1, fnum1, 130, 0);
2212         correct = True;
2213
2214 fail:
2215         cli_close(cli1, fnum1);
2216         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2217         torture_close_connection(cli1);
2218
2219         printf("finished locktest7\n");
2220         return correct;
2221 }
2222
2223 /*
2224  * This demonstrates a problem with our use of GPFS share modes: A file
2225  * descriptor sitting in the pending close queue holding a GPFS share mode
2226  * blocks opening a file another time. Happens with Word 2007 temp files.
2227  * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2228  * open is denied with NT_STATUS_SHARING_VIOLATION.
2229  */
2230
2231 static bool run_locktest8(int dummy)
2232 {
2233         struct cli_state *cli1;
2234         const char *fname = "\\lockt8.lck";
2235         uint16_t fnum1, fnum2;
2236         char buf[200];
2237         bool correct = False;
2238         NTSTATUS status;
2239
2240         if (!torture_open_connection(&cli1, 0)) {
2241                 return False;
2242         }
2243
2244         cli_sockopt(cli1, sockops);
2245
2246         printf("starting locktest8\n");
2247
2248         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2249
2250         status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2251                           &fnum1);
2252         if (!NT_STATUS_IS_OK(status)) {
2253                 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2254                 return false;
2255         }
2256
2257         memset(buf, 0, sizeof(buf));
2258
2259         status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2260         if (!NT_STATUS_IS_OK(status)) {
2261                 d_fprintf(stderr, "cli_open second time returned %s\n",
2262                           cli_errstr(cli1));
2263                 goto fail;
2264         }
2265
2266         if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2267                 printf("Unable to apply read lock on range 1:1, error was "
2268                        "%s\n", cli_errstr(cli1));
2269                 goto fail;
2270         }
2271
2272         status = cli_close(cli1, fnum1);
2273         if (!NT_STATUS_IS_OK(status)) {
2274                 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2275                 goto fail;
2276         }
2277
2278         status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2279         if (!NT_STATUS_IS_OK(status)) {
2280                 d_fprintf(stderr, "cli_open third time returned %s\n",
2281                           cli_errstr(cli1));
2282                 goto fail;
2283         }
2284
2285         correct = true;
2286
2287 fail:
2288         cli_close(cli1, fnum1);
2289         cli_close(cli1, fnum2);
2290         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2291         torture_close_connection(cli1);
2292
2293         printf("finished locktest8\n");
2294         return correct;
2295 }
2296
2297 /*
2298  * This test is designed to be run in conjunction with
2299  * external NFS or POSIX locks taken in the filesystem.
2300  * It checks that the smbd server will block until the
2301  * lock is released and then acquire it. JRA.
2302  */
2303
2304 static bool got_alarm;
2305 static int alarm_fd;
2306
2307 static void alarm_handler(int dummy)
2308 {
2309         got_alarm = True;
2310 }
2311
2312 static void alarm_handler_parent(int dummy)
2313 {
2314         close(alarm_fd);
2315 }
2316
2317 static void do_local_lock(int read_fd, int write_fd)
2318 {
2319         int fd;
2320         char c = '\0';
2321         struct flock lock;
2322         const char *local_pathname = NULL;
2323         int ret;
2324
2325         local_pathname = talloc_asprintf(talloc_tos(),
2326                         "%s/lockt9.lck", local_path);
2327         if (!local_pathname) {
2328                 printf("child: alloc fail\n");
2329                 exit(1);
2330         }
2331
2332         unlink(local_pathname);
2333         fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2334         if (fd == -1) {
2335                 printf("child: open of %s failed %s.\n",
2336                         local_pathname, strerror(errno));
2337                 exit(1);
2338         }
2339
2340         /* Now take a fcntl lock. */
2341         lock.l_type = F_WRLCK;
2342         lock.l_whence = SEEK_SET;
2343         lock.l_start = 0;
2344         lock.l_len = 4;
2345         lock.l_pid = getpid();
2346
2347         ret = fcntl(fd,F_SETLK,&lock);
2348         if (ret == -1) {
2349                 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2350                         local_pathname, strerror(errno));
2351                 exit(1);
2352         } else {
2353                 printf("child: got lock 0:4 on file %s.\n",
2354                         local_pathname );
2355                 fflush(stdout);
2356         }
2357
2358         CatchSignal(SIGALRM, alarm_handler);
2359         alarm(5);
2360         /* Signal the parent. */
2361         if (write(write_fd, &c, 1) != 1) {
2362                 printf("child: start signal fail %s.\n",
2363                         strerror(errno));
2364                 exit(1);
2365         }
2366         alarm(0);
2367
2368         alarm(10);
2369         /* Wait for the parent to be ready. */
2370         if (read(read_fd, &c, 1) != 1) {
2371                 printf("child: reply signal fail %s.\n",
2372                         strerror(errno));
2373                 exit(1);
2374         }
2375         alarm(0);
2376
2377         sleep(5);
2378         close(fd);
2379         printf("child: released lock 0:4 on file %s.\n",
2380                 local_pathname );
2381         fflush(stdout);
2382         exit(0);
2383 }
2384
2385 static bool run_locktest9(int dummy)
2386 {
2387         struct cli_state *cli1;
2388         const char *fname = "\\lockt9.lck";
2389         uint16_t fnum;
2390         bool correct = False;
2391         int pipe_in[2], pipe_out[2];
2392         pid_t child_pid;
2393         char c = '\0';
2394         int ret;
2395         struct timeval start;
2396         double seconds;
2397         NTSTATUS status;
2398
2399         printf("starting locktest9\n");
2400
2401         if (local_path == NULL) {
2402                 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2403                 return false;
2404         }
2405
2406         if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2407                 return false;
2408         }
2409
2410         child_pid = fork();
2411         if (child_pid == -1) {
2412                 return false;
2413         }
2414
2415         if (child_pid == 0) {
2416                 /* Child. */
2417                 do_local_lock(pipe_out[0], pipe_in[1]);
2418                 exit(0);
2419         }
2420
2421         close(pipe_out[0]);
2422         close(pipe_in[1]);
2423         pipe_out[0] = -1;
2424         pipe_in[1] = -1;
2425
2426         /* Parent. */
2427         ret = read(pipe_in[0], &c, 1);
2428         if (ret != 1) {
2429                 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2430                         strerror(errno));
2431                 return false;
2432         }
2433
2434         if (!torture_open_connection(&cli1, 0)) {
2435                 return false;
2436         }
2437
2438         cli_sockopt(cli1, sockops);
2439
2440         status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2441                           &fnum);
2442         if (!NT_STATUS_IS_OK(status)) {
2443                 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2444                 return false;
2445         }
2446
2447         /* Ensure the child has the lock. */
2448         if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2449                 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2450                 goto fail;
2451         } else {
2452                 d_printf("Child has the lock.\n");
2453         }
2454
2455         /* Tell the child to wait 5 seconds then exit. */
2456         ret = write(pipe_out[1], &c, 1);
2457         if (ret != 1) {
2458                 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2459                         strerror(errno));
2460                 goto fail;
2461         }
2462
2463         /* Wait 20 seconds for the lock. */
2464         alarm_fd = cli1->fd;
2465         CatchSignal(SIGALRM, alarm_handler_parent);
2466         alarm(20);
2467
2468         start = timeval_current();
2469
2470         if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2471                 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2472                        "%s\n", cli_errstr(cli1));
2473                 goto fail_nofd;
2474         }
2475         alarm(0);
2476
2477         seconds = timeval_elapsed(&start);
2478
2479         printf("Parent got the lock after %.2f seconds.\n",
2480                 seconds);
2481
2482         status = cli_close(cli1, fnum);
2483         if (!NT_STATUS_IS_OK(status)) {
2484                 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2485                 goto fail;
2486         }
2487
2488         correct = true;
2489
2490 fail:
2491         cli_close(cli1, fnum);
2492         torture_close_connection(cli1);
2493
2494 fail_nofd:
2495
2496         printf("finished locktest9\n");
2497         return correct;
2498 }
2499
2500 /*
2501 test whether fnums and tids open on one VC are available on another (a major
2502 security hole)
2503 */
2504 static bool run_fdpasstest(int dummy)
2505 {
2506         struct cli_state *cli1, *cli2;
2507         const char *fname = "\\fdpass.tst";
2508         uint16_t fnum1;
2509         char buf[1024];
2510
2511         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2512                 return False;
2513         }
2514         cli_sockopt(cli1, sockops);
2515         cli_sockopt(cli2, sockops);
2516
2517         printf("starting fdpasstest\n");
2518
2519         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2520
2521         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2522                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2523                 return False;
2524         }
2525
2526         if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2527                 printf("write failed (%s)\n", cli_errstr(cli1));
2528                 return False;
2529         }
2530
2531         cli2->vuid = cli1->vuid;
2532         cli2->cnum = cli1->cnum;
2533         cli2->pid = cli1->pid;
2534
2535         if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2536                 printf("read succeeded! nasty security hole [%s]\n",
2537                        buf);
2538                 return False;
2539         }
2540
2541         cli_close(cli1, fnum1);
2542         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2543
2544         torture_close_connection(cli1);
2545         torture_close_connection(cli2);
2546
2547         printf("finished fdpasstest\n");
2548         return True;
2549 }
2550
2551 static bool run_fdsesstest(int dummy)
2552 {
2553         struct cli_state *cli;
2554         uint16 new_vuid;
2555         uint16 saved_vuid;
2556         uint16 new_cnum;
2557         uint16 saved_cnum;
2558         const char *fname = "\\fdsess.tst";
2559         const char *fname1 = "\\fdsess1.tst";
2560         uint16_t fnum1;
2561         uint16_t fnum2;
2562         char buf[1024];
2563         bool ret = True;
2564
2565         if (!torture_open_connection(&cli, 0))
2566                 return False;
2567         cli_sockopt(cli, sockops);
2568
2569         if (!torture_cli_session_setup2(cli, &new_vuid))
2570                 return False;
2571
2572         saved_cnum = cli->cnum;
2573         if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2574                 return False;
2575         new_cnum = cli->cnum;
2576         cli->cnum = saved_cnum;
2577
2578         printf("starting fdsesstest\n");
2579
2580         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2581         cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2582
2583         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2584                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2585                 return False;
2586         }
2587
2588         if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2589                 printf("write failed (%s)\n", cli_errstr(cli));
2590                 return False;
2591         }
2592
2593         saved_vuid = cli->vuid;
2594         cli->vuid = new_vuid;
2595
2596         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2597                 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2598                        buf);
2599                 ret = False;
2600         }
2601         /* Try to open a file with different vuid, samba cnum. */
2602         if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2603                 printf("create with different vuid, same cnum succeeded.\n");
2604                 cli_close(cli, fnum2);
2605                 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2606         } else {
2607                 printf("create with different vuid, same cnum failed.\n");
2608                 printf("This will cause problems with service clients.\n");
2609                 ret = False;
2610         }
2611
2612         cli->vuid = saved_vuid;
2613
2614         /* Try with same vuid, different cnum. */
2615         cli->cnum = new_cnum;
2616
2617         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2618                 printf("read succeeded with different cnum![%s]\n",
2619                        buf);
2620                 ret = False;
2621         }
2622
2623         cli->cnum = saved_cnum;
2624         cli_close(cli, fnum1);
2625         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2626
2627         torture_close_connection(cli);
2628
2629         printf("finished fdsesstest\n");
2630         return ret;
2631 }
2632
2633 /*
2634   This test checks that 
2635
2636   1) the server does not allow an unlink on a file that is open
2637 */
2638 static bool run_unlinktest(int dummy)
2639 {
2640         struct cli_state *cli;
2641         const char *fname = "\\unlink.tst";
2642         uint16_t fnum;
2643         bool correct = True;
2644
2645         if (!torture_open_connection(&cli, 0)) {
2646                 return False;
2647         }
2648
2649         cli_sockopt(cli, sockops);
2650
2651         printf("starting unlink test\n");
2652
2653         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2654
2655         cli_setpid(cli, 1);
2656
2657         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2658                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2659                 return False;
2660         }
2661
2662         if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2663                 printf("error: server allowed unlink on an open file\n");
2664                 correct = False;
2665         } else {
2666                 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare, 
2667                                       NT_STATUS_SHARING_VIOLATION);
2668         }
2669
2670         cli_close(cli, fnum);
2671         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2672
2673         if (!torture_close_connection(cli)) {
2674                 correct = False;
2675         }
2676
2677         printf("unlink test finished\n");
2678
2679         return correct;
2680 }
2681
2682
2683 /*
2684 test how many open files this server supports on the one socket
2685 */
2686 static bool run_maxfidtest(int dummy)
2687 {
2688         struct cli_state *cli;
2689         const char *ftemplate = "\\maxfid.%d.%d";
2690         fstring fname;
2691         uint16_t fnums[0x11000];
2692         int i;
2693         int retries=4;
2694         bool correct = True;
2695
2696         cli = current_cli;
2697
2698         if (retries <= 0) {
2699                 printf("failed to connect\n");
2700                 return False;
2701         }
2702
2703         cli_sockopt(cli, sockops);
2704
2705         for (i=0; i<0x11000; i++) {
2706                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2707                 if (!NT_STATUS_IS_OK(cli_open(cli, fname, 
2708                                         O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2709                         printf("open of %s failed (%s)\n", 
2710                                fname, cli_errstr(cli));
2711                         printf("maximum fnum is %d\n", i);
2712                         break;
2713                 }
2714                 printf("%6d\r", i);
2715         }
2716         printf("%6d\n", i);
2717         i--;
2718
2719         printf("cleaning up\n");
2720         for (;i>=0;i--) {
2721                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2722                 cli_close(cli, fnums[i]);
2723                 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2724                         printf("unlink of %s failed (%s)\n", 
2725                                fname, cli_errstr(cli));
2726                         correct = False;
2727                 }
2728                 printf("%6d\r", i);
2729         }
2730         printf("%6d\n", 0);
2731
2732         printf("maxfid test finished\n");
2733         if (!torture_close_connection(cli)) {
2734                 correct = False;
2735         }
2736         return correct;
2737 }
2738
2739 /* generate a random buffer */
2740 static void rand_buf(char *buf, int len)
2741 {
2742         while (len--) {
2743                 *buf = (char)sys_random();
2744                 buf++;
2745         }
2746 }
2747
2748 /* send smb negprot commands, not reading the response */
2749 static bool run_negprot_nowait(int dummy)
2750 {
2751         int i;
2752         static struct cli_state *cli;
2753         bool correct = True;
2754
2755         printf("starting negprot nowait test\n");
2756
2757         if (!(cli = open_nbt_connection())) {
2758                 return False;
2759         }
2760
2761         for (i=0;i<50000;i++) {
2762                 cli_negprot_sendsync(cli);
2763         }
2764
2765         if (!torture_close_connection(cli)) {
2766                 correct = False;
2767         }
2768
2769         printf("finished negprot nowait test\n");
2770
2771         return correct;
2772 }
2773
2774 /* send smb negprot commands, not reading the response */
2775 static bool run_bad_nbt_session(int dummy)
2776 {
2777         static struct cli_state *cli;
2778
2779         printf("starting bad nbt session test\n");
2780
2781         if (!(cli = open_bad_nbt_connection())) {
2782                 return False;
2783         }
2784
2785         cli_shutdown(cli);
2786         printf("finished bad nbt session test\n");
2787         return true;
2788 }
2789
2790 /* send random IPC commands */
2791 static bool run_randomipc(int dummy)
2792 {
2793         char *rparam = NULL;
2794         char *rdata = NULL;
2795         unsigned int rdrcnt,rprcnt;
2796         char param[1024];
2797         int api, param_len, i;
2798         struct cli_state *cli;
2799         bool correct = True;
2800         int count = 50000;
2801
2802         printf("starting random ipc test\n");
2803
2804         if (!torture_open_connection(&cli, 0)) {
2805                 return False;
2806         }
2807
2808         for (i=0;i<count;i++) {
2809                 api = sys_random() % 500;
2810                 param_len = (sys_random() % 64);
2811
2812                 rand_buf(param, param_len);
2813
2814                 SSVAL(param,0,api); 
2815
2816                 cli_api(cli, 
2817                         param, param_len, 8,  
2818                         NULL, 0, BUFFER_SIZE, 
2819                         &rparam, &rprcnt,     
2820                         &rdata, &rdrcnt);
2821                 if (i % 100 == 0) {
2822                         printf("%d/%d\r", i,count);
2823                 }
2824         }
2825         printf("%d/%d\n", i, count);
2826
2827         if (!torture_close_connection(cli)) {
2828                 correct = False;
2829         }
2830
2831         printf("finished random ipc test\n");
2832
2833         return correct;
2834 }
2835
2836
2837
2838 static void browse_callback(const char *sname, uint32 stype, 
2839                             const char *comment, void *state)
2840 {
2841         printf("\t%20.20s %08x %s\n", sname, stype, comment);
2842 }
2843
2844
2845
2846 /*
2847   This test checks the browse list code
2848
2849 */
2850 static bool run_browsetest(int dummy)
2851 {
2852         static struct cli_state *cli;
2853         bool correct = True;
2854
2855         printf("starting browse test\n");
2856
2857         if (!torture_open_connection(&cli, 0)) {
2858                 return False;
2859         }
2860
2861         printf("domain list:\n");
2862         cli_NetServerEnum(cli, cli->server_domain, 
2863                           SV_TYPE_DOMAIN_ENUM,
2864                           browse_callback, NULL);
2865
2866         printf("machine list:\n");
2867         cli_NetServerEnum(cli, cli->server_domain, 
2868                           SV_TYPE_ALL,
2869                           browse_callback, NULL);
2870
2871         if (!torture_close_connection(cli)) {
2872                 correct = False;
2873         }
2874
2875         printf("browse test finished\n");
2876
2877         return correct;
2878
2879 }
2880
2881
2882 /*
2883   This checks how the getatr calls works
2884 */
2885 static bool run_attrtest(int dummy)
2886 {
2887         struct cli_state *cli;
2888         uint16_t fnum;
2889         time_t t, t2;
2890         const char *fname = "\\attrib123456789.tst";
2891         bool correct = True;
2892
2893         printf("starting attrib test\n");
2894
2895         if (!torture_open_connection(&cli, 0)) {
2896                 return False;
2897         }
2898
2899         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2900         cli_open(cli, fname, 
2901                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2902         cli_close(cli, fnum);
2903         if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2904                 printf("getatr failed (%s)\n", cli_errstr(cli));
2905                 correct = False;
2906         }
2907
2908         if (abs(t - time(NULL)) > 60*60*24*10) {
2909                 printf("ERROR: SMBgetatr bug. time is %s",
2910                        ctime(&t));
2911                 t = time(NULL);
2912                 correct = True;
2913         }
2914
2915         t2 = t-60*60*24; /* 1 day ago */
2916
2917         if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2918                 printf("setatr failed (%s)\n", cli_errstr(cli));
2919                 correct = True;
2920         }
2921
2922         if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2923                 printf("getatr failed (%s)\n", cli_errstr(cli));
2924                 correct = True;
2925         }
2926
2927         if (t != t2) {
2928                 printf("ERROR: getatr/setatr bug. times are\n%s",
2929                        ctime(&t));
2930                 printf("%s", ctime(&t2));
2931                 correct = True;
2932         }
2933
2934         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2935
2936         if (!torture_close_connection(cli)) {
2937                 correct = False;
2938         }
2939
2940         printf("attrib test finished\n");
2941
2942         return correct;
2943 }
2944
2945
2946 /*
2947   This checks a couple of trans2 calls
2948 */
2949 static bool run_trans2test(int dummy)
2950 {
2951         struct cli_state *cli;
2952         uint16_t fnum;
2953         SMB_OFF_T size;
2954         time_t c_time, a_time, m_time;
2955         struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2956         const char *fname = "\\trans2.tst";
2957         const char *dname = "\\trans2";
2958         const char *fname2 = "\\trans2\\trans2.tst";
2959         char pname[1024];
2960         bool correct = True;
2961         NTSTATUS status;
2962         uint32_t fs_attr;
2963
2964         printf("starting trans2 test\n");
2965
2966         if (!torture_open_connection(&cli, 0)) {
2967                 return False;
2968         }
2969
2970         status = cli_get_fs_attr_info(cli, &fs_attr);
2971         if (!NT_STATUS_IS_OK(status)) {
2972                 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2973                        nt_errstr(status));
2974                 correct = false;
2975         }
2976
2977         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2978         cli_open(cli, fname, 
2979                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2980         if (!cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
2981                                  &a_time_ts, &w_time_ts,
2982                            &m_time_ts, NULL)) {
2983                 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2984                 correct = False;
2985         }
2986
2987         if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2988                 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2989                 correct = False;
2990         }
2991
2992         if (strcmp(pname, fname)) {
2993                 printf("qfilename gave different name? [%s] [%s]\n",
2994                        fname, pname);
2995                 correct = False;
2996         }
2997
2998         cli_close(cli, fnum);
2999
3000         sleep(2);
3001
3002         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3003         if (!NT_STATUS_IS_OK(cli_open(cli, fname, 
3004                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
3005                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3006                 return False;
3007         }
3008         cli_close(cli, fnum);
3009
3010         status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3011                                 NULL);
3012         if (!NT_STATUS_IS_OK(status)) {
3013                 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3014                 correct = False;
3015         } else {
3016                 if (c_time != m_time) {
3017                         printf("create time=%s", ctime(&c_time));
3018                         printf("modify time=%s", ctime(&m_time));
3019                         printf("This system appears to have sticky create times\n");
3020                 }
3021                 if (a_time % (60*60) == 0) {
3022                         printf("access time=%s", ctime(&a_time));
3023                         printf("This system appears to set a midnight access time\n");
3024                         correct = False;
3025                 }
3026
3027                 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3028                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3029                         correct = False;
3030                 }
3031         }
3032
3033
3034         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3035         cli_open(cli, fname, 
3036                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3037         cli_close(cli, fnum);
3038         status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3039                                 &m_time_ts, &size, NULL, NULL);
3040         if (!NT_STATUS_IS_OK(status)) {
3041                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3042                 correct = False;
3043         } else {
3044                 if (w_time_ts.tv_sec < 60*60*24*2) {
3045                         printf("write time=%s", ctime(&w_time_ts.tv_sec));
3046                         printf("This system appears to set a initial 0 write time\n");
3047                         correct = False;
3048                 }
3049         }
3050
3051         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3052
3053
3054         /* check if the server updates the directory modification time
3055            when creating a new file */
3056         if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
3057                 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
3058                 correct = False;
3059         }
3060         sleep(3);
3061         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3062                                 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3063         if (!NT_STATUS_IS_OK(status)) {
3064                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3065                 correct = False;
3066         }
3067
3068         cli_open(cli, fname2, 
3069                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3070         cli_write(cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
3071         cli_close(cli, fnum);
3072         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3073                                 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3074         if (!NT_STATUS_IS_OK(status)) {
3075                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3076                 correct = False;
3077         } else {
3078                 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3079                     == 0) {
3080                         printf("This system does not update directory modification times\n");
3081                         correct = False;
3082                 }
3083         }
3084         cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
3085         cli_rmdir(cli, dname);
3086
3087         if (!torture_close_connection(cli)) {
3088                 correct = False;
3089         }
3090
3091         printf("trans2 test finished\n");
3092
3093         return correct;
3094 }
3095
3096 /*
3097   This checks new W2K calls.
3098 */
3099
3100 static bool new_trans(struct cli_state *pcli, int fnum, int level)
3101 {
3102         char *buf = NULL;
3103         uint32 len;
3104         bool correct = True;
3105
3106         if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
3107                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
3108                 correct = False;
3109         } else {
3110                 printf("qfileinfo: level %d, len = %u\n", level, len);
3111                 dump_data(0, (uint8 *)buf, len);
3112                 printf("\n");
3113         }
3114         SAFE_FREE(buf);
3115         return correct;
3116 }
3117
3118 static bool run_w2ktest(int dummy)
3119 {
3120         struct cli_state *cli;
3121         uint16_t fnum;
3122         const char *fname = "\\w2ktest\\w2k.tst";
3123         int level;
3124         bool correct = True;
3125
3126         printf("starting w2k test\n");
3127
3128         if (!torture_open_connection(&cli, 0)) {
3129                 return False;
3130         }
3131
3132         cli_open(cli, fname, 
3133                         O_RDWR | O_CREAT , DENY_NONE, &fnum);
3134
3135         for (level = 1004; level < 1040; level++) {
3136                 new_trans(cli, fnum, level);
3137         }
3138
3139         cli_close(cli, fnum);
3140
3141         if (!torture_close_connection(cli)) {
3142                 correct = False;
3143         }
3144
3145         printf("w2k test finished\n");
3146
3147         return correct;
3148 }
3149
3150
3151 /*
3152   this is a harness for some oplock tests
3153  */
3154 static bool run_oplock1(int dummy)
3155 {
3156         struct cli_state *cli1;
3157         const char *fname = "\\lockt1.lck";
3158         uint16_t fnum1;
3159         bool correct = True;
3160
3161         printf("starting oplock test 1\n");
3162
3163         if (!torture_open_connection(&cli1, 0)) {
3164                 return False;
3165         }
3166
3167         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3168
3169         cli_sockopt(cli1, sockops);
3170
3171         cli1->use_oplocks = True;
3172
3173         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3174                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3175                 return False;
3176         }
3177
3178         cli1->use_oplocks = False;
3179
3180         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3181         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3182
3183         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3184                 printf("close2 failed (%s)\n", cli_errstr(cli1));
3185                 return False;
3186         }
3187
3188         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3189                 printf("unlink failed (%s)\n", cli_errstr(cli1));
3190                 return False;
3191         }
3192
3193         if (!torture_close_connection(cli1)) {
3194                 correct = False;
3195         }
3196
3197         printf("finished oplock test 1\n");
3198
3199         return correct;
3200 }
3201
3202 static bool run_oplock2(int dummy)
3203 {
3204         struct cli_state *cli1, *cli2;
3205         const char *fname = "\\lockt2.lck";
3206         uint16_t fnum1, fnum2;
3207         int saved_use_oplocks = use_oplocks;
3208         char buf[4];
3209         bool correct = True;
3210         volatile bool *shared_correct;
3211
3212         shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3213         *shared_correct = True;
3214
3215         use_level_II_oplocks = True;
3216         use_oplocks = True;
3217
3218         printf("starting oplock test 2\n");
3219
3220         if (!torture_open_connection(&cli1, 0)) {
3221                 use_level_II_oplocks = False;
3222                 use_oplocks = saved_use_oplocks;
3223                 return False;
3224         }
3225
3226         cli1->use_oplocks = True;
3227         cli1->use_level_II_oplocks = True;
3228
3229         if (!torture_open_connection(&cli2, 1)) {
3230                 use_level_II_oplocks = False;
3231                 use_oplocks = saved_use_oplocks;
3232                 return False;
3233         }
3234
3235         cli2->use_oplocks = True;
3236         cli2->use_level_II_oplocks = True;
3237
3238         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3239
3240         cli_sockopt(cli1, sockops);
3241         cli_sockopt(cli2, sockops);
3242
3243         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3244                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3245                 return False;
3246         }
3247
3248         /* Don't need the globals any more. */
3249         use_level_II_oplocks = False;
3250         use_oplocks = saved_use_oplocks;
3251
3252         if (fork() == 0) {
3253                 /* Child code */
3254                 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3255                         printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3256                         *shared_correct = False;
3257                         exit(0);
3258                 }
3259
3260                 sleep(2);
3261
3262                 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3263                         printf("close2 failed (%s)\n", cli_errstr(cli1));
3264                         *shared_correct = False;
3265                 }
3266
3267                 exit(0);
3268         }
3269
3270         sleep(2);
3271
3272         /* Ensure cli1 processes the break. Empty file should always return 0
3273          * bytes.  */
3274
3275         if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3276                 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3277                 correct = False;
3278         }
3279
3280         /* Should now be at level II. */
3281         /* Test if sending a write locks causes a break to none. */
3282
3283         if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3284                 printf("lock failed (%s)\n", cli_errstr(cli1));
3285                 correct = False;
3286         }
3287
3288         cli_unlock(cli1, fnum1, 0, 4);
3289
3290         sleep(2);
3291
3292         if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3293                 printf("lock failed (%s)\n", cli_errstr(cli1));
3294                 correct = False;
3295         }
3296
3297         cli_unlock(cli1, fnum1, 0, 4);
3298
3299         sleep(2);
3300
3301         cli_read(cli1, fnum1, buf, 0, 4);
3302
3303 #if 0
3304         if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3305                 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3306                 correct = False;
3307         }
3308 #endif
3309
3310         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3311                 printf("close1 failed (%s)\n", cli_errstr(cli1));
3312                 correct = False;
3313         }
3314
3315         sleep(4);
3316
3317         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3318                 printf("unlink failed (%s)\n", cli_errstr(cli1));
3319                 correct = False;
3320         }
3321
3322         if (!torture_close_connection(cli1)) {
3323                 correct = False;
3324         }
3325
3326         if (!*shared_correct) {
3327                 correct = False;
3328         }
3329
3330         printf("finished oplock test 2\n");
3331
3332         return correct;
3333 }
3334
3335 /* handler for oplock 3 tests */
3336 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3337 {
3338         printf("got oplock break fnum=%d level=%d\n",
3339                fnum, level);
3340         return cli_oplock_ack(cli, fnum, level);
3341 }
3342
3343 static bool run_oplock3(int dummy)
3344 {
3345         struct cli_state *cli;
3346         const char *fname = "\\oplockt3.dat";
3347         uint16_t fnum;
3348         char buf[4] = "abcd";
3349         bool correct = True;
3350         volatile bool *shared_correct;
3351
3352         shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3353         *shared_correct = True;
3354
3355         printf("starting oplock test 3\n");
3356
3357         if (fork() == 0) {
3358                 /* Child code */
3359                 use_oplocks = True;
3360                 use_level_II_oplocks = True;
3361                 if (!torture_open_connection(&cli, 0)) {
3362                         *shared_correct = False;
3363                         exit(0);
3364                 } 
3365                 sleep(2);
3366                 /* try to trigger a oplock break in parent */
3367                 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3368                 cli_write(cli, fnum, 0, buf, 0, 4);
3369                 exit(0);
3370         }
3371
3372         /* parent code */
3373         use_oplocks = True;
3374         use_level_II_oplocks = True;
3375         if (!torture_open_connection(&cli, 1)) { /* other is forked */
3376                 return False;
3377         }
3378         cli_oplock_handler(cli, oplock3_handler);
3379         cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3380         cli_write(cli, fnum, 0, buf, 0, 4);
3381         cli_close(cli, fnum);
3382         cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3383         cli->timeout = 20000;
3384         cli_receive_smb(cli);
3385         printf("finished oplock test 3\n");
3386
3387         return (correct && *shared_correct);
3388
3389 /* What are we looking for here?  What's sucess and what's FAILURE? */
3390 }
3391
3392
3393
3394 /*
3395   Test delete on close semantics.
3396  */
3397 static bool run_deletetest(int dummy)
3398 {
3399         struct cli_state *cli1 = NULL;
3400         struct cli_state *cli2 = NULL;
3401         const char *fname = "\\delete.file";
3402         uint16_t fnum1 = (uint16_t)-1;
3403         uint16_t fnum2 = (uint16_t)-1;
3404         bool correct = True;
3405
3406         printf("starting delete test\n");
3407
3408         if (!torture_open_connection(&cli1, 0)) {
3409                 return False;
3410         }
3411
3412         cli_sockopt(cli1, sockops);
3413
3414         /* Test 1 - this should delete the file on close. */
3415
3416         cli_setatr(cli1, fname, 0, 0);
3417         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3418
3419         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3420                                    0, FILE_OVERWRITE_IF, 
3421                                    FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3422                 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3423                 correct = False;
3424                 goto fail;
3425         }
3426
3427 #if 0 /* JRATEST */
3428         {
3429                 uint32 *accinfo = NULL;
3430                 uint32 len;
3431                 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3432                 if (accinfo)
3433                         printf("access mode = 0x%lx\n", *accinfo);
3434                 SAFE_FREE(accinfo);
3435         }
3436 #endif
3437
3438         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3439                 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3440                 correct = False;
3441                 goto fail;
3442         }
3443
3444         if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3445                 printf("[1] open of %s succeeded (should fail)\n", fname);
3446                 correct = False;
3447                 goto fail;
3448         }
3449
3450         printf("first delete on close test succeeded.\n");
3451
3452         /* Test 2 - this should delete the file on close. */
3453
3454         cli_setatr(cli1, fname, 0, 0);
3455         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3456
3457         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3458                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, 
3459                                    FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3460                 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3461                 correct = False;
3462                 goto fail;
3463         }
3464
3465         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3466                 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3467                 correct = False;
3468                 goto fail;
3469         }
3470
3471         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3472                 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3473                 correct = False;
3474                 goto fail;
3475         }
3476
3477         if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3478                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3479                 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3480                         printf("[2] close failed (%s)\n", cli_errstr(cli1));
3481                         correct = False;
3482                         goto fail;
3483                 }
3484                 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3485         } else
3486                 printf("second delete on close test succeeded.\n");
3487
3488         /* Test 3 - ... */
3489         cli_setatr(cli1, fname, 0, 0);
3490         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3491
3492         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3493                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3494                 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3495                 correct = False;
3496                 goto fail;
3497         }
3498
3499         /* This should fail with a sharing violation - open for delete is only compatible
3500            with SHARE_DELETE. */
3501
3502         if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3503                         FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3504                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
3505                 correct = False;
3506                 goto fail;
3507         }
3508
3509         /* This should succeed. */
3510
3511         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3512                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3513                 printf("[3] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3514                 correct = False;
3515                 goto fail;
3516         }
3517
3518         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3519                 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3520                 correct = False;
3521                 goto fail;
3522         }
3523
3524         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3525                 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3526                 correct = False;
3527                 goto fail;
3528         }
3529
3530         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3531                 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3532                 correct = False;
3533                 goto fail;
3534         }
3535
3536         /* This should fail - file should no longer be there. */
3537
3538         if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3539                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3540                 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3541                         printf("[3] close failed (%s)\n", cli_errstr(cli1));
3542                 }
3543                 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3544                 correct = False;
3545                 goto fail;
3546         } else
3547                 printf("third delete on close test succeeded.\n");
3548
3549         /* Test 4 ... */
3550         cli_setatr(cli1, fname, 0, 0);
3551         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3552
3553         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3554                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3555                 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3556                 correct = False;
3557                 goto fail;
3558         }
3559
3560         /* This should succeed. */
3561         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3562                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3563                 printf("[4] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3564                 correct = False;
3565                 goto fail;
3566         }
3567
3568         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3569                 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3570                 correct = False;
3571                 goto fail;
3572         }
3573
3574         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3575                 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3576                 correct = False;
3577                 goto fail;
3578         }
3579
3580         /* This should fail - no more opens once delete on close set. */
3581         if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3582                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3583                                    FILE_OPEN, 0, 0, &fnum2))) {
3584                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
3585                 correct = False;
3586                 goto fail;
3587         } else
3588                 printf("fourth delete on close test succeeded.\n");
3589
3590         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3591                 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3592                 correct = False;
3593                 goto fail;
3594         }
3595
3596         /* Test 5 ... */
3597         cli_setatr(cli1, fname, 0, 0);
3598         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3599
3600         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3601                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3602                 correct = False;
3603                 goto fail;
3604         }
3605
3606         /* This should fail - only allowed on NT opens with DELETE access. */
3607
3608         if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3609                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3610                 correct = False;
3611                 goto fail;
3612         }
3613
3614         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3615                 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3616                 correct = False;
3617                 goto fail;
3618         }
3619
3620         printf("fifth delete on close test succeeded.\n");
3621
3622         /* Test 6 ... */
3623         cli_setatr(cli1, fname, 0, 0);
3624         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3625
3626         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3627                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,