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