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