Reproduce a bug with a custom GET_REAL_FILENAME
[ira/wip.git] / source3 / torture / torture.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB torture tester
4    Copyright (C) Andrew Tridgell 1997-1998
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21 #include "wbc_async.h"
22
23 extern char *optarg;
24 extern int optind;
25
26 static fstring host, workgroup, share, password, username, myname;
27 static int max_protocol = PROTOCOL_NT1;
28 static const char *sockops="TCP_NODELAY";
29 static int nprocs=1;
30 static int port_to_use=0;
31 int torture_numops=100;
32 int torture_blocksize=1024*1024;
33 static int procnum; /* records process count number when forking */
34 static struct cli_state *current_cli;
35 static fstring randomfname;
36 static bool use_oplocks;
37 static bool use_level_II_oplocks;
38 static const char *client_txt = "client_oplocks.txt";
39 static bool use_kerberos;
40 static fstring multishare_conn_fname;
41 static bool use_multishare_conn = False;
42 static bool do_encrypt;
43
44 bool torture_showall = False;
45
46 static double create_procs(bool (*fn)(int), bool *result);
47
48
49 static struct timeval tp1,tp2;
50
51
52 void start_timer(void)
53 {
54         GetTimeOfDay(&tp1);
55 }
56
57 double end_timer(void)
58 {
59         GetTimeOfDay(&tp2);
60         return((tp2.tv_sec - tp1.tv_sec) + 
61                (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
62 }
63
64
65 /* return a pointer to a anonymous shared memory segment of size "size"
66    which will persist across fork() but will disappear when all processes
67    exit 
68
69    The memory is not zeroed 
70
71    This function uses system5 shared memory. It takes advantage of a property
72    that the memory is not destroyed if it is attached when the id is removed
73    */
74 void *shm_setup(int size)
75 {
76         int shmid;
77         void *ret;
78
79         shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
80         if (shmid == -1) {
81                 printf("can't get shared memory\n");
82                 exit(1);
83         }
84         ret = (void *)shmat(shmid, 0, 0);
85         if (!ret || ret == (void *)-1) {
86                 printf("can't attach to shared memory\n");
87                 return NULL;
88         }
89         /* the following releases the ipc, but note that this process
90            and all its children will still have access to the memory, its
91            just that the shmid is no longer valid for other shm calls. This
92            means we don't leave behind lots of shm segments after we exit 
93
94            See Stevens "advanced programming in unix env" for details
95            */
96         shmctl(shmid, IPC_RMID, 0);
97         
98         return ret;
99 }
100
101 /********************************************************************
102  Ensure a connection is encrypted.
103 ********************************************************************/
104
105 static bool force_cli_encryption(struct cli_state *c,
106                         const char *sharename)
107 {
108         uint16 major, minor;
109         uint32 caplow, caphigh;
110         NTSTATUS status;
111
112         if (!SERVER_HAS_UNIX_CIFS(c)) {
113                 d_printf("Encryption required and "
114                         "server that doesn't support "
115                         "UNIX extensions - failing connect\n");
116                         return false;
117         }
118
119         if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) {
120                 d_printf("Encryption required and "
121                         "can't get UNIX CIFS extensions "
122                         "version from server.\n");
123                 return false;
124         }
125
126         if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
127                 d_printf("Encryption required and "
128                         "share %s doesn't support "
129                         "encryption.\n", sharename);
130                 return false;
131         }
132
133         if (c->use_kerberos) {
134                 status = cli_gss_smb_encryption_start(c);
135         } else {
136                 status = cli_raw_ntlm_smb_encryption_start(c,
137                                                 username,
138                                                 password,
139                                                 workgroup);
140         }
141
142         if (!NT_STATUS_IS_OK(status)) {
143                 d_printf("Encryption required and "
144                         "setup failed with error %s.\n",
145                         nt_errstr(status));
146                 return false;
147         }
148
149         return true;
150 }
151
152
153 static struct cli_state *open_nbt_connection(void)
154 {
155         struct nmb_name called, calling;
156         struct sockaddr_storage ss;
157         struct cli_state *c;
158         NTSTATUS status;
159
160         make_nmb_name(&calling, myname, 0x0);
161         make_nmb_name(&called , host, 0x20);
162
163         zero_sockaddr(&ss);
164
165         if (!(c = cli_initialise())) {
166                 printf("Failed initialize cli_struct to connect with %s\n", host);
167                 return NULL;
168         }
169
170         c->port = port_to_use;
171
172         status = cli_connect(c, host, &ss);
173         if (!NT_STATUS_IS_OK(status)) {
174                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
175                 return NULL;
176         }
177
178         c->use_kerberos = use_kerberos;
179
180         c->timeout = 120000; /* set a really long timeout (2 minutes) */
181         if (use_oplocks) c->use_oplocks = True;
182         if (use_level_II_oplocks) c->use_level_II_oplocks = True;
183
184         if (!cli_session_request(c, &calling, &called)) {
185                 /*
186                  * Well, that failed, try *SMBSERVER ...
187                  * However, we must reconnect as well ...
188                  */
189                 status = cli_connect(c, host, &ss);
190                 if (!NT_STATUS_IS_OK(status)) {
191                         printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
192                         return NULL;
193                 }
194
195                 make_nmb_name(&called, "*SMBSERVER", 0x20);
196                 if (!cli_session_request(c, &calling, &called)) {
197                         printf("%s rejected the session\n",host);
198                         printf("We tried with a called name of %s & %s\n",
199                                 host, "*SMBSERVER");
200                         cli_shutdown(c);
201                         return NULL;
202                 }
203         }
204
205         return c;
206 }
207
208 /* Insert a NULL at the first separator of the given path and return a pointer
209  * to the remainder of the string.
210  */
211 static char *
212 terminate_path_at_separator(char * path)
213 {
214         char * p;
215
216         if (!path) {
217                 return NULL;
218         }
219
220         if ((p = strchr_m(path, '/'))) {
221                 *p = '\0';
222                 return p + 1;
223         }
224
225         if ((p = strchr_m(path, '\\'))) {
226                 *p = '\0';
227                 return p + 1;
228         }
229         
230         /* No separator. */
231         return NULL;
232 }
233
234 /*
235   parse a //server/share type UNC name
236 */
237 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
238                       char **hostname, char **sharename)
239 {
240         char *p;
241
242         *hostname = *sharename = NULL;
243
244         if (strncmp(unc_name, "\\\\", 2) &&
245             strncmp(unc_name, "//", 2)) {
246                 return False;
247         }
248
249         *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
250         p = terminate_path_at_separator(*hostname);
251
252         if (p && *p) {
253                 *sharename = talloc_strdup(mem_ctx, p);
254                 terminate_path_at_separator(*sharename);
255         }
256
257         if (*hostname && *sharename) {
258                 return True;
259         }
260
261         TALLOC_FREE(*hostname);
262         TALLOC_FREE(*sharename);
263         return False;
264 }
265
266 static bool torture_open_connection_share(struct cli_state **c,
267                                    const char *hostname, 
268                                    const char *sharename)
269 {
270         bool retry;
271         int flags = 0;
272         NTSTATUS status;
273
274         if (use_kerberos)
275                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
276         if (use_oplocks)
277                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
278         if (use_level_II_oplocks)
279                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
280
281         status = cli_full_connection(c, myname,
282                                      hostname, NULL, port_to_use, 
283                                      sharename, "?????", 
284                                      username, workgroup, 
285                                      password, flags, Undefined, &retry);
286         if (!NT_STATUS_IS_OK(status)) {
287                 printf("failed to open share connection: //%s/%s port:%d - %s\n",
288                         hostname, sharename, port_to_use, nt_errstr(status));
289                 return False;
290         }
291
292         (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
293
294         if (do_encrypt) {
295                 return force_cli_encryption(*c,
296                                         sharename);
297         }
298         return True;
299 }
300
301 bool torture_open_connection(struct cli_state **c, int conn_index)
302 {
303         char **unc_list = NULL;
304         int num_unc_names = 0;
305         bool result;
306
307         if (use_multishare_conn==True) {
308                 char *h, *s;
309                 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
310                 if (!unc_list || num_unc_names <= 0) {
311                         printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
312                         exit(1);
313                 }
314
315                 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
316                                       NULL, &h, &s)) {
317                         printf("Failed to parse UNC name %s\n",
318                                unc_list[conn_index % num_unc_names]);
319                         TALLOC_FREE(unc_list);
320                         exit(1);
321                 }
322
323                 result = torture_open_connection_share(c, h, s);
324
325                 /* h, s were copied earlier */
326                 TALLOC_FREE(unc_list);
327                 return result;
328         }
329
330         return torture_open_connection_share(c, host, share);
331 }
332
333 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
334 {
335         uint16 old_vuid = cli->vuid;
336         fstring old_user_name;
337         size_t passlen = strlen(password);
338         NTSTATUS status;
339         bool ret;
340
341         fstrcpy(old_user_name, cli->user_name);
342         cli->vuid = 0;
343         ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
344                                                 password, passlen,
345                                                 password, passlen,
346                                                 workgroup));
347         *new_vuid = cli->vuid;
348         cli->vuid = old_vuid;
349         status = cli_set_username(cli, old_user_name);
350         if (!NT_STATUS_IS_OK(status)) {
351                 return false;
352         }
353         return ret;
354 }
355
356
357 bool torture_close_connection(struct cli_state *c)
358 {
359         bool ret = True;
360         if (!cli_tdis(c)) {
361                 printf("tdis failed (%s)\n", cli_errstr(c));
362                 ret = False;
363         }
364
365         cli_shutdown(c);
366
367         return ret;
368 }
369
370
371 /* check if the server produced the expected error code */
372 static bool check_error(int line, struct cli_state *c, 
373                         uint8 eclass, uint32 ecode, NTSTATUS nterr)
374 {
375         if (cli_is_dos_error(c)) {
376                 uint8 cclass;
377                 uint32 num;
378
379                 /* Check DOS error */
380
381                 cli_dos_error(c, &cclass, &num);
382
383                 if (eclass != cclass || ecode != num) {
384                         printf("unexpected error code class=%d code=%d\n", 
385                                (int)cclass, (int)num);
386                         printf(" expected %d/%d %s (line=%d)\n", 
387                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
388                         return False;
389                 }
390
391         } else {
392                 NTSTATUS status;
393
394                 /* Check NT error */
395
396                 status = cli_nt_error(c);
397
398                 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
399                         printf("unexpected error code %s\n", nt_errstr(status));
400                         printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
401                         return False;
402                 }
403         }
404
405         return True;
406 }
407
408
409 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
410 {
411         while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
412                 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
413         }
414         return True;
415 }
416
417
418 static bool rw_torture(struct cli_state *c)
419 {
420         const char *lockfname = "\\torture.lck";
421         fstring fname;
422         int fnum;
423         int fnum2;
424         pid_t pid2, pid = getpid();
425         int i, j;
426         char buf[1024];
427         bool correct = True;
428
429         memset(buf, '\0', sizeof(buf));
430
431         fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
432                          DENY_NONE);
433         if (fnum2 == -1)
434                 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
435         if (fnum2 == -1) {
436                 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
437                 return False;
438         }
439
440
441         for (i=0;i<torture_numops;i++) {
442                 unsigned n = (unsigned)sys_random()%10;
443                 if (i % 10 == 0) {
444                         printf("%d\r", i); fflush(stdout);
445                 }
446                 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
447
448                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
449                         return False;
450                 }
451
452                 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
453                 if (fnum == -1) {
454                         printf("open failed (%s)\n", cli_errstr(c));
455                         correct = False;
456                         break;
457                 }
458
459                 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
460                         printf("write failed (%s)\n", cli_errstr(c));
461                         correct = False;
462                 }
463
464                 for (j=0;j<50;j++) {
465                         if (cli_write(c, fnum, 0, (char *)buf, 
466                                       sizeof(pid)+(j*sizeof(buf)), 
467                                       sizeof(buf)) != sizeof(buf)) {
468                                 printf("write failed (%s)\n", cli_errstr(c));
469                                 correct = False;
470                         }
471                 }
472
473                 pid2 = 0;
474
475                 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
476                         printf("read failed (%s)\n", cli_errstr(c));
477                         correct = False;
478                 }
479
480                 if (pid2 != pid) {
481                         printf("data corruption!\n");
482                         correct = False;
483                 }
484
485                 if (!cli_close(c, fnum)) {
486                         printf("close failed (%s)\n", cli_errstr(c));
487                         correct = False;
488                 }
489
490                 if (!cli_unlink(c, fname)) {
491                         printf("unlink failed (%s)\n", cli_errstr(c));
492                         correct = False;
493                 }
494
495                 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
496                         printf("unlock failed (%s)\n", cli_errstr(c));
497                         correct = False;
498                 }
499         }
500
501         cli_close(c, fnum2);
502         cli_unlink(c, lockfname);
503
504         printf("%d\n", i);
505
506         return correct;
507 }
508
509 static bool run_torture(int dummy)
510 {
511         struct cli_state *cli;
512         bool ret;
513
514         cli = current_cli;
515
516         cli_sockopt(cli, sockops);
517
518         ret = rw_torture(cli);
519         
520         if (!torture_close_connection(cli)) {
521                 ret = False;
522         }
523
524         return ret;
525 }
526
527 static bool rw_torture3(struct cli_state *c, char *lockfname)
528 {
529         int fnum = -1;
530         unsigned int i = 0;
531         char buf[131072];
532         char buf_rd[131072];
533         unsigned count;
534         unsigned countprev = 0;
535         ssize_t sent = 0;
536         bool correct = True;
537
538         srandom(1);
539         for (i = 0; i < sizeof(buf); i += sizeof(uint32))
540         {
541                 SIVAL(buf, i, sys_random());
542         }
543
544         if (procnum == 0)
545         {
546                 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
547                                  DENY_NONE);
548                 if (fnum == -1) {
549                         printf("first open read/write of %s failed (%s)\n",
550                                         lockfname, cli_errstr(c));
551                         return False;
552                 }
553         }
554         else
555         {
556                 for (i = 0; i < 500 && fnum == -1; i++)
557                 {
558                         fnum = cli_open(c, lockfname, O_RDONLY, 
559                                          DENY_NONE);
560                         smb_msleep(10);
561                 }
562                 if (fnum == -1) {
563                         printf("second open read-only of %s failed (%s)\n",
564                                         lockfname, cli_errstr(c));
565                         return False;
566                 }
567         }
568
569         i = 0;
570         for (count = 0; count < sizeof(buf); count += sent)
571         {
572                 if (count >= countprev) {
573                         printf("%d %8d\r", i, count);
574                         fflush(stdout);
575                         i++;
576                         countprev += (sizeof(buf) / 20);
577                 }
578
579                 if (procnum == 0)
580                 {
581                         sent = ((unsigned)sys_random()%(20))+ 1;
582                         if (sent > sizeof(buf) - count)
583                         {
584                                 sent = sizeof(buf) - count;
585                         }
586
587                         if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
588                                 printf("write failed (%s)\n", cli_errstr(c));
589                                 correct = False;
590                         }
591                 }
592                 else
593                 {
594                         sent = cli_read(c, fnum, buf_rd+count, count,
595                                                   sizeof(buf)-count);
596                         if (sent < 0)
597                         {
598                                 printf("read failed offset:%d size:%ld (%s)\n",
599                                        count, (unsigned long)sizeof(buf)-count,
600                                        cli_errstr(c));
601                                 correct = False;
602                                 sent = 0;
603                         }
604                         if (sent > 0)
605                         {
606                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
607                                 {
608                                         printf("read/write compare failed\n");
609                                         printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
610                                         correct = False;
611                                         break;
612                                 }
613                         }
614                 }
615
616         }
617
618         if (!cli_close(c, fnum)) {
619                 printf("close failed (%s)\n", cli_errstr(c));
620                 correct = False;
621         }
622
623         return correct;
624 }
625
626 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
627 {
628         const char *lockfname = "\\torture2.lck";
629         int fnum1;
630         int fnum2;
631         int i;
632         char buf[131072];
633         char buf_rd[131072];
634         bool correct = True;
635         ssize_t bytes_read;
636
637         if (!cli_unlink(c1, lockfname)) {
638                 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
639         }
640
641         fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL, 
642                          DENY_NONE);
643         if (fnum1 == -1) {
644                 printf("first open read/write of %s failed (%s)\n",
645                                 lockfname, cli_errstr(c1));
646                 return False;
647         }
648         fnum2 = cli_open(c2, lockfname, O_RDONLY, 
649                          DENY_NONE);
650         if (fnum2 == -1) {
651                 printf("second open read-only of %s failed (%s)\n",
652                                 lockfname, cli_errstr(c2));
653                 cli_close(c1, fnum1);
654                 return False;
655         }
656
657         for (i=0;i<torture_numops;i++)
658         {
659                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
660                 if (i % 10 == 0) {
661                         printf("%d\r", i); fflush(stdout);
662                 }
663
664                 generate_random_buffer((unsigned char *)buf, buf_size);
665
666                 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
667                         printf("write failed (%s)\n", cli_errstr(c1));
668                         correct = False;
669                         break;
670                 }
671
672                 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
673                         printf("read failed (%s)\n", cli_errstr(c2));
674                         printf("read %d, expected %ld\n", (int)bytes_read, 
675                                (unsigned long)buf_size); 
676                         correct = False;
677                         break;
678                 }
679
680                 if (memcmp(buf_rd, buf, buf_size) != 0)
681                 {
682                         printf("read/write compare failed\n");
683                         correct = False;
684                         break;
685                 }
686         }
687
688         if (!cli_close(c2, fnum2)) {
689                 printf("close failed (%s)\n", cli_errstr(c2));
690                 correct = False;
691         }
692         if (!cli_close(c1, fnum1)) {
693                 printf("close failed (%s)\n", cli_errstr(c1));
694                 correct = False;
695         }
696
697         if (!cli_unlink(c1, lockfname)) {
698                 printf("unlink failed (%s)\n", cli_errstr(c1));
699                 correct = False;
700         }
701
702         return correct;
703 }
704
705 static bool run_readwritetest(int dummy)
706 {
707         static struct cli_state *cli1, *cli2;
708         bool test1, test2 = False;
709
710         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
711                 return False;
712         }
713         cli_sockopt(cli1, sockops);
714         cli_sockopt(cli2, sockops);
715
716         printf("starting readwritetest\n");
717
718         test1 = rw_torture2(cli1, cli2);
719         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
720
721         if (test1) {
722                 test2 = rw_torture2(cli1, cli1);
723                 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
724         }
725
726         if (!torture_close_connection(cli1)) {
727                 test1 = False;
728         }
729
730         if (!torture_close_connection(cli2)) {
731                 test2 = False;
732         }
733
734         return (test1 && test2);
735 }
736
737 static bool run_readwritemulti(int dummy)
738 {
739         struct cli_state *cli;
740         bool test;
741
742         cli = current_cli;
743
744         cli_sockopt(cli, sockops);
745
746         printf("run_readwritemulti: fname %s\n", randomfname);
747         test = rw_torture3(cli, randomfname);
748
749         if (!torture_close_connection(cli)) {
750                 test = False;
751         }
752         
753         return test;
754 }
755
756 static bool run_readwritelarge(int dummy)
757 {
758         static struct cli_state *cli1;
759         int fnum1;
760         const char *lockfname = "\\large.dat";
761         SMB_OFF_T fsize;
762         char buf[126*1024];
763         bool correct = True;
764  
765         if (!torture_open_connection(&cli1, 0)) {
766                 return False;
767         }
768         cli_sockopt(cli1, sockops);
769         memset(buf,'\0',sizeof(buf));
770         
771         cli1->max_xmit = 128*1024;
772         
773         printf("starting readwritelarge\n");
774  
775         cli_unlink(cli1, lockfname);
776
777         fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
778         if (fnum1 == -1) {
779                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
780                 return False;
781         }
782    
783         cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
784
785         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
786                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
787                 correct = False;
788         }
789
790         if (fsize == sizeof(buf))
791                 printf("readwritelarge test 1 succeeded (size = %lx)\n", 
792                        (unsigned long)fsize);
793         else {
794                 printf("readwritelarge test 1 failed (size = %lx)\n", 
795                        (unsigned long)fsize);
796                 correct = False;
797         }
798
799         if (!cli_close(cli1, fnum1)) {
800                 printf("close failed (%s)\n", cli_errstr(cli1));
801                 correct = False;
802         }
803
804         if (!cli_unlink(cli1, lockfname)) {
805                 printf("unlink failed (%s)\n", cli_errstr(cli1));
806                 correct = False;
807         }
808
809         fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
810         if (fnum1 == -1) {
811                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
812                 return False;
813         }
814         
815         cli1->max_xmit = 4*1024;
816         
817         cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
818         
819         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
820                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
821                 correct = False;
822         }
823
824         if (fsize == sizeof(buf))
825                 printf("readwritelarge test 2 succeeded (size = %lx)\n", 
826                        (unsigned long)fsize);
827         else {
828                 printf("readwritelarge test 2 failed (size = %lx)\n", 
829                        (unsigned long)fsize);
830                 correct = False;
831         }
832
833 #if 0
834         /* ToDo - set allocation. JRA */
835         if(!cli_set_allocation_size(cli1, fnum1, 0)) {
836                 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
837                 return False;
838         }
839         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
840                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
841                 correct = False;
842         }
843         if (fsize != 0)
844                 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
845 #endif
846
847         if (!cli_close(cli1, fnum1)) {
848                 printf("close failed (%s)\n", cli_errstr(cli1));
849                 correct = False;
850         }
851         
852         if (!torture_close_connection(cli1)) {
853                 correct = False;
854         }
855         return correct;
856 }
857
858 int line_count = 0;
859 int nbio_id;
860
861 #define ival(s) strtol(s, NULL, 0)
862
863 /* run a test that simulates an approximate netbench client load */
864 static bool run_netbench(int client)
865 {
866         struct cli_state *cli;
867         int i;
868         char line[1024];
869         char cname[20];
870         FILE *f;
871         const char *params[20];
872         bool correct = True;
873
874         cli = current_cli;
875
876         nbio_id = client;
877
878         cli_sockopt(cli, sockops);
879
880         nb_setup(cli);
881
882         slprintf(cname,sizeof(cname)-1, "client%d", client);
883
884         f = fopen(client_txt, "r");
885
886         if (!f) {
887                 perror(client_txt);
888                 return False;
889         }
890
891         while (fgets(line, sizeof(line)-1, f)) {
892                 char *saveptr;
893                 line_count++;
894
895                 line[strlen(line)-1] = 0;
896
897                 /* printf("[%d] %s\n", line_count, line); */
898
899                 all_string_sub(line,"client1", cname, sizeof(line));
900
901                 /* parse the command parameters */
902                 params[0] = strtok_r(line, " ", &saveptr);
903                 i = 0;
904                 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
905
906                 params[i] = "";
907
908                 if (i < 2) continue;
909
910                 if (!strncmp(params[0],"SMB", 3)) {
911                         printf("ERROR: You are using a dbench 1 load file\n");
912                         exit(1);
913                 }
914
915                 if (!strcmp(params[0],"NTCreateX")) {
916                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
917                                    ival(params[4]));
918                 } else if (!strcmp(params[0],"Close")) {
919                         nb_close(ival(params[1]));
920                 } else if (!strcmp(params[0],"Rename")) {
921                         nb_rename(params[1], params[2]);
922                 } else if (!strcmp(params[0],"Unlink")) {
923                         nb_unlink(params[1]);
924                 } else if (!strcmp(params[0],"Deltree")) {
925                         nb_deltree(params[1]);
926                 } else if (!strcmp(params[0],"Rmdir")) {
927                         nb_rmdir(params[1]);
928                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
929                         nb_qpathinfo(params[1]);
930                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
931                         nb_qfileinfo(ival(params[1]));
932                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
933                         nb_qfsinfo(ival(params[1]));
934                 } else if (!strcmp(params[0],"FIND_FIRST")) {
935                         nb_findfirst(params[1]);
936                 } else if (!strcmp(params[0],"WriteX")) {
937                         nb_writex(ival(params[1]), 
938                                   ival(params[2]), ival(params[3]), ival(params[4]));
939                 } else if (!strcmp(params[0],"ReadX")) {
940                         nb_readx(ival(params[1]), 
941                                   ival(params[2]), ival(params[3]), ival(params[4]));
942                 } else if (!strcmp(params[0],"Flush")) {
943                         nb_flush(ival(params[1]));
944                 } else {
945                         printf("Unknown operation %s\n", params[0]);
946                         exit(1);
947                 }
948         }
949         fclose(f);
950
951         nb_cleanup();
952
953         if (!torture_close_connection(cli)) {
954                 correct = False;
955         }
956         
957         return correct;
958 }
959
960
961 /* run a test that simulates an approximate netbench client load */
962 static bool run_nbench(int dummy)
963 {
964         double t;
965         bool correct = True;
966
967         nbio_shmem(nprocs);
968
969         nbio_id = -1;
970
971         signal(SIGALRM, nb_alarm);
972         alarm(1);
973         t = create_procs(run_netbench, &correct);
974         alarm(0);
975
976         printf("\nThroughput %g MB/sec\n", 
977                1.0e-6 * nbio_total() / t);
978         return correct;
979 }
980
981
982 /*
983   This test checks for two things:
984
985   1) correct support for retaining locks over a close (ie. the server
986      must not use posix semantics)
987   2) support for lock timeouts
988  */
989 static bool run_locktest1(int dummy)
990 {
991         struct cli_state *cli1, *cli2;
992         const char *fname = "\\lockt1.lck";
993         int fnum1, fnum2, fnum3;
994         time_t t1, t2;
995         unsigned lock_timeout;
996
997         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
998                 return False;
999         }
1000         cli_sockopt(cli1, sockops);
1001         cli_sockopt(cli2, sockops);
1002
1003         printf("starting locktest1\n");
1004
1005         cli_unlink(cli1, fname);
1006
1007         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1008         if (fnum1 == -1) {
1009                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1010                 return False;
1011         }
1012         fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1013         if (fnum2 == -1) {
1014                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1015                 return False;
1016         }
1017         fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1018         if (fnum3 == -1) {
1019                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1020                 return False;
1021         }
1022
1023         if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1024                 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1025                 return False;
1026         }
1027
1028
1029         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1030                 printf("lock2 succeeded! This is a locking bug\n");
1031                 return False;
1032         } else {
1033                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1034                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1035         }
1036
1037
1038         lock_timeout = (1 + (random() % 20));
1039         printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1040         t1 = time(NULL);
1041         if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1042                 printf("lock3 succeeded! This is a locking bug\n");
1043                 return False;
1044         } else {
1045                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1046                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1047         }
1048         t2 = time(NULL);
1049
1050         if (ABS(t2 - t1) < lock_timeout-1) {
1051                 printf("error: This server appears not to support timed lock requests\n");
1052         }
1053
1054         printf("server slept for %u seconds for a %u second timeout\n",
1055                (unsigned int)(t2-t1), lock_timeout);
1056
1057         if (!cli_close(cli1, fnum2)) {
1058                 printf("close1 failed (%s)\n", cli_errstr(cli1));
1059                 return False;
1060         }
1061
1062         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1063                 printf("lock4 succeeded! This is a locking bug\n");
1064                 return False;
1065         } else {
1066                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1067                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1068         }
1069
1070         if (!cli_close(cli1, fnum1)) {
1071                 printf("close2 failed (%s)\n", cli_errstr(cli1));
1072                 return False;
1073         }
1074
1075         if (!cli_close(cli2, fnum3)) {
1076                 printf("close3 failed (%s)\n", cli_errstr(cli2));
1077                 return False;
1078         }
1079
1080         if (!cli_unlink(cli1, fname)) {
1081                 printf("unlink failed (%s)\n", cli_errstr(cli1));
1082                 return False;
1083         }
1084
1085
1086         if (!torture_close_connection(cli1)) {
1087                 return False;
1088         }
1089
1090         if (!torture_close_connection(cli2)) {
1091                 return False;
1092         }
1093
1094         printf("Passed locktest1\n");
1095         return True;
1096 }
1097
1098 /*
1099   this checks to see if a secondary tconx can use open files from an
1100   earlier tconx
1101  */
1102 static bool run_tcon_test(int dummy)
1103 {
1104         static struct cli_state *cli;
1105         const char *fname = "\\tcontest.tmp";
1106         int fnum1;
1107         uint16 cnum1, cnum2, cnum3;
1108         uint16 vuid1, vuid2;
1109         char buf[4];
1110         bool ret = True;
1111         NTSTATUS status;
1112
1113         memset(buf, '\0', sizeof(buf));
1114
1115         if (!torture_open_connection(&cli, 0)) {
1116                 return False;
1117         }
1118         cli_sockopt(cli, sockops);
1119
1120         printf("starting tcontest\n");
1121
1122         cli_unlink(cli, fname);
1123
1124         fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1125         if (fnum1 == -1) {
1126                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1127                 return False;
1128         }
1129
1130         cnum1 = cli->cnum;
1131         vuid1 = cli->vuid;
1132
1133         if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1134                 printf("initial write failed (%s)", cli_errstr(cli));
1135                 return False;
1136         }
1137
1138         status = cli_tcon_andx(cli, share, "?????",
1139                                password, strlen(password)+1);
1140         if (!NT_STATUS_IS_OK(status)) {
1141                 printf("%s refused 2nd tree connect (%s)\n", host,
1142                        nt_errstr(status));
1143                 cli_shutdown(cli);
1144                 return False;
1145         }
1146
1147         cnum2 = cli->cnum;
1148         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1149         vuid2 = cli->vuid + 1;
1150
1151         /* try a write with the wrong tid */
1152         cli->cnum = cnum2;
1153
1154         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1155                 printf("* server allows write with wrong TID\n");
1156                 ret = False;
1157         } else {
1158                 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1159         }
1160
1161
1162         /* try a write with an invalid tid */
1163         cli->cnum = cnum3;
1164
1165         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1166                 printf("* server allows write with invalid TID\n");
1167                 ret = False;
1168         } else {
1169                 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1170         }
1171
1172         /* try a write with an invalid vuid */
1173         cli->vuid = vuid2;
1174         cli->cnum = cnum1;
1175
1176         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1177                 printf("* server allows write with invalid VUID\n");
1178                 ret = False;
1179         } else {
1180                 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1181         }
1182
1183         cli->cnum = cnum1;
1184         cli->vuid = vuid1;
1185
1186         if (!cli_close(cli, fnum1)) {
1187                 printf("close failed (%s)\n", cli_errstr(cli));
1188                 return False;
1189         }
1190
1191         cli->cnum = cnum2;
1192
1193         if (!cli_tdis(cli)) {
1194                 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
1195                 return False;
1196         }
1197
1198         cli->cnum = cnum1;
1199
1200         if (!torture_close_connection(cli)) {
1201                 return False;
1202         }
1203
1204         return ret;
1205 }
1206
1207
1208 /*
1209  checks for old style tcon support
1210  */
1211 static bool run_tcon2_test(int dummy)
1212 {
1213         static struct cli_state *cli;
1214         uint16 cnum, max_xmit;
1215         char *service;
1216         NTSTATUS status;
1217
1218         if (!torture_open_connection(&cli, 0)) {
1219                 return False;
1220         }
1221         cli_sockopt(cli, sockops);
1222
1223         printf("starting tcon2 test\n");
1224
1225         if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1226                 return false;
1227         }
1228
1229         status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1230
1231         if (!NT_STATUS_IS_OK(status)) {
1232                 printf("tcon2 failed : %s\n", cli_errstr(cli));
1233         } else {
1234                 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n", 
1235                        (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1236         }
1237
1238         if (!torture_close_connection(cli)) {
1239                 return False;
1240         }
1241
1242         printf("Passed tcon2 test\n");
1243         return True;
1244 }
1245
1246 static bool tcon_devtest(struct cli_state *cli,
1247                          const char *myshare, const char *devtype,
1248                          const char *return_devtype,
1249                          NTSTATUS expected_error)
1250 {
1251         NTSTATUS status;
1252         bool ret;
1253
1254         status = cli_tcon_andx(cli, myshare, devtype,
1255                                password, strlen(password)+1);
1256
1257         if (NT_STATUS_IS_OK(expected_error)) {
1258                 if (NT_STATUS_IS_OK(status)) {
1259                         if (strcmp(cli->dev, return_devtype) == 0) {
1260                                 ret = True;
1261                         } else { 
1262                                 printf("tconX to share %s with type %s "
1263                                        "succeeded but returned the wrong "
1264                                        "device type (got [%s] but should have got [%s])\n",
1265                                        myshare, devtype, cli->dev, return_devtype);
1266                                 ret = False;
1267                         }
1268                 } else {
1269                         printf("tconX to share %s with type %s "
1270                                "should have succeeded but failed\n",
1271                                myshare, devtype);
1272                         ret = False;
1273                 }
1274                 cli_tdis(cli);
1275         } else {
1276                 if (NT_STATUS_IS_OK(status)) {
1277                         printf("tconx to share %s with type %s "
1278                                "should have failed but succeeded\n",
1279                                myshare, devtype);
1280                         ret = False;
1281                 } else {
1282                         if (NT_STATUS_EQUAL(cli_nt_error(cli),
1283                                             expected_error)) {
1284                                 ret = True;
1285                         } else {
1286                                 printf("Returned unexpected error\n");
1287                                 ret = False;
1288                         }
1289                 }
1290         }
1291         return ret;
1292 }
1293
1294 /*
1295  checks for correct tconX support
1296  */
1297 static bool run_tcon_devtype_test(int dummy)
1298 {
1299         static struct cli_state *cli1 = NULL;
1300         bool retry;
1301         int flags = 0;
1302         NTSTATUS status;
1303         bool ret = True;
1304
1305         status = cli_full_connection(&cli1, myname,
1306                                      host, NULL, port_to_use,
1307                                      NULL, NULL,
1308                                      username, workgroup,
1309                                      password, flags, Undefined, &retry);
1310
1311         if (!NT_STATUS_IS_OK(status)) {
1312                 printf("could not open connection\n");
1313                 return False;
1314         }
1315
1316         if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1317                 ret = False;
1318
1319         if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1320                 ret = False;
1321
1322         if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1323                 ret = False;
1324
1325         if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1326                 ret = False;
1327                         
1328         if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1329                 ret = False;
1330
1331         if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1332                 ret = False;
1333
1334         if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1335                 ret = False;
1336
1337         if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1338                 ret = False;
1339
1340         if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1341                 ret = False;
1342                         
1343         if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1344                 ret = False;
1345
1346         cli_shutdown(cli1);
1347
1348         if (ret)
1349                 printf("Passed tcondevtest\n");
1350
1351         return ret;
1352 }
1353
1354
1355 /*
1356   This test checks that 
1357
1358   1) the server supports multiple locking contexts on the one SMB
1359   connection, distinguished by PID.  
1360
1361   2) the server correctly fails overlapping locks made by the same PID (this
1362      goes against POSIX behaviour, which is why it is tricky to implement)
1363
1364   3) the server denies unlock requests by an incorrect client PID
1365 */
1366 static bool run_locktest2(int dummy)
1367 {
1368         static struct cli_state *cli;
1369         const char *fname = "\\lockt2.lck";
1370         int fnum1, fnum2, fnum3;
1371         bool correct = True;
1372
1373         if (!torture_open_connection(&cli, 0)) {
1374                 return False;
1375         }
1376
1377         cli_sockopt(cli, sockops);
1378
1379         printf("starting locktest2\n");
1380
1381         cli_unlink(cli, fname);
1382
1383         cli_setpid(cli, 1);
1384
1385         fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1386         if (fnum1 == -1) {
1387                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1388                 return False;
1389         }
1390
1391         fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1392         if (fnum2 == -1) {
1393                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1394                 return False;
1395         }
1396
1397         cli_setpid(cli, 2);
1398
1399         fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1400         if (fnum3 == -1) {
1401                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1402                 return False;
1403         }
1404
1405         cli_setpid(cli, 1);
1406
1407         if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1408                 printf("lock1 failed (%s)\n", cli_errstr(cli));
1409                 return False;
1410         }
1411
1412         if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1413                 printf("WRITE lock1 succeeded! This is a locking bug\n");
1414                 correct = False;
1415         } else {
1416                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1417                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1418         }
1419
1420         if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1421                 printf("WRITE lock2 succeeded! This is a locking bug\n");
1422                 correct = False;
1423         } else {
1424                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1425                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1426         }
1427
1428         if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1429                 printf("READ lock2 succeeded! This is a locking bug\n");
1430                 correct = False;
1431         } else {
1432                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1433                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1434         }
1435
1436         if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1437                 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1438         }
1439         cli_setpid(cli, 2);
1440         if (cli_unlock(cli, fnum1, 100, 4)) {
1441                 printf("unlock at 100 succeeded! This is a locking bug\n");
1442                 correct = False;
1443         }
1444
1445         if (cli_unlock(cli, fnum1, 0, 4)) {
1446                 printf("unlock1 succeeded! This is a locking bug\n");
1447                 correct = False;
1448         } else {
1449                 if (!check_error(__LINE__, cli, 
1450                                  ERRDOS, ERRlock, 
1451                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1452         }
1453
1454         if (cli_unlock(cli, fnum1, 0, 8)) {
1455                 printf("unlock2 succeeded! This is a locking bug\n");
1456                 correct = False;
1457         } else {
1458                 if (!check_error(__LINE__, cli, 
1459                                  ERRDOS, ERRlock, 
1460                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1461         }
1462
1463         if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1464                 printf("lock3 succeeded! This is a locking bug\n");
1465                 correct = False;
1466         } else {
1467                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1468         }
1469
1470         cli_setpid(cli, 1);
1471
1472         if (!cli_close(cli, fnum1)) {
1473                 printf("close1 failed (%s)\n", cli_errstr(cli));
1474                 return False;
1475         }
1476
1477         if (!cli_close(cli, fnum2)) {
1478                 printf("close2 failed (%s)\n", cli_errstr(cli));
1479                 return False;
1480         }
1481
1482         if (!cli_close(cli, fnum3)) {
1483                 printf("close3 failed (%s)\n", cli_errstr(cli));
1484                 return False;
1485         }
1486
1487         if (!torture_close_connection(cli)) {
1488                 correct = False;
1489         }
1490
1491         printf("locktest2 finished\n");
1492
1493         return correct;
1494 }
1495
1496
1497 /*
1498   This test checks that 
1499
1500   1) the server supports the full offset range in lock requests
1501 */
1502 static bool run_locktest3(int dummy)
1503 {
1504         static struct cli_state *cli1, *cli2;
1505         const char *fname = "\\lockt3.lck";
1506         int fnum1, fnum2, i;
1507         uint32 offset;
1508         bool correct = True;
1509
1510 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1511
1512         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1513                 return False;
1514         }
1515         cli_sockopt(cli1, sockops);
1516         cli_sockopt(cli2, sockops);
1517
1518         printf("starting locktest3\n");
1519
1520         cli_unlink(cli1, fname);
1521
1522         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1523         if (fnum1 == -1) {
1524                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1525                 return False;
1526         }
1527         fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1528         if (fnum2 == -1) {
1529                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1530                 return False;
1531         }
1532
1533         for (offset=i=0;i<torture_numops;i++) {
1534                 NEXT_OFFSET;
1535                 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1536                         printf("lock1 %d failed (%s)\n", 
1537                                i,
1538                                cli_errstr(cli1));
1539                         return False;
1540                 }
1541
1542                 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1543                         printf("lock2 %d failed (%s)\n", 
1544                                i,
1545                                cli_errstr(cli1));
1546                         return False;
1547                 }
1548         }
1549
1550         for (offset=i=0;i<torture_numops;i++) {
1551                 NEXT_OFFSET;
1552
1553                 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1554                         printf("error: lock1 %d succeeded!\n", i);
1555                         return False;
1556                 }
1557
1558                 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1559                         printf("error: lock2 %d succeeded!\n", i);
1560                         return False;
1561                 }
1562
1563                 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1564                         printf("error: lock3 %d succeeded!\n", i);
1565                         return False;
1566                 }
1567
1568                 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1569                         printf("error: lock4 %d succeeded!\n", i);
1570                         return False;
1571                 }
1572         }
1573
1574         for (offset=i=0;i<torture_numops;i++) {
1575                 NEXT_OFFSET;
1576
1577                 if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
1578                         printf("unlock1 %d failed (%s)\n", 
1579                                i,
1580                                cli_errstr(cli1));
1581                         return False;
1582                 }
1583
1584                 if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
1585                         printf("unlock2 %d failed (%s)\n", 
1586                                i,
1587                                cli_errstr(cli1));
1588                         return False;
1589                 }
1590         }
1591
1592         if (!cli_close(cli1, fnum1)) {
1593                 printf("close1 failed (%s)\n", cli_errstr(cli1));
1594                 return False;
1595         }
1596
1597         if (!cli_close(cli2, fnum2)) {
1598                 printf("close2 failed (%s)\n", cli_errstr(cli2));
1599                 return False;
1600         }
1601
1602         if (!cli_unlink(cli1, fname)) {
1603                 printf("unlink failed (%s)\n", cli_errstr(cli1));
1604                 return False;
1605         }
1606
1607         if (!torture_close_connection(cli1)) {
1608                 correct = False;
1609         }
1610         
1611         if (!torture_close_connection(cli2)) {
1612                 correct = False;
1613         }
1614
1615         printf("finished locktest3\n");
1616
1617         return correct;
1618 }
1619
1620 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1621         printf("** "); correct = False; \
1622         }
1623
1624 /*
1625   looks at overlapping locks
1626 */
1627 static bool run_locktest4(int dummy)
1628 {
1629         static struct cli_state *cli1, *cli2;
1630         const char *fname = "\\lockt4.lck";
1631         int fnum1, fnum2, f;
1632         bool ret;
1633         char buf[1000];
1634         bool correct = True;
1635
1636         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1637                 return False;
1638         }
1639
1640         cli_sockopt(cli1, sockops);
1641         cli_sockopt(cli2, sockops);
1642
1643         printf("starting locktest4\n");
1644
1645         cli_unlink(cli1, fname);
1646
1647         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1648         fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1649
1650         memset(buf, 0, sizeof(buf));
1651
1652         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1653                 printf("Failed to create file\n");
1654                 correct = False;
1655                 goto fail;
1656         }
1657
1658         ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1659               cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1660         EXPECTED(ret, False);
1661         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1662             
1663         ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1664               cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1665         EXPECTED(ret, True);
1666         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1667
1668         ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1669               cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1670         EXPECTED(ret, False);
1671         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1672             
1673         ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1674               cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1675         EXPECTED(ret, True);
1676         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1677         
1678         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1679               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1680         EXPECTED(ret, False);
1681         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1682             
1683         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1684               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1685         EXPECTED(ret, True);
1686         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1687
1688         ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1689               cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1690         EXPECTED(ret, True);
1691         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1692
1693         ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1694               cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1695         EXPECTED(ret, False);
1696         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1697
1698         ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1699               cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1700         EXPECTED(ret, False);
1701         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1702
1703         ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1704               cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1705         EXPECTED(ret, True);
1706         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1707
1708         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1709               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1710         EXPECTED(ret, False);
1711         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1712
1713         ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1714               cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1715               cli_unlock(cli1, fnum1, 110, 6);
1716         EXPECTED(ret, False);
1717         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1718
1719
1720         ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1721               (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1722         EXPECTED(ret, False);
1723         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1724
1725         ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1726               (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1727         EXPECTED(ret, False);
1728         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1729
1730
1731         ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1732               cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1733               cli_unlock(cli1, fnum1, 140, 4) &&
1734               cli_unlock(cli1, fnum1, 140, 4);
1735         EXPECTED(ret, True);
1736         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1737
1738
1739         ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1740               cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1741               cli_unlock(cli1, fnum1, 150, 4) &&
1742               (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1743               !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1744               cli_unlock(cli1, fnum1, 150, 4);
1745         EXPECTED(ret, True);
1746         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1747
1748         ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1749               cli_unlock(cli1, fnum1, 160, 4) &&
1750               (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&          
1751               (cli_read(cli2, fnum2, buf, 160, 4) == 4);                
1752         EXPECTED(ret, True);
1753         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1754
1755         ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1756               cli_unlock(cli1, fnum1, 170, 4) &&
1757               (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&          
1758               (cli_read(cli2, fnum2, buf, 170, 4) == 4);                
1759         EXPECTED(ret, True);
1760         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1761
1762         ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1763               cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1764               cli_unlock(cli1, fnum1, 190, 4) &&
1765               !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&         
1766               (cli_read(cli2, fnum2, buf, 190, 4) == 4);                
1767         EXPECTED(ret, True);
1768         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1769
1770         cli_close(cli1, fnum1);
1771         cli_close(cli2, fnum2);
1772         fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1773         f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1774         ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1775               cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1776               cli_close(cli1, fnum1) &&
1777               ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1778               cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1779         cli_close(cli1, f);
1780         cli_close(cli1, fnum1);
1781         EXPECTED(ret, True);
1782         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1783
1784  fail:
1785         cli_close(cli1, fnum1);
1786         cli_close(cli2, fnum2);
1787         cli_unlink(cli1, fname);
1788         torture_close_connection(cli1);
1789         torture_close_connection(cli2);
1790
1791         printf("finished locktest4\n");
1792         return correct;
1793 }
1794
1795 /*
1796   looks at lock upgrade/downgrade.
1797 */
1798 static bool run_locktest5(int dummy)
1799 {
1800         static struct cli_state *cli1, *cli2;
1801         const char *fname = "\\lockt5.lck";
1802         int fnum1, fnum2, fnum3;
1803         bool ret;
1804         char buf[1000];
1805         bool correct = True;
1806
1807         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1808                 return False;
1809         }
1810
1811         cli_sockopt(cli1, sockops);
1812         cli_sockopt(cli2, sockops);
1813
1814         printf("starting locktest5\n");
1815
1816         cli_unlink(cli1, fname);
1817
1818         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1819         fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1820         fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1821
1822         memset(buf, 0, sizeof(buf));
1823
1824         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1825                 printf("Failed to create file\n");
1826                 correct = False;
1827                 goto fail;
1828         }
1829
1830         /* Check for NT bug... */
1831         ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1832                   cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1833         cli_close(cli1, fnum1);
1834         fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1835         ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1836         EXPECTED(ret, True);
1837         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1838         cli_close(cli1, fnum1);
1839         fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1840         cli_unlock(cli1, fnum3, 0, 1);
1841
1842         ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1843               cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1844         EXPECTED(ret, True);
1845         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1846
1847         ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1848         EXPECTED(ret, False);
1849
1850         printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1851
1852         /* Unlock the process 2 lock. */
1853         cli_unlock(cli2, fnum2, 0, 4);
1854
1855         ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1856         EXPECTED(ret, False);
1857
1858         printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1859
1860         /* Unlock the process 1 fnum3 lock. */
1861         cli_unlock(cli1, fnum3, 0, 4);
1862
1863         /* Stack 2 more locks here. */
1864         ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1865                   cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1866
1867         EXPECTED(ret, True);
1868         printf("the same process %s stack read locks\n", ret?"can":"cannot");
1869
1870         /* Unlock the first process lock, then check this was the WRITE lock that was
1871                 removed. */
1872
1873         ret = cli_unlock(cli1, fnum1, 0, 4) &&
1874                         cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1875
1876         EXPECTED(ret, True);
1877         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1878
1879         /* Unlock the process 2 lock. */
1880         cli_unlock(cli2, fnum2, 0, 4);
1881
1882         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1883
1884         ret = cli_unlock(cli1, fnum1, 1, 1) &&
1885                   cli_unlock(cli1, fnum1, 0, 4) &&
1886                   cli_unlock(cli1, fnum1, 0, 4);
1887
1888         EXPECTED(ret, True);
1889         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
1890
1891         /* Ensure the next unlock fails. */
1892         ret = cli_unlock(cli1, fnum1, 0, 4);
1893         EXPECTED(ret, False);
1894         printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
1895
1896         /* Ensure connection 2 can get a write lock. */
1897         ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1898         EXPECTED(ret, True);
1899
1900         printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1901
1902
1903  fail:
1904         cli_close(cli1, fnum1);
1905         cli_close(cli2, fnum2);
1906         cli_unlink(cli1, fname);
1907         if (!torture_close_connection(cli1)) {
1908                 correct = False;
1909         }
1910         if (!torture_close_connection(cli2)) {
1911                 correct = False;
1912         }
1913
1914         printf("finished locktest5\n");
1915        
1916         return correct;
1917 }
1918
1919 /*
1920   tries the unusual lockingX locktype bits
1921 */
1922 static bool run_locktest6(int dummy)
1923 {
1924         static struct cli_state *cli;
1925         const char *fname[1] = { "\\lock6.txt" };
1926         int i;
1927         int fnum;
1928         NTSTATUS status;
1929
1930         if (!torture_open_connection(&cli, 0)) {
1931                 return False;
1932         }
1933
1934         cli_sockopt(cli, sockops);
1935
1936         printf("starting locktest6\n");
1937
1938         for (i=0;i<1;i++) {
1939                 printf("Testing %s\n", fname[i]);
1940
1941                 cli_unlink(cli, fname[i]);
1942
1943                 fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1944                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1945                 cli_close(cli, fnum);
1946                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1947
1948                 fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
1949                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1950                 cli_close(cli, fnum);
1951                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1952
1953                 cli_unlink(cli, fname[i]);
1954         }
1955
1956         torture_close_connection(cli);
1957
1958         printf("finished locktest6\n");
1959         return True;
1960 }
1961
1962 static bool run_locktest7(int dummy)
1963 {
1964         struct cli_state *cli1;
1965         const char *fname = "\\lockt7.lck";
1966         int fnum1;
1967         char buf[200];
1968         bool correct = False;
1969
1970         if (!torture_open_connection(&cli1, 0)) {
1971                 return False;
1972         }
1973
1974         cli_sockopt(cli1, sockops);
1975
1976         printf("starting locktest7\n");
1977
1978         cli_unlink(cli1, fname);
1979
1980         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1981
1982         memset(buf, 0, sizeof(buf));
1983
1984         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1985                 printf("Failed to create file\n");
1986                 goto fail;
1987         }
1988
1989         cli_setpid(cli1, 1);
1990
1991         if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1992                 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1993                 goto fail;
1994         } else {
1995                 printf("pid1 successfully locked range 130:4 for READ\n");
1996         }
1997
1998         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1999                 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2000                 goto fail;
2001         } else {
2002                 printf("pid1 successfully read the range 130:4\n");
2003         }
2004
2005         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2006                 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2007                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2008                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2009                         goto fail;
2010                 }
2011         } else {
2012                 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2013                 goto fail;
2014         }
2015
2016         cli_setpid(cli1, 2);
2017
2018         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2019                 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2020         } else {
2021                 printf("pid2 successfully read the range 130:4\n");
2022         }
2023
2024         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2025                 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2026                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2027                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2028                         goto fail;
2029                 }
2030         } else {
2031                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2032                 goto fail;
2033         }
2034
2035         cli_setpid(cli1, 1);
2036         cli_unlock(cli1, fnum1, 130, 4);
2037
2038         if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2039                 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2040                 goto fail;
2041         } else {
2042                 printf("pid1 successfully locked range 130:4 for WRITE\n");
2043         }
2044
2045         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2046                 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2047                 goto fail;
2048         } else {
2049                 printf("pid1 successfully read the range 130:4\n");
2050         }
2051
2052         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2053                 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2054                 goto fail;
2055         } else {
2056                 printf("pid1 successfully wrote to the range 130:4\n");
2057         }
2058
2059         cli_setpid(cli1, 2);
2060
2061         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2062                 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2063                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2064                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2065                         goto fail;
2066                 }
2067         } else {
2068                 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2069                 goto fail;
2070         }
2071
2072         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2073                 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2074                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2075                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2076                         goto fail;
2077                 }
2078         } else {
2079                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2080                 goto fail;
2081         }
2082
2083         cli_unlock(cli1, fnum1, 130, 0);
2084         correct = True;
2085
2086 fail:
2087         cli_close(cli1, fnum1);
2088         cli_unlink(cli1, fname);
2089         torture_close_connection(cli1);
2090
2091         printf("finished locktest7\n");
2092         return correct;
2093 }
2094
2095 /*
2096 test whether fnums and tids open on one VC are available on another (a major
2097 security hole)
2098 */
2099 static bool run_fdpasstest(int dummy)
2100 {
2101         struct cli_state *cli1, *cli2;
2102         const char *fname = "\\fdpass.tst";
2103         int fnum1;
2104         char buf[1024];
2105
2106         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2107                 return False;
2108         }
2109         cli_sockopt(cli1, sockops);
2110         cli_sockopt(cli2, sockops);
2111
2112         printf("starting fdpasstest\n");
2113
2114         cli_unlink(cli1, fname);
2115
2116         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2117         if (fnum1 == -1) {
2118                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2119                 return False;
2120         }
2121
2122         if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2123                 printf("write failed (%s)\n", cli_errstr(cli1));
2124                 return False;
2125         }
2126
2127         cli2->vuid = cli1->vuid;
2128         cli2->cnum = cli1->cnum;
2129         cli2->pid = cli1->pid;
2130
2131         if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2132                 printf("read succeeded! nasty security hole [%s]\n",
2133                        buf);
2134                 return False;
2135         }
2136
2137         cli_close(cli1, fnum1);
2138         cli_unlink(cli1, fname);
2139
2140         torture_close_connection(cli1);
2141         torture_close_connection(cli2);
2142
2143         printf("finished fdpasstest\n");
2144         return True;
2145 }
2146
2147 static bool run_fdsesstest(int dummy)
2148 {
2149         struct cli_state *cli;
2150         uint16 new_vuid;
2151         uint16 saved_vuid;
2152         uint16 new_cnum;
2153         uint16 saved_cnum;
2154         const char *fname = "\\fdsess.tst";
2155         const char *fname1 = "\\fdsess1.tst";
2156         int fnum1;
2157         int fnum2;
2158         char buf[1024];
2159         bool ret = True;
2160
2161         if (!torture_open_connection(&cli, 0))
2162                 return False;
2163         cli_sockopt(cli, sockops);
2164
2165         if (!torture_cli_session_setup2(cli, &new_vuid))
2166                 return False;
2167
2168         saved_cnum = cli->cnum;
2169         if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2170                 return False;
2171         new_cnum = cli->cnum;
2172         cli->cnum = saved_cnum;
2173
2174         printf("starting fdsesstest\n");
2175
2176         cli_unlink(cli, fname);
2177         cli_unlink(cli, fname1);
2178
2179         fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2180         if (fnum1 == -1) {
2181                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2182                 return False;
2183         }
2184
2185         if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2186                 printf("write failed (%s)\n", cli_errstr(cli));
2187                 return False;
2188         }
2189
2190         saved_vuid = cli->vuid;
2191         cli->vuid = new_vuid;
2192
2193         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2194                 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2195                        buf);
2196                 ret = False;
2197         }
2198         /* Try to open a file with different vuid, samba cnum. */
2199         fnum2 = cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2200         if (fnum2 != -1) {
2201                 printf("create with different vuid, same cnum succeeded.\n");
2202                 cli_close(cli, fnum2);
2203                 cli_unlink(cli, fname1);
2204         } else {
2205                 printf("create with different vuid, same cnum failed.\n");
2206                 printf("This will cause problems with service clients.\n");
2207                 ret = False;
2208         }
2209
2210         cli->vuid = saved_vuid;
2211
2212         /* Try with same vuid, different cnum. */
2213         cli->cnum = new_cnum;
2214
2215         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2216                 printf("read succeeded with different cnum![%s]\n",
2217                        buf);
2218                 ret = False;
2219         }
2220
2221         cli->cnum = saved_cnum;
2222         cli_close(cli, fnum1);
2223         cli_unlink(cli, fname);
2224
2225         torture_close_connection(cli);
2226
2227         printf("finished fdsesstest\n");
2228         return ret;
2229 }
2230
2231 /*
2232   This test checks that 
2233
2234   1) the server does not allow an unlink on a file that is open
2235 */
2236 static bool run_unlinktest(int dummy)
2237 {
2238         struct cli_state *cli;
2239         const char *fname = "\\unlink.tst";
2240         int fnum;
2241         bool correct = True;
2242
2243         if (!torture_open_connection(&cli, 0)) {
2244                 return False;
2245         }
2246
2247         cli_sockopt(cli, sockops);
2248
2249         printf("starting unlink test\n");
2250
2251         cli_unlink(cli, fname);
2252
2253         cli_setpid(cli, 1);
2254
2255         fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2256         if (fnum == -1) {
2257                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2258                 return False;
2259         }
2260
2261         if (cli_unlink(cli, fname)) {
2262                 printf("error: server allowed unlink on an open file\n");
2263                 correct = False;
2264         } else {
2265                 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare, 
2266                                       NT_STATUS_SHARING_VIOLATION);
2267         }
2268
2269         cli_close(cli, fnum);
2270         cli_unlink(cli, fname);
2271
2272         if (!torture_close_connection(cli)) {
2273                 correct = False;
2274         }
2275
2276         printf("unlink test finished\n");
2277         
2278         return correct;
2279 }
2280
2281
2282 /*
2283 test how many open files this server supports on the one socket
2284 */
2285 static bool run_maxfidtest(int dummy)
2286 {
2287         struct cli_state *cli;
2288         const char *ftemplate = "\\maxfid.%d.%d";
2289         fstring fname;
2290         int fnums[0x11000], i;
2291         int retries=4;
2292         bool correct = True;
2293
2294         cli = current_cli;
2295
2296         if (retries <= 0) {
2297                 printf("failed to connect\n");
2298                 return False;
2299         }
2300
2301         cli_sockopt(cli, sockops);
2302
2303         for (i=0; i<0x11000; i++) {
2304                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2305                 if ((fnums[i] = cli_open(cli, fname, 
2306                                         O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
2307                     -1) {
2308                         printf("open of %s failed (%s)\n", 
2309                                fname, cli_errstr(cli));
2310                         printf("maximum fnum is %d\n", i);
2311                         break;
2312                 }
2313                 printf("%6d\r", i);
2314         }
2315         printf("%6d\n", i);
2316         i--;
2317
2318         printf("cleaning up\n");
2319         for (;i>=0;i--) {
2320                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2321                 cli_close(cli, fnums[i]);
2322                 if (!cli_unlink(cli, fname)) {
2323                         printf("unlink of %s failed (%s)\n", 
2324                                fname, cli_errstr(cli));
2325                         correct = False;
2326                 }
2327                 printf("%6d\r", i);
2328         }
2329         printf("%6d\n", 0);
2330
2331         printf("maxfid test finished\n");
2332         if (!torture_close_connection(cli)) {
2333                 correct = False;
2334         }
2335         return correct;
2336 }
2337
2338 /* generate a random buffer */
2339 static void rand_buf(char *buf, int len)
2340 {
2341         while (len--) {
2342                 *buf = (char)sys_random();
2343                 buf++;
2344         }
2345 }
2346
2347 /* send smb negprot commands, not reading the response */
2348 static bool run_negprot_nowait(int dummy)
2349 {
2350         int i;
2351         static struct cli_state *cli;
2352         bool correct = True;
2353
2354         printf("starting negprot nowait test\n");
2355
2356         if (!(cli = open_nbt_connection())) {
2357                 return False;
2358         }
2359
2360         for (i=0;i<50000;i++) {
2361                 cli_negprot_sendsync(cli);
2362         }
2363
2364         if (!torture_close_connection(cli)) {
2365                 correct = False;
2366         }
2367
2368         printf("finished negprot nowait test\n");
2369
2370         return correct;
2371 }
2372
2373
2374 /* send random IPC commands */
2375 static bool run_randomipc(int dummy)
2376 {
2377         char *rparam = NULL;
2378         char *rdata = NULL;
2379         unsigned int rdrcnt,rprcnt;
2380         char param[1024];
2381         int api, param_len, i;
2382         struct cli_state *cli;
2383         bool correct = True;
2384         int count = 50000;
2385
2386         printf("starting random ipc test\n");
2387
2388         if (!torture_open_connection(&cli, 0)) {
2389                 return False;
2390         }
2391
2392         for (i=0;i<count;i++) {
2393                 api = sys_random() % 500;
2394                 param_len = (sys_random() % 64);
2395
2396                 rand_buf(param, param_len);
2397   
2398                 SSVAL(param,0,api); 
2399
2400                 cli_api(cli, 
2401                         param, param_len, 8,  
2402                         NULL, 0, BUFFER_SIZE, 
2403                         &rparam, &rprcnt,     
2404                         &rdata, &rdrcnt);
2405                 if (i % 100 == 0) {
2406                         printf("%d/%d\r", i,count);
2407                 }
2408         }
2409         printf("%d/%d\n", i, count);
2410
2411         if (!torture_close_connection(cli)) {
2412                 correct = False;
2413         }
2414
2415         printf("finished random ipc test\n");
2416
2417         return correct;
2418 }
2419
2420
2421
2422 static void browse_callback(const char *sname, uint32 stype, 
2423                             const char *comment, void *state)
2424 {
2425         printf("\t%20.20s %08x %s\n", sname, stype, comment);
2426 }
2427
2428
2429
2430 /*
2431   This test checks the browse list code
2432
2433 */
2434 static bool run_browsetest(int dummy)
2435 {
2436         static struct cli_state *cli;
2437         bool correct = True;
2438
2439         printf("starting browse test\n");
2440
2441         if (!torture_open_connection(&cli, 0)) {
2442                 return False;
2443         }
2444
2445         printf("domain list:\n");
2446         cli_NetServerEnum(cli, cli->server_domain, 
2447                           SV_TYPE_DOMAIN_ENUM,
2448                           browse_callback, NULL);
2449
2450         printf("machine list:\n");
2451         cli_NetServerEnum(cli, cli->server_domain, 
2452                           SV_TYPE_ALL,
2453                           browse_callback, NULL);
2454
2455         if (!torture_close_connection(cli)) {
2456                 correct = False;
2457         }
2458
2459         printf("browse test finished\n");
2460
2461         return correct;
2462
2463 }
2464
2465
2466 /*
2467   This checks how the getatr calls works
2468 */
2469 static bool run_attrtest(int dummy)
2470 {
2471         struct cli_state *cli;
2472         int fnum;
2473         time_t t, t2;
2474         const char *fname = "\\attrib123456789.tst";
2475         bool correct = True;
2476
2477         printf("starting attrib test\n");
2478
2479         if (!torture_open_connection(&cli, 0)) {
2480                 return False;
2481         }
2482
2483         cli_unlink(cli, fname);
2484         fnum = cli_open(cli, fname, 
2485                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2486         cli_close(cli, fnum);
2487         if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2488                 printf("getatr failed (%s)\n", cli_errstr(cli));
2489                 correct = False;
2490         }
2491
2492         if (abs(t - time(NULL)) > 60*60*24*10) {
2493                 printf("ERROR: SMBgetatr bug. time is %s",
2494                        ctime(&t));
2495                 t = time(NULL);
2496                 correct = True;
2497         }
2498
2499         t2 = t-60*60*24; /* 1 day ago */
2500
2501         if (!cli_setatr(cli, fname, 0, t2)) {
2502                 printf("setatr failed (%s)\n", cli_errstr(cli));
2503                 correct = True;
2504         }
2505
2506         if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2507                 printf("getatr failed (%s)\n", cli_errstr(cli));
2508                 correct = True;
2509         }
2510
2511         if (t != t2) {
2512                 printf("ERROR: getatr/setatr bug. times are\n%s",
2513                        ctime(&t));
2514                 printf("%s", ctime(&t2));
2515                 correct = True;
2516         }
2517
2518         cli_unlink(cli, fname);
2519
2520         if (!torture_close_connection(cli)) {
2521                 correct = False;
2522         }
2523
2524         printf("attrib test finished\n");
2525
2526         return correct;
2527 }
2528
2529
2530 /*
2531   This checks a couple of trans2 calls
2532 */
2533 static bool run_trans2test(int dummy)
2534 {
2535         struct cli_state *cli;
2536         int fnum;
2537         SMB_OFF_T size;
2538         time_t c_time, a_time, m_time;
2539         struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2540         const char *fname = "\\trans2.tst";
2541         const char *dname = "\\trans2";
2542         const char *fname2 = "\\trans2\\trans2.tst";
2543         char pname[1024];
2544         bool correct = True;
2545
2546         printf("starting trans2 test\n");
2547
2548         if (!torture_open_connection(&cli, 0)) {
2549                 return False;
2550         }
2551
2552         cli_unlink(cli, fname);
2553         fnum = cli_open(cli, fname, 
2554                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2555         if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2556                            &m_time_ts, NULL)) {
2557                 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2558                 correct = False;
2559         }
2560
2561         if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2562                 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2563                 correct = False;
2564         }
2565
2566         if (strcmp(pname, fname)) {
2567                 printf("qfilename gave different name? [%s] [%s]\n",
2568                        fname, pname);
2569                 correct = False;
2570         }
2571
2572         cli_close(cli, fnum);
2573
2574         sleep(2);
2575
2576         cli_unlink(cli, fname);
2577         fnum = cli_open(cli, fname, 
2578                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2579         if (fnum == -1) {
2580                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2581                 return False;
2582         }
2583         cli_close(cli, fnum);
2584
2585         if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2586                 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2587                 correct = False;
2588         } else {
2589                 if (c_time != m_time) {
2590                         printf("create time=%s", ctime(&c_time));
2591                         printf("modify time=%s", ctime(&m_time));
2592                         printf("This system appears to have sticky create times\n");
2593                 }
2594                 if (a_time % (60*60) == 0) {
2595                         printf("access time=%s", ctime(&a_time));
2596                         printf("This system appears to set a midnight access time\n");
2597                         correct = False;
2598                 }
2599
2600                 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2601                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2602                         correct = False;
2603                 }
2604         }
2605
2606
2607         cli_unlink(cli, fname);
2608         fnum = cli_open(cli, fname, 
2609                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2610         cli_close(cli, fnum);
2611         if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts, 
2612                             &m_time_ts, &size, NULL, NULL)) {
2613                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2614                 correct = False;
2615         } else {
2616                 if (w_time_ts.tv_sec < 60*60*24*2) {
2617                         printf("write time=%s", ctime(&w_time_ts.tv_sec));
2618                         printf("This system appears to set a initial 0 write time\n");
2619                         correct = False;
2620                 }
2621         }
2622
2623         cli_unlink(cli, fname);
2624
2625
2626         /* check if the server updates the directory modification time
2627            when creating a new file */
2628         if (!cli_mkdir(cli, dname)) {
2629                 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2630                 correct = False;
2631         }
2632         sleep(3);
2633         if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts, 
2634                             &m_time_ts, &size, NULL, NULL)) {
2635                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2636                 correct = False;
2637         }
2638
2639         fnum = cli_open(cli, fname2, 
2640                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2641         cli_write(cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
2642         cli_close(cli, fnum);
2643         if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts, 
2644                             &m_time2_ts, &size, NULL, NULL)) {
2645                 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2646                 correct = False;
2647         } else {
2648                 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2649                     == 0) {
2650                         printf("This system does not update directory modification times\n");
2651                         correct = False;
2652                 }
2653         }
2654         cli_unlink(cli, fname2);
2655         cli_rmdir(cli, dname);
2656
2657         if (!torture_close_connection(cli)) {
2658                 correct = False;
2659         }
2660
2661         printf("trans2 test finished\n");
2662
2663         return correct;
2664 }
2665
2666 /*
2667   This checks new W2K calls.
2668 */
2669
2670 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2671 {
2672         char *buf = NULL;
2673         uint32 len;
2674         bool correct = True;
2675
2676         if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2677                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2678                 correct = False;
2679         } else {
2680                 printf("qfileinfo: level %d, len = %u\n", level, len);
2681                 dump_data(0, (uint8 *)buf, len);
2682                 printf("\n");
2683         }
2684         SAFE_FREE(buf);
2685         return correct;
2686 }
2687
2688 static bool run_w2ktest(int dummy)
2689 {
2690         struct cli_state *cli;
2691         int fnum;
2692         const char *fname = "\\w2ktest\\w2k.tst";
2693         int level;
2694         bool correct = True;
2695
2696         printf("starting w2k test\n");
2697
2698         if (!torture_open_connection(&cli, 0)) {
2699                 return False;
2700         }
2701
2702         fnum = cli_open(cli, fname, 
2703                         O_RDWR | O_CREAT , DENY_NONE);
2704
2705         for (level = 1004; level < 1040; level++) {
2706                 new_trans(cli, fnum, level);
2707         }
2708
2709         cli_close(cli, fnum);
2710
2711         if (!torture_close_connection(cli)) {
2712                 correct = False;
2713         }
2714
2715         printf("w2k test finished\n");
2716         
2717         return correct;
2718 }
2719
2720
2721 /*
2722   this is a harness for some oplock tests
2723  */
2724 static bool run_oplock1(int dummy)
2725 {
2726         struct cli_state *cli1;
2727         const char *fname = "\\lockt1.lck";
2728         int fnum1;
2729         bool correct = True;
2730
2731         printf("starting oplock test 1\n");
2732
2733         if (!torture_open_connection(&cli1, 0)) {
2734                 return False;
2735         }
2736
2737         cli_unlink(cli1, fname);
2738
2739         cli_sockopt(cli1, sockops);
2740
2741         cli1->use_oplocks = True;
2742
2743         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2744         if (fnum1 == -1) {
2745                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2746                 return False;
2747         }
2748
2749         cli1->use_oplocks = False;
2750
2751         cli_unlink(cli1, fname);
2752         cli_unlink(cli1, fname);
2753
2754         if (!cli_close(cli1, fnum1)) {
2755                 printf("close2 failed (%s)\n", cli_errstr(cli1));
2756                 return False;
2757         }
2758
2759         if (!cli_unlink(cli1, fname)) {
2760                 printf("unlink failed (%s)\n", cli_errstr(cli1));
2761                 return False;
2762         }
2763
2764         if (!torture_close_connection(cli1)) {
2765                 correct = False;
2766         }
2767
2768         printf("finished oplock test 1\n");
2769
2770         return correct;
2771 }
2772
2773 static bool run_oplock2(int dummy)
2774 {
2775         struct cli_state *cli1, *cli2;
2776         const char *fname = "\\lockt2.lck";
2777         int fnum1, fnum2;
2778         int saved_use_oplocks = use_oplocks;
2779         char buf[4];
2780         bool correct = True;
2781         volatile bool *shared_correct;
2782
2783         shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2784         *shared_correct = True;
2785
2786         use_level_II_oplocks = True;
2787         use_oplocks = True;
2788
2789         printf("starting oplock test 2\n");
2790
2791         if (!torture_open_connection(&cli1, 0)) {
2792                 use_level_II_oplocks = False;
2793                 use_oplocks = saved_use_oplocks;
2794                 return False;
2795         }
2796
2797         cli1->use_oplocks = True;
2798         cli1->use_level_II_oplocks = True;
2799
2800         if (!torture_open_connection(&cli2, 1)) {
2801                 use_level_II_oplocks = False;
2802                 use_oplocks = saved_use_oplocks;
2803                 return False;
2804         }
2805
2806         cli2->use_oplocks = True;
2807         cli2->use_level_II_oplocks = True;
2808
2809         cli_unlink(cli1, fname);
2810
2811         cli_sockopt(cli1, sockops);
2812         cli_sockopt(cli2, sockops);
2813
2814         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2815         if (fnum1 == -1) {
2816                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2817                 return False;
2818         }
2819
2820         /* Don't need the globals any more. */
2821         use_level_II_oplocks = False;
2822         use_oplocks = saved_use_oplocks;
2823
2824         if (fork() == 0) {
2825                 /* Child code */
2826                 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
2827                 if (fnum2 == -1) {
2828                         printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
2829                         *shared_correct = False;
2830                         exit(0);
2831                 }
2832
2833                 sleep(2);
2834
2835                 if (!cli_close(cli2, fnum2)) {
2836                         printf("close2 failed (%s)\n", cli_errstr(cli1));
2837                         *shared_correct = False;
2838                 }
2839
2840                 exit(0);
2841         }
2842
2843         sleep(2);
2844
2845         /* Ensure cli1 processes the break. Empty file should always return 0
2846          * bytes.  */
2847
2848         if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
2849                 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
2850                 correct = False;
2851         }
2852
2853         /* Should now be at level II. */
2854         /* Test if sending a write locks causes a break to none. */
2855
2856         if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2857                 printf("lock failed (%s)\n", cli_errstr(cli1));
2858                 correct = False;
2859         }
2860
2861         cli_unlock(cli1, fnum1, 0, 4);
2862
2863         sleep(2);
2864
2865         if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2866                 printf("lock failed (%s)\n", cli_errstr(cli1));
2867                 correct = False;
2868         }
2869
2870         cli_unlock(cli1, fnum1, 0, 4);
2871
2872         sleep(2);
2873
2874         cli_read(cli1, fnum1, buf, 0, 4);
2875
2876 #if 0
2877         if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
2878                 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
2879                 correct = False;
2880         }
2881 #endif
2882
2883         if (!cli_close(cli1, fnum1)) {
2884                 printf("close1 failed (%s)\n", cli_errstr(cli1));
2885                 correct = False;
2886         }
2887
2888         sleep(4);
2889
2890         if (!cli_unlink(cli1, fname)) {
2891                 printf("unlink failed (%s)\n", cli_errstr(cli1));
2892                 correct = False;
2893         }
2894
2895         if (!torture_close_connection(cli1)) {
2896                 correct = False;
2897         }
2898
2899         if (!*shared_correct) {
2900                 correct = False;
2901         }
2902
2903         printf("finished oplock test 2\n");
2904
2905         return correct;
2906 }
2907
2908 /* handler for oplock 3 tests */
2909 static bool oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2910 {
2911         printf("got oplock break fnum=%d level=%d\n",
2912                fnum, level);
2913         return cli_oplock_ack(cli, fnum, level);
2914 }
2915
2916 static bool run_oplock3(int dummy)
2917 {
2918         struct cli_state *cli;
2919         const char *fname = "\\oplockt3.dat";
2920         int fnum;
2921         char buf[4] = "abcd";
2922         bool correct = True;
2923         volatile bool *shared_correct;
2924
2925         shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2926         *shared_correct = True;
2927
2928         printf("starting oplock test 3\n");
2929
2930         if (fork() == 0) {
2931                 /* Child code */
2932                 use_oplocks = True;
2933                 use_level_II_oplocks = True;
2934                 if (!torture_open_connection(&cli, 0)) {
2935                         *shared_correct = False;
2936                         exit(0);
2937                 } 
2938                 sleep(2);
2939                 /* try to trigger a oplock break in parent */
2940                 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2941                 cli_write(cli, fnum, 0, buf, 0, 4);
2942                 exit(0);
2943         }
2944
2945         /* parent code */
2946         use_oplocks = True;
2947         use_level_II_oplocks = True;
2948         if (!torture_open_connection(&cli, 1)) { /* other is forked */
2949                 return False;
2950         }
2951         cli_oplock_handler(cli, oplock3_handler);
2952         fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2953         cli_write(cli, fnum, 0, buf, 0, 4);
2954         cli_close(cli, fnum);
2955         fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2956         cli->timeout = 20000;
2957         cli_receive_smb(cli);
2958         printf("finished oplock test 3\n");
2959
2960         return (correct && *shared_correct);
2961
2962 /* What are we looking for here?  What's sucess and what's FAILURE? */
2963 }
2964
2965
2966
2967 /*
2968   Test delete on close semantics.
2969  */
2970 static bool run_deletetest(int dummy)
2971 {
2972         struct cli_state *cli1 = NULL;
2973         struct cli_state *cli2 = NULL;
2974         const char *fname = "\\delete.file";
2975         int fnum1 = -1;
2976         int fnum2 = -1;
2977         bool correct = True;
2978         
2979         printf("starting delete test\n");
2980         
2981         if (!torture_open_connection(&cli1, 0)) {
2982                 return False;
2983         }
2984         
2985         cli_sockopt(cli1, sockops);
2986
2987         /* Test 1 - this should delete the file on close. */
2988         
2989         cli_setatr(cli1, fname, 0, 0);
2990         cli_unlink(cli1, fname);
2991         
2992         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2993                                    0, FILE_OVERWRITE_IF, 
2994                                    FILE_DELETE_ON_CLOSE, 0);
2995         
2996         if (fnum1 == -1) {
2997                 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2998                 correct = False;
2999                 goto fail;
3000         }
3001
3002 #if 0 /* JRATEST */
3003         {
3004                 uint32 *accinfo = NULL;
3005                 uint32 len;
3006                 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3007                 if (accinfo)
3008                         printf("access mode = 0x%lx\n", *accinfo);
3009                 SAFE_FREE(accinfo);
3010         }
3011 #endif
3012
3013         if (!cli_close(cli1, fnum1)) {
3014                 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3015                 correct = False;
3016                 goto fail;
3017         }
3018
3019         fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
3020         if (fnum1 != -1) {
3021                 printf("[1] open of %s succeeded (should fail)\n", fname);
3022                 correct = False;
3023                 goto fail;
3024         }
3025         
3026         printf("first delete on close test succeeded.\n");
3027         
3028         /* Test 2 - this should delete the file on close. */
3029         
3030         cli_setatr(cli1, fname, 0, 0);
3031         cli_unlink(cli1, fname);
3032         
3033         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS,
3034                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, 
3035                                    FILE_OVERWRITE_IF, 0, 0);
3036         
3037         if (fnum1 == -1) {
3038                 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3039                 correct = False;
3040                 goto fail;
3041         }
3042         
3043         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3044                 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3045                 correct = False;
3046                 goto fail;
3047         }
3048         
3049         if (!cli_close(cli1, fnum1)) {
3050                 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3051                 correct = False;
3052                 goto fail;
3053         }
3054         
3055         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3056         if (fnum1 != -1) {
3057                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3058                 if (!cli_close(cli1, fnum1)) {
3059                         printf("[2] close failed (%s)\n", cli_errstr(cli1));
3060                         correct = False;
3061                         goto fail;
3062                 }
3063                 cli_unlink(cli1, fname);
3064         } else
3065                 printf("second delete on close test succeeded.\n");
3066         
3067         /* Test 3 - ... */
3068         cli_setatr(cli1, fname, 0, 0);
3069         cli_unlink(cli1, fname);
3070
3071         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3072                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3073
3074         if (fnum1 == -1) {
3075                 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3076                 correct = False;
3077                 goto fail;
3078         }
3079
3080         /* This should fail with a sharing violation - open for delete is only compatible
3081            with SHARE_DELETE. */
3082
3083         fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3084                         FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0);
3085
3086         if (fnum2 != -1) {
3087                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
3088                 correct = False;
3089                 goto fail;
3090         }
3091
3092         /* This should succeed. */
3093
3094         fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3095                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3096
3097         if (fnum2 == -1) {
3098                 printf("[3] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3099                 correct = False;
3100                 goto fail;
3101         }
3102
3103         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3104                 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3105                 correct = False;
3106                 goto fail;
3107         }
3108         
3109         if (!cli_close(cli1, fnum1)) {
3110                 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3111                 correct = False;
3112                 goto fail;
3113         }
3114         
3115         if (!cli_close(cli1, fnum2)) {
3116                 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3117                 correct = False;
3118                 goto fail;
3119         }
3120         
3121         /* This should fail - file should no longer be there. */
3122
3123         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3124         if (fnum1 != -1) {
3125                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3126                 if (!cli_close(cli1, fnum1)) {
3127                         printf("[3] close failed (%s)\n", cli_errstr(cli1));
3128                 }
3129                 cli_unlink(cli1, fname);
3130                 correct = False;
3131                 goto fail;
3132         } else
3133                 printf("third delete on close test succeeded.\n");
3134
3135         /* Test 4 ... */
3136         cli_setatr(cli1, fname, 0, 0);
3137         cli_unlink(cli1, fname);
3138
3139         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3140                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3141                                                                 
3142         if (fnum1 == -1) {
3143                 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3144                 correct = False;
3145                 goto fail;
3146         }
3147
3148         /* This should succeed. */
3149         fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3150                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3151         if (fnum2 == -1) {
3152                 printf("[4] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3153                 correct = False;
3154                 goto fail;
3155         }
3156         
3157         if (!cli_close(cli1, fnum2)) {
3158                 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3159                 correct = False;
3160                 goto fail;
3161         }
3162         
3163         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3164                 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3165                 correct = False;
3166                 goto fail;
3167         }
3168         
3169         /* This should fail - no more opens once delete on close set. */
3170         fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3171                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3172                                    FILE_OPEN, 0, 0);
3173         if (fnum2 != -1) {
3174                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
3175                 correct = False;
3176                 goto fail;
3177         } else
3178                 printf("fourth delete on close test succeeded.\n");
3179         
3180         if (!cli_close(cli1, fnum1)) {
3181                 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3182                 correct = False;
3183                 goto fail;
3184         }
3185         
3186         /* Test 5 ... */
3187         cli_setatr(cli1, fname, 0, 0);
3188         cli_unlink(cli1, fname);
3189         
3190         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
3191         if (fnum1 == -1) {
3192                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3193                 correct = False;
3194                 goto fail;
3195         }
3196
3197         /* This should fail - only allowed on NT opens with DELETE access. */
3198
3199         if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3200                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3201                 correct = False;
3202                 goto fail;
3203         }
3204
3205         if (!cli_close(cli1, fnum1)) {
3206                 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3207                 correct = False;
3208                 goto fail;
3209         }
3210         
3211         printf("fifth delete on close test succeeded.\n");
3212         
3213         /* Test 6 ... */
3214         cli_setatr(cli1, fname, 0, 0);
3215         cli_unlink(cli1, fname);
3216         
3217         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3218                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3219                                    FILE_OVERWRITE_IF, 0, 0);
3220         
3221         if (fnum1 == -1) {
3222                 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3223                 correct = False;
3224                 goto fail;
3225         }
3226         
3227         /* This should fail - only allowed on NT opens with DELETE access. */
3228         
3229         if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3230                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3231                 correct = False;
3232                 goto fail;
3233         }
3234
3235         if (!cli_close(cli1, fnum1)) {
3236                 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3237                 correct = False;
3238                 goto fail;
3239         }
3240
3241         printf("sixth delete on close test succeeded.\n");
3242         
3243         /* Test 7 ... */
3244         cli_setatr(cli1, fname, 0, 0);
3245         cli_unlink(cli1, fname);
3246         
3247         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3248                                    FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);
3249                                                                 
3250         if (fnum1 == -1) {
3251                 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3252                 correct = False;
3253                 goto fail;
3254         }
3255
3256         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3257                 printf("[7] setting delete_on_close on file failed !\n");
3258                 correct = False;
3259                 goto fail;
3260         }
3261         
3262         if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
3263                 printf("[7] unsetting delete_on_close on file failed !\n");
3264                 correct = False;
3265                 goto fail;
3266         }
3267
3268         if (!cli_close(cli1, fnum1)) {
3269                 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3270                 correct = False;
3271                 goto fail;
3272         }
3273         
3274         /* This next open should succeed - we reset the flag. */
3275         
3276         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3277         if (fnum1 == -1) {
3278                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3279                 correct = False;
3280                 goto fail;
3281         }
3282
3283         if (!cli_close(cli1, fnum1)) {
3284                 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3285                 correct = False;
3286                 goto fail;
3287         }
3288
3289         printf("seventh delete on close test succeeded.\n");
3290         
3291         /* Test 7 ... */
3292         cli_setatr(cli1, fname, 0, 0);
3293         cli_unlink(cli1, fname);
3294         
3295         if (!torture_open_connection(&cli2, 1)) {
3296                 printf("[8] failed to open second connection.\n");
3297                 correct = False;
3298                 goto fail;
3299         }
3300
3301         cli_sockopt(cli1, sockops);
3302         
3303         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3304                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3305                                    FILE_OVERWRITE_IF, 0, 0);
3306         
3307         if (fnum1 == -1) {
3308                 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3309                 correct = False;
3310                 goto fail;
3311         }
3312
3313         fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3314                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3315                                    FILE_OPEN, 0, 0);
3316         
3317         if (fnum2 == -1) {
3318                 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3319                 correct = False;
3320                 goto fail;
3321         }
3322
3323         if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3324                 printf("[8] setting delete_on_close on file failed !\n");
3325                 correct = False;
3326                 goto fail;
3327         }
3328         
3329         if (!cli_close(cli1, fnum1)) {
3330                 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3331                 correct = False;
3332                 goto fail;
3333         }
3334
3335         if (!cli_close(cli2, fnum2)) {
3336                 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3337                 correct = False;
3338                 goto fail;
3339         }
3340
3341         /* This should fail.. */
3342         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3343         if (fnum1 != -1) {
3344                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3345                 goto fail;
3346                 correct = False;
3347         } else
3348                 printf("eighth delete on close test succeeded.\n");
3349
3350         /* This should fail - we need to set DELETE_ACCESS. */
3351         fnum1 = cli_nt_create_full(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3352                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3353         
3354         if (fnum1 != -1) {
3355                 printf("[9] open of %s succeeded should have failed!\n", fname);
3356                 correct = False;
3357                 goto fail;
3358         }
3359
3360         printf("ninth delete on close test succeeded.\n");
3361
3362         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3363                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3364         if (fnum1 == -1) {
3365                 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3366                 correct = False;
3367                 goto fail;
3368         }
3369
3370         /* This should delete the file. */
3371         if (!cli_close(cli1, fnum1)) {
3372                 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3373                 correct = False;
3374                 goto fail;
3375         }
3376
3377         /* This should fail.. */
3378         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3379         if (fnum1 != -1) {
3380                 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3381                 goto fail;
3382                 correct = False;
3383         } else
3384                 printf("tenth delete on close test succeeded.\n");
3385
3386         cli_setatr(cli1, fname, 0, 0);
3387         cli_unlink(cli1, fname);
3388
3389         /* What error do we get when attempting to open a read-only file with
3390            delete access ? */
3391
3392         /* Create a readonly file. */
3393         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3394                                    FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3395         if (fnum1 == -1) {
3396                 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3397                 correct = False;
3398                 goto fail;
3399         }
3400
3401         if (!cli_close(cli1, fnum1)) {
3402                 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3403                 correct = False;
3404                 goto fail;
3405         }
3406
3407         /* Now try open for delete access. */
3408         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3409                                    0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3410                                    FILE_OVERWRITE_IF, 0, 0);
3411         
3412         if (fnum1 != -1) {
3413                 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3414                 cli_close(cli1, fnum1);
3415                 goto fail;
3416                 correct = False;
3417         } else {
3418                 NTSTATUS nterr = cli_nt_error(cli1);
3419                 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3420                         printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3421                         goto fail;
3422                         correct = False;
3423                 } else {
3424                         printf("eleventh delete on close test succeeded.\n");
3425                 }
3426         }
3427         
3428         printf("finished delete test\n");
3429
3430   fail:
3431         /* FIXME: This will crash if we aborted before cli2 got
3432          * intialized, because these functions don't handle
3433          * uninitialized connections. */
3434                 
3435         if (fnum1 != -1) cli_close(cli1, fnum1);
3436         if (fnum2 != -1) cli_close(cli1, fnum2);
3437         cli_setatr(cli1, fname, 0, 0);
3438         cli_unlink(cli1, fname);
3439
3440         if (cli1 && !torture_close_connection(cli1)) {
3441                 correct = False;
3442         }
3443         if (cli2 && !torture_close_connection(cli2)) {
3444                 correct = False;
3445         }
3446         return correct;
3447 }
3448
3449
3450 /*
3451   print out server properties
3452  */
3453 static bool run_properties(int dummy)
3454 {
3455         static struct cli_state *cli;
3456         bool correct = True;
3457         
3458         printf("starting properties test\n");
3459         
3460         ZERO_STRUCT(cli);
3461
3462         if (!torture_open_connection(&cli, 0)) {
3463                 return False;
3464         }
3465         
3466         cli_sockopt(cli, sockops);
3467
3468         d_printf("Capabilities 0x%08x\n", cli->capabilities);
3469
3470         if (!torture_close_connection(cli)) {
3471                 correct = False;
3472         }
3473
3474         return correct;
3475 }
3476
3477
3478
3479 /* FIRST_DESIRED_ACCESS   0xf019f */
3480 #define FIRST_DESIRED_ACCESS   FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3481                                FILE_READ_EA|                           /* 0xf */ \
3482                                FILE_WRITE_EA|FILE_READ_ATTRIBUTES|     /* 0x90 */ \
3483                                FILE_WRITE_ATTRIBUTES|                  /* 0x100 */ \
3484                                DELETE_ACCESS|READ_CONTROL_ACCESS|\
3485                                WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS     /* 0xf0000 */
3486 /* SECOND_DESIRED_ACCESS  0xe0080 */
3487 #define SECOND_DESIRED_ACCESS  FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
3488                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3489                                WRITE_OWNER_ACCESS                      /* 0xe0000 */
3490
3491 #if 0
3492 #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
3493                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3494                                FILE_READ_DATA|\
3495                                WRITE_OWNER_ACCESS                      /* */
3496 #endif
3497
3498 /*
3499   Test ntcreate calls made by xcopy
3500  */
3501 static bool run_xcopy(int dummy)
3502 {
3503         static struct cli_state *cli1;
3504         const char *fname = "\\test.txt";
3505         bool correct = True;
3506         int fnum1, fnum2;
3507
3508         printf("starting xcopy test\n");
3509         
3510         if (!torture_open_connection(&cli1, 0)) {
3511                 return False;
3512         }
3513         
3514         fnum1 = cli_nt_create_full(cli1, fname, 0,
3515                                    FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3516                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 
3517                                    0x4044, 0);
3518
3519         if (fnum1 == -1) {
3520                 printf("First open failed - %s\n", cli_errstr(cli1));
3521                 return False;
3522         }
3523
3524         fnum2 = cli_nt_create_full(cli1, fname, 0,
3525                                    SECOND_DESIRED_ACCESS, 0,
3526                                    FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 
3527                                    0x200000, 0);
3528         if (fnum2 == -1) {
3529                 printf("second open failed - %s\n", cli_errstr(cli1));
3530                 return False;
3531         }
3532         
3533         if (!torture_close_connection(cli1)) {
3534                 correct = False;
3535         }
3536         
3537         return correct;
3538 }
3539
3540 /*
3541   Test rename on files open with share delete and no share delete.
3542  */
3543 static bool run_rename(int dummy)
3544 {
3545         static struct cli_state *cli1;
3546         const char *fname = "\\test.txt";
3547         const char *fname1 = "\\test1.txt";
3548         bool correct = True;
3549         int fnum1;
3550
3551         printf("starting rename test\n");
3552         
3553         if (!torture_open_connection(&cli1, 0)) {
3554                 return False;
3555         }
3556         
3557         cli_unlink(cli1, fname);
3558         cli_unlink(cli1, fname1);
3559         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3560                                    FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3561
3562         if (fnum1 == -1) {
3563                 printf("First open failed - %s\n", cli_errstr(cli1));
3564                 return False;
3565         }
3566
3567         if (!cli_rename(cli1, fname, fname1)) {
3568                 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3569         } else {
3570                 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3571                 correct = False;
3572         }
3573
3574         if (!cli_close(cli1, fnum1)) {
3575                 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3576                 return False;
3577         }
3578
3579         cli_unlink(cli1, fname);
3580         cli_unlink(cli1, fname1);
3581         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3582 #if 0
3583                                    FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3584 #else
3585                                    FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3586 #endif
3587
3588         if (fnum1 == -1) {
3589                 printf("Second open failed - %s\n", cli_errstr(cli1));
3590                 return False;
3591         }
3592
3593         if (!cli_rename(cli1, fname, fname1)) {
3594                 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3595                 correct = False;
3596         } else {
3597                 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3598         }
3599
3600         if (!cli_close(cli1, fnum1)) {
3601                 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3602                 return False;
3603         }
3604
3605         cli_unlink(cli1, fname);
3606         cli_unlink(cli1, fname1);
3607
3608         fnum1 = cli_nt_create_full(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3609                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3610
3611         if (fnum1 == -1) {
3612                 printf("Third open failed - %s\n", cli_errstr(cli1));
3613                 return False;
3614         }
3615
3616
3617 #if 0
3618   {
3619   int fnum2;
3620
3621         fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3622                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3623
3624         if (fnum2 == -1) {
3625                 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3626                 return False;
3627         }
3628         if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
3629                 printf("[8] setting delete_on_close on file failed !\n");
3630                 return False;
3631         }
3632         
3633         if (!cli_close(cli1, fnum2)) {
3634                 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3635                 return False;
3636         }
3637   }
3638 #endif
3639
3640         if (!cli_rename(cli1, fname, fname1)) {
3641                 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3642                 correct = False;
3643         } else {
3644                 printf("Third rename succeeded (SHARE_NONE)\n");
3645         }
3646
3647         if (!cli_close(cli1, fnum1)) {
3648                 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3649                 return False;
3650         }
3651
3652         cli_unlink(cli1, fname);
3653         cli_unlink(cli1, fname1);
3654
3655         /*----*/
3656
3657         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3658                                    FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3659
3660         if (fnum1 == -1) {
3661                 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3662                 return False;
3663         }
3664
3665         if (!cli_rename(cli1, fname, fname1)) {
3666                 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3667         } else {
3668                 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3669                 correct = False;
3670         }
3671
3672         if (!cli_close(cli1, fnum1)) {
3673                 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3674                 return False;
3675         }
3676
3677         cli_unlink(cli1, fname);
3678         cli_unlink(cli1, fname1);
3679
3680         /*--*/
3681
3682         fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3683                                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3684
3685         if (fnum1 == -1) {
3686                 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3687                 return False;
3688         }
3689
3690         if (!cli_rename(cli1, fname, fname1)) {
3691                 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3692                         cli_errstr(cli1));
3693                 correct = False;
3694         } else {
3695                 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3696         }
3697
3698         /*
3699          * Now check if the first name still exists ...
3700          */
3701
3702         /*fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3703                                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3704
3705         if (fnum2 == -1) {
3706           printf("Opening original file after rename of open file fails: %s\n",
3707               cli_errstr(cli1));
3708         }
3709         else {
3710           printf("Opening original file after rename of open file works ...\n");
3711           (void)cli_close(cli1, fnum2);
3712           } */
3713
3714         /*--*/
3715
3716
3717         if (!cli_close(cli1, fnum1)) {
3718                 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3719                 return False;
3720         }
3721
3722         cli_unlink(cli1, fname);
3723         cli_unlink(cli1, fname1);
3724         
3725         if (!torture_close_connection(cli1)) {
3726                 correct = False;
3727         }
3728         
3729         return correct;
3730 }
3731
3732 static bool run_pipe_number(int dummy)
3733 {
3734         struct cli_state *cli1;
3735         const char *pipe_name = "\\SPOOLSS";
3736         int fnum;
3737         int num_pipes = 0;
3738
3739         printf("starting pipenumber test\n");
3740         if (!torture_open_connection(&cli1, 0)) {
3741                 return False;
3742         }
3743
3744         cli_sockopt(cli1, sockops);
3745         while(1) {
3746                 fnum = cli_nt_create_full(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3747                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0);
3748
3749                 if (fnum == -1) {
3750                         printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3751                         break;
3752                 }
3753                 num_pipes++;
3754                 printf("\r%6d", num_pipes);
3755         }
3756
3757         printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3758         torture_close_connection(cli1);
3759         return True;
3760 }
3761
3762 /*
3763   Test open mode returns on read-only files.
3764  */
3765 static bool run_opentest(int dummy)
3766 {
3767         static struct cli_state *cli1;
3768         static struct cli_state *cli2;
3769         const char *fname = "\\readonly.file";
3770         int fnum1, fnum2;
3771         char buf[20];
3772         SMB_OFF_T fsize;
3773         bool correct = True;
3774         char *tmp_path;
3775
3776         printf("starting open test\n");
3777         
3778         if (!torture_open_connection(&cli1, 0)) {
3779                 return False;
3780         }
3781         
3782         cli_setatr(cli1, fname, 0, 0);
3783         cli_unlink(cli1, fname);
3784         
3785         cli_sockopt(cli1, sockops);
3786         
3787         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3788         if (fnum1 == -1) {
3789                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3790                 return False;
3791         }
3792
3793         if (!cli_close(cli1, fnum1)) {
3794                 printf("close2 failed (%s)\n", cli_errstr(cli1));
3795                 return False;
3796         }
3797         
3798         if (!cli_setatr(cli1, fname, aRONLY, 0)) {
3799                 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
3800                 return False;
3801         }
3802         
3803         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3804         if (fnum1 == -1) {
3805                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3806                 return False;
3807         }
3808         
3809         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3810         fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3811         
3812         if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess, 
3813                         NT_STATUS_ACCESS_DENIED)) {
3814                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3815         }
3816         
3817         printf("finished open test 1\n");
3818         
3819         cli_close(cli1, fnum1);
3820         
3821         /* Now try not readonly and ensure ERRbadshare is returned. */
3822         
3823         cli_setatr(cli1, fname, 0, 0);
3824         
3825         fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3826         if (fnum1 == -1) {
3827                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3828                 return False;
3829         }
3830         
3831         /* This will fail - but the error should be ERRshare. */
3832         fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3833         
3834         if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare, 
3835                         NT_STATUS_SHARING_VIOLATION)) {
3836                 printf("correct error code ERRDOS/ERRbadshare returned\n");
3837         }
3838         
3839         if (!cli_close(cli1, fnum1)) {
3840                 printf("close2 failed (%s)\n", cli_errstr(cli1));
3841                 return False;
3842         }
3843         
3844         cli_unlink(cli1, fname);
3845         
3846         printf("finished open test 2\n");
3847         
3848         /* Test truncate open disposition on file opened for read. */
3849         
3850         fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3851         if (fnum1 == -1) {
3852                 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
3853                 return False;
3854         }
3855         
3856         /* write 20 bytes. */
3857         
3858         memset(buf, '\0', 20);
3859
3860         if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
3861                 printf("write failed (%s)\n", cli_errstr(cli1));
3862                 correct = False;
3863         }
3864
3865         if (!cli_close(cli1, fnum1)) {
3866                 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
3867                 return False;
3868         }
3869         
3870         /* Ensure size == 20. */
3871         if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3872                 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3873                 return False;
3874         }
3875         
3876         if (fsize != 20) {
3877                 printf("(3) file size != 20\n");
3878                 return False;
3879         }
3880
3881         /* Now test if we can truncate a file opened for readonly. */
3882         
3883         fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3884         if (fnum1 == -1) {
3885                 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
3886                 return False;
3887         }
3888         
3889         if (!cli_close(cli1, fnum1)) {
3890                 printf("close2 failed (%s)\n", cli_errstr(cli1));
3891                 return False;
3892         }
3893
3894         /* Ensure size == 0. */
3895         if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3896                 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3897                 return False;
3898         }
3899
3900         if (fsize != 0) {
3901                 printf("(3) file size != 0\n");
3902                 return False;
3903         }
3904         printf("finished open test 3\n");
3905         
3906         cli_unlink(cli1, fname);
3907
3908
3909         printf("testing ctemp\n");
3910         fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
3911         if (fnum1 == -1) {
3912                 printf("ctemp failed (%s)\n", cli_errstr(cli1));
3913                 return False;
3914         }
3915         printf("ctemp gave path %s\n", tmp_path);
3916         if (!cli_close(cli1, fnum1)) {
3917                 printf("close of temp failed (%s)\n", cli_errstr(cli1));
3918         }
3919         if (!cli_unlink(cli1, tmp_path)) {
3920                 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3921         }
3922         
3923         /* Test the non-io opens... */
3924
3925         if (!torture_open_connection(&cli2, 1)) {
3926                 return False;
3927         }
3928         
3929         cli_setatr(cli2, fname, 0, 0);
3930         cli_unlink(cli2, fname);
3931         
3932         cli_sockopt(cli2, sockops);
3933
3934         printf("TEST #1 testing 2 non-io opens (no delete)\n");
3935         
3936         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3937                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3938
3939         if (fnum1 == -1) {
3940                 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3941                 return False;
3942         }
3943
3944         fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3945                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3946
3947         if (fnum2 == -1) {
3948                 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3949                 return False;
3950         }
3951
3952         if (!cli_close(cli1, fnum1)) {
3953                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3954                 return False;
3955         }
3956         if (!cli_close(cli2, fnum2)) {
3957                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3958                 return False;
3959         }
3960
3961         printf("non-io open test #1 passed.\n");
3962
3963         cli_unlink(cli1, fname);
3964
3965         printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3966         
3967         fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3968                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3969
3970         if (fnum1 == -1) {
3971                 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3972                 return False;
3973         }
3974
3975         fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3976                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3977
3978         if (fnum2 == -1) {
3979                 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3980                 return False;
3981         }
3982
3983         if (!cli_close(cli1, fnum1)) {
3984                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3985                 return False;
3986         }
3987         if (!cli_close(cli2, fnum2)) {
3988                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3989                 return False;
3990         }
3991
3992         printf("non-io open test #2 passed.\n");
3993
3994         cli_unlink(cli1, fname);
3995
3996         printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3997         
3998         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3999                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4000
4001         if (fnum1 == -1) {
4002                 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4003                 return False;
4004         }
4005
4006         fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4007                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
4008
4009         if (fnum2 == -1) {
4010                 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4011                 return False;
4012         }
4013
4014         if (!cli_close(cli1, fnum1)) {
4015                 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4016                 return False;
4017         }
4018         if (!cli_close(cli2, fnum2)) {
4019                 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4020                 return False;
4021         }
4022
4023         printf("non-io open test #3 passed.\n");
4024
4025         cli_unlink(cli1, fname);
4026
4027         printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4028         
4029         fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4030                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4031
4032         if (fnum1 == -1) {
4033                 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4034                 return False;
4035         }
4036
4037         fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4038                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
4039
4040         if (fnum2 != -1) {
4041                 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4042                 return False;
4043         }
4044
4045         printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4046
4047         if (!cli_close(cli1, fnum1)) {
4048                 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4049                 return False;
4050         }
4051
4052         printf("non-io open test #4 passed.\n");
4053
4054         cli_unlink(cli1, fname);
4055
4056         printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4057         
4058         fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4059                                    FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
4060
4061         if (fnum1 == -1) {
4062                 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4063                 return False;
4064         }
4065
4066         fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4067                                    FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4068
4069         if (fnum2 == -1) {
4070                 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4071                 return False;
4072         }
4073
4074         if (!cli_close(cli1, fnum1)) {
4075                 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4076                 return False;
4077         }
4078
4079         if (!cli_close(cli2, fnum2)) {
4080                 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4081                 return False;
4082         }
4083
4084         printf("non-io open test #5 passed.\n");
4085
4086         printf("TEST #6 testing 1 non-io open, one io open\n");
4087         
4088         cli_unlink(cli1, fname);
4089
4090         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4091                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4092
4093         if (fnum1 == -1) {
4094                 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4095                 return False;
4096         }
4097
4098         fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4099                                    FILE_SHARE_READ, FILE_OPEN_IF, 0, 0);
4100
4101         if (fnum2 == -1) {
4102                 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4103                 return False;
4104         }
4105
4106         if (!cli_close(cli1, fnum1)) {
4107                 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4108                 return False;
4109         }
4110
4111         if (!cli_close(cli2, fnum2)) {
4112                 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4113                 return False;
4114         }
4115
4116         printf("non-io open test #6 passed.\n");
4117
4118         printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4119
4120         cli_unlink(cli1, fname);
4121
4122         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4123                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4124
4125         if (fnum1 == -1) {
4126                 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4127                 return False;
4128         }
4129
4130         fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4131                                    FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4132
4133         if (fnum2 != -1) {
4134                 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4135                 return False;
4136         }
4137
4138         printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4139
4140         if (!cli_close(cli1, fnum1)) {
4141                 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4142                 return False;
4143         }
4144
4145         printf("non-io open test #7 passed.\n");
4146
4147         cli_unlink(cli1, fname);
4148
4149         if (!torture_close_connection(cli1)) {
4150                 correct = False;
4151         }
4152         if (!torture_close_connection(cli2)) {
4153                 correct = False;
4154         }
4155         
4156         return correct;
4157 }
4158
4159 /*
4160   Test POSIX open /mkdir calls.
4161  */
4162 static bool run_simple_posix_open_test(int dummy)
4163 {
4164         static struct cli_state *cli1;
4165         const char *fname = "\\posix:file";
4166         const char *dname = "\\posix:dir";
4167         uint16 major, minor;
4168         uint32 caplow, caphigh;
4169         int fnum1 = -1;
4170         bool correct = false;
4171
4172         printf("Starting simple POSIX open test\n");
4173
4174         if (!torture_open_connection(&cli1, 0)) {
4175                 return false;
4176         }
4177
4178         cli_sockopt(cli1, sockops);
4179
4180         if (!SERVER_HAS_UNIX_CIFS(cli1)) {
4181                 printf("Server doesn't support UNIX CIFS extensions.\n");
4182                 return false;
4183         }
4184
4185         if (!cli_unix_extensions_version(cli1, &major,
4186                         &minor, &caplow, &caphigh)) {
4187                 printf("Server didn't return UNIX CIFS extensions.\n");
4188                 return false;
4189         }
4190
4191         if (!cli_set_unix_extensions_capabilities(cli1,
4192                         major, minor, caplow, caphigh)) {
4193                 printf("Server doesn't support setting UNIX CIFS extensions.\n");
4194                 return false;
4195         }
4196
4197         cli_setatr(cli1, fname, 0, 0);
4198         cli_posix_unlink(cli1, fname);
4199         cli_setatr(cli1, dname, 0, 0);
4200         cli_posix_rmdir(cli1, dname);
4201
4202         /* Create a directory. */
4203         if (cli_posix_mkdir(cli1, dname, 0777) == -1) {
4204                 printf("Server doesn't support setting UNIX CIFS extensions.\n");
4205                 goto out;
4206         }
4207
4208         fnum1 = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600);
4209         if (fnum1 == -1) {
4210                 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4211                 goto out;
4212         }
4213
4214         if (!cli_close(cli1, fnum1)) {
4215                 printf("close failed (%s)\n", cli_errstr(cli1));
4216                 goto out;
4217         }
4218
4219         /* Now open the file again for read only. */
4220         fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
4221         if (fnum1 == -1) {
4222                 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4223                 goto out;
4224         }
4225
4226         /* Now unlink while open. */
4227         if (!cli_posix_unlink(cli1, fname)) {
4228                 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4229                 goto out;
4230         }
4231
4232         if (!cli_close(cli1, fnum1)) {
4233                 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4234                 goto out;
4235         }
4236
4237         /* Ensure the file has gone. */
4238         fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
4239         if (fnum1 != -1) {
4240                 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4241                 goto out;
4242         }
4243
4244         if (!cli_posix_rmdir(cli1, dname)) {
4245                 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4246                 goto out;
4247         }
4248
4249         printf("Simple POSIX open test passed\n");
4250         correct = true;
4251
4252   out:
4253
4254         if (fnum1 != -1) {
4255                 cli_close(cli1, fnum1);
4256                 fnum1 = -1;
4257         }
4258
4259         cli_setatr(cli1, fname, 0, 0);
4260         cli_posix_unlink(cli1, fname);
4261         cli_setatr(cli1, dname, 0, 0);
4262         cli_posix_rmdir(cli1, dname);
4263
4264         if (!torture_close_connection(cli1)) {
4265                 correct = false;
4266         }
4267
4268         return correct;
4269 }
4270
4271
4272 static uint32 open_attrs_table[] = {
4273                 FILE_ATTRIBUTE_NORMAL,
4274                 FILE_ATTRIBUTE_ARCHIVE,
4275                 FILE_ATTRIBUTE_READONLY,
4276                 FILE_ATTRIBUTE_HIDDEN,
4277                 FILE_ATTRIBUTE_SYSTEM,
4278
4279                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4280                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4281                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4282                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4283                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4284                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4285
4286                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4287                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4288                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4289                 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4290 };
4291
4292 struct trunc_open_results {
4293         unsigned int num;
4294         uint32 init_attr;
4295         uint32 trunc_attr;
4296         uint32 result_attr;
4297 };
4298
4299 static struct trunc_open_results attr_results[] = {
4300         { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4301         { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4302         { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4303         { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4304         { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4305         { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4306         { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4307         { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4308         { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4309         { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4310         { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4311         { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4312         { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4313         { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4314         { 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 },
4315         { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4316         { 119,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4317         { 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 },
4318         { 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 },
4319         { 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 },
4320         { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4321         { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4322         { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4323         { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4324         { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4325         { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4326 };
4327
4328 static bool run_openattrtest(int dummy)
4329 {
4330         static struct cli_state *cli1;
4331         const char *fname = "\\openattr.file";
4332         int fnum1;
4333         bool correct = True;
4334         uint16 attr;
4335         unsigned int i, j, k, l;
4336
4337         printf("starting open attr test\n");
4338         
4339         if (!torture_open_connection(&cli1, 0)) {
4340                 return False;
4341         }
4342         
4343         cli_sockopt(cli1, sockops);
4344
4345         for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4346                 cli_setatr(cli1, fname, 0, 0);
4347                 cli_unlink(cli1, fname);
4348                 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4349                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4350
4351                 if (fnum1 == -1) {
4352                         printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4353                         return False;
4354                 }
4355
4356                 if (!cli_close(cli1, fnum1)) {
4357                         printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4358                         return False;
4359                 }
4360
4361                 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4362                         fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4363                                            FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0);
4364
4365                         if (fnum1 == -1) {
4366                                 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4367                                         if (attr_results[l].num == k) {
4368                                                 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4369                                                                 k, open_attrs_table[i],
4370                                                                 open_attrs_table[j],
4371                                                                 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4372                                                 correct = False;
4373                                         }
4374                                 }
4375                                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4376                                         printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4377                                                         k, open_attrs_table[i], open_attrs_table[j],
4378                                                         cli_errstr(cli1));
4379                                         correct = False;
4380                                 }
4381 #if 0
4382                                 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4383 #endif
4384                                 k++;
4385                                 continue;
4386                         }
4387
4388                         if (!cli_close(cli1, fnum1)) {
4389                                 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4390                                 return False;
4391                         }
4392
4393                         if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
4394                                 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4395                                 return False;
4396                         }
4397
4398 #if 0
4399                         printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4400                                         k,  open_attrs_table[i],  open_attrs_table[j], attr );
4401 #endif
4402
4403                         for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4404                                 if (attr_results[l].num == k) {
4405                                         if (attr != attr_results[l].result_attr ||
4406                                                         open_attrs_table[i] != attr_results[l].init_attr ||
4407                                                         open_attrs_table[j] != attr_results[l].trunc_attr) {
4408                                                 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4409                                                 open_attrs_table[i],
4410                                                 open_attrs_table[j],
4411                                                 (unsigned int)attr,
4412                                                 attr_results[l].result_attr);
4413                                                 correct = False;
4414                                         }
4415                                         break;
4416                                 }
4417                         }
4418                         k++;
4419                 }
4420         }
4421
4422         cli_setatr(cli1, fname, 0, 0);
4423         cli_unlink(cli1, fname);
4424
4425         printf("open attr test %s.\n", correct ? "passed" : "failed");
4426
4427         if (!torture_close_connection(cli1)) {
4428                 correct = False;
4429         }
4430         return correct;
4431 }
4432
4433 static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
4434 {
4435         
4436 }
4437
4438 /*
4439   test directory listing speed
4440  */
4441 static bool run_dirtest(int dummy)
4442 {
4443         int i;
4444         static struct cli_state *cli;
4445         int fnum;
4446         double t1;
4447         bool correct = True;
4448
4449         printf("starting directory test\n");
4450
4451         if (!torture_open_connection(&cli, 0)) {
4452                 return False;
4453         }
4454
4455         cli_sockopt(cli, sockops);
4456
4457         srandom(0);
4458         for (i=0;i<torture_numops;i++) {
4459                 fstring fname;
4460                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4461                 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
4462                 if (fnum == -1) {
4463                         fprintf(stderr,"Failed to open %s\n", fname);
4464                         return False;
4465                 }
4466                 cli_close(cli, fnum);
4467         }
4468
4469         t1 = end_timer();
4470
4471         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4472         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4473         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4474
4475         printf("dirtest core %g seconds\n", end_timer() - t1);
4476
4477         srandom(0);
4478         for (i=0;i<torture_numops;i++) {
4479                 fstring fname;
4480                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4481                 cli_unlink(cli, fname);
4482         }
4483
4484         if (!torture_close_connection(cli)) {
4485                 correct = False;
4486         }
4487
4488         printf("finished dirtest\n");
4489
4490         return correct;
4491 }
4492
4493 static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
4494 {
4495         struct cli_state *pcli = (struct cli_state *)state;
4496         fstring fname;
4497         slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4498
4499         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4500                 return;
4501
4502         if (finfo->mode & aDIR) {
4503                 if (!cli_rmdir(pcli, fname))
4504                         printf("del_fn: failed to rmdir %s\n,", fname );
4505         } else {
4506                 if (!cli_unlink(pcli, fname))
4507                         printf("del_fn: failed to unlink %s\n,", fname );
4508         }
4509 }
4510
4511
4512 /*
4513   sees what IOCTLs are supported
4514  */
4515 bool torture_ioctl_test(int dummy)
4516 {
4517         static struct cli_state *cli;
4518         uint16 device, function;
4519         int fnum;
4520         const char *fname = "\\ioctl.dat";
4521         DATA_BLOB blob;
4522         NTSTATUS status;
4523
4524         if (!torture_open_connection(&cli, 0)) {
4525                 return False;
4526         }
4527
4528         printf("starting ioctl test\n");
4529
4530         cli_unlink(cli, fname);
4531
4532         fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4533         if (fnum == -1) {
4534                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4535                 return False;
4536         }
4537
4538         status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4539         printf("ioctl device info: %s\n", cli_errstr(cli));
4540
4541         status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4542         printf("ioctl job info: %s\n", cli_errstr(cli));
4543
4544         for (device=0;device<0x100;device++) {
4545                 printf("testing device=0x%x\n", device);
4546                 for (function=0;function<0x100;function++) {
4547                         uint32 code = (device<<16) | function;
4548
4549                         status = cli_raw_ioctl(cli, fnum, code, &blob);
4550
4551                         if (NT_STATUS_IS_OK(status)) {
4552                                 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4553                                        (int)blob.length);
4554                                 data_blob_free(&blob);
4555                         }
4556                 }
4557         }
4558
4559         if (!torture_close_connection(cli)) {
4560                 return False;
4561         }
4562
4563         return True;
4564 }
4565
4566
4567 /*
4568   tries varients of chkpath
4569  */
4570 bool torture_chkpath_test(int dummy)
4571 {
4572         static struct cli_state *cli;
4573         int fnum;
4574         bool ret;
4575
4576         if (!torture_open_connection(&cli, 0)) {
4577                 return False;
4578         }
4579
4580         printf("starting chkpath test\n");
4581
4582         /* cleanup from an old run */
4583         cli_rmdir(cli, "\\chkpath.dir\\dir2");
4584         cli_unlink(cli, "\\chkpath.dir\\*");
4585         cli_rmdir(cli, "\\chkpath.dir");
4586
4587         if (!cli_mkdir(cli, "\\chkpath.dir")) {
4588                 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4589                 return False;
4590         }
4591
4592         if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
4593                 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4594                 return False;
4595         }
4596
4597         fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4598         if (fnum == -1) {
4599                 printf("open1 failed (%s)\n", cli_errstr(cli));
4600                 return False;
4601         }
4602         cli_close(cli, fnum);
4603
4604         if (!cli_chkpath(cli, "\\chkpath.dir")) {
4605                 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4606                 ret = False;
4607         }
4608
4609         if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
4610                 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4611                 ret = False;
4612         }
4613
4614         if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
4615                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath, 
4616                                   NT_STATUS_NOT_A_DIRECTORY);
4617         } else {
4618                 printf("* chkpath on a file should fail\n");
4619                 ret = False;
4620         }
4621
4622         if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
4623                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile, 
4624                                   NT_STATUS_OBJECT_NAME_NOT_FOUND);
4625         } else {
4626                 printf("* chkpath on a non existant file should fail\n");
4627                 ret = False;
4628         }
4629
4630         if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
4631                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath, 
4632                                   NT_STATUS_OBJECT_PATH_NOT_FOUND);
4633         } else {
4634                 printf("* chkpath on a non existent component should fail\n");
4635                 ret = False;
4636         }
4637
4638         cli_rmdir(cli, "\\chkpath.dir\\dir2");
4639         cli_unlink(cli, "\\chkpath.dir\\*");
4640         cli_rmdir(cli, "\\chkpath.dir");
4641
4642         if (!torture_close_connection(cli)) {
4643                 return False;
4644         }
4645
4646         return ret;
4647 }
4648
4649 static bool run_eatest(int dummy)
4650 {
4651         static struct cli_state *cli;
4652         const char *fname = "\\eatest.txt";
4653         bool correct = True;
4654         int fnum, i;
4655         size_t num_eas;
4656         struct ea_struct *ea_list = NULL;
4657         TALLOC_CTX *mem_ctx = talloc_init("eatest");
4658
4659         printf("starting eatest\n");
4660         
4661         if (!torture_open_connection(&cli, 0)) {
4662                 talloc_destroy(mem_ctx);
4663                 return False;
4664         }
4665         
4666         cli_unlink(cli, fname);
4667         fnum = cli_nt_create_full(cli, fname, 0,
4668                                    FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4669                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 
4670                                    0x4044, 0);
4671
4672         if (fnum == -1) {
4673                 printf("open failed - %s\n", cli_errstr(cli));
4674                 talloc_destroy(mem_ctx);
4675                 return False;
4676         }
4677
4678         for (i = 0; i < 10; i++) {
4679                 fstring ea_name, ea_val;
4680
4681                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
4682                 memset(ea_val, (char)i+1, i+1);
4683                 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
4684                         printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4685                         talloc_destroy(mem_ctx);
4686                         return False;
4687                 }
4688         }
4689         
4690         cli_close(cli, fnum);
4691         for (i = 0; i < 10; i++) {
4692                 fstring ea_name, ea_val;
4693
4694                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
4695                 memset(ea_val, (char)i+1, i+1);
4696                 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
4697                         printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4698                         talloc_destroy(mem_ctx);
4699                         return False;
4700                 }
4701         }
4702         
4703         if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4704                 printf("ea_get list failed - %s\n", cli_errstr(cli));
4705                 correct = False;
4706         }
4707
4708         printf("num_eas = %d\n", (int)num_eas);
4709
4710         if (num_eas != 20) {
4711                 printf("Should be 20 EA's stored... failing.\n");
4712                 correct = False;
4713         }
4714
4715         for (i = 0; i < num_eas; i++) {
4716                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4717                 dump_data(0, ea_list[i].value.data,
4718                           ea_list[i].value.length);
4719         }
4720
4721         /* Setting EA's to zero length deletes them. Test this */
4722         printf("Now deleting all EA's - case indepenent....\n");
4723
4724 #if 1
4725         cli_set_ea_path(cli, fname, "", "", 0);
4726 #else
4727         for (i = 0; i < 20; i++) {
4728                 fstring ea_name;
4729                 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
4730                 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
4731                         printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4732                         talloc_destroy(mem_ctx);
4733                         return False;
4734                 }
4735         }
4736 #endif
4737
4738         if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4739                 printf("ea_get list failed - %s\n", cli_errstr(cli));
4740                 correct = False;
4741         }
4742
4743         printf("num_eas = %d\n", (int)num_eas);
4744         for (i = 0; i < num_eas; i++) {
4745                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4746                 dump_data(0, ea_list[i].value.data,
4747                           ea_list[i].value.length);
4748         }
4749
4750         if (num_eas != 0) {
4751                 printf("deleting EA's failed.\n");
4752                 correct = False;
4753         }
4754
4755         /* Try and delete a non existant EA. */
4756         if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
4757                 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
4758                 correct = False;
4759         }
4760
4761         talloc_destroy(mem_ctx);
4762         if (!torture_close_connection(cli)) {
4763                 correct = False;
4764         }
4765         
4766         return correct;
4767 }
4768
4769 static bool run_dirtest1(int dummy)
4770 {
4771         int i;
4772         static struct cli_state *cli;
4773         int fnum, num_seen;
4774         bool correct = True;
4775
4776         printf("starting directory test\n");
4777
4778         if (!torture_open_connection(&cli, 0)) {
4779                 return False;
4780         }
4781
4782         cli_sockopt(cli, sockops);
4783
4784         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4785         cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4786         cli_rmdir(cli, "\\LISTDIR");
4787         cli_mkdir(cli, "\\LISTDIR");
4788
4789         /* Create 1000 files and 1000 directories. */
4790         for (i=0;i<1000;i++) {
4791                 fstring fname;
4792                 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
4793                 fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4794                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
4795                 if (fnum == -1) {
4796                         fprintf(stderr,"Failed to open %s\n", fname);
4797                         return False;
4798                 }
4799                 cli_close(cli, fnum);
4800         }
4801         for (i=0;i<1000;i++) {
4802                 fstring fname;
4803                 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
4804                 if (!cli_mkdir(cli, fname)) {
4805                         fprintf(stderr,"Failed to open %s\n", fname);
4806                         return False;
4807                 }
4808         }
4809
4810         /* Now ensure that doing an old list sees both files and directories. */
4811         num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
4812         printf("num_seen = %d\n", num_seen );
4813         /* We should see 100 files + 1000 directories + . and .. */
4814         if (num_seen != 2002)
4815                 correct = False;
4816
4817         /* Ensure if we have the "must have" bits we only see the
4818          * relevent entries.
4819          */
4820         num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
4821         printf("num_seen = %d\n", num_seen );
4822         if (num_seen != 1002)
4823                 correct = False;
4824
4825         num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
4826         printf("num_seen = %d\n", num_seen );
4827         if (num_seen != 1000)
4828                 correct = False;
4829
4830         /* Delete everything. */
4831         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4832         cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4833         cli_rmdir(cli, "\\LISTDIR");
4834
4835 #if 0
4836         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4837         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4838         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4839 #endif
4840
4841         if (!torture_close_connection(cli)) {
4842                 correct = False;
4843         }
4844
4845         printf("finished dirtest1\n");
4846
4847         return correct;
4848 }
4849
4850 static bool run_error_map_extract(int dummy) {
4851         
4852         static struct cli_state *c_dos;
4853         static struct cli_state *c_nt;
4854         NTSTATUS status;
4855
4856         uint32 error;
4857
4858         uint32 flgs2, errnum;
4859         uint8 errclass;
4860
4861         NTSTATUS nt_status;
4862
4863         fstring user;
4864
4865         /* NT-Error connection */
4866
4867         if (!(c_nt = open_nbt_connection())) {
4868                 return False;
4869         }
4870
4871         c_nt->use_spnego = False;
4872
4873         status = cli_negprot(c_nt);
4874
4875         if (!NT_STATUS_IS_OK(status)) {
4876                 printf("%s rejected the NT-error negprot (%s)\n", host,
4877                        nt_errstr(status));
4878                 cli_shutdown(c_nt);
4879                 return False;
4880         }
4881
4882         if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
4883                                                workgroup))) {
4884                 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
4885                 return False;
4886         }
4887
4888         /* DOS-Error connection */
4889
4890         if (!(c_dos = open_nbt_connection())) {
4891                 return False;
4892         }
4893
4894         c_dos->use_spnego = False;
4895         c_dos->force_dos_errors = True;
4896
4897         status = cli_negprot(c_dos);
4898         if (!NT_STATUS_IS_OK(status)) {
4899                 printf("%s rejected the DOS-error negprot (%s)\n", host,
4900                        nt_errstr(status));
4901                 cli_shutdown(c_dos);
4902                 return False;
4903         }
4904
4905         if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
4906                                                workgroup))) {
4907                 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
4908                 return False;
4909         }
4910
4911         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
4912                 fstr_sprintf(user, "%X", error);
4913
4914                 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user, 
4915                                                       password, strlen(password),
4916                                                       password, strlen(password),
4917                                                       workgroup))) {
4918                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
4919                 }
4920                 
4921                 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
4922                 
4923                 /* Case #1: 32-bit NT errors */
4924                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4925                         nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
4926                 } else {
4927                         printf("/** Dos error on NT connection! (%s) */\n", 
4928                                cli_errstr(c_nt));
4929                         nt_status = NT_STATUS(0xc0000000);
4930                 }
4931
4932                 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user, 
4933                                                       password, strlen(password),
4934                                                       password, strlen(password),
4935                                                       workgroup))) {
4936                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
4937                 }
4938                 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
4939                 
4940                 /* Case #1: 32-bit NT errors */
4941                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4942                         printf("/** NT error on DOS connection! (%s) */\n", 
4943                                cli_errstr(c_nt));
4944                         errnum = errclass = 0;
4945                 } else {
4946                         cli_dos_error(c_dos, &errclass, &errnum);
4947                 }
4948
4949                 if (NT_STATUS_V(nt_status) != error) { 
4950                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
4951                                get_nt_error_c_code(NT_STATUS(error)), 
4952                                get_nt_error_c_code(nt_status));
4953                 }
4954                 
4955                 printf("\t{%s,\t%s,\t%s},\n", 
4956                        smb_dos_err_class(errclass), 
4957                        smb_dos_err_name(errclass, errnum), 
4958                        get_nt_error_c_code(NT_STATUS(error)));
4959         }
4960         return True;
4961 }
4962
4963 static bool run_sesssetup_bench(int dummy)
4964 {
4965         static struct cli_state *c;
4966         const char *fname = "\\file.dat";
4967         int fnum;
4968         NTSTATUS status;
4969         int i;
4970
4971         if (!torture_open_connection(&c, 0)) {
4972                 return false;
4973         }
4974
4975         fnum = cli_nt_create_full(
4976                 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
4977                 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4978                 FILE_DELETE_ON_CLOSE, 0);
4979         if (fnum == -1) {
4980                 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
4981                 return false;
4982         }
4983
4984         for (i=0; i<torture_numops; i++) {
4985                 status = cli_session_setup(
4986                         c, username,
4987                         password, strlen(password),
4988                         password, strlen(password),
4989                         workgroup);
4990                 if (!NT_STATUS_IS_OK(status)) {
4991                         d_printf("(%s) cli_session_setup failed: %s\n",
4992                                  __location__, nt_errstr(status));
4993                         return false;
4994                 }
4995
4996                 d_printf("\r%d   ", (int)c->vuid);
4997
4998                 if (!cli_ulogoff(c)) {
4999                         d_printf("(%s) cli_ulogoff failed: %s\n",
5000                                  __location__, cli_errstr(c));
5001                         return false;
5002                 }
5003                 c->vuid = 0;
5004         }
5005
5006         return true;
5007 }
5008
5009 static bool subst_test(const char *str, const char *user, const char *domain,
5010                        uid_t uid, gid_t gid, const char *expected)
5011 {
5012         char *subst;
5013         bool result = true;
5014
5015         subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5016
5017         if (strcmp(subst, expected) != 0) {
5018                 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5019                        "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5020                        expected);
5021                 result = false;
5022         }
5023
5024         TALLOC_FREE(subst);
5025         return result;
5026 }
5027
5028 static void chain1_open_completion(struct tevent_req *req)
5029 {
5030         int fnum;
5031         NTSTATUS status;
5032         status = cli_open_recv(req, &fnum);
5033         TALLOC_FREE(req);
5034
5035         d_printf("cli_open_recv returned %s: %d\n",
5036                  nt_errstr(status),
5037                  NT_STATUS_IS_OK(status) ? fnum : -1);
5038 }
5039
5040 static void chain1_write_completion(struct tevent_req *req)
5041 {
5042         size_t written;
5043         NTSTATUS status;
5044         status = cli_write_andx_recv(req, &written);
5045         TALLOC_FREE(req);
5046
5047         d_printf("cli_write_andx_recv returned %s: %d\n",
5048                  nt_errstr(status),
5049                  NT_STATUS_IS_OK(status) ? (int)written : -1);
5050 }
5051
5052 static void chain1_close_completion(struct tevent_req *req)
5053 {
5054         NTSTATUS status;
5055         bool *done = (bool *)tevent_req_callback_data_void(req);
5056
5057         status = cli_close_recv(req);
5058         *done = true;
5059
5060         TALLOC_FREE(req);
5061
5062         d_printf("cli_close returned %s\n", nt_errstr(status));
5063 }
5064
5065 static bool run_chain1(int dummy)
5066 {
5067         struct cli_state *cli1;
5068         struct event_context *evt = event_context_init(NULL);
5069         struct tevent_req *reqs[3], *smbreqs[3];
5070         bool done = false;
5071         const char *str = "foobar";
5072
5073         printf("starting chain1 test\n");
5074         if (!torture_open_connection(&cli1, 0)) {
5075                 return False;
5076         }
5077
5078         cli_sockopt(cli1, sockops);
5079
5080         reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5081                                   O_CREAT|O_RDWR, 0, &smbreqs[0]);
5082         if (reqs[0] == NULL) return false;
5083         tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5084
5085
5086         reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5087                                         (uint8_t *)str, 0, strlen(str)+1,
5088                                         smbreqs, 1, &smbreqs[1]);
5089         if (reqs[1] == NULL) return false;
5090         tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5091
5092         reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5093         if (reqs[2] == NULL) return false;
5094         tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5095
5096         if (!cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs))) {
5097                 return false;
5098         }
5099
5100         while (!done) {
5101                 event_loop_once(evt);
5102         }
5103
5104         torture_close_connection(cli1);
5105         return True;
5106 }
5107
5108 static bool run_mangle1(int dummy)
5109 {
5110         struct cli_state *cli;
5111         const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
5112         int fnum;
5113         fstring alt_name;
5114         NTSTATUS status;
5115         time_t change, access, write;
5116         SMB_OFF_T size;
5117         uint16_t mode;
5118
5119         printf("starting chain1 test\n");
5120         if (!torture_open_connection(&cli, 0)) {
5121                 return False;
5122         }
5123
5124         cli_sockopt(cli, sockops);
5125
5126         fnum = cli_nt_create_full(
5127                 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5128                 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);
5129         if (fnum == -1) {
5130                 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
5131                 return false;
5132         }
5133         cli_close(cli, fnum);
5134
5135         status = cli_qpathinfo_alt_name(cli, fname, alt_name);
5136         if (!NT_STATUS_IS_OK(status)) {
5137                 d_printf("cli_qpathinfo_alt_name failed: %s\n",
5138                          nt_errstr(status));
5139                 return false;
5140         }
5141         d_printf("alt_name: %s\n", alt_name);
5142
5143         fnum = cli_open(cli, alt_name, O_RDONLY, DENY_NONE);
5144         if (fnum == -1) {
5145                 d_printf("cli_open(%s) failed: %s\n", alt_name,
5146                          cli_errstr(cli));
5147                 return false;
5148         }
5149         cli_close(cli, fnum);
5150
5151         if (!cli_qpathinfo(cli, alt_name, &change, &access, &write, &size,
5152                            &mode)) {
5153                 d_printf("cli_qpathinfo(%s) failed: %s\n", alt_name,
5154                          cli_errstr(cli));
5155                 return false;
5156         }
5157
5158         return true;
5159 }
5160
5161 static size_t null_source(uint8_t *buf, size_t n, void *priv)
5162 {
5163         size_t *to_pull = (size_t *)priv;
5164         size_t thistime = *to_pull;
5165
5166         thistime = MIN(thistime, n);
5167         if (thistime == 0) {
5168                 return 0;
5169         }
5170
5171         memset(buf, 0, thistime);
5172         *to_pull -= thistime;
5173         return thistime;
5174 }
5175
5176 static bool run_windows_write(int dummy)
5177 {
5178         struct cli_state *cli1;
5179         int fnum;
5180         int i;
5181         bool ret = false;
5182         const char *fname = "\\writetest.txt";
5183         double seconds;
5184         double kbytes;
5185
5186         printf("starting windows_write test\n");
5187         if (!torture_open_connection(&cli1, 0)) {
5188                 return False;
5189         }
5190
5191         fnum = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
5192         if (fnum == -1) {
5193                 printf("open failed (%s)\n", cli_errstr(cli1));
5194                 return False;
5195         }
5196
5197         cli_sockopt(cli1, sockops);
5198
5199         start_timer();
5200
5201         for (i=0; i<torture_numops; i++) {
5202                 char c = 0;
5203                 off_t start = i * torture_blocksize;
5204                 NTSTATUS status;
5205                 size_t to_pull = torture_blocksize - 1;
5206
5207                 if (cli_write(cli1, fnum, 0, &c,
5208                               start + torture_blocksize - 1, 1) != 1) {
5209                         printf("cli_write failed: %s\n", cli_errstr(cli1));
5210                         goto fail;
5211                 }
5212
5213                 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
5214                                   null_source, &to_pull);
5215                 if (!NT_STATUS_IS_OK(status)) {
5216                         printf("cli_push returned: %s\n", nt_errstr(status));
5217                         goto fail;
5218                 }
5219         }
5220
5221         seconds = end_timer();
5222         kbytes = (double)torture_blocksize * torture_numops;
5223         kbytes /= 1024;
5224
5225         printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
5226                (double)seconds, (int)(kbytes/seconds));
5227
5228         ret = true;
5229  fail:
5230         cli_close(cli1, fnum);
5231         cli_unlink(cli1, fname);
5232         torture_close_connection(cli1);
5233         return ret;
5234 }
5235
5236 static bool run_cli_echo(int dummy)
5237 {
5238         struct cli_state *cli;
5239         NTSTATUS status;
5240
5241         printf("starting cli_echo test\n");
5242         if (!torture_open_connection(&cli, 0)) {
5243                 return false;
5244         }
5245         cli_sockopt(cli, sockops);
5246
5247         status = cli_echo(cli, 5, data_blob_const("hello", 5));
5248
5249         d_printf("cli_echo returned %s\n", nt_errstr(status));
5250
5251         torture_close_connection(cli);
5252         return NT_STATUS_IS_OK(status);
5253 }
5254
5255 static bool run_uid_regression_test(int dummy)
5256 {
5257         static struct cli_state *cli;
5258         int16_t old_vuid;
5259         bool correct = True;
5260
5261         printf("starting uid regression test\n");
5262
5263         if (!torture_open_connection(&cli, 0)) {
5264                 return False;
5265         }
5266
5267         cli_sockopt(cli, sockops);
5268
5269         /* Ok - now save then logoff our current user. */
5270         old_vuid = cli->vuid;
5271
5272         if (!cli_ulogoff(cli)) {
5273                 d_printf("(%s) cli_ulogoff failed: %s\n",
5274                         __location__, cli_errstr(cli));
5275                 correct = false;
5276                 goto out;
5277         }
5278
5279         cli->vuid = old_vuid;
5280
5281         /* Try an operation. */
5282         if (!cli_mkdir(cli, "\\uid_reg_test")) {
5283                 /* We expect bad uid. */
5284                 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
5285                                 NT_STATUS_NO_SUCH_USER)) {
5286                         return False;
5287                 }
5288                 goto out;
5289         }
5290
5291         cli_rmdir(cli, "\\uid_reg_test");
5292
5293   out:
5294
5295         torture_close_connection(cli);
5296         return correct;
5297 }
5298
5299 static bool run_local_substitute(int dummy)
5300 {
5301         bool ok = true;
5302
5303         ok &= subst_test("%U", "bla", "", -1, -1, "bla");
5304         ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
5305         ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
5306         ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
5307         ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
5308         ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
5309         ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
5310         ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
5311
5312         /* Different captialization rules in sub_basic... */
5313
5314         ok &=  (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
5315                        "blaDOM") == 0);
5316
5317         return ok;
5318 }
5319
5320 static bool run_local_gencache(int dummy)
5321 {
5322         char *val;
5323         time_t tm;
5324         DATA_BLOB blob;
5325
5326         if (!gencache_init()) {
5327                 d_printf("%s: gencache_init() failed\n", __location__);
5328                 return False;
5329         }
5330
5331         if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
5332                 d_printf("%s: gencache_set() failed\n", __location__);
5333                 return False;
5334         }
5335
5336         if (!gencache_get("foo", &val, &tm)) {
5337                 d_printf("%s: gencache_get() failed\n", __location__);
5338                 return False;
5339         }
5340
5341         if (strcmp(val, "bar") != 0) {
5342                 d_printf("%s: gencache_get() returned %s, expected %s\n",
5343                          __location__, val, "bar");
5344                 SAFE_FREE(val);
5345                 return False;
5346         }
5347
5348         SAFE_FREE(val);
5349
5350         if (!gencache_del("foo")) {
5351                 d_printf("%s: gencache_del() failed\n", __location__);
5352                 return False;
5353         }
5354         if (gencache_del("foo")) {
5355                 d_printf("%s: second gencache_del() succeeded\n",
5356                          __location__);
5357                 return False;
5358         }
5359                         
5360         if (gencache_get("foo", &val, &tm)) {
5361                 d_printf("%s: gencache_get() on deleted entry "
5362                          "succeeded\n", __location__);
5363                 return False;
5364         }
5365
5366         blob = data_blob_string_const_null("bar");
5367         tm = time(NULL);
5368
5369         if (!gencache_set_data_blob("foo", &blob, tm)) {
5370                 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
5371                 return False;
5372         }
5373
5374         data_blob_free(&blob);
5375
5376         if (!gencache_get_data_blob("foo", &blob, NULL)) {
5377                 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
5378                 return False;
5379         }
5380
5381         if (strcmp((const char *)blob.data, "bar") != 0) {
5382                 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
5383                          __location__, (const char *)blob.data, "bar");
5384                 data_blob_free(&blob);
5385                 return False;
5386         }
5387
5388         data_blob_free(&blob);
5389
5390         if (!gencache_del("foo")) {
5391                 d_printf("%s: gencache_del() failed\n", __location__);
5392                 return False;
5393         }
5394         if (gencache_del("foo")) {
5395                 d_printf("%s: second gencache_del() succeeded\n",
5396                          __location__);
5397                 return False;
5398         }
5399
5400         if (gencache_get_data_blob("foo", &blob, NULL)) {
5401                 d_printf("%s: gencache_get_data_blob() on deleted entry "
5402                          "succeeded\n", __location__);
5403                 return False;
5404         }
5405
5406         if (!gencache_shutdown()) {
5407                 d_printf("%s: gencache_shutdown() failed\n", __location__);
5408                 return False;
5409         }
5410
5411         if (gencache_shutdown()) {
5412                 d_printf("%s: second gencache_shutdown() succeeded\n",
5413                          __location__);
5414                 return False;
5415         }
5416
5417         return True;
5418 }
5419
5420 static bool rbt_testval(struct db_context *db, const char *key,
5421                         const char *value)
5422 {
5423         struct db_record *rec;
5424         TDB_DATA data = string_tdb_data(value);
5425         bool ret = false;
5426         NTSTATUS status;
5427
5428         rec = db->fetch_locked(db, db, string_tdb_data(key));
5429         if (rec == NULL) {
5430                 d_fprintf(stderr, "fetch_locked failed\n");
5431                 goto done;
5432         }
5433         status = rec->store(rec, data, 0);
5434         if (!NT_STATUS_IS_OK(status)) {
5435                 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
5436                 goto done;
5437         }
5438         TALLOC_FREE(rec);
5439
5440         rec = db->fetch_locked(db, db, string_tdb_data(key));
5441         if (rec == NULL) {
5442                 d_fprintf(stderr, "second fetch_locked failed\n");
5443                 goto done;
5444         }
5445         if ((rec->value.dsize != data.dsize)
5446             || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
5447                 d_fprintf(stderr, "Got wrong data back\n");
5448                 goto done;
5449         }
5450
5451         ret = true;
5452  done:
5453         TALLOC_FREE(rec);
5454         return ret;
5455 }
5456
5457 static bool run_local_rbtree(int dummy)
5458 {
5459         struct db_context *db;
5460         bool ret = false;
5461         int i;
5462
5463         db = db_open_rbt(NULL);
5464
5465         if (db == NULL) {
5466                 d_fprintf(stderr, "db_open_rbt failed\n");
5467                 return false;
5468         }
5469
5470         for (i=0; i<1000; i++) {
5471                 char *key, *value;
5472
5473                 if (asprintf(&key, "key%ld", random()) == -1) {
5474                         goto done;
5475                 }
5476                 if (asprintf(&value, "value%ld", random()) == -1) {
5477                         SAFE_FREE(key);
5478                         goto done;
5479                 }
5480
5481                 if (!rbt_testval(db, key, value)) {
5482                         SAFE_FREE(key);
5483                         SAFE_FREE(value);
5484                         goto done;
5485                 }
5486
5487                 SAFE_FREE(value);
5488                 if (asprintf(&value, "value%ld", random()) == -1) {
5489                         SAFE_FREE(key);
5490                         goto done;
5491                 }
5492
5493                 if (!rbt_testval(db, key, value)) {
5494                         SAFE_FREE(key);
5495                         SAFE_FREE(value);
5496                         goto done;
5497                 }
5498
5499                 SAFE_FREE(key);
5500                 SAFE_FREE(value);
5501         }
5502
5503         ret = true;
5504
5505  done:
5506         TALLOC_FREE(db);
5507         return ret;
5508 }
5509
5510 static bool test_stream_name(const char *fname, const char *expected_base,
5511                              const char *expected_stream,
5512                              NTSTATUS expected_status)
5513 {
5514         NTSTATUS status;
5515         char *base = NULL;
5516         char *stream = NULL;
5517
5518         status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
5519         if (!NT_STATUS_EQUAL(status, expected_status)) {
5520                 goto error;
5521         }
5522
5523         if (!NT_STATUS_IS_OK(status)) {
5524                 return true;
5525         }
5526
5527         if (base == NULL) goto error;
5528
5529         if (strcmp(expected_base, base) != 0) goto error;
5530
5531         if ((expected_stream != NULL) && (stream == NULL)) goto error;
5532         if ((expected_stream == NULL) && (stream != NULL)) goto error;
5533
5534         if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
5535                 goto error;
5536
5537         TALLOC_FREE(base);
5538         TALLOC_FREE(stream);
5539         return true;
5540
5541  error:
5542         d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
5543                   fname, expected_base ? expected_base : "<NULL>",
5544                   expected_stream ? expected_stream : "<NULL>",
5545                   nt_errstr(expected_status));
5546         d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
5547                   base ? base : "<NULL>", stream ? stream : "<NULL>",
5548                   nt_errstr(status));
5549         TALLOC_FREE(base);
5550         TALLOC_FREE(stream);
5551         return false;
5552 }
5553
5554 static bool run_local_stream_name(int dummy)
5555 {
5556         bool ret = true;
5557
5558         ret &= test_stream_name(
5559                 "bla", "bla", NULL, NT_STATUS_OK);
5560         ret &= test_stream_name(
5561                 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
5562         ret &= test_stream_name(
5563                 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5564         ret &= test_stream_name(
5565                 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
5566         ret &= test_stream_name(
5567                 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5568         ret &= test_stream_name(
5569                 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
5570         ret &= test_stream_name(
5571                 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
5572         ret &= test_stream_name(
5573                 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
5574
5575         return ret;
5576 }
5577
5578 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
5579 {
5580         if (a.length != b.length) {
5581                 printf("a.length=%d != b.length=%d\n",
5582                        (int)a.length, (int)b.length);
5583                 return false;
5584         }
5585         if (memcmp(a.data, b.data, a.length) != 0) {
5586                 printf("a.data and b.data differ\n");
5587                 return false;
5588         }
5589         return true;
5590 }
5591
5592 static bool run_local_memcache(int dummy)
5593 {
5594         struct memcache *cache;
5595         DATA_BLOB k1, k2;
5596         DATA_BLOB d1, d2, d3;
5597         DATA_BLOB v1, v2, v3;
5598
5599         TALLOC_CTX *mem_ctx;
5600         char *str1, *str2;
5601         size_t size1, size2;
5602         bool ret = false;
5603
5604         cache = memcache_init(NULL, 100);
5605
5606         if (cache == NULL) {
5607                 printf("memcache_init failed\n");
5608                 return false;
5609         }
5610
5611         d1 = data_blob_const("d1", 2);
5612         d2 = data_blob_const("d2", 2);
5613         d3 = data_blob_const("d3", 2);
5614
5615         k1 = data_blob_const("d1", 2);
5616         k2 = data_blob_const("d2", 2);
5617
5618         memcache_add(cache, STAT_CACHE, k1, d1);
5619         memcache_add(cache, GETWD_CACHE, k2, d2);
5620
5621         if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
5622                 printf("could not find k1\n");
5623                 return false;
5624         }
5625         if (!data_blob_equal(d1, v1)) {
5626                 return false;
5627         }
5628
5629         if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5630                 printf("could not find k2\n");
5631                 return false;
5632         }
5633         if (!data_blob_equal(d2, v2)) {
5634                 return false;
5635         }
5636
5637         memcache_add(cache, STAT_CACHE, k1, d3);
5638
5639         if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
5640                 printf("could not find replaced k1\n");
5641                 return false;
5642         }
5643         if (!data_blob_equal(d3, v3)) {
5644                 return false;
5645         }
5646
5647         memcache_add(cache, GETWD_CACHE, k1, d1);
5648
5649         if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5650                 printf("Did find k2, should have been purged\n");
5651                 return false;
5652         }
5653
5654         TALLOC_FREE(cache);
5655
5656         cache = memcache_init(NULL, 0);
5657
5658         mem_ctx = talloc_init("foo");
5659
5660         str1 = talloc_strdup(mem_ctx, "string1");
5661         str2 = talloc_strdup(mem_ctx, "string2");
5662
5663         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5664                             data_blob_string_const("torture"), &str1);
5665         size1 = talloc_total_size(cache);
5666
5667         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5668                             data_blob_string_const("torture"), &str2);
5669         size2 = talloc_total_size(cache);
5670
5671         printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
5672
5673         if (size2 > size1) {
5674                 printf("memcache leaks memory!\n");
5675                 goto fail;
5676         }
5677
5678         ret = true;
5679  fail:
5680         TALLOC_FREE(cache);
5681         return ret;
5682 }
5683
5684 static void wbclient_done(struct tevent_req *req)
5685 {
5686         wbcErr wbc_err;
5687         struct winbindd_response *wb_resp;
5688         int *i = (int *)tevent_req_callback_data_void(req);
5689
5690         wbc_err = wb_trans_recv(req, req, &wb_resp);
5691         TALLOC_FREE(req);
5692         *i += 1;
5693         d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
5694 }
5695
5696 static bool run_local_wbclient(int dummy)
5697 {
5698         struct event_context *ev;
5699         struct wb_context **wb_ctx;
5700         struct winbindd_request wb_req;
5701         bool result = false;
5702         int i, j;
5703
5704         BlockSignals(True, SIGPIPE);
5705
5706         ev = event_context_init(talloc_tos());
5707         if (ev == NULL) {
5708                 goto fail;
5709         }
5710
5711         wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, torture_numops);
5712         if (wb_ctx == NULL) {
5713                 goto fail;
5714         }
5715
5716         ZERO_STRUCT(wb_req);
5717         wb_req.cmd = WINBINDD_PING;
5718
5719         for (i=0; i<torture_numops; i++) {
5720                 wb_ctx[i] = wb_context_init(ev);
5721                 if (wb_ctx[i] == NULL) {
5722                         goto fail;
5723                 }
5724                 for (j=0; j<5; j++) {
5725                         struct tevent_req *req;
5726                         req = wb_trans_send(ev, ev, wb_ctx[i],
5727                                             (j % 2) == 0, &wb_req);
5728                         if (req == NULL) {
5729                                 goto fail;
5730                         }
5731                         tevent_req_set_callback(req, wbclient_done, &i);
5732                 }
5733         }
5734
5735         i = 0;
5736
5737         while (i < 5 * torture_numops) {
5738                 event_loop_once(ev);
5739         }
5740
5741         result = true;
5742  fail:
5743         TALLOC_FREE(ev);
5744         return result;
5745 }
5746
5747 static double create_procs(bool (*fn)(int), bool *result)
5748 {
5749         int i, status;
5750         volatile pid_t *child_status;
5751         volatile bool *child_status_out;
5752         int synccount;
5753         int tries = 8;
5754
5755         synccount = 0;
5756
5757         child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
5758         if (!child_status) {
5759                 printf("Failed to setup shared memory\n");
5760                 return -1;
5761         }
5762
5763         child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
5764         if (!child_status_out) {
5765                 printf("Failed to setup result status shared memory\n");
5766                 return -1;
5767         }
5768
5769         for (i = 0; i < nprocs; i++) {
5770                 child_status[i] = 0;
5771                 child_status_out[i] = True;
5772         }
5773
5774         start_timer();
5775
5776         for (i=0;i<nprocs;i++) {
5777                 procnum = i;
5778                 if (fork() == 0) {
5779                         pid_t mypid = getpid();
5780                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
5781
5782                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
5783
5784                         while (1) {
5785                                 if (torture_open_connection(&current_cli, i)) break;
5786                                 if (tries-- == 0) {
5787                                         printf("pid %d failed to start\n", (int)getpid());
5788                                         _exit(1);
5789                                 }
5790                                 smb_msleep(10); 
5791                         }
5792
5793                         child_status[i] = getpid();
5794
5795                         while (child_status[i] && end_timer() < 5) smb_msleep(2);
5796
5797                         child_status_out[i] = fn(i);
5798                         _exit(0);
5799                 }
5800         }
5801
5802         do {
5803                 synccount = 0;
5804                 for (i=0;i<nprocs;i++) {
5805                         if (child_status[i]) synccount++;
5806                 }
5807                 if (synccount == nprocs) break;
5808                 smb_msleep(10);
5809         } while (end_timer() < 30);
5810
5811         if (synccount != nprocs) {
5812                 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
5813                 *result = False;
5814                 return end_timer();
5815         }
5816
5817         /* start the client load */
5818         start_timer();
5819
5820         for (i=0;i<nprocs;i++) {
5821                 child_status[i] = 0;
5822         }
5823
5824         printf("%d clients started\n", nprocs);
5825
5826         for (i=0;i<nprocs;i++) {
5827                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
5828         }
5829
5830         printf("\n");
5831         
5832         for (i=0;i<nprocs;i++) {
5833                 if (!child_status_out[i]) {
5834                         *result = False;
5835                 }
5836         }
5837         return end_timer();
5838 }
5839
5840 #define FLAG_MULTIPROC 1
5841
5842 static struct {
5843         const char *name;
5844         bool (*fn)(int);
5845         unsigned flags;
5846 } torture_ops[] = {
5847         {"FDPASS", run_fdpasstest, 0},
5848         {"LOCK1",  run_locktest1,  0},
5849         {"LOCK2",  run_locktest2,  0},
5850         {"LOCK3",  run_locktest3,  0},
5851         {"LOCK4",  run_locktest4,  0},
5852         {"LOCK5",  run_locktest5,  0},
5853         {"LOCK6",  run_locktest6,  0},
5854         {"LOCK7",  run_locktest7,  0},
5855         {"UNLINK", run_unlinktest, 0},
5856         {"BROWSE", run_browsetest, 0},
5857         {"ATTR",   run_attrtest,   0},
5858         {"TRANS2", run_trans2test, 0},
5859         {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
5860         {"TORTURE",run_torture,    FLAG_MULTIPROC},
5861         {"RANDOMIPC", run_randomipc, 0},
5862         {"NEGNOWAIT", run_negprot_nowait, 0},
5863         {"NBENCH",  run_nbench, 0},
5864         {"OPLOCK1",  run_oplock1, 0},
5865         {"OPLOCK2",  run_oplock2, 0},
5866         {"OPLOCK3",  run_oplock3, 0},
5867         {"DIR",  run_dirtest, 0},
5868         {"DIR1",  run_dirtest1, 0},
5869         {"DENY1",  torture_denytest1, 0},
5870         {"DENY2",  torture_denytest2, 0},
5871         {"TCON",  run_tcon_test, 0},
5872         {"TCONDEV",  run_tcon_devtype_test, 0},
5873         {"RW1",  run_readwritetest, 0},
5874         {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
5875         {"RW3",  run_readwritelarge, 0},
5876         {"OPEN", run_opentest, 0},
5877         {"POSIX", run_simple_posix_open_test, 0},
5878         { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
5879 #if 1
5880         {"OPENATTR", run_openattrtest, 0},
5881 #endif
5882         {"XCOPY", run_xcopy, 0},
5883         {"RENAME", run_rename, 0},
5884         {"DELETE", run_deletetest, 0},
5885         {"PROPERTIES", run_properties, 0},
5886         {"MANGLE", torture_mangle, 0},
5887         {"MANGLE1", run_mangle1, 0},
5888         {"W2K", run_w2ktest, 0},
5889         {"TRANS2SCAN", torture_trans2_scan, 0},
5890         {"NTTRANSSCAN", torture_nttrans_scan, 0},
5891         {"UTABLE", torture_utable, 0},
5892         {"CASETABLE", torture_casetable, 0},
5893         {"ERRMAPEXTRACT", run_error_map_extract, 0},
5894         {"PIPE_NUMBER", run_pipe_number, 0},
5895         {"TCON2",  run_tcon2_test, 0},
5896         {"IOCTL",  torture_ioctl_test, 0},
5897         {"CHKPATH",  torture_chkpath_test, 0},
5898         {"FDSESS", run_fdsesstest, 0},
5899         { "EATEST", run_eatest, 0},
5900         { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
5901         { "CHAIN1", run_chain1, 0},
5902         { "WINDOWS-WRITE", run_windows_write, 0},
5903         { "CLI_ECHO", run_cli_echo, 0},
5904         { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
5905         { "LOCAL-GENCACHE", run_local_gencache, 0},
5906         { "LOCAL-RBTREE", run_local_rbtree, 0},
5907         { "LOCAL-MEMCACHE", run_local_memcache, 0},
5908         { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
5909         { "LOCAL-WBCLIENT", run_local_wbclient, 0},
5910         {NULL, NULL, 0}};
5911
5912
5913
5914 /****************************************************************************
5915 run a specified test or "ALL"
5916 ****************************************************************************/
5917 static bool run_test(const char *name)
5918 {
5919         bool ret = True;
5920         bool result = True;
5921         bool found = False;
5922         int i;
5923         double t;
5924         if (strequal(name,"ALL")) {
5925                 for (i=0;torture_ops[i].name;i++) {
5926                         run_test(torture_ops[i].name);
5927                 }
5928                 found = True;
5929         }
5930         
5931         for (i=0;torture_ops[i].name;i++) {
5932                 fstr_sprintf(randomfname, "\\XX%x", 
5933                          (unsigned)random());
5934
5935                 if (strequal(name, torture_ops[i].name)) {
5936                         found = True;
5937                         printf("Running %s\n", name);
5938                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
5939                                 t = create_procs(torture_ops[i].fn, &result);
5940                                 if (!result) { 
5941                                         ret = False;
5942                                         printf("TEST %s FAILED!\n", name);
5943                                 }
5944                                          
5945                         } else {
5946                                 start_timer();
5947                                 if (!torture_ops[i].fn(0)) {
5948                                         ret = False;
5949                                         printf("TEST %s FAILED!\n", name);
5950                                 }
5951                                 t = end_timer();
5952                         }
5953                         printf("%s took %g secs\n\n", name, t);
5954                 }
5955         }
5956
5957         if (!found) {
5958                 printf("Did not find a test named %s\n", name);
5959                 ret = False;
5960         }
5961
5962         return ret;
5963 }
5964
5965
5966 static void usage(void)
5967 {
5968         int i;
5969
5970         printf("WARNING samba4 test suite is much more complete nowadays.\n");
5971         printf("Please use samba4 torture.\n\n");
5972
5973         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
5974
5975         printf("\t-d debuglevel\n");
5976         printf("\t-U user%%pass\n");
5977         printf("\t-k               use kerberos\n");
5978         printf("\t-N numprocs\n");
5979         printf("\t-n my_netbios_name\n");
5980         printf("\t-W workgroup\n");
5981         printf("\t-o num_operations\n");
5982         printf("\t-O socket_options\n");
5983         printf("\t-m maximum protocol\n");
5984         printf("\t-L use oplocks\n");
5985         printf("\t-c CLIENT.TXT   specify client load file for NBENCH\n");
5986         printf("\t-A showall\n");
5987         printf("\t-p port\n");
5988         printf("\t-s seed\n");
5989         printf("\t-b unclist_filename   specify multiple shares for multiple connections\n");
5990         printf("\n\n");
5991
5992         printf("tests are:");
5993         for (i=0;torture_ops[i].name;i++) {
5994                 printf(" %s", torture_ops[i].name);
5995         }
5996         printf("\n");
5997
5998         printf("default test is ALL\n");
5999         
6000         exit(1);
6001 }
6002
6003 /****************************************************************************
6004   main program
6005 ****************************************************************************/
6006  int main(int argc,char *argv[])
6007 {
6008         int opt, i;
6009         char *p;
6010         int gotuser = 0;
6011         int gotpass = 0;
6012         bool correct = True;
6013         TALLOC_CTX *frame = talloc_stackframe();
6014         int seed = time(NULL);
6015
6016         dbf = x_stdout;
6017
6018 #ifdef HAVE_SETBUFFER
6019         setbuffer(stdout, NULL, 0);
6020 #endif
6021
6022         load_case_tables();
6023
6024         if (is_default_dyn_CONFIGFILE()) {
6025                 if(getenv("SMB_CONF_PATH")) {
6026                         set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
6027                 }
6028         }
6029         lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
6030         load_interfaces();
6031
6032         if (argc < 2) {
6033                 usage();
6034         }
6035
6036         for(p = argv[1]; *p; p++)
6037           if(*p == '\\')
6038             *p = '/';
6039  
6040         if (strncmp(argv[1], "//", 2)) {
6041                 usage();
6042         }
6043
6044         fstrcpy(host, &argv[1][2]);
6045         p = strchr_m(&host[2],'/');
6046         if (!p) {
6047                 usage();
6048         }
6049         *p = 0;
6050         fstrcpy(share, p+1);
6051
6052         fstrcpy(myname, get_myname(talloc_tos()));
6053         if (!*myname) {
6054                 fprintf(stderr, "Failed to get my hostname.\n");
6055                 return 1;
6056         }
6057
6058         if (*username == 0 && getenv("LOGNAME")) {
6059           fstrcpy(username,getenv("LOGNAME"));
6060         }
6061
6062         argc--;
6063         argv++;
6064
6065         fstrcpy(workgroup, lp_workgroup());
6066
6067         while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:B:")) != EOF) {
6068                 switch (opt) {
6069                 case 'p':
6070                         port_to_use = atoi(optarg);
6071                         break;
6072                 case 's':
6073                         seed = atoi(optarg);
6074                         break;
6075                 case 'W':
6076                         fstrcpy(workgroup,optarg);
6077                         break;
6078                 case 'm':
6079                         max_protocol = interpret_protocol(optarg, max_protocol);
6080                         break;
6081                 case 'N':
6082                         nprocs = atoi(optarg);
6083                         break;
6084                 case 'o':
6085                         torture_numops = atoi(optarg);
6086                         break;
6087                 case 'd':
6088                         DEBUGLEVEL = atoi(optarg);
6089                         break;
6090                 case 'O':
6091                         sockops = optarg;
6092                         break;
6093                 case 'L':
6094                         use_oplocks = True;
6095                         break;
6096                 case 'A':
6097                         torture_showall = True;
6098                         break;
6099                 case 'n':
6100                         fstrcpy(myname, optarg);
6101                         break;
6102                 case 'c':
6103                         client_txt = optarg;
6104                         break;
6105                 case 'e':
6106                         do_encrypt = true;
6107                         break;
6108                 case 'k':
6109 #ifdef HAVE_KRB5
6110                         use_kerberos = True;
6111 #else
6112                         d_printf("No kerberos support compiled in\n");
6113                         exit(1);
6114 #endif
6115                         break;
6116                 case 'U':
6117                         gotuser = 1;
6118                         fstrcpy(username,optarg);
6119                         p = strchr_m(username,'%');
6120                         if (p) {
6121                                 *p = 0;
6122                                 fstrcpy(password, p+1);
6123                                 gotpass = 1;
6124                         }
6125                         break;
6126                 case 'b':
6127                         fstrcpy(multishare_conn_fname, optarg);
6128                         use_multishare_conn = True;
6129                         break;
6130                 case 'B':
6131                         torture_blocksize = atoi(optarg);
6132                         break;
6133                 default:
6134                         printf("Unknown option %c (%d)\n", (char)opt, opt);
6135                         usage();
6136                 }
6137         }
6138
6139         d_printf("using seed %d\n", seed);
6140
6141         srandom(seed);
6142
6143         if(use_kerberos && !gotuser) gotpass = True;
6144
6145         while (!gotpass) {
6146                 p = getpass("Password:");
6147                 if (p) {
6148                         fstrcpy(password, p);
6149                         gotpass = 1;
6150                 }
6151         }
6152
6153         printf("host=%s share=%s user=%s myname=%s\n", 
6154                host, share, username, myname);
6155
6156         if (argc == optind) {
6157                 correct = run_test("ALL");
6158         } else {
6159                 for (i=optind;i<argc;i++) {
6160                         if (!run_test(argv[i])) {
6161                                 correct = False;
6162                         }
6163                 }
6164         }
6165
6166         TALLOC_FREE(frame);
6167
6168         if (correct) {
6169                 return(0);
6170         } else {
6171                 return(1);
6172         }
6173 }