1b492ce736b6f5a9d6e5f28dbc3f5c3584809859
[nivanova/samba-autobuild/.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 "wbc_async.h"
23 #include "torture/proto.h"
24 #include "libcli/security/security.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 #include "talloc_dict.h"
32 #include "async_smb.h"
33
34 extern char *optarg;
35 extern int optind;
36
37 static fstring host, workgroup, share, password, username, myname;
38 static int max_protocol = PROTOCOL_NT1;
39 static const char *sockops="TCP_NODELAY";
40 static int nprocs=1;
41 static int port_to_use=0;
42 int torture_numops=100;
43 int torture_blocksize=1024*1024;
44 static int procnum; /* records process count number when forking */
45 static struct cli_state *current_cli;
46 static fstring randomfname;
47 static bool use_oplocks;
48 static bool use_level_II_oplocks;
49 static const char *client_txt = "client_oplocks.txt";
50 static bool use_kerberos;
51 static fstring multishare_conn_fname;
52 static bool use_multishare_conn = False;
53 static bool do_encrypt;
54 static const char *local_path = NULL;
55 static int signing_state = Undefined;
56
57 bool torture_showall = False;
58
59 static double create_procs(bool (*fn)(int), bool *result);
60
61
62 /* return a pointer to a anonymous shared memory segment of size "size"
63    which will persist across fork() but will disappear when all processes
64    exit 
65
66    The memory is not zeroed 
67
68    This function uses system5 shared memory. It takes advantage of a property
69    that the memory is not destroyed if it is attached when the id is removed
70    */
71 void *shm_setup(int size)
72 {
73         int shmid;
74         void *ret;
75
76 #ifdef __QNXNTO__
77         shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
78         if (shmid == -1) {
79                 printf("can't get shared memory\n");
80                 exit(1);
81         }
82         shm_unlink("private");
83         if (ftruncate(shmid, size) == -1) {
84                 printf("can't set shared memory size\n");
85                 exit(1);
86         }
87         ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
88         if (ret == MAP_FAILED) {
89                 printf("can't map shared memory\n");
90                 exit(1);
91         }
92 #else
93         shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
94         if (shmid == -1) {
95                 printf("can't get shared memory\n");
96                 exit(1);
97         }
98         ret = (void *)shmat(shmid, 0, 0);
99         if (!ret || ret == (void *)-1) {
100                 printf("can't attach to shared memory\n");
101                 return NULL;
102         }
103         /* the following releases the ipc, but note that this process
104            and all its children will still have access to the memory, its
105            just that the shmid is no longer valid for other shm calls. This
106            means we don't leave behind lots of shm segments after we exit 
107
108            See Stevens "advanced programming in unix env" for details
109            */
110         shmctl(shmid, IPC_RMID, 0);
111 #endif
112
113         return ret;
114 }
115
116 /********************************************************************
117  Ensure a connection is encrypted.
118 ********************************************************************/
119
120 static bool force_cli_encryption(struct cli_state *c,
121                         const char *sharename)
122 {
123         uint16 major, minor;
124         uint32 caplow, caphigh;
125         NTSTATUS status;
126
127         if (!SERVER_HAS_UNIX_CIFS(c)) {
128                 d_printf("Encryption required and "
129                         "server that doesn't support "
130                         "UNIX extensions - failing connect\n");
131                         return false;
132         }
133
134         status = cli_unix_extensions_version(c, &major, &minor, &caplow,
135                                              &caphigh);
136         if (!NT_STATUS_IS_OK(status)) {
137                 d_printf("Encryption required and "
138                         "can't get UNIX CIFS extensions "
139                         "version from server: %s\n", nt_errstr(status));
140                 return false;
141         }
142
143         if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
144                 d_printf("Encryption required and "
145                         "share %s doesn't support "
146                         "encryption.\n", sharename);
147                 return false;
148         }
149
150         if (c->use_kerberos) {
151                 status = cli_gss_smb_encryption_start(c);
152         } else {
153                 status = cli_raw_ntlm_smb_encryption_start(c,
154                                                 username,
155                                                 password,
156                                                 workgroup);
157         }
158
159         if (!NT_STATUS_IS_OK(status)) {
160                 d_printf("Encryption required and "
161                         "setup failed with error %s.\n",
162                         nt_errstr(status));
163                 return false;
164         }
165
166         return true;
167 }
168
169
170 static struct cli_state *open_nbt_connection(void)
171 {
172         struct nmb_name called, calling;
173         struct sockaddr_storage ss;
174         struct cli_state *c;
175         NTSTATUS status;
176
177         make_nmb_name(&calling, myname, 0x0);
178         make_nmb_name(&called , host, 0x20);
179
180         zero_sockaddr(&ss);
181
182         if (!(c = cli_initialise_ex(signing_state))) {
183                 printf("Failed initialize cli_struct to connect with %s\n", host);
184                 return NULL;
185         }
186
187         c->port = port_to_use;
188
189         status = cli_connect(c, host, &ss);
190         if (!NT_STATUS_IS_OK(status)) {
191                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
192                 return NULL;
193         }
194
195         c->use_kerberos = use_kerberos;
196
197         c->timeout = 120000; /* set a really long timeout (2 minutes) */
198         if (use_oplocks) c->use_oplocks = True;
199         if (use_level_II_oplocks) c->use_level_II_oplocks = True;
200
201         if (!cli_session_request(c, &calling, &called)) {
202                 /*
203                  * Well, that failed, try *SMBSERVER ...
204                  * However, we must reconnect as well ...
205                  */
206                 status = cli_connect(c, host, &ss);
207                 if (!NT_STATUS_IS_OK(status)) {
208                         printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
209                         return NULL;
210                 }
211
212                 make_nmb_name(&called, "*SMBSERVER", 0x20);
213                 if (!cli_session_request(c, &calling, &called)) {
214                         printf("%s rejected the session\n",host);
215                         printf("We tried with a called name of %s & %s\n",
216                                 host, "*SMBSERVER");
217                         cli_shutdown(c);
218                         return NULL;
219                 }
220         }
221
222         return c;
223 }
224
225 /****************************************************************************
226  Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
227 ****************************************************************************/
228
229 static bool cli_bad_session_request(struct cli_state *cli,
230                          struct nmb_name *calling, struct nmb_name *called)
231 {
232         char *p;
233         int len = 4;
234         int namelen = 0;
235         char *tmp;
236
237         memcpy(&(cli->calling), calling, sizeof(*calling));
238         memcpy(&(cli->called ), called , sizeof(*called ));
239
240         /* put in the destination name */
241
242         tmp = name_mangle(talloc_tos(), cli->called.name,
243                           cli->called.name_type);
244         if (tmp == NULL) {
245                 return false;
246         }
247
248         p = cli->outbuf+len;
249         namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
250         if (namelen > 0) {
251                 memcpy(p, tmp, namelen);
252                 len += namelen;
253         }
254         TALLOC_FREE(tmp);
255
256         /* Deliberately corrupt the name len (first byte) */
257         *p = 100;
258
259         /* and my name */
260
261         tmp = name_mangle(talloc_tos(), cli->calling.name,
262                           cli->calling.name_type);
263         if (tmp == NULL) {
264                 return false;
265         }
266
267         p = cli->outbuf+len;
268         namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
269         if (namelen > 0) {
270                 memcpy(p, tmp, namelen);
271                 len += namelen;
272         }
273         TALLOC_FREE(tmp);
274         /* Deliberately corrupt the name len (first byte) */
275         *p = 100;
276
277         /* send a session request (RFC 1002) */
278         /* setup the packet length
279          * Remove four bytes from the length count, since the length
280          * field in the NBT Session Service header counts the number
281          * of bytes which follow.  The cli_send_smb() function knows
282          * about this and accounts for those four bytes.
283          * CRH.
284          */
285         len -= 4;
286         _smb_setlen(cli->outbuf,len);
287         SCVAL(cli->outbuf,0,0x81);
288
289         cli_send_smb(cli);
290         DEBUG(5,("Sent session request\n"));
291
292         if (!cli_receive_smb(cli))
293                 return False;
294
295         if (CVAL(cli->inbuf,0) != 0x82) {
296                 /* This is the wrong place to put the error... JRA. */
297                 cli->rap_error = CVAL(cli->inbuf,4);
298                 return False;
299         }
300         return(True);
301 }
302
303 static struct cli_state *open_bad_nbt_connection(void)
304 {
305         struct nmb_name called, calling;
306         struct sockaddr_storage ss;
307         struct cli_state *c;
308         NTSTATUS status;
309
310         make_nmb_name(&calling, myname, 0x0);
311         make_nmb_name(&called , host, 0x20);
312
313         zero_sockaddr(&ss);
314
315         if (!(c = cli_initialise_ex(signing_state))) {
316                 printf("Failed initialize cli_struct to connect with %s\n", host);
317                 return NULL;
318         }
319
320         c->port = 139;
321
322         status = cli_connect(c, host, &ss);
323         if (!NT_STATUS_IS_OK(status)) {
324                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
325                 return NULL;
326         }
327
328         c->timeout = 4000; /* set a short timeout (4 seconds) */
329
330         if (!cli_bad_session_request(c, &calling, &called)) {
331                 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
332                 return NULL;
333         }
334
335         return c;
336 }
337
338
339 /* Insert a NULL at the first separator of the given path and return a pointer
340  * to the remainder of the string.
341  */
342 static char *
343 terminate_path_at_separator(char * path)
344 {
345         char * p;
346
347         if (!path) {
348                 return NULL;
349         }
350
351         if ((p = strchr_m(path, '/'))) {
352                 *p = '\0';
353                 return p + 1;
354         }
355
356         if ((p = strchr_m(path, '\\'))) {
357                 *p = '\0';
358                 return p + 1;
359         }
360
361         /* No separator. */
362         return NULL;
363 }
364
365 /*
366   parse a //server/share type UNC name
367 */
368 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
369                       char **hostname, char **sharename)
370 {
371         char *p;
372
373         *hostname = *sharename = NULL;
374
375         if (strncmp(unc_name, "\\\\", 2) &&
376             strncmp(unc_name, "//", 2)) {
377                 return False;
378         }
379
380         *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
381         p = terminate_path_at_separator(*hostname);
382
383         if (p && *p) {
384                 *sharename = talloc_strdup(mem_ctx, p);
385                 terminate_path_at_separator(*sharename);
386         }
387
388         if (*hostname && *sharename) {
389                 return True;
390         }
391
392         TALLOC_FREE(*hostname);
393         TALLOC_FREE(*sharename);
394         return False;
395 }
396
397 static bool torture_open_connection_share(struct cli_state **c,
398                                    const char *hostname, 
399                                    const char *sharename)
400 {
401         int flags = 0;
402         NTSTATUS status;
403
404         if (use_kerberos)
405                 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
406         if (use_oplocks)
407                 flags |= CLI_FULL_CONNECTION_OPLOCKS;
408         if (use_level_II_oplocks)
409                 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
410
411         status = cli_full_connection(c, myname,
412                                      hostname, NULL, port_to_use, 
413                                      sharename, "?????", 
414                                      username, workgroup, 
415                                      password, flags, signing_state);
416         if (!NT_STATUS_IS_OK(status)) {
417                 printf("failed to open share connection: //%s/%s port:%d - %s\n",
418                         hostname, sharename, port_to_use, nt_errstr(status));
419                 return False;
420         }
421
422         (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
423
424         if (do_encrypt) {
425                 return force_cli_encryption(*c,
426                                         sharename);
427         }
428         return True;
429 }
430
431 bool torture_open_connection(struct cli_state **c, int conn_index)
432 {
433         char **unc_list = NULL;
434         int num_unc_names = 0;
435         bool result;
436
437         if (use_multishare_conn==True) {
438                 char *h, *s;
439                 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
440                 if (!unc_list || num_unc_names <= 0) {
441                         printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
442                         exit(1);
443                 }
444
445                 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
446                                       NULL, &h, &s)) {
447                         printf("Failed to parse UNC name %s\n",
448                                unc_list[conn_index % num_unc_names]);
449                         TALLOC_FREE(unc_list);
450                         exit(1);
451                 }
452
453                 result = torture_open_connection_share(c, h, s);
454
455                 /* h, s were copied earlier */
456                 TALLOC_FREE(unc_list);
457                 return result;
458         }
459
460         return torture_open_connection_share(c, host, share);
461 }
462
463 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
464 {
465         uint16 old_vuid = cli->vuid;
466         fstring old_user_name;
467         size_t passlen = strlen(password);
468         NTSTATUS status;
469         bool ret;
470
471         fstrcpy(old_user_name, cli->user_name);
472         cli->vuid = 0;
473         ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
474                                                 password, passlen,
475                                                 password, passlen,
476                                                 workgroup));
477         *new_vuid = cli->vuid;
478         cli->vuid = old_vuid;
479         status = cli_set_username(cli, old_user_name);
480         if (!NT_STATUS_IS_OK(status)) {
481                 return false;
482         }
483         return ret;
484 }
485
486
487 bool torture_close_connection(struct cli_state *c)
488 {
489         bool ret = True;
490         NTSTATUS status;
491
492         status = cli_tdis(c);
493         if (!NT_STATUS_IS_OK(status)) {
494                 printf("tdis failed (%s)\n", nt_errstr(status));
495                 ret = False;
496         }
497
498         cli_shutdown(c);
499
500         return ret;
501 }
502
503
504 /* check if the server produced the expected error code */
505 static bool check_error(int line, struct cli_state *c, 
506                         uint8 eclass, uint32 ecode, NTSTATUS nterr)
507 {
508         if (cli_is_dos_error(c)) {
509                 uint8 cclass;
510                 uint32 num;
511
512                 /* Check DOS error */
513
514                 cli_dos_error(c, &cclass, &num);
515
516                 if (eclass != cclass || ecode != num) {
517                         printf("unexpected error code class=%d code=%d\n", 
518                                (int)cclass, (int)num);
519                         printf(" expected %d/%d %s (line=%d)\n", 
520                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
521                         return False;
522                 }
523
524         } else {
525                 NTSTATUS status;
526
527                 /* Check NT error */
528
529                 status = cli_nt_error(c);
530
531                 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
532                         printf("unexpected error code %s\n", nt_errstr(status));
533                         printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
534                         return False;
535                 }
536         }
537
538         return True;
539 }
540
541
542 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
543 {
544         while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
545                 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
546         }
547         return True;
548 }
549
550
551 static bool rw_torture(struct cli_state *c)
552 {
553         const char *lockfname = "\\torture.lck";
554         fstring fname;
555         uint16_t fnum;
556         uint16_t fnum2;
557         pid_t pid2, pid = getpid();
558         int i, j;
559         char buf[1024];
560         bool correct = True;
561         NTSTATUS status;
562
563         memset(buf, '\0', sizeof(buf));
564
565         status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
566                          DENY_NONE, &fnum2);
567         if (!NT_STATUS_IS_OK(status)) {
568                 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
569         }
570         if (!NT_STATUS_IS_OK(status)) {
571                 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
572                 return False;
573         }
574
575         for (i=0;i<torture_numops;i++) {
576                 unsigned n = (unsigned)sys_random()%10;
577                 if (i % 10 == 0) {
578                         printf("%d\r", i); fflush(stdout);
579                 }
580                 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
581
582                 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
583                         return False;
584                 }
585
586                 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
587                         printf("open failed (%s)\n", cli_errstr(c));
588                         correct = False;
589                         break;
590                 }
591
592                 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
593                         printf("write failed (%s)\n", cli_errstr(c));
594                         correct = False;
595                 }
596
597                 for (j=0;j<50;j++) {
598                         if (cli_write(c, fnum, 0, (char *)buf, 
599                                       sizeof(pid)+(j*sizeof(buf)), 
600                                       sizeof(buf)) != sizeof(buf)) {
601                                 printf("write failed (%s)\n", cli_errstr(c));
602                                 correct = False;
603                         }
604                 }
605
606                 pid2 = 0;
607
608                 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
609                         printf("read failed (%s)\n", cli_errstr(c));
610                         correct = False;
611                 }
612
613                 if (pid2 != pid) {
614                         printf("data corruption!\n");
615                         correct = False;
616                 }
617
618                 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
619                         printf("close failed (%s)\n", cli_errstr(c));
620                         correct = False;
621                 }
622
623                 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
624                         printf("unlink failed (%s)\n", cli_errstr(c));
625                         correct = False;
626                 }
627
628                 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
629                         printf("unlock failed (%s)\n", cli_errstr(c));
630                         correct = False;
631                 }
632         }
633
634         cli_close(c, fnum2);
635         cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
636
637         printf("%d\n", i);
638
639         return correct;
640 }
641
642 static bool run_torture(int dummy)
643 {
644         struct cli_state *cli;
645         bool ret;
646
647         cli = current_cli;
648
649         cli_sockopt(cli, sockops);
650
651         ret = rw_torture(cli);
652
653         if (!torture_close_connection(cli)) {
654                 ret = False;
655         }
656
657         return ret;
658 }
659
660 static bool rw_torture3(struct cli_state *c, char *lockfname)
661 {
662         uint16_t fnum = (uint16_t)-1;
663         unsigned int i = 0;
664         char buf[131072];
665         char buf_rd[131072];
666         unsigned count;
667         unsigned countprev = 0;
668         ssize_t sent = 0;
669         bool correct = True;
670         NTSTATUS status;
671
672         srandom(1);
673         for (i = 0; i < sizeof(buf); i += sizeof(uint32))
674         {
675                 SIVAL(buf, i, sys_random());
676         }
677
678         if (procnum == 0)
679         {
680                 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
681                                  DENY_NONE, &fnum))) {
682                         printf("first open read/write of %s failed (%s)\n",
683                                         lockfname, cli_errstr(c));
684                         return False;
685                 }
686         }
687         else
688         {
689                 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
690                 {
691                         status = cli_open(c, lockfname, O_RDONLY, 
692                                          DENY_NONE, &fnum);
693                         if (!NT_STATUS_IS_OK(status)) {
694                                 break;
695                         }
696                         smb_msleep(10);
697                 }
698                 if (!NT_STATUS_IS_OK(status)) {
699                         printf("second open read-only of %s failed (%s)\n",
700                                         lockfname, cli_errstr(c));
701                         return False;
702                 }
703         }
704
705         i = 0;
706         for (count = 0; count < sizeof(buf); count += sent)
707         {
708                 if (count >= countprev) {
709                         printf("%d %8d\r", i, count);
710                         fflush(stdout);
711                         i++;
712                         countprev += (sizeof(buf) / 20);
713                 }
714
715                 if (procnum == 0)
716                 {
717                         sent = ((unsigned)sys_random()%(20))+ 1;
718                         if (sent > sizeof(buf) - count)
719                         {
720                                 sent = sizeof(buf) - count;
721                         }
722
723                         if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
724                                 printf("write failed (%s)\n", cli_errstr(c));
725                                 correct = False;
726                         }
727                 }
728                 else
729                 {
730                         sent = cli_read(c, fnum, buf_rd+count, count,
731                                                   sizeof(buf)-count);
732                         if (sent < 0)
733                         {
734                                 printf("read failed offset:%d size:%ld (%s)\n",
735                                        count, (unsigned long)sizeof(buf)-count,
736                                        cli_errstr(c));
737                                 correct = False;
738                                 sent = 0;
739                         }
740                         if (sent > 0)
741                         {
742                                 if (memcmp(buf_rd+count, buf+count, sent) != 0)
743                                 {
744                                         printf("read/write compare failed\n");
745                                         printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
746                                         correct = False;
747                                         break;
748                                 }
749                         }
750                 }
751
752         }
753
754         if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
755                 printf("close failed (%s)\n", cli_errstr(c));
756                 correct = False;
757         }
758
759         return correct;
760 }
761
762 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
763 {
764         const char *lockfname = "\\torture2.lck";
765         uint16_t fnum1;
766         uint16_t fnum2;
767         int i;
768         char buf[131072];
769         char buf_rd[131072];
770         bool correct = True;
771         ssize_t bytes_read;
772
773         if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
774                 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
775         }
776
777         if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL, 
778                          DENY_NONE, &fnum1))) {
779                 printf("first open read/write of %s failed (%s)\n",
780                                 lockfname, cli_errstr(c1));
781                 return False;
782         }
783         if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY, 
784                          DENY_NONE, &fnum2))) {
785                 printf("second open read-only of %s failed (%s)\n",
786                                 lockfname, cli_errstr(c2));
787                 cli_close(c1, fnum1);
788                 return False;
789         }
790
791         for (i=0;i<torture_numops;i++)
792         {
793                 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
794                 if (i % 10 == 0) {
795                         printf("%d\r", i); fflush(stdout);
796                 }
797
798                 generate_random_buffer((unsigned char *)buf, buf_size);
799
800                 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
801                         printf("write failed (%s)\n", cli_errstr(c1));
802                         correct = False;
803                         break;
804                 }
805
806                 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
807                         printf("read failed (%s)\n", cli_errstr(c2));
808                         printf("read %d, expected %ld\n", (int)bytes_read, 
809                                (unsigned long)buf_size); 
810                         correct = False;
811                         break;
812                 }
813
814                 if (memcmp(buf_rd, buf, buf_size) != 0)
815                 {
816                         printf("read/write compare failed\n");
817                         correct = False;
818                         break;
819                 }
820         }
821
822         if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
823                 printf("close failed (%s)\n", cli_errstr(c2));
824                 correct = False;
825         }
826         if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
827                 printf("close failed (%s)\n", cli_errstr(c1));
828                 correct = False;
829         }
830
831         if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
832                 printf("unlink failed (%s)\n", cli_errstr(c1));
833                 correct = False;
834         }
835
836         return correct;
837 }
838
839 static bool run_readwritetest(int dummy)
840 {
841         struct cli_state *cli1, *cli2;
842         bool test1, test2 = False;
843
844         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
845                 return False;
846         }
847         cli_sockopt(cli1, sockops);
848         cli_sockopt(cli2, sockops);
849
850         printf("starting readwritetest\n");
851
852         test1 = rw_torture2(cli1, cli2);
853         printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
854
855         if (test1) {
856                 test2 = rw_torture2(cli1, cli1);
857                 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
858         }
859
860         if (!torture_close_connection(cli1)) {
861                 test1 = False;
862         }
863
864         if (!torture_close_connection(cli2)) {
865                 test2 = False;
866         }
867
868         return (test1 && test2);
869 }
870
871 static bool run_readwritemulti(int dummy)
872 {
873         struct cli_state *cli;
874         bool test;
875
876         cli = current_cli;
877
878         cli_sockopt(cli, sockops);
879
880         printf("run_readwritemulti: fname %s\n", randomfname);
881         test = rw_torture3(cli, randomfname);
882
883         if (!torture_close_connection(cli)) {
884                 test = False;
885         }
886
887         return test;
888 }
889
890 static bool run_readwritelarge_internal(int max_xmit_k)
891 {
892         static struct cli_state *cli1;
893         uint16_t fnum1;
894         const char *lockfname = "\\large.dat";
895         SMB_OFF_T fsize;
896         char buf[126*1024];
897         bool correct = True;
898
899         if (!torture_open_connection(&cli1, 0)) {
900                 return False;
901         }
902         cli_sockopt(cli1, sockops);
903         memset(buf,'\0',sizeof(buf));
904
905         cli1->max_xmit = max_xmit_k*1024;
906
907         if (signing_state == Required) {
908                 /* Horrible cheat to force
909                    multiple signed outstanding
910                    packets against a Samba server.
911                 */
912                 cli1->is_samba = false;
913         }
914
915         printf("starting readwritelarge_internal\n");
916
917         cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
918
919         if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
920                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
921                 return False;
922         }
923
924         cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
925
926         if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
927                                      cli1, fnum1, NULL, &fsize, NULL, NULL,
928                                      NULL, NULL, NULL))) {
929                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
930                 correct = False;
931         }
932
933         if (fsize == sizeof(buf))
934                 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
935                        (unsigned long)fsize);
936         else {
937                 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
938                        (unsigned long)fsize);
939                 correct = False;
940         }
941
942         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
943                 printf("close failed (%s)\n", cli_errstr(cli1));
944                 correct = False;
945         }
946
947         if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
948                 printf("unlink failed (%s)\n", cli_errstr(cli1));
949                 correct = False;
950         }
951
952         if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
953                 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
954                 return False;
955         }
956
957         cli1->max_xmit = 4*1024;
958
959         cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
960
961         if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
962                                      cli1, fnum1, NULL, &fsize, NULL, NULL,
963                                      NULL, NULL, NULL))) {
964                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
965                 correct = False;
966         }
967
968         if (fsize == sizeof(buf))
969                 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
970                        (unsigned long)fsize);
971         else {
972                 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
973                        (unsigned long)fsize);
974                 correct = False;
975         }
976
977 #if 0
978         /* ToDo - set allocation. JRA */
979         if(!cli_set_allocation_size(cli1, fnum1, 0)) {
980                 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
981                 return False;
982         }
983         if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
984                                  NULL, NULL)) {
985                 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
986                 correct = False;
987         }
988         if (fsize != 0)
989                 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
990 #endif
991
992         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
993                 printf("close failed (%s)\n", cli_errstr(cli1));
994                 correct = False;
995         }
996
997         if (!torture_close_connection(cli1)) {
998                 correct = False;
999         }
1000         return correct;
1001 }
1002
1003 static bool run_readwritelarge(int dummy)
1004 {
1005         return run_readwritelarge_internal(128);
1006 }
1007
1008 static bool run_readwritelarge_signtest(int dummy)
1009 {
1010         bool ret;
1011         signing_state = Required;
1012         ret = run_readwritelarge_internal(2);
1013         signing_state = Undefined;
1014         return ret;
1015 }
1016
1017 int line_count = 0;
1018 int nbio_id;
1019
1020 #define ival(s) strtol(s, NULL, 0)
1021
1022 /* run a test that simulates an approximate netbench client load */
1023 static bool run_netbench(int client)
1024 {
1025         struct cli_state *cli;
1026         int i;
1027         char line[1024];
1028         char cname[20];
1029         FILE *f;
1030         const char *params[20];
1031         bool correct = True;
1032
1033         cli = current_cli;
1034
1035         nbio_id = client;
1036
1037         cli_sockopt(cli, sockops);
1038
1039         nb_setup(cli);
1040
1041         slprintf(cname,sizeof(cname)-1, "client%d", client);
1042
1043         f = fopen(client_txt, "r");
1044
1045         if (!f) {
1046                 perror(client_txt);
1047                 return False;
1048         }
1049
1050         while (fgets(line, sizeof(line)-1, f)) {
1051                 char *saveptr;
1052                 line_count++;
1053
1054                 line[strlen(line)-1] = 0;
1055
1056                 /* printf("[%d] %s\n", line_count, line); */
1057
1058                 all_string_sub(line,"client1", cname, sizeof(line));
1059
1060                 /* parse the command parameters */
1061                 params[0] = strtok_r(line, " ", &saveptr);
1062                 i = 0;
1063                 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1064
1065                 params[i] = "";
1066
1067                 if (i < 2) continue;
1068
1069                 if (!strncmp(params[0],"SMB", 3)) {
1070                         printf("ERROR: You are using a dbench 1 load file\n");
1071                         exit(1);
1072                 }
1073
1074                 if (!strcmp(params[0],"NTCreateX")) {
1075                         nb_createx(params[1], ival(params[2]), ival(params[3]), 
1076                                    ival(params[4]));
1077                 } else if (!strcmp(params[0],"Close")) {
1078                         nb_close(ival(params[1]));
1079                 } else if (!strcmp(params[0],"Rename")) {
1080                         nb_rename(params[1], params[2]);
1081                 } else if (!strcmp(params[0],"Unlink")) {
1082                         nb_unlink(params[1]);
1083                 } else if (!strcmp(params[0],"Deltree")) {
1084                         nb_deltree(params[1]);
1085                 } else if (!strcmp(params[0],"Rmdir")) {
1086                         nb_rmdir(params[1]);
1087                 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1088                         nb_qpathinfo(params[1]);
1089                 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1090                         nb_qfileinfo(ival(params[1]));
1091                 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1092                         nb_qfsinfo(ival(params[1]));
1093                 } else if (!strcmp(params[0],"FIND_FIRST")) {
1094                         nb_findfirst(params[1]);
1095                 } else if (!strcmp(params[0],"WriteX")) {
1096                         nb_writex(ival(params[1]), 
1097                                   ival(params[2]), ival(params[3]), ival(params[4]));
1098                 } else if (!strcmp(params[0],"ReadX")) {
1099                         nb_readx(ival(params[1]), 
1100                                   ival(params[2]), ival(params[3]), ival(params[4]));
1101                 } else if (!strcmp(params[0],"Flush")) {
1102                         nb_flush(ival(params[1]));
1103                 } else {
1104                         printf("Unknown operation %s\n", params[0]);
1105                         exit(1);
1106                 }
1107         }
1108         fclose(f);
1109
1110         nb_cleanup();
1111
1112         if (!torture_close_connection(cli)) {
1113                 correct = False;
1114         }
1115
1116         return correct;
1117 }
1118
1119
1120 /* run a test that simulates an approximate netbench client load */
1121 static bool run_nbench(int dummy)
1122 {
1123         double t;
1124         bool correct = True;
1125
1126         nbio_shmem(nprocs);
1127
1128         nbio_id = -1;
1129
1130         signal(SIGALRM, nb_alarm);
1131         alarm(1);
1132         t = create_procs(run_netbench, &correct);
1133         alarm(0);
1134
1135         printf("\nThroughput %g MB/sec\n", 
1136                1.0e-6 * nbio_total() / t);
1137         return correct;
1138 }
1139
1140
1141 /*
1142   This test checks for two things:
1143
1144   1) correct support for retaining locks over a close (ie. the server
1145      must not use posix semantics)
1146   2) support for lock timeouts
1147  */
1148 static bool run_locktest1(int dummy)
1149 {
1150         struct cli_state *cli1, *cli2;
1151         const char *fname = "\\lockt1.lck";
1152         uint16_t fnum1, fnum2, fnum3;
1153         time_t t1, t2;
1154         unsigned lock_timeout;
1155
1156         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1157                 return False;
1158         }
1159         cli_sockopt(cli1, sockops);
1160         cli_sockopt(cli2, sockops);
1161
1162         printf("starting locktest1\n");
1163
1164         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1165
1166         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1167                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1168                 return False;
1169         }
1170         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1171                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1172                 return False;
1173         }
1174         if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1175                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1176                 return False;
1177         }
1178
1179         if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1180                 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1181                 return False;
1182         }
1183
1184
1185         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1186                 printf("lock2 succeeded! This is a locking bug\n");
1187                 return False;
1188         } else {
1189                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1190                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1191         }
1192
1193
1194         lock_timeout = (1 + (random() % 20));
1195         printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1196         t1 = time(NULL);
1197         if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1198                 printf("lock3 succeeded! This is a locking bug\n");
1199                 return False;
1200         } else {
1201                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1202                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1203         }
1204         t2 = time(NULL);
1205
1206         if (ABS(t2 - t1) < lock_timeout-1) {
1207                 printf("error: This server appears not to support timed lock requests\n");
1208         }
1209
1210         printf("server slept for %u seconds for a %u second timeout\n",
1211                (unsigned int)(t2-t1), lock_timeout);
1212
1213         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1214                 printf("close1 failed (%s)\n", cli_errstr(cli1));
1215                 return False;
1216         }
1217
1218         if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1219                 printf("lock4 succeeded! This is a locking bug\n");
1220                 return False;
1221         } else {
1222                 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
1223                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1224         }
1225
1226         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1227                 printf("close2 failed (%s)\n", cli_errstr(cli1));
1228                 return False;
1229         }
1230
1231         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1232                 printf("close3 failed (%s)\n", cli_errstr(cli2));
1233                 return False;
1234         }
1235
1236         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1237                 printf("unlink failed (%s)\n", cli_errstr(cli1));
1238                 return False;
1239         }
1240
1241
1242         if (!torture_close_connection(cli1)) {
1243                 return False;
1244         }
1245
1246         if (!torture_close_connection(cli2)) {
1247                 return False;
1248         }
1249
1250         printf("Passed locktest1\n");
1251         return True;
1252 }
1253
1254 /*
1255   this checks to see if a secondary tconx can use open files from an
1256   earlier tconx
1257  */
1258 static bool run_tcon_test(int dummy)
1259 {
1260         static struct cli_state *cli;
1261         const char *fname = "\\tcontest.tmp";
1262         uint16 fnum1;
1263         uint16 cnum1, cnum2, cnum3;
1264         uint16 vuid1, vuid2;
1265         char buf[4];
1266         bool ret = True;
1267         NTSTATUS status;
1268
1269         memset(buf, '\0', sizeof(buf));
1270
1271         if (!torture_open_connection(&cli, 0)) {
1272                 return False;
1273         }
1274         cli_sockopt(cli, sockops);
1275
1276         printf("starting tcontest\n");
1277
1278         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1279
1280         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1281                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1282                 return False;
1283         }
1284
1285         cnum1 = cli->cnum;
1286         vuid1 = cli->vuid;
1287
1288         if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1289                 printf("initial write failed (%s)", cli_errstr(cli));
1290                 return False;
1291         }
1292
1293         status = cli_tcon_andx(cli, share, "?????",
1294                                password, strlen(password)+1);
1295         if (!NT_STATUS_IS_OK(status)) {
1296                 printf("%s refused 2nd tree connect (%s)\n", host,
1297                        nt_errstr(status));
1298                 cli_shutdown(cli);
1299                 return False;
1300         }
1301
1302         cnum2 = cli->cnum;
1303         cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1304         vuid2 = cli->vuid + 1;
1305
1306         /* try a write with the wrong tid */
1307         cli->cnum = cnum2;
1308
1309         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1310                 printf("* server allows write with wrong TID\n");
1311                 ret = False;
1312         } else {
1313                 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1314         }
1315
1316
1317         /* try a write with an invalid tid */
1318         cli->cnum = cnum3;
1319
1320         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1321                 printf("* server allows write with invalid TID\n");
1322                 ret = False;
1323         } else {
1324                 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1325         }
1326
1327         /* try a write with an invalid vuid */
1328         cli->vuid = vuid2;
1329         cli->cnum = cnum1;
1330
1331         if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1332                 printf("* server allows write with invalid VUID\n");
1333                 ret = False;
1334         } else {
1335                 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1336         }
1337
1338         cli->cnum = cnum1;
1339         cli->vuid = vuid1;
1340
1341         if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1342                 printf("close failed (%s)\n", cli_errstr(cli));
1343                 return False;
1344         }
1345
1346         cli->cnum = cnum2;
1347
1348         status = cli_tdis(cli);
1349         if (!NT_STATUS_IS_OK(status)) {
1350                 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1351                 return False;
1352         }
1353
1354         cli->cnum = cnum1;
1355
1356         if (!torture_close_connection(cli)) {
1357                 return False;
1358         }
1359
1360         return ret;
1361 }
1362
1363
1364 /*
1365  checks for old style tcon support
1366  */
1367 static bool run_tcon2_test(int dummy)
1368 {
1369         static struct cli_state *cli;
1370         uint16 cnum, max_xmit;
1371         char *service;
1372         NTSTATUS status;
1373
1374         if (!torture_open_connection(&cli, 0)) {
1375                 return False;
1376         }
1377         cli_sockopt(cli, sockops);
1378
1379         printf("starting tcon2 test\n");
1380
1381         if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1382                 return false;
1383         }
1384
1385         status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1386
1387         if (!NT_STATUS_IS_OK(status)) {
1388                 printf("tcon2 failed : %s\n", cli_errstr(cli));
1389         } else {
1390                 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n", 
1391                        (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1392         }
1393
1394         if (!torture_close_connection(cli)) {
1395                 return False;
1396         }
1397
1398         printf("Passed tcon2 test\n");
1399         return True;
1400 }
1401
1402 static bool tcon_devtest(struct cli_state *cli,
1403                          const char *myshare, const char *devtype,
1404                          const char *return_devtype,
1405                          NTSTATUS expected_error)
1406 {
1407         NTSTATUS status;
1408         bool ret;
1409
1410         status = cli_tcon_andx(cli, myshare, devtype,
1411                                password, strlen(password)+1);
1412
1413         if (NT_STATUS_IS_OK(expected_error)) {
1414                 if (NT_STATUS_IS_OK(status)) {
1415                         if (strcmp(cli->dev, return_devtype) == 0) {
1416                                 ret = True;
1417                         } else { 
1418                                 printf("tconX to share %s with type %s "
1419                                        "succeeded but returned the wrong "
1420                                        "device type (got [%s] but should have got [%s])\n",
1421                                        myshare, devtype, cli->dev, return_devtype);
1422                                 ret = False;
1423                         }
1424                 } else {
1425                         printf("tconX to share %s with type %s "
1426                                "should have succeeded but failed\n",
1427                                myshare, devtype);
1428                         ret = False;
1429                 }
1430                 cli_tdis(cli);
1431         } else {
1432                 if (NT_STATUS_IS_OK(status)) {
1433                         printf("tconx to share %s with type %s "
1434                                "should have failed but succeeded\n",
1435                                myshare, devtype);
1436                         ret = False;
1437                 } else {
1438                         if (NT_STATUS_EQUAL(cli_nt_error(cli),
1439                                             expected_error)) {
1440                                 ret = True;
1441                         } else {
1442                                 printf("Returned unexpected error\n");
1443                                 ret = False;
1444                         }
1445                 }
1446         }
1447         return ret;
1448 }
1449
1450 /*
1451  checks for correct tconX support
1452  */
1453 static bool run_tcon_devtype_test(int dummy)
1454 {
1455         static struct cli_state *cli1 = NULL;
1456         int flags = 0;
1457         NTSTATUS status;
1458         bool ret = True;
1459
1460         status = cli_full_connection(&cli1, myname,
1461                                      host, NULL, port_to_use,
1462                                      NULL, NULL,
1463                                      username, workgroup,
1464                                      password, flags, signing_state);
1465
1466         if (!NT_STATUS_IS_OK(status)) {
1467                 printf("could not open connection\n");
1468                 return False;
1469         }
1470
1471         if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1472                 ret = False;
1473
1474         if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1475                 ret = False;
1476
1477         if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1478                 ret = False;
1479
1480         if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1481                 ret = False;
1482
1483         if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1484                 ret = False;
1485
1486         if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1487                 ret = False;
1488
1489         if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1490                 ret = False;
1491
1492         if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1493                 ret = False;
1494
1495         if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1496                 ret = False;
1497
1498         if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1499                 ret = False;
1500
1501         cli_shutdown(cli1);
1502
1503         if (ret)
1504                 printf("Passed tcondevtest\n");
1505
1506         return ret;
1507 }
1508
1509
1510 /*
1511   This test checks that 
1512
1513   1) the server supports multiple locking contexts on the one SMB
1514   connection, distinguished by PID.  
1515
1516   2) the server correctly fails overlapping locks made by the same PID (this
1517      goes against POSIX behaviour, which is why it is tricky to implement)
1518
1519   3) the server denies unlock requests by an incorrect client PID
1520 */
1521 static bool run_locktest2(int dummy)
1522 {
1523         static struct cli_state *cli;
1524         const char *fname = "\\lockt2.lck";
1525         uint16_t fnum1, fnum2, fnum3;
1526         bool correct = True;
1527
1528         if (!torture_open_connection(&cli, 0)) {
1529                 return False;
1530         }
1531
1532         cli_sockopt(cli, sockops);
1533
1534         printf("starting locktest2\n");
1535
1536         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1537
1538         cli_setpid(cli, 1);
1539
1540         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1541                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1542                 return False;
1543         }
1544
1545         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1546                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1547                 return False;
1548         }
1549
1550         cli_setpid(cli, 2);
1551
1552         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1553                 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1554                 return False;
1555         }
1556
1557         cli_setpid(cli, 1);
1558
1559         if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1560                 printf("lock1 failed (%s)\n", cli_errstr(cli));
1561                 return False;
1562         }
1563
1564         if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1565                 printf("WRITE lock1 succeeded! This is a locking bug\n");
1566                 correct = False;
1567         } else {
1568                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1569                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1570         }
1571
1572         if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1573                 printf("WRITE lock2 succeeded! This is a locking bug\n");
1574                 correct = False;
1575         } else {
1576                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1577                                  NT_STATUS_LOCK_NOT_GRANTED)) return False;
1578         }
1579
1580         if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1581                 printf("READ lock2 succeeded! This is a locking bug\n");
1582                 correct = False;
1583         } else {
1584                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
1585                                  NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1586         }
1587
1588         if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1589                 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1590         }
1591         cli_setpid(cli, 2);
1592         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1593                 printf("unlock at 100 succeeded! This is a locking bug\n");
1594                 correct = False;
1595         }
1596
1597         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1598                 printf("unlock1 succeeded! This is a locking bug\n");
1599                 correct = False;
1600         } else {
1601                 if (!check_error(__LINE__, cli, 
1602                                  ERRDOS, ERRlock, 
1603                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1604         }
1605
1606         if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1607                 printf("unlock2 succeeded! This is a locking bug\n");
1608                 correct = False;
1609         } else {
1610                 if (!check_error(__LINE__, cli, 
1611                                  ERRDOS, ERRlock, 
1612                                  NT_STATUS_RANGE_NOT_LOCKED)) return False;
1613         }
1614
1615         if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1616                 printf("lock3 succeeded! This is a locking bug\n");
1617                 correct = False;
1618         } else {
1619                 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1620         }
1621
1622         cli_setpid(cli, 1);
1623
1624         if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1625                 printf("close1 failed (%s)\n", cli_errstr(cli));
1626                 return False;
1627         }
1628
1629         if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1630                 printf("close2 failed (%s)\n", cli_errstr(cli));
1631                 return False;
1632         }
1633
1634         if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1635                 printf("close3 failed (%s)\n", cli_errstr(cli));
1636                 return False;
1637         }
1638
1639         if (!torture_close_connection(cli)) {
1640                 correct = False;
1641         }
1642
1643         printf("locktest2 finished\n");
1644
1645         return correct;
1646 }
1647
1648
1649 /*
1650   This test checks that 
1651
1652   1) the server supports the full offset range in lock requests
1653 */
1654 static bool run_locktest3(int dummy)
1655 {
1656         static struct cli_state *cli1, *cli2;
1657         const char *fname = "\\lockt3.lck";
1658         uint16_t fnum1, fnum2;
1659         int i;
1660         uint32 offset;
1661         bool correct = True;
1662
1663 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1664
1665         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1666                 return False;
1667         }
1668         cli_sockopt(cli1, sockops);
1669         cli_sockopt(cli2, sockops);
1670
1671         printf("starting locktest3\n");
1672
1673         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1674
1675         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1676                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1677                 return False;
1678         }
1679         if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1680                 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1681                 return False;
1682         }
1683
1684         for (offset=i=0;i<torture_numops;i++) {
1685                 NEXT_OFFSET;
1686                 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1687                         printf("lock1 %d failed (%s)\n", 
1688                                i,
1689                                cli_errstr(cli1));
1690                         return False;
1691                 }
1692
1693                 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1694                         printf("lock2 %d failed (%s)\n", 
1695                                i,
1696                                cli_errstr(cli1));
1697                         return False;
1698                 }
1699         }
1700
1701         for (offset=i=0;i<torture_numops;i++) {
1702                 NEXT_OFFSET;
1703
1704                 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1705                         printf("error: lock1 %d succeeded!\n", i);
1706                         return False;
1707                 }
1708
1709                 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1710                         printf("error: lock2 %d succeeded!\n", i);
1711                         return False;
1712                 }
1713
1714                 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1715                         printf("error: lock3 %d succeeded!\n", i);
1716                         return False;
1717                 }
1718
1719                 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1720                         printf("error: lock4 %d succeeded!\n", i);
1721                         return False;
1722                 }
1723         }
1724
1725         for (offset=i=0;i<torture_numops;i++) {
1726                 NEXT_OFFSET;
1727
1728                 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1729                         printf("unlock1 %d failed (%s)\n", 
1730                                i,
1731                                cli_errstr(cli1));
1732                         return False;
1733                 }
1734
1735                 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1736                         printf("unlock2 %d failed (%s)\n", 
1737                                i,
1738                                cli_errstr(cli1));
1739                         return False;
1740                 }
1741         }
1742
1743         if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1744                 printf("close1 failed (%s)\n", cli_errstr(cli1));
1745                 return False;
1746         }
1747
1748         if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1749                 printf("close2 failed (%s)\n", cli_errstr(cli2));
1750                 return False;
1751         }
1752
1753         if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1754                 printf("unlink failed (%s)\n", cli_errstr(cli1));
1755                 return False;
1756         }
1757
1758         if (!torture_close_connection(cli1)) {
1759                 correct = False;
1760         }
1761
1762         if (!torture_close_connection(cli2)) {
1763                 correct = False;
1764         }
1765
1766         printf("finished locktest3\n");
1767
1768         return correct;
1769 }
1770
1771 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1772         printf("** "); correct = False; \
1773         }
1774
1775 /*
1776   looks at overlapping locks
1777 */
1778 static bool run_locktest4(int dummy)
1779 {
1780         static struct cli_state *cli1, *cli2;
1781         const char *fname = "\\lockt4.lck";
1782         uint16_t fnum1, fnum2, f;
1783         bool ret;
1784         char buf[1000];
1785         bool correct = True;
1786
1787         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1788                 return False;
1789         }
1790
1791         cli_sockopt(cli1, sockops);
1792         cli_sockopt(cli2, sockops);
1793
1794         printf("starting locktest4\n");
1795
1796         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1797
1798         cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1799         cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1800
1801         memset(buf, 0, sizeof(buf));
1802
1803         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1804                 printf("Failed to create file\n");
1805                 correct = False;
1806                 goto fail;
1807         }
1808
1809         ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1810               cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1811         EXPECTED(ret, False);
1812         printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1813
1814         ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1815               cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1816         EXPECTED(ret, True);
1817         printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1818
1819         ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1820               cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1821         EXPECTED(ret, False);
1822         printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1823
1824         ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1825               cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1826         EXPECTED(ret, True);
1827         printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1828
1829         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1830               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1831         EXPECTED(ret, False);
1832         printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1833
1834         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1835               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1836         EXPECTED(ret, True);
1837         printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1838
1839         ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1840               cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1841         EXPECTED(ret, True);
1842         printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1843
1844         ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1845               cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1846         EXPECTED(ret, False);
1847         printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1848
1849         ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1850               cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1851         EXPECTED(ret, False);
1852         printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1853
1854         ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1855               cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1856         EXPECTED(ret, True);
1857         printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1858
1859         ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1860               (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1861         EXPECTED(ret, False);
1862         printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1863
1864         ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1865               cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1866               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1867         EXPECTED(ret, False);
1868         printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1869
1870
1871         ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1872               (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1873         EXPECTED(ret, False);
1874         printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1875
1876         ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1877               (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1878         EXPECTED(ret, False);
1879         printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1880
1881
1882         ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1883               cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1884               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1885               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1886         EXPECTED(ret, True);
1887         printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1888
1889
1890         ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1891               cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1892               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1893               (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1894               !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1895               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1896         EXPECTED(ret, True);
1897         printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1898
1899         ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1900               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1901               (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&          
1902               (cli_read(cli2, fnum2, buf, 160, 4) == 4);                
1903         EXPECTED(ret, True);
1904         printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1905
1906         ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1907               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1908               (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&          
1909               (cli_read(cli2, fnum2, buf, 170, 4) == 4);                
1910         EXPECTED(ret, True);
1911         printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1912
1913         ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1914               cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1915               NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1916               !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&         
1917               (cli_read(cli2, fnum2, buf, 190, 4) == 4);                
1918         EXPECTED(ret, True);
1919         printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1920
1921         cli_close(cli1, fnum1);
1922         cli_close(cli2, fnum2);
1923         cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1924         cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1925         ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1926               cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1927               NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1928               NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1929               cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1930         cli_close(cli1, f);
1931         cli_close(cli1, fnum1);
1932         EXPECTED(ret, True);
1933         printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1934
1935  fail:
1936         cli_close(cli1, fnum1);
1937         cli_close(cli2, fnum2);
1938         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1939         torture_close_connection(cli1);
1940         torture_close_connection(cli2);
1941
1942         printf("finished locktest4\n");
1943         return correct;
1944 }
1945
1946 /*
1947   looks at lock upgrade/downgrade.
1948 */
1949 static bool run_locktest5(int dummy)
1950 {
1951         static struct cli_state *cli1, *cli2;
1952         const char *fname = "\\lockt5.lck";
1953         uint16_t fnum1, fnum2, fnum3;
1954         bool ret;
1955         char buf[1000];
1956         bool correct = True;
1957
1958         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1959                 return False;
1960         }
1961
1962         cli_sockopt(cli1, sockops);
1963         cli_sockopt(cli2, sockops);
1964
1965         printf("starting locktest5\n");
1966
1967         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1968
1969         cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1970         cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1971         cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1972
1973         memset(buf, 0, sizeof(buf));
1974
1975         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1976                 printf("Failed to create file\n");
1977                 correct = False;
1978                 goto fail;
1979         }
1980
1981         /* Check for NT bug... */
1982         ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1983                   cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1984         cli_close(cli1, fnum1);
1985         cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1986         ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1987         EXPECTED(ret, True);
1988         printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1989         cli_close(cli1, fnum1);
1990         cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1991         cli_unlock(cli1, fnum3, 0, 1);
1992
1993         ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1994               cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1995         EXPECTED(ret, True);
1996         printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1997
1998         ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1999         EXPECTED(ret, False);
2000
2001         printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2002
2003         /* Unlock the process 2 lock. */
2004         cli_unlock(cli2, fnum2, 0, 4);
2005
2006         ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2007         EXPECTED(ret, False);
2008
2009         printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2010
2011         /* Unlock the process 1 fnum3 lock. */
2012         cli_unlock(cli1, fnum3, 0, 4);
2013
2014         /* Stack 2 more locks here. */
2015         ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2016                   cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2017
2018         EXPECTED(ret, True);
2019         printf("the same process %s stack read locks\n", ret?"can":"cannot");
2020
2021         /* Unlock the first process lock, then check this was the WRITE lock that was
2022                 removed. */
2023
2024         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2025                         cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2026
2027         EXPECTED(ret, True);
2028         printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2029
2030         /* Unlock the process 2 lock. */
2031         cli_unlock(cli2, fnum2, 0, 4);
2032
2033         /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2034
2035         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2036                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2037                   NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2038
2039         EXPECTED(ret, True);
2040         printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
2041
2042         /* Ensure the next unlock fails. */
2043         ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2044         EXPECTED(ret, False);
2045         printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
2046
2047         /* Ensure connection 2 can get a write lock. */
2048         ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2049         EXPECTED(ret, True);
2050
2051         printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2052
2053
2054  fail:
2055         cli_close(cli1, fnum1);
2056         cli_close(cli2, fnum2);
2057         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2058         if (!torture_close_connection(cli1)) {
2059                 correct = False;
2060         }
2061         if (!torture_close_connection(cli2)) {
2062                 correct = False;
2063         }
2064
2065         printf("finished locktest5\n");
2066
2067         return correct;
2068 }
2069
2070 /*
2071   tries the unusual lockingX locktype bits
2072 */
2073 static bool run_locktest6(int dummy)
2074 {
2075         static struct cli_state *cli;
2076         const char *fname[1] = { "\\lock6.txt" };
2077         int i;
2078         uint16_t fnum;
2079         NTSTATUS status;
2080
2081         if (!torture_open_connection(&cli, 0)) {
2082                 return False;
2083         }
2084
2085         cli_sockopt(cli, sockops);
2086
2087         printf("starting locktest6\n");
2088
2089         for (i=0;i<1;i++) {
2090                 printf("Testing %s\n", fname[i]);
2091
2092                 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2093
2094                 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2095                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2096                 cli_close(cli, fnum);
2097                 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2098
2099                 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2100                 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2101                 cli_close(cli, fnum);
2102                 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2103
2104                 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2105         }
2106
2107         torture_close_connection(cli);
2108
2109         printf("finished locktest6\n");
2110         return True;
2111 }
2112
2113 static bool run_locktest7(int dummy)
2114 {
2115         struct cli_state *cli1;
2116         const char *fname = "\\lockt7.lck";
2117         uint16_t fnum1;
2118         char buf[200];
2119         bool correct = False;
2120
2121         if (!torture_open_connection(&cli1, 0)) {
2122                 return False;
2123         }
2124
2125         cli_sockopt(cli1, sockops);
2126
2127         printf("starting locktest7\n");
2128
2129         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2130
2131         cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2132
2133         memset(buf, 0, sizeof(buf));
2134
2135         if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
2136                 printf("Failed to create file\n");
2137                 goto fail;
2138         }
2139
2140         cli_setpid(cli1, 1);
2141
2142         if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2143                 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2144                 goto fail;
2145         } else {
2146                 printf("pid1 successfully locked range 130:4 for READ\n");
2147         }
2148
2149         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2150                 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2151                 goto fail;
2152         } else {
2153                 printf("pid1 successfully read the range 130:4\n");
2154         }
2155
2156         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2157                 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2158                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2159                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2160                         goto fail;
2161                 }
2162         } else {
2163                 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2164                 goto fail;
2165         }
2166
2167         cli_setpid(cli1, 2);
2168
2169         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2170                 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2171         } else {
2172                 printf("pid2 successfully read the range 130:4\n");
2173         }
2174
2175         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2176                 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2177                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2178                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2179                         goto fail;
2180                 }
2181         } else {
2182                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2183                 goto fail;
2184         }
2185
2186         cli_setpid(cli1, 1);
2187         cli_unlock(cli1, fnum1, 130, 4);
2188
2189         if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2190                 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2191                 goto fail;
2192         } else {
2193                 printf("pid1 successfully locked range 130:4 for WRITE\n");
2194         }
2195
2196         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2197                 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2198                 goto fail;
2199         } else {
2200                 printf("pid1 successfully read the range 130:4\n");
2201         }
2202
2203         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2204                 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2205                 goto fail;
2206         } else {
2207                 printf("pid1 successfully wrote to the range 130:4\n");
2208         }
2209
2210         cli_setpid(cli1, 2);
2211
2212         if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2213                 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2214                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2215                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2216                         goto fail;
2217                 }
2218         } else {
2219                 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2220                 goto fail;
2221         }
2222
2223         if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2224                 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2225                 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2226                         printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2227                         goto fail;
2228                 }
2229         } else {
2230                 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2231                 goto fail;
2232         }
2233
2234         cli_unlock(cli1, fnum1, 130, 0);
2235         correct = True;
2236
2237 fail:
2238         cli_close(cli1, fnum1);
2239         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2240         torture_close_connection(cli1);
2241
2242         printf("finished locktest7\n");
2243         return correct;
2244 }
2245
2246 /*
2247  * This demonstrates a problem with our use of GPFS share modes: A file
2248  * descriptor sitting in the pending close queue holding a GPFS share mode
2249  * blocks opening a file another time. Happens with Word 2007 temp files.
2250  * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2251  * open is denied with NT_STATUS_SHARING_VIOLATION.
2252  */
2253
2254 static bool run_locktest8(int dummy)
2255 {
2256         struct cli_state *cli1;
2257         const char *fname = "\\lockt8.lck";
2258         uint16_t fnum1, fnum2;
2259         char buf[200];
2260         bool correct = False;
2261         NTSTATUS status;
2262
2263         if (!torture_open_connection(&cli1, 0)) {
2264                 return False;
2265         }
2266
2267         cli_sockopt(cli1, sockops);
2268
2269         printf("starting locktest8\n");
2270
2271         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2272
2273         status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2274                           &fnum1);
2275         if (!NT_STATUS_IS_OK(status)) {
2276                 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2277                 return false;
2278         }
2279
2280         memset(buf, 0, sizeof(buf));
2281
2282         status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2283         if (!NT_STATUS_IS_OK(status)) {
2284                 d_fprintf(stderr, "cli_open second time returned %s\n",
2285                           cli_errstr(cli1));
2286                 goto fail;
2287         }
2288
2289         if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2290                 printf("Unable to apply read lock on range 1:1, error was "
2291                        "%s\n", cli_errstr(cli1));
2292                 goto fail;
2293         }
2294
2295         status = cli_close(cli1, fnum1);
2296         if (!NT_STATUS_IS_OK(status)) {
2297                 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2298                 goto fail;
2299         }
2300
2301         status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2302         if (!NT_STATUS_IS_OK(status)) {
2303                 d_fprintf(stderr, "cli_open third time returned %s\n",
2304                           cli_errstr(cli1));
2305                 goto fail;
2306         }
2307
2308         correct = true;
2309
2310 fail:
2311         cli_close(cli1, fnum1);
2312         cli_close(cli1, fnum2);
2313         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2314         torture_close_connection(cli1);
2315
2316         printf("finished locktest8\n");
2317         return correct;
2318 }
2319
2320 /*
2321  * This test is designed to be run in conjunction with
2322  * external NFS or POSIX locks taken in the filesystem.
2323  * It checks that the smbd server will block until the
2324  * lock is released and then acquire it. JRA.
2325  */
2326
2327 static bool got_alarm;
2328 static int alarm_fd;
2329
2330 static void alarm_handler(int dummy)
2331 {
2332         got_alarm = True;
2333 }
2334
2335 static void alarm_handler_parent(int dummy)
2336 {
2337         close(alarm_fd);
2338 }
2339
2340 static void do_local_lock(int read_fd, int write_fd)
2341 {
2342         int fd;
2343         char c = '\0';
2344         struct flock lock;
2345         const char *local_pathname = NULL;
2346         int ret;
2347
2348         local_pathname = talloc_asprintf(talloc_tos(),
2349                         "%s/lockt9.lck", local_path);
2350         if (!local_pathname) {
2351                 printf("child: alloc fail\n");
2352                 exit(1);
2353         }
2354
2355         unlink(local_pathname);
2356         fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2357         if (fd == -1) {
2358                 printf("child: open of %s failed %s.\n",
2359                         local_pathname, strerror(errno));
2360                 exit(1);
2361         }
2362
2363         /* Now take a fcntl lock. */
2364         lock.l_type = F_WRLCK;
2365         lock.l_whence = SEEK_SET;
2366         lock.l_start = 0;
2367         lock.l_len = 4;
2368         lock.l_pid = getpid();
2369
2370         ret = fcntl(fd,F_SETLK,&lock);
2371         if (ret == -1) {
2372                 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2373                         local_pathname, strerror(errno));
2374                 exit(1);
2375         } else {
2376                 printf("child: got lock 0:4 on file %s.\n",
2377                         local_pathname );
2378                 fflush(stdout);
2379         }
2380
2381         CatchSignal(SIGALRM, alarm_handler);
2382         alarm(5);
2383         /* Signal the parent. */
2384         if (write(write_fd, &c, 1) != 1) {
2385                 printf("child: start signal fail %s.\n",
2386                         strerror(errno));
2387                 exit(1);
2388         }
2389         alarm(0);
2390
2391         alarm(10);
2392         /* Wait for the parent to be ready. */
2393         if (read(read_fd, &c, 1) != 1) {
2394                 printf("child: reply signal fail %s.\n",
2395                         strerror(errno));
2396                 exit(1);
2397         }
2398         alarm(0);
2399
2400         sleep(5);
2401         close(fd);
2402         printf("child: released lock 0:4 on file %s.\n",
2403                 local_pathname );
2404         fflush(stdout);
2405         exit(0);
2406 }
2407
2408 static bool run_locktest9(int dummy)
2409 {
2410         struct cli_state *cli1;
2411         const char *fname = "\\lockt9.lck";
2412         uint16_t fnum;
2413         bool correct = False;
2414         int pipe_in[2], pipe_out[2];
2415         pid_t child_pid;
2416         char c = '\0';
2417         int ret;
2418         struct timeval start;
2419         double seconds;
2420         NTSTATUS status;
2421
2422         printf("starting locktest9\n");
2423
2424         if (local_path == NULL) {
2425                 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2426                 return false;
2427         }
2428
2429         if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2430                 return false;
2431         }
2432
2433         child_pid = fork();
2434         if (child_pid == -1) {
2435                 return false;
2436         }
2437
2438         if (child_pid == 0) {
2439                 /* Child. */
2440                 do_local_lock(pipe_out[0], pipe_in[1]);
2441                 exit(0);
2442         }
2443
2444         close(pipe_out[0]);
2445         close(pipe_in[1]);
2446         pipe_out[0] = -1;
2447         pipe_in[1] = -1;
2448
2449         /* Parent. */
2450         ret = read(pipe_in[0], &c, 1);
2451         if (ret != 1) {
2452                 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2453                         strerror(errno));
2454                 return false;
2455         }
2456
2457         if (!torture_open_connection(&cli1, 0)) {
2458                 return false;
2459         }
2460
2461         cli_sockopt(cli1, sockops);
2462
2463         status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2464                           &fnum);
2465         if (!NT_STATUS_IS_OK(status)) {
2466                 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2467                 return false;
2468         }
2469
2470         /* Ensure the child has the lock. */
2471         if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2472                 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2473                 goto fail;
2474         } else {
2475                 d_printf("Child has the lock.\n");
2476         }
2477
2478         /* Tell the child to wait 5 seconds then exit. */
2479         ret = write(pipe_out[1], &c, 1);
2480         if (ret != 1) {
2481                 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2482                         strerror(errno));
2483                 goto fail;
2484         }
2485
2486         /* Wait 20 seconds for the lock. */
2487         alarm_fd = cli1->fd;
2488         CatchSignal(SIGALRM, alarm_handler_parent);
2489         alarm(20);
2490
2491         start = timeval_current();
2492
2493         if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2494                 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2495                        "%s\n", cli_errstr(cli1));
2496                 goto fail_nofd;
2497         }
2498         alarm(0);
2499
2500         seconds = timeval_elapsed(&start);
2501
2502         printf("Parent got the lock after %.2f seconds.\n",
2503                 seconds);
2504
2505         status = cli_close(cli1, fnum);
2506         if (!NT_STATUS_IS_OK(status)) {
2507                 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2508                 goto fail;
2509         }
2510
2511         correct = true;
2512
2513 fail:
2514         cli_close(cli1, fnum);
2515         torture_close_connection(cli1);
2516
2517 fail_nofd:
2518
2519         printf("finished locktest9\n");
2520         return correct;
2521 }
2522
2523 /*
2524 test whether fnums and tids open on one VC are available on another (a major
2525 security hole)
2526 */
2527 static bool run_fdpasstest(int dummy)
2528 {
2529         struct cli_state *cli1, *cli2;
2530         const char *fname = "\\fdpass.tst";
2531         uint16_t fnum1;
2532         char buf[1024];
2533
2534         if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2535                 return False;
2536         }
2537         cli_sockopt(cli1, sockops);
2538         cli_sockopt(cli2, sockops);
2539
2540         printf("starting fdpasstest\n");
2541
2542         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2543
2544         if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2545                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2546                 return False;
2547         }
2548
2549         if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2550                 printf("write failed (%s)\n", cli_errstr(cli1));
2551                 return False;
2552         }
2553
2554         cli2->vuid = cli1->vuid;
2555         cli2->cnum = cli1->cnum;
2556         cli2->pid = cli1->pid;
2557
2558         if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2559                 printf("read succeeded! nasty security hole [%s]\n",
2560                        buf);
2561                 return False;
2562         }
2563
2564         cli_close(cli1, fnum1);
2565         cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2566
2567         torture_close_connection(cli1);
2568         torture_close_connection(cli2);
2569
2570         printf("finished fdpasstest\n");
2571         return True;
2572 }
2573
2574 static bool run_fdsesstest(int dummy)
2575 {
2576         struct cli_state *cli;
2577         uint16 new_vuid;
2578         uint16 saved_vuid;
2579         uint16 new_cnum;
2580         uint16 saved_cnum;
2581         const char *fname = "\\fdsess.tst";
2582         const char *fname1 = "\\fdsess1.tst";
2583         uint16_t fnum1;
2584         uint16_t fnum2;
2585         char buf[1024];
2586         bool ret = True;
2587
2588         if (!torture_open_connection(&cli, 0))
2589                 return False;
2590         cli_sockopt(cli, sockops);
2591
2592         if (!torture_cli_session_setup2(cli, &new_vuid))
2593                 return False;
2594
2595         saved_cnum = cli->cnum;
2596         if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2597                 return False;
2598         new_cnum = cli->cnum;
2599         cli->cnum = saved_cnum;
2600
2601         printf("starting fdsesstest\n");
2602
2603         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2604         cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2605
2606         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2607                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2608                 return False;
2609         }
2610
2611         if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2612                 printf("write failed (%s)\n", cli_errstr(cli));
2613                 return False;
2614         }
2615
2616         saved_vuid = cli->vuid;
2617         cli->vuid = new_vuid;
2618
2619         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2620                 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2621                        buf);
2622                 ret = False;
2623         }
2624         /* Try to open a file with different vuid, samba cnum. */
2625         if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2626                 printf("create with different vuid, same cnum succeeded.\n");
2627                 cli_close(cli, fnum2);
2628                 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2629         } else {
2630                 printf("create with different vuid, same cnum failed.\n");
2631                 printf("This will cause problems with service clients.\n");
2632                 ret = False;
2633         }
2634
2635         cli->vuid = saved_vuid;
2636
2637         /* Try with same vuid, different cnum. */
2638         cli->cnum = new_cnum;
2639
2640         if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2641                 printf("read succeeded with different cnum![%s]\n",
2642                        buf);
2643                 ret = False;
2644         }
2645
2646         cli->cnum = saved_cnum;
2647         cli_close(cli, fnum1);
2648         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2649
2650         torture_close_connection(cli);
2651
2652         printf("finished fdsesstest\n");
2653         return ret;
2654 }
2655
2656 /*
2657   This test checks that 
2658
2659   1) the server does not allow an unlink on a file that is open
2660 */
2661 static bool run_unlinktest(int dummy)
2662 {
2663         struct cli_state *cli;
2664         const char *fname = "\\unlink.tst";
2665         uint16_t fnum;
2666         bool correct = True;
2667
2668         if (!torture_open_connection(&cli, 0)) {
2669                 return False;
2670         }
2671
2672         cli_sockopt(cli, sockops);
2673
2674         printf("starting unlink test\n");
2675
2676         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2677
2678         cli_setpid(cli, 1);
2679
2680         if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2681                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2682                 return False;
2683         }
2684
2685         if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2686                 printf("error: server allowed unlink on an open file\n");
2687                 correct = False;
2688         } else {
2689                 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare, 
2690                                       NT_STATUS_SHARING_VIOLATION);
2691         }
2692
2693         cli_close(cli, fnum);
2694         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2695
2696         if (!torture_close_connection(cli)) {
2697                 correct = False;
2698         }
2699
2700         printf("unlink test finished\n");
2701
2702         return correct;
2703 }
2704
2705
2706 /*
2707 test how many open files this server supports on the one socket
2708 */
2709 static bool run_maxfidtest(int dummy)
2710 {
2711         struct cli_state *cli;
2712         const char *ftemplate = "\\maxfid.%d.%d";
2713         fstring fname;
2714         uint16_t fnums[0x11000];
2715         int i;
2716         int retries=4;
2717         bool correct = True;
2718
2719         cli = current_cli;
2720
2721         if (retries <= 0) {
2722                 printf("failed to connect\n");
2723                 return False;
2724         }
2725
2726         cli_sockopt(cli, sockops);
2727
2728         for (i=0; i<0x11000; i++) {
2729                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2730                 if (!NT_STATUS_IS_OK(cli_open(cli, fname, 
2731                                         O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2732                         printf("open of %s failed (%s)\n", 
2733                                fname, cli_errstr(cli));
2734                         printf("maximum fnum is %d\n", i);
2735                         break;
2736                 }
2737                 printf("%6d\r", i);
2738         }
2739         printf("%6d\n", i);
2740         i--;
2741
2742         printf("cleaning up\n");
2743         for (;i>=0;i--) {
2744                 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2745                 cli_close(cli, fnums[i]);
2746                 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2747                         printf("unlink of %s failed (%s)\n", 
2748                                fname, cli_errstr(cli));
2749                         correct = False;
2750                 }
2751                 printf("%6d\r", i);
2752         }
2753         printf("%6d\n", 0);
2754
2755         printf("maxfid test finished\n");
2756         if (!torture_close_connection(cli)) {
2757                 correct = False;
2758         }
2759         return correct;
2760 }
2761
2762 /* generate a random buffer */
2763 static void rand_buf(char *buf, int len)
2764 {
2765         while (len--) {
2766                 *buf = (char)sys_random();
2767                 buf++;
2768         }
2769 }
2770
2771 /* send smb negprot commands, not reading the response */
2772 static bool run_negprot_nowait(int dummy)
2773 {
2774         int i;
2775         static struct cli_state *cli;
2776         bool correct = True;
2777
2778         printf("starting negprot nowait test\n");
2779
2780         if (!(cli = open_nbt_connection())) {
2781                 return False;
2782         }
2783
2784         for (i=0;i<50000;i++) {
2785                 cli_negprot_sendsync(cli);
2786         }
2787
2788         if (!torture_close_connection(cli)) {
2789                 correct = False;
2790         }
2791
2792         printf("finished negprot nowait test\n");
2793
2794         return correct;
2795 }
2796
2797 /* send smb negprot commands, not reading the response */
2798 static bool run_bad_nbt_session(int dummy)
2799 {
2800         static struct cli_state *cli;
2801
2802         printf("starting bad nbt session test\n");
2803
2804         if (!(cli = open_bad_nbt_connection())) {
2805                 return False;
2806         }
2807
2808         cli_shutdown(cli);
2809         printf("finished bad nbt session test\n");
2810         return true;
2811 }
2812
2813 /* send random IPC commands */
2814 static bool run_randomipc(int dummy)
2815 {
2816         char *rparam = NULL;
2817         char *rdata = NULL;
2818         unsigned int rdrcnt,rprcnt;
2819         char param[1024];
2820         int api, param_len, i;
2821         struct cli_state *cli;
2822         bool correct = True;
2823         int count = 50000;
2824
2825         printf("starting random ipc test\n");
2826
2827         if (!torture_open_connection(&cli, 0)) {
2828                 return False;
2829         }
2830
2831         for (i=0;i<count;i++) {
2832                 api = sys_random() % 500;
2833                 param_len = (sys_random() % 64);
2834
2835                 rand_buf(param, param_len);
2836
2837                 SSVAL(param,0,api); 
2838
2839                 cli_api(cli, 
2840                         param, param_len, 8,  
2841                         NULL, 0, BUFFER_SIZE, 
2842                         &rparam, &rprcnt,     
2843                         &rdata, &rdrcnt);
2844                 if (i % 100 == 0) {
2845                         printf("%d/%d\r", i,count);
2846                 }
2847         }
2848         printf("%d/%d\n", i, count);
2849
2850         if (!torture_close_connection(cli)) {
2851                 correct = False;
2852         }
2853
2854         printf("finished random ipc test\n");
2855
2856         return correct;
2857 }
2858
2859
2860
2861 static void browse_callback(const char *sname, uint32 stype, 
2862                             const char *comment, void *state)
2863 {
2864         printf("\t%20.20s %08x %s\n", sname, stype, comment);
2865 }
2866
2867
2868
2869 /*
2870   This test checks the browse list code
2871
2872 */
2873 static bool run_browsetest(int dummy)
2874 {
2875         static struct cli_state *cli;
2876         bool correct = True;
2877
2878         printf("starting browse test\n");
2879
2880         if (!torture_open_connection(&cli, 0)) {
2881                 return False;
2882         }
2883
2884         printf("domain list:\n");
2885         cli_NetServerEnum(cli, cli->server_domain, 
2886                           SV_TYPE_DOMAIN_ENUM,
2887                           browse_callback, NULL);
2888
2889         printf("machine list:\n");
2890         cli_NetServerEnum(cli, cli->server_domain, 
2891                           SV_TYPE_ALL,
2892                           browse_callback, NULL);
2893
2894         if (!torture_close_connection(cli)) {
2895                 correct = False;
2896         }
2897
2898         printf("browse test finished\n");
2899
2900         return correct;
2901
2902 }
2903
2904
2905 /*
2906   This checks how the getatr calls works
2907 */
2908 static bool run_attrtest(int dummy)
2909 {
2910         struct cli_state *cli;
2911         uint16_t fnum;
2912         time_t t, t2;
2913         const char *fname = "\\attrib123456789.tst";
2914         bool correct = True;
2915
2916         printf("starting attrib test\n");
2917
2918         if (!torture_open_connection(&cli, 0)) {
2919                 return False;
2920         }
2921
2922         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2923         cli_open(cli, fname, 
2924                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2925         cli_close(cli, fnum);
2926         if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2927                 printf("getatr failed (%s)\n", cli_errstr(cli));
2928                 correct = False;
2929         }
2930
2931         if (abs(t - time(NULL)) > 60*60*24*10) {
2932                 printf("ERROR: SMBgetatr bug. time is %s",
2933                        ctime(&t));
2934                 t = time(NULL);
2935                 correct = True;
2936         }
2937
2938         t2 = t-60*60*24; /* 1 day ago */
2939
2940         if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2941                 printf("setatr failed (%s)\n", cli_errstr(cli));
2942                 correct = True;
2943         }
2944
2945         if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2946                 printf("getatr failed (%s)\n", cli_errstr(cli));
2947                 correct = True;
2948         }
2949
2950         if (t != t2) {
2951                 printf("ERROR: getatr/setatr bug. times are\n%s",
2952                        ctime(&t));
2953                 printf("%s", ctime(&t2));
2954                 correct = True;
2955         }
2956
2957         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2958
2959         if (!torture_close_connection(cli)) {
2960                 correct = False;
2961         }
2962
2963         printf("attrib test finished\n");
2964
2965         return correct;
2966 }
2967
2968
2969 /*
2970   This checks a couple of trans2 calls
2971 */
2972 static bool run_trans2test(int dummy)
2973 {
2974         struct cli_state *cli;
2975         uint16_t fnum;
2976         SMB_OFF_T size;
2977         time_t c_time, a_time, m_time;
2978         struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2979         const char *fname = "\\trans2.tst";
2980         const char *dname = "\\trans2";
2981         const char *fname2 = "\\trans2\\trans2.tst";
2982         char pname[1024];
2983         bool correct = True;
2984         NTSTATUS status;
2985         uint32_t fs_attr;
2986
2987         printf("starting trans2 test\n");
2988
2989         if (!torture_open_connection(&cli, 0)) {
2990                 return False;
2991         }
2992
2993         status = cli_get_fs_attr_info(cli, &fs_attr);
2994         if (!NT_STATUS_IS_OK(status)) {
2995                 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2996                        nt_errstr(status));
2997                 correct = false;
2998         }
2999
3000         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3001         cli_open(cli, fname, 
3002                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3003         if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
3004                                      cli, fnum, NULL, &size, &c_time_ts,
3005                                      &a_time_ts, &w_time_ts,
3006                                      &m_time_ts, NULL))) {
3007                 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
3008                 correct = False;
3009         }
3010
3011         if (!NT_STATUS_IS_OK(cli_qfilename(cli, fnum, pname, sizeof(pname)))) {
3012                 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
3013                 correct = False;
3014         }
3015
3016         if (strcmp(pname, fname)) {
3017                 printf("qfilename gave different name? [%s] [%s]\n",
3018                        fname, pname);
3019                 correct = False;
3020         }
3021
3022         cli_close(cli, fnum);
3023
3024         sleep(2);
3025
3026         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3027         if (!NT_STATUS_IS_OK(cli_open(cli, fname, 
3028                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
3029                 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3030                 return False;
3031         }
3032         cli_close(cli, fnum);
3033
3034         status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3035                                 NULL);
3036         if (!NT_STATUS_IS_OK(status)) {
3037                 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3038                 correct = False;
3039         } else {
3040                 if (c_time != m_time) {
3041                         printf("create time=%s", ctime(&c_time));
3042                         printf("modify time=%s", ctime(&m_time));
3043                         printf("This system appears to have sticky create times\n");
3044                 }
3045                 if (a_time % (60*60) == 0) {
3046                         printf("access time=%s", ctime(&a_time));
3047                         printf("This system appears to set a midnight access time\n");
3048                         correct = False;
3049                 }
3050
3051                 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3052                         printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3053                         correct = False;
3054                 }
3055         }
3056
3057
3058         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3059         cli_open(cli, fname, 
3060                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3061         cli_close(cli, fnum);
3062         status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3063                                 &m_time_ts, &size, NULL, NULL);
3064         if (!NT_STATUS_IS_OK(status)) {
3065                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3066                 correct = False;
3067         } else {
3068                 if (w_time_ts.tv_sec < 60*60*24*2) {
3069                         printf("write time=%s", ctime(&w_time_ts.tv_sec));
3070                         printf("This system appears to set a initial 0 write time\n");
3071                         correct = False;
3072                 }
3073         }
3074
3075         cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3076
3077
3078         /* check if the server updates the directory modification time
3079            when creating a new file */
3080         if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
3081                 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
3082                 correct = False;
3083         }
3084         sleep(3);
3085         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3086                                 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3087         if (!NT_STATUS_IS_OK(status)) {
3088                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3089                 correct = False;
3090         }
3091
3092         cli_open(cli, fname2, 
3093                         O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3094         cli_write(cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
3095         cli_close(cli, fnum);
3096         status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3097                                 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3098         if (!NT_STATUS_IS_OK(status)) {
3099                 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3100                 correct = False;
3101         } else {
3102                 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3103                     == 0) {
3104                         printf("This system does not update directory modification times\n");
3105                         correct = False;
3106                 }
3107         }
3108         cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
3109         cli_rmdir(cli, dname);
3110
3111         if (!torture_close_connection(cli)) {
3112                 correct = False;
3113         }
3114
3115         printf("trans2 test finished\n");
3116
3117         return correct;
3118 }
3119
3120 /*
3121   This checks new W2K calls.
3122 */
3123
3124 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3125 {
3126         uint8_t *buf = NULL;
3127         uint32 len;
3128         NTSTATUS status;
3129
3130         status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3131                                pcli->max_xmit, &buf, &len);
3132         if (!NT_STATUS_IS_OK(status)) {
3133                 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3134                        nt_errstr(status));
3135         } else {
3136                 printf("qfileinfo: level %d, len = %u\n", level, len);
3137                 dump_data(0, (uint8 *)buf, len);
3138                 printf("\n");
3139         }
3140         TALLOC_FREE(buf);
3141         return status;
3142 }
3143
3144 static bool run_w2ktest(int dummy)
3145 {
3146         struct cli_state *cli;
3147         uint16_t fnum;
3148         const char *fname = "\\w2ktest\\w2k.tst";
3149         int level;
3150         bool correct = True;
3151
3152         printf("starting w2k test\n");
3153
3154         if (!torture_open_connection(&cli, 0)) {
3155                 return False;
3156         }
3157
3158         cli_open(cli, fname, 
3159                         O_RDWR | O_CREAT , DENY_NONE, &fnum);