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