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