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