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