s3: Convert cli_list() to return NTSTATUS
[amitay/samba.git] / source3 / torture / torture.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB torture tester
4    Copyright (C) Andrew Tridgell 1997-1998
5    Copyright (C) Jeremy Allison 2009
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "nsswitch/libwbclient/wbc_async.h"
23 #include "torture/proto.h"
24 #include "libcli/security/dom_sid.h"
25 #include "tldap.h"
26 #include "tldap_util.h"
27
28 extern char *optarg;
29 extern int optind;
30
31 static fstring host, workgroup, share, password, username, myname;
32 static int max_protocol = PROTOCOL_NT1;
33 static const char *sockops="TCP_NODELAY";
34 static int nprocs=1;
35 static int port_to_use=0;
36 int torture_numops=100;
37 int torture_blocksize=1024*1024;
38 static int procnum; /* records process count number when forking */
39 static struct cli_state *current_cli;
40 static fstring randomfname;
41 static bool use_oplocks;
42 static bool use_level_II_oplocks;
43 static const char *client_txt = "client_oplocks.txt";
44 static bool use_kerberos;
45 static fstring multishare_conn_fname;
46 static bool use_multishare_conn = False;
47 static bool do_encrypt;
48 static const char *local_path = NULL;
49
50 bool torture_showall = False;
51
52 static double create_procs(bool (*fn)(int), bool *result);
53
54
55 /* return a pointer to a anonymous shared memory segment of size "size"
56    which will persist across fork() but will disappear when all processes
57    exit 
58
59    The memory is not zeroed 
60
61    This function uses system5 shared memory. It takes advantage of a property
62    that the memory is not destroyed if it is attached when the id is removed
63    */
64 void *shm_setup(int size)
65 {
66         int shmid;
67         void *ret;
68
69 #ifdef __QNXNTO__
70         shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
71         if (shmid == -1) {
72                 printf("can't get shared memory\n");
73                 exit(1);
74         }
75         shm_unlink("private");
76         if (ftruncate(shmid, size) == -1) {
77                 printf("can't set shared memory size\n");
78                 exit(1);
79         }
80         ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
81         if (ret == MAP_FAILED) {
82                 printf("can't map shared memory\n");
83                 exit(1);
84         }
85 #else
86         shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
87         if (shmid == -1) {
88                 printf("can't get shared memory\n");
89                 exit(1);
90         }
91         ret = (void *)shmat(shmid, 0, 0);
92         if (!ret || ret == (void *)-1) {
93                 printf("can't attach to shared memory\n");
94                 return NULL;
95         }
96         /* the following releases the ipc, but note that this process
97            and all its children will still have access to the memory, its
98            just that the shmid is no longer valid for other shm calls. This
99            means we don't leave behind lots of shm segments after we exit 
100
101            See Stevens "advanced programming in unix env" for details
102            */
103         shmctl(shmid, IPC_RMID, 0);
104 #endif
105
106         return ret;
107 }
108
109 /********************************************************************
110  Ensure a connection is encrypted.
111 ********************************************************************/
112
113 static bool force_cli_encryption(struct cli_state *c,
114                         const char *sharename)
115 {
116         uint16 major, minor;
117         uint32 caplow, caphigh;
118         NTSTATUS status;
119
120         if (!SERVER_HAS_UNIX_CIFS(c)) {
121                 d_printf("Encryption required and "
122                         "server that doesn't support "
123                         "UNIX extensions - failing connect\n");
124                         return false;
125         }
126
127         status = cli_unix_extensions_version(c, &major, &minor, &caplow,
128                                              &caphigh);
129         if (!NT_STATUS_IS_OK(status)) {
130                 d_printf("Encryption required and "
131                         "can't get UNIX CIFS extensions "
132                         "version from server: %s\n", nt_errstr(status));
133                 return false;
134         }
135
136         if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
137                 d_printf("Encryption required and "
138                         "share %s doesn't support "
139                         "encryption.\n", sharename);
140                 return false;
141         }
142
143         if (c->use_kerberos) {
144                 status = cli_gss_smb_encryption_start(c);
145         } else {
146                 status = cli_raw_ntlm_smb_encryption_start(c,
147                                                 username,
148                                                 password,
149                                                 workgroup);
150         }
151
152         if (!NT_STATUS_IS_OK(status)) {
153                 d_printf("Encryption required and "
154                         "setup failed with error %s.\n",
155                         nt_errstr(status));
156                 return false;
157         }
158
159         return true;
160 }
161
162
163 static struct cli_state *open_nbt_connection(void)
164 {
165         struct nmb_name called, calling;
166         struct sockaddr_storage ss;
167         struct cli_state *c;
168         NTSTATUS status;
169
170         make_nmb_name(&calling, myname, 0x0);
171         make_nmb_name(&called , host, 0x20);
172
173         zero_sockaddr(&ss);
174
175         if (!(c = cli_initialise())) {
176                 printf("Failed initialize cli_struct to connect with %s\n", host);
177                 return NULL;
178         }
179
180         c->port = port_to_use;
181
182         status = cli_connect(c, host, &ss);
183         if (!NT_STATUS_IS_OK(status)) {
184                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
185                 return NULL;
186         }
187
188         c->use_kerberos = use_kerberos;
189
190         c->timeout = 120000; /* set a really long timeout (2 minutes) */
191         if (use_oplocks) c->use_oplocks = True;
192         if (use_level_II_oplocks) c->use_level_II_oplocks = True;
193
194         if (!cli_session_request(c, &calling, &called)) {
195                 /*
196                  * Well, that failed, try *SMBSERVER ...
197                  * However, we must reconnect as well ...
198                  */
199                 status = cli_connect(c, host, &ss);
200                 if (!NT_STATUS_IS_OK(status)) {
201                         printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
202                         return NULL;
203                 }
204
205                 make_nmb_name(&called, "*SMBSERVER", 0x20);
206                 if (!cli_session_request(c, &calling, &called)) {
207                         printf("%s rejected the session\n",host);
208                         printf("We tried with a called name of %s & %s\n",
209                                 host, "*SMBSERVER");
210                         cli_shutdown(c);
211                         return NULL;
212                 }
213         }
214
215         return c;
216 }
217
218 /* Insert a NULL at the first separator of the given path and return a pointer
219  * to the remainder of the string.
220  */
221 static char *
222 terminate_path_at_separator(char * path)
223 {
224         char * p;
225
226         if (!path) {
227                 return NULL;
228         }
229
230         if ((p = strchr_m(path, '/'))) {
231                 *p = '\0';
232                 return p + 1;
233         }
234
235         if ((p = strchr_m(path, '\\'))) {
236                 *p = '\0';
237                 return p + 1;
238         }
239
240         /* No separator. */
241         return NULL;
242 }
243
244 /*
245   parse a //server/share type UNC name
246 */
247 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
248                       char **hostname, char **sharename)
249 {
250         char *p;
251
252         *hostname = *sharename = NULL;
253
254         if (strncmp(unc_name, "\\\\", 2) &&
255             strncmp(unc_name, "//", 2)) {
256                 return False;
257         }
258
259         *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
260         p = terminate_path_at_separator(*hostname);
261
262         if (p && *p) {
263                 *sharename = talloc_strdup(mem_ctx, p);
264                 terminate_path_at_separator(*sharename);
265         }
266
267         if (*hostname && *sharename) {
268                 return True;
269         }
270
271         TALLOC_FREE(*hostname);
272         TALLOC_FREE(*sharename);
273         return False;
274 }
275
276 static bool torture_open_connection_share(struct cli_state **c,
277                                    const char *hostname, 
278                                    const char *sharename)
279 {
280         bool retry;
281         int flags = 0;
282         NTSTATUS status;
283
284         if (use_kerberos)
285                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
286         if (use_oplocks)
287                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
288         if (use_level_II_oplocks)
289                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
290
291         status = cli_full_connection(c, myname,
292                                      hostname, NULL, port_to_use, 
293                                      sharename, "?????", 
294                                      username, workgroup, 
295                                      password, flags, Undefined, &retry);
296         if (!NT_STATUS_IS_OK(status)) {
297                 printf("failed to open share connection: //%s/%s port:%d - %s\n",
298                         hostname, sharename, port_to_use, nt_errstr(status));
299                 return False;
300         }
301
302         (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
303
304         if (do_encrypt) {
305                 return force_cli_encryption(*c,
306                                         sharename);
307         }
308         return True;
309 }
310
311 bool torture_open_connection(struct cli_state **c, int conn_index)
312 {
313         char **unc_list = NULL;
314         int num_unc_names = 0;
315         bool result;
316
317         if (use_multishare_conn==True) {
318                 char *h, *s;
319                 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
320                 if (!unc_list || num_unc_names <= 0) {
321                         printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
322                         exit(1);
323                 }
324
325                 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
326                                       NULL, &h, &s)) {
327                         printf("Failed to parse UNC name %s\n",
328                                unc_list[conn_index % num_unc_names]);
329                         TALLOC_FREE(unc_list);
330                         exit(1);
331                 }
332
333                 result = torture_open_connection_share(c, h, s);
334
335                 /* h, s were copied earlier */
336                 TALLOC_FREE(unc_list);
337                 return result;
338         }
339
340         return torture_open_connection_share(c, host, share);
341 }
342
343 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
344 {
345         uint16 old_vuid = cli->vuid;
346         fstring old_user_name;
347         size_t passlen = strlen(password);
348         NTSTATUS status;
349         bool ret;
350
351         fstrcpy(old_user_name, cli->user_name);
352         cli->vuid = 0;
353         ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
354                                                 password, passlen,
355                                                 password, passlen,
356                                                 workgroup));
357         *new_vuid = cli->vuid;
358         cli->vuid = old_vuid;
359         status = cli_set_username(cli, old_user_name);
360         if (!NT_STATUS_IS_OK(status)) {
361                 return false;
362         }
363         return ret;
364 }
365
366
367 bool torture_close_connection(struct cli_state *c)
368 {
369         bool ret = True;
370         NTSTATUS status;
371
372         status = cli_tdis(c);
373         if (!NT_STATUS_IS_OK(status)) {
374                 printf("tdis failed (%s)\n", nt_errstr(status));
375                 ret = False;
376         }
377
378         cli_shutdown(c);
379
380         return ret;
381 }
382
383
384 /* check if the server produced the expected error code */
385 static bool check_error(int line, struct cli_state *c, 
386                         uint8 eclass, uint32 ecode, NTSTATUS nterr)
387 {
388         if (cli_is_dos_error(c)) {
389                 uint8 cclass;
390                 uint32 num;
391
392                 /* Check DOS error */
393
394                 cli_dos_error(c, &cclass, &num);
395
396                 if (eclass != cclass || ecode != num) {
397                         printf("unexpected error code class=%d code=%d\n", 
398                                (int)cclass, (int)num);
399                         printf(" expected %d/%d %s (line=%d)\n", 
400                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
401                         return False;
402                 }
403
404         } else {
405                 NTSTATUS status;
406
407                 /* Check NT error */
408
409                 status = cli_nt_error(c);
410
411                 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
412                         printf("unexpected error code %s\n", nt_errstr(status));
413                         printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
414                         return False;
415                 }
416         }
417
418         return True;
419 }
420
421
422 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
423 {
424         while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
425                 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
426         }
427         return True;
428 }
429
430
431 static bool rw_torture(struct cli_state *c)
432 {
433         const char *lockfname = "\\torture.lck";
434         fstring fname;
435         uint16_t fnum;
436         uint16_t fnum2;
437         pid_t pid2, pid = getpid();
438         int i, j;
439         char buf[1024];
440         bool correct = True;
441         NTSTATUS status;
442
443         memset(buf, '\0', sizeof(buf));
444
445         status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
446                          DENY_NONE, &fnum2);
447         if (!NT_STATUS_IS_OK(status)) {
448                 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
449         }
450         if (!NT_STATUS_IS_OK(status)) {
451                 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
452                 return False;
453         }
454
455         for (i=0;i<torture_numops;i++) {
456                 unsigned n = (unsigned)sys_random()%10;
457                 if (i % 10 == 0) {
458                         printf("%d\r", i); fflush(stdout);
459                 }
460                 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
461
462                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
463                         return False;
464                 }
465
466                 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
467                         printf("open failed (%s)\n", cli_errstr(c));
468                         correct = False;
469                         break;
470                 }
471
472                 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
473                         printf("write failed (%s)\n", cli_errstr(c));
474                         correct = False;
475                 }
476
477                 for (j=0;j<50;j++) {
478                         if (cli_write(c, fnum, 0, (char *)buf, 
479                                       sizeof(pid)+(j*sizeof(buf)), 
480                                       sizeof(buf)) != sizeof(buf)) {
481                                 printf("write failed (%s)\n", cli_errstr(c));
482                                 correct = False;
483                         }
484                 }
485
486                 pid2 = 0;
487
488                 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
489                         printf("read failed (%s)\n", cli_errstr(c));
490                         correct = False;
491                 }
492
493                 if (pid2 != pid) {
494                         printf("data corruption!\n");
495                         correct = False;
496                 }
497
498                 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
499                         printf("close failed (%s)\n", cli_errstr(c));
500                         correct = False;
501                 }
502
503                 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
504                         printf("unlink failed (%s)\n", cli_errstr(c));
505                         correct = False;
506                 }
507
508                 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
509                         printf("unlock failed (%s)\n", cli_errstr(c));
510                         correct = False;
511                 }
512         }
513
514         cli_close(c, fnum2);
515         cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
516
517         printf("%d\n", i);
518
519         return correct;
520 }
521
522 static bool run_torture(int dummy)
523 {
524         struct cli_state *cli;
525         bool ret;
526
527         cli = current_cli;
528
529         cli_sockopt(cli, sockops);
530
531         ret = rw_torture(cli);
532
533         if (!torture_close_connection(cli)) {
534                 ret = False;
535         }
536
537         return ret;
538 }
539
540 static bool rw_torture3(struct cli_state *c, char *lockfname)
541 {
542         uint16_t fnum = (uint16_t)-1;
543         unsigned int i = 0;
544         char buf[131072];
545         char buf_rd[131072];
546         unsigned count;
547         unsigned countprev = 0;
548         ssize_t sent = 0;
549         bool correct = True;
550         NTSTATUS status;
551
552         srandom(1);
553         for (i = 0; i < sizeof(buf); i += sizeof(uint32))
554         {
555                 SIVAL(buf, i, sys_random());
556         }
557
558         if (procnum == 0)
559         {
560                 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
561                                  DENY_NONE, &fnum))) {
562                         printf("first open read/write of %s failed (%s)\n",
563                                         lockfname, cli_errstr(c));
564                         return False;
565                 }
566         }
567         else
568         {
569                 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
570                 {
571                         status = cli_open(c, lockfname, O_RDONLY, 
572                                          DENY_NONE, &fnum);
573                         if (!NT_STATUS_IS_OK(status)) {
574                                 break;
575                         }
576                         smb_msleep(10);
577                 }
578                 if (!NT_STATUS_IS_OK(status)) {
579                         printf("second open read-only of %s failed (%s)\n",
580                                         lockfname, cli_errstr(c));
581                         return False;
582                 }
583         }
584
585         i = 0;
586         for (count = 0; count < sizeof(buf); count += sent)
587         {
588                 if (count >= countprev) {
589                         printf("%d %8d\r", i, count);
590                         fflush(stdout);
591                         i++;
592                         countprev += (sizeof(buf) / 20);
593                 }
594
595                 if (procnum == 0)
596                 {
597                         sent = ((unsigned)sys_random()%(20))+ 1;
598                         if (sent > sizeof(buf) - count)
599                         {
600                                 sent = sizeof(buf) - count;
601                         }
602
603                         if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
604                                 printf("write failed (%s)\n", cli_errstr(c));
605                                 correct = False;
606                         }
607                 }
608                 else
609                 {
610                         sent = cli_read(c, fnum, buf_rd+count, count,
611                                                   sizeof(buf)-count);
612                         if (sent < 0)
613                         {
614                                 printf("read failed offset:%d size:%ld (%s)\n",
615                                        count, (unsigned long)sizeof(buf)-count,
616                                        cli_errstr(c));
617                                 correct = False;
618                                 sent = 0;
619                         }
620                         if (sent > 0)
621                         {
622                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
623                                 {
624                                         printf("read/write compare failed\n");
625                                         printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
626                                         correct = False;
627                                         break;
628                                 }
629                         }
630                 }
631
632         }
633
634         if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
635                 printf("close failed (%s)\n", cli_errstr(c));
636                 correct = False;
637         }
638
639         return correct;
640 }
641
642 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
643 {
644         const char *lockfname = "\\torture2.lck";
645         uint16_t fnum1;
646         uint16_t fnum2;
647         int i;
648         char buf[131072];
649         char buf_rd[131072];
650         bool correct = True;
651         ssize_t bytes_read;
652
653         if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
654                 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
655         }
656
657         if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL, 
658                          DENY_NONE, &fnum1))) {
659                 printf("first open read/write of %s failed (%s)\n",
660                                 lockfname, cli_errstr(c1));
661                 return False;
662         }
663         if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY, 
664                          DENY_NONE, &fnum2))) {
665                 printf("second open read-only of %s failed (%s)\n",
666                                 lockfname, cli_errstr(c2));
667                 cli_close(c1, fnum1);
668                 return False;
669         }
670
671         for (i=0;i<torture_numops;i++)
672         {
673                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
674                 if (i % 10 == 0) {
675                         printf("%d\r", i); fflush(stdout);
676                 }
677
678                 generate_random_buffer((unsigned char *)buf, buf_size);
679
680                 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
681                         printf("write failed (%s)\n", cli_errstr(c1));
682                         correct = False;
683                         break;
684                 }
685
686                 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
687                         printf("read failed (%s)\n", cli_errstr(c2));
688                         printf("read %d, expected %ld\n", (int)bytes_read, 
689                                (unsigned long)buf_size); 
690                         correct = False;
691                         break;
692                 }
693
694                 if (memcmp(buf_rd, buf, buf_size) != 0)
695                 {
696                         printf("read/write compare failed\n");
697                         correct = False;
698                         break;
699                 }
700         }
701
702         if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
703                 printf("close failed (%s)\n", cli_errstr(c2));
704                 correct = False;
705         }
706         if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
707                 printf("close failed (%s)\n", cli_errstr(c1));
708                 correct = False;
709         }
710
711         if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
712                 printf("unlink failed (%s)\n", cli_errstr(c1));
713                 correct = False;
714         }
715
716         return correct;
717 }
718
719 static bool run_readwritetest(int dummy)
720 {
721         struct cli_state *cli1, *cli2;
722         bool test1, test2 = False;
723
724         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
725                 return False;
726         }
727         cli_sockopt(cli1, sockops);
728         cli_sockopt(cli2, sockops);
729
730         printf("starting readwritetest\n");
731
732         test1 = rw_torture2(cli1, cli2);
733         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
734
735         if (test1) {
736                 test2 = rw_torture2(cli1, cli1);
737                 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
738         }
739
740         if (!torture_close_connection(cli1)) {
741                 test1 = False;
742         }
743
744         if (!torture_close_connection(cli2)) {
745                 test2 = False;
746         }
747
748         return (test1 && test2);
749 }
750
751 static bool run_readwritemulti(int dummy)
752 {
753         struct cli_state *cli;
754         bool test;
755
756         cli = current_cli;
757
758         cli_sockopt(cli, sockops);
759
760         printf("run_readwritemulti: fname %s\n", randomfname);
761         test = rw_torture3(cli, randomfname);
762
763         if (!torture_close_connection(cli)) {
764                 test = False;
765         }
766
767         return test;
768 }
769
770 static bool run_readwritelarge(int dummy)
771 {
772         static struct cli_state *cli1;
773         uint16_t fnum1;
774         const char *lockfname = "\\large.dat";
775         SMB_OFF_T fsize;
776         char buf[126*1024];
777         bool correct = True;
778
779         if (!torture_open_connection(&cli1, 0)) {
780                 return False;
781         }
782         cli_sockopt(cli1, sockops);
783         memset(buf,'\0',sizeof(buf));
784
785         cli1->max_xmit = 128*1024;
786
787         printf("starting readwritelarge\n");
788
789         cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
790
791         if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
792                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
793                 return False;
794         }
795
796         cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
797
798         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
799                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
800                 correct = False;
801         }
802
803         if (fsize == sizeof(buf))
804                 printf("readwritelarge test 1 succeeded (size = %lx)\n", 
805                        (unsigned long)fsize);
806         else {
807                 printf("readwritelarge test 1 failed (size = %lx)\n", 
808                        (unsigned long)fsize);
809                 correct = False;
810         }
811
812         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
813                 printf("close failed (%s)\n", cli_errstr(cli1));
814                 correct = False;
815         }
816
817         if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
818                 printf("unlink failed (%s)\n", cli_errstr(cli1));
819                 correct = False;
820         }
821
822         if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
823                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
824                 return False;
825         }
826
827         cli1->max_xmit = 4*1024;
828
829         cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
830
831         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
832                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
833                 correct = False;
834         }
835
836         if (fsize == sizeof(buf))
837                 printf("readwritelarge test 2 succeeded (size = %lx)\n", 
838                        (unsigned long)fsize);
839         else {
840                 printf("readwritelarge test 2 failed (size = %lx)\n", 
841                        (unsigned long)fsize);
842                 correct = False;
843         }
844
845 #if 0
846         /* ToDo - set allocation. JRA */
847         if(!cli_set_allocation_size(cli1, fnum1, 0)) {
848                 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
849                 return False;
850         }
851         if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
852                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
853                 correct = False;
854         }
855         if (fsize != 0)
856                 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
857 #endif
858
859         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
860                 printf("close failed (%s)\n", cli_errstr(cli1));
861                 correct = False;
862         }
863
864         if (!torture_close_connection(cli1)) {
865                 correct = False;
866         }
867         return correct;
868 }
869
870 int line_count = 0;
871 int nbio_id;
872
873 #define ival(s) strtol(s, NULL, 0)
874
875 /* run a test that simulates an approximate netbench client load */
876 static bool run_netbench(int client)
877 {
878         struct cli_state *cli;
879         int i;
880         char line[1024];
881         char cname[20];
882         FILE *f;
883         const char *params[20];
884         bool correct = True;
885
886         cli = current_cli;
887
888         nbio_id = client;
889
890         cli_sockopt(cli, sockops);
891
892         nb_setup(cli);
893
894         slprintf(cname,sizeof(cname)-1, "client%d", client);
895
896         f = fopen(client_txt, "r");
897
898         if (!f) {
899                 perror(client_txt);
900                 return False;
901         }
902
903         while (fgets(line, sizeof(line)-1, f)) {
904                 char *saveptr;
905                 line_count++;
906
907                 line[strlen(line)-1] = 0;
908
909                 /* printf("[%d] %s\n", line_count, line); */
910
911                 all_string_sub(line,"client1", cname, sizeof(line));
912
913                 /* parse the command parameters */
914                 params[0] = strtok_r(line, " ", &saveptr);
915                 i = 0;
916                 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
917
918                 params[i] = "";
919
920                 if (i < 2) continue;
921
922                 if (!strncmp(params[0],"SMB", 3)) {
923                         printf("ERROR: You are using a dbench 1 load file\n");
924                         exit(1);
925                 }
926
927                 if (!strcmp(params[0],"NTCreateX")) {
928                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
929                                    ival(params[4]));
930                 } else if (!strcmp(params[0],"Close")) {
931                         nb_close(ival(params[1]));
932                 } else if (!strcmp(params[0],"Rename")) {
933                         nb_rename(params[1], params[2]);
934                 } else if (!strcmp(params[0],"Unlink")) {
935                         nb_unlink(params[1]);
936                 } else if (!strcmp(params[0],"Deltree")) {
937                         nb_deltree(params[1]);
938                 } else if (!strcmp(params[0],"Rmdir")) {
939                         nb_rmdir(params[1]);
940                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
941                         nb_qpathinfo(params[1]);
942                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
943                         nb_qfileinfo(ival(params[1]));
944                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
945                         nb_qfsinfo(ival(params[1]));
946                 } else if (!strcmp(params[0],"FIND_FIRST")) {
947                         nb_findfirst(params[1]);
948                 } else if (!strcmp(params[0],"WriteX")) {
949                         nb_writex(ival(params[1]), 
950                                   ival(params[2]), ival(params[3]), ival(params[4]));
951                 } else if (!strcmp(params[0],"ReadX")) {
952                         nb_readx(ival(params[1]), 
953                                   ival(params[2]), ival(params[3]), ival(params[4]));
954                 } else if (!strcmp(params[0],"Flush")) {
955                         nb_flush(ival(params[1]));
956                 } else {
957                         printf("Unknown operation %s\n", params[0]);
958                         exit(1);
959                 }
960         }
961         fclose(f);
962
963         nb_cleanup();
964
965         if (!torture_close_connection(cli)) {
966                 correct = False;
967         }
968
969         return correct;
970 }
971
972
973 /* run a test that simulates an approximate netbench client load */
974 static bool run_nbench(int dummy)
975 {
976         double t;
977         bool correct = True;
978
979         nbio_shmem(nprocs);
980
981         nbio_id = -1;
982
983         signal(SIGALRM, nb_alarm);
984         alarm(1);
985         t = create_procs(run_netbench, &correct);
986         alarm(0);
987
988         printf("\nThroughput %g MB/sec\n", 
989                1.0e-6 * nbio_total() / t);
990         return correct;
991 }
992
993
994 /*
995   This test checks for two things:
996
997   1) correct support for retaining locks over a close (ie. the server
998      must not use posix semantics)
999   2) support for lock timeouts
1000  */
1001 static bool run_locktest1(int dummy)
1002 {
1003         struct cli_state *cli1, *cli2;
1004         const char *fname = "\\lockt1.lck";
1005         uint16_t fnum1, fnum2, fnum3;
1006         time_t t1, t2;
1007         unsigned lock_timeout;
1008
1009         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1010                 return False;
1011         }
1012         cli_sockopt(cli1, sockops);
1013         cli_sockopt(cli2, sockops);
1014
1015         printf("starting locktest1\n");
1016
1017         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1018
1019         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1020                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1021                 return False;
1022         }
1023         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1024                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1025                 return False;
1026         }
1027         if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1028                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1029                 return False;
1030         }
1031
1032         if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1033                 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1034                 return False;
1035         }
1036
1037
1038         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1039                 printf("lock2 succeeded! This is a locking bug\n");
1040                 return False;
1041         } else {
1042                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1043                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1044         }
1045
1046
1047         lock_timeout = (1 + (random() % 20));
1048         printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1049         t1 = time(NULL);
1050         if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1051                 printf("lock3 succeeded! This is a locking bug\n");
1052                 return False;
1053         } else {
1054                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1055                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1056         }
1057         t2 = time(NULL);
1058
1059         if (ABS(t2 - t1) < lock_timeout-1) {
1060                 printf("error: This server appears not to support timed lock requests\n");
1061         }
1062
1063         printf("server slept for %u seconds for a %u second timeout\n",
1064                (unsigned int)(t2-t1), lock_timeout);
1065
1066         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1067                 printf("close1 failed (%s)\n", cli_errstr(cli1));
1068                 return False;
1069         }
1070
1071         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1072                 printf("lock4 succeeded! This is a locking bug\n");
1073                 return False;
1074         } else {
1075                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1076                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1077         }
1078
1079         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1080                 printf("close2 failed (%s)\n", cli_errstr(cli1));
1081                 return False;
1082         }
1083
1084         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1085                 printf("close3 failed (%s)\n", cli_errstr(cli2));
1086                 return False;
1087         }
1088
1089         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1090                 printf("unlink failed (%s)\n", cli_errstr(cli1));
1091                 return False;
1092         }
1093
1094
1095         if (!torture_close_connection(cli1)) {
1096                 return False;
1097         }
1098
1099         if (!torture_close_connection(cli2)) {
1100                 return False;
1101         }
1102
1103         printf("Passed locktest1\n");
1104         return True;
1105 }
1106
1107 /*
1108   this checks to see if a secondary tconx can use open files from an
1109   earlier tconx
1110  */
1111 static bool run_tcon_test(int dummy)
1112 {
1113         static struct cli_state *cli;
1114         const char *fname = "\\tcontest.tmp";
1115         uint16 fnum1;
1116         uint16 cnum1, cnum2, cnum3;
1117         uint16 vuid1, vuid2;
1118         char buf[4];
1119         bool ret = True;
1120         NTSTATUS status;
1121
1122         memset(buf, '\0', sizeof(buf));
1123
1124         if (!torture_open_connection(&cli, 0)) {
1125                 return False;
1126         }
1127         cli_sockopt(cli, sockops);
1128
1129         printf("starting tcontest\n");
1130
1131         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1132
1133         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1134                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1135                 return False;
1136         }
1137
1138         cnum1 = cli->cnum;
1139         vuid1 = cli->vuid;
1140
1141         if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1142                 printf("initial write failed (%s)", cli_errstr(cli));
1143                 return False;
1144         }
1145
1146         status = cli_tcon_andx(cli, share, "?????",
1147                                password, strlen(password)+1);
1148         if (!NT_STATUS_IS_OK(status)) {
1149                 printf("%s refused 2nd tree connect (%s)\n", host,
1150                        nt_errstr(status));
1151                 cli_shutdown(cli);
1152                 return False;
1153         }
1154
1155         cnum2 = cli->cnum;
1156         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1157         vuid2 = cli->vuid + 1;
1158
1159         /* try a write with the wrong tid */
1160         cli->cnum = cnum2;
1161
1162         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1163                 printf("* server allows write with wrong TID\n");
1164                 ret = False;
1165         } else {
1166                 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1167         }
1168
1169
1170         /* try a write with an invalid tid */
1171         cli->cnum = cnum3;
1172
1173         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1174                 printf("* server allows write with invalid TID\n");
1175                 ret = False;
1176         } else {
1177                 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1178         }
1179
1180         /* try a write with an invalid vuid */
1181         cli->vuid = vuid2;
1182         cli->cnum = cnum1;
1183
1184         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1185                 printf("* server allows write with invalid VUID\n");
1186                 ret = False;
1187         } else {
1188                 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1189         }
1190
1191         cli->cnum = cnum1;
1192         cli->vuid = vuid1;
1193
1194         if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1195                 printf("close failed (%s)\n", cli_errstr(cli));
1196                 return False;
1197         }
1198
1199         cli->cnum = cnum2;
1200
1201         status = cli_tdis(cli);
1202         if (!NT_STATUS_IS_OK(status)) {
1203                 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1204                 return False;
1205         }
1206
1207         cli->cnum = cnum1;
1208
1209         if (!torture_close_connection(cli)) {
1210                 return False;
1211         }
1212
1213         return ret;
1214 }
1215
1216
1217 /*
1218  checks for old style tcon support
1219  */
1220 static bool run_tcon2_test(int dummy)
1221 {
1222         static struct cli_state *cli;
1223         uint16 cnum, max_xmit;
1224         char *service;
1225         NTSTATUS status;
1226
1227         if (!torture_open_connection(&cli, 0)) {
1228                 return False;
1229         }
1230         cli_sockopt(cli, sockops);
1231
1232         printf("starting tcon2 test\n");
1233
1234         if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1235                 return false;
1236         }
1237
1238         status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1239
1240         if (!NT_STATUS_IS_OK(status)) {
1241                 printf("tcon2 failed : %s\n", cli_errstr(cli));
1242         } else {
1243                 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n", 
1244                        (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1245         }
1246
1247         if (!torture_close_connection(cli)) {
1248                 return False;
1249         }
1250
1251         printf("Passed tcon2 test\n");
1252         return True;
1253 }
1254
1255 static bool tcon_devtest(struct cli_state *cli,
1256                          const char *myshare, const char *devtype,
1257                          const char *return_devtype,
1258                          NTSTATUS expected_error)
1259 {
1260         NTSTATUS status;
1261         bool ret;
1262
1263         status = cli_tcon_andx(cli, myshare, devtype,
1264                                password, strlen(password)+1);
1265
1266         if (NT_STATUS_IS_OK(expected_error)) {
1267                 if (NT_STATUS_IS_OK(status)) {
1268                         if (strcmp(cli->dev, return_devtype) == 0) {
1269                                 ret = True;
1270                         } else { 
1271                                 printf("tconX to share %s with type %s "
1272                                        "succeeded but returned the wrong "
1273                                        "device type (got [%s] but should have got [%s])\n",
1274                                        myshare, devtype, cli->dev, return_devtype);
1275                                 ret = False;
1276                         }
1277                 } else {
1278                         printf("tconX to share %s with type %s "
1279                                "should have succeeded but failed\n",
1280                                myshare, devtype);
1281                         ret = False;
1282                 }
1283                 cli_tdis(cli);
1284         } else {
1285                 if (NT_STATUS_IS_OK(status)) {
1286                         printf("tconx to share %s with type %s "
1287                                "should have failed but succeeded\n",
1288                                myshare, devtype);
1289                         ret = False;
1290                 } else {
1291                         if (NT_STATUS_EQUAL(cli_nt_error(cli),
1292                                             expected_error)) {
1293                                 ret = True;
1294                         } else {
1295                                 printf("Returned unexpected error\n");
1296                                 ret = False;
1297                         }
1298                 }
1299         }
1300         return ret;
1301 }
1302
1303 /*
1304  checks for correct tconX support
1305  */
1306 static bool run_tcon_devtype_test(int dummy)
1307 {
1308         static struct cli_state *cli1 = NULL;
1309         bool retry;
1310         int flags = 0;
1311         NTSTATUS status;
1312         bool ret = True;
1313
1314         status = cli_full_connection(&cli1, myname,
1315                                      host, NULL, port_to_use,
1316                                      NULL, NULL,
1317                                      username, workgroup,
1318                                      password, flags, Undefined, &retry);
1319
1320         if (!NT_STATUS_IS_OK(status)) {
1321                 printf("could not open connection\n");
1322                 return False;
1323         }
1324
1325         if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1326                 ret = False;
1327
1328         if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1329                 ret = False;
1330
1331         if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1332                 ret = False;
1333
1334         if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1335                 ret = False;
1336
1337         if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1338                 ret = False;
1339
1340         if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1341                 ret = False;
1342
1343         if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1344                 ret = False;
1345
1346         if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1347                 ret = False;
1348
1349         if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1350                 ret = False;
1351
1352         if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1353                 ret = False;
1354
1355         cli_shutdown(cli1);
1356
1357         if (ret)
1358                 printf("Passed tcondevtest\n");
1359
1360         return ret;
1361 }
1362
1363
1364 /*
1365   This test checks that 
1366
1367   1) the server supports multiple locking contexts on the one SMB
1368   connection, distinguished by PID.  
1369
1370   2) the server correctly fails overlapping locks made by the same PID (this
1371      goes against POSIX behaviour, which is why it is tricky to implement)
1372
1373   3) the server denies unlock requests by an incorrect client PID
1374 */
1375 static bool run_locktest2(int dummy)
1376 {
1377         static struct cli_state *cli;
1378         const char *fname = "\\lockt2.lck";
1379         uint16_t fnum1, fnum2, fnum3;
1380         bool correct = True;
1381
1382         if (!torture_open_connection(&cli, 0)) {
1383                 return False;
1384         }
1385
1386         cli_sockopt(cli, sockops);
1387
1388         printf("starting locktest2\n");
1389
1390         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1391
1392         cli_setpid(cli, 1);
1393
1394         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1395                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1396                 return False;
1397         }
1398
1399         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1400                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1401                 return False;
1402         }
1403
1404         cli_setpid(cli, 2);
1405
1406         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1407                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1408                 return False;
1409         }
1410
1411         cli_setpid(cli, 1);
1412
1413         if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1414                 printf("lock1 failed (%s)\n", cli_errstr(cli));
1415                 return False;
1416         }
1417
1418         if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1419                 printf("WRITE lock1 succeeded! This is a locking bug\n");
1420                 correct = False;
1421         } else {
1422                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1423                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1424         }
1425
1426         if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1427                 printf("WRITE lock2 succeeded! This is a locking bug\n");
1428                 correct = False;
1429         } else {
1430                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1431                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1432         }
1433
1434         if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1435                 printf("READ lock2 succeeded! This is a locking bug\n");
1436                 correct = False;
1437         } else {
1438                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1439                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1440         }
1441
1442         if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1443                 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1444         }
1445         cli_setpid(cli, 2);
1446         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1447                 printf("unlock at 100 succeeded! This is a locking bug\n");
1448                 correct = False;
1449         }
1450
1451         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1452                 printf("unlock1 succeeded! This is a locking bug\n");
1453                 correct = False;
1454         } else {
1455                 if (!check_error(__LINE__, cli, 
1456                                  ERRDOS, ERRlock, 
1457                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1458         }
1459
1460         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1461                 printf("unlock2 succeeded! This is a locking bug\n");
1462                 correct = False;
1463         } else {
1464                 if (!check_error(__LINE__, cli, 
1465                                  ERRDOS, ERRlock, 
1466                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1467         }
1468
1469         if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1470                 printf("lock3 succeeded! This is a locking bug\n");
1471                 correct = False;
1472         } else {
1473                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1474         }
1475
1476         cli_setpid(cli, 1);
1477
1478         if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1479                 printf("close1 failed (%s)\n", cli_errstr(cli));
1480                 return False;
1481         }
1482
1483         if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1484                 printf("close2 failed (%s)\n", cli_errstr(cli));
1485                 return False;
1486         }
1487
1488         if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1489                 printf("close3 failed (%s)\n", cli_errstr(cli));
1490                 return False;
1491         }
1492
1493         if (!torture_close_connection(cli)) {
1494                 correct = False;
1495         }
1496
1497         printf("locktest2 finished\n");
1498
1499         return correct;
1500 }
1501
1502
1503 /*
1504   This test checks that 
1505
1506   1) the server supports the full offset range in lock requests
1507 */
1508 static bool run_locktest3(int dummy)
1509 {
1510         static struct cli_state *cli1, *cli2;
1511         const char *fname = "\\lockt3.lck";
1512         uint16_t fnum1, fnum2;
1513         int i;
1514         uint32 offset;
1515         bool correct = True;
1516
1517 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1518
1519         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1520                 return False;
1521         }
1522         cli_sockopt(cli1, sockops);
1523         cli_sockopt(cli2, sockops);
1524
1525         printf("starting locktest3\n");
1526
1527         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1528
1529         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1530                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1531                 return False;
1532         }
1533         if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1534                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1535                 return False;
1536         }
1537
1538         for (offset=i=0;i<torture_numops;i++) {
1539                 NEXT_OFFSET;
1540                 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1541                         printf("lock1 %d failed (%s)\n", 
1542                                i,
1543                                cli_errstr(cli1));
1544                         return False;
1545                 }
1546
1547                 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1548                         printf("lock2 %d failed (%s)\n", 
1549                                i,
1550                                cli_errstr(cli1));
1551                         return False;
1552                 }
1553         }
1554
1555         for (offset=i=0;i<torture_numops;i++) {
1556                 NEXT_OFFSET;
1557
1558                 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1559                         printf("error: lock1 %d succeeded!\n", i);
1560                         return False;
1561                 }
1562
1563                 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1564                         printf("error: lock2 %d succeeded!\n", i);
1565                         return False;
1566                 }
1567
1568                 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1569                         printf("error: lock3 %d succeeded!\n", i);
1570                         return False;
1571                 }
1572
1573                 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1574                         printf("error: lock4 %d succeeded!\n", i);
1575                         return False;
1576                 }
1577         }
1578
1579         for (offset=i=0;i<torture_numops;i++) {
1580                 NEXT_OFFSET;
1581
1582                 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1583                         printf("unlock1 %d failed (%s)\n", 
1584                                i,
1585                                cli_errstr(cli1));
1586                         return False;
1587                 }
1588
1589                 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1590                         printf("unlock2 %d failed (%s)\n", 
1591                                i,
1592                                cli_errstr(cli1));
1593                         return False;
1594                 }
1595         }
1596
1597         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1598                 printf("close1 failed (%s)\n", cli_errstr(cli1));
1599                 return False;
1600         }
1601
1602         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1603                 printf("close2 failed (%s)\n", cli_errstr(cli2));
1604                 return False;
1605         }
1606
1607         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1608                 printf("unlink failed (%s)\n", cli_errstr(cli1));
1609                 return False;
1610         }
1611
1612         if (!torture_close_connection(cli1)) {
1613                 correct = False;
1614         }
1615
1616         if (!torture_close_connection(cli2)) {
1617                 correct = False;
1618         }
1619
1620         printf("finished locktest3\n");
1621
1622         return correct;
1623 }
1624
1625 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1626         printf("** "); correct = False; \
1627         }
1628
1629 /*
1630   looks at overlapping locks
1631 */
1632 static bool run_locktest4(int dummy)
1633 {
1634         static struct cli_state *cli1, *cli2;
1635         const char *fname = "\\lockt4.lck";
1636         uint16_t fnum1, fnum2, f;
1637         bool ret;
1638         char buf[1000];
1639         bool correct = True;
1640
1641         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1642                 return False;
1643         }
1644
1645         cli_sockopt(cli1, sockops);
1646         cli_sockopt(cli2, sockops);
1647
1648         printf("starting locktest4\n");
1649
1650         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1651
1652         cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1653         cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1654
1655         memset(buf, 0, sizeof(buf));
1656
1657         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1658                 printf("Failed to create file\n");
1659                 correct = False;
1660                 goto fail;
1661         }
1662
1663         ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1664               cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1665         EXPECTED(ret, False);
1666         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1667
1668         ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1669               cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1670         EXPECTED(ret, True);
1671         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1672
1673         ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1674               cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1675         EXPECTED(ret, False);
1676         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1677
1678         ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1679               cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1680         EXPECTED(ret, True);
1681         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1682
1683         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1684               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1685         EXPECTED(ret, False);
1686         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1687
1688         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1689               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1690         EXPECTED(ret, True);
1691         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1692
1693         ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1694               cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1695         EXPECTED(ret, True);
1696         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1697
1698         ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1699               cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1700         EXPECTED(ret, False);
1701         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1702
1703         ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1704               cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1705         EXPECTED(ret, False);
1706         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1707
1708         ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1709               cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1710         EXPECTED(ret, True);
1711         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1712
1713         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1714               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1715         EXPECTED(ret, False);
1716         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1717
1718         ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1719               cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1720               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1721         EXPECTED(ret, False);
1722         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1723
1724
1725         ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1726               (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1727         EXPECTED(ret, False);
1728         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1729
1730         ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1731               (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1732         EXPECTED(ret, False);
1733         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1734
1735
1736         ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1737               cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1738               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1739               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1740         EXPECTED(ret, True);
1741         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1742
1743
1744         ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1745               cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1746               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1747               (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1748               !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1749               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1750         EXPECTED(ret, True);
1751         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1752
1753         ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1754               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1755               (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&          
1756               (cli_read(cli2, fnum2, buf, 160, 4) == 4);                
1757         EXPECTED(ret, True);
1758         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1759
1760         ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1761               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1762               (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&          
1763               (cli_read(cli2, fnum2, buf, 170, 4) == 4);                
1764         EXPECTED(ret, True);
1765         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1766
1767         ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1768               cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1769               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1770               !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&         
1771               (cli_read(cli2, fnum2, buf, 190, 4) == 4);                
1772         EXPECTED(ret, True);
1773         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1774
1775         cli_close(cli1, fnum1);
1776         cli_close(cli2, fnum2);
1777         cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1778         cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1779         ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1780               cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1781               NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1782               NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1783               cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1784         cli_close(cli1, f);
1785         cli_close(cli1, fnum1);
1786         EXPECTED(ret, True);
1787         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1788
1789  fail:
1790         cli_close(cli1, fnum1);
1791         cli_close(cli2, fnum2);
1792         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1793         torture_close_connection(cli1);
1794         torture_close_connection(cli2);
1795
1796         printf("finished locktest4\n");
1797         return correct;
1798 }
1799
1800 /*
1801   looks at lock upgrade/downgrade.
1802 */
1803 static bool run_locktest5(int dummy)
1804 {
1805         static struct cli_state *cli1, *cli2;
1806         const char *fname = "\\lockt5.lck";
1807         uint16_t fnum1, fnum2, fnum3;
1808         bool ret;
1809         char buf[1000];
1810         bool correct = True;
1811
1812         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1813                 return False;
1814         }
1815
1816         cli_sockopt(cli1, sockops);
1817         cli_sockopt(cli2, sockops);
1818
1819         printf("starting locktest5\n");
1820
1821         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1822
1823         cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1824         cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1825         cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1826
1827         memset(buf, 0, sizeof(buf));
1828
1829         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1830                 printf("Failed to create file\n");
1831                 correct = False;
1832                 goto fail;
1833         }
1834
1835         /* Check for NT bug... */
1836         ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1837                   cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1838         cli_close(cli1, fnum1);
1839         cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1840         ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1841         EXPECTED(ret, True);
1842         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1843         cli_close(cli1, fnum1);
1844         cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1845         cli_unlock(cli1, fnum3, 0, 1);
1846
1847         ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1848               cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1849         EXPECTED(ret, True);
1850         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1851
1852         ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1853         EXPECTED(ret, False);
1854
1855         printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1856
1857         /* Unlock the process 2 lock. */
1858         cli_unlock(cli2, fnum2, 0, 4);
1859
1860         ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1861         EXPECTED(ret, False);
1862
1863         printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1864
1865         /* Unlock the process 1 fnum3 lock. */
1866         cli_unlock(cli1, fnum3, 0, 4);
1867
1868         /* Stack 2 more locks here. */
1869         ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1870                   cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1871
1872         EXPECTED(ret, True);
1873         printf("the same process %s stack read locks\n", ret?"can":"cannot");
1874
1875         /* Unlock the first process lock, then check this was the WRITE lock that was
1876                 removed. */
1877
1878         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1879                         cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1880
1881         EXPECTED(ret, True);
1882         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1883
1884         /* Unlock the process 2 lock. */
1885         cli_unlock(cli2, fnum2, 0, 4);
1886
1887         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1888
1889         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
1890                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1891                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1892
1893         EXPECTED(ret, True);
1894         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
1895
1896         /* Ensure the next unlock fails. */
1897         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1898         EXPECTED(ret, False);
1899         printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
1900
1901         /* Ensure connection 2 can get a write lock. */
1902         ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1903         EXPECTED(ret, True);
1904
1905         printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1906
1907
1908  fail:
1909         cli_close(cli1, fnum1);
1910         cli_close(cli2, fnum2);
1911         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1912         if (!torture_close_connection(cli1)) {
1913                 correct = False;
1914         }
1915         if (!torture_close_connection(cli2)) {
1916                 correct = False;
1917         }
1918
1919         printf("finished locktest5\n");
1920
1921         return correct;
1922 }
1923
1924 /*
1925   tries the unusual lockingX locktype bits
1926 */
1927 static bool run_locktest6(int dummy)
1928 {
1929         static struct cli_state *cli;
1930         const char *fname[1] = { "\\lock6.txt" };
1931         int i;
1932         uint16_t fnum;
1933         NTSTATUS status;
1934
1935         if (!torture_open_connection(&cli, 0)) {
1936                 return False;
1937         }
1938
1939         cli_sockopt(cli, sockops);
1940
1941         printf("starting locktest6\n");
1942
1943         for (i=0;i<1;i++) {
1944                 printf("Testing %s\n", fname[i]);
1945
1946                 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1947
1948                 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
1949                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1950                 cli_close(cli, fnum);
1951                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1952
1953                 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
1954                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1955                 cli_close(cli, fnum);
1956                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1957
1958                 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1959         }
1960
1961         torture_close_connection(cli);
1962
1963         printf("finished locktest6\n");
1964         return True;
1965 }
1966
1967 static bool run_locktest7(int dummy)
1968 {
1969         struct cli_state *cli1;
1970         const char *fname = "\\lockt7.lck";
1971         uint16_t fnum1;
1972         char buf[200];
1973         bool correct = False;
1974
1975         if (!torture_open_connection(&cli1, 0)) {
1976                 return False;
1977         }
1978
1979         cli_sockopt(cli1, sockops);
1980
1981         printf("starting locktest7\n");
1982
1983         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1984
1985         cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1986
1987         memset(buf, 0, sizeof(buf));
1988
1989         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1990                 printf("Failed to create file\n");
1991                 goto fail;
1992         }
1993
1994         cli_setpid(cli1, 1);
1995
1996         if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1997                 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1998                 goto fail;
1999         } else {
2000                 printf("pid1 successfully locked range 130:4 for READ\n");
2001         }
2002
2003         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2004                 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2005                 goto fail;
2006         } else {
2007                 printf("pid1 successfully read the range 130:4\n");
2008         }
2009
2010         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2011                 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2012                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2013                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2014                         goto fail;
2015                 }
2016         } else {
2017                 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2018                 goto fail;
2019         }
2020
2021         cli_setpid(cli1, 2);
2022
2023         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2024                 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2025         } else {
2026                 printf("pid2 successfully read the range 130:4\n");
2027         }
2028
2029         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2030                 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2031                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2032                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2033                         goto fail;
2034                 }
2035         } else {
2036                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2037                 goto fail;
2038         }
2039
2040         cli_setpid(cli1, 1);
2041         cli_unlock(cli1, fnum1, 130, 4);
2042
2043         if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2044                 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2045                 goto fail;
2046         } else {
2047                 printf("pid1 successfully locked range 130:4 for WRITE\n");
2048         }
2049
2050         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2051                 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2052                 goto fail;
2053         } else {
2054                 printf("pid1 successfully read the range 130:4\n");
2055         }
2056
2057         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2058                 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2059                 goto fail;
2060         } else {
2061                 printf("pid1 successfully wrote to the range 130:4\n");
2062         }
2063
2064         cli_setpid(cli1, 2);
2065
2066         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2067                 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2068                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2069                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2070                         goto fail;
2071                 }
2072         } else {
2073                 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2074                 goto fail;
2075         }
2076
2077         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2078                 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2079                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2080                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2081                         goto fail;
2082                 }
2083         } else {
2084                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2085                 goto fail;
2086         }
2087
2088         cli_unlock(cli1, fnum1, 130, 0);
2089         correct = True;
2090
2091 fail:
2092         cli_close(cli1, fnum1);
2093         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2094         torture_close_connection(cli1);
2095
2096         printf("finished locktest7\n");
2097         return correct;
2098 }
2099
2100 /*
2101  * This demonstrates a problem with our use of GPFS share modes: A file
2102  * descriptor sitting in the pending close queue holding a GPFS share mode
2103  * blocks opening a file another time. Happens with Word 2007 temp files.
2104  * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2105  * open is denied with NT_STATUS_SHARING_VIOLATION.
2106  */
2107
2108 static bool run_locktest8(int dummy)
2109 {
2110         struct cli_state *cli1;
2111         const char *fname = "\\lockt8.lck";
2112         uint16_t fnum1, fnum2;
2113         char buf[200];
2114         bool correct = False;
2115         NTSTATUS status;
2116
2117         if (!torture_open_connection(&cli1, 0)) {
2118                 return False;
2119         }
2120
2121         cli_sockopt(cli1, sockops);
2122
2123         printf("starting locktest8\n");
2124
2125         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2126
2127         status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2128                           &fnum1);
2129         if (!NT_STATUS_IS_OK(status)) {
2130                 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2131                 return false;
2132         }
2133
2134         memset(buf, 0, sizeof(buf));
2135
2136         status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2137         if (!NT_STATUS_IS_OK(status)) {
2138                 d_fprintf(stderr, "cli_open second time returned %s\n",
2139                           cli_errstr(cli1));
2140                 goto fail;
2141         }
2142
2143         if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2144                 printf("Unable to apply read lock on range 1:1, error was "
2145                        "%s\n", cli_errstr(cli1));
2146                 goto fail;
2147         }
2148
2149         status = cli_close(cli1, fnum1);
2150         if (!NT_STATUS_IS_OK(status)) {
2151                 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2152                 goto fail;
2153         }
2154
2155         status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2156         if (!NT_STATUS_IS_OK(status)) {
2157                 d_fprintf(stderr, "cli_open third time returned %s\n",
2158                           cli_errstr(cli1));
2159                 goto fail;
2160         }
2161
2162         correct = true;
2163
2164 fail:
2165         cli_close(cli1, fnum1);
2166         cli_close(cli1, fnum2);
2167         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2168         torture_close_connection(cli1);
2169
2170         printf("finished locktest8\n");
2171         return correct;
2172 }
2173
2174 /*
2175  * This test is designed to be run in conjunction with
2176  * external NFS or POSIX locks taken in the filesystem.
2177  * It checks that the smbd server will block until the
2178  * lock is released and then acquire it. JRA.
2179  */
2180
2181 static bool got_alarm;
2182 static int alarm_fd;
2183
2184 static void alarm_handler(int dummy)
2185 {
2186         got_alarm = True;
2187 }
2188
2189 static void alarm_handler_parent(int dummy)
2190 {
2191         close(alarm_fd);
2192 }
2193
2194 static void do_local_lock(int read_fd, int write_fd)
2195 {
2196         int fd;
2197         char c = '\0';
2198         struct flock lock;
2199         const char *local_pathname = NULL;
2200         int ret;
2201
2202         local_pathname = talloc_asprintf(talloc_tos(),
2203                         "%s/lockt9.lck", local_path);
2204         if (!local_pathname) {
2205                 printf("child: alloc fail\n");
2206                 exit(1);
2207         }
2208
2209         unlink(local_pathname);
2210         fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2211         if (fd == -1) {
2212                 printf("child: open of %s failed %s.\n",
2213                         local_pathname, strerror(errno));
2214                 exit(1);
2215         }
2216
2217         /* Now take a fcntl lock. */
2218         lock.l_type = F_WRLCK;
2219         lock.l_whence = SEEK_SET;
2220         lock.l_start = 0;
2221         lock.l_len = 4;
2222         lock.l_pid = getpid();
2223
2224         ret = fcntl(fd,F_SETLK,&lock);
2225         if (ret == -1) {
2226                 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2227                         local_pathname, strerror(errno));
2228                 exit(1);
2229         } else {
2230                 printf("child: got lock 0:4 on file %s.\n",
2231                         local_pathname );
2232                 fflush(stdout);
2233         }
2234
2235         CatchSignal(SIGALRM, alarm_handler);
2236         alarm(5);
2237         /* Signal the parent. */
2238         if (write(write_fd, &c, 1) != 1) {
2239                 printf("child: start signal fail %s.\n",
2240                         strerror(errno));
2241                 exit(1);
2242         }
2243         alarm(0);
2244
2245         alarm(10);
2246         /* Wait for the parent to be ready. */
2247         if (read(read_fd, &c, 1) != 1) {
2248                 printf("child: reply signal fail %s.\n",
2249                         strerror(errno));
2250                 exit(1);
2251         }
2252         alarm(0);
2253
2254         sleep(5);
2255         close(fd);
2256         printf("child: released lock 0:4 on file %s.\n",
2257                 local_pathname );
2258         fflush(stdout);
2259         exit(0);
2260 }
2261
2262 static bool run_locktest9(int dummy)
2263 {
2264         struct cli_state *cli1;
2265         const char *fname = "\\lockt9.lck";
2266         uint16_t fnum;
2267         bool correct = False;
2268         int pipe_in[2], pipe_out[2];
2269         pid_t child_pid;
2270         char c = '\0';
2271         int ret;
2272         struct timeval start;
2273         double seconds;
2274         NTSTATUS status;
2275
2276         printf("starting locktest9\n");
2277
2278         if (local_path == NULL) {
2279                 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2280                 return false;
2281         }
2282
2283         if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2284                 return false;
2285         }
2286
2287         child_pid = fork();
2288         if (child_pid == -1) {
2289                 return false;
2290         }
2291
2292         if (child_pid == 0) {
2293                 /* Child. */
2294                 do_local_lock(pipe_out[0], pipe_in[1]);
2295                 exit(0);
2296         }
2297
2298         close(pipe_out[0]);
2299         close(pipe_in[1]);
2300         pipe_out[0] = -1;
2301         pipe_in[1] = -1;
2302
2303         /* Parent. */
2304         ret = read(pipe_in[0], &c, 1);
2305         if (ret != 1) {
2306                 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2307                         strerror(errno));
2308                 return false;
2309         }
2310
2311         if (!torture_open_connection(&cli1, 0)) {
2312                 return false;
2313         }
2314
2315         cli_sockopt(cli1, sockops);
2316
2317         status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2318                           &fnum);
2319         if (!NT_STATUS_IS_OK(status)) {
2320                 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2321                 return false;
2322         }
2323
2324         /* Ensure the child has the lock. */
2325         if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2326                 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2327                 goto fail;
2328         } else {
2329                 d_printf("Child has the lock.\n");
2330         }
2331
2332         /* Tell the child to wait 5 seconds then exit. */
2333         ret = write(pipe_out[1], &c, 1);
2334         if (ret != 1) {
2335                 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2336                         strerror(errno));
2337                 goto fail;
2338         }
2339
2340         /* Wait 20 seconds for the lock. */
2341         alarm_fd = cli1->fd;
2342         CatchSignal(SIGALRM, alarm_handler_parent);
2343         alarm(20);
2344
2345         start = timeval_current();
2346
2347         if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2348                 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2349                        "%s\n", cli_errstr(cli1));
2350                 goto fail_nofd;
2351         }
2352         alarm(0);
2353
2354         seconds = timeval_elapsed(&start);
2355
2356         printf("Parent got the lock after %.2f seconds.\n",
2357                 seconds);
2358
2359         status = cli_close(cli1, fnum);
2360         if (!NT_STATUS_IS_OK(status)) {
2361                 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2362                 goto fail;
2363         }
2364
2365         correct = true;
2366
2367 fail:
2368         cli_close(cli1, fnum);
2369         torture_close_connection(cli1);
2370
2371 fail_nofd:
2372
2373         printf("finished locktest9\n");
2374         return correct;
2375 }
2376
2377 /*
2378 test whether fnums and tids open on one VC are available on another (a major
2379 security hole)
2380 */
2381 static bool run_fdpasstest(int dummy)
2382 {
2383         struct cli_state *cli1, *cli2;
2384         const char *fname = "\\fdpass.tst";
2385         uint16_t fnum1;
2386         char buf[1024];
2387
2388         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2389                 return False;
2390         }
2391         cli_sockopt(cli1, sockops);
2392         cli_sockopt(cli2, sockops);
2393
2394         printf("starting fdpasstest\n");
2395
2396         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2397
2398         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2399                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2400                 return False;
2401         }
2402
2403         if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2404                 printf("write failed (%s)\n", cli_errstr(cli1));
2405                 return False;
2406         }
2407
2408         cli2->vuid = cli1->vuid;
2409         cli2->cnum = cli1->cnum;
2410         cli2->pid = cli1->pid;
2411
2412         if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2413                 printf("read succeeded! nasty security hole [%s]\n",
2414                        buf);
2415                 return False;
2416         }
2417
2418         cli_close(cli1, fnum1);
2419         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2420
2421         torture_close_connection(cli1);
2422         torture_close_connection(cli2);
2423
2424         printf("finished fdpasstest\n");
2425         return True;
2426 }
2427
2428 static bool run_fdsesstest(int dummy)
2429 {
2430         struct cli_state *cli;
2431         uint16 new_vuid;
2432         uint16 saved_vuid;
2433         uint16 new_cnum;
2434         uint16 saved_cnum;
2435         const char *fname = "\\fdsess.tst";
2436         const char *fname1 = "\\fdsess1.tst";
2437         uint16_t fnum1;
2438         uint16_t fnum2;
2439         char buf[1024];
2440         bool ret = True;
2441
2442         if (!torture_open_connection(&cli, 0))
2443                 return False;
2444         cli_sockopt(cli, sockops);
2445
2446         if (!torture_cli_session_setup2(cli, &new_vuid))
2447                 return False;
2448
2449         saved_cnum = cli->cnum;
2450         if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2451                 return False;
2452         new_cnum = cli->cnum;
2453         cli->cnum = saved_cnum;
2454
2455         printf("starting fdsesstest\n");
2456
2457         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2458         cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2459
2460         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2461                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2462                 return False;
2463         }
2464
2465         if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2466                 printf("write failed (%s)\n", cli_errstr(cli));
2467                 return False;
2468         }
2469
2470         saved_vuid = cli->vuid;
2471         cli->vuid = new_vuid;
2472
2473         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2474                 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2475                        buf);
2476                 ret = False;
2477         }
2478         /* Try to open a file with different vuid, samba cnum. */
2479         if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2480                 printf("create with different vuid, same cnum succeeded.\n");
2481                 cli_close(cli, fnum2);
2482                 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2483         } else {
2484                 printf("create with different vuid, same cnum failed.\n");
2485                 printf("This will cause problems with service clients.\n");
2486                 ret = False;
2487         }
2488
2489         cli->vuid = saved_vuid;
2490
2491         /* Try with same vuid, different cnum. */
2492         cli->cnum = new_cnum;
2493
2494         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2495                 printf("read succeeded with different cnum![%s]\n",
2496                        buf);
2497                 ret = False;
2498         }
2499
2500         cli->cnum = saved_cnum;
2501         cli_close(cli, fnum1);
2502         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2503
2504         torture_close_connection(cli);
2505
2506         printf("finished fdsesstest\n");
2507         return ret;
2508 }
2509
2510 /*
2511   This test checks that 
2512
2513   1) the server does not allow an unlink on a file that is open
2514 */
2515 static bool run_unlinktest(int dummy)
2516 {
2517         struct cli_state *cli;
2518         const char *fname = "\\unlink.tst";
2519         uint16_t fnum;
2520         bool correct = True;
2521
2522         if (!torture_open_connection(&cli, 0)) {
2523                 return False;
2524         }
2525
2526         cli_sockopt(cli, sockops);
2527
2528         printf("starting unlink test\n");
2529
2530         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2531
2532         cli_setpid(cli, 1);
2533
2534         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2535                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2536                 return False;
2537         }
2538
2539         if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2540                 printf("error: server allowed unlink on an open file\n");
2541                 correct = False;
2542         } else {
2543                 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare, 
2544                                       NT_STATUS_SHARING_VIOLATION);
2545         }
2546
2547         cli_close(cli, fnum);
2548         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2549
2550         if (!torture_close_connection(cli)) {
2551                 correct = False;
2552         }
2553
2554         printf("unlink test finished\n");
2555
2556         return correct;
2557 }
2558
2559
2560 /*
2561 test how many open files this server supports on the one socket
2562 */
2563 static bool run_maxfidtest(int dummy)
2564 {
2565         struct cli_state *cli;
2566         const char *ftemplate = "\\maxfid.%d.%d";
2567         fstring fname;
2568         uint16_t fnums[0x11000];
2569         int i;
2570         int retries=4;
2571         bool correct = True;
2572
2573         cli = current_cli;
2574
2575         if (retries <= 0) {
2576                 printf("failed to connect\n");
2577                 return False;
2578         }
2579
2580         cli_sockopt(cli, sockops);
2581
2582         for (i=0; i<0x11000; i++) {
2583                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2584                 if (!NT_STATUS_IS_OK(cli_open(cli, fname, 
2585                                         O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2586                         printf("open of %s failed (%s)\n", 
2587                                fname, cli_errstr(cli));
2588                         printf("maximum fnum is %d\n", i);
2589                         break;
2590                 }
2591                 printf("%6d\r", i);
2592         }
2593         printf("%6d\n", i);
2594         i--;
2595
2596         printf("cleaning up\n");
2597         for (;i>=0;i--) {
2598                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2599                 cli_close(cli, fnums[i]);
2600                 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2601                         printf("unlink of %s failed (%s)\n", 
2602                                fname, cli_errstr(cli));
2603                         correct = False;
2604                 }
2605                 printf("%6d\r", i);
2606         }
2607         printf("%6d\n", 0);
2608
2609         printf("maxfid test finished\n");
2610         if (!torture_close_connection(cli)) {
2611                 correct = False;
2612         }
2613         return correct;
2614 }
2615
2616 /* generate a random buffer */
2617 static void rand_buf(char *buf, int len)
2618 {
2619         while (len--) {
2620                 *buf = (char)sys_random();
2621                 buf++;
2622         }
2623 }
2624
2625 /* send smb negprot commands, not reading the response */
2626 static bool run_negprot_nowait(int dummy)
2627 {
2628         int i;
2629         static struct cli_state *cli;
2630         bool correct = True;
2631
2632         printf("starting negprot nowait test\n");
2633
2634         if (!(cli = open_nbt_connection())) {
2635                 return False;
2636         }
2637
2638         for (i=0;i<50000;i++) {
2639                 cli_negprot_sendsync(cli);
2640         }
2641
2642         if (!torture_close_connection(cli)) {
2643                 correct = False;
2644         }
2645
2646         printf("finished negprot nowait test\n");
2647
2648         return correct;
2649 }
2650
2651
2652 /* send random IPC commands */
2653 static bool run_randomipc(int dummy)
2654 {
2655         char *rparam = NULL;
2656         char *rdata = NULL;
2657         unsigned int rdrcnt,rprcnt;
2658         char param[1024];
2659         int api, param_len, i;
2660         struct cli_state *cli;
2661         bool correct = True;
2662         int count = 50000;
2663
2664         printf("starting random ipc test\n");
2665
2666         if (!torture_open_connection(&cli, 0)) {
2667                 return False;
2668         }
2669
2670         for (i=0;i<count;i++) {
2671                 api = sys_random() % 500;
2672                 param_len = (sys_random() % 64);
2673
2674                 rand_buf(param, param_len);
2675
2676                 SSVAL(param,0,api); 
2677
2678                 cli_api(cli, 
2679                         param, param_len, 8,  
2680                         NULL, 0, BUFFER_SIZE, 
2681                         &rparam, &rprcnt,     
2682                         &rdata, &rdrcnt);
2683                 if (i % 100 == 0) {
2684                         printf("%d/%d\r", i,count);
2685                 }
2686         }
2687         printf("%d/%d\n", i, count);
2688
2689         if (!torture_close_connection(cli)) {
2690                 correct = False;
2691         }
2692
2693         printf("finished random ipc test\n");
2694
2695         return correct;
2696 }
2697
2698
2699
2700 static void browse_callback(const char *sname, uint32 stype, 
2701                             const char *comment, void *state)
2702 {
2703         printf("\t%20.20s %08x %s\n", sname, stype, comment);
2704 }
2705
2706
2707
2708 /*
2709   This test checks the browse list code
2710
2711 */
2712 static bool run_browsetest(int dummy)
2713 {
2714         static struct cli_state *cli;
2715         bool correct = True;
2716
2717         printf("starting browse test\n");
2718
2719         if (!torture_open_connection(&cli, 0)) {
2720                 return False;
2721         }
2722
2723         printf("domain list:\n");
2724         cli_NetServerEnum(cli, cli->server_domain, 
2725                           SV_TYPE_DOMAIN_ENUM,
2726                           browse_callback, NULL);
2727
2728         printf("machine list:\n");
2729         cli_NetServerEnum(cli, cli->server_domain, 
2730                           SV_TYPE_ALL,
2731                           browse_callback, NULL);
2732
2733         if (!torture_close_connection(cli)) {
2734                 correct = False;
2735         }
2736
2737         printf("browse test finished\n");
2738
2739         return correct;
2740
2741 }
2742
2743
2744 /*
2745   This checks how the getatr calls works
2746 */
2747 static bool run_attrtest(int dummy)
2748 {
2749         struct cli_state *cli;
2750         uint16_t fnum;
2751         time_t t, t2;
2752         const char *fname = "\\attrib123456789.tst";
2753         bool correct = True;
2754
2755         printf("starting attrib test\n");
2756
2757         if (!torture_open_connection(&cli, 0)) {
2758                 return False;
2759         }
2760
2761         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2762         cli_open(cli, fname, 
2763                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2764         cli_close(cli, fnum);
2765         if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2766                 printf("getatr failed (%s)\n", cli_errstr(cli));
2767                 correct = False;
2768         }
2769
2770         if (abs(t - time(NULL)) > 60*60*24*10) {
2771                 printf("ERROR: SMBgetatr bug. time is %s",
2772                        ctime(&t));
2773                 t = time(NULL);
2774                 correct = True;
2775         }
2776
2777         t2 = t-60*60*24; /* 1 day ago */
2778
2779         if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2780                 printf("setatr failed (%s)\n", cli_errstr(cli));
2781                 correct = True;
2782         }
2783
2784         if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2785                 printf("getatr failed (%s)\n", cli_errstr(cli));
2786                 correct = True;
2787         }
2788
2789         if (t != t2) {
2790                 printf("ERROR: getatr/setatr bug. times are\n%s",
2791                        ctime(&t));
2792                 printf("%s", ctime(&t2));
2793                 correct = True;
2794         }
2795
2796         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2797
2798         if (!torture_close_connection(cli)) {
2799                 correct = False;
2800         }
2801
2802         printf("attrib test finished\n");
2803
2804         return correct;
2805 }
2806
2807
2808 /*
2809   This checks a couple of trans2 calls
2810 */
2811 static bool run_trans2test(int dummy)
2812 {
2813         struct cli_state *cli;
2814         uint16_t fnum;
2815         SMB_OFF_T size;
2816         time_t c_time, a_time, m_time;
2817         struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2818         const char *fname = "\\trans2.tst";
2819         const char *dname = "\\trans2";
2820         const char *fname2 = "\\trans2\\trans2.tst";
2821         char pname[1024];
2822         bool correct = True;
2823         NTSTATUS status;
2824         uint32_t fs_attr;
2825
2826         printf("starting trans2 test\n");
2827
2828         if (!torture_open_connection(&cli, 0)) {
2829                 return False;
2830         }
2831
2832         status = cli_get_fs_attr_info(cli, &fs_attr);
2833         if (!NT_STATUS_IS_OK(status)) {
2834                 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2835                        nt_errstr(status));
2836                 correct = false;
2837         }
2838
2839         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2840         cli_open(cli, fname, 
2841                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2842         if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2843                            &m_time_ts, NULL)) {
2844                 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2845                 correct = False;
2846         }
2847
2848         if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2849                 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2850                 correct = False;
2851         }
2852
2853         if (strcmp(pname, fname)) {
2854                 printf("qfilename gave different name? [%s] [%s]\n",
2855                        fname, pname);
2856                 correct = False;
2857         }
2858
2859         cli_close(cli, fnum);
2860
2861         sleep(2);
2862
2863         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2864         if (!NT_STATUS_IS_OK(cli_open(cli, fname, 
2865                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
2866                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2867                 return False;
2868         }
2869         cli_close(cli, fnum);
2870
2871         status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
2872                                 NULL);
2873         if (!NT_STATUS_IS_OK(status)) {
2874                 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
2875                 correct = False;
2876         } else {
2877                 if (c_time != m_time) {
2878                         printf("create time=%s", ctime(&c_time));
2879                         printf("modify time=%s", ctime(&m_time));
2880                         printf("This system appears to have sticky create times\n");
2881                 }
2882                 if (a_time % (60*60) == 0) {
2883                         printf("access time=%s", ctime(&a_time));
2884                         printf("This system appears to set a midnight access time\n");
2885                         correct = False;
2886                 }
2887
2888                 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2889                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2890                         correct = False;
2891                 }
2892         }
2893
2894
2895         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2896         cli_open(cli, fname, 
2897                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2898         cli_close(cli, fnum);
2899         status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2900                                 &m_time_ts, &size, NULL, NULL);
2901         if (!NT_STATUS_IS_OK(status)) {
2902                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2903                 correct = False;
2904         } else {
2905                 if (w_time_ts.tv_sec < 60*60*24*2) {
2906                         printf("write time=%s", ctime(&w_time_ts.tv_sec));
2907                         printf("This system appears to set a initial 0 write time\n");
2908                         correct = False;
2909                 }
2910         }
2911
2912         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2913
2914
2915         /* check if the server updates the directory modification time
2916            when creating a new file */
2917         if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
2918                 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2919                 correct = False;
2920         }
2921         sleep(3);
2922         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
2923                                 &w_time_ts, &m_time_ts, &size, NULL, NULL);
2924         if (!NT_STATUS_IS_OK(status)) {
2925                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2926                 correct = False;
2927         }
2928
2929         cli_open(cli, fname2, 
2930                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2931         cli_write(cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
2932         cli_close(cli, fnum);
2933         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
2934                                 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
2935         if (!NT_STATUS_IS_OK(status)) {
2936                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2937                 correct = False;
2938         } else {
2939                 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2940                     == 0) {
2941                         printf("This system does not update directory modification times\n");
2942                         correct = False;
2943                 }
2944         }
2945         cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
2946         cli_rmdir(cli, dname);
2947
2948         if (!torture_close_connection(cli)) {
2949                 correct = False;
2950         }
2951
2952         printf("trans2 test finished\n");
2953
2954         return correct;
2955 }
2956
2957 /*
2958   This checks new W2K calls.
2959 */
2960
2961 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2962 {
2963         char *buf = NULL;
2964         uint32 len;
2965         bool correct = True;
2966
2967         if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2968                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2969                 correct = False;
2970         } else {
2971                 printf("qfileinfo: level %d, len = %u\n", level, len);
2972                 dump_data(0, (uint8 *)buf, len);
2973                 printf("\n");
2974         }
2975         SAFE_FREE(buf);
2976         return correct;
2977 }
2978
2979 static bool run_w2ktest(int dummy)
2980 {
2981         struct cli_state *cli;
2982         uint16_t fnum;
2983         const char *fname = "\\w2ktest\\w2k.tst";
2984         int level;
2985         bool correct = True;
2986
2987         printf("starting w2k test\n");
2988
2989         if (!torture_open_connection(&cli, 0)) {
2990                 return False;
2991         }
2992
2993         cli_open(cli, fname, 
2994                         O_RDWR | O_CREAT , DENY_NONE, &fnum);
2995
2996         for (level = 1004; level < 1040; level++) {
2997                 new_trans(cli, fnum, level);
2998         }
2999
3000         cli_close(cli, fnum);
3001
3002         if (!torture_close_connection(cli)) {
3003                 correct = False;
3004         }
3005
3006         printf("w2k test finished\n");
3007
3008         return correct;
3009 }
3010
3011
3012 /*
3013   this is a harness for some oplock tests
3014  */
3015 static bool run_oplock1(int dummy)
3016 {
3017         struct cli_state *cli1;
3018         const char *fname = "\\lockt1.lck";
3019         uint16_t fnum1;
3020         bool correct = True;
3021
3022         printf("starting oplock test 1\n");
3023
3024         if (!torture_open_connection(&cli1, 0)) {
3025                 return False;
3026         }
3027
3028         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3029
3030         cli_sockopt(cli1, sockops);
3031
3032         cli1->use_oplocks = True;
3033
3034         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3035                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3036                 return False;
3037         }
3038
3039         cli1->use_oplocks = False;
3040
3041         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3042         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3043
3044         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3045                 printf("close2 failed (%s)\n", cli_errstr(cli1));
3046                 return False;
3047         }
3048
3049         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3050                 printf("unlink failed (%s)\n", cli_errstr(cli1));
3051                 return False;
3052         }
3053
3054         if (!torture_close_connection(cli1)) {
3055                 correct = False;
3056         }
3057
3058         printf("finished oplock test 1\n");
3059
3060         return correct;
3061 }
3062
3063 static bool run_oplock2(int dummy)
3064 {
3065         struct cli_state *cli1, *cli2;
3066         const char *fname = "\\lockt2.lck";
3067         uint16_t fnum1, fnum2;
3068         int saved_use_oplocks = use_oplocks;
3069         char buf[4];
3070         bool correct = True;
3071         volatile bool *shared_correct;
3072
3073         shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3074         *shared_correct = True;
3075
3076         use_level_II_oplocks = True;
3077         use_oplocks = True;
3078
3079         printf("starting oplock test 2\n");
3080
3081         if (!torture_open_connection(&cli1, 0)) {
3082                 use_level_II_oplocks = False;
3083                 use_oplocks = saved_use_oplocks;
3084                 return False;
3085         }
3086
3087         cli1->use_oplocks = True;
3088         cli1->use_level_II_oplocks = True;
3089
3090         if (!torture_open_connection(&cli2, 1)) {
3091                 use_level_II_oplocks = False;
3092                 use_oplocks = saved_use_oplocks;
3093                 return False;
3094         }
3095
3096         cli2->use_oplocks = True;
3097         cli2->use_level_II_oplocks = True;
3098
3099         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3100
3101         cli_sockopt(cli1, sockops);
3102         cli_sockopt(cli2, sockops);
3103
3104         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3105                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3106                 return False;
3107         }
3108
3109         /* Don't need the globals any more. */
3110         use_level_II_oplocks = False;
3111         use_oplocks = saved_use_oplocks;
3112
3113         if (fork() == 0) {
3114                 /* Child code */
3115                 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3116                         printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3117                         *shared_correct = False;
3118                         exit(0);
3119                 }
3120
3121                 sleep(2);
3122
3123                 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3124                         printf("close2 failed (%s)\n", cli_errstr(cli1));
3125                         *shared_correct = False;
3126                 }
3127
3128                 exit(0);
3129         }
3130
3131         sleep(2);
3132
3133         /* Ensure cli1 processes the break. Empty file should always return 0
3134          * bytes.  */
3135
3136         if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3137                 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3138                 correct = False;
3139         }
3140
3141         /* Should now be at level II. */
3142         /* Test if sending a write locks causes a break to none. */
3143
3144         if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3145                 printf("lock failed (%s)\n", cli_errstr(cli1));
3146                 correct = False;
3147         }
3148
3149         cli_unlock(cli1, fnum1, 0, 4);
3150
3151         sleep(2);
3152
3153         if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3154                 printf("lock failed (%s)\n", cli_errstr(cli1));
3155                 correct = False;
3156         }
3157
3158         cli_unlock(cli1, fnum1, 0, 4);
3159
3160         sleep(2);
3161
3162         cli_read(cli1, fnum1, buf, 0, 4);
3163
3164 #if 0
3165         if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3166                 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3167                 correct = False;
3168         }
3169 #endif
3170
3171         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3172                 printf("close1 failed (%s)\n", cli_errstr(cli1));
3173                 correct = False;
3174         }
3175
3176         sleep(4);
3177
3178         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3179                 printf("unlink failed (%s)\n", cli_errstr(cli1));
3180                 correct = False;
3181         }
3182
3183         if (!torture_close_connection(cli1)) {
3184                 correct = False;
3185         }
3186
3187         if (!*shared_correct) {
3188                 correct = False;
3189         }
3190
3191         printf("finished oplock test 2\n");
3192
3193         return correct;
3194 }
3195
3196 /* handler for oplock 3 tests */
3197 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3198 {
3199         printf("got oplock break fnum=%d level=%d\n",
3200                fnum, level);
3201         return cli_oplock_ack(cli, fnum, level);
3202 }
3203
3204 static bool run_oplock3(int dummy)
3205 {
3206         struct cli_state *cli;
3207         const char *fname = "\\oplockt3.dat";
3208         uint16_t fnum;
3209         char buf[4] = "abcd";
3210         bool correct = True;
3211         volatile bool *shared_correct;
3212
3213         shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3214         *shared_correct = True;
3215
3216         printf("starting oplock test 3\n");
3217
3218         if (fork() == 0) {
3219                 /* Child code */
3220                 use_oplocks = True;
3221                 use_level_II_oplocks = True;
3222                 if (!torture_open_connection(&cli, 0)) {
3223                         *shared_correct = False;
3224                         exit(0);
3225                 } 
3226                 sleep(2);
3227                 /* try to trigger a oplock break in parent */
3228                 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3229                 cli_write(cli, fnum, 0, buf, 0, 4);
3230                 exit(0);
3231         }
3232
3233         /* parent code */
3234         use_oplocks = True;
3235         use_level_II_oplocks = True;
3236         if (!torture_open_connection(&cli, 1)) { /* other is forked */
3237                 return False;
3238         }
3239         cli_oplock_handler(cli, oplock3_handler);
3240         cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3241         cli_write(cli, fnum, 0, buf, 0, 4);
3242         cli_close(cli, fnum);
3243         cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3244         cli->timeout = 20000;
3245         cli_receive_smb(cli);
3246         printf("finished oplock test 3\n");
3247
3248         return (correct && *shared_correct);
3249
3250 /* What are we looking for here?  What's sucess and what's FAILURE? */
3251 }
3252
3253
3254
3255 /*
3256   Test delete on close semantics.
3257  */
3258 static bool run_deletetest(int dummy)
3259 {
3260         struct cli_state *cli1 = NULL;
3261         struct cli_state *cli2 = NULL;
3262         const char *fname = "\\delete.file";
3263         uint16_t fnum1 = (uint16_t)-1;
3264         uint16_t fnum2 = (uint16_t)-1;
3265         bool correct = True;
3266
3267         printf("starting delete test\n");
3268
3269         if (!torture_open_connection(&cli1, 0)) {
3270                 return False;
3271         }
3272
3273         cli_sockopt(cli1, sockops);
3274
3275         /* Test 1 - this should delete the file on close. */
3276
3277         cli_setatr(cli1, fname, 0, 0);
3278         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3279
3280         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3281                                    0, FILE_OVERWRITE_IF, 
3282                                    FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3283                 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3284                 correct = False;
3285                 goto fail;
3286         }
3287
3288 #if 0 /* JRATEST */
3289         {
3290                 uint32 *accinfo = NULL;
3291                 uint32 len;
3292                 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3293                 if (accinfo)
3294                         printf("access mode = 0x%lx\n", *accinfo);
3295                 SAFE_FREE(accinfo);
3296         }
3297 #endif
3298
3299         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3300                 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3301                 correct = False;
3302                 goto fail;
3303         }
3304
3305         if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3306                 printf("[1] open of %s succeeded (should fail)\n", fname);
3307                 correct = False;
3308                 goto fail;
3309         }
3310
3311         printf("first delete on close test succeeded.\n");
3312
3313         /* Test 2 - this should delete the file on close. */
3314
3315         cli_setatr(cli1, fname, 0, 0);
3316         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3317
3318         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3319                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, 
3320                                    FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3321                 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3322                 correct = False;
3323                 goto fail;
3324         }
3325
3326         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3327                 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3328                 correct = False;
3329                 goto fail;
3330         }
3331
3332         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3333                 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3334                 correct = False;
3335                 goto fail;
3336         }
3337
3338         if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3339                 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3340                 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3341                         printf("[2] close failed (%s)\n", cli_errstr(cli1));
3342                         correct = False;
3343                         goto fail;
3344                 }
3345                 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3346         } else
3347                 printf("second delete on close test succeeded.\n");
3348
3349         /* Test 3 - ... */
3350         cli_setatr(cli1, fname, 0, 0);
3351         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3352
3353         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3354                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3355                 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3356                 correct = False;
3357                 goto fail;
3358         }
3359
3360         /* This should fail with a sharing violation - open for delete is only compatible
3361            with SHARE_DELETE. */
3362
3363         if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3364                         FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3365                 printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
3366                 correct = False;
3367                 goto fail;
3368         }
3369
3370         /* This should succeed. */
3371
3372         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3373                         FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3374                 printf("[3] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3375                 correct = False;
3376                 goto fail;
3377         }
3378
3379         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3380                 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3381                 correct = False;
3382                 goto fail;
3383         }
3384
3385         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3386                 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3387                 correct = False;
3388                 goto fail;
3389         }
3390
3391         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3392                 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3393                 correct = False;
3394                 goto fail;
3395         }
3396
3397         /* This should fail - file should no longer be there. */
3398
3399         if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3400                 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3401                 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3402                         printf("[3] close failed (%s)\n", cli_errstr(cli1));
3403                 }
3404                 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3405                 correct = False;
3406                 goto fail;
3407         } else
3408                 printf("third delete on close test succeeded.\n");
3409
3410         /* Test 4 ... */
3411         cli_setatr(cli1, fname, 0, 0);
3412         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3413
3414         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3415                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3416                 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3417                 correct = False;
3418                 goto fail;
3419         }
3420
3421         /* This should succeed. */
3422         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3423                         FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3424                 printf("[4] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3425                 correct = False;
3426                 goto fail;
3427         }
3428
3429         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3430                 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3431                 correct = False;
3432                 goto fail;
3433         }
3434
3435         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3436                 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3437                 correct = False;
3438                 goto fail;
3439         }
3440
3441         /* This should fail - no more opens once delete on close set. */
3442         if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3443                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3444                                    FILE_OPEN, 0, 0, &fnum2))) {
3445                 printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
3446                 correct = False;
3447                 goto fail;
3448         } else
3449                 printf("fourth delete on close test succeeded.\n");
3450
3451         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3452                 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3453                 correct = False;
3454                 goto fail;
3455         }
3456
3457         /* Test 5 ... */
3458         cli_setatr(cli1, fname, 0, 0);
3459         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3460
3461         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3462                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3463                 correct = False;
3464                 goto fail;
3465         }
3466
3467         /* This should fail - only allowed on NT opens with DELETE access. */
3468
3469         if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3470                 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3471                 correct = False;
3472                 goto fail;
3473         }
3474
3475         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3476                 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3477                 correct = False;
3478                 goto fail;
3479         }
3480
3481         printf("fifth delete on close test succeeded.\n");
3482
3483         /* Test 6 ... */
3484         cli_setatr(cli1, fname, 0, 0);
3485         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3486
3487         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3488                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3489                                    FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3490                 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3491                 correct = False;
3492                 goto fail;
3493         }
3494
3495         /* This should fail - only allowed on NT opens with DELETE access. */
3496
3497         if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3498                 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3499                 correct = False;
3500                 goto fail;
3501         }
3502
3503         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3504                 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3505                 correct = False;
3506                 goto fail;
3507         }
3508
3509         printf("sixth delete on close test succeeded.\n");
3510
3511         /* Test 7 ... */
3512         cli_setatr(cli1, fname, 0, 0);
3513         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3514
3515         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3516                                    FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3517                 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3518                 correct = False;
3519                 goto fail;
3520         }
3521
3522         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3523                 printf("[7] setting delete_on_close on file failed !\n");
3524                 correct = False;
3525                 goto fail;
3526         }
3527
3528         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3529                 printf("[7] unsetting delete_on_close on file failed !\n");
3530                 correct = False;
3531                 goto fail;
3532         }
3533
3534         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3535                 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3536                 correct = False;
3537                 goto fail;
3538         }
3539
3540         /* This next open should succeed - we reset the flag. */
3541
3542         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3543                 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3544                 correct = False;
3545                 goto fail;
3546         }
3547
3548         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3549                 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3550                 correct = False;
3551                 goto fail;
3552         }
3553
3554         printf("seventh delete on close test succeeded.\n");
3555
3556         /* Test 7 ... */
3557         cli_setatr(cli1, fname, 0, 0);
3558         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3559
3560         if (!torture_open_connection(&cli2, 1)) {
3561                 printf("[8] failed to open second connection.\n");
3562                 correct = False;
3563                 goto fail;
3564         }
3565
3566         cli_sockopt(cli1, sockops);
3567
3568         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3569                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3570                                    FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3571                 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3572                 correct = False;
3573                 goto fail;
3574         }
3575
3576         if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3577                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3578                                    FILE_OPEN, 0, 0, &fnum2))) {
3579                 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3580                 correct = False;
3581                 goto fail;
3582         }
3583
3584         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3585                 printf("[8] setting delete_on_close on file failed !\n");
3586                 correct = False;
3587                 goto fail;
3588         }
3589
3590         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3591                 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3592                 correct = False;
3593                 goto fail;
3594         }
3595
3596         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3597                 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3598                 correct = False;
3599                 goto fail;
3600         }
3601
3602         /* This should fail.. */
3603         if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3604                 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3605                 goto fail;
3606                 correct = False;
3607         } else
3608                 printf("eighth delete on close test succeeded.\n");
3609
3610         /* This should fail - we need to set DELETE_ACCESS. */
3611         if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3612                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3613                 printf("[9] open of %s succeeded should have failed!\n", fname);
3614                 correct = False;
3615                 goto fail;
3616         }
3617
3618         printf("ninth delete on close test succeeded.\n");
3619
3620         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3621                                    FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3622                 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3623                 correct = False;
3624                 goto fail;
3625         }
3626
3627         /* This should delete the file. */
3628         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3629                 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3630                 correct = False;
3631                 goto fail;
3632         }
3633
3634         /* This should fail.. */
3635         if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3636                 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3637                 goto fail;
3638                 correct = False;
3639         } else
3640                 printf("tenth delete on close test succeeded.\n");
3641
3642         cli_setatr(cli1, fname, 0, 0);
3643         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3644
3645         /* What error do we get when attempting to open a read-only file with
3646            delete access ? */
3647
3648         /* Create a readonly file. */
3649         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3650                                    FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3651                 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3652                 correct = False;
3653                 goto fail;
3654         }
3655
3656         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3657                 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3658                 correct = False;
3659                 goto fail;
3660         }
3661
3662         /* Now try open for delete access. */
3663         if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3664                                    0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3665                                    FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3666                 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3667                 cli_close(cli1, fnum1);
3668                 goto fail;
3669                 correct = False;
3670         } else {
3671                 NTSTATUS nterr = cli_nt_error(cli1);
3672                 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3673                         printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3674                         goto fail;
3675                         correct = False;
3676                 } else {
3677                         printf("eleventh delete on close test succeeded.\n");
3678                 }
3679         }
3680
3681         printf("finished delete test\n");
3682
3683   fail:
3684         /* FIXME: This will crash if we aborted before cli2 got
3685          * intialized, because these functions don't handle
3686          * uninitialized connections. */
3687
3688         if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
3689         if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
3690         cli_setatr(cli1, fname, 0, 0);
3691         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3692
3693         if (cli1 && !torture_close_connection(cli1)) {
3694                 correct = False;
3695         }
3696         if (cli2 && !torture_close_connection(cli2)) {
3697                 correct = False;
3698         }
3699         return correct;
3700 }
3701
3702
3703 /*
3704   print out server properties
3705  */
3706 static bool run_properties(int dummy)
3707 {
3708         struct cli_state *cli;
3709         bool correct = True;
3710
3711         printf("starting properties test\n");
3712
3713         ZERO_STRUCT(cli);
3714
3715         if (!torture_open_connection(&cli, 0)) {
3716                 return False;
3717         }
3718
3719         cli_sockopt(cli, sockops);
3720
3721         d_printf("Capabilities 0x%08x\n", cli->capabilities);
3722
3723         if (!torture_close_connection(cli)) {
3724                 correct = False;
3725         }
3726
3727         return correct;
3728 }
3729
3730
3731
3732 /* FIRST_DESIRED_ACCESS   0xf019f */
3733 #define FIRST_DESIRED_ACCESS   FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3734                                FILE_READ_EA|                           /* 0xf */ \
3735                                FILE_WRITE_EA|FILE_READ_ATTRIBUTES|     /* 0x90 */ \
3736                                FILE_WRITE_ATTRIBUTES|                  /* 0x100 */ \
3737                                DELETE_ACCESS|READ_CONTROL_ACCESS|\
3738                                WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS     /* 0xf0000 */
3739 /* SECOND_DESIRED_ACCESS  0xe0080 */
3740 #define SECOND_DESIRED_ACCESS  FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
3741                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3742                                WRITE_OWNER_ACCESS                      /* 0xe0000 */
3743
3744 #if 0
3745 #define THIRD_DESIRED_ACCESS   FILE_READ_ATTRIBUTES|                   /* 0x80 */ \
3746                                READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3747                                FILE_READ_DATA|\
3748                                WRITE_OWNER_ACCESS                      /* */
3749 #endif
3750
3751 /*
3752   Test ntcreate calls made by xcopy
3753  */
3754 static bool run_xcopy(int dummy)
3755 {
3756         static struct cli_state *cli1;
3757         const char *fname = "\\test.txt";
3758         bool correct = True;
3759         uint16_t fnum1, fnum2;
3760
3761         printf("starting xcopy test\n");
3762
3763         if (!torture_open_connection(&cli1, 0)) {
3764                 return False;
3765         }
3766
3767         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3768                                    FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3769                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 
3770                                    0x4044, 0, &fnum1))) {
3771                 printf("First open failed - %s\n", cli_errstr(cli1));
3772                 return False;
3773         }
3774
3775         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3776                                    SECOND_DESIRED_ACCESS, 0,
3777                                    FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 
3778                                    0x200000, 0, &fnum2))) {
3779                 printf("second open failed - %s\n", cli_errstr(cli1));
3780                 return False;
3781         }
3782
3783         if (!torture_close_connection(cli1)) {
3784                 correct = False;
3785         }
3786
3787         return correct;
3788 }
3789
3790 /*
3791   Test rename on files open with share delete and no share delete.
3792  */
3793 static bool run_rename(int dummy)
3794 {
3795         static struct cli_state *cli1;
3796         const char *fname = "\\test.txt";
3797         const char *fname1 = "\\test1.txt";
3798         bool correct = True;
3799         uint16_t fnum1;
3800         uint16_t attr;
3801         NTSTATUS status;
3802
3803         printf("starting rename test\n");
3804
3805         if (!torture_open_connection(&cli1, 0)) {
3806                 return False;
3807         }
3808
3809         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3810         cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3811         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3812                                    FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3813                 printf("First open failed - %s\n", cli_errstr(cli1));
3814                 return False;
3815         }
3816
3817         if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3818                 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3819         } else {
3820                 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3821                 correct = False;
3822         }
3823
3824         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3825                 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3826                 return False;
3827         }
3828
3829         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3830         cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3831         status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3832 #if 0
3833                               FILE_SHARE_DELETE|FILE_SHARE_NONE,
3834 #else
3835                               FILE_SHARE_DELETE|FILE_SHARE_READ,
3836 #endif
3837                               FILE_OVERWRITE_IF, 0, 0, &fnum1);
3838         if (!NT_STATUS_IS_OK(status)) {
3839                 printf("Second open failed - %s\n", cli_errstr(cli1));
3840                 return False;
3841         }
3842
3843         if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3844                 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3845                 correct = False;
3846         } else {
3847                 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3848         }
3849
3850         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3851                 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3852                 return False;
3853         }
3854
3855         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3856         cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3857
3858         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3859                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3860                 printf("Third open failed - %s\n", cli_errstr(cli1));
3861                 return False;
3862         }
3863
3864
3865 #if 0
3866   {
3867         uint16_t fnum2;
3868
3869         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3870                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3871                 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3872                 return False;
3873         }
3874         if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
3875                 printf("[8] setting delete_on_close on file failed !\n");
3876                 return False;
3877         }
3878
3879         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3880                 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3881                 return False;
3882         }
3883   }
3884 #endif
3885
3886         if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3887                 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3888                 correct = False;
3889         } else {
3890                 printf("Third rename succeeded (SHARE_NONE)\n");
3891         }
3892
3893         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3894                 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3895                 return False;
3896         }
3897
3898         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3899         cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3900
3901         /*----*/
3902
3903         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3904                                    FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3905                 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3906                 return False;
3907         }
3908
3909         if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3910                 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3911         } else {
3912                 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3913                 correct = False;
3914         }
3915
3916         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3917                 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3918                 return False;
3919         }
3920
3921         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3922         cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3923
3924         /*--*/
3925
3926         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3927                                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3928                 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3929                 return False;
3930         }
3931
3932         if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3933                 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3934                         cli_errstr(cli1));
3935                 correct = False;
3936         } else {
3937                 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3938         }
3939
3940         /*
3941          * Now check if the first name still exists ...
3942          */
3943
3944         /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3945                                    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3946           printf("Opening original file after rename of open file fails: %s\n",
3947               cli_errstr(cli1));
3948         }
3949         else {
3950           printf("Opening original file after rename of open file works ...\n");
3951           (void)cli_close(cli1, fnum2);
3952           } */
3953
3954         /*--*/
3955         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3956                 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3957                 return False;
3958         }
3959
3960         /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
3961         if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
3962                 printf("getatr on file %s failed - %s ! \n",
3963                         fname1,
3964                         cli_errstr(cli1));
3965                 correct = False;
3966         } else {
3967                 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
3968                         printf("Renamed file %s has wrong attr 0x%x "
3969                                 "(should be 0x%x)\n",
3970                                 fname1,
3971                                 attr,
3972                                 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
3973                         correct = False;
3974                 } else {
3975                         printf("Renamed file %s has archive bit set\n", fname1);
3976                 }
3977         }
3978
3979         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3980         cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3981
3982         if (!torture_close_connection(cli1)) {
3983                 correct = False;
3984         }
3985
3986         return correct;
3987 }
3988
3989 static bool run_pipe_number(int dummy)
3990 {
3991         struct cli_state *cli1;
3992         const char *pipe_name = "\\SPOOLSS";
3993         uint16_t fnum;
3994         int num_pipes = 0;
3995
3996         printf("starting pipenumber test\n");
3997         if (!torture_open_connection(&cli1, 0)) {
3998                 return False;
3999         }
4000
4001         cli_sockopt(cli1, sockops);
4002         while(1) {
4003                 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4004                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4005                         printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4006                         break;
4007                 }
4008                 num_pipes++;
4009                 printf("\r%6d", num_pipes);
4010         }
4011
4012         printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4013         torture_close_connection(cli1);
4014         return True;
4015 }
4016
4017 /*
4018   Test open mode returns on read-only files.
4019  */
4020 static bool run_opentest(int dummy)
4021 {
4022         static struct cli_state *cli1;
4023         static struct cli_state *cli2;
4024         const char *fname = "\\readonly.file";
4025         uint16_t fnum1, fnum2;
4026         char buf[20];
4027         SMB_OFF_T fsize;
4028         bool correct = True;
4029         char *tmp_path;
4030
4031         printf("starting open test\n");
4032
4033         if (!torture_open_connection(&cli1, 0)) {
4034                 return False;
4035         }
4036
4037         cli_setatr(cli1, fname, 0, 0);
4038         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4039
4040         cli_sockopt(cli1, sockops);
4041
4042         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4043                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4044                 return False;
4045         }
4046
4047         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4048                 printf("close2 failed (%s)\n", cli_errstr(cli1));
4049                 return False;
4050         }
4051
4052         if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
4053                 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4054                 return False;
4055         }
4056
4057         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4058                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4059                 return False;
4060         }
4061
4062         /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4063         cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4064
4065         if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess, 
4066                         NT_STATUS_ACCESS_DENIED)) {
4067                 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4068         }
4069
4070         printf("finished open test 1\n");
4071
4072         cli_close(cli1, fnum1);
4073
4074         /* Now try not readonly and ensure ERRbadshare is returned. */
4075
4076         cli_setatr(cli1, fname, 0, 0);
4077
4078         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4079                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4080                 return False;
4081         }
4082
4083         /* This will fail - but the error should be ERRshare. */
4084         cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4085
4086         if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare, 
4087                         NT_STATUS_SHARING_VIOLATION)) {
4088                 printf("correct error code ERRDOS/ERRbadshare returned\n");
4089         }
4090
4091         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4092                 printf("close2 failed (%s)\n", cli_errstr(cli1));
4093                 return False;
4094         }
4095
4096         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4097
4098         printf("finished open test 2\n");
4099
4100         /* Test truncate open disposition on file opened for read. */
4101
4102         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4103                 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4104                 return False;
4105         }
4106
4107         /* write 20 bytes. */
4108
4109         memset(buf, '\0', 20);
4110
4111         if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
4112                 printf("write failed (%s)\n", cli_errstr(cli1));
4113                 correct = False;
4114         }
4115
4116         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4117                 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4118                 return False;
4119         }
4120
4121         /* Ensure size == 20. */
4122         if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4123                 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4124                 return False;
4125         }
4126
4127         if (fsize != 20) {
4128                 printf("(3) file size != 20\n");
4129                 return False;
4130         }
4131
4132         /* Now test if we can truncate a file opened for readonly. */
4133
4134         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4135                 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4136                 return False;
4137         }
4138
4139         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4140                 printf("close2 failed (%s)\n", cli_errstr(cli1));
4141                 return False;
4142         }
4143
4144         /* Ensure size == 0. */
4145         if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4146                 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4147                 return False;
4148         }
4149
4150         if (fsize != 0) {
4151                 printf("(3) file size != 0\n");
4152                 return False;
4153         }
4154         printf("finished open test 3\n");
4155
4156         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4157
4158
4159         printf("testing ctemp\n");
4160         if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4161                 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4162                 return False;
4163         }
4164         printf("ctemp gave path %s\n", tmp_path);
4165         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4166                 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4167         }
4168         if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
4169                 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4170         }
4171
4172         /* Test the non-io opens... */
4173
4174         if (!torture_open_connection(&cli2, 1)) {
4175                 return False;
4176         }
4177
4178         cli_setatr(cli2, fname, 0, 0);
4179         cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
4180
4181         cli_sockopt(cli2, sockops);
4182
4183         printf("TEST #1 testing 2 non-io opens (no delete)\n");
4184
4185         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4186                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4187                 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4188                 return False;
4189         }
4190
4191         if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4192                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4193                 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4194                 return False;
4195         }
4196
4197         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4198                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4199                 return False;
4200         }
4201         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4202                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4203                 return False;
4204         }
4205
4206         printf("non-io open test #1 passed.\n");
4207
4208         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4209
4210         printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4211
4212         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4213                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4214                 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4215                 return False;
4216         }
4217
4218         if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4219                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4220                 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4221                 return False;
4222         }
4223
4224         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4225                 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4226                 return False;
4227         }
4228         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4229                 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4230                 return False;
4231         }
4232
4233         printf("non-io open test #2 passed.\n");
4234
4235         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4236
4237         printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4238
4239         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4240                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4241                 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4242                 return False;
4243         }
4244
4245         if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4246                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4247                 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4248                 return False;
4249         }
4250
4251         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4252                 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4253                 return False;
4254         }
4255         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4256                 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4257                 return False;
4258         }
4259
4260         printf("non-io open test #3 passed.\n");
4261
4262         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4263
4264         printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4265
4266         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4267                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4268                 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4269                 return False;
4270         }
4271
4272         if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4273                                    FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4274                 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4275                 return False;
4276         }
4277
4278         printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4279
4280         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4281                 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4282                 return False;
4283         }
4284
4285         printf("non-io open test #4 passed.\n");
4286
4287         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4288
4289         printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4290
4291         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4292                                    FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4293                 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4294                 return False;
4295         }
4296
4297         if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4298                                    FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4299                 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4300                 return False;
4301         }
4302
4303         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4304                 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4305                 return False;
4306         }
4307
4308         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4309                 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4310                 return False;
4311         }
4312
4313         printf("non-io open test #5 passed.\n");
4314
4315         printf("TEST #6 testing 1 non-io open, one io open\n");
4316
4317         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4318
4319         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4320                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4321                 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4322                 return False;
4323         }
4324
4325         if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4326                                    FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4327                 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4328                 return False;
4329         }
4330
4331         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4332                 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4333                 return False;
4334         }
4335
4336         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4337                 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4338                 return False;
4339         }
4340
4341         printf("non-io open test #6 passed.\n");
4342
4343         printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4344
4345         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4346
4347         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4348                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4349                 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4350                 return False;
4351         }
4352
4353         if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4354                                    FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4355                 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4356                 return False;
4357         }
4358
4359         printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4360
4361         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4362                 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4363                 return False;
4364         }
4365
4366         printf("non-io open test #7 passed.\n");
4367
4368         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4369
4370         if (!torture_close_connection(cli1)) {
4371                 correct = False;
4372         }
4373         if (!torture_close_connection(cli2)) {
4374                 correct = False;
4375         }
4376
4377         return correct;
4378 }
4379
4380 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4381 {
4382         uint16 major, minor;
4383         uint32 caplow, caphigh;
4384         NTSTATUS status;
4385
4386         if (!SERVER_HAS_UNIX_CIFS(cli)) {
4387                 printf("Server doesn't support UNIX CIFS extensions.\n");
4388                 return NT_STATUS_NOT_SUPPORTED;
4389         }
4390
4391         status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4392                                              &caphigh);
4393         if (!NT_STATUS_IS_OK(status)) {
4394                 printf("Server didn't return UNIX CIFS extensions: %s\n",
4395                        nt_errstr(status));
4396                 return status;
4397         }
4398
4399         status = cli_set_unix_extensions_capabilities(cli, major, minor,
4400                                                       caplow, caphigh);
4401         if (!NT_STATUS_IS_OK(status)) {
4402                 printf("Server doesn't support setting UNIX CIFS extensions: "
4403                        "%s.\n", nt_errstr(status));
4404                 return status;
4405         }
4406
4407         return NT_STATUS_OK;
4408 }
4409
4410 /*
4411   Test POSIX open /mkdir calls.
4412  */
4413 static bool run_simple_posix_open_test(int dummy)
4414 {
4415         static struct cli_state *cli1;
4416         const char *fname = "posix:file";
4417         const char *hname = "posix:hlink";
4418         const char *sname = "posix:symlink";
4419         const char *dname = "posix:dir";
4420         char buf[10];
4421         char namebuf[11];
4422         uint16_t fnum1 = (uint16_t)-1;
4423         SMB_STRUCT_STAT sbuf;
4424         bool correct = false;
4425         NTSTATUS status;
4426
4427         printf("Starting simple POSIX open test\n");
4428
4429         if (!torture_open_connection(&cli1, 0)) {
4430                 return false;
4431         }
4432
4433         cli_sockopt(cli1, sockops);
4434
4435         status = torture_setup_unix_extensions(cli1);
4436         if (!NT_STATUS_IS_OK(status)) {
4437                 return false;
4438         }
4439
4440         cli_setatr(cli1, fname, 0, 0);
4441         cli_posix_unlink(cli1, fname);
4442         cli_setatr(cli1, dname, 0, 0);
4443         cli_posix_rmdir(cli1, dname);
4444         cli_setatr(cli1, hname, 0, 0);
4445         cli_posix_unlink(cli1, hname);
4446         cli_setatr(cli1, sname, 0, 0);
4447         cli_posix_unlink(cli1, sname);
4448
4449         /* Create a directory. */
4450         if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4451                 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4452                 goto out;
4453         }
4454
4455         if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4456                 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4457                 goto out;
4458         }
4459
4460         /* Test ftruncate - set file size. */
4461         if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4462                 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4463                 goto out;
4464         }
4465
4466         /* Ensure st_size == 1000 */
4467         if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4468                 printf("stat failed (%s)\n", cli_errstr(cli1));
4469                 goto out;
4470         }
4471
4472         if (sbuf.st_ex_size != 1000) {
4473                 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4474                 goto out;
4475         }
4476
4477         /* Test ftruncate - set file size back to zero. */
4478         if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4479                 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4480                 goto out;
4481         }
4482
4483         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4484                 printf("close failed (%s)\n", cli_errstr(cli1));
4485                 goto out;
4486         }
4487
4488         /* Now open the file again for read only. */
4489         if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4490                 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4491                 goto out;
4492         }
4493
4494         /* Now unlink while open. */
4495         if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4496                 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4497                 goto out;
4498         }
4499
4500         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4501                 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4502                 goto out;
4503         }
4504
4505         /* Ensure the file has gone. */
4506         if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4507                 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4508                 goto out;
4509         }
4510
4511         /* What happens when we try and POSIX open a directory ? */
4512         if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4513                 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4514                 goto out;
4515         } else {
4516                 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4517                                 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4518                         goto out;
4519                 }
4520         }
4521
4522         /* Create the file. */
4523         if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4524                 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4525                 goto out;
4526         }
4527
4528         /* Write some data into it. */
4529         if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4530                 printf("cli_write failed: %s\n", cli_errstr(cli1));
4531                 goto out;
4532         }
4533
4534         cli_close(cli1, fnum1);
4535
4536         /* Now create a hardlink. */
4537         if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
4538                 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
4539                 goto out;
4540         }
4541
4542         /* Now create a symlink. */
4543         if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
4544                 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
4545                 goto out;
4546         }
4547
4548         /* Open the hardlink for read. */
4549         if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
4550                 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
4551                 goto out;
4552         }
4553
4554         if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
4555                 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
4556                 goto out;
4557         }
4558
4559         if (memcmp(buf, "TEST DATA\n", 10)) {
4560                 printf("invalid data read from hardlink\n");
4561                 goto out;
4562         }
4563
4564         /* Do a POSIX lock/unlock. */
4565         if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
4566                 printf("POSIX lock failed %s\n", cli_errstr(cli1));
4567                 goto out;
4568         }
4569
4570         /* Punch a hole in the locked area. */
4571         if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
4572                 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
4573                 goto out;
4574         }
4575
4576         cli_close(cli1, fnum1);
4577
4578         /* Open the symlink for read - this should fail. A POSIX
4579            client should not be doing opens on a symlink. */
4580         if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
4581                 printf("POSIX open of %s succeeded (should have failed)\n", sname);
4582                 goto out;
4583         } else {
4584                 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
4585                                 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4586                         printf("POSIX open of %s should have failed "
4587                                 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4588                                 "failed with %s instead.\n",
4589                                 sname, cli_errstr(cli1));
4590                         goto out;
4591                 }
4592         }
4593
4594         if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
4595                 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
4596                 goto out;
4597         }
4598
4599         if (strcmp(namebuf, fname) != 0) {
4600                 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
4601                         sname, fname, namebuf);
4602                 goto out;
4603         }
4604
4605         if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
4606                 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4607                 goto out;
4608         }
4609
4610         printf("Simple POSIX open test passed\n");
4611         correct = true;
4612
4613   out:
4614
4615         if (fnum1 != (uint16_t)-1) {
4616                 cli_close(cli1, fnum1);
4617                 fnum1 = (uint16_t)-1;
4618         }
4619
4620         cli_setatr(cli1, sname, 0, 0);
4621         cli_posix_unlink(cli1, sname);
4622         cli_setatr(cli1, hname, 0, 0);
4623         cli_posix_unlink(cli1, hname);
4624         cli_setatr(cli1, fname, 0, 0);
4625         cli_posix_unlink(cli1, fname);
4626         cli_setatr(cli1, dname, 0, 0);
4627         cli_posix_rmdir(cli1, dname);
4628
4629         if (!torture_close_connection(cli1)) {
4630                 correct = false;
4631         }
4632
4633         return correct;
4634 }
4635
4636
4637 static uint32 open_attrs_table[] = {
4638                 FILE_ATTRIBUTE_NORMAL,
4639                 FILE_ATTRIBUTE_ARCHIVE,
4640                 FILE_ATTRIBUTE_READONLY,
4641                 FILE_ATTRIBUTE_HIDDEN,
4642                 FILE_ATTRIBUTE_SYSTEM,
4643
4644                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4645                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4646                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4647                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4648                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4649                 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4650
4651                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4652                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4653                 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4654                 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4655 };
4656
4657 struct trunc_open_results {
4658         unsigned int num;
4659         uint32 init_attr;
4660         uint32 trunc_attr;
4661         uint32 result_attr;
4662 };
4663
4664 static struct trunc_open_results attr_results[] = {
4665         { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4666         { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4667         { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4668         { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4669         { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4670         { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4671         { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4672         { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4673         { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4674         { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4675         { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4676         { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4677         { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4678         { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4679         { 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 },
4680         { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4681         { 119,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,  FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4682         { 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 },
4683         { 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 },
4684         { 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 },
4685         { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4686         { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4687         { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4688         { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4689         { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4690         { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4691 };
4692
4693 static bool run_openattrtest(int dummy)
4694 {
4695         static struct cli_state *cli1;
4696         const char *fname = "\\openattr.file";
4697         uint16_t fnum1;
4698         bool correct = True;
4699         uint16 attr;
4700         unsigned int i, j, k, l;
4701
4702         printf("starting open attr test\n");
4703
4704         if (!torture_open_connection(&cli1, 0)) {
4705                 return False;
4706         }
4707
4708         cli_sockopt(cli1, sockops);
4709
4710         for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4711                 cli_setatr(cli1, fname, 0, 0);
4712                 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4713                 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4714                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4715                         printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4716                         return False;
4717                 }
4718
4719                 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4720                         printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4721                         return False;
4722                 }
4723
4724                 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4725                         if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4726                                            FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
4727                                 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4728                                         if (attr_results[l].num == k) {
4729                                                 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4730                                                                 k, open_attrs_table[i],
4731                                                                 open_attrs_table[j],
4732                                                                 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4733                                                 correct = False;
4734                                         }
4735                                 }
4736                                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4737                                         printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4738                                                         k, open_attrs_table[i], open_attrs_table[j],
4739                                                         cli_errstr(cli1));
4740                                         correct = False;
4741                                 }
4742 #if 0
4743                                 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4744 #endif
4745                                 k++;
4746                                 continue;
4747                         }
4748
4749                         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4750                                 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4751                                 return False;
4752                         }
4753
4754                         if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
4755                                 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4756                                 return False;
4757                         }
4758
4759 #if 0
4760                         printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4761                                         k,  open_attrs_table[i],  open_attrs_table[j], attr );
4762 #endif
4763
4764                         for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4765                                 if (attr_results[l].num == k) {
4766                                         if (attr != attr_results[l].result_attr ||
4767                                                         open_attrs_table[i] != attr_results[l].init_attr ||
4768                                                         open_attrs_table[j] != attr_results[l].trunc_attr) {
4769                                                 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4770                                                 open_attrs_table[i],
4771                                                 open_attrs_table[j],
4772                                                 (unsigned int)attr,
4773                                                 attr_results[l].result_attr);
4774                                                 correct = False;
4775                                         }
4776                                         break;
4777                                 }
4778                         }
4779                         k++;
4780                 }
4781         }
4782
4783         cli_setatr(cli1, fname, 0, 0);
4784         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4785
4786         printf("open attr test %s.\n", correct ? "passed" : "failed");
4787
4788         if (!torture_close_connection(cli1)) {
4789                 correct = False;
4790         }
4791         return correct;
4792 }
4793
4794 static void list_fn(const char *mnt, struct file_info *finfo,
4795                     const char *name, void *state)
4796 {
4797         int *matched = (int *)state;
4798         if (matched != NULL) {
4799                 *matched += 1;
4800         }
4801 }
4802
4803 /*
4804   test directory listing speed
4805  */
4806 static bool run_dirtest(int dummy)
4807 {
4808         int i;
4809         static struct cli_state *cli;
4810         uint16_t fnum;
4811         struct timeval core_start;
4812         bool correct = True;
4813         int matched;
4814
4815         printf("starting directory test\n");
4816
4817         if (!torture_open_connection(&cli, 0)) {
4818                 return False;
4819         }
4820
4821         cli_sockopt(cli, sockops);
4822
4823         srandom(0);
4824         for (i=0;i<torture_numops;i++) {
4825                 fstring fname;
4826                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4827                 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
4828                         fprintf(stderr,"Failed to open %s\n", fname);
4829                         return False;
4830                 }
4831                 cli_close(cli, fnum);
4832         }
4833
4834         core_start = timeval_current();
4835
4836         matched = 0;
4837         cli_list(cli, "a*.*", 0, list_fn, &matched);
4838         printf("Matched %d\n", matched);
4839
4840         matched = 0;
4841         cli_list(cli, "b*.*", 0, list_fn, &matched);
4842         printf("Matched %d\n", matched);
4843
4844         matched = 0;
4845         cli_list(cli, "xyzabc", 0, list_fn, &matched);
4846         printf("Matched %d\n", matched);
4847
4848         printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
4849
4850         srandom(0);
4851         for (i=0;i<torture_numops;i++) {
4852                 fstring fname;
4853                 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4854                 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4855         }
4856
4857         if (!torture_close_connection(cli)) {
4858                 correct = False;
4859         }
4860
4861         printf("finished dirtest\n");
4862
4863         return correct;
4864 }
4865
4866 static void del_fn(const char *mnt, struct file_info *finfo, const char *mask,
4867                    void *state)
4868 {
4869         struct cli_state *pcli = (struct cli_state *)state;
4870         fstring fname;
4871         slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4872
4873         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4874                 return;
4875
4876         if (finfo->mode & aDIR) {
4877                 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
4878                         printf("del_fn: failed to rmdir %s\n,", fname );
4879         } else {
4880                 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
4881                         printf("del_fn: failed to unlink %s\n,", fname );
4882         }
4883 }
4884
4885
4886 /*
4887   sees what IOCTLs are supported
4888  */
4889 bool torture_ioctl_test(int dummy)
4890 {
4891         static struct cli_state *cli;
4892         uint16_t device, function;
4893         uint16_t fnum;
4894         const char *fname = "\\ioctl.dat";
4895         DATA_BLOB blob;
4896         NTSTATUS status;
4897
4898         if (!torture_open_connection(&cli, 0)) {
4899                 return False;
4900         }
4901
4902         printf("starting ioctl test\n");
4903
4904         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4905
4906         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4907                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4908                 return False;
4909         }
4910
4911         status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4912         printf("ioctl device info: %s\n", nt_errstr(status));
4913
4914         status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4915         printf("ioctl job info: %s\n", nt_errstr(status));
4916
4917         for (device=0;device<0x100;device++) {
4918                 printf("testing device=0x%x\n", device);
4919                 for (function=0;function<0x100;function++) {
4920                         uint32 code = (device<<16) | function;
4921
4922                         status = cli_raw_ioctl(cli, fnum, code, &blob);
4923
4924                         if (NT_STATUS_IS_OK(status)) {
4925                                 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4926                                        (int)blob.length);
4927                                 data_blob_free(&blob);
4928                         }
4929                 }
4930         }
4931
4932         if (!torture_close_connection(cli)) {
4933                 return False;
4934         }
4935
4936         return True;
4937 }
4938
4939
4940 /*
4941   tries varients of chkpath
4942  */
4943 bool torture_chkpath_test(int dummy)
4944 {
4945         static struct cli_state *cli;
4946         uint16_t fnum;
4947         bool ret;
4948
4949         if (!torture_open_connection(&cli, 0)) {
4950                 return False;
4951         }
4952
4953         printf("starting chkpath test\n");
4954
4955         /* cleanup from an old run */
4956         cli_rmdir(cli, "\\chkpath.dir\\dir2");
4957         cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4958         cli_rmdir(cli, "\\chkpath.dir");
4959
4960         if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
4961                 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4962                 return False;
4963         }
4964
4965         if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
4966                 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4967                 return False;
4968         }
4969
4970         if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4971                 printf("open1 failed (%s)\n", cli_errstr(cli));
4972                 return False;
4973         }
4974         cli_close(cli, fnum);
4975
4976         if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
4977                 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4978                 ret = False;
4979         }
4980
4981         if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
4982                 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4983                 ret = False;
4984         }
4985
4986         if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
4987                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath, 
4988                                   NT_STATUS_NOT_A_DIRECTORY);
4989         } else {
4990                 printf("* chkpath on a file should fail\n");
4991                 ret = False;
4992         }
4993
4994         if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
4995                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile, 
4996                                   NT_STATUS_OBJECT_NAME_NOT_FOUND);
4997         } else {
4998                 printf("* chkpath on a non existant file should fail\n");
4999                 ret = False;
5000         }
5001
5002         if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5003                 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath, 
5004                                   NT_STATUS_OBJECT_PATH_NOT_FOUND);
5005         } else {
5006                 printf("* chkpath on a non existent component should fail\n");
5007                 ret = False;
5008         }
5009
5010         cli_rmdir(cli, "\\chkpath.dir\\dir2");
5011         cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5012         cli_rmdir(cli, "\\chkpath.dir");
5013
5014         if (!torture_close_connection(cli)) {
5015                 return False;
5016         }
5017
5018         return ret;
5019 }
5020
5021 static bool run_eatest(int dummy)
5022 {
5023         static struct cli_state *cli;
5024         const char *fname = "\\eatest.txt";
5025         bool correct = True;
5026         uint16_t fnum;
5027         int i;
5028         size_t num_eas;
5029         struct ea_struct *ea_list = NULL;
5030         TALLOC_CTX *mem_ctx = talloc_init("eatest");
5031         NTSTATUS status;
5032
5033         printf("starting eatest\n");
5034
5035         if (!torture_open_connection(&cli, 0)) {
5036                 talloc_destroy(mem_ctx);
5037                 return False;
5038         }
5039
5040         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5041         if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5042                                    FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5043                                    FILE_SHARE_NONE, FILE_OVERWRITE_IF, 
5044                                    0x4044, 0, &fnum))) {
5045                 printf("open failed - %s\n", cli_errstr(cli));
5046                 talloc_destroy(mem_ctx);
5047                 return False;
5048         }
5049
5050         for (i = 0; i < 10; i++) {
5051                 fstring ea_name, ea_val;
5052
5053                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5054                 memset(ea_val, (char)i+1, i+1);
5055                 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
5056                         printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5057                         talloc_destroy(mem_ctx);
5058                         return False;
5059                 }
5060         }
5061
5062         cli_close(cli, fnum);
5063         for (i = 0; i < 10; i++) {
5064                 fstring ea_name, ea_val;
5065
5066                 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5067                 memset(ea_val, (char)i+1, i+1);
5068                 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
5069                         printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5070                         talloc_destroy(mem_ctx);
5071                         return False;
5072                 }
5073         }
5074
5075         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5076         if (!NT_STATUS_IS_OK(status)) {
5077                 printf("ea_get list failed - %s\n", nt_errstr(status));
5078                 correct = False;
5079         }
5080
5081         printf("num_eas = %d\n", (int)num_eas);
5082
5083         if (num_eas != 20) {
5084                 printf("Should be 20 EA's stored... failing.\n");
5085                 correct = False;
5086         }
5087
5088         for (i = 0; i < num_eas; i++) {
5089                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5090                 dump_data(0, ea_list[i].value.data,
5091                           ea_list[i].value.length);
5092         }
5093
5094         /* Setting EA's to zero length deletes them. Test this */
5095         printf("Now deleting all EA's - case indepenent....\n");
5096
5097 #if 1
5098         cli_set_ea_path(cli, fname, "", "", 0);
5099 #else
5100         for (i = 0; i < 20; i++) {
5101                 fstring ea_name;
5102                 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5103                 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
5104                         printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5105                         talloc_destroy(mem_ctx);
5106                         return False;
5107                 }
5108         }
5109 #endif
5110
5111         status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5112         if (!NT_STATUS_IS_OK(status)) {
5113                 printf("ea_get list failed - %s\n", nt_errstr(status));
5114                 correct = False;
5115         }
5116
5117         printf("num_eas = %d\n", (int)num_eas);
5118         for (i = 0; i < num_eas; i++) {
5119                 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5120                 dump_data(0, ea_list[i].value.data,
5121                           ea_list[i].value.length);
5122         }
5123
5124         if (num_eas != 0) {
5125                 printf("deleting EA's failed.\n");
5126                 correct = False;
5127         }
5128
5129         /* Try and delete a non existant EA. */
5130         if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
5131                 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
5132                 correct = False;
5133         }
5134
5135         talloc_destroy(mem_ctx);
5136         if (!torture_close_connection(cli)) {
5137                 correct = False;
5138         }
5139
5140         return correct;
5141 }
5142
5143 static bool run_dirtest1(int dummy)
5144 {
5145         int i;
5146         static struct cli_state *cli;
5147         uint16_t fnum;
5148         int num_seen;
5149         bool correct = True;
5150
5151         printf("starting directory test\n");
5152
5153         if (!torture_open_connection(&cli, 0)) {
5154                 return False;
5155         }
5156
5157         cli_sockopt(cli, sockops);
5158
5159         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5160         cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5161         cli_rmdir(cli, "\\LISTDIR");
5162         cli_mkdir(cli, "\\LISTDIR");
5163
5164         /* Create 1000 files and 1000 directories. */
5165         for (i=0;i<1000;i++) {
5166                 fstring fname;
5167                 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5168                 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5169                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5170                         fprintf(stderr,"Failed to open %s\n", fname);
5171                         return False;
5172                 }
5173                 cli_close(cli, fnum);
5174         }
5175         for (i=0;i<1000;i++) {
5176                 fstring fname;
5177                 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5178                 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5179                         fprintf(stderr,"Failed to open %s\n", fname);
5180                         return False;
5181                 }
5182         }
5183
5184         /* Now ensure that doing an old list sees both files and directories. */
5185         num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
5186         printf("num_seen = %d\n", num_seen );
5187         /* We should see 100 files + 1000 directories + . and .. */
5188         if (num_seen != 2002)
5189                 correct = False;
5190
5191         /* Ensure if we have the "must have" bits we only see the
5192          * relevent entries.
5193          */
5194         num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
5195         printf("num_seen = %d\n", num_seen );
5196         if (num_seen != 1002)
5197                 correct = False;
5198
5199         num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
5200         printf("num_seen = %d\n", num_seen );
5201         if (num_seen != 1000)
5202                 correct = False;
5203
5204         /* Delete everything. */
5205         cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5206         cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5207         cli_rmdir(cli, "\\LISTDIR");
5208
5209 #if 0
5210         printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5211         printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5212         printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5213 #endif
5214
5215         if (!torture_close_connection(cli)) {
5216                 correct = False;
5217         }
5218
5219         printf("finished dirtest1\n");
5220
5221         return correct;
5222 }
5223
5224 static bool run_error_map_extract(int dummy) {
5225
5226         static struct cli_state *c_dos;
5227         static struct cli_state *c_nt;
5228         NTSTATUS status;
5229
5230         uint32 error;
5231
5232         uint32 flgs2, errnum;
5233         uint8 errclass;
5234
5235         NTSTATUS nt_status;
5236
5237         fstring user;
5238
5239         /* NT-Error connection */
5240
5241         if (!(c_nt = open_nbt_connection())) {
5242                 return False;
5243         }
5244
5245         c_nt->use_spnego = False;
5246
5247         status = cli_negprot(c_nt);
5248
5249         if (!NT_STATUS_IS_OK(status)) {
5250                 printf("%s rejected the NT-error negprot (%s)\n", host,
5251                        nt_errstr(status));
5252                 cli_shutdown(c_nt);
5253                 return False;
5254         }
5255
5256         if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5257                                                workgroup))) {
5258                 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5259                 return False;
5260         }
5261
5262         /* DOS-Error connection */
5263
5264         if (!(c_dos = open_nbt_connection())) {
5265                 return False;
5266         }
5267
5268         c_dos->use_spnego = False;
5269         c_dos->force_dos_errors = True;
5270
5271         status = cli_negprot(c_dos);
5272         if (!NT_STATUS_IS_OK(status)) {
5273                 printf("%s rejected the DOS-error negprot (%s)\n", host,
5274                        nt_errstr(status));
5275                 cli_shutdown(c_dos);
5276                 return False;
5277         }
5278
5279         if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5280                                                workgroup))) {
5281                 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5282                 return False;
5283         }
5284
5285         for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5286                 fstr_sprintf(user, "%X", error);
5287
5288                 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user, 
5289                                                       password, strlen(password),
5290                                                       password, strlen(password),
5291                                                       workgroup))) {
5292                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
5293                 }
5294
5295                 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5296
5297                 /* Case #1: 32-bit NT errors */
5298                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5299                         nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5300                 } else {
5301                         printf("/** Dos error on NT connection! (%s) */\n", 
5302                                cli_errstr(c_nt));
5303                         nt_status = NT_STATUS(0xc0000000);
5304                 }
5305
5306                 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user, 
5307                                                       password, strlen(password),
5308                                                       password, strlen(password),
5309                                                       workgroup))) {
5310                         printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
5311                 }
5312                 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5313
5314                 /* Case #1: 32-bit NT errors */
5315                 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5316                         printf("/** NT error on DOS connection! (%s) */\n", 
5317                                cli_errstr(c_nt));
5318                         errnum = errclass = 0;
5319                 } else {
5320                         cli_dos_error(c_dos, &errclass, &errnum);
5321                 }
5322
5323                 if (NT_STATUS_V(nt_status) != error) { 
5324                         printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n", 
5325                                get_nt_error_c_code(NT_STATUS(error)), 
5326                                get_nt_error_c_code(nt_status));
5327                 }
5328
5329                 printf("\t{%s,\t%s,\t%s},\n", 
5330                        smb_dos_err_class(errclass), 
5331                        smb_dos_err_name(errclass, errnum), 
5332                        get_nt_error_c_code(NT_STATUS(error)));
5333         }
5334         return True;
5335 }
5336
5337 static bool run_sesssetup_bench(int dummy)
5338 {
5339         static struct cli_state *c;
5340         const char *fname = "\\file.dat";
5341         uint16_t fnum;
5342         NTSTATUS status;
5343         int i;
5344
5345         if (!torture_open_connection(&c, 0)) {
5346                 return false;
5347         }
5348
5349         if (!NT_STATUS_IS_OK(cli_ntcreate(
5350                         c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5351                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5352                         FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5353                 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5354                 return false;
5355         }
5356
5357         for (i=0; i<torture_numops; i++) {
5358                 status = cli_session_setup(
5359                         c, username,
5360                         password, strlen(password),
5361                         password, strlen(password),
5362                         workgroup);
5363                 if (!NT_STATUS_IS_OK(status)) {
5364                         d_printf("(%s) cli_session_setup failed: %s\n",
5365                                  __location__, nt_errstr(status));
5366                         return false;
5367                 }
5368
5369                 d_printf("\r%d   ", (int)c->vuid);
5370
5371                 status = cli_ulogoff(c);
5372                 if (!NT_STATUS_IS_OK(status)) {
5373                         d_printf("(%s) cli_ulogoff failed: %s\n",
5374                                  __location__, nt_errstr(status));
5375                         return false;
5376                 }
5377                 c->vuid = 0;
5378         }
5379
5380         return true;
5381 }
5382
5383 static bool subst_test(const char *str, const char *user, const char *domain,
5384                        uid_t uid, gid_t gid, const char *expected)
5385 {
5386         char *subst;
5387         bool result = true;
5388
5389         subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5390
5391         if (strcmp(subst, expected) != 0) {
5392                 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5393                        "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5394                        expected);
5395                 result = false;
5396         }
5397
5398         TALLOC_FREE(subst);
5399         return result;
5400 }
5401
5402 static void chain1_open_completion(struct tevent_req *req)
5403 {
5404         uint16_t fnum;
5405         NTSTATUS status;
5406         status = cli_open_recv(req, &fnum);
5407         TALLOC_FREE(req);
5408
5409         d_printf("cli_open_recv returned %s: %d\n",
5410                  nt_errstr(status),
5411                  NT_STATUS_IS_OK(status) ? fnum : -1);
5412 }
5413
5414 static void chain1_write_completion(struct tevent_req *req)
5415 {
5416         size_t written;
5417         NTSTATUS status;
5418         status = cli_write_andx_recv(req, &written);
5419         TALLOC_FREE(req);
5420
5421         d_printf("cli_write_andx_recv returned %s: %d\n",
5422                  nt_errstr(status),
5423                  NT_STATUS_IS_OK(status) ? (int)written : -1);
5424 }
5425
5426 static void chain1_close_completion(struct tevent_req *req)
5427 {
5428         NTSTATUS status;
5429         bool *done = (bool *)tevent_req_callback_data_void(req);
5430
5431         status = cli_close_recv(req);
5432         *done = true;
5433
5434         TALLOC_FREE(req);
5435
5436         d_printf("cli_close returned %s\n", nt_errstr(status));
5437 }
5438
5439 static bool run_chain1(int dummy)
5440 {
5441         struct cli_state *cli1;
5442         struct event_context *evt = event_context_init(NULL);
5443         struct tevent_req *reqs[3], *smbreqs[3];
5444         bool done = false;
5445         const char *str = "foobar";
5446         NTSTATUS status;
5447
5448         printf("starting chain1 test\n");
5449         if (!torture_open_connection(&cli1, 0)) {
5450                 return False;
5451         }
5452
5453         cli_sockopt(cli1, sockops);
5454
5455         reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5456                                   O_CREAT|O_RDWR, 0, &smbreqs[0]);
5457         if (reqs[0] == NULL) return false;
5458         tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5459
5460
5461         reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5462                                         (uint8_t *)str, 0, strlen(str)+1,
5463                                         smbreqs, 1, &smbreqs[1]);
5464         if (reqs[1] == NULL) return false;
5465         tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5466
5467         reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5468         if (reqs[2] == NULL) return false;
5469         tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5470
5471         status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5472         if (!NT_STATUS_IS_OK(status)) {
5473                 return false;
5474         }
5475
5476         while (!done) {
5477                 event_loop_once(evt);
5478         }
5479
5480         torture_close_connection(cli1);
5481         return True;
5482 }
5483
5484 static void chain2_sesssetup_completion(struct tevent_req *req)
5485 {
5486         NTSTATUS status;
5487         status = cli_session_setup_guest_recv(req);
5488         d_printf("sesssetup returned %s\n", nt_errstr(status));
5489 }
5490
5491 static void chain2_tcon_completion(struct tevent_req *req)
5492 {
5493         bool *done = (bool *)tevent_req_callback_data_void(req);
5494         NTSTATUS status;
5495         status = cli_tcon_andx_recv(req);
5496         d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5497         *done = true;
5498 }
5499
5500 static bool run_chain2(int dummy)
5501 {
5502         struct cli_state *cli1;
5503         struct event_context *evt = event_context_init(NULL);
5504         struct tevent_req *reqs[2], *smbreqs[2];
5505         bool done = false;
5506         NTSTATUS status;
5507
5508         printf("starting chain2 test\n");
5509         status = cli_start_connection(&cli1, global_myname(), host, NULL,
5510                                       port_to_use, Undefined, 0, NULL);
5511         if (!NT_STATUS_IS_OK(status)) {
5512                 return False;
5513         }
5514
5515         cli_sockopt(cli1, sockops);
5516
5517         reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5518                                                  &smbreqs[0]);
5519         if (reqs[0] == NULL) return false;
5520         tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5521
5522         reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5523                                        "?????", NULL, 0, &smbreqs[1]);
5524         if (reqs[1] == NULL) return false;
5525         tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
5526
5527         status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5528         if (!NT_STATUS_IS_OK(status)) {
5529                 return false;
5530         }
5531
5532         while (!done) {
5533                 event_loop_once(evt);
5534         }
5535
5536         torture_close_connection(cli1);
5537         return True;
5538 }
5539
5540
5541 struct torture_createdel_state {
5542         struct tevent_context *ev;
5543         struct cli_state *cli;
5544 };
5545
5546 static void torture_createdel_created(struct tevent_req *subreq);
5547 static void torture_createdel_closed(struct tevent_req *subreq);
5548
5549 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
5550                                                  struct tevent_context *ev,
5551                                                  struct cli_state *cli,
5552                                                  const char *name)
5553 {
5554         struct tevent_req *req, *subreq;
5555         struct torture_createdel_state *state;
5556
5557         req = tevent_req_create(mem_ctx, &state,
5558                                 struct torture_createdel_state);
5559         if (req == NULL) {
5560                 return NULL;
5561         }
5562         state->ev = ev;
5563         state->cli = cli;
5564
5565         subreq = cli_ntcreate_send(
5566                 state, ev, cli, name, 0,
5567                 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5568                 FILE_ATTRIBUTE_NORMAL,
5569                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5570                 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
5571
5572         if (tevent_req_nomem(subreq, req)) {
5573                 return tevent_req_post(req, ev);
5574         }
5575         tevent_req_set_callback(subreq, torture_createdel_created, req);
5576         return req;
5577 }
5578
5579 static void torture_createdel_created(struct tevent_req *subreq)
5580 {
5581         struct tevent_req *req = tevent_req_callback_data(
5582                 subreq, struct tevent_req);
5583         struct torture_createdel_state *state = tevent_req_data(
5584                 req, struct torture_createdel_state);
5585         NTSTATUS status;
5586         uint16_t fnum;
5587
5588         status = cli_ntcreate_recv(subreq, &fnum);
5589         TALLOC_FREE(subreq);
5590         if (!NT_STATUS_IS_OK(status)) {
5591                 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
5592                            nt_errstr(status)));
5593                 tevent_req_nterror(req, status);
5594                 return;
5595         }
5596
5597         subreq = cli_close_send(state, state->ev, state->cli, fnum);
5598         if (tevent_req_nomem(subreq, req)) {
5599                 return;
5600         }
5601         tevent_req_set_callback(subreq, torture_createdel_closed, req);
5602 }
5603
5604 static void torture_createdel_closed(struct tevent_req *subreq)
5605 {
5606         struct tevent_req *req = tevent_req_callback_data(
5607                 subreq, struct tevent_req);
5608         NTSTATUS status;
5609
5610         status = cli_close_recv(subreq);
5611         if (!NT_STATUS_IS_OK(status)) {
5612                 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
5613                 tevent_req_nterror(req, status);
5614                 return;
5615         }
5616         tevent_req_done(req);
5617 }
5618
5619 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
5620 {
5621         return tevent_req_simple_recv_ntstatus(req);
5622 }
5623
5624 struct torture_createdels_state {
5625         struct tevent_context *ev;
5626         struct cli_state *cli;
5627         const char *base_name;
5628         int sent;
5629         int received;
5630         int num_files;
5631         struct tevent_req **reqs;
5632 };
5633
5634 static void torture_createdels_done(struct tevent_req *subreq);
5635
5636 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
5637                                                   struct tevent_context *ev,
5638                                                   struct cli_state *cli,
5639                                                   const char *base_name,
5640                                                   int num_parallel,
5641                                                   int num_files)
5642 {
5643         struct tevent_req *req;
5644         struct torture_createdels_state *state;
5645         int i;
5646
5647         req = tevent_req_create(mem_ctx, &state,
5648                                 struct torture_createdels_state);
5649         if (req == NULL) {
5650                 return NULL;
5651         }
5652         state->ev = ev;
5653         state->cli = cli;
5654         state->base_name = talloc_strdup(state, base_name);
5655         if (tevent_req_nomem(state->base_name, req)) {
5656                 return tevent_req_post(req, ev);
5657         }
5658         state->num_files = MAX(num_parallel, num_files);
5659         state->sent = 0;
5660         state->received = 0;
5661
5662         state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
5663         if (tevent_req_nomem(state->reqs, req)) {
5664                 return tevent_req_post(req, ev);
5665         }
5666
5667         for (i=0; i<num_parallel; i++) {
5668                 char *name;
5669
5670                 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5671                                        state->sent);
5672                 if (tevent_req_nomem(name, req)) {
5673                         return tevent_req_post(req, ev);
5674                 }
5675                 state->reqs[i] = torture_createdel_send(
5676                         state->reqs, state->ev, state->cli, name);
5677                 if (tevent_req_nomem(state->reqs[i], req)) {
5678                         return tevent_req_post(req, ev);
5679                 }
5680                 name = talloc_move(state->reqs[i], &name);
5681                 tevent_req_set_callback(state->reqs[i],
5682                                         torture_createdels_done, req);
5683                 state->sent += 1;
5684         }
5685         return req;
5686 }
5687
5688 static void torture_createdels_done(struct tevent_req *subreq)
5689 {
5690         struct tevent_req *req = tevent_req_callback_data(
5691                 subreq, struct tevent_req);
5692         struct torture_createdels_state *state = tevent_req_data(
5693                 req, struct torture_createdels_state);
5694         size_t num_parallel = talloc_array_length(state->reqs);
5695         NTSTATUS status;
5696         char *name;
5697         int i;
5698
5699         status = torture_createdel_recv(subreq);
5700         if (!NT_STATUS_IS_OK(status)){
5701                 DEBUG(10, ("torture_createdel_recv returned %s\n",
5702                            nt_errstr(status)));
5703                 TALLOC_FREE(subreq);
5704                 tevent_req_nterror(req, status);
5705                 return;
5706         }
5707
5708         for (i=0; i<num_parallel; i++) {
5709                 if (subreq == state->reqs[i]) {
5710                         break;
5711                 }
5712         }
5713         if (i == num_parallel) {
5714                 DEBUG(10, ("received something we did not send\n"));
5715                 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
5716                 return;
5717         }
5718         TALLOC_FREE(state->reqs[i]);
5719
5720         if (state->sent >= state->num_files) {
5721                 tevent_req_done(req);
5722                 return;
5723         }
5724
5725         name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5726                                state->sent);
5727         if (tevent_req_nomem(name, req)) {
5728                 return;
5729         }
5730         state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
5731                                                 state->cli, name);
5732         if (tevent_req_nomem(state->reqs[i], req)) {
5733                 return;
5734         }
5735         name = talloc_move(state->reqs[i], &name);
5736         tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
5737         state->sent += 1;
5738 }
5739
5740 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
5741 {
5742         return tevent_req_simple_recv_ntstatus(req);
5743 }
5744
5745 struct swallow_notify_state {
5746         struct tevent_context *ev;
5747         struct cli_state *cli;
5748         uint16_t fnum;
5749         uint32_t completion_filter;
5750         bool recursive;
5751         bool (*fn)(uint32_t action, const char *name, void *priv);
5752         void *priv;
5753 };
5754
5755 static void swallow_notify_done(struct tevent_req *subreq);
5756
5757 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
5758                                               struct tevent_context *ev,
5759                                               struct cli_state *cli,
5760                                               uint16_t fnum,
5761                                               uint32_t completion_filter,
5762                                               bool recursive,
5763                                               bool (*fn)(uint32_t action,
5764                                                          const char *name,
5765                                                          void *priv),
5766                                               void *priv)
5767 {
5768         struct tevent_req *req, *subreq;
5769         struct swallow_notify_state *state;
5770
5771         req = tevent_req_create(mem_ctx, &state,
5772                                 struct swallow_notify_state);
5773         if (req == NULL) {
5774                 return NULL;
5775         }
5776         state->ev = ev;
5777         state->cli = cli;
5778         state->fnum = fnum;
5779         state->completion_filter = completion_filter;
5780         state->recursive = recursive;
5781         state->fn = fn;
5782         state->priv = priv;
5783
5784         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5785                                  0xffff, state->completion_filter,
5786                                  state->recursive);
5787         if (tevent_req_nomem(subreq, req)) {
5788                 return tevent_req_post(req, ev);
5789         }
5790         tevent_req_set_callback(subreq, swallow_notify_done, req);
5791         return req;
5792 }
5793
5794 static void swallow_notify_done(struct tevent_req *subreq)
5795 {
5796         struct tevent_req *req = tevent_req_callback_data(
5797                 subreq, struct tevent_req);
5798         struct swallow_notify_state *state = tevent_req_data(
5799                 req, struct swallow_notify_state);
5800         NTSTATUS status;
5801         uint32_t i, num_changes;
5802         struct notify_change *changes;
5803
5804         status = cli_notify_recv(subreq, state, &num_changes, &changes);
5805         TALLOC_FREE(subreq);
5806         if (!NT_STATUS_IS_OK(status)) {
5807                 DEBUG(10, ("cli_notify_recv returned %s\n",
5808                            nt_errstr(status)));
5809                 tevent_req_nterror(req, status);
5810                 return;
5811         }
5812
5813         for (i=0; i<num_changes; i++) {
5814                 state->fn(changes[i].action, changes[i].name, state->priv);
5815         }
5816         TALLOC_FREE(changes);
5817
5818         subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5819                                  0xffff, state->completion_filter,
5820                                  state->recursive);
5821         if (tevent_req_nomem(subreq, req)) {
5822                 return;
5823         }
5824         tevent_req_set_callback(subreq, swallow_notify_done, req);
5825 }
5826
5827 static bool print_notifies(uint32_t action, const char *name, void *priv)
5828 {
5829         if (DEBUGLEVEL > 5) {
5830                 d_printf("%d %s\n", (int)action, name);
5831         }
5832         return true;
5833 }
5834
5835 static void notify_bench_done(struct tevent_req *req)
5836 {
5837         int *num_finished = (int *)tevent_req_callback_data_void(req);
5838         *num_finished += 1;
5839 }
5840
5841 static bool run_notify_bench(int dummy)
5842 {
5843         const char *dname = "\\notify-bench";
5844         struct tevent_context *ev;
5845         NTSTATUS status;
5846         uint16_t dnum;
5847         struct tevent_req *req1;
5848         struct tevent_req *req2 = NULL;
5849         int i, num_unc_names;
5850         int num_finished = 0;
5851
5852         printf("starting notify-bench test\n");
5853
5854         if (use_multishare_conn) {
5855                 char **unc_list;
5856                 unc_list = file_lines_load(multishare_conn_fname,
5857                                            &num_unc_names, 0, NULL);
5858                 if (!unc_list || num_unc_names <= 0) {
5859                         d_printf("Failed to load unc names list from '%s'\n",
5860                                  multishare_conn_fname);
5861                         return false;
5862                 }
5863                 TALLOC_FREE(unc_list);
5864         } else {
5865                 num_unc_names = 1;
5866         }
5867
5868         ev = tevent_context_init(talloc_tos());
5869         if (ev == NULL) {
5870                 d_printf("tevent_context_init failed\n");
5871                 return false;
5872         }
5873
5874         for (i=0; i<num_unc_names; i++) {
5875                 struct cli_state *cli;
5876                 char *base_fname;
5877
5878                 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
5879                                              dname, i);
5880                 if (base_fname == NULL) {
5881                         return false;
5882                 }
5883
5884                 if (!torture_open_connection(&cli, i)) {
5885                         return false;
5886                 }
5887
5888                 status = cli_ntcreate(cli, dname, 0,
5889                                       MAXIMUM_ALLOWED_ACCESS,
5890                                       0, FILE_SHARE_READ|FILE_SHARE_WRITE|
5891                                       FILE_SHARE_DELETE,
5892                                       FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
5893                                       &dnum);
5894
5895                 if (!NT_STATUS_IS_OK(status)) {
5896                         d_printf("Could not create %s: %s\n", dname,
5897                                  nt_errstr(status));
5898                         return false;
5899                 }
5900
5901                 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
5902                                            FILE_NOTIFY_CHANGE_FILE_NAME |
5903                                            FILE_NOTIFY_CHANGE_DIR_NAME |
5904                                            FILE_NOTIFY_CHANGE_ATTRIBUTES |
5905                                            FILE_NOTIFY_CHANGE_LAST_WRITE,
5906                                            false, print_notifies, NULL);
5907                 if (req1 == NULL) {
5908                         d_printf("Could not create notify request\n");
5909                         return false;
5910                 }
5911
5912                 req2 = torture_createdels_send(talloc_tos(), ev, cli,
5913                                                base_fname, 10, torture_numops);
5914                 if (req2 == NULL) {
5915                         d_printf("Could not create createdels request\n");
5916                         return false;
5917                 }
5918                 TALLOC_FREE(base_fname);
5919
5920                 tevent_req_set_callback(req2, notify_bench_done,
5921                                         &num_finished);
5922         }
5923
5924         while (num_finished < num_unc_names) {
5925                 int ret;
5926                 ret = tevent_loop_once(ev);
5927                 if (ret != 0) {
5928                         d_printf("tevent_loop_once failed\n");
5929                         return false;
5930                 }
5931         }
5932
5933         if (!tevent_req_poll(req2, ev)) {
5934                 d_printf("tevent_req_poll failed\n");
5935         }
5936
5937         status = torture_createdels_recv(req2);
5938         d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
5939
5940         return true;
5941 }
5942
5943 static bool run_mangle1(int dummy)
5944 {
5945         struct cli_state *cli;
5946         const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
5947         uint16_t fnum;
5948         fstring alt_name;
5949         NTSTATUS status;
5950         time_t change_time, access_time, write_time;
5951         SMB_OFF_T size;
5952         uint16_t mode;
5953
5954         printf("starting mangle1 test\n");
5955         if (!torture_open_connection(&cli, 0)) {
5956                 return False;
5957         }
5958
5959         cli_sockopt(cli, sockops);
5960
5961         if (!NT_STATUS_IS_OK(cli_ntcreate(
5962                         cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5963                         FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5964                 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
5965                 return false;
5966         }
5967         cli_close(cli, fnum);
5968
5969         status = cli_qpathinfo_alt_name(cli, fname, alt_name);
5970         if (!NT_STATUS_IS_OK(status)) {
5971                 d_printf("cli_qpathinfo_alt_name failed: %s\n",
5972                          nt_errstr(status));
5973                 return false;
5974         }
5975         d_printf("alt_name: %s\n", alt_name);
5976
5977         if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
5978                 d_printf("cli_open(%s) failed: %s\n", alt_name,
5979                          cli_errstr(cli));
5980                 return false;
5981         }
5982         cli_close(cli, fnum);
5983
5984         status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
5985                                 &write_time, &size, &mode);
5986         if (!NT_STATUS_IS_OK(status)) {
5987                 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
5988                          nt_errstr(status));
5989                 return false;
5990         }
5991
5992         return true;
5993 }
5994
5995 static size_t null_source(uint8_t *buf, size_t n, void *priv)
5996 {
5997         size_t *to_pull = (size_t *)priv;
5998         size_t thistime = *to_pull;
5999
6000         thistime = MIN(thistime, n);
6001         if (thistime == 0) {
6002                 return 0;
6003         }
6004
6005         memset(buf, 0, thistime);
6006         *to_pull -= thistime;
6007         return thistime;
6008 }
6009
6010 static bool run_windows_write(int dummy)
6011 {
6012         struct cli_state *cli1;
6013         uint16_t fnum;
6014         int i;
6015         bool ret = false;
6016         const char *fname = "\\writetest.txt";
6017         struct timeval start_time;
6018         double seconds;
6019         double kbytes;
6020
6021         printf("starting windows_write test\n");
6022         if (!torture_open_connection(&cli1, 0)) {
6023                 return False;
6024         }
6025
6026         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6027                 printf("open failed (%s)\n", cli_errstr(cli1));
6028                 return False;
6029         }
6030
6031         cli_sockopt(cli1, sockops);
6032
6033         start_time = timeval_current();
6034
6035         for (i=0; i<torture_numops; i++) {
6036                 char c = 0;
6037                 off_t start = i * torture_blocksize;
6038                 NTSTATUS status;
6039                 size_t to_pull = torture_blocksize - 1;
6040
6041                 if (cli_write(cli1, fnum, 0, &c,
6042                               start + torture_blocksize - 1, 1) != 1) {
6043                         printf("cli_write failed: %s\n", cli_errstr(cli1));
6044                         goto fail;
6045                 }
6046
6047                 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6048                                   null_source, &to_pull);
6049                 if (!NT_STATUS_IS_OK(status)) {
6050                         printf("cli_push returned: %s\n", nt_errstr(status));
6051                         goto fail;
6052                 }
6053         }
6054
6055         seconds = timeval_elapsed(&start_time);
6056         kbytes = (double)torture_blocksize * torture_numops;
6057         kbytes /= 1024;
6058
6059         printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6060                (double)seconds, (int)(kbytes/seconds));
6061
6062         ret = true;
6063  fail:
6064         cli_close(cli1, fnum);
6065         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6066         torture_close_connection(cli1);
6067         return ret;
6068 }
6069
6070 static bool run_cli_echo(int dummy)
6071 {
6072         struct cli_state *cli;
6073         NTSTATUS status;
6074
6075         printf("starting cli_echo test\n");
6076         if (!torture_open_connection(&cli, 0)) {
6077                 return false;
6078         }
6079         cli_sockopt(cli, sockops);
6080
6081         status = cli_echo(cli, 5, data_blob_const("hello", 5));
6082
6083         d_printf("cli_echo returned %s\n", nt_errstr(status));
6084
6085         torture_close_connection(cli);
6086         return NT_STATUS_IS_OK(status);
6087 }
6088
6089 static bool run_uid_regression_test(int dummy)
6090 {
6091         static struct cli_state *cli;
6092         int16_t old_vuid;
6093         int16_t old_cnum;
6094         bool correct = True;
6095         NTSTATUS status;
6096
6097         printf("starting uid regression test\n");
6098
6099         if (!torture_open_connection(&cli, 0)) {
6100                 return False;
6101         }
6102
6103         cli_sockopt(cli, sockops);
6104
6105         /* Ok - now save then logoff our current user. */
6106         old_vuid = cli->vuid;
6107
6108         status = cli_ulogoff(cli);
6109         if (!NT_STATUS_IS_OK(status)) {
6110                 d_printf("(%s) cli_ulogoff failed: %s\n",
6111                          __location__, nt_errstr(status));
6112                 correct = false;
6113                 goto out;
6114         }
6115
6116         cli->vuid = old_vuid;
6117
6118         /* Try an operation. */
6119         if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\uid_reg_test"))) {
6120                 /* We expect bad uid. */
6121                 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6122                                 NT_STATUS_NO_SUCH_USER)) {
6123                         return False;
6124                 }
6125         }
6126
6127         old_cnum = cli->cnum;
6128
6129         /* Now try a SMBtdis with the invald vuid set to zero. */
6130         cli->vuid = 0;
6131
6132         /* This should succeed. */
6133         status = cli_tdis(cli);
6134
6135         if (NT_STATUS_IS_OK(status)) {
6136                 printf("First tdis with invalid vuid should succeed.\n");
6137         } else {
6138                 printf("First tdis failed (%s)\n", nt_errstr(status));
6139         }
6140
6141         cli->vuid = old_vuid;
6142         cli->cnum = old_cnum;
6143
6144         /* This should fail. */
6145         status = cli_tdis(cli);
6146         if (NT_STATUS_IS_OK(status)) {
6147                 printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6148         } else {
6149                 /* Should be bad tid. */
6150                 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6151                                 NT_STATUS_NETWORK_NAME_DELETED)) {
6152                         return False;
6153                 }
6154         }
6155
6156         cli_rmdir(cli, "\\uid_reg_test");
6157
6158   out:
6159
6160         cli_shutdown(cli);
6161         return correct;
6162 }
6163
6164
6165 static const char *illegal_chars = "*\\/?<>|\":";
6166 static char force_shortname_chars[] = " +,.[];=\177";
6167
6168 static void shortname_del_fn(const char *mnt, struct file_info *finfo,
6169                              const char *mask, void *state)
6170 {
6171         struct cli_state *pcli = (struct cli_state *)state;
6172         fstring fname;
6173         slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6174
6175         if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6176                 return;
6177
6178         if (finfo->mode & aDIR) {
6179                 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
6180                         printf("del_fn: failed to rmdir %s\n,", fname );
6181         } else {
6182                 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
6183                         printf("del_fn: failed to unlink %s\n,", fname );
6184         }
6185 }
6186
6187 struct sn_state {
6188         int matched;
6189         int i;
6190         bool val;
6191 };
6192
6193 static void shortname_list_fn(const char *mnt, struct file_info *finfo,
6194                               const char *name, void *state)
6195 {
6196         struct sn_state *s = (struct sn_state  *)state;
6197         int i = s->i;
6198
6199 #if 0
6200         printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6201                 i, finfo->name, finfo->short_name);
6202 #endif
6203
6204         if (strchr(force_shortname_chars, i)) {
6205                 if (!finfo->short_name[0]) {
6206                         /* Shortname not created when it should be. */
6207                         d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6208                                 __location__, finfo->name, i);
6209                         s->val = true;
6210                 }
6211         } else if (finfo->short_name[0]){
6212                 /* Shortname created when it should not be. */
6213                 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6214                         __location__, finfo->short_name, finfo->name);
6215                 s->val = true;
6216         }
6217         s->matched += 1;
6218 }
6219
6220 static bool run_shortname_test(int dummy)
6221 {
6222         static struct cli_state *cli;
6223         bool correct = True;
6224         int i;
6225         struct sn_state s;
6226         char fname[20];
6227
6228         printf("starting shortname test\n");
6229
6230         if (!torture_open_connection(&cli, 0)) {
6231                 return False;
6232         }
6233
6234         cli_sockopt(cli, sockops);
6235
6236         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6237         cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6238         cli_rmdir(cli, "\\shortname");
6239
6240         if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6241                 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6242                         __location__, cli_errstr(cli));
6243                 correct = false;
6244                 goto out;
6245         }
6246
6247         strlcpy(fname, "\\shortname\\", sizeof(fname));
6248         strlcat(fname, "test .txt", sizeof(fname));
6249
6250         s.val = false;
6251
6252         for (i = 32; i < 128; i++) {
6253                 NTSTATUS status;
6254                 uint16_t fnum = (uint16_t)-1;
6255
6256                 s.i = i;
6257
6258                 if (strchr(illegal_chars, i)) {
6259                         continue;
6260                 }
6261                 fname[15] = i;
6262
6263                 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6264                                    FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6265                 if (!NT_STATUS_IS_OK(status)) {
6266                         d_printf("(%s) cli_nt_create of %s failed: %s\n",
6267                                 __location__, fname, cli_errstr(cli));
6268                         correct = false;
6269                         goto out;
6270                 }
6271                 cli_close(cli, fnum);
6272
6273                 s.matched = 0;
6274                 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6275                          &s);
6276                 if (s.matched != 1) {
6277                         d_printf("(%s) failed to list %s: %s\n",
6278                                 __location__, fname, cli_errstr(cli));
6279                         correct = false;
6280                         goto out;
6281                 }
6282                 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6283                         d_printf("(%s) failed to delete %s: %s\n",
6284                                 __location__, fname, cli_errstr(cli));
6285                         correct = false;
6286                         goto out;
6287                 }
6288
6289                 if (s.val) {
6290                         correct = false;
6291                         goto out;
6292                 }
6293         }
6294
6295   out:
6296
6297         cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6298         cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6299         cli_rmdir(cli, "\\shortname");
6300         torture_close_connection(cli);
6301         return correct;
6302 }
6303
6304 static void pagedsearch_cb(struct tevent_req *req)
6305 {
6306         int rc;
6307         struct tldap_message *msg;
6308         char *dn;
6309
6310         rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6311         if (rc != TLDAP_SUCCESS) {
6312                 d_printf("tldap_search_paged_recv failed: %s\n",
6313                          tldap_err2string(rc));
6314                 return;
6315         }
6316         if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6317                 TALLOC_FREE(msg);
6318                 return;
6319         }
6320         if (!tldap_entry_dn(msg, &dn)) {
6321                 d_printf("tldap_entry_dn failed\n");
6322                 return;
6323         }
6324         d_printf("%s\n", dn);
6325         TALLOC_FREE(msg);
6326 }
6327
6328 static bool run_tldap(int dummy)
6329 {
6330         struct tldap_context *ld;
6331         int fd, rc;
6332         NTSTATUS status;
6333         struct sockaddr_storage addr;
6334         struct tevent_context *ev;
6335         struct tevent_req *req;
6336         char *basedn;
6337         const char *filter;
6338
6339         if (!resolve_name(host, &addr, 0, false)) {
6340                 d_printf("could not find host %s\n", host);
6341                 return false;
6342         }
6343         status = open_socket_out(&addr, 389, 9999, &fd);
6344         if (!NT_STATUS_IS_OK(status)) {
6345                 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6346                 return false;
6347         }
6348
6349         ld = tldap_context_create(talloc_tos(), fd);
6350         if (ld == NULL) {
6351                 close(fd);
6352                 d_printf("tldap_context_create failed\n");
6353                 return false;
6354         }
6355
6356         rc = tldap_fetch_rootdse(ld);
6357         if (rc != TLDAP_SUCCESS) {
6358                 d_printf("tldap_fetch_rootdse failed: %s\n",
6359                          tldap_errstr(talloc_tos(), ld, rc));
6360                 return false;
6361         }
6362
6363         basedn = tldap_talloc_single_attribute(
6364                 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6365         if (basedn == NULL) {
6366                 d_printf("no defaultNamingContext\n");
6367                 return false;
6368         }
6369         d_printf("defaultNamingContext: %s\n", basedn);
6370
6371         ev = tevent_context_init(talloc_tos());
6372         if (ev == NULL) {
6373                 d_printf("tevent_context_init failed\n");
6374                 return false;
6375         }
6376
6377         req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6378                                       TLDAP_SCOPE_SUB, "(objectclass=*)",
6379                                       NULL, 0, 0,
6380                                       NULL, 0, NULL, 0, 0, 0, 0, 5);
6381         if (req == NULL) {
6382                 d_printf("tldap_search_paged_send failed\n");
6383                 return false;
6384         }
6385         tevent_req_set_callback(req, pagedsearch_cb, NULL);
6386
6387         tevent_req_poll(req, ev);
6388
6389         TALLOC_FREE(req);
6390
6391         /* test search filters against rootDSE */
6392         filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6393                    "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6394
6395         rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6396                           NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6397                           talloc_tos(), NULL, NULL);
6398         if (rc != TLDAP_SUCCESS) {
6399                 d_printf("tldap_search with complex filter failed: %s\n",
6400                          tldap_errstr(talloc_tos(), ld, rc));
6401                 return false;
6402         }
6403
6404         TALLOC_FREE(ld);
6405         return true;
6406 }
6407
6408 /* Torture test to ensure no regression of :
6409 https://bugzilla.samba.org/show_bug.cgi?id=7084
6410 */
6411
6412 static bool run_dir_createtime(int dummy)
6413 {
6414         struct cli_state *cli;
6415         const char *dname = "\\testdir";
6416         const char *fname = "\\testdir\\testfile";
6417         NTSTATUS status;
6418         struct timespec create_time;
6419         struct timespec create_time1;
6420         uint16_t fnum;
6421         bool ret = false;
6422
6423         if (!torture_open_connection(&cli, 0)) {
6424                 return false;
6425         }
6426
6427         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6428         cli_rmdir(cli, dname);
6429
6430         status = cli_mkdir(cli, dname);
6431         if (!NT_STATUS_IS_OK(status)) {
6432                 printf("mkdir failed: %s\n", nt_errstr(status));
6433                 goto out;
6434         }
6435
6436         status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
6437                                 NULL, NULL, NULL);
6438         if (!NT_STATUS_IS_OK(status)) {
6439                 printf("cli_qpathinfo2 returned %s\n",
6440                        nt_errstr(status));
6441                 goto out;
6442         }
6443
6444         /* Sleep 3 seconds, then create a file. */
6445         sleep(3);
6446
6447         status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6448                          DENY_NONE, &fnum);
6449         if (!NT_STATUS_IS_OK(status)) {
6450                 printf("cli_open failed: %s\n", nt_errstr(status));
6451                 goto out;
6452         }
6453
6454         status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
6455                                 NULL, NULL, NULL);
6456         if (!NT_STATUS_IS_OK(status)) {
6457                 printf("cli_qpathinfo2 (2) returned %s\n",
6458                        nt_errstr(status));
6459                 goto out;
6460         }
6461
6462         if (timespec_compare(&create_time1, &create_time)) {
6463                 printf("run_dir_createtime: create time was updated (error)\n");
6464         } else {
6465                 printf("run_dir_createtime: create time was not updated (correct)\n");
6466                 ret = true;
6467         }
6468
6469   out:
6470
6471         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6472         cli_rmdir(cli, dname);
6473         if (!torture_close_connection(cli)) {
6474                 ret = false;
6475         }
6476         return ret;
6477 }
6478
6479
6480 static bool run_streamerror(int dummy)
6481 {
6482         struct cli_state *cli;
6483         const char *dname = "\\testdir";
6484         const char *streamname =
6485                 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6486         NTSTATUS status;
6487         time_t change_time, access_time, write_time;
6488         SMB_OFF_T size;
6489         uint16_t mode, fnum;
6490         bool ret = true;
6491
6492         if (!torture_open_connection(&cli, 0)) {
6493                 return false;
6494         }
6495
6496         cli_unlink(cli, "\\testdir\\*", aSYSTEM | aHIDDEN);
6497         cli_rmdir(cli, dname);
6498
6499         status = cli_mkdir(cli, dname);
6500         if (!NT_STATUS_IS_OK(status)) {
6501                 printf("mkdir failed: %s\n", nt_errstr(status));
6502                 return false;
6503         }
6504
6505         cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
6506                       &size, &mode);
6507         status = cli_nt_error(cli);
6508
6509         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6510                 printf("pathinfo returned %s, expected "
6511                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6512                        nt_errstr(status));
6513                 ret = false;
6514         }
6515
6516         status = cli_ntcreate(cli, streamname, 0x16,
6517                               FILE_READ_DATA|FILE_READ_EA|
6518                               FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
6519                               FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6520                               FILE_OPEN, 0, 0, &fnum);
6521
6522         if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6523                 printf("ntcreate returned %s, expected "
6524                        "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6525                        nt_errstr(status));
6526                 ret = false;
6527         }
6528
6529
6530         cli_rmdir(cli, dname);
6531         return ret;
6532 }
6533
6534 static bool run_local_substitute(int dummy)
6535 {
6536         bool ok = true;
6537
6538         ok &= subst_test("%U", "bla", "", -1, -1, "bla");
6539         ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
6540         ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
6541         ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
6542         ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
6543         ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
6544         ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
6545         ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
6546
6547         /* Different captialization rules in sub_basic... */
6548
6549         ok &=  (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
6550                        "blaDOM") == 0);
6551
6552         return ok;
6553 }
6554
6555 static bool run_local_base64(int dummy)
6556 {
6557         int i;
6558         bool ret = true;
6559
6560         for (i=1; i<2000; i++) {
6561                 DATA_BLOB blob1, blob2;
6562                 char *b64;
6563
6564                 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
6565                 blob1.length = i;
6566                 generate_random_buffer(blob1.data, blob1.length);
6567
6568                 b64 = base64_encode_data_blob(talloc_tos(), blob1);
6569                 if (b64 == NULL) {
6570                         d_fprintf(stderr, "base64_encode_data_blob failed "
6571                                   "for %d bytes\n", i);
6572                         ret = false;
6573                 }
6574                 blob2 = base64_decode_data_blob(b64);
6575                 TALLOC_FREE(b64);
6576
6577                 if (data_blob_cmp(&blob1, &blob2)) {
6578                         d_fprintf(stderr, "data_blob_cmp failed for %d "
6579                                   "bytes\n", i);
6580                         ret = false;
6581                 }
6582                 TALLOC_FREE(blob1.data);
6583                 data_blob_free(&blob2);
6584         }
6585         return ret;
6586 }
6587
6588 static bool run_local_gencache(int dummy)
6589 {
6590         char *val;
6591         time_t tm;
6592         DATA_BLOB blob;
6593
6594         if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
6595                 d_printf("%s: gencache_set() failed\n", __location__);
6596                 return False;
6597         }
6598
6599         if (!gencache_get("foo", NULL, NULL)) {
6600                 d_printf("%s: gencache_get() failed\n", __location__);
6601                 return False;
6602         }
6603
6604         if (!gencache_get("foo", &val, &tm)) {
6605                 d_printf("%s: gencache_get() failed\n", __location__);
6606                 return False;
6607         }
6608
6609         if (strcmp(val, "bar") != 0) {
6610                 d_printf("%s: gencache_get() returned %s, expected %s\n",
6611                          __location__, val, "bar");
6612                 SAFE_FREE(val);
6613                 return False;
6614         }
6615
6616         SAFE_FREE(val);
6617
6618         if (!gencache_del("foo")) {
6619                 d_printf("%s: gencache_del() failed\n", __location__);
6620                 return False;
6621         }
6622         if (gencache_del("foo")) {
6623                 d_printf("%s: second gencache_del() succeeded\n",
6624                          __location__);
6625                 return False;
6626         }
6627
6628         if (gencache_get("foo", &val, &tm)) {
6629                 d_printf("%s: gencache_get() on deleted entry "
6630                          "succeeded\n", __location__);
6631                 return False;
6632         }
6633
6634         blob = data_blob_string_const_null("bar");
6635         tm = time(NULL) + 60;
6636
6637         if (!gencache_set_data_blob("foo", &blob, tm)) {
6638                 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
6639                 return False;
6640         }
6641
6642         if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6643                 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
6644                 return False;
6645         }
6646
6647         if (strcmp((const char *)blob.data, "bar") != 0) {
6648                 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
6649                          __location__, (const char *)blob.data, "bar");
6650                 data_blob_free(&blob);
6651                 return False;
6652         }
6653
6654         data_blob_free(&blob);
6655
6656         if (!gencache_del("foo")) {
6657                 d_printf("%s: gencache_del() failed\n", __location__);
6658                 return False;
6659         }
6660         if (gencache_del("foo")) {
6661                 d_printf("%s: second gencache_del() succeeded\n",
6662                          __location__);
6663                 return False;
6664         }
6665
6666         if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6667                 d_printf("%s: gencache_get_data_blob() on deleted entry "
6668                          "succeeded\n", __location__);
6669                 return False;
6670         }
6671
6672         return True;
6673 }
6674
6675 static bool rbt_testval(struct db_context *db, const char *key,
6676                         const char *value)
6677 {
6678         struct db_record *rec;
6679         TDB_DATA data = string_tdb_data(value);
6680         bool ret = false;
6681         NTSTATUS status;
6682
6683         rec = db->fetch_locked(db, db, string_tdb_data(key));
6684         if (rec == NULL) {
6685                 d_fprintf(stderr, "fetch_locked failed\n");
6686                 goto done;
6687         }
6688         status = rec->store(rec, data, 0);
6689         if (!NT_STATUS_IS_OK(status)) {
6690                 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
6691                 goto done;
6692         }
6693         TALLOC_FREE(rec);
6694
6695         rec = db->fetch_locked(db, db, string_tdb_data(key));
6696         if (rec == NULL) {
6697                 d_fprintf(stderr, "second fetch_locked failed\n");
6698                 goto done;
6699         }
6700         if ((rec->value.dsize != data.dsize)
6701             || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
6702                 d_fprintf(stderr, "Got wrong data back\n");
6703                 goto done;
6704         }
6705
6706         ret = true;
6707  done:
6708         TALLOC_FREE(rec);
6709         return ret;
6710 }
6711
6712 static bool run_local_rbtree(int dummy)
6713 {
6714         struct db_context *db;
6715         bool ret = false;
6716         int i;
6717
6718         db = db_open_rbt(NULL);
6719
6720         if (db == NULL) {
6721                 d_fprintf(stderr, "db_open_rbt failed\n");
6722                 return false;
6723         }
6724
6725         for (i=0; i<1000; i++) {
6726                 char *key, *value;
6727
6728                 if (asprintf(&key, "key%ld", random()) == -1) {
6729                         goto done;
6730                 }
6731                 if (asprintf(&value, "value%ld", random()) == -1) {
6732                         SAFE_FREE(key);
6733                         goto done;
6734                 }
6735
6736                 if (!rbt_testval(db, key, value)) {
6737                         SAFE_FREE(key);
6738                         SAFE_FREE(value);
6739                         goto done;
6740                 }
6741
6742                 SAFE_FREE(value);
6743                 if (asprintf(&value, "value%ld", random()) == -1) {
6744                         SAFE_FREE(key);
6745                         goto done;
6746                 }
6747
6748                 if (!rbt_testval(db, key, value)) {
6749                         SAFE_FREE(key);
6750                         SAFE_FREE(value);
6751                         goto done;
6752                 }
6753
6754                 SAFE_FREE(key);
6755                 SAFE_FREE(value);
6756         }
6757
6758         ret = true;
6759
6760  done:
6761         TALLOC_FREE(db);
6762         return ret;
6763 }
6764
6765 struct talloc_dict_test {
6766         int content;
6767 };
6768
6769 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
6770 {
6771         int *count = (int *)priv;
6772         *count += 1;
6773         return 0;
6774 }
6775
6776 static bool run_local_talloc_dict(int dummy)
6777 {
6778         struct talloc_dict *dict;
6779         struct talloc_dict_test *t;
6780         int key, count;
6781
6782         dict = talloc_dict_init(talloc_tos());
6783         if (dict == NULL) {
6784                 return false;
6785         }
6786
6787         t = talloc(talloc_tos(), struct talloc_dict_test);
6788         if (t == NULL) {
6789                 return false;
6790         }
6791
6792         key = 1;
6793         t->content = 1;
6794         if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
6795                 return false;
6796         }
6797
6798         count = 0;
6799         if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
6800                 return false;
6801         }
6802
6803         if (count != 1) {
6804                 return false;
6805         }
6806
6807         TALLOC_FREE(dict);
6808
6809         return true;
6810 }
6811
6812 static bool run_local_string_to_sid(int dummy) {
6813         struct dom_sid sid;
6814
6815         if (string_to_sid(&sid, "S--1-5-32-545")) {
6816                 printf("allowing S--1-5-32-545\n");
6817                 return false;
6818         }
6819         if (string_to_sid(&sid, "S-1-5-32-+545")) {
6820                 printf("allowing S-1-5-32-+545\n");
6821                 return false;
6822         }
6823         if (string_to_sid(&sid, "S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0")) {
6824                 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
6825                 return false;
6826         }
6827         if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
6828                 printf("allowing S-1-5-32-545-abc\n");
6829                 return false;
6830         }
6831         if (!string_to_sid(&sid, "S-1-5-32-545")) {
6832                 printf("could not parse S-1-5-32-545\n");
6833                 return false;
6834         }
6835         if (!sid_equal(&sid, &global_sid_Builtin_Users)) {
6836                 printf("mis-parsed S-1-5-32-545 as %s\n",
6837                        sid_string_tos(&sid));
6838                 return false;
6839         }
6840         return true;
6841 }
6842
6843 /* Split a path name into filename and stream name components. Canonicalise
6844  * such that an implicit $DATA token is always explicit.
6845  *
6846  * The "specification" of this function can be found in the
6847  * run_local_stream_name() function in torture.c, I've tried those
6848  * combinations against a W2k3 server.
6849  */
6850
6851 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
6852                                        char **pbase, char **pstream)
6853 {
6854         char *base = NULL;
6855         char *stream = NULL;
6856         char *sname; /* stream name */
6857         const char *stype; /* stream type */
6858
6859         DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
6860
6861         sname = strchr_m(fname, ':');
6862
6863         if (lp_posix_pathnames() || (sname == NULL)) {
6864                 if (pbase != NULL) {
6865                         base = talloc_strdup(mem_ctx, fname);
6866                         NT_STATUS_HAVE_NO_MEMORY(base);
6867                 }
6868                 goto done;
6869         }
6870
6871         if (pbase != NULL) {
6872                 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
6873                 NT_STATUS_HAVE_NO_MEMORY(base);
6874         }
6875
6876         sname += 1;
6877
6878         stype = strchr_m(sname, ':');
6879
6880         if (stype == NULL) {
6881                 sname = talloc_strdup(mem_ctx, sname);
6882                 stype = "$DATA";
6883         }
6884         else {
6885                 if (StrCaseCmp(stype, ":$DATA") != 0) {
6886                         /*
6887                          * If there is an explicit stream type, so far we only
6888                          * allow $DATA. Is there anything else allowed? -- vl
6889                          */
6890                         DEBUG(10, ("[%s] is an invalid stream type\n", stype));
6891                         TALLOC_FREE(base);
6892                         return NT_STATUS_OBJECT_NAME_INVALID;
6893                 }
6894                 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
6895                 stype += 1;
6896         }
6897
6898         if (sname == NULL) {
6899                 TALLOC_FREE(base);
6900                 return NT_STATUS_NO_MEMORY;
6901         }
6902
6903         if (sname[0] == '\0') {
6904                 /*
6905                  * no stream name, so no stream
6906                  */
6907                 goto done;
6908         }
6909
6910         if (pstream != NULL) {
6911                 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
6912                 if (stream == NULL) {
6913                         TALLOC_FREE(sname);
6914                         TALLOC_FREE(base);
6915                         return NT_STATUS_NO_MEMORY;
6916                 }
6917                 /*
6918                  * upper-case the type field
6919                  */
6920                 strupper_m(strchr_m(stream, ':')+1);
6921         }
6922
6923  done:
6924         if (pbase != NULL) {
6925                 *pbase = base;
6926         }
6927         if (pstream != NULL) {
6928                 *pstream = stream;
6929         }
6930         return NT_STATUS_OK;
6931 }
6932
6933 static bool test_stream_name(const char *fname, const char *expected_base,
6934                              const char *expected_stream,
6935                              NTSTATUS expected_status)
6936 {
6937         NTSTATUS status;
6938         char *base = NULL;
6939         char *stream = NULL;
6940
6941         status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
6942         if (!NT_STATUS_EQUAL(status, expected_status)) {
6943                 goto error;
6944         }
6945
6946         if (!NT_STATUS_IS_OK(status)) {
6947                 return true;
6948         }
6949
6950         if (base == NULL) goto error;
6951
6952         if (strcmp(expected_base, base) != 0) goto error;
6953
6954         if ((expected_stream != NULL) && (stream == NULL)) goto error;
6955         if ((expected_stream == NULL) && (stream != NULL)) goto error;
6956
6957         if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
6958                 goto error;
6959
6960         TALLOC_FREE(base);
6961         TALLOC_FREE(stream);
6962         return true;
6963
6964  error:
6965         d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
6966                   fname, expected_base ? expected_base : "<NULL>",
6967                   expected_stream ? expected_stream : "<NULL>",
6968                   nt_errstr(expected_status));
6969         d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
6970                   base ? base : "<NULL>", stream ? stream : "<NULL>",
6971                   nt_errstr(status));
6972         TALLOC_FREE(base);
6973         TALLOC_FREE(stream);
6974         return false;
6975 }
6976
6977 static bool run_local_stream_name(int dummy)
6978 {
6979         bool ret = true;
6980
6981         ret &= test_stream_name(
6982                 "bla", "bla", NULL, NT_STATUS_OK);
6983         ret &= test_stream_name(
6984                 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
6985         ret &= test_stream_name(
6986                 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6987         ret &= test_stream_name(
6988                 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
6989         ret &= test_stream_name(
6990                 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6991         ret &= test_stream_name(
6992                 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
6993         ret &= test_stream_name(
6994                 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
6995         ret &= test_stream_name(
6996                 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
6997
6998         return ret;
6999 }
7000
7001 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7002 {
7003         if (a.length != b.length) {
7004                 printf("a.length=%d != b.length=%d\n",
7005                        (int)a.length, (int)b.length);
7006                 return false;
7007         }
7008         if (memcmp(a.data, b.data, a.length) != 0) {
7009                 printf("a.data and b.data differ\n");
7010                 return false;
7011         }
7012         return true;
7013 }
7014
7015 static bool run_local_memcache(int dummy)
7016 {
7017         struct memcache *cache;
7018         DATA_BLOB k1, k2;
7019         DATA_BLOB d1, d2, d3;
7020         DATA_BLOB v1, v2, v3;
7021
7022         TALLOC_CTX *mem_ctx;
7023         char *str1, *str2;
7024         size_t size1, size2;
7025         bool ret = false;
7026
7027         cache = memcache_init(NULL, 100);
7028
7029         if (cache == NULL) {
7030                 printf("memcache_init failed\n");
7031                 return false;
7032         }
7033
7034         d1 = data_blob_const("d1", 2);
7035         d2 = data_blob_const("d2", 2);
7036         d3 = data_blob_const("d3", 2);
7037
7038         k1 = data_blob_const("d1", 2);
7039         k2 = data_blob_const("d2", 2);
7040
7041         memcache_add(cache, STAT_CACHE, k1, d1);
7042         memcache_add(cache, GETWD_CACHE, k2, d2);
7043
7044         if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7045                 printf("could not find k1\n");
7046                 return false;
7047         }
7048         if (!data_blob_equal(d1, v1)) {
7049                 return false;
7050         }
7051
7052         if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7053                 printf("could not find k2\n");
7054                 return false;
7055         }
7056         if (!data_blob_equal(d2, v2)) {
7057                 return false;
7058         }
7059
7060         memcache_add(cache, STAT_CACHE, k1, d3);
7061
7062         if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7063                 printf("could not find replaced k1\n");
7064                 return false;
7065         }
7066         if (!data_blob_equal(d3, v3)) {
7067                 return false;
7068         }
7069
7070         memcache_add(cache, GETWD_CACHE, k1, d1);
7071
7072         if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7073                 printf("Did find k2, should have been purged\n");
7074                 return false;
7075         }
7076
7077         TALLOC_FREE(cache);
7078
7079         cache = memcache_init(NULL, 0);
7080
7081         mem_ctx = talloc_init("foo");
7082
7083         str1 = talloc_strdup(mem_ctx, "string1");
7084         str2 = talloc_strdup(mem_ctx, "string2");
7085
7086         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7087                             data_blob_string_const("torture"), &str1);
7088         size1 = talloc_total_size(cache);
7089
7090         memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7091                             data_blob_string_const("torture"), &str2);
7092         size2 = talloc_total_size(cache);
7093
7094         printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7095
7096         if (size2 > size1) {
7097                 printf("memcache leaks memory!\n");
7098                 goto fail;
7099         }
7100
7101         ret = true;
7102  fail:
7103         TALLOC_FREE(cache);
7104         return ret;
7105 }
7106
7107 static void wbclient_done(struct tevent_req *req)
7108 {
7109         wbcErr wbc_err;
7110         struct winbindd_response *wb_resp;
7111         int *i = (int *)tevent_req_callback_data_void(req);
7112
7113         wbc_err = wb_trans_recv(req, req, &wb_resp);
7114         TALLOC_FREE(req);
7115         *i += 1;
7116         d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7117 }
7118
7119 static bool run_local_wbclient(int dummy)
7120 {
7121         struct event_context *ev;
7122         struct wb_context **wb_ctx;
7123         struct winbindd_request wb_req;
7124         bool result = false;
7125         int i, j;
7126
7127         BlockSignals(True, SIGPIPE);
7128
7129         ev = tevent_context_init_byname(talloc_tos(), "epoll");
7130         if (ev == NULL) {
7131                 goto fail;
7132         }
7133
7134         wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7135         if (wb_ctx == NULL) {
7136                 goto fail;
7137         }
7138
7139         ZERO_STRUCT(wb_req);
7140         wb_req.cmd = WINBINDD_PING;
7141
7142         d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7143
7144         for (i=0; i<nprocs; i++) {
7145                 wb_ctx[i] = wb_context_init(ev, NULL);
7146                 if (wb_ctx[i] == NULL) {
7147                         goto fail;
7148                 }
7149                 for (j=0; j<torture_numops; j++) {
7150                         struct tevent_req *req;
7151                         req = wb_trans_send(ev, ev, wb_ctx[i],
7152                                             (j % 2) == 0, &wb_req);
7153                         if (req == NULL) {
7154                                 goto fail;
7155                         }
7156                         tevent_req_set_callback(req, wbclient_done, &i);
7157                 }
7158         }
7159
7160         i = 0;
7161
7162         while (i < nprocs * torture_numops) {
7163                 event_loop_once(ev);
7164         }
7165
7166         result = true;
7167  fail:
7168         TALLOC_FREE(ev);
7169         return result;
7170 }
7171
7172 static void getaddrinfo_finished(struct tevent_req *req)
7173 {
7174         char *name = (char *)tevent_req_callback_data_void(req);
7175         struct addrinfo *ainfo;
7176         int res;
7177
7178         res = getaddrinfo_recv(req, &ainfo);
7179         if (res != 0) {
7180                 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7181                 return;
7182         }
7183         d_printf("gai(%s) succeeded\n", name);
7184         freeaddrinfo(ainfo);
7185 }
7186
7187 static bool run_getaddrinfo_send(int dummy)
7188 {
7189         TALLOC_CTX *frame = talloc_stackframe();
7190         struct fncall_context *ctx;
7191         struct tevent_context *ev;
7192         bool result = false;
7193         const char *names[4] = { "www.samba.org", "notfound.samba.org",
7194                                  "www.slashdot.org", "heise.de" };
7195         struct tevent_req *reqs[4];
7196         int i;
7197
7198         ev = event_context_init(frame);
7199         if (ev == NULL) {
7200                 goto fail;
7201         }
7202
7203         ctx = fncall_context_init(frame, 4);
7204
7205         for (i=0; i<ARRAY_SIZE(names); i++) {
7206                 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7207                                            NULL);
7208                 if (reqs[i] == NULL) {
7209                         goto fail;
7210                 }
7211                 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7212                                         (void *)names[i]);
7213         }
7214
7215         for (i=0; i<ARRAY_SIZE(reqs); i++) {
7216                 tevent_loop_once(ev);
7217         }
7218
7219         result = true;
7220 fail:
7221         TALLOC_FREE(frame);
7222         return result;
7223 }
7224
7225 static bool dbtrans_inc(struct db_context *db)
7226 {
7227         struct db_record *rec;
7228         uint32_t *val;
7229         bool ret = false;
7230         NTSTATUS status;
7231
7232         rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7233         if (rec == NULL) {
7234                 printf(__location__ "fetch_lock failed\n");
7235                 return false;
7236         }
7237
7238         if (rec->value.dsize != sizeof(uint32_t)) {
7239                 printf(__location__ "value.dsize = %d\n",
7240                        (int)rec->value.dsize);
7241                 goto fail;
7242         }
7243
7244         val = (uint32_t *)rec->value.dptr;
7245         *val += 1;
7246
7247         status = rec->store(rec, make_tdb_data((uint8_t *)val,
7248                                                sizeof(uint32_t)),
7249                             0);
7250         if (!NT_STATUS_IS_OK(status)) {
7251                 printf(__location__ "store failed: %s\n",
7252                        nt_errstr(status));
7253                 goto fail;
7254         }
7255
7256         ret = true;
7257 fail:
7258         TALLOC_FREE(rec);
7259         return ret;
7260 }
7261
7262 static bool run_local_dbtrans(int dummy)
7263 {
7264         struct db_context *db;
7265         struct db_record *rec;
7266         NTSTATUS status;
7267         uint32_t initial;
7268         int res;
7269
7270         db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7271                      O_RDWR|O_CREAT, 0600);
7272         if (db == NULL) {
7273                 printf("Could not open transtest.db\n");
7274                 return false;
7275         }
7276
7277         res = db->transaction_start(db);
7278         if (res == -1) {
7279                 printf(__location__ "transaction_start failed\n");
7280                 return false;
7281         }
7282
7283         rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7284         if (rec == NULL) {
7285                 printf(__location__ "fetch_lock failed\n");
7286                 return false;
7287         }
7288
7289         if (rec->value.dptr == NULL) {
7290                 initial = 0;
7291                 status = rec->store(
7292                         rec, make_tdb_data((uint8_t *)&initial,
7293                                            sizeof(initial)),
7294                         0);
7295                 if (!NT_STATUS_IS_OK(status)) {
7296                         printf(__location__ "store returned %s\n",
7297                                nt_errstr(status));
7298                         return false;
7299                 }
7300         }
7301
7302         TALLOC_FREE(rec);
7303
7304         res = db->transaction_commit(db);
7305         if (res == -1) {
7306                 printf(__location__ "transaction_commit failed\n");
7307                 return false;
7308         }
7309
7310         while (true) {
7311                 uint32_t val, val2;
7312                 int i;
7313
7314                 res = db->transaction_start(db);
7315                 if (res == -1) {
7316                         printf(__location__ "transaction_start failed\n");
7317                         break;
7318                 }
7319
7320                 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7321                         printf(__location__ "dbwrap_fetch_uint32 failed\n");
7322                         break;
7323                 }
7324
7325                 for (i=0; i<10; i++) {
7326                         if (!dbtrans_inc(db)) {
7327                                 return false;
7328                         }
7329                 }
7330
7331                 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7332                         printf(__location__ "dbwrap_fetch_uint32 failed\n");
7333                         break;
7334                 }
7335
7336                 if (val2 != val + 10) {
7337                         printf(__location__ "val=%d, val2=%d\n",
7338                                (int)val, (int)val2);
7339                         break;
7340                 }
7341
7342                 printf("val2=%d\r", val2);
7343
7344                 res = db->transaction_commit(db);
7345                 if (res == -1) {
7346                         printf(__location__ "transaction_commit failed\n");
7347                         break;
7348                 }
7349         }
7350
7351         TALLOC_FREE(db);
7352         return true;
7353 }
7354
7355 /*
7356  * Just a dummy test to be run under a debugger. There's no real way
7357  * to inspect the tevent_select specific function from outside of
7358  * tevent_select.c.
7359  */
7360
7361 static bool run_local_tevent_select(int dummy)
7362 {
7363         struct tevent_context *ev;
7364         struct tevent_fd *fd1, *fd2;
7365         bool result = false;
7366
7367         ev = tevent_context_init_byname(NULL, "select");
7368         if (ev == NULL) {
7369                 d_fprintf(stderr, "tevent_context_init_byname failed\n");
7370                 goto fail;
7371         }
7372
7373         fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
7374         if (fd1 == NULL) {
7375                 d_fprintf(stderr, "tevent_add_fd failed\n");
7376                 goto fail;
7377         }
7378         fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
7379         if (fd2 == NULL) {
7380                 d_fprintf(stderr, "tevent_add_fd failed\n");
7381                 goto fail;
7382         }
7383         TALLOC_FREE(fd2);
7384
7385         fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
7386         if (fd2 == NULL) {
7387                 d_fprintf(stderr, "tevent_add_fd failed\n");
7388                 goto fail;
7389         }
7390
7391         result = true;
7392 fail:
7393         TALLOC_FREE(ev);
7394         return result;
7395 }
7396
7397 static double create_procs(bool (*fn)(int), bool *result)
7398 {
7399         int i, status;
7400         volatile pid_t *child_status;
7401         volatile bool *child_status_out;
7402         int synccount;
7403         int tries = 8;
7404         struct timeval start;
7405
7406         synccount = 0;
7407
7408         child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
7409         if (!child_status) {
7410                 printf("Failed to setup shared memory\n");
7411                 return -1;
7412         }
7413
7414         child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
7415         if (!child_status_out) {
7416                 printf("Failed to setup result status shared memory\n");
7417                 return -1;
7418         }
7419
7420         for (i = 0; i < nprocs; i++) {
7421                 child_status[i] = 0;
7422                 child_status_out[i] = True;
7423         }
7424
7425         start = timeval_current();
7426
7427         for (i=0;i<nprocs;i++) {
7428                 procnum = i;
7429                 if (fork() == 0) {
7430                         pid_t mypid = getpid();
7431                         sys_srandom(((int)mypid) ^ ((int)time(NULL)));
7432
7433                         slprintf(myname,sizeof(myname),"CLIENT%d", i);
7434
7435                         while (1) {
7436                                 if (torture_open_connection(&current_cli, i)) break;
7437                                 if (tries-- == 0) {
7438                                         printf("pid %d failed to start\n", (int)getpid());
7439                                         _exit(1);
7440                                 }
7441                                 smb_msleep(10); 
7442                         }
7443
7444                         child_status[i] = getpid();
7445
7446                         while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
7447
7448                         child_status_out[i] = fn(i);
7449                         _exit(0);
7450                 }
7451         }
7452
7453         do {
7454                 synccount = 0;
7455                 for (i=0;i<nprocs;i++) {
7456                         if (child_status[i]) synccount++;
7457                 }
7458                 if (synccount == nprocs) break;
7459                 smb_msleep(10);
7460         } while (timeval_elapsed(&start) < 30);
7461
7462         if (synccount != nprocs) {
7463                 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
7464                 *result = False;
7465                 return timeval_elapsed(&start);
7466         }
7467
7468         /* start the client load */
7469         start = timeval_current();
7470
7471         for (i=0;i<nprocs;i++) {
7472                 child_status[i] = 0;
7473         }
7474
7475         printf("%d clients started\n", nprocs);
7476
7477         for (i=0;i<nprocs;i++) {
7478                 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
7479         }
7480
7481         printf("\n");
7482
7483         for (i=0;i<nprocs;i++) {
7484                 if (!child_status_out[i]) {
7485                         *result = False;
7486                 }
7487         }
7488         return timeval_elapsed(&start);
7489 }
7490
7491 #define FLAG_MULTIPROC 1
7492
7493 static struct {
7494         const char *name;
7495         bool (*fn)(int);
7496         unsigned flags;
7497 } torture_ops[] = {
7498         {"FDPASS", run_fdpasstest, 0},
7499         {"LOCK1",  run_locktest1,  0},
7500         {"LOCK2",  run_locktest2,  0},
7501         {"LOCK3",  run_locktest3,  0},
7502         {"LOCK4",  run_locktest4,  0},
7503         {"LOCK5",  run_locktest5,  0},
7504         {"LOCK6",  run_locktest6,  0},
7505         {"LOCK7",  run_locktest7,  0},
7506         {"LOCK8",  run_locktest8,  0},
7507         {"LOCK9",  run_locktest9,  0},
7508         {"UNLINK", run_unlinktest, 0},
7509         {"BROWSE", run_browsetest, 0},
7510         {"ATTR",   run_attrtest,   0},
7511         {"TRANS2", run_trans2test, 0},
7512         {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
7513         {"TORTURE",run_torture,    FLAG_MULTIPROC},
7514         {"RANDOMIPC", run_randomipc, 0},
7515         {"NEGNOWAIT", run_negprot_nowait, 0},
7516         {"NBENCH",  run_nbench, 0},
7517         {"NBENCH2", run_nbench2, 0},
7518         {"OPLOCK1",  run_oplock1, 0},
7519         {"OPLOCK2",  run_oplock2, 0},
7520         {"OPLOCK3",  run_oplock3, 0},
7521         {"DIR",  run_dirtest, 0},
7522         {"DIR1",  run_dirtest1, 0},
7523         {"DIR-CREATETIME",  run_dir_createtime, 0},
7524         {"DENY1",  torture_denytest1, 0},
7525         {"DENY2",  torture_denytest2, 0},
7526         {"TCON",  run_tcon_test, 0},
7527         {"TCONDEV",  run_tcon_devtype_test, 0},
7528         {"RW1",  run_readwritetest, 0},
7529         {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
7530         {"RW3",  run_readwritelarge, 0},
7531         {"OPEN", run_opentest, 0},
7532         {"POSIX", run_simple_posix_open_test, 0},
7533         {"POSIX-APPEND", run_posix_append, 0},
7534         { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
7535         { "SHORTNAME-TEST", run_shortname_test, 0},
7536 #if 1
7537         {"OPENATTR", run_openattrtest, 0},
7538 #endif
7539         {"XCOPY", run_xcopy, 0},
7540         {"RENAME", run_rename, 0},
7541         {"DELETE", run_deletetest, 0},
7542         {"PROPERTIES", run_properties, 0},
7543         {"MANGLE", torture_mangle, 0},
7544         {"MANGLE1", run_mangle1, 0},
7545         {"W2K", run_w2ktest, 0},
7546         {"TRANS2SCAN", torture_trans2_scan, 0},
7547         {"NTTRANSSCAN", torture_nttrans_scan, 0},
7548         {"UTABLE", torture_utable, 0},
7549         {"CASETABLE", torture_casetable, 0},
7550         {"ERRMAPEXTRACT", run_error_map_extract, 0},
7551         {"PIPE_NUMBER", run_pipe_number, 0},
7552         {"TCON2",  run_tcon2_test, 0},
7553         {"IOCTL",  torture_ioctl_test, 0},
7554         {"CHKPATH",  torture_chkpath_test, 0},
7555         {"FDSESS", run_fdsesstest, 0},
7556         { "EATEST", run_eatest, 0},
7557         { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
7558         { "CHAIN1", run_chain1, 0},
7559         { "CHAIN2", run_chain2, 0},
7560         { "WINDOWS-WRITE", run_windows_write, 0},
7561         { "CLI_ECHO", run_cli_echo, 0},
7562         { "GETADDRINFO", run_getaddrinfo_send, 0},
7563         { "TLDAP", run_tldap },
7564         { "STREAMERROR", run_streamerror },
7565         { "NOTIFY-BENCH", run_notify_bench },
7566         { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
7567         { "LOCAL-GENCACHE", run_local_gencache, 0},
7568         { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
7569         { "LOCAL-BASE64", run_local_base64, 0},
7570         { "LOCAL-RBTREE", run_local_rbtree, 0},
7571         { "LOCAL-MEMCACHE", run_local_memcache, 0},
7572         { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
7573         { "LOCAL-WBCLIENT", run_local_wbclient, 0},
7574         { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
7575         { "LOCAL-DBTRANS", run_local_dbtrans, 0},
7576         { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
7577         {NULL, NULL, 0}};
7578
7579
7580
7581 /****************************************************************************
7582 run a specified test or "ALL"
7583 ****************************************************************************/
7584 static bool run_test(const char *name)
7585 {
7586         bool ret = True;
7587         bool result = True;
7588         bool found = False;
7589         int i;
7590         double t;
7591         if (strequal(name,"ALL")) {
7592                 for (i=0;torture_ops[i].name;i++) {
7593                         run_test(torture_ops[i].name);
7594                 }
7595                 found = True;
7596         }
7597
7598         for (i=0;torture_ops[i].name;i++) {
7599                 fstr_sprintf(randomfname, "\\XX%x", 
7600                          (unsigned)random());
7601
7602                 if (strequal(name, torture_ops[i].name)) {
7603                         found = True;
7604                         printf("Running %s\n", name);
7605                         if (torture_ops[i].flags & FLAG_MULTIPROC) {
7606                                 t = create_procs(torture_ops[i].fn, &result);
7607                                 if (!result) { 
7608                                         ret = False;
7609                                         printf("TEST %s FAILED!\n", name);
7610                                 }
7611                         } else {
7612                                 struct timeval start;
7613                                 start = timeval_current();
7614                                 if (!torture_ops[i].fn(0)) {
7615                                         ret = False;
7616                                         printf("TEST %s FAILED!\n", name);
7617                                 }
7618                                 t = timeval_elapsed(&start);
7619                         }
7620                         printf("%s took %g secs\n\n", name, t);
7621                 }
7622         }
7623
7624         if (!found) {
7625                 printf("Did not find a test named %s\n", name);
7626                 ret = False;
7627         }
7628
7629         return ret;
7630 }
7631
7632
7633 static void usage(void)
7634 {
7635         int i;
7636
7637         printf("WARNING samba4 test suite is much more complete nowadays.\n");
7638         printf("Please use samba4 torture.\n\n");
7639
7640         printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
7641
7642         printf("\t-d debuglevel\n");
7643         printf("\t-U user%%pass\n");
7644         printf("\t-k               use kerberos\n");
7645         printf("\t-N numprocs\n");
7646         printf("\t-n my_netbios_name\n");
7647         printf("\t-W workgroup\n");
7648         printf("\t-o num_operations\n");
7649         printf("\t-O socket_options\n");
7650         printf("\t-m maximum protocol\n");
7651         printf("\t-L use oplocks\n");
7652         printf("\t-c CLIENT.TXT   specify client load file for NBENCH\n");
7653         printf("\t-A showall\n");
7654         printf("\t-p port\n");
7655         printf("\t-s seed\n");
7656         printf("\t-b unclist_filename   specify multiple shares for multiple connections\n");
7657         printf("\n\n");
7658
7659         printf("tests are:");
7660         for (i=0;torture_ops[i].name;i++) {
7661                 printf(" %s", torture_ops[i].name);
7662         }
7663         printf("\n");
7664
7665         printf("default test is ALL\n");
7666
7667         exit(1);
7668 }
7669
7670 /****************************************************************************
7671   main program
7672 ****************************************************************************/
7673  int main(int argc,char *argv[])
7674 {
7675         int opt, i;
7676         char *p;
7677         int gotuser = 0;
7678         int gotpass = 0;
7679         bool correct = True;
7680         TALLOC_CTX *frame = talloc_stackframe();
7681         int seed = time(NULL);
7682
7683         dbf = x_stdout;
7684
7685 #ifdef HAVE_SETBUFFER
7686         setbuffer(stdout, NULL, 0);
7687 #endif
7688
7689         load_case_tables();
7690
7691         setup_logging("smbtorture", true);
7692
7693         if (is_default_dyn_CONFIGFILE()) {
7694                 if(getenv("SMB_CONF_PATH")) {
7695                         set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
7696                 }
7697         }
7698         lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
7699         load_interfaces();
7700
7701         if (argc < 2) {
7702                 usage();
7703         }
7704
7705         for(p = argv[1]; *p; p++)
7706           if(*p == '\\')
7707             *p = '/';
7708
7709         if (strncmp(argv[1], "//", 2)) {
7710                 usage();
7711         }
7712
7713         fstrcpy(host, &argv[1][2]);
7714         p = strchr_m(&host[2],'/');
7715         if (!p) {
7716                 usage();
7717         }
7718         *p = 0;
7719         fstrcpy(share, p+1);
7720
7721         fstrcpy(myname, get_myname(talloc_tos()));
7722         if (!*myname) {
7723                 fprintf(stderr, "Failed to get my hostname.\n");
7724                 return 1;
7725         }
7726
7727         if (*username == 0 && getenv("LOGNAME")) {
7728           fstrcpy(username,getenv("LOGNAME"));
7729         }
7730
7731         argc--;
7732         argv++;
7733
7734         fstrcpy(workgroup, lp_workgroup());
7735
7736         while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
7737                 switch (opt) {
7738                 case 'p':
7739                         port_to_use = atoi(optarg);
7740                         break;
7741                 case 's':
7742                         seed = atoi(optarg);
7743                         break;
7744                 case 'W':
7745                         fstrcpy(workgroup,optarg);
7746                         break;
7747                 case 'm':
7748                         max_protocol = interpret_protocol(optarg, max_protocol);
7749                         break;
7750                 case 'N':
7751                         nprocs = atoi(optarg);
7752                         break;
7753                 case 'o':
7754                         torture_numops = atoi(optarg);
7755                         break;
7756                 case 'd':
7757                         DEBUGLEVEL = atoi(optarg);
7758                         break;
7759                 case 'O':
7760                         sockops = optarg;
7761                         break;
7762                 case 'L':
7763                         use_oplocks = True;
7764                         break;
7765                 case 'l':
7766                         local_path = optarg;
7767                         break;
7768                 case 'A':
7769                         torture_showall = True;
7770                         break;
7771                 case 'n':
7772                         fstrcpy(myname, optarg);
7773                         break;
7774                 case 'c':
7775                         client_txt = optarg;
7776                         break;
7777                 case 'e':
7778                         do_encrypt = true;
7779                         break;
7780                 case 'k':
7781 #ifdef HAVE_KRB5
7782                         use_kerberos = True;
7783 #else
7784                         d_printf("No kerberos support compiled in\n");
7785                         exit(1);
7786 #endif
7787                         break;
7788                 case 'U':
7789                         gotuser = 1;
7790                         fstrcpy(username,optarg);
7791                         p = strchr_m(username,'%');
7792                         if (p) {
7793                                 *p = 0;
7794                                 fstrcpy(password, p+1);
7795                                 gotpass = 1;
7796                         }
7797                         break;
7798                 case 'b':
7799                         fstrcpy(multishare_conn_fname, optarg);
7800                         use_multishare_conn = True;
7801                         break;
7802                 case 'B':
7803                         torture_blocksize = atoi(optarg);
7804                         break;
7805                 default:
7806                         printf("Unknown option %c (%d)\n", (char)opt, opt);
7807                         usage();
7808                 }
7809         }
7810
7811         d_printf("using seed %d\n", seed);
7812
7813         srandom(seed);
7814
7815         if(use_kerberos && !gotuser) gotpass = True;
7816
7817         while (!gotpass) {
7818                 p = getpass("Password:");
7819                 if (p) {
7820                         fstrcpy(password, p);
7821                         gotpass = 1;
7822                 }
7823         }
7824
7825         printf("host=%s share=%s user=%s myname=%s\n", 
7826                host, share, username, myname);
7827
7828         if (argc == optind) {
7829                 correct = run_test("ALL");
7830         } else {
7831                 for (i=optind;i<argc;i++) {
7832                         if (!run_test(argv[i])) {
7833                                 correct = False;
7834                         }
7835                 }
7836         }
7837
7838         TALLOC_FREE(frame);
7839
7840         if (correct) {
7841                 return(0);
7842         } else {
7843                 return(1);
7844         }
7845 }