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