Add *SMBSERVER fallback code to smbtorture ...
[Samba/gebeck_regimport.git] / source / torture / torture.c
blob2f779b9c893bbe7e5d1b4935c2194a83ed60237a
1 /*
2 Unix SMB/CIFS implementation.
3 SMB torture tester
4 Copyright (C) Andrew Tridgell 1997-1998
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.
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.
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.
21 #define NO_SYSLOG
23 #include "includes.h"
25 static fstring host, workgroup, share, password, username, myname;
26 static int max_protocol = PROTOCOL_NT1;
27 static const char *sockops="TCP_NODELAY";
28 static int nprocs=1;
29 static int port_to_use=0;
30 int torture_numops=100;
31 static int procnum; /* records process count number when forking */
32 static struct cli_state current_cli;
33 static fstring randomfname;
34 static BOOL use_oplocks;
35 static BOOL use_level_II_oplocks;
36 static const char *client_txt = "client_oplocks.txt";
37 static BOOL use_kerberos;
39 BOOL torture_showall = False;
41 static double create_procs(BOOL (*fn)(int), BOOL *result);
44 static struct timeval tp1,tp2;
46 void start_timer(void)
48 gettimeofday(&tp1,NULL);
51 double end_timer(void)
53 gettimeofday(&tp2,NULL);
54 return((tp2.tv_sec - tp1.tv_sec) +
55 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
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
63 The memory is not zeroed
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
68 void *shm_setup(int size)
70 int shmid;
71 void *ret;
73 shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
74 if (shmid == -1) {
75 printf("can't get shared memory\n");
76 exit(1);
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;
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
88 See Stevens "advanced programming in unix env" for details
90 shmctl(shmid, IPC_RMID, 0);
92 return ret;
96 static BOOL open_nbt_connection(struct cli_state *c)
98 struct nmb_name called, calling;
99 struct in_addr ip;
101 ZERO_STRUCTP(c);
103 make_nmb_name(&calling, myname, 0x0);
104 make_nmb_name(&called , host, 0x20);
106 zero_ip(&ip);
108 if (!cli_initialise(c)) {
109 printf("Failed initialize cli_struct to connect with %s\n", host);
110 return False;
113 c->port = port_to_use;
115 if (!cli_connect(c, host, &ip)) {
116 printf("Failed to connect with %s\n", host);
117 return False;
120 c->use_kerberos = use_kerberos;
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;
126 if (!cli_session_request(c, &calling, &called)) {
128 * Well, that failed, try *SMBSERVER ...
129 * However, we must reconnect as well ...
131 if (!cli_connect(c, host, &ip)) {
132 printf("Failed to connect with %s\n", host);
133 return False;
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;
146 return True;
149 BOOL torture_open_connection(struct cli_state *c)
151 ZERO_STRUCTP(c);
153 if (!open_nbt_connection(c)) {
154 return False;
157 if (!cli_negprot(c)) {
158 printf("%s rejected the negprot (%s)\n",host, cli_errstr(c));
159 cli_shutdown(c);
160 return False;
163 if (!cli_session_setup(c, username,
164 password, strlen(password),
165 password, strlen(password),
166 workgroup)) {
167 printf("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c));
168 cli_shutdown(c);
169 return False;
172 if (!cli_send_tconX(c, share, "?????",
173 password, strlen(password)+1)) {
174 printf("%s refused tree connect (%s)\n", host, cli_errstr(c));
175 cli_shutdown(c);
176 return False;
179 return True;
183 BOOL torture_close_connection(struct cli_state *c)
185 BOOL ret = True;
186 if (!cli_tdis(c)) {
187 printf("tdis failed (%s)\n", cli_errstr(c));
188 ret = False;
191 cli_shutdown(c);
193 return ret;
197 /* check if the server produced the expected error code */
198 static BOOL check_error(int line, struct cli_state *c,
199 uint8 eclass, uint32 ecode, NTSTATUS nterr)
201 if (cli_is_dos_error(c)) {
202 uint8 class;
203 uint32 num;
205 /* Check DOS error */
207 cli_dos_error(c, &class, &num);
209 if (eclass != class || ecode != num) {
210 printf("unexpected error code class=%d code=%d\n",
211 (int)class, (int)num);
212 printf(" expected %d/%d %s (line=%d)\n",
213 (int)eclass, (int)ecode, nt_errstr(nterr), line);
214 return False;
217 } else {
218 NTSTATUS status;
220 /* Check NT error */
222 status = cli_nt_error(c);
224 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
225 printf("unexpected error code %s\n", nt_errstr(status));
226 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
227 return False;
231 return True;
235 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
237 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
238 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
240 return True;
244 static BOOL rw_torture(struct cli_state *c)
246 const char *lockfname = "\\torture.lck";
247 fstring fname;
248 int fnum;
249 int fnum2;
250 pid_t pid2, pid = getpid();
251 int i, j;
252 char buf[1024];
253 BOOL correct = True;
255 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
256 DENY_NONE);
257 if (fnum2 == -1)
258 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
259 if (fnum2 == -1) {
260 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
261 return False;
265 for (i=0;i<torture_numops;i++) {
266 unsigned n = (unsigned)sys_random()%10;
267 if (i % 10 == 0) {
268 printf("%d\r", i); fflush(stdout);
270 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
272 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
273 return False;
276 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
277 if (fnum == -1) {
278 printf("open failed (%s)\n", cli_errstr(c));
279 correct = False;
280 break;
283 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
284 printf("write failed (%s)\n", cli_errstr(c));
285 correct = False;
288 for (j=0;j<50;j++) {
289 if (cli_write(c, fnum, 0, (char *)buf,
290 sizeof(pid)+(j*sizeof(buf)),
291 sizeof(buf)) != sizeof(buf)) {
292 printf("write failed (%s)\n", cli_errstr(c));
293 correct = False;
297 pid2 = 0;
299 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
300 printf("read failed (%s)\n", cli_errstr(c));
301 correct = False;
304 if (pid2 != pid) {
305 printf("data corruption!\n");
306 correct = False;
309 if (!cli_close(c, fnum)) {
310 printf("close failed (%s)\n", cli_errstr(c));
311 correct = False;
314 if (!cli_unlink(c, fname)) {
315 printf("unlink failed (%s)\n", cli_errstr(c));
316 correct = False;
319 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
320 printf("unlock failed (%s)\n", cli_errstr(c));
321 correct = False;
325 cli_close(c, fnum2);
326 cli_unlink(c, lockfname);
328 printf("%d\n", i);
330 return correct;
333 static BOOL run_torture(int dummy)
335 struct cli_state cli;
336 BOOL ret;
338 cli = current_cli;
340 cli_sockopt(&cli, sockops);
342 ret = rw_torture(&cli);
344 if (!torture_close_connection(&cli)) {
345 ret = False;
348 return ret;
351 static BOOL rw_torture3(struct cli_state *c, char *lockfname)
353 int fnum = -1;
354 int i = 0;
355 char buf[131072];
356 char buf_rd[131072];
357 unsigned count;
358 unsigned countprev = 0;
359 ssize_t sent = 0;
360 BOOL correct = True;
362 srandom(1);
363 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
365 SIVAL(buf, i, sys_random());
368 if (procnum == 0)
370 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
371 DENY_NONE);
372 if (fnum == -1) {
373 printf("first open read/write of %s failed (%s)\n",
374 lockfname, cli_errstr(c));
375 return False;
378 else
380 for (i = 0; i < 500 && fnum == -1; i++)
382 fnum = cli_open(c, lockfname, O_RDONLY,
383 DENY_NONE);
384 msleep(10);
386 if (fnum == -1) {
387 printf("second open read-only of %s failed (%s)\n",
388 lockfname, cli_errstr(c));
389 return False;
393 i = 0;
394 for (count = 0; count < sizeof(buf); count += sent)
396 if (count >= countprev) {
397 printf("%d %8d\r", i, count);
398 fflush(stdout);
399 i++;
400 countprev += (sizeof(buf) / 20);
403 if (procnum == 0)
405 sent = ((unsigned)sys_random()%(20))+ 1;
406 if (sent > sizeof(buf) - count)
408 sent = sizeof(buf) - count;
411 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
412 printf("write failed (%s)\n", cli_errstr(c));
413 correct = False;
416 else
418 sent = cli_read(c, fnum, buf_rd+count, count,
419 sizeof(buf)-count);
420 if (sent < 0)
422 printf("read failed offset:%d size:%d (%s)\n",
423 count, sizeof(buf)-count,
424 cli_errstr(c));
425 correct = False;
426 sent = 0;
428 if (sent > 0)
430 if (memcmp(buf_rd+count, buf+count, sent) != 0)
432 printf("read/write compare failed\n");
433 printf("offset: %d req %d recvd %d\n",
434 count, sizeof(buf)-count, sent);
435 correct = False;
436 break;
443 if (!cli_close(c, fnum)) {
444 printf("close failed (%s)\n", cli_errstr(c));
445 correct = False;
448 return correct;
451 static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
453 const char *lockfname = "\\torture2.lck";
454 int fnum1;
455 int fnum2;
456 int i;
457 uchar buf[131072];
458 uchar buf_rd[131072];
459 BOOL correct = True;
460 ssize_t bytes_read;
462 if (!cli_unlink(c1, lockfname)) {
463 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
466 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
467 DENY_NONE);
468 if (fnum1 == -1) {
469 printf("first open read/write of %s failed (%s)\n",
470 lockfname, cli_errstr(c1));
471 return False;
473 fnum2 = cli_open(c2, lockfname, O_RDONLY,
474 DENY_NONE);
475 if (fnum2 == -1) {
476 printf("second open read-only of %s failed (%s)\n",
477 lockfname, cli_errstr(c2));
478 cli_close(c1, fnum1);
479 return False;
482 for (i=0;i<torture_numops;i++)
484 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
485 if (i % 10 == 0) {
486 printf("%d\r", i); fflush(stdout);
489 generate_random_buffer(buf, buf_size, False);
491 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
492 printf("write failed (%s)\n", cli_errstr(c1));
493 correct = False;
496 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
497 printf("read failed (%s)\n", cli_errstr(c2));
498 printf("read %d, expected %d\n", bytes_read, buf_size);
499 correct = False;
502 if (memcmp(buf_rd, buf, buf_size) != 0)
504 printf("read/write compare failed\n");
505 correct = False;
509 if (!cli_close(c2, fnum2)) {
510 printf("close failed (%s)\n", cli_errstr(c2));
511 correct = False;
513 if (!cli_close(c1, fnum1)) {
514 printf("close failed (%s)\n", cli_errstr(c1));
515 correct = False;
518 if (!cli_unlink(c1, lockfname)) {
519 printf("unlink failed (%s)\n", cli_errstr(c1));
520 correct = False;
523 return correct;
526 static BOOL run_readwritetest(int dummy)
528 static struct cli_state cli1, cli2;
529 BOOL test1, test2;
531 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
532 return False;
534 cli_sockopt(&cli1, sockops);
535 cli_sockopt(&cli2, sockops);
537 printf("starting readwritetest\n");
539 test1 = rw_torture2(&cli1, &cli2);
540 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
542 test2 = rw_torture2(&cli1, &cli1);
543 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
545 if (!torture_close_connection(&cli1)) {
546 test1 = False;
549 if (!torture_close_connection(&cli2)) {
550 test2 = False;
553 return (test1 && test2);
556 static BOOL run_readwritemulti(int dummy)
558 static struct cli_state cli;
559 BOOL test;
561 cli = current_cli;
563 cli_sockopt(&cli, sockops);
565 printf("run_readwritemulti: fname %s\n", randomfname);
566 test = rw_torture3(&cli, randomfname);
568 if (!torture_close_connection(&cli)) {
569 test = False;
572 return test;
575 static BOOL run_readwritelarge(int dummy)
577 static struct cli_state cli1;
578 int fnum1;
579 const char *lockfname = "\\large.dat";
580 size_t fsize;
581 char buf[126*1024];
582 BOOL correct = True;
584 if (!torture_open_connection(&cli1)) {
585 return False;
587 cli_sockopt(&cli1, sockops);
588 memset(buf,'\0',sizeof(buf));
590 cli1.max_xmit = 128*1024;
592 printf("starting readwritelarge\n");
594 cli_unlink(&cli1, lockfname);
596 fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
597 if (fnum1 == -1) {
598 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
599 return False;
602 cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf));
604 if (!cli_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
605 printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
606 correct = False;
609 if (fsize == sizeof(buf))
610 printf("readwritelarge test 1 succeeded (size = %x)\n", fsize);
611 else {
612 printf("readwritelarge test 1 failed (size = %x)\n", fsize);
613 correct = False;
616 if (!cli_close(&cli1, fnum1)) {
617 printf("close failed (%s)\n", cli_errstr(&cli1));
618 correct = False;
621 if (!cli_unlink(&cli1, lockfname)) {
622 printf("unlink failed (%s)\n", cli_errstr(&cli1));
623 correct = False;
626 fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
627 if (fnum1 == -1) {
628 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
629 return False;
632 cli1.max_xmit = 4*1024;
634 cli_smbwrite(&cli1, fnum1, buf, 0, sizeof(buf));
636 if (!cli_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
637 printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
638 correct = False;
641 if (fsize == sizeof(buf))
642 printf("readwritelarge test 2 succeeded (size = %x)\n", fsize);
643 else {
644 printf("readwritelarge test 2 failed (size = %x)\n", fsize);
645 correct = False;
648 #if 0
649 /* ToDo - set allocation. JRA */
650 if(!cli_set_allocation_size(&cli1, fnum1, 0)) {
651 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
652 return False;
654 if (!cli_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
655 printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
656 correct = False;
658 if (fsize != 0)
659 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
660 #endif
662 if (!cli_close(&cli1, fnum1)) {
663 printf("close failed (%s)\n", cli_errstr(&cli1));
664 correct = False;
667 if (!torture_close_connection(&cli1)) {
668 correct = False;
670 return correct;
673 int line_count = 0;
674 int nbio_id;
676 #define ival(s) strtol(s, NULL, 0)
678 /* run a test that simulates an approximate netbench client load */
679 static BOOL run_netbench(int client)
681 struct cli_state cli;
682 int i;
683 fstring fname;
684 pstring line;
685 char cname[20];
686 FILE *f;
687 char *params[20];
688 BOOL correct = True;
690 cli = current_cli;
692 nbio_id = client;
694 cli_sockopt(&cli, sockops);
696 nb_setup(&cli);
698 slprintf(cname,sizeof(fname), "client%d", client);
700 f = fopen(client_txt, "r");
702 if (!f) {
703 perror(client_txt);
704 return False;
707 while (fgets(line, sizeof(line)-1, f)) {
708 line_count++;
710 line[strlen(line)-1] = 0;
712 /* printf("[%d] %s\n", line_count, line); */
714 all_string_sub(line,"client1", cname, sizeof(line));
716 /* parse the command parameters */
717 params[0] = strtok(line," ");
718 i = 0;
719 while (params[i]) params[++i] = strtok(NULL," ");
721 params[i] = "";
723 if (i < 2) continue;
725 if (!strncmp(params[0],"SMB", 3)) {
726 printf("ERROR: You are using a dbench 1 load file\n");
727 exit(1);
730 if (!strcmp(params[0],"NTCreateX")) {
731 nb_createx(params[1], ival(params[2]), ival(params[3]),
732 ival(params[4]));
733 } else if (!strcmp(params[0],"Close")) {
734 nb_close(ival(params[1]));
735 } else if (!strcmp(params[0],"Rename")) {
736 nb_rename(params[1], params[2]);
737 } else if (!strcmp(params[0],"Unlink")) {
738 nb_unlink(params[1]);
739 } else if (!strcmp(params[0],"Deltree")) {
740 nb_deltree(params[1]);
741 } else if (!strcmp(params[0],"Rmdir")) {
742 nb_rmdir(params[1]);
743 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
744 nb_qpathinfo(params[1]);
745 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
746 nb_qfileinfo(ival(params[1]));
747 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
748 nb_qfsinfo(ival(params[1]));
749 } else if (!strcmp(params[0],"FIND_FIRST")) {
750 nb_findfirst(params[1]);
751 } else if (!strcmp(params[0],"WriteX")) {
752 nb_writex(ival(params[1]),
753 ival(params[2]), ival(params[3]), ival(params[4]));
754 } else if (!strcmp(params[0],"ReadX")) {
755 nb_readx(ival(params[1]),
756 ival(params[2]), ival(params[3]), ival(params[4]));
757 } else if (!strcmp(params[0],"Flush")) {
758 nb_flush(ival(params[1]));
759 } else {
760 printf("Unknown operation %s\n", params[0]);
761 exit(1);
764 fclose(f);
766 nb_cleanup();
768 if (!torture_close_connection(&cli)) {
769 correct = False;
772 return correct;
776 /* run a test that simulates an approximate netbench client load */
777 static BOOL run_nbench(int dummy)
779 double t;
780 BOOL correct = True;
782 nbio_shmem(nprocs);
784 nbio_id = -1;
786 signal(SIGALRM, nb_alarm);
787 alarm(1);
788 t = create_procs(run_netbench, &correct);
789 alarm(0);
791 printf("\nThroughput %g MB/sec\n",
792 1.0e-6 * nbio_total() / t);
793 return correct;
798 This test checks for two things:
800 1) correct support for retaining locks over a close (ie. the server
801 must not use posix semantics)
802 2) support for lock timeouts
804 static BOOL run_locktest1(int dummy)
806 static struct cli_state cli1, cli2;
807 const char *fname = "\\lockt1.lck";
808 int fnum1, fnum2, fnum3;
809 time_t t1, t2;
810 unsigned lock_timeout;
812 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
813 return False;
815 cli_sockopt(&cli1, sockops);
816 cli_sockopt(&cli2, sockops);
818 printf("starting locktest1\n");
820 cli_unlink(&cli1, fname);
822 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
823 if (fnum1 == -1) {
824 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
825 return False;
827 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
828 if (fnum2 == -1) {
829 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
830 return False;
832 fnum3 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
833 if (fnum3 == -1) {
834 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2));
835 return False;
838 if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
839 printf("lock1 failed (%s)\n", cli_errstr(&cli1));
840 return False;
844 if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
845 printf("lock2 succeeded! This is a locking bug\n");
846 return False;
847 } else {
848 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock,
849 NT_STATUS_LOCK_NOT_GRANTED)) return False;
853 lock_timeout = (1 + (random() % 20));
854 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
855 t1 = time(NULL);
856 if (cli_lock(&cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
857 printf("lock3 succeeded! This is a locking bug\n");
858 return False;
859 } else {
860 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock,
861 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
863 t2 = time(NULL);
865 if (t2 - t1 < 5) {
866 printf("error: This server appears not to support timed lock requests\n");
868 printf("server slept for %u seconds for a %u second timeout\n",
869 (unsigned int)(t2-t1), lock_timeout);
871 if (!cli_close(&cli1, fnum2)) {
872 printf("close1 failed (%s)\n", cli_errstr(&cli1));
873 return False;
876 if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
877 printf("lock4 succeeded! This is a locking bug\n");
878 return False;
879 } else {
880 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock,
881 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
884 if (!cli_close(&cli1, fnum1)) {
885 printf("close2 failed (%s)\n", cli_errstr(&cli1));
886 return False;
889 if (!cli_close(&cli2, fnum3)) {
890 printf("close3 failed (%s)\n", cli_errstr(&cli2));
891 return False;
894 if (!cli_unlink(&cli1, fname)) {
895 printf("unlink failed (%s)\n", cli_errstr(&cli1));
896 return False;
900 if (!torture_close_connection(&cli1)) {
901 return False;
904 if (!torture_close_connection(&cli2)) {
905 return False;
908 printf("Passed locktest1\n");
909 return True;
913 checks for correct tconX support
915 static BOOL run_tcon_test(int dummy)
917 static struct cli_state cli1;
918 const char *fname = "\\tcontest.tmp";
919 int fnum1;
920 uint16 cnum;
921 char buf[4];
923 if (!torture_open_connection(&cli1)) {
924 return False;
926 cli_sockopt(&cli1, sockops);
928 printf("starting tcontest\n");
930 cli_unlink(&cli1, fname);
932 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
933 if (fnum1 == -1)
935 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
936 return False;
939 cnum = cli1.cnum;
941 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4)
943 printf("write failed (%s)", cli_errstr(&cli1));
944 return False;
947 if (!cli_send_tconX(&cli1, share, "?????",
948 password, strlen(password)+1)) {
949 printf("%s refused 2nd tree connect (%s)\n", host,
950 cli_errstr(&cli1));
951 cli_shutdown(&cli1);
952 return False;
955 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) == 4)
957 printf("write succeeded (%s)", cli_errstr(&cli1));
958 return False;
961 if (cli_close(&cli1, fnum1)) {
962 printf("close2 succeeded (%s)\n", cli_errstr(&cli1));
963 return False;
966 if (!cli_tdis(&cli1)) {
967 printf("tdis failed (%s)\n", cli_errstr(&cli1));
968 return False;
971 cli1.cnum = cnum;
973 if (!cli_close(&cli1, fnum1)) {
974 printf("close2 failed (%s)\n", cli_errstr(&cli1));
975 return False;
978 if (!torture_close_connection(&cli1)) {
979 return False;
982 printf("Passed tcontest\n");
983 return True;
988 This test checks that
990 1) the server supports multiple locking contexts on the one SMB
991 connection, distinguished by PID.
993 2) the server correctly fails overlapping locks made by the same PID (this
994 goes against POSIX behaviour, which is why it is tricky to implement)
996 3) the server denies unlock requests by an incorrect client PID
998 static BOOL run_locktest2(int dummy)
1000 static struct cli_state cli;
1001 const char *fname = "\\lockt2.lck";
1002 int fnum1, fnum2, fnum3;
1003 BOOL correct = True;
1005 if (!torture_open_connection(&cli)) {
1006 return False;
1009 cli_sockopt(&cli, sockops);
1011 printf("starting locktest2\n");
1013 cli_unlink(&cli, fname);
1015 cli_setpid(&cli, 1);
1017 fnum1 = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1018 if (fnum1 == -1) {
1019 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1020 return False;
1023 fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
1024 if (fnum2 == -1) {
1025 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli));
1026 return False;
1029 cli_setpid(&cli, 2);
1031 fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
1032 if (fnum3 == -1) {
1033 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli));
1034 return False;
1037 cli_setpid(&cli, 1);
1039 if (!cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1040 printf("lock1 failed (%s)\n", cli_errstr(&cli));
1041 return False;
1044 if (cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1045 printf("WRITE lock1 succeeded! This is a locking bug\n");
1046 correct = False;
1047 } else {
1048 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock,
1049 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1052 if (cli_lock(&cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1053 printf("WRITE lock2 succeeded! This is a locking bug\n");
1054 correct = False;
1055 } else {
1056 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock,
1057 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1060 if (cli_lock(&cli, fnum2, 0, 4, 0, READ_LOCK)) {
1061 printf("READ lock2 succeeded! This is a locking bug\n");
1062 correct = False;
1063 } else {
1064 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock,
1065 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1068 if (!cli_lock(&cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1069 printf("lock at 100 failed (%s)\n", cli_errstr(&cli));
1071 cli_setpid(&cli, 2);
1072 if (cli_unlock(&cli, fnum1, 100, 4)) {
1073 printf("unlock at 100 succeeded! This is a locking bug\n");
1074 correct = False;
1077 if (cli_unlock(&cli, fnum1, 0, 4)) {
1078 printf("unlock1 succeeded! This is a locking bug\n");
1079 correct = False;
1080 } else {
1081 if (!check_error(__LINE__, &cli,
1082 ERRDOS, ERRlock,
1083 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1086 if (cli_unlock(&cli, fnum1, 0, 8)) {
1087 printf("unlock2 succeeded! This is a locking bug\n");
1088 correct = False;
1089 } else {
1090 if (!check_error(__LINE__, &cli,
1091 ERRDOS, ERRlock,
1092 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1095 if (cli_lock(&cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1096 printf("lock3 succeeded! This is a locking bug\n");
1097 correct = False;
1098 } else {
1099 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1102 cli_setpid(&cli, 1);
1104 if (!cli_close(&cli, fnum1)) {
1105 printf("close1 failed (%s)\n", cli_errstr(&cli));
1106 return False;
1109 if (!cli_close(&cli, fnum2)) {
1110 printf("close2 failed (%s)\n", cli_errstr(&cli));
1111 return False;
1114 if (!cli_close(&cli, fnum3)) {
1115 printf("close3 failed (%s)\n", cli_errstr(&cli));
1116 return False;
1119 if (!torture_close_connection(&cli)) {
1120 correct = False;
1123 printf("locktest2 finished\n");
1125 return correct;
1130 This test checks that
1132 1) the server supports the full offset range in lock requests
1134 static BOOL run_locktest3(int dummy)
1136 static struct cli_state cli1, cli2;
1137 const char *fname = "\\lockt3.lck";
1138 int fnum1, fnum2, i;
1139 uint32 offset;
1140 BOOL correct = True;
1142 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1144 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1145 return False;
1147 cli_sockopt(&cli1, sockops);
1148 cli_sockopt(&cli2, sockops);
1150 printf("starting locktest3\n");
1152 cli_unlink(&cli1, fname);
1154 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1155 if (fnum1 == -1) {
1156 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1157 return False;
1159 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1160 if (fnum2 == -1) {
1161 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
1162 return False;
1165 for (offset=i=0;i<torture_numops;i++) {
1166 NEXT_OFFSET;
1167 if (!cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1168 printf("lock1 %d failed (%s)\n",
1170 cli_errstr(&cli1));
1171 return False;
1174 if (!cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1175 printf("lock2 %d failed (%s)\n",
1177 cli_errstr(&cli1));
1178 return False;
1182 for (offset=i=0;i<torture_numops;i++) {
1183 NEXT_OFFSET;
1185 if (cli_lock(&cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1186 printf("error: lock1 %d succeeded!\n", i);
1187 return False;
1190 if (cli_lock(&cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1191 printf("error: lock2 %d succeeded!\n", i);
1192 return False;
1195 if (cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1196 printf("error: lock3 %d succeeded!\n", i);
1197 return False;
1200 if (cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1201 printf("error: lock4 %d succeeded!\n", i);
1202 return False;
1206 for (offset=i=0;i<torture_numops;i++) {
1207 NEXT_OFFSET;
1209 if (!cli_unlock(&cli1, fnum1, offset-1, 1)) {
1210 printf("unlock1 %d failed (%s)\n",
1212 cli_errstr(&cli1));
1213 return False;
1216 if (!cli_unlock(&cli2, fnum2, offset-2, 1)) {
1217 printf("unlock2 %d failed (%s)\n",
1219 cli_errstr(&cli1));
1220 return False;
1224 if (!cli_close(&cli1, fnum1)) {
1225 printf("close1 failed (%s)\n", cli_errstr(&cli1));
1226 return False;
1229 if (!cli_close(&cli2, fnum2)) {
1230 printf("close2 failed (%s)\n", cli_errstr(&cli2));
1231 return False;
1234 if (!cli_unlink(&cli1, fname)) {
1235 printf("unlink failed (%s)\n", cli_errstr(&cli1));
1236 return False;
1239 if (!torture_close_connection(&cli1)) {
1240 correct = False;
1243 if (!torture_close_connection(&cli2)) {
1244 correct = False;
1247 printf("finished locktest3\n");
1249 return correct;
1252 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1253 printf("** "); correct = False; \
1257 looks at overlapping locks
1259 static BOOL run_locktest4(int dummy)
1261 static struct cli_state cli1, cli2;
1262 const char *fname = "\\lockt4.lck";
1263 int fnum1, fnum2, f;
1264 BOOL ret;
1265 char buf[1000];
1266 BOOL correct = True;
1268 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1269 return False;
1272 cli_sockopt(&cli1, sockops);
1273 cli_sockopt(&cli2, sockops);
1275 printf("starting locktest4\n");
1277 cli_unlink(&cli1, fname);
1279 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1280 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1282 memset(buf, 0, sizeof(buf));
1284 if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1285 printf("Failed to create file\n");
1286 correct = False;
1287 goto fail;
1290 ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1291 cli_lock(&cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1292 EXPECTED(ret, False);
1293 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1295 ret = cli_lock(&cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1296 cli_lock(&cli1, fnum1, 12, 4, 0, READ_LOCK);
1297 EXPECTED(ret, True);
1298 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1300 ret = cli_lock(&cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1301 cli_lock(&cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1302 EXPECTED(ret, False);
1303 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1305 ret = cli_lock(&cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1306 cli_lock(&cli2, fnum2, 32, 4, 0, READ_LOCK);
1307 EXPECTED(ret, True);
1308 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1310 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1311 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1312 EXPECTED(ret, False);
1313 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1315 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1316 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 52, 4, 0, READ_LOCK));
1317 EXPECTED(ret, True);
1318 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1320 ret = cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1321 cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK);
1322 EXPECTED(ret, True);
1323 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1325 ret = cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1326 cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1327 EXPECTED(ret, False);
1328 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1330 ret = cli_lock(&cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1331 cli_lock(&cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1332 EXPECTED(ret, False);
1333 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1335 ret = cli_lock(&cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1336 cli_lock(&cli1, fnum1, 90, 4, 0, READ_LOCK);
1337 EXPECTED(ret, True);
1338 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1340 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1341 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 100, 4, 0, READ_LOCK));
1342 EXPECTED(ret, False);
1343 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1345 ret = cli_lock(&cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1346 cli_lock(&cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1347 cli_unlock(&cli1, fnum1, 110, 6);
1348 EXPECTED(ret, False);
1349 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1352 ret = cli_lock(&cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1353 (cli_read(&cli2, fnum2, buf, 120, 4) == 4);
1354 EXPECTED(ret, False);
1355 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1357 ret = cli_lock(&cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1358 (cli_write(&cli2, fnum2, 0, buf, 130, 4) == 4);
1359 EXPECTED(ret, False);
1360 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1363 ret = cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1364 cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1365 cli_unlock(&cli1, fnum1, 140, 4) &&
1366 cli_unlock(&cli1, fnum1, 140, 4);
1367 EXPECTED(ret, True);
1368 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1371 ret = cli_lock(&cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1372 cli_lock(&cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1373 cli_unlock(&cli1, fnum1, 150, 4) &&
1374 (cli_read(&cli2, fnum2, buf, 150, 4) == 4) &&
1375 !(cli_write(&cli2, fnum2, 0, buf, 150, 4) == 4) &&
1376 cli_unlock(&cli1, fnum1, 150, 4);
1377 EXPECTED(ret, True);
1378 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1380 ret = cli_lock(&cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1381 cli_unlock(&cli1, fnum1, 160, 4) &&
1382 (cli_write(&cli2, fnum2, 0, buf, 160, 4) == 4) &&
1383 (cli_read(&cli2, fnum2, buf, 160, 4) == 4);
1384 EXPECTED(ret, True);
1385 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1387 ret = cli_lock(&cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1388 cli_unlock(&cli1, fnum1, 170, 4) &&
1389 (cli_write(&cli2, fnum2, 0, buf, 170, 4) == 4) &&
1390 (cli_read(&cli2, fnum2, buf, 170, 4) == 4);
1391 EXPECTED(ret, True);
1392 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1394 ret = cli_lock(&cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1395 cli_lock(&cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1396 cli_unlock(&cli1, fnum1, 190, 4) &&
1397 !(cli_write(&cli2, fnum2, 0, buf, 190, 4) == 4) &&
1398 (cli_read(&cli2, fnum2, buf, 190, 4) == 4);
1399 EXPECTED(ret, True);
1400 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1402 cli_close(&cli1, fnum1);
1403 cli_close(&cli2, fnum2);
1404 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1405 f = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1406 ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1407 cli_lock(&cli1, f, 0, 1, 0, READ_LOCK) &&
1408 cli_close(&cli1, fnum1) &&
1409 ((fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1410 cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1411 cli_close(&cli1, f);
1412 cli_close(&cli1, fnum1);
1413 EXPECTED(ret, True);
1414 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1416 fail:
1417 cli_close(&cli1, fnum1);
1418 cli_close(&cli2, fnum2);
1419 cli_unlink(&cli1, fname);
1420 torture_close_connection(&cli1);
1421 torture_close_connection(&cli2);
1423 printf("finished locktest4\n");
1424 return correct;
1428 looks at lock upgrade/downgrade.
1430 static BOOL run_locktest5(int dummy)
1432 static struct cli_state cli1, cli2;
1433 const char *fname = "\\lockt5.lck";
1434 int fnum1, fnum2, fnum3;
1435 BOOL ret;
1436 char buf[1000];
1437 BOOL correct = True;
1439 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1440 return False;
1443 cli_sockopt(&cli1, sockops);
1444 cli_sockopt(&cli2, sockops);
1446 printf("starting locktest5\n");
1448 cli_unlink(&cli1, fname);
1450 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1451 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1452 fnum3 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1454 memset(buf, 0, sizeof(buf));
1456 if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1457 printf("Failed to create file\n");
1458 correct = False;
1459 goto fail;
1462 /* Check for NT bug... */
1463 ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1464 cli_lock(&cli1, fnum3, 0, 1, 0, READ_LOCK);
1465 cli_close(&cli1, fnum1);
1466 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1467 ret = cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1468 EXPECTED(ret, True);
1469 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1470 cli_close(&cli1, fnum1);
1471 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1472 cli_unlock(&cli1, fnum3, 0, 1);
1474 ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1475 cli_lock(&cli1, fnum1, 1, 1, 0, READ_LOCK);
1476 EXPECTED(ret, True);
1477 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1479 ret = cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1480 EXPECTED(ret, False);
1482 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1484 /* Unlock the process 2 lock. */
1485 cli_unlock(&cli2, fnum2, 0, 4);
1487 ret = cli_lock(&cli1, fnum3, 0, 4, 0, READ_LOCK);
1488 EXPECTED(ret, False);
1490 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1492 /* Unlock the process 1 fnum3 lock. */
1493 cli_unlock(&cli1, fnum3, 0, 4);
1495 /* Stack 2 more locks here. */
1496 ret = cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1497 cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK);
1499 EXPECTED(ret, True);
1500 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1502 /* Unlock the first process lock, then check this was the WRITE lock that was
1503 removed. */
1505 ret = cli_unlock(&cli1, fnum1, 0, 4) &&
1506 cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1508 EXPECTED(ret, True);
1509 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1511 /* Unlock the process 2 lock. */
1512 cli_unlock(&cli2, fnum2, 0, 4);
1514 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1516 ret = cli_unlock(&cli1, fnum1, 1, 1) &&
1517 cli_unlock(&cli1, fnum1, 0, 4) &&
1518 cli_unlock(&cli1, fnum1, 0, 4);
1520 EXPECTED(ret, True);
1521 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1523 /* Ensure the next unlock fails. */
1524 ret = cli_unlock(&cli1, fnum1, 0, 4);
1525 EXPECTED(ret, False);
1526 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1528 /* Ensure connection 2 can get a write lock. */
1529 ret = cli_lock(&cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1530 EXPECTED(ret, True);
1532 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1535 fail:
1536 cli_close(&cli1, fnum1);
1537 cli_close(&cli2, fnum2);
1538 cli_unlink(&cli1, fname);
1539 if (!torture_close_connection(&cli1)) {
1540 correct = False;
1542 if (!torture_close_connection(&cli2)) {
1543 correct = False;
1546 printf("finished locktest5\n");
1548 return correct;
1552 tries the unusual lockingX locktype bits
1554 static BOOL run_locktest6(int dummy)
1556 static struct cli_state cli;
1557 const char *fname[1] = { "\\lock6.txt" };
1558 int i;
1559 int fnum;
1560 NTSTATUS status;
1562 if (!torture_open_connection(&cli)) {
1563 return False;
1566 cli_sockopt(&cli, sockops);
1568 printf("starting locktest6\n");
1570 for (i=0;i<1;i++) {
1571 printf("Testing %s\n", fname[i]);
1573 cli_unlink(&cli, fname[i]);
1575 fnum = cli_open(&cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1576 status = cli_locktype(&cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1577 cli_close(&cli, fnum);
1578 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1580 fnum = cli_open(&cli, fname[i], O_RDWR, DENY_NONE);
1581 status = cli_locktype(&cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1582 cli_close(&cli, fnum);
1583 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1585 cli_unlink(&cli, fname[i]);
1588 torture_close_connection(&cli);
1590 printf("finished locktest6\n");
1591 return True;
1594 static BOOL run_locktest7(int dummy)
1596 static struct cli_state cli1;
1597 const char *fname = "\\lockt7.lck";
1598 int fnum1;
1599 char buf[200];
1600 BOOL correct = False;
1602 if (!torture_open_connection(&cli1)) {
1603 return False;
1606 cli_sockopt(&cli1, sockops);
1608 printf("starting locktest7\n");
1610 cli_unlink(&cli1, fname);
1612 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1614 memset(buf, 0, sizeof(buf));
1616 if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1617 printf("Failed to create file\n");
1618 goto fail;
1621 cli_setpid(&cli1, 1);
1623 if (!cli_lock(&cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1624 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(&cli1));
1625 goto fail;
1626 } else {
1627 printf("pid1 successfully locked range 130:4 for READ\n");
1630 if (cli_read(&cli1, fnum1, buf, 130, 4) != 4) {
1631 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(&cli1));
1632 goto fail;
1633 } else {
1634 printf("pid1 successfully read the range 130:4\n");
1637 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4) {
1638 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(&cli1));
1639 if (NT_STATUS_V(cli_nt_error(&cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1640 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1641 goto fail;
1643 } else {
1644 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
1645 goto fail;
1648 cli_setpid(&cli1, 2);
1650 if (cli_read(&cli1, fnum1, buf, 130, 4) != 4) {
1651 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(&cli1));
1652 } else {
1653 printf("pid2 successfully read the range 130:4\n");
1656 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4) {
1657 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(&cli1));
1658 if (NT_STATUS_V(cli_nt_error(&cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1659 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1660 goto fail;
1662 } else {
1663 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1664 goto fail;
1667 cli_setpid(&cli1, 1);
1668 cli_unlock(&cli1, fnum1, 130, 4);
1670 if (!cli_lock(&cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
1671 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(&cli1));
1672 goto fail;
1673 } else {
1674 printf("pid1 successfully locked range 130:4 for WRITE\n");
1677 if (cli_read(&cli1, fnum1, buf, 130, 4) != 4) {
1678 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(&cli1));
1679 goto fail;
1680 } else {
1681 printf("pid1 successfully read the range 130:4\n");
1684 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4) {
1685 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(&cli1));
1686 goto fail;
1687 } else {
1688 printf("pid1 successfully wrote to the range 130:4\n");
1691 cli_setpid(&cli1, 2);
1693 if (cli_read(&cli1, fnum1, buf, 130, 4) != 4) {
1694 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(&cli1));
1695 if (NT_STATUS_V(cli_nt_error(&cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1696 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1697 goto fail;
1699 } else {
1700 printf("pid2 successfully read the range 130:4 (should be denied)\n");
1701 goto fail;
1704 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4) {
1705 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(&cli1));
1706 if (NT_STATUS_V(cli_nt_error(&cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1707 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
1708 goto fail;
1710 } else {
1711 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
1712 goto fail;
1715 cli_unlock(&cli1, fnum1, 130, 0);
1716 correct = True;
1718 fail:
1719 cli_close(&cli1, fnum1);
1720 cli_unlink(&cli1, fname);
1721 torture_close_connection(&cli1);
1723 printf("finished locktest7\n");
1724 return correct;
1728 test whether fnums and tids open on one VC are available on another (a major
1729 security hole)
1731 static BOOL run_fdpasstest(int dummy)
1733 static struct cli_state cli1, cli2, cli3;
1734 const char *fname = "\\fdpass.tst";
1735 int fnum1;
1736 pstring buf;
1738 if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
1739 return False;
1741 cli_sockopt(&cli1, sockops);
1742 cli_sockopt(&cli2, sockops);
1744 printf("starting fdpasstest\n");
1746 cli_unlink(&cli1, fname);
1748 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1749 if (fnum1 == -1) {
1750 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1751 return False;
1754 if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
1755 printf("write failed (%s)\n", cli_errstr(&cli1));
1756 return False;
1759 cli3 = cli2;
1760 cli3.vuid = cli1.vuid;
1761 cli3.cnum = cli1.cnum;
1762 cli3.pid = cli1.pid;
1764 if (cli_read(&cli3, fnum1, buf, 0, 13) == 13) {
1765 printf("read succeeded! nasty security hole [%s]\n",
1766 buf);
1767 return False;
1770 cli_close(&cli1, fnum1);
1771 cli_unlink(&cli1, fname);
1773 torture_close_connection(&cli1);
1774 torture_close_connection(&cli2);
1776 printf("finished fdpasstest\n");
1777 return True;
1782 This test checks that
1784 1) the server does not allow an unlink on a file that is open
1786 static BOOL run_unlinktest(int dummy)
1788 static struct cli_state cli;
1789 const char *fname = "\\unlink.tst";
1790 int fnum;
1791 BOOL correct = True;
1793 if (!torture_open_connection(&cli)) {
1794 return False;
1797 cli_sockopt(&cli, sockops);
1799 printf("starting unlink test\n");
1801 cli_unlink(&cli, fname);
1803 cli_setpid(&cli, 1);
1805 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1806 if (fnum == -1) {
1807 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1808 return False;
1811 if (cli_unlink(&cli, fname)) {
1812 printf("error: server allowed unlink on an open file\n");
1813 correct = False;
1814 } else {
1815 correct = check_error(__LINE__, &cli, ERRDOS, ERRbadshare,
1816 NT_STATUS_SHARING_VIOLATION);
1819 cli_close(&cli, fnum);
1820 cli_unlink(&cli, fname);
1822 if (!torture_close_connection(&cli)) {
1823 correct = False;
1826 printf("unlink test finished\n");
1828 return correct;
1833 test how many open files this server supports on the one socket
1835 static BOOL run_maxfidtest(int dummy)
1837 static struct cli_state cli;
1838 const char *template = "\\maxfid.%d.%d";
1839 fstring fname;
1840 int fnums[0x11000], i;
1841 int retries=4;
1842 BOOL correct = True;
1844 cli = current_cli;
1846 if (retries <= 0) {
1847 printf("failed to connect\n");
1848 return False;
1851 cli_sockopt(&cli, sockops);
1853 for (i=0; i<0x11000; i++) {
1854 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1855 if ((fnums[i] = cli_open(&cli, fname,
1856 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1857 -1) {
1858 printf("open of %s failed (%s)\n",
1859 fname, cli_errstr(&cli));
1860 printf("maximum fnum is %d\n", i);
1861 break;
1863 printf("%6d\r", i);
1865 printf("%6d\n", i);
1866 i--;
1868 printf("cleaning up\n");
1869 for (;i>=0;i--) {
1870 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1871 cli_close(&cli, fnums[i]);
1872 if (!cli_unlink(&cli, fname)) {
1873 printf("unlink of %s failed (%s)\n",
1874 fname, cli_errstr(&cli));
1875 correct = False;
1877 printf("%6d\r", i);
1879 printf("%6d\n", 0);
1881 printf("maxfid test finished\n");
1882 if (!torture_close_connection(&cli)) {
1883 correct = False;
1885 return correct;
1888 /* generate a random buffer */
1889 static void rand_buf(char *buf, int len)
1891 while (len--) {
1892 *buf = (char)sys_random();
1893 buf++;
1897 /* send smb negprot commands, not reading the response */
1898 static BOOL run_negprot_nowait(int dummy)
1900 int i;
1901 static struct cli_state cli;
1902 BOOL correct = True;
1904 printf("starting negprot nowait test\n");
1906 if (!open_nbt_connection(&cli)) {
1907 return False;
1910 for (i=0;i<50000;i++) {
1911 cli_negprot_send(&cli);
1914 if (!torture_close_connection(&cli)) {
1915 correct = False;
1918 printf("finished negprot nowait test\n");
1920 return correct;
1924 /* send random IPC commands */
1925 static BOOL run_randomipc(int dummy)
1927 char *rparam = NULL;
1928 char *rdata = NULL;
1929 int rdrcnt,rprcnt;
1930 pstring param;
1931 int api, param_len, i;
1932 static struct cli_state cli;
1933 BOOL correct = True;
1934 int count = 50000;
1936 printf("starting random ipc test\n");
1938 if (!torture_open_connection(&cli)) {
1939 return False;
1942 for (i=0;i<count;i++) {
1943 api = sys_random() % 500;
1944 param_len = (sys_random() % 64);
1946 rand_buf(param, param_len);
1948 SSVAL(param,0,api);
1950 cli_api(&cli,
1951 param, param_len, 8,
1952 NULL, 0, BUFFER_SIZE,
1953 &rparam, &rprcnt,
1954 &rdata, &rdrcnt);
1955 if (i % 100 == 0) {
1956 printf("%d/%d\r", i,count);
1959 printf("%d/%d\n", i, count);
1961 if (!torture_close_connection(&cli)) {
1962 correct = False;
1965 printf("finished random ipc test\n");
1967 return correct;
1972 static void browse_callback(const char *sname, uint32 stype,
1973 const char *comment, void *state)
1975 printf("\t%20.20s %08x %s\n", sname, stype, comment);
1981 This test checks the browse list code
1984 static BOOL run_browsetest(int dummy)
1986 static struct cli_state cli;
1987 BOOL correct = True;
1989 printf("starting browse test\n");
1991 if (!torture_open_connection(&cli)) {
1992 return False;
1995 printf("domain list:\n");
1996 cli_NetServerEnum(&cli, cli.server_domain,
1997 SV_TYPE_DOMAIN_ENUM,
1998 browse_callback, NULL);
2000 printf("machine list:\n");
2001 cli_NetServerEnum(&cli, cli.server_domain,
2002 SV_TYPE_ALL,
2003 browse_callback, NULL);
2005 if (!torture_close_connection(&cli)) {
2006 correct = False;
2009 printf("browse test finished\n");
2011 return correct;
2017 This checks how the getatr calls works
2019 static BOOL run_attrtest(int dummy)
2021 static struct cli_state cli;
2022 int fnum;
2023 time_t t, t2;
2024 const char *fname = "\\attrib.tst";
2025 BOOL correct = True;
2027 printf("starting attrib test\n");
2029 if (!torture_open_connection(&cli)) {
2030 return False;
2033 cli_unlink(&cli, fname);
2034 fnum = cli_open(&cli, fname,
2035 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2036 cli_close(&cli, fnum);
2037 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
2038 printf("getatr failed (%s)\n", cli_errstr(&cli));
2039 correct = False;
2042 if (abs(t - time(NULL)) > 60*60*24*10) {
2043 printf("ERROR: SMBgetatr bug. time is %s",
2044 ctime(&t));
2045 t = time(NULL);
2046 correct = True;
2049 t2 = t-60*60*24; /* 1 day ago */
2051 if (!cli_setatr(&cli, fname, 0, t2)) {
2052 printf("setatr failed (%s)\n", cli_errstr(&cli));
2053 correct = True;
2056 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
2057 printf("getatr failed (%s)\n", cli_errstr(&cli));
2058 correct = True;
2061 if (t != t2) {
2062 printf("ERROR: getatr/setatr bug. times are\n%s",
2063 ctime(&t));
2064 printf("%s", ctime(&t2));
2065 correct = True;
2068 cli_unlink(&cli, fname);
2070 if (!torture_close_connection(&cli)) {
2071 correct = False;
2074 printf("attrib test finished\n");
2076 return correct;
2081 This checks a couple of trans2 calls
2083 static BOOL run_trans2test(int dummy)
2085 static struct cli_state cli;
2086 int fnum;
2087 size_t size;
2088 time_t c_time, a_time, m_time, w_time, m_time2;
2089 const char *fname = "\\trans2.tst";
2090 const char *dname = "\\trans2";
2091 const char *fname2 = "\\trans2\\trans2.tst";
2092 pstring pname;
2093 BOOL correct = True;
2095 printf("starting trans2 test\n");
2097 if (!torture_open_connection(&cli)) {
2098 return False;
2101 cli_unlink(&cli, fname);
2102 fnum = cli_open(&cli, fname,
2103 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2104 if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
2105 NULL, NULL)) {
2106 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
2107 correct = False;
2110 if (!cli_qfilename(&cli, fnum, pname)) {
2111 printf("ERROR: qfilename failed (%s)\n", cli_errstr(&cli));
2112 correct = False;
2115 if (strcmp(pname, fname)) {
2116 printf("qfilename gave different name? [%s] [%s]\n",
2117 fname, pname);
2118 correct = False;
2121 cli_close(&cli, fnum);
2123 sleep(2);
2125 cli_unlink(&cli, fname);
2126 fnum = cli_open(&cli, fname,
2127 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2128 if (fnum == -1) {
2129 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
2130 return False;
2132 cli_close(&cli, fnum);
2134 if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2135 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
2136 correct = False;
2137 } else {
2138 if (c_time != m_time) {
2139 printf("create time=%s", ctime(&c_time));
2140 printf("modify time=%s", ctime(&m_time));
2141 printf("This system appears to have sticky create times\n");
2142 correct = False;
2144 if (a_time % (60*60) == 0) {
2145 printf("access time=%s", ctime(&a_time));
2146 printf("This system appears to set a midnight access time\n");
2147 correct = False;
2150 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2151 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2152 correct = False;
2157 cli_unlink(&cli, fname);
2158 fnum = cli_open(&cli, fname,
2159 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2160 cli_close(&cli, fnum);
2161 if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time,
2162 &w_time, &size, NULL, NULL)) {
2163 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2164 correct = False;
2165 } else {
2166 if (w_time < 60*60*24*2) {
2167 printf("write time=%s", ctime(&w_time));
2168 printf("This system appears to set a initial 0 write time\n");
2169 correct = False;
2173 cli_unlink(&cli, fname);
2176 /* check if the server updates the directory modification time
2177 when creating a new file */
2178 if (!cli_mkdir(&cli, dname)) {
2179 printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
2180 correct = False;
2182 sleep(3);
2183 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time,
2184 &w_time, &size, NULL, NULL)) {
2185 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2186 correct = False;
2189 fnum = cli_open(&cli, fname2,
2190 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2191 cli_write(&cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2192 cli_close(&cli, fnum);
2193 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2,
2194 &w_time, &size, NULL, NULL)) {
2195 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2196 correct = False;
2197 } else {
2198 if (m_time2 == m_time) {
2199 printf("This system does not update directory modification times\n");
2200 correct = False;
2203 cli_unlink(&cli, fname2);
2204 cli_rmdir(&cli, dname);
2206 if (!torture_close_connection(&cli)) {
2207 correct = False;
2210 printf("trans2 test finished\n");
2212 return correct;
2216 This checks new W2K calls.
2219 static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
2221 char buf[4096];
2222 BOOL correct = True;
2224 memset(buf, 0xff, sizeof(buf));
2226 if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
2227 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2228 correct = False;
2229 } else {
2230 printf("qfileinfo: level %d\n", level);
2231 dump_data(0, buf, 256);
2232 printf("\n");
2234 return correct;
2237 static BOOL run_w2ktest(int dummy)
2239 static struct cli_state cli;
2240 int fnum;
2241 const char *fname = "\\w2ktest\\w2k.tst";
2242 int level;
2243 BOOL correct = True;
2245 printf("starting w2k test\n");
2247 if (!torture_open_connection(&cli)) {
2248 return False;
2251 fnum = cli_open(&cli, fname,
2252 O_RDWR | O_CREAT , DENY_NONE);
2254 for (level = 1004; level < 1040; level++) {
2255 new_trans(&cli, fnum, level);
2258 cli_close(&cli, fnum);
2260 if (!torture_close_connection(&cli)) {
2261 correct = False;
2264 printf("w2k test finished\n");
2266 return correct;
2271 this is a harness for some oplock tests
2273 static BOOL run_oplock1(int dummy)
2275 static struct cli_state cli1;
2276 const char *fname = "\\lockt1.lck";
2277 int fnum1;
2278 BOOL correct = True;
2280 printf("starting oplock test 1\n");
2282 if (!torture_open_connection(&cli1)) {
2283 return False;
2286 cli_unlink(&cli1, fname);
2288 cli_sockopt(&cli1, sockops);
2290 cli1.use_oplocks = True;
2292 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2293 if (fnum1 == -1) {
2294 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2295 return False;
2298 cli1.use_oplocks = False;
2300 cli_unlink(&cli1, fname);
2301 cli_unlink(&cli1, fname);
2303 if (!cli_close(&cli1, fnum1)) {
2304 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2305 return False;
2308 if (!cli_unlink(&cli1, fname)) {
2309 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2310 return False;
2313 if (!torture_close_connection(&cli1)) {
2314 correct = False;
2317 printf("finished oplock test 1\n");
2319 return correct;
2322 static BOOL run_oplock2(int dummy)
2324 static struct cli_state cli1, cli2;
2325 const char *fname = "\\lockt2.lck";
2326 int fnum1, fnum2;
2327 int saved_use_oplocks = use_oplocks;
2328 char buf[4];
2329 BOOL correct = True;
2330 volatile BOOL *shared_correct;
2332 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2333 *shared_correct = True;
2335 use_level_II_oplocks = True;
2336 use_oplocks = True;
2338 printf("starting oplock test 2\n");
2340 if (!torture_open_connection(&cli1)) {
2341 use_level_II_oplocks = False;
2342 use_oplocks = saved_use_oplocks;
2343 return False;
2346 cli1.use_oplocks = True;
2347 cli1.use_level_II_oplocks = True;
2349 if (!torture_open_connection(&cli2)) {
2350 use_level_II_oplocks = False;
2351 use_oplocks = saved_use_oplocks;
2352 return False;
2355 cli2.use_oplocks = True;
2356 cli2.use_level_II_oplocks = True;
2358 cli_unlink(&cli1, fname);
2360 cli_sockopt(&cli1, sockops);
2361 cli_sockopt(&cli2, sockops);
2363 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2364 if (fnum1 == -1) {
2365 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2366 return False;
2369 /* Don't need the globals any more. */
2370 use_level_II_oplocks = False;
2371 use_oplocks = saved_use_oplocks;
2373 if (fork() == 0) {
2374 /* Child code */
2375 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
2376 if (fnum2 == -1) {
2377 printf("second open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2378 *shared_correct = False;
2379 exit(0);
2382 sleep(2);
2384 if (!cli_close(&cli2, fnum2)) {
2385 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2386 *shared_correct = False;
2389 exit(0);
2392 sleep(2);
2394 /* Ensure cli1 processes the break. */
2396 if (cli_read(&cli1, fnum1, buf, 0, 4) != 4) {
2397 printf("read on fnum1 failed (%s)\n", cli_errstr(&cli1));
2398 correct = False;
2401 /* Should now be at level II. */
2402 /* Test if sending a write locks causes a break to none. */
2404 if (!cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2405 printf("lock failed (%s)\n", cli_errstr(&cli1));
2406 correct = False;
2409 cli_unlock(&cli1, fnum1, 0, 4);
2411 sleep(2);
2413 if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2414 printf("lock failed (%s)\n", cli_errstr(&cli1));
2415 correct = False;
2418 cli_unlock(&cli1, fnum1, 0, 4);
2420 sleep(2);
2422 cli_read(&cli1, fnum1, buf, 0, 4);
2424 #if 0
2425 if (cli_write(&cli1, fnum1, 0, buf, 0, 4) != 4) {
2426 printf("write on fnum1 failed (%s)\n", cli_errstr(&cli1));
2427 correct = False;
2429 #endif
2431 if (!cli_close(&cli1, fnum1)) {
2432 printf("close1 failed (%s)\n", cli_errstr(&cli1));
2433 correct = False;
2436 sleep(4);
2438 if (!cli_unlink(&cli1, fname)) {
2439 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2440 correct = False;
2443 if (!torture_close_connection(&cli1)) {
2444 correct = False;
2447 if (!*shared_correct) {
2448 correct = False;
2451 printf("finished oplock test 2\n");
2453 return correct;
2456 /* handler for oplock 3 tests */
2457 static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2459 printf("got oplock break fnum=%d level=%d\n",
2460 fnum, level);
2461 return cli_oplock_ack(cli, fnum, level);
2464 static BOOL run_oplock3(int dummy)
2466 static struct cli_state cli;
2467 const char *fname = "\\oplockt3.dat";
2468 int fnum;
2469 char buf[4] = "abcd";
2470 BOOL correct = True;
2471 volatile BOOL *shared_correct;
2473 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2474 *shared_correct = True;
2476 printf("starting oplock test 3\n");
2478 if (fork() == 0) {
2479 /* Child code */
2480 use_oplocks = True;
2481 use_level_II_oplocks = True;
2482 if (!torture_open_connection(&cli)) {
2483 *shared_correct = False;
2484 exit(0);
2486 sleep(2);
2487 /* try to trigger a oplock break in parent */
2488 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2489 cli_write(&cli, fnum, 0, buf, 0, 4);
2490 exit(0);
2493 /* parent code */
2494 use_oplocks = True;
2495 use_level_II_oplocks = True;
2496 if (!torture_open_connection(&cli)) {
2497 return False;
2499 cli_oplock_handler(&cli, oplock3_handler);
2500 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2501 cli_write(&cli, fnum, 0, buf, 0, 4);
2502 cli_close(&cli, fnum);
2503 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2504 cli.timeout = 20000;
2505 cli_receive_smb(&cli);
2506 printf("finished oplock test 3\n");
2508 return (correct && *shared_correct);
2510 /* What are we looking for here? What's sucess and what's FAILURE? */
2516 Test delete on close semantics.
2518 static BOOL run_deletetest(int dummy)
2520 static struct cli_state cli1;
2521 static struct cli_state cli2;
2522 const char *fname = "\\delete.file";
2523 int fnum1 = -1;
2524 int fnum2 = -1;
2525 BOOL correct = True;
2527 printf("starting delete test\n");
2529 ZERO_STRUCT(cli1);
2530 ZERO_STRUCT(cli2);
2532 if (!torture_open_connection(&cli1)) {
2533 return False;
2536 cli_sockopt(&cli1, sockops);
2538 /* Test 1 - this should delete the file on close. */
2540 cli_setatr(&cli1, fname, 0, 0);
2541 cli_unlink(&cli1, fname);
2543 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2544 FILE_SHARE_DELETE, FILE_OVERWRITE_IF,
2545 FILE_DELETE_ON_CLOSE);
2547 if (fnum1 == -1) {
2548 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2549 correct = False;
2550 goto fail;
2553 if (!cli_close(&cli1, fnum1)) {
2554 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2555 correct = False;
2556 goto fail;
2559 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
2560 if (fnum1 != -1) {
2561 printf("[1] open of %s succeeded (should fail)\n", fname);
2562 correct = False;
2563 goto fail;
2566 printf("first delete on close test succeeded.\n");
2568 /* Test 2 - this should delete the file on close. */
2570 cli_setatr(&cli1, fname, 0, 0);
2571 cli_unlink(&cli1, fname);
2573 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS,
2574 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
2575 FILE_OVERWRITE_IF, 0);
2577 if (fnum1 == -1) {
2578 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2579 correct = False;
2580 goto fail;
2583 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2584 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2585 correct = False;
2586 goto fail;
2589 if (!cli_close(&cli1, fnum1)) {
2590 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2591 correct = False;
2592 goto fail;
2595 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2596 if (fnum1 != -1) {
2597 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2598 if (!cli_close(&cli1, fnum1)) {
2599 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2600 correct = False;
2601 goto fail;
2603 cli_unlink(&cli1, fname);
2604 } else
2605 printf("second delete on close test succeeded.\n");
2607 /* Test 3 - ... */
2608 cli_setatr(&cli1, fname, 0, 0);
2609 cli_unlink(&cli1, fname);
2611 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2612 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2614 if (fnum1 == -1) {
2615 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2616 correct = False;
2617 goto fail;
2620 /* This should fail with a sharing violation - open for delete is only compatible
2621 with SHARE_DELETE. */
2623 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2624 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0);
2626 if (fnum2 != -1) {
2627 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2628 correct = False;
2629 goto fail;
2632 /* This should succeed. */
2634 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2635 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2637 if (fnum2 == -1) {
2638 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2639 correct = False;
2640 goto fail;
2643 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2644 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2645 correct = False;
2646 goto fail;
2649 if (!cli_close(&cli1, fnum1)) {
2650 printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1));
2651 correct = False;
2652 goto fail;
2655 if (!cli_close(&cli1, fnum2)) {
2656 printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1));
2657 correct = False;
2658 goto fail;
2661 /* This should fail - file should no longer be there. */
2663 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2664 if (fnum1 != -1) {
2665 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2666 if (!cli_close(&cli1, fnum1)) {
2667 printf("[3] close failed (%s)\n", cli_errstr(&cli1));
2669 cli_unlink(&cli1, fname);
2670 correct = False;
2671 goto fail;
2672 } else
2673 printf("third delete on close test succeeded.\n");
2675 /* Test 4 ... */
2676 cli_setatr(&cli1, fname, 0, 0);
2677 cli_unlink(&cli1, fname);
2679 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2680 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2682 if (fnum1 == -1) {
2683 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2684 correct = False;
2685 goto fail;
2688 /* This should succeed. */
2689 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2690 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2691 if (fnum2 == -1) {
2692 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2693 correct = False;
2694 goto fail;
2697 if (!cli_close(&cli1, fnum2)) {
2698 printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1));
2699 correct = False;
2700 goto fail;
2703 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2704 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2705 correct = False;
2706 goto fail;
2709 /* This should fail - no more opens once delete on close set. */
2710 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2711 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2712 if (fnum2 != -1) {
2713 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2714 correct = False;
2715 goto fail;
2716 } else
2717 printf("fourth delete on close test succeeded.\n");
2719 if (!cli_close(&cli1, fnum1)) {
2720 printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1));
2721 correct = False;
2722 goto fail;
2725 /* Test 5 ... */
2726 cli_setatr(&cli1, fname, 0, 0);
2727 cli_unlink(&cli1, fname);
2729 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
2730 if (fnum1 == -1) {
2731 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2732 correct = False;
2733 goto fail;
2736 /* This should fail - only allowed on NT opens with DELETE access. */
2738 if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2739 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2740 correct = False;
2741 goto fail;
2744 if (!cli_close(&cli1, fnum1)) {
2745 printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1));
2746 correct = False;
2747 goto fail;
2750 printf("fifth delete on close test succeeded.\n");
2752 /* Test 6 ... */
2753 cli_setatr(&cli1, fname, 0, 0);
2754 cli_unlink(&cli1, fname);
2756 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2757 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2758 FILE_OVERWRITE_IF, 0);
2760 if (fnum1 == -1) {
2761 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2762 correct = False;
2763 goto fail;
2766 /* This should fail - only allowed on NT opens with DELETE access. */
2768 if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2769 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2770 correct = False;
2771 goto fail;
2774 if (!cli_close(&cli1, fnum1)) {
2775 printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1));
2776 correct = False;
2777 goto fail;
2780 printf("sixth delete on close test succeeded.\n");
2782 /* Test 7 ... */
2783 cli_setatr(&cli1, fname, 0, 0);
2784 cli_unlink(&cli1, fname);
2786 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2787 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0);
2789 if (fnum1 == -1) {
2790 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2791 correct = False;
2792 goto fail;
2795 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2796 printf("[7] setting delete_on_close on file failed !\n");
2797 correct = False;
2798 goto fail;
2801 if (!cli_nt_delete_on_close(&cli1, fnum1, False)) {
2802 printf("[7] unsetting delete_on_close on file failed !\n");
2803 correct = False;
2804 goto fail;
2807 if (!cli_close(&cli1, fnum1)) {
2808 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2809 correct = False;
2810 goto fail;
2813 /* This next open should succeed - we reset the flag. */
2815 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2816 if (fnum1 == -1) {
2817 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2818 correct = False;
2819 goto fail;
2822 if (!cli_close(&cli1, fnum1)) {
2823 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2824 correct = False;
2825 goto fail;
2828 printf("seventh delete on close test succeeded.\n");
2830 /* Test 7 ... */
2831 cli_setatr(&cli1, fname, 0, 0);
2832 cli_unlink(&cli1, fname);
2834 if (!torture_open_connection(&cli2)) {
2835 printf("[8] failed to open second connection.\n");
2836 correct = False;
2837 goto fail;
2840 cli_sockopt(&cli1, sockops);
2842 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2843 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
2845 if (fnum1 == -1) {
2846 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2847 correct = False;
2848 goto fail;
2851 fnum2 = cli_nt_create_full(&cli2, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2852 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2854 if (fnum2 == -1) {
2855 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2856 correct = False;
2857 goto fail;
2860 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2861 printf("[8] setting delete_on_close on file failed !\n");
2862 correct = False;
2863 goto fail;
2866 if (!cli_close(&cli1, fnum1)) {
2867 printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1));
2868 correct = False;
2869 goto fail;
2872 if (!cli_close(&cli2, fnum2)) {
2873 printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2));
2874 correct = False;
2875 goto fail;
2878 /* This should fail.. */
2879 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2880 if (fnum1 != -1) {
2881 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2882 goto fail;
2883 correct = False;
2884 } else
2885 printf("eighth delete on close test succeeded.\n");
2887 /* This should fail - we need to set DELETE_ACCESS. */
2888 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2889 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
2891 if (fnum1 != -1) {
2892 printf("[9] open of %s succeeded should have failed!\n", fname);
2893 correct = False;
2894 goto fail;
2897 printf("ninth delete on close test succeeded.\n");
2899 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2900 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
2901 if (fnum1 == -1) {
2902 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2903 correct = False;
2904 goto fail;
2907 /* This should delete the file. */
2908 if (!cli_close(&cli1, fnum1)) {
2909 printf("[10] close failed (%s)\n", cli_errstr(&cli1));
2910 correct = False;
2911 goto fail;
2914 /* This should fail.. */
2915 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2916 if (fnum1 != -1) {
2917 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
2918 goto fail;
2919 correct = False;
2920 } else
2921 printf("tenth delete on close test succeeded.\n");
2922 printf("finished delete test\n");
2924 fail:
2926 cli_close(&cli1, fnum1);
2927 cli_close(&cli1, fnum2);
2928 cli_setatr(&cli1, fname, 0, 0);
2929 cli_unlink(&cli1, fname);
2931 if (!torture_close_connection(&cli1)) {
2932 correct = False;
2934 if (!torture_close_connection(&cli2)) {
2935 correct = False;
2937 return correct;
2942 print out server properties
2944 static BOOL run_properties(int dummy)
2946 static struct cli_state cli;
2947 BOOL correct = True;
2949 printf("starting properties test\n");
2951 ZERO_STRUCT(cli);
2953 if (!torture_open_connection(&cli)) {
2954 return False;
2957 cli_sockopt(&cli, sockops);
2959 d_printf("Capabilities 0x%08x\n", cli.capabilities);
2961 if (!torture_close_connection(&cli)) {
2962 correct = False;
2965 return correct;
2970 /* FIRST_DESIRED_ACCESS 0xf019f */
2971 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
2972 FILE_READ_EA| /* 0xf */ \
2973 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
2974 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
2975 DELETE_ACCESS|READ_CONTROL_ACCESS|\
2976 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
2977 /* SECOND_DESIRED_ACCESS 0xe0080 */
2978 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
2979 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2980 WRITE_OWNER_ACCESS /* 0xe0000 */
2982 #if 0
2983 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
2984 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
2985 FILE_READ_DATA|\
2986 WRITE_OWNER_ACCESS /* */
2987 #endif
2990 Test ntcreate calls made by xcopy
2992 static BOOL run_xcopy(int dummy)
2994 static struct cli_state cli1;
2995 const char *fname = "\\test.txt";
2996 BOOL correct = True;
2997 int fnum1, fnum2;
2999 printf("starting xcopy test\n");
3001 if (!torture_open_connection(&cli1)) {
3002 return False;
3005 fnum1 = cli_nt_create_full(&cli1, fname,
3006 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3007 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3008 0x4044);
3010 if (fnum1 == -1) {
3011 printf("First open failed - %s\n", cli_errstr(&cli1));
3012 return False;
3015 fnum2 = cli_nt_create_full(&cli1, fname,
3016 SECOND_DESIRED_ACCESS, 0,
3017 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3018 0x200000);
3019 if (fnum2 == -1) {
3020 printf("second open failed - %s\n", cli_errstr(&cli1));
3021 return False;
3024 if (!torture_close_connection(&cli1)) {
3025 correct = False;
3028 return correct;
3032 Test rename on files open with share delete and no share delete.
3034 static BOOL run_rename(int dummy)
3036 static struct cli_state cli1;
3037 const char *fname = "\\test.txt";
3038 const char *fname1 = "\\test1.txt";
3039 BOOL correct = True;
3040 int fnum1;
3042 printf("starting rename test\n");
3044 if (!torture_open_connection(&cli1)) {
3045 return False;
3048 cli_unlink(&cli1, fname);
3049 cli_unlink(&cli1, fname1);
3050 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3051 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
3053 if (fnum1 == -1) {
3054 printf("First open failed - %s\n", cli_errstr(&cli1));
3055 return False;
3058 if (!cli_rename(&cli1, fname, fname1)) {
3059 printf("First rename failed (this is correct) - %s\n", cli_errstr(&cli1));
3060 } else {
3061 printf("First rename succeeded - this should have failed !\n");
3062 correct = False;
3065 if (!cli_close(&cli1, fnum1)) {
3066 printf("close - 1 failed (%s)\n", cli_errstr(&cli1));
3067 return False;
3070 cli_unlink(&cli1, fname);
3071 cli_unlink(&cli1, fname1);
3072 fnum1 = cli_nt_create_full(&cli1, fname,GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3073 #if 0
3074 FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3075 #else
3076 FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
3077 #endif
3079 if (fnum1 == -1) {
3080 printf("Second open failed - %s\n", cli_errstr(&cli1));
3081 return False;
3084 if (!cli_rename(&cli1, fname, fname1)) {
3085 printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(&cli1));
3086 correct = False;
3087 } else {
3088 printf("Second rename succeeded\n");
3091 if (!cli_close(&cli1, fnum1)) {
3092 printf("close - 2 failed (%s)\n", cli_errstr(&cli1));
3093 return False;
3096 cli_unlink(&cli1, fname);
3097 cli_unlink(&cli1, fname1);
3099 fnum1 = cli_nt_create_full(&cli1, fname,READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3100 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3102 if (fnum1 == -1) {
3103 printf("Third open failed - %s\n", cli_errstr(&cli1));
3104 return False;
3108 #if 0
3110 int fnum2;
3112 fnum2 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3113 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3115 if (fnum2 == -1) {
3116 printf("Fourth open failed - %s\n", cli_errstr(&cli1));
3117 return False;
3119 if (!cli_nt_delete_on_close(&cli1, fnum2, True)) {
3120 printf("[8] setting delete_on_close on file failed !\n");
3121 return False;
3124 if (!cli_close(&cli1, fnum2)) {
3125 printf("close - 4 failed (%s)\n", cli_errstr(&cli1));
3126 return False;
3129 #endif
3131 if (!cli_rename(&cli1, fname, fname1)) {
3132 printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(&cli1));
3133 correct = False;
3134 } else {
3135 printf("Third rename succeeded\n");
3138 if (!cli_close(&cli1, fnum1)) {
3139 printf("close - 3 failed (%s)\n", cli_errstr(&cli1));
3140 return False;
3143 cli_unlink(&cli1, fname);
3144 cli_unlink(&cli1, fname1);
3146 if (!torture_close_connection(&cli1)) {
3147 correct = False;
3150 return correct;
3153 static BOOL run_pipe_number(int dummy)
3155 static struct cli_state cli1;
3156 const char *pipe_name = "\\SPOOLSS";
3157 int fnum;
3158 int num_pipes = 0;
3160 printf("starting pipenumber test\n");
3161 if (!torture_open_connection(&cli1)) {
3162 return False;
3165 cli_sockopt(&cli1, sockops);
3166 while(1) {
3167 fnum = cli_nt_create_full(&cli1, pipe_name,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3168 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0);
3170 if (fnum == -1) {
3171 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(&cli1));
3172 break;
3174 num_pipes++;
3177 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3178 torture_close_connection(&cli1);
3179 return True;
3183 Test open mode returns on read-only files.
3185 static BOOL run_opentest(int dummy)
3187 static struct cli_state cli1;
3188 static struct cli_state cli2;
3189 const char *fname = "\\readonly.file";
3190 int fnum1, fnum2;
3191 char buf[20];
3192 size_t fsize;
3193 BOOL correct = True;
3194 char *tmp_path;
3196 printf("starting open test\n");
3198 if (!torture_open_connection(&cli1)) {
3199 return False;
3202 cli_setatr(&cli1, fname, 0, 0);
3203 cli_unlink(&cli1, fname);
3205 cli_sockopt(&cli1, sockops);
3207 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3208 if (fnum1 == -1) {
3209 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3210 return False;
3213 if (!cli_close(&cli1, fnum1)) {
3214 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3215 return False;
3218 if (!cli_setatr(&cli1, fname, aRONLY, 0)) {
3219 printf("cli_setatr failed (%s)\n", cli_errstr(&cli1));
3220 return False;
3223 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
3224 if (fnum1 == -1) {
3225 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3226 return False;
3229 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3230 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
3232 if (check_error(__LINE__, &cli1, ERRDOS, ERRnoaccess,
3233 NT_STATUS_ACCESS_DENIED)) {
3234 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3237 printf("finished open test 1\n");
3239 cli_close(&cli1, fnum1);
3241 /* Now try not readonly and ensure ERRbadshare is returned. */
3243 cli_setatr(&cli1, fname, 0, 0);
3245 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
3246 if (fnum1 == -1) {
3247 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
3248 return False;
3251 /* This will fail - but the error should be ERRshare. */
3252 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
3254 if (check_error(__LINE__, &cli1, ERRDOS, ERRbadshare,
3255 NT_STATUS_SHARING_VIOLATION)) {
3256 printf("correct error code ERRDOS/ERRbadshare returned\n");
3259 if (!cli_close(&cli1, fnum1)) {
3260 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3261 return False;
3264 cli_unlink(&cli1, fname);
3266 printf("finished open test 2\n");
3268 /* Test truncate open disposition on file opened for read. */
3270 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3271 if (fnum1 == -1) {
3272 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(&cli1));
3273 return False;
3276 /* write 20 bytes. */
3278 memset(buf, '\0', 20);
3280 if (cli_write(&cli1, fnum1, 0, buf, 0, 20) != 20) {
3281 printf("write failed (%s)\n", cli_errstr(&cli1));
3282 correct = False;
3285 if (!cli_close(&cli1, fnum1)) {
3286 printf("(3) close1 failed (%s)\n", cli_errstr(&cli1));
3287 return False;
3290 /* Ensure size == 20. */
3291 if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
3292 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
3293 return False;
3296 if (fsize != 20) {
3297 printf("(3) file size != 20\n");
3298 return False;
3301 /* Now test if we can truncate a file opened for readonly. */
3303 fnum1 = cli_open(&cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3304 if (fnum1 == -1) {
3305 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(&cli1));
3306 return False;
3309 if (!cli_close(&cli1, fnum1)) {
3310 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3311 return False;
3314 /* Ensure size == 0. */
3315 if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
3316 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
3317 return False;
3320 if (fsize != 0) {
3321 printf("(3) file size != 0\n");
3322 return False;
3324 printf("finished open test 3\n");
3326 cli_unlink(&cli1, fname);
3329 printf("testing ctemp\n");
3330 fnum1 = cli_ctemp(&cli1, "\\", &tmp_path);
3331 if (fnum1 == -1) {
3332 printf("ctemp failed (%s)\n", cli_errstr(&cli1));
3333 return False;
3335 printf("ctemp gave path %s\n", tmp_path);
3336 if (!cli_close(&cli1, fnum1)) {
3337 printf("close of temp failed (%s)\n", cli_errstr(&cli1));
3339 if (!cli_unlink(&cli1, tmp_path)) {
3340 printf("unlink of temp failed (%s)\n", cli_errstr(&cli1));
3343 /* Test the non-io opens... */
3345 if (!torture_open_connection(&cli2)) {
3346 return False;
3349 cli_setatr(&cli2, fname, 0, 0);
3350 cli_unlink(&cli2, fname);
3352 cli_sockopt(&cli2, sockops);
3354 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3356 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3357 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3359 if (fnum1 == -1) {
3360 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3361 return False;
3364 fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3365 FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3367 if (fnum2 == -1) {
3368 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3369 return False;
3372 if (!cli_close(&cli1, fnum1)) {
3373 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3374 return False;
3376 if (!cli_close(&cli2, fnum2)) {
3377 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3378 return False;
3381 printf("non-io open test #1 passed.\n");
3383 cli_unlink(&cli1, fname);
3385 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3387 fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3388 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3390 if (fnum1 == -1) {
3391 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3392 return False;
3395 fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3396 FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3398 if (fnum2 == -1) {
3399 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3400 return False;
3403 if (!cli_close(&cli1, fnum1)) {
3404 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3405 return False;
3407 if (!cli_close(&cli2, fnum2)) {
3408 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3409 return False;
3412 printf("non-io open test #2 passed.\n");
3414 cli_unlink(&cli1, fname);
3416 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3418 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3419 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3421 if (fnum1 == -1) {
3422 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3423 return False;
3426 fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3427 FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3429 if (fnum2 == -1) {
3430 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3431 return False;
3434 if (!cli_close(&cli1, fnum1)) {
3435 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3436 return False;
3438 if (!cli_close(&cli2, fnum2)) {
3439 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3440 return False;
3443 printf("non-io open test #3 passed.\n");
3445 cli_unlink(&cli1, fname);
3447 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
3449 fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3450 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3452 if (fnum1 == -1) {
3453 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3454 return False;
3457 fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3458 FILE_SHARE_NONE, FILE_OPEN_IF, 0);
3460 if (fnum2 != -1) {
3461 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(&cli2));
3462 return False;
3465 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(&cli2), "sharing violation");
3467 if (!cli_close(&cli1, fnum1)) {
3468 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3469 return False;
3472 printf("non-io open test #4 passed.\n");
3474 cli_unlink(&cli1, fname);
3476 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
3478 fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3479 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
3481 if (fnum1 == -1) {
3482 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3483 return False;
3486 fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3487 FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
3489 if (fnum2 == -1) {
3490 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3491 return False;
3494 if (!cli_close(&cli1, fnum1)) {
3495 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3496 return False;
3499 if (!cli_close(&cli2, fnum2)) {
3500 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3501 return False;
3504 printf("non-io open test #5 passed.\n");
3506 printf("TEST #6 testing 1 non-io open, one io open\n");
3508 cli_unlink(&cli1, fname);
3510 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3511 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3513 if (fnum1 == -1) {
3514 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3515 return False;
3518 fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3519 FILE_SHARE_READ, FILE_OPEN_IF, 0);
3521 if (fnum2 == -1) {
3522 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3523 return False;
3526 if (!cli_close(&cli1, fnum1)) {
3527 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3528 return False;
3531 if (!cli_close(&cli2, fnum2)) {
3532 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
3533 return False;
3536 printf("non-io open test #6 passed.\n");
3538 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
3540 cli_unlink(&cli1, fname);
3542 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3543 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3545 if (fnum1 == -1) {
3546 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3547 return False;
3550 fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3551 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
3553 if (fnum2 != -1) {
3554 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(&cli2));
3555 return False;
3558 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(&cli2), "sharing violation");
3560 if (!cli_close(&cli1, fnum1)) {
3561 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
3562 return False;
3565 printf("non-io open test #7 passed.\n");
3567 cli_unlink(&cli1, fname);
3569 if (!torture_close_connection(&cli1)) {
3570 correct = False;
3572 if (!torture_close_connection(&cli2)) {
3573 correct = False;
3576 return correct;
3579 static uint32 open_attrs_table[] = {
3580 FILE_ATTRIBUTE_NORMAL,
3581 FILE_ATTRIBUTE_ARCHIVE,
3582 FILE_ATTRIBUTE_READONLY,
3583 FILE_ATTRIBUTE_HIDDEN,
3584 FILE_ATTRIBUTE_SYSTEM,
3586 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
3587 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
3588 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
3589 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3590 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3591 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3593 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
3594 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
3595 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
3596 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
3599 struct trunc_open_results {
3600 int num;
3601 uint32 init_attr;
3602 uint32 trunc_attr;
3603 uint32 result_attr;
3606 static struct trunc_open_results attr_results[] = {
3607 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3608 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3609 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3610 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
3611 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
3612 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
3613 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3614 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3615 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3616 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3617 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3618 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
3619 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3620 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3621 { 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 },
3622 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3623 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3624 { 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 },
3625 { 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 },
3626 { 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 },
3627 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3628 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
3629 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
3630 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3631 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
3632 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
3635 static BOOL run_openattrtest(int dummy)
3637 static struct cli_state cli1;
3638 const char *fname = "\\openattr.file";
3639 int fnum1;
3640 BOOL correct = True;
3641 uint16 attr;
3642 int i, j, k, l;
3644 printf("starting open attr test\n");
3646 if (!torture_open_connection(&cli1)) {
3647 return False;
3650 cli_sockopt(&cli1, sockops);
3652 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
3653 cli_setatr(&cli1, fname, 0, 0);
3654 cli_unlink(&cli1, fname);
3655 fnum1 = cli_nt_create_full(&cli1, fname,FILE_WRITE_DATA, open_attrs_table[i],
3656 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
3658 if (fnum1 == -1) {
3659 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(&cli1));
3660 return False;
3663 if (!cli_close(&cli1, fnum1)) {
3664 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(&cli1));
3665 return False;
3668 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
3669 fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
3670 FILE_SHARE_NONE, FILE_OVERWRITE, 0);
3672 if (fnum1 == -1) {
3673 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
3674 if (attr_results[l].num == k) {
3675 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
3676 k, open_attrs_table[i],
3677 open_attrs_table[j],
3678 fname, NT_STATUS_V(cli_nt_error(&cli1)), cli_errstr(&cli1));
3679 correct = False;
3682 if (NT_STATUS_V(cli_nt_error(&cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
3683 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
3684 k, open_attrs_table[i], open_attrs_table[j],
3685 cli_errstr(&cli1));
3686 correct = False;
3688 #if 0
3689 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
3690 #endif
3691 k++;
3692 continue;
3695 if (!cli_close(&cli1, fnum1)) {
3696 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(&cli1));
3697 return False;
3700 if (!cli_getatr(&cli1, fname, &attr, NULL, NULL)) {
3701 printf("getatr(2) failed (%s)\n", cli_errstr(&cli1));
3702 return False;
3705 #if 0
3706 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
3707 k, open_attrs_table[i], open_attrs_table[j], attr );
3708 #endif
3710 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
3711 if (attr_results[l].num == k) {
3712 if (attr != attr_results[l].result_attr ||
3713 open_attrs_table[i] != attr_results[l].init_attr ||
3714 open_attrs_table[j] != attr_results[l].trunc_attr) {
3715 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
3716 open_attrs_table[i],
3717 open_attrs_table[j],
3718 (unsigned int)attr,
3719 attr_results[l].result_attr);
3720 correct = False;
3722 break;
3725 k++;
3729 cli_setatr(&cli1, fname, 0, 0);
3730 cli_unlink(&cli1, fname);
3732 printf("open attr test %s.\n", correct ? "passed" : "failed");
3734 if (!torture_close_connection(&cli1)) {
3735 correct = False;
3737 return correct;
3740 static void list_fn(file_info *finfo, const char *name, void *state)
3746 test directory listing speed
3748 static BOOL run_dirtest(int dummy)
3750 int i;
3751 static struct cli_state cli;
3752 int fnum;
3753 double t1;
3754 BOOL correct = True;
3756 printf("starting directory test\n");
3758 if (!torture_open_connection(&cli)) {
3759 return False;
3762 cli_sockopt(&cli, sockops);
3764 srandom(0);
3765 for (i=0;i<torture_numops;i++) {
3766 fstring fname;
3767 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3768 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
3769 if (fnum == -1) {
3770 fprintf(stderr,"Failed to open %s\n", fname);
3771 return False;
3773 cli_close(&cli, fnum);
3776 t1 = end_timer();
3778 printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
3779 printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
3780 printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
3782 printf("dirtest core %g seconds\n", end_timer() - t1);
3784 srandom(0);
3785 for (i=0;i<torture_numops;i++) {
3786 fstring fname;
3787 slprintf(fname, sizeof(fname), "\\%x", (int)random());
3788 cli_unlink(&cli, fname);
3791 if (!torture_close_connection(&cli)) {
3792 correct = False;
3795 printf("finished dirtest\n");
3797 return correct;
3800 static void del_fn(file_info *finfo, const char *mask, void *state)
3802 struct cli_state *pcli = (struct cli_state *)state;
3803 fstring fname;
3804 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
3806 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
3807 return;
3809 if (finfo->mode & aDIR) {
3810 if (!cli_rmdir(pcli, fname))
3811 printf("del_fn: failed to rmdir %s\n,", fname );
3812 } else {
3813 if (!cli_unlink(pcli, fname))
3814 printf("del_fn: failed to unlink %s\n,", fname );
3818 static BOOL run_dirtest1(int dummy)
3820 int i;
3821 static struct cli_state cli;
3822 int fnum, num_seen;
3823 BOOL correct = True;
3825 printf("starting directory test\n");
3827 if (!torture_open_connection(&cli)) {
3828 return False;
3831 cli_sockopt(&cli, sockops);
3833 cli_list(&cli, "\\LISTDIR\\*", 0, del_fn, &cli);
3834 cli_list(&cli, "\\LISTDIR\\*", aDIR, del_fn, &cli);
3835 cli_rmdir(&cli, "\\LISTDIR");
3836 cli_mkdir(&cli, "\\LISTDIR");
3838 /* Create 1000 files and 1000 directories. */
3839 for (i=0;i<1000;i++) {
3840 fstring fname;
3841 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
3842 fnum = cli_nt_create_full(&cli, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3843 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
3844 if (fnum == -1) {
3845 fprintf(stderr,"Failed to open %s\n", fname);
3846 return False;
3848 cli_close(&cli, fnum);
3850 for (i=0;i<1000;i++) {
3851 fstring fname;
3852 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
3853 if (!cli_mkdir(&cli, fname)) {
3854 fprintf(stderr,"Failed to open %s\n", fname);
3855 return False;
3859 /* Now ensure that doing an old list sees both files and directories. */
3860 num_seen = cli_list_old(&cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
3861 printf("num_seen = %d\n", num_seen );
3862 /* We should see 100 files + 1000 directories + . and .. */
3863 if (num_seen != 2002)
3864 correct = False;
3866 /* Ensure if we have the "must have" bits we only see the
3867 * relevent entries.
3869 num_seen = cli_list_old(&cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
3870 printf("num_seen = %d\n", num_seen );
3871 if (num_seen != 1002)
3872 correct = False;
3874 num_seen = cli_list_old(&cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
3875 printf("num_seen = %d\n", num_seen );
3876 if (num_seen != 1000)
3877 correct = False;
3879 /* Delete everything. */
3880 cli_list(&cli, "\\LISTDIR\\*", 0, del_fn, &cli);
3881 cli_list(&cli, "\\LISTDIR\\*", aDIR, del_fn, &cli);
3882 cli_rmdir(&cli, "\\LISTDIR");
3884 #if 0
3885 printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
3886 printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
3887 printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
3888 #endif
3890 if (!torture_close_connection(&cli)) {
3891 correct = False;
3894 printf("finished dirtest1\n");
3896 return correct;
3899 static BOOL run_error_map_extract(int dummy) {
3901 static struct cli_state c_dos;
3902 static struct cli_state c_nt;
3904 uint32 error;
3906 uint32 flgs2, errnum;
3907 uint8 errclass;
3909 NTSTATUS nt_status;
3911 fstring user;
3913 /* NT-Error connection */
3915 if (!open_nbt_connection(&c_nt)) {
3916 return False;
3919 c_nt.use_spnego = False;
3921 if (!cli_negprot(&c_nt)) {
3922 printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(&c_nt));
3923 cli_shutdown(&c_nt);
3924 return False;
3927 if (!cli_session_setup(&c_nt, "", "", 0, "", 0,
3928 workgroup)) {
3929 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(&c_nt));
3930 return False;
3933 /* DOS-Error connection */
3935 if (!open_nbt_connection(&c_dos)) {
3936 return False;
3939 c_dos.use_spnego = False;
3940 c_dos.force_dos_errors = True;
3942 if (!cli_negprot(&c_dos)) {
3943 printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(&c_dos));
3944 cli_shutdown(&c_dos);
3945 return False;
3948 if (!cli_session_setup(&c_dos, "", "", 0, "", 0,
3949 workgroup)) {
3950 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(&c_dos));
3951 return False;
3954 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
3955 snprintf(user, sizeof(user), "%X", error);
3957 if (cli_session_setup(&c_nt, user,
3958 password, strlen(password),
3959 password, strlen(password),
3960 workgroup)) {
3961 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
3964 flgs2 = SVAL(c_nt.inbuf,smb_flg2);
3966 /* Case #1: 32-bit NT errors */
3967 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
3968 nt_status = NT_STATUS(IVAL(c_nt.inbuf,smb_rcls));
3969 } else {
3970 printf("/** Dos error on NT connection! (%s) */\n",
3971 cli_errstr(&c_nt));
3972 nt_status = NT_STATUS(0xc0000000);
3975 if (cli_session_setup(&c_dos, user,
3976 password, strlen(password),
3977 password, strlen(password),
3978 workgroup)) {
3979 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
3981 flgs2 = SVAL(c_dos.inbuf,smb_flg2), errnum;
3983 /* Case #1: 32-bit NT errors */
3984 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
3985 printf("/** NT error on DOS connection! (%s) */\n",
3986 cli_errstr(&c_nt));
3987 errnum = errclass = 0;
3988 } else {
3989 cli_dos_error(&c_dos, &errclass, &errnum);
3992 if (NT_STATUS_V(nt_status) != error) {
3993 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
3994 get_nt_error_c_code(NT_STATUS(error)),
3995 get_nt_error_c_code(nt_status));
3998 printf("\t{%s,\t%s,\t%s},\n",
3999 smb_dos_err_class(errclass),
4000 smb_dos_err_name(errclass, errnum),
4001 get_nt_error_c_code(NT_STATUS(error)));
4003 return True;
4006 static double create_procs(BOOL (*fn)(int), BOOL *result)
4008 int i, status;
4009 volatile pid_t *child_status;
4010 volatile BOOL *child_status_out;
4011 int synccount;
4012 int tries = 8;
4014 synccount = 0;
4016 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
4017 if (!child_status) {
4018 printf("Failed to setup shared memory\n");
4019 return -1;
4022 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
4023 if (!child_status_out) {
4024 printf("Failed to setup result status shared memory\n");
4025 return -1;
4028 for (i = 0; i < nprocs; i++) {
4029 child_status[i] = 0;
4030 child_status_out[i] = True;
4033 start_timer();
4035 for (i=0;i<nprocs;i++) {
4036 procnum = i;
4037 if (fork() == 0) {
4038 pid_t mypid = getpid();
4039 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
4041 slprintf(myname,sizeof(myname),"CLIENT%d", i);
4043 while (1) {
4044 memset(&current_cli, 0, sizeof(current_cli));
4045 if (torture_open_connection(&current_cli)) break;
4046 if (tries-- == 0) {
4047 printf("pid %d failed to start\n", (int)getpid());
4048 _exit(1);
4050 msleep(10);
4053 child_status[i] = getpid();
4055 while (child_status[i] && end_timer() < 5) msleep(2);
4057 child_status_out[i] = fn(i);
4058 _exit(0);
4062 do {
4063 synccount = 0;
4064 for (i=0;i<nprocs;i++) {
4065 if (child_status[i]) synccount++;
4067 if (synccount == nprocs) break;
4068 msleep(10);
4069 } while (end_timer() < 30);
4071 if (synccount != nprocs) {
4072 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
4073 *result = False;
4074 return end_timer();
4077 /* start the client load */
4078 start_timer();
4080 for (i=0;i<nprocs;i++) {
4081 child_status[i] = 0;
4084 printf("%d clients started\n", nprocs);
4086 for (i=0;i<nprocs;i++) {
4087 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
4090 printf("\n");
4092 for (i=0;i<nprocs;i++) {
4093 if (!child_status_out[i]) {
4094 *result = False;
4097 return end_timer();
4100 #define FLAG_MULTIPROC 1
4102 static struct {
4103 const char *name;
4104 BOOL (*fn)(int);
4105 unsigned flags;
4106 } torture_ops[] = {
4107 {"FDPASS", run_fdpasstest, 0},
4108 {"LOCK1", run_locktest1, 0},
4109 {"LOCK2", run_locktest2, 0},
4110 {"LOCK3", run_locktest3, 0},
4111 {"LOCK4", run_locktest4, 0},
4112 {"LOCK5", run_locktest5, 0},
4113 {"LOCK6", run_locktest6, 0},
4114 {"LOCK7", run_locktest7, 0},
4115 {"UNLINK", run_unlinktest, 0},
4116 {"BROWSE", run_browsetest, 0},
4117 {"ATTR", run_attrtest, 0},
4118 {"TRANS2", run_trans2test, 0},
4119 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
4120 {"TORTURE",run_torture, FLAG_MULTIPROC},
4121 {"RANDOMIPC", run_randomipc, 0},
4122 {"NEGNOWAIT", run_negprot_nowait, 0},
4123 {"NBENCH", run_nbench, 0},
4124 {"OPLOCK1", run_oplock1, 0},
4125 {"OPLOCK2", run_oplock2, 0},
4126 {"OPLOCK3", run_oplock3, 0},
4127 {"DIR", run_dirtest, 0},
4128 {"DIR1", run_dirtest1, 0},
4129 {"DENY1", torture_denytest1, 0},
4130 {"DENY2", torture_denytest2, 0},
4131 {"TCON", run_tcon_test, 0},
4132 {"RW1", run_readwritetest, 0},
4133 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
4134 {"RW3", run_readwritelarge, 0},
4135 {"OPEN", run_opentest, 0},
4136 #if 1
4137 {"OPENATTR", run_openattrtest, 0},
4138 #endif
4139 {"XCOPY", run_xcopy, 0},
4140 {"RENAME", run_rename, 0},
4141 {"DELETE", run_deletetest, 0},
4142 {"PROPERTIES", run_properties, 0},
4143 {"MANGLE", torture_mangle, 0},
4144 {"W2K", run_w2ktest, 0},
4145 {"TRANS2SCAN", torture_trans2_scan, 0},
4146 {"NTTRANSSCAN", torture_nttrans_scan, 0},
4147 {"UTABLE", torture_utable, 0},
4148 {"CASETABLE", torture_casetable, 0},
4149 {"ERRMAPEXTRACT", run_error_map_extract, 0},
4150 {"PIPE_NUMBER", run_pipe_number, 0},
4151 {NULL, NULL, 0}};
4155 /****************************************************************************
4156 run a specified test or "ALL"
4157 ****************************************************************************/
4158 static BOOL run_test(const char *name)
4160 BOOL ret = True;
4161 BOOL result = True;
4162 int i;
4163 double t;
4164 if (strequal(name,"ALL")) {
4165 for (i=0;torture_ops[i].name;i++) {
4166 run_test(torture_ops[i].name);
4170 for (i=0;torture_ops[i].name;i++) {
4171 snprintf(randomfname, sizeof(randomfname), "\\XX%x",
4172 (unsigned)random());
4174 if (strequal(name, torture_ops[i].name)) {
4175 printf("Running %s\n", name);
4176 if (torture_ops[i].flags & FLAG_MULTIPROC) {
4177 t = create_procs(torture_ops[i].fn, &result);
4178 if (!result) {
4179 ret = False;
4180 printf("TEST %s FAILED!\n", name);
4183 } else {
4184 start_timer();
4185 if (!torture_ops[i].fn(0)) {
4186 ret = False;
4187 printf("TEST %s FAILED!\n", name);
4189 t = end_timer();
4191 printf("%s took %g secs\n\n", name, t);
4194 return ret;
4198 static void usage(void)
4200 int i;
4202 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
4204 printf("\t-d debuglevel\n");
4205 printf("\t-U user%%pass\n");
4206 printf("\t-k use kerberos\n");
4207 printf("\t-N numprocs\n");
4208 printf("\t-n my_netbios_name\n");
4209 printf("\t-W workgroup\n");
4210 printf("\t-o num_operations\n");
4211 printf("\t-O socket_options\n");
4212 printf("\t-m maximum protocol\n");
4213 printf("\t-L use oplocks\n");
4214 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
4215 printf("\t-A showall\n");
4216 printf("\t-p port\n");
4217 printf("\t-s seed\n");
4218 printf("\n\n");
4220 printf("tests are:");
4221 for (i=0;torture_ops[i].name;i++) {
4222 printf(" %s", torture_ops[i].name);
4224 printf("\n");
4226 printf("default test is ALL\n");
4228 exit(1);
4231 /****************************************************************************
4232 main program
4233 ****************************************************************************/
4234 int main(int argc,char *argv[])
4236 int opt, i;
4237 char *p;
4238 int gotuser = 0;
4239 int gotpass = 0;
4240 extern char *optarg;
4241 extern int optind;
4242 BOOL correct = True;
4244 dbf = x_stdout;
4246 #ifdef HAVE_SETBUFFER
4247 setbuffer(stdout, NULL, 0);
4248 #endif
4250 lp_load(dyn_CONFIGFILE,True,False,False);
4251 load_interfaces();
4253 if (argc < 2) {
4254 usage();
4257 for(p = argv[1]; *p; p++)
4258 if(*p == '\\')
4259 *p = '/';
4261 if (strncmp(argv[1], "//", 2)) {
4262 usage();
4265 fstrcpy(host, &argv[1][2]);
4266 p = strchr_m(&host[2],'/');
4267 if (!p) {
4268 usage();
4270 *p = 0;
4271 fstrcpy(share, p+1);
4273 get_myname(myname);
4275 if (*username == 0 && getenv("LOGNAME")) {
4276 fstrcpy(username,getenv("LOGNAME"));
4279 argc--;
4280 argv++;
4282 srandom(time(NULL));
4284 fstrcpy(workgroup, lp_workgroup());
4286 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Ac:ks:")) != EOF) {
4287 switch (opt) {
4288 case 'p':
4289 port_to_use = atoi(optarg);
4290 break;
4291 case 's':
4292 srandom(atoi(optarg));
4293 break;
4294 case 'W':
4295 fstrcpy(workgroup,optarg);
4296 break;
4297 case 'm':
4298 max_protocol = interpret_protocol(optarg, max_protocol);
4299 break;
4300 case 'N':
4301 nprocs = atoi(optarg);
4302 break;
4303 case 'o':
4304 torture_numops = atoi(optarg);
4305 break;
4306 case 'd':
4307 DEBUGLEVEL = atoi(optarg);
4308 break;
4309 case 'O':
4310 sockops = optarg;
4311 break;
4312 case 'L':
4313 use_oplocks = True;
4314 break;
4315 case 'A':
4316 torture_showall = True;
4317 break;
4318 case 'n':
4319 fstrcpy(myname, optarg);
4320 break;
4321 case 'c':
4322 client_txt = optarg;
4323 break;
4324 case 'k':
4325 #ifdef HAVE_KRB5
4326 use_kerberos = True;
4327 #else
4328 d_printf("No kerberos support compiled in\n");
4329 exit(1);
4330 #endif
4331 break;
4332 case 'U':
4333 gotuser = 1;
4334 fstrcpy(username,optarg);
4335 p = strchr_m(username,'%');
4336 if (p) {
4337 *p = 0;
4338 fstrcpy(password, p+1);
4339 gotpass = 1;
4341 break;
4342 default:
4343 printf("Unknown option %c (%d)\n", (char)opt, opt);
4344 usage();
4348 if(use_kerberos && !gotuser) gotpass = True;
4350 while (!gotpass) {
4351 p = getpass("Password:");
4352 if (p) {
4353 fstrcpy(password, p);
4354 gotpass = 1;
4358 printf("host=%s share=%s user=%s myname=%s\n",
4359 host, share, username, myname);
4361 if (argc == 1) {
4362 correct = run_test("ALL");
4363 } else {
4364 for (i=1;i<argc;i++) {
4365 if (!run_test(argv[i])) {
4366 correct = False;
4371 if (correct) {
4372 return(0);
4373 } else {
4374 return(1);