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