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