2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1997-1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 static fstring host, workgroup, share, password, username, myname;
27 static int max_protocol = PROTOCOL_NT1;
28 static char *sockops="TCP_NODELAY";
29 static int nprocs=1, numops=100;
30 static int procnum; /* records process count number when forking */
31 static struct cli_state current_cli;
32 static fstring randomfname;
33 static BOOL use_oplocks;
34 static BOOL use_level_II_oplocks;
36 static double create_procs(BOOL (*fn)(int), BOOL *result);
39 static struct timeval tp1,tp2;
41 static void start_timer(void)
43 gettimeofday(&tp1,NULL);
46 static double end_timer(void)
48 gettimeofday(&tp2,NULL);
49 return((tp2.tv_sec - tp1.tv_sec) +
50 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
54 /* return a pointer to a anonymous shared memory segment of size "size"
55 which will persist across fork() but will disappear when all processes
58 The memory is not zeroed
60 This function uses system5 shared memory. It takes advantage of a property
61 that the memory is not destroyed if it is attached when the id is removed
63 static void *shm_setup(int size)
68 shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
70 printf("can't get shared memory\n");
73 ret = (void *)shmat(shmid, 0, 0);
74 if (!ret || ret == (void *)-1) {
75 printf("can't attach to shared memory\n");
78 /* the following releases the ipc, but note that this process
79 and all its children will still have access to the memory, its
80 just that the shmid is no longer valid for other shm calls. This
81 means we don't leave behind lots of shm segments after we exit
83 See Stevens "advanced programming in unix env" for details
85 shmctl(shmid, IPC_RMID, 0);
91 static BOOL open_nbt_connection(struct cli_state *c)
93 struct nmb_name called, calling;
95 extern struct in_addr ipzero;
99 make_nmb_name(&calling, myname, 0x0);
100 make_nmb_name(&called , host, 0x20);
104 if (!cli_initialise(c) || !cli_connect(c, host, &ip)) {
105 printf("Failed to connect with %s\n", host);
109 c->timeout = 120000; /* set a really long timeout (2 minutes) */
110 if (use_oplocks) c->use_oplocks = True;
111 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
113 if (!cli_session_request(c, &calling, &called)) {
114 printf("%s rejected the session\n",host);
122 static BOOL open_connection(struct cli_state *c)
126 if (!open_nbt_connection(c)) {
130 if (!cli_negprot(c)) {
131 printf("%s rejected the negprot (%s)\n",host, cli_errstr(c));
136 if (!cli_session_setup(c, username,
137 password, strlen(password),
138 password, strlen(password),
140 printf("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c));
145 if (!cli_send_tconX(c, share, "?????",
146 password, strlen(password)+1)) {
147 printf("%s refused tree connect (%s)\n", host, cli_errstr(c));
156 static BOOL close_connection(struct cli_state *c)
160 printf("tdis failed (%s)\n", cli_errstr(c));
170 /* check if the server produced the expected error code */
171 static BOOL check_error(struct cli_state *c,
172 uint8 eclass, uint32 ecode, uint32 nterr)
176 (void)cli_error(c, &class, &num, NULL);
177 if ((eclass != class || ecode != num) &&
178 num != (nterr&0xFFFFFF)) {
179 printf("unexpected error code class=%d code=%d\n",
180 (int)class, (int)num);
181 printf(" expected %d/%d %d\n",
182 (int)eclass, (int)ecode, (int)nterr);
189 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
191 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
192 if (!check_error(c, ERRDOS, ERRlock, 0)) return False;
198 static BOOL rw_torture(struct cli_state *c)
200 char *lockfname = "\\torture.lck";
204 pid_t pid2, pid = getpid();
209 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
212 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
214 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
219 for (i=0;i<numops;i++) {
220 unsigned n = (unsigned)sys_random()%10;
222 printf("%d\r", i); fflush(stdout);
224 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
226 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
230 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
232 printf("open failed (%s)\n", cli_errstr(c));
237 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
238 printf("write failed (%s)\n", cli_errstr(c));
243 if (cli_write(c, fnum, 0, (char *)buf,
244 sizeof(pid)+(j*sizeof(buf)),
245 sizeof(buf)) != sizeof(buf)) {
246 printf("write failed (%s)\n", cli_errstr(c));
253 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
254 printf("read failed (%s)\n", cli_errstr(c));
259 printf("data corruption!\n");
263 if (!cli_close(c, fnum)) {
264 printf("close failed (%s)\n", cli_errstr(c));
268 if (!cli_unlink(c, fname)) {
269 printf("unlink failed (%s)\n", cli_errstr(c));
273 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
274 printf("unlock failed (%s)\n", cli_errstr(c));
280 cli_unlink(c, lockfname);
287 static BOOL run_torture(int dummy)
289 struct cli_state cli;
294 cli_sockopt(&cli, sockops);
296 ret = rw_torture(&cli);
298 if (!close_connection(&cli)) {
305 static BOOL rw_torture3(struct cli_state *c, char *lockfname)
312 unsigned countprev = 0;
317 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
319 SIVAL(buf, i, sys_random());
324 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
327 printf("first open read/write of %s failed (%s)\n",
328 lockfname, cli_errstr(c));
334 for (i = 0; i < 500 && fnum == -1; i++)
336 fnum = cli_open(c, lockfname, O_RDONLY,
341 printf("second open read-only of %s failed (%s)\n",
342 lockfname, cli_errstr(c));
348 for (count = 0; count < sizeof(buf); count += sent)
350 if (count >= countprev) {
351 printf("%d %8d\r", i, count);
354 countprev += (sizeof(buf) / 20);
359 sent = ((unsigned)sys_random()%(20))+ 1;
360 if (sent > sizeof(buf) - count)
362 sent = sizeof(buf) - count;
365 if (cli_write(c, fnum, 0, buf+count, count, sent) != sent) {
366 printf("write failed (%s)\n", cli_errstr(c));
372 sent = cli_read(c, fnum, buf_rd+count, count,
376 printf("read failed offset:%d size:%d (%s)\n",
377 count, sizeof(buf)-count,
384 if (memcmp(buf_rd+count, buf+count, sent) != 0)
386 printf("read/write compare failed\n");
387 printf("offset: %d req %d recvd %d\n",
388 count, sizeof(buf)-count, sent);
397 if (!cli_close(c, fnum)) {
398 printf("close failed (%s)\n", cli_errstr(c));
405 static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
407 char *lockfname = "\\torture.lck";
416 if (!cli_unlink(c1, lockfname)) {
417 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
420 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
423 printf("first open read/write of %s failed (%s)\n",
424 lockfname, cli_errstr(c1));
427 fnum2 = cli_open(c2, lockfname, O_RDONLY,
430 printf("second open read-only of %s failed (%s)\n",
431 lockfname, cli_errstr(c2));
432 cli_close(c1, fnum1);
436 for (i=0;i<numops;i++)
438 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
440 printf("%d\r", i); fflush(stdout);
443 generate_random_buffer(buf, buf_size, False);
445 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
446 printf("write failed (%s)\n", cli_errstr(c1));
450 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
451 printf("read failed (%s)\n", cli_errstr(c2));
452 printf("read %d, expected %d\n", bytes_read, buf_size);
456 if (memcmp(buf_rd, buf, buf_size) != 0)
458 printf("read/write compare failed\n");
463 if (!cli_close(c2, fnum2)) {
464 printf("close failed (%s)\n", cli_errstr(c2));
467 if (!cli_close(c1, fnum1)) {
468 printf("close failed (%s)\n", cli_errstr(c1));
472 if (!cli_unlink(c1, lockfname)) {
473 printf("unlink failed (%s)\n", cli_errstr(c1));
480 static BOOL run_readwritetest(int dummy)
482 static struct cli_state cli1, cli2;
485 if (!open_connection(&cli1) || !open_connection(&cli2)) {
488 cli_sockopt(&cli1, sockops);
489 cli_sockopt(&cli2, sockops);
491 printf("starting readwritetest\n");
493 test1 = rw_torture2(&cli1, &cli2);
494 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
496 test2 = rw_torture2(&cli1, &cli1);
497 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
499 if (!close_connection(&cli1)) {
503 if (!close_connection(&cli2)) {
507 return (test1 && test2);
510 static BOOL run_readwritemulti(int dummy)
512 static struct cli_state cli;
517 cli_sockopt(&cli, sockops);
519 printf("run_readwritemulti: fname %s\n", randomfname);
520 test = rw_torture3(&cli, randomfname);
522 if (!close_connection(&cli)) {
529 static BOOL run_readwritelarge(int dummy)
531 static struct cli_state cli1;
533 char *lockfname = "\\large.dat";
538 if (!open_connection(&cli1)) {
541 cli_sockopt(&cli1, sockops);
542 memset(buf,'\0',sizeof(buf));
544 cli1.max_xmit = 0x11000;
546 printf("starting readwritelarge\n");
548 cli_unlink(&cli1, lockfname);
550 fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
552 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
556 cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf));
558 if (!cli_close(&cli1, fnum1)) {
559 printf("close failed (%s)\n", cli_errstr(&cli1));
563 if (!cli_qpathinfo(&cli1, lockfname, NULL, NULL, NULL, &fsize, NULL)) {
564 printf("qpathinfo failed (%s)\n", cli_errstr(&cli1));
568 if (fsize == sizeof(buf))
569 printf("readwritelarge test 1 succeeded (size = %x)\n", fsize);
571 printf("readwritelarge test 1 failed (size = %x)\n", fsize);
575 if (!cli_unlink(&cli1, lockfname)) {
576 printf("unlink failed (%s)\n", cli_errstr(&cli1));
580 fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
582 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
586 cli_smbwrite(&cli1, fnum1, buf, 0, sizeof(buf));
588 if (!cli_close(&cli1, fnum1)) {
589 printf("close failed (%s)\n", cli_errstr(&cli1));
593 if (!close_connection(&cli1)) {
601 /* run a test that simulates an approximate netbench client load */
602 static BOOL run_netbench(int client)
604 struct cli_state cli;
615 cli_sockopt(&cli, sockops);
619 slprintf(cname,sizeof(fname), "CLIENT%d", client);
621 f = fopen("client.txt", "r");
624 perror("client.txt");
628 while (fgets(line, sizeof(line)-1, f)) {
631 line[strlen(line)-1] = 0;
633 /* printf("[%d] %s\n", line_count, line); */
635 all_string_sub(line,"CLIENT1", cname, sizeof(line));
637 for (i=0;i<20;i++) params[i] = "";
639 /* parse the command parameters */
640 params[0] = strtok(line," ");
642 while (params[i]) params[++i] = strtok(NULL," ");
648 if (strcmp(params[1],"REQUEST") == 0) {
649 if (!strcmp(params[0],"SMBopenX")) {
650 fstrcpy(fname, params[5]);
651 } else if (!strcmp(params[0],"SMBclose")) {
652 nb_close(atoi(params[3]));
653 } else if (!strcmp(params[0],"SMBmkdir")) {
655 } else if (!strcmp(params[0],"CREATE")) {
656 nb_create(params[3], atoi(params[5]));
657 } else if (!strcmp(params[0],"SMBrmdir")) {
659 } else if (!strcmp(params[0],"SMBunlink")) {
660 fstrcpy(fname, params[3]);
661 } else if (!strcmp(params[0],"SMBmv")) {
662 nb_rename(params[3], params[5]);
663 } else if (!strcmp(params[0],"SMBgetatr")) {
664 fstrcpy(fname, params[3]);
665 } else if (!strcmp(params[0],"SMBwrite")) {
666 nb_write(atoi(params[3]),
667 atoi(params[5]), atoi(params[7]));
668 } else if (!strcmp(params[0],"SMBwritebraw")) {
669 nb_write(atoi(params[3]),
670 atoi(params[7]), atoi(params[5]));
671 } else if (!strcmp(params[0],"SMBreadbraw")) {
672 nb_read(atoi(params[3]),
673 atoi(params[7]), atoi(params[5]));
674 } else if (!strcmp(params[0],"SMBread")) {
675 nb_read(atoi(params[3]),
676 atoi(params[5]), atoi(params[7]));
679 if (!strcmp(params[0],"SMBopenX")) {
680 if (!strncmp(params[2], "ERR", 3)) continue;
681 nb_open(fname, atoi(params[3]), atoi(params[5]));
682 } else if (!strcmp(params[0],"SMBgetatr")) {
683 if (!strncmp(params[2], "ERR", 3)) continue;
684 nb_stat(fname, atoi(params[3]));
685 } else if (!strcmp(params[0],"SMBunlink")) {
686 if (!strncmp(params[2], "ERR", 3)) continue;
693 slprintf(fname,sizeof(fname), "CLIENTS/CLIENT%d", client);
699 if (!close_connection(&cli)) {
707 /* run a test that simulates an approximate netbench w9X client load */
708 static BOOL run_nbw95(int dummy)
712 t = create_procs(run_netbench, &correct);
713 /* to produce a netbench result we scale accoding to the
714 netbench measured throughput for the run that produced the
715 sniff that was used to produce client.txt. That run used 2
716 clients and ran for 660 seconds to produce a result of
718 printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n",
719 132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t);
723 /* run a test that simulates an approximate netbench wNT client load */
724 static BOOL run_nbwnt(int dummy)
728 t = create_procs(run_netbench, &correct);
729 printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n",
730 132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t);
737 This test checks for two things:
739 1) correct support for retaining locks over a close (ie. the server
740 must not use posix semantics)
741 2) support for lock timeouts
743 static BOOL run_locktest1(int dummy)
745 static struct cli_state cli1, cli2;
746 char *fname = "\\lockt1.lck";
747 int fnum1, fnum2, fnum3;
750 if (!open_connection(&cli1) || !open_connection(&cli2)) {
753 cli_sockopt(&cli1, sockops);
754 cli_sockopt(&cli2, sockops);
756 printf("starting locktest1\n");
758 cli_unlink(&cli1, fname);
760 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
762 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
765 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
767 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
770 fnum3 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
772 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2));
776 if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
777 printf("lock1 failed (%s)\n", cli_errstr(&cli1));
782 if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
783 printf("lock2 succeeded! This is a locking bug\n");
786 if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return False;
790 printf("Testing lock timeouts\n");
792 if (cli_lock(&cli2, fnum3, 0, 4, 10*1000, WRITE_LOCK)) {
793 printf("lock3 succeeded! This is a locking bug\n");
796 if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return False;
801 printf("error: This server appears not to support timed lock requests\n");
804 if (!cli_close(&cli1, fnum2)) {
805 printf("close1 failed (%s)\n", cli_errstr(&cli1));
809 if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
810 printf("lock4 succeeded! This is a locking bug\n");
813 if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return False;
816 if (!cli_close(&cli1, fnum1)) {
817 printf("close2 failed (%s)\n", cli_errstr(&cli1));
821 if (!cli_close(&cli2, fnum3)) {
822 printf("close3 failed (%s)\n", cli_errstr(&cli2));
826 if (!cli_unlink(&cli1, fname)) {
827 printf("unlink failed (%s)\n", cli_errstr(&cli1));
832 if (!close_connection(&cli1)) {
836 if (!close_connection(&cli2)) {
840 printf("Passed locktest1\n");
845 checks for correct tconX support
847 static BOOL run_tcon_test(int dummy)
849 static struct cli_state cli1;
850 char *fname = "\\tcontest.tmp";
855 if (!open_connection(&cli1)) {
858 cli_sockopt(&cli1, sockops);
860 printf("starting tcontest\n");
862 cli_unlink(&cli1, fname);
864 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
867 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
873 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4)
875 printf("write failed (%s)", cli_errstr(&cli1));
879 if (!cli_send_tconX(&cli1, share, "?????",
880 password, strlen(password)+1)) {
881 printf("%s refused 2nd tree connect (%s)\n", host,
887 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) == 4)
889 printf("write succeeded (%s)", cli_errstr(&cli1));
893 if (cli_close(&cli1, fnum1)) {
894 printf("close2 succeeded (%s)\n", cli_errstr(&cli1));
898 if (!cli_tdis(&cli1)) {
899 printf("tdis failed (%s)\n", cli_errstr(&cli1));
905 if (!cli_close(&cli1, fnum1)) {
906 printf("close2 failed (%s)\n", cli_errstr(&cli1));
910 if (!close_connection(&cli1)) {
914 printf("Passed tcontest\n");
920 This test checks that
922 1) the server supports multiple locking contexts on the one SMB
923 connection, distinguished by PID.
925 2) the server correctly fails overlapping locks made by the same PID (this
926 goes against POSIX behaviour, which is why it is tricky to implement)
928 3) the server denies unlock requests by an incorrect client PID
930 static BOOL run_locktest2(int dummy)
932 static struct cli_state cli;
933 char *fname = "\\lockt2.lck";
934 int fnum1, fnum2, fnum3;
937 if (!open_connection(&cli)) {
941 cli_sockopt(&cli, sockops);
943 printf("starting locktest2\n");
945 cli_unlink(&cli, fname);
949 fnum1 = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
951 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
955 fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
957 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli));
963 fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
965 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli));
971 if (!cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
972 printf("lock1 failed (%s)\n", cli_errstr(&cli));
976 if (cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
977 printf("WRITE lock1 succeeded! This is a locking bug\n");
980 if (!check_error(&cli, ERRDOS, ERRlock, 0)) return False;
983 if (cli_lock(&cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
984 printf("WRITE lock2 succeeded! This is a locking bug\n");
987 if (!check_error(&cli, ERRDOS, ERRlock, 0)) return False;
990 if (cli_lock(&cli, fnum2, 0, 4, 0, READ_LOCK)) {
991 printf("READ lock2 succeeded! This is a locking bug\n");
994 if (!check_error(&cli, ERRDOS, ERRlock, 0)) return False;
997 if (!cli_lock(&cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
998 printf("lock at 100 failed (%s)\n", cli_errstr(&cli));
1000 cli_setpid(&cli, 2);
1001 if (cli_unlock(&cli, fnum1, 100, 4)) {
1002 printf("unlock at 100 succeeded! This is a locking bug\n");
1006 if (cli_unlock(&cli, fnum1, 0, 4)) {
1007 printf("unlock1 succeeded! This is a locking bug\n");
1010 if (!check_error(&cli, ERRDOS, ERRnotlocked, 0)) return False;
1013 if (cli_unlock(&cli, fnum1, 0, 8)) {
1014 printf("unlock2 succeeded! This is a locking bug\n");
1017 if (!check_error(&cli, ERRDOS, ERRnotlocked, 0)) return False;
1020 if (cli_lock(&cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1021 printf("lock3 succeeded! This is a locking bug\n");
1024 if (!check_error(&cli, ERRDOS, ERRlock, 0)) return False;
1027 cli_setpid(&cli, 1);
1029 if (!cli_close(&cli, fnum1)) {
1030 printf("close1 failed (%s)\n", cli_errstr(&cli));
1034 if (!cli_close(&cli, fnum2)) {
1035 printf("close2 failed (%s)\n", cli_errstr(&cli));
1039 if (!cli_close(&cli, fnum3)) {
1040 printf("close3 failed (%s)\n", cli_errstr(&cli));
1044 if (!close_connection(&cli)) {
1048 printf("locktest2 finished\n");
1055 This test checks that
1057 1) the server supports the full offset range in lock requests
1059 static BOOL run_locktest3(int dummy)
1061 static struct cli_state cli1, cli2;
1062 char *fname = "\\lockt3.lck";
1063 int fnum1, fnum2, i;
1065 BOOL correct = True;
1067 #define NEXT_OFFSET offset += (~(uint32)0) / numops
1069 if (!open_connection(&cli1) || !open_connection(&cli2)) {
1072 cli_sockopt(&cli1, sockops);
1073 cli_sockopt(&cli2, sockops);
1075 printf("starting locktest3\n");
1077 cli_unlink(&cli1, fname);
1079 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1081 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1084 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1086 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
1090 for (offset=i=0;i<numops;i++) {
1092 if (!cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1093 printf("lock1 %d failed (%s)\n",
1099 if (!cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1100 printf("lock2 %d failed (%s)\n",
1107 for (offset=i=0;i<numops;i++) {
1110 if (cli_lock(&cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1111 printf("error: lock1 %d succeeded!\n", i);
1115 if (cli_lock(&cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1116 printf("error: lock2 %d succeeded!\n", i);
1120 if (cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1121 printf("error: lock3 %d succeeded!\n", i);
1125 if (cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1126 printf("error: lock4 %d succeeded!\n", i);
1131 for (offset=i=0;i<numops;i++) {
1134 if (!cli_unlock(&cli1, fnum1, offset-1, 1)) {
1135 printf("unlock1 %d failed (%s)\n",
1141 if (!cli_unlock(&cli2, fnum2, offset-2, 1)) {
1142 printf("unlock2 %d failed (%s)\n",
1149 if (!cli_close(&cli1, fnum1)) {
1150 printf("close1 failed (%s)\n", cli_errstr(&cli1));
1154 if (!cli_close(&cli2, fnum2)) {
1155 printf("close2 failed (%s)\n", cli_errstr(&cli2));
1159 if (!cli_unlink(&cli1, fname)) {
1160 printf("unlink failed (%s)\n", cli_errstr(&cli1));
1164 if (!close_connection(&cli1)) {
1168 if (!close_connection(&cli2)) {
1172 printf("finished locktest3\n");
1177 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1178 printf("** "); correct = False; \
1182 looks at overlapping locks
1184 static BOOL run_locktest4(int dummy)
1186 static struct cli_state cli1, cli2;
1187 char *fname = "\\lockt4.lck";
1188 int fnum1, fnum2, f;
1191 BOOL correct = True;
1193 if (!open_connection(&cli1) || !open_connection(&cli2)) {
1197 cli_sockopt(&cli1, sockops);
1198 cli_sockopt(&cli2, sockops);
1200 printf("starting locktest4\n");
1202 cli_unlink(&cli1, fname);
1204 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1205 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1207 memset(buf, 0, sizeof(buf));
1209 if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1210 printf("Failed to create file\n");
1215 ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1216 cli_lock(&cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1217 EXPECTED(ret, False);
1218 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1220 ret = cli_lock(&cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1221 cli_lock(&cli1, fnum1, 12, 4, 0, READ_LOCK);
1222 EXPECTED(ret, True);
1223 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1225 ret = cli_lock(&cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1226 cli_lock(&cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1227 EXPECTED(ret, False);
1228 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1230 ret = cli_lock(&cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1231 cli_lock(&cli2, fnum2, 32, 4, 0, READ_LOCK);
1232 EXPECTED(ret, True);
1233 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1235 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1236 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1237 EXPECTED(ret, False);
1238 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1240 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1241 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 52, 4, 0, READ_LOCK));
1242 EXPECTED(ret, True);
1243 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1245 ret = cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1246 cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK);
1247 EXPECTED(ret, True);
1248 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1250 ret = cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1251 cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1252 EXPECTED(ret, False);
1253 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1255 ret = cli_lock(&cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1256 cli_lock(&cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1257 EXPECTED(ret, False);
1258 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1260 ret = cli_lock(&cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1261 cli_lock(&cli1, fnum1, 90, 4, 0, READ_LOCK);
1262 EXPECTED(ret, True);
1263 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1265 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1266 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 100, 4, 0, READ_LOCK));
1267 EXPECTED(ret, False);
1268 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1270 ret = cli_lock(&cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1271 cli_lock(&cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1272 cli_unlock(&cli1, fnum1, 110, 6);
1273 EXPECTED(ret, False);
1274 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1277 ret = cli_lock(&cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1278 (cli_read(&cli2, fnum2, buf, 120, 4) == 4);
1279 EXPECTED(ret, False);
1280 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1282 ret = cli_lock(&cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1283 (cli_write(&cli2, fnum2, 0, buf, 130, 4) == 4);
1284 EXPECTED(ret, False);
1285 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1288 ret = cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1289 cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1290 cli_unlock(&cli1, fnum1, 140, 4) &&
1291 cli_unlock(&cli1, fnum1, 140, 4);
1292 EXPECTED(ret, True);
1293 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1296 ret = cli_lock(&cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1297 cli_lock(&cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1298 cli_unlock(&cli1, fnum1, 150, 4) &&
1299 (cli_read(&cli2, fnum2, buf, 150, 4) == 4) &&
1300 !(cli_write(&cli2, fnum2, 0, buf, 150, 4) == 4) &&
1301 cli_unlock(&cli1, fnum1, 150, 4);
1302 EXPECTED(ret, True);
1303 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1305 ret = cli_lock(&cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1306 cli_unlock(&cli1, fnum1, 160, 4) &&
1307 (cli_write(&cli2, fnum2, 0, buf, 160, 4) == 4) &&
1308 (cli_read(&cli2, fnum2, buf, 160, 4) == 4);
1309 EXPECTED(ret, True);
1310 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1312 ret = cli_lock(&cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1313 cli_unlock(&cli1, fnum1, 170, 4) &&
1314 (cli_write(&cli2, fnum2, 0, buf, 170, 4) == 4) &&
1315 (cli_read(&cli2, fnum2, buf, 170, 4) == 4);
1316 EXPECTED(ret, True);
1317 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1319 ret = cli_lock(&cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1320 cli_lock(&cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1321 cli_unlock(&cli1, fnum1, 190, 4) &&
1322 !(cli_write(&cli2, fnum2, 0, buf, 190, 4) == 4) &&
1323 (cli_read(&cli2, fnum2, buf, 190, 4) == 4);
1324 EXPECTED(ret, True);
1325 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1327 cli_close(&cli1, fnum1);
1328 cli_close(&cli2, fnum2);
1329 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1330 f = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1331 ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1332 cli_lock(&cli1, f, 0, 1, 0, READ_LOCK) &&
1333 cli_close(&cli1, fnum1) &&
1334 ((fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1335 cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1336 cli_close(&cli1, f);
1337 EXPECTED(ret, True);
1338 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1341 cli_close(&cli1, fnum1);
1342 cli_close(&cli2, fnum2);
1343 cli_unlink(&cli1, fname);
1344 close_connection(&cli1);
1345 close_connection(&cli2);
1347 printf("finished locktest4\n");
1352 looks at lock upgrade/downgrade.
1354 static BOOL run_locktest5(int dummy)
1356 static struct cli_state cli1, cli2;
1357 char *fname = "\\lockt5.lck";
1358 int fnum1, fnum2, fnum3;
1361 BOOL correct = True;
1363 if (!open_connection(&cli1) || !open_connection(&cli2)) {
1367 cli_sockopt(&cli1, sockops);
1368 cli_sockopt(&cli2, sockops);
1370 printf("starting locktest5\n");
1372 cli_unlink(&cli1, fname);
1374 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1375 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1376 fnum3 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1378 memset(buf, 0, sizeof(buf));
1380 if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1381 printf("Failed to create file\n");
1386 /* Check for NT bug... */
1387 ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1388 cli_lock(&cli1, fnum3, 0, 1, 0, READ_LOCK);
1389 cli_close(&cli1, fnum1);
1390 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1391 ret = cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1392 EXPECTED(ret, True);
1393 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1394 cli_close(&cli1, fnum1);
1395 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1396 cli_unlock(&cli1, fnum3, 0, 1);
1398 ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1399 cli_lock(&cli1, fnum1, 1, 1, 0, READ_LOCK);
1400 EXPECTED(ret, True);
1401 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1403 ret = cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1404 EXPECTED(ret, False);
1406 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1408 /* Unlock the process 2 lock. */
1409 cli_unlock(&cli2, fnum2, 0, 4);
1411 ret = cli_lock(&cli1, fnum3, 0, 4, 0, READ_LOCK);
1412 EXPECTED(ret, False);
1414 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1416 /* Unlock the process 1 fnum3 lock. */
1417 cli_unlock(&cli1, fnum3, 0, 4);
1419 /* Stack 2 more locks here. */
1420 ret = cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1421 cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK);
1423 EXPECTED(ret, True);
1424 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1426 /* Unlock the first process lock, then check this was the WRITE lock that was
1429 ret = cli_unlock(&cli1, fnum1, 0, 4) &&
1430 cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1432 EXPECTED(ret, True);
1433 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1435 /* Unlock the process 2 lock. */
1436 cli_unlock(&cli2, fnum2, 0, 4);
1438 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1440 ret = cli_unlock(&cli1, fnum1, 1, 1) &&
1441 cli_unlock(&cli1, fnum1, 0, 4) &&
1442 cli_unlock(&cli1, fnum1, 0, 4);
1444 EXPECTED(ret, True);
1445 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1447 /* Ensure the next unlock fails. */
1448 ret = cli_unlock(&cli1, fnum1, 0, 4);
1449 EXPECTED(ret, False);
1450 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1452 /* Ensure connection 2 can get a write lock. */
1453 ret = cli_lock(&cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1454 EXPECTED(ret, True);
1456 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1460 cli_close(&cli1, fnum1);
1461 cli_close(&cli2, fnum2);
1462 cli_unlink(&cli1, fname);
1463 if (!close_connection(&cli1)) {
1466 if (!close_connection(&cli2)) {
1470 printf("finished locktest5\n");
1477 this produces a matrix of deny mode behaviour
1479 static BOOL run_denytest1(int dummy)
1481 static struct cli_state cli1, cli2;
1483 int f, d1, d2, o1, o2, x=0;
1484 char *fnames[] = {"\\denytest1.exe", "\\denytest1.dat", NULL};
1489 {DENY_DOS, "DENY_DOS"},
1490 {DENY_ALL, "DENY_ALL"},
1491 {DENY_WRITE, "DENY_WRITE"},
1492 {DENY_READ, "DENY_READ"},
1493 {DENY_NONE, "DENY_NONE"},
1494 {DENY_FCB, "DENY_FCB"},
1501 {O_RDONLY, "O_RDONLY"},
1502 {O_WRONLY, "O_WRONLY"},
1504 BOOL correct = True;
1506 if (!open_connection(&cli1) || !open_connection(&cli2)) {
1509 cli_sockopt(&cli1, sockops);
1510 cli_sockopt(&cli2, sockops);
1512 printf("starting denytest1\n");
1514 for (f=0;fnames[f];f++) {
1515 cli_unlink(&cli1, fnames[f]);
1517 fnum1 = cli_open(&cli1, fnames[f], O_RDWR|O_CREAT, DENY_NONE);
1518 cli_write(&cli1, fnum1, 0, fnames[f], 0, strlen(fnames[f]));
1519 cli_close(&cli1, fnum1);
1521 for (d1=0;deny_modes[d1].name;d1++)
1522 for (o1=0;open_modes[o1].name;o1++)
1523 for (d2=0;deny_modes[d2].name;d2++)
1524 for (o2=0;open_modes[o2].name;o2++) {
1525 fnum1 = cli_open(&cli1, fnames[f],
1528 fnum2 = cli_open(&cli2, fnames[f],
1532 printf("%s %8s %10s %8s %10s ",
1534 open_modes[o1].name,
1535 deny_modes[d1].name,
1536 open_modes[o2].name,
1537 deny_modes[d2].name);
1541 } else if (fnum2 == -1) {
1544 if (cli_read(&cli2, fnum2, (void *)&x, 0, 1) == 1) {
1547 if (cli_write(&cli2, fnum2, 0, (void *)&x, 0, 1) == 1) {
1553 cli_close(&cli1, fnum1);
1554 cli_close(&cli2, fnum2);
1557 cli_unlink(&cli1, fnames[f]);
1560 if (!close_connection(&cli1)) {
1563 if (!close_connection(&cli2)) {
1567 printf("finshed denytest1\n");
1573 this produces a matrix of deny mode behaviour for two opens on the
1576 static BOOL run_denytest2(int dummy)
1578 static struct cli_state cli1;
1580 int f, d1, d2, o1, o2, x=0;
1581 char *fnames[] = {"\\denytest2.exe", "\\denytest2.dat", NULL};
1586 {DENY_DOS, "DENY_DOS"},
1587 {DENY_ALL, "DENY_ALL"},
1588 {DENY_WRITE, "DENY_WRITE"},
1589 {DENY_READ, "DENY_READ"},
1590 {DENY_NONE, "DENY_NONE"},
1591 {DENY_FCB, "DENY_FCB"},
1598 {O_RDONLY, "O_RDONLY"},
1599 {O_WRONLY, "O_WRONLY"},
1601 BOOL correct = True;
1603 if (!open_connection(&cli1)) {
1606 cli_sockopt(&cli1, sockops);
1608 printf("starting denytest2\n");
1610 for (f=0;fnames[f];f++) {
1611 cli_unlink(&cli1, fnames[f]);
1613 fnum1 = cli_open(&cli1, fnames[f], O_RDWR|O_CREAT, DENY_NONE);
1614 cli_write(&cli1, fnum1, 0, fnames[f], 0, strlen(fnames[f]));
1615 cli_close(&cli1, fnum1);
1617 for (d1=0;deny_modes[d1].name;d1++)
1618 for (o1=0;open_modes[o1].name;o1++)
1619 for (d2=0;deny_modes[d2].name;d2++)
1620 for (o2=0;open_modes[o2].name;o2++) {
1621 fnum1 = cli_open(&cli1, fnames[f],
1624 fnum2 = cli_open(&cli1, fnames[f],
1628 printf("%s %8s %10s %8s %10s ",
1630 open_modes[o1].name,
1631 deny_modes[d1].name,
1632 open_modes[o2].name,
1633 deny_modes[d2].name);
1637 } else if (fnum2 == -1) {
1640 if (cli_read(&cli1, fnum2, (void *)&x, 0, 1) == 1) {
1643 if (cli_write(&cli1, fnum2, 0, (void *)&x, 0, 1) == 1) {
1649 cli_close(&cli1, fnum1);
1650 cli_close(&cli1, fnum2);
1653 cli_unlink(&cli1, fnames[f]);
1656 if (!close_connection(&cli1)) {
1660 printf("finshed denytest2\n");
1665 test whether fnums and tids open on one VC are available on another (a major
1668 static BOOL run_fdpasstest(int dummy)
1670 static struct cli_state cli1, cli2, cli3;
1671 char *fname = "\\fdpass.tst";
1675 if (!open_connection(&cli1) || !open_connection(&cli2)) {
1678 cli_sockopt(&cli1, sockops);
1679 cli_sockopt(&cli2, sockops);
1681 printf("starting fdpasstest\n");
1683 cli_unlink(&cli1, fname);
1685 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1687 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1691 if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
1692 printf("write failed (%s)\n", cli_errstr(&cli1));
1697 cli3.vuid = cli1.vuid;
1698 cli3.cnum = cli1.cnum;
1699 cli3.pid = cli1.pid;
1701 if (cli_read(&cli3, fnum1, buf, 0, 13) == 13) {
1702 printf("read succeeded! nasty security hole [%s]\n",
1707 cli_close(&cli1, fnum1);
1708 cli_unlink(&cli1, fname);
1710 close_connection(&cli1);
1711 close_connection(&cli2);
1713 printf("finished fdpasstest\n");
1719 This test checks that
1721 1) the server does not allow an unlink on a file that is open
1723 static BOOL run_unlinktest(int dummy)
1725 static struct cli_state cli;
1726 char *fname = "\\unlink.tst";
1728 BOOL correct = True;
1730 if (!open_connection(&cli)) {
1734 cli_sockopt(&cli, sockops);
1736 printf("starting unlink test\n");
1738 cli_unlink(&cli, fname);
1740 cli_setpid(&cli, 1);
1742 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1744 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1748 if (cli_unlink(&cli, fname)) {
1749 printf("error: server allowed unlink on an open file\n");
1753 cli_close(&cli, fnum);
1754 cli_unlink(&cli, fname);
1756 if (!close_connection(&cli)) {
1760 printf("unlink test finished\n");
1767 test how many open files this server supports on the one socket
1769 static BOOL run_maxfidtest(int dummy)
1771 static struct cli_state cli;
1772 char *template = "\\maxfid.%d.%d";
1776 BOOL correct = True;
1781 printf("failed to connect\n");
1785 cli_sockopt(&cli, sockops);
1789 slprintf(fname,sizeof(fname)-1,template, fnum,(int)getpid());
1790 if (cli_open(&cli, fname,
1791 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE) ==
1793 printf("open of %s failed (%s)\n",
1794 fname, cli_errstr(&cli));
1795 printf("maximum fnum is %d\n", fnum);
1799 if (fnum % 100 == 0) printf("%d\r", fnum);
1801 printf("%d\n", fnum);
1803 printf("cleaning up\n");
1806 slprintf(fname,sizeof(fname)-1,template, fnum,(int)getpid());
1807 cli_close(&cli, fnum);
1808 if (!cli_unlink(&cli, fname)) {
1809 printf("unlink of %s failed (%s)\n",
1810 fname, cli_errstr(&cli));
1815 printf("maxfid test finished\n");
1816 if (!close_connection(&cli)) {
1822 /* generate a random buffer */
1823 static void rand_buf(char *buf, int len)
1826 *buf = (char)sys_random();
1831 /* send smb negprot commands, not reading the response */
1832 static BOOL run_negprot_nowait(int dummy)
1835 static struct cli_state cli;
1836 BOOL correct = True;
1838 printf("starting negprot nowait test\n");
1840 if (!open_nbt_connection(&cli)) {
1844 for (i=0;i<50000;i++) {
1845 cli_negprot_send(&cli);
1848 if (!close_connection(&cli)) {
1852 printf("finished negprot nowait test\n");
1858 /* send random IPC commands */
1859 static BOOL run_randomipc(int dummy)
1861 char *rparam = NULL;
1865 int api, param_len, i;
1866 static struct cli_state cli;
1867 BOOL correct = True;
1869 printf("starting random ipc test\n");
1871 if (!open_connection(&cli)) {
1875 for (i=0;i<50000;i++) {
1876 api = sys_random() % 500;
1877 param_len = (sys_random() % 64);
1879 rand_buf(param, param_len);
1884 param, param_len, 8,
1885 NULL, 0, BUFFER_SIZE,
1890 if (!close_connection(&cli)) {
1894 printf("finished random ipc test\n");
1901 static void browse_callback(const char *sname, uint32 stype,
1902 const char *comment, void *state)
1904 printf("\t%20.20s %08x %s\n", sname, stype, comment);
1910 This test checks the browse list code
1913 static BOOL run_browsetest(int dummy)
1915 static struct cli_state cli;
1916 BOOL correct = True;
1918 printf("starting browse test\n");
1920 if (!open_connection(&cli)) {
1924 printf("domain list:\n");
1925 cli_NetServerEnum(&cli, cli.server_domain,
1926 SV_TYPE_DOMAIN_ENUM,
1927 browse_callback, NULL);
1929 printf("machine list:\n");
1930 cli_NetServerEnum(&cli, cli.server_domain,
1932 browse_callback, NULL);
1934 if (!close_connection(&cli)) {
1938 printf("browse test finished\n");
1946 This checks how the getatr calls works
1948 static BOOL run_attrtest(int dummy)
1950 static struct cli_state cli;
1953 char *fname = "\\attrib.tst";
1954 BOOL correct = True;
1956 printf("starting attrib test\n");
1958 if (!open_connection(&cli)) {
1962 cli_unlink(&cli, fname);
1963 fnum = cli_open(&cli, fname,
1964 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1965 cli_close(&cli, fnum);
1966 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1967 printf("getatr failed (%s)\n", cli_errstr(&cli));
1971 if (abs(t - time(NULL)) > 2) {
1972 printf("ERROR: SMBgetatr bug. time is %s",
1978 t2 = t-60*60*24; /* 1 day ago */
1980 if (!cli_setatr(&cli, fname, 0, t2)) {
1981 printf("setatr failed (%s)\n", cli_errstr(&cli));
1985 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1986 printf("getatr failed (%s)\n", cli_errstr(&cli));
1991 printf("ERROR: getatr/setatr bug. times are\n%s",
1993 printf("%s", ctime(&t2));
1997 cli_unlink(&cli, fname);
1999 if (!close_connection(&cli)) {
2003 printf("attrib test finished\n");
2010 This checks a couple of trans2 calls
2012 static BOOL run_trans2test(int dummy)
2014 static struct cli_state cli;
2017 time_t c_time, a_time, m_time, w_time, m_time2;
2018 char *fname = "\\trans2.tst";
2019 char *dname = "\\trans2";
2020 char *fname2 = "\\trans2\\trans2.tst";
2021 BOOL correct = True;
2023 printf("starting trans2 test\n");
2025 if (!open_connection(&cli)) {
2029 cli_unlink(&cli, fname);
2030 fnum = cli_open(&cli, fname,
2031 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2032 if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
2034 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
2037 cli_close(&cli, fnum);
2041 cli_unlink(&cli, fname);
2042 fnum = cli_open(&cli, fname,
2043 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2044 cli_close(&cli, fnum);
2046 if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2047 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
2050 if (c_time != m_time) {
2051 printf("create time=%s", ctime(&c_time));
2052 printf("modify time=%s", ctime(&m_time));
2053 printf("This system appears to have sticky create times\n");
2056 if (a_time % (60*60) == 0) {
2057 printf("access time=%s", ctime(&a_time));
2058 printf("This system appears to set a midnight access time\n");
2062 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2063 printf("ERROR: totally incorrect times - maybe word reversed?\n");
2069 cli_unlink(&cli, fname);
2070 fnum = cli_open(&cli, fname,
2071 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2072 cli_close(&cli, fnum);
2073 if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time,
2074 &w_time, &size, NULL, NULL)) {
2075 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2078 if (w_time < 60*60*24*2) {
2079 printf("write time=%s", ctime(&w_time));
2080 printf("This system appears to set a initial 0 write time\n");
2085 cli_unlink(&cli, fname);
2088 /* check if the server updates the directory modification time
2089 when creating a new file */
2090 if (!cli_mkdir(&cli, dname)) {
2091 printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
2095 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time,
2096 &w_time, &size, NULL, NULL)) {
2097 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2101 fnum = cli_open(&cli, fname2,
2102 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2103 cli_write(&cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2104 cli_close(&cli, fnum);
2105 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2,
2106 &w_time, &size, NULL, NULL)) {
2107 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2110 if (m_time2 == m_time) {
2111 printf("This system does not update directory modification times\n");
2115 cli_unlink(&cli, fname2);
2116 cli_rmdir(&cli, dname);
2118 if (!close_connection(&cli)) {
2122 printf("trans2 test finished\n");
2128 This checks new W2K calls.
2131 static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
2134 BOOL correct = True;
2136 memset(buf, 0xff, sizeof(buf));
2138 if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
2139 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2142 printf("qfileinfo: level %d\n", level);
2143 dump_data(0, buf, 256);
2149 static BOOL run_w2ktest(int dummy)
2151 static struct cli_state cli;
2153 char *fname = "\\w2ktest\\w2k.tst";
2155 BOOL correct = True;
2157 printf("starting w2k test\n");
2159 if (!open_connection(&cli)) {
2163 fnum = cli_open(&cli, fname,
2164 O_RDWR | O_CREAT , DENY_NONE);
2166 for (level = 1004; level < 1040; level++) {
2167 if (!new_trans(&cli, fnum, level)) {
2172 cli_close(&cli, fnum);
2174 if (!close_connection(&cli)) {
2178 printf("w2k test finished\n");
2185 this is a harness for some oplock tests
2187 static BOOL run_oplock1(int dummy)
2189 static struct cli_state cli1;
2190 char *fname = "\\lockt1.lck";
2192 BOOL correct = True;
2194 printf("starting oplock test 1\n");
2196 if (!open_connection(&cli1)) {
2200 cli_unlink(&cli1, fname);
2202 cli_sockopt(&cli1, sockops);
2204 cli1.use_oplocks = True;
2206 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2208 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2212 cli1.use_oplocks = False;
2214 cli_unlink(&cli1, fname);
2215 cli_unlink(&cli1, fname);
2217 if (!cli_close(&cli1, fnum1)) {
2218 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2222 if (!cli_unlink(&cli1, fname)) {
2223 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2227 if (!close_connection(&cli1)) {
2231 printf("finished oplock test 1\n");
2236 static BOOL run_oplock2(int dummy)
2238 static struct cli_state cli1, cli2;
2239 char *fname = "\\lockt2.lck";
2241 int saved_use_oplocks = use_oplocks;
2243 BOOL correct = True;
2244 volatile BOOL *shared_correct;
2246 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2247 *shared_correct = True;
2249 use_level_II_oplocks = True;
2252 printf("starting oplock test 2\n");
2254 if (!open_connection(&cli1)) {
2255 use_level_II_oplocks = False;
2256 use_oplocks = saved_use_oplocks;
2260 cli1.use_oplocks = True;
2261 cli1.use_level_II_oplocks = True;
2263 if (!open_connection(&cli2)) {
2264 use_level_II_oplocks = False;
2265 use_oplocks = saved_use_oplocks;
2269 cli2.use_oplocks = True;
2270 cli2.use_level_II_oplocks = True;
2272 cli_unlink(&cli1, fname);
2274 cli_sockopt(&cli1, sockops);
2275 cli_sockopt(&cli2, sockops);
2277 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2279 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2283 /* Don't need the globals any more. */
2284 use_level_II_oplocks = False;
2285 use_oplocks = saved_use_oplocks;
2289 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
2291 printf("second open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2292 *shared_correct = False;
2298 if (!cli_close(&cli2, fnum2)) {
2299 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2300 *shared_correct = False;
2308 /* Ensure cli1 processes the break. */
2310 if (cli_read(&cli1, fnum1, buf, 0, 4) != 4) {
2311 printf("read on fnum1 failed (%s)\n", cli_errstr(&cli1));
2315 /* Should now be at level II. */
2316 /* Test if sending a write locks causes a break to none. */
2318 if (!cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2319 printf("lock failed (%s)\n", cli_errstr(&cli1));
2323 cli_unlock(&cli1, fnum1, 0, 4);
2327 if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2328 printf("lock failed (%s)\n", cli_errstr(&cli1));
2332 cli_unlock(&cli1, fnum1, 0, 4);
2336 cli_read(&cli1, fnum1, buf, 0, 4);
2339 if (cli_write(&cli1, fnum1, 0, buf, 0, 4) != 4) {
2340 printf("write on fnum1 failed (%s)\n", cli_errstr(&cli1));
2345 if (!cli_close(&cli1, fnum1)) {
2346 printf("close1 failed (%s)\n", cli_errstr(&cli1));
2352 if (!cli_unlink(&cli1, fname)) {
2353 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2357 if (!close_connection(&cli1)) {
2361 if (!*shared_correct) {
2365 printf("finished oplock test 2\n");
2370 /* handler for oplock 3 tests */
2371 static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2373 printf("got oplock break fnum=%d level=%d\n",
2375 return cli_oplock_ack(cli, fnum, level);
2378 static BOOL run_oplock3(int dummy)
2380 static struct cli_state cli;
2381 char *fname = "\\oplockt3.dat";
2383 char buf[4] = "abcd";
2384 BOOL correct = True;
2385 volatile BOOL *shared_correct;
2387 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2388 *shared_correct = True;
2390 printf("starting oplock test 3\n");
2395 use_level_II_oplocks = True;
2396 if (!open_connection(&cli)) {
2397 *shared_correct = False;
2401 /* try to trigger a oplock break in parent */
2402 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2403 cli_write(&cli, fnum, 0, buf, 0, 4);
2409 use_level_II_oplocks = True;
2410 if (!open_connection(&cli)) {
2413 cli_oplock_handler(&cli, oplock3_handler);
2414 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2415 cli_write(&cli, fnum, 0, buf, 0, 4);
2416 cli_close(&cli, fnum);
2417 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2418 cli.timeout = 20000;
2419 cli_receive_smb(&cli);
2420 printf("finished oplock test 3\n");
2422 return (correct && *shared_correct);
2424 /* What are we looking for here? What's sucess and what's FAILURE? */
2430 Test delete on close semantics.
2432 static BOOL run_deletetest(int dummy)
2434 static struct cli_state cli1;
2435 static struct cli_state cli2;
2436 char *fname = "\\delete.file";
2438 BOOL correct = True;
2440 printf("starting delete test\n");
2442 if (!open_connection(&cli1)) {
2446 cli_sockopt(&cli1, sockops);
2448 /* Test 1 - this should *NOT* delete the file on close. */
2450 cli_setatr(&cli1, fname, 0, 0);
2451 cli_unlink(&cli1, fname);
2453 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2454 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, DELETE_ON_CLOSE_FLAG);
2457 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2461 if (!cli_close(&cli1, fnum1)) {
2462 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2466 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
2468 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2472 if (!cli_close(&cli1, fnum1)) {
2473 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2477 printf("first delete on close test succeeded.\n");
2479 /* Test 2 - this should delete the file on close. */
2481 cli_setatr(&cli1, fname, 0, 0);
2482 cli_unlink(&cli1, fname);
2484 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS,
2485 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
2488 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2492 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2493 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2497 if (!cli_close(&cli1, fnum1)) {
2498 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2502 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2504 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2505 if (!cli_close(&cli1, fnum1)) {
2506 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2509 cli_unlink(&cli1, fname);
2511 printf("second delete on close test succeeded.\n");
2515 cli_setatr(&cli1, fname, 0, 0);
2516 cli_unlink(&cli1, fname);
2518 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2519 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2522 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2526 /* This should fail with a sharing violation - open for delete is only compatible
2527 with SHARE_DELETE. */
2529 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2530 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0);
2533 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2537 /* This should succeed. */
2539 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2540 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2543 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2547 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2548 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2552 if (!cli_close(&cli1, fnum1)) {
2553 printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1));
2557 if (!cli_close(&cli1, fnum2)) {
2558 printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1));
2562 /* This should fail - file should no longer be there. */
2564 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2566 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2567 if (!cli_close(&cli1, fnum1)) {
2568 printf("[3] close failed (%s)\n", cli_errstr(&cli1));
2570 cli_unlink(&cli1, fname);
2573 printf("third delete on close test succeeded.\n");
2576 cli_setatr(&cli1, fname, 0, 0);
2577 cli_unlink(&cli1, fname);
2579 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2580 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2583 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2587 /* This should succeed. */
2588 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2589 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2591 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2595 if (!cli_close(&cli1, fnum2)) {
2596 printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1));
2600 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2601 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2605 /* This should fail - no more opens once delete on close set. */
2606 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2607 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2609 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2612 printf("fourth delete on close test succeeded.\n");
2614 if (!cli_close(&cli1, fnum1)) {
2615 printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1));
2620 cli_setatr(&cli1, fname, 0, 0);
2621 cli_unlink(&cli1, fname);
2623 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
2625 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2629 /* This should fail - only allowed on NT opens with DELETE access. */
2631 if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2632 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2636 if (!cli_close(&cli1, fnum1)) {
2637 printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1));
2641 printf("fifth delete on close test succeeded.\n");
2644 cli_setatr(&cli1, fname, 0, 0);
2645 cli_unlink(&cli1, fname);
2647 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2648 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2649 FILE_OVERWRITE_IF, 0);
2652 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2656 /* This should fail - only allowed on NT opens with DELETE access. */
2658 if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2659 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2663 if (!cli_close(&cli1, fnum1)) {
2664 printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1));
2668 printf("sixth delete on close test succeeded.\n");
2671 cli_setatr(&cli1, fname, 0, 0);
2672 cli_unlink(&cli1, fname);
2674 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2675 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0);
2678 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2682 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2683 printf("[7] setting delete_on_close on file failed !\n");
2687 if (!cli_nt_delete_on_close(&cli1, fnum1, False)) {
2688 printf("[7] unsetting delete_on_close on file failed !\n");
2692 if (!cli_close(&cli1, fnum1)) {
2693 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2697 /* This next open should succeed - we reset the flag. */
2699 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2701 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2705 if (!cli_close(&cli1, fnum1)) {
2706 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2710 printf("seventh delete on close test succeeded.\n");
2713 cli_setatr(&cli1, fname, 0, 0);
2714 cli_unlink(&cli1, fname);
2716 if (!open_connection(&cli2)) {
2717 printf("[8] failed to open second connection.\n");
2721 cli_sockopt(&cli1, sockops);
2723 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2724 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
2727 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2731 fnum2 = cli_nt_create_full(&cli2, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2732 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2735 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2739 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2740 printf("[8] setting delete_on_close on file failed !\n");
2744 if (!cli_close(&cli1, fnum1)) {
2745 printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1));
2749 if (!cli_close(&cli2, fnum2)) {
2750 printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2));
2754 /* This should fail.. */
2755 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2757 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2758 if (!cli_close(&cli1, fnum1)) {
2759 printf("[8] close failed (%s)\n", cli_errstr(&cli1));
2761 cli_unlink(&cli1, fname);
2764 printf("eighth delete on close test succeeded.\n");
2766 printf("finished delete test\n");
2768 cli_setatr(&cli1, fname, 0, 0);
2769 cli_unlink(&cli1, fname);
2771 if (!close_connection(&cli1)) {
2774 if (!close_connection(&cli2)) {
2781 Test open mode returns on read-only files.
2783 static BOOL run_opentest(int dummy)
2785 static struct cli_state cli1;
2786 char *fname = "\\readonly.file";
2792 BOOL correct = True;
2794 printf("starting open test\n");
2796 if (!open_connection(&cli1)) {
2800 cli_setatr(&cli1, fname, 0, 0);
2801 cli_unlink(&cli1, fname);
2803 cli_sockopt(&cli1, sockops);
2805 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2807 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2811 if (!cli_close(&cli1, fnum1)) {
2812 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2816 if (!cli_setatr(&cli1, fname, aRONLY, 0)) {
2817 printf("cli_setatr failed (%s)\n", cli_errstr(&cli1));
2821 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
2823 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2827 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
2828 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
2830 cli_error( &cli1, &eclass, &errnum, NULL);
2832 if (eclass != ERRDOS || errnum != ERRnoaccess) {
2833 printf("wrong error code (%x,%x) = %s\n", (unsigned int)eclass,
2834 (unsigned int)errnum, cli_errstr(&cli1) );
2837 printf("correct error code ERRDOS/ERRnoaccess returned\n");
2841 printf("finished open test 1\n");
2843 cli_close(&cli1, fnum1);
2845 /* Now try not readonly and ensure ERRbadshare is returned. */
2847 cli_setatr(&cli1, fname, 0, 0);
2849 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
2851 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2855 /* This will fail - but the error should be ERRshare. */
2856 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
2858 cli_error( &cli1, &eclass, &errnum, NULL);
2860 if (eclass != ERRDOS || errnum != ERRbadshare) {
2861 printf("wrong error code (%x,%x) = %s\n", (unsigned int)eclass,
2862 (unsigned int)errnum, cli_errstr(&cli1) );
2865 printf("correct error code ERRDOS/ERRbadshare returned\n");
2868 if (!cli_close(&cli1, fnum1)) {
2869 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2873 cli_unlink(&cli1, fname);
2875 printf("finished open test 2\n");
2877 /* Test truncate open disposition on file opened for read. */
2879 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2881 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(&cli1));
2885 /* write 20 bytes. */
2887 memset(buf, '\0', 20);
2889 if (cli_write(&cli1, fnum1, 0, buf, 0, 20) != 20) {
2890 printf("write failed (%s)\n", cli_errstr(&cli1));
2894 if (!cli_close(&cli1, fnum1)) {
2895 printf("(3) close1 failed (%s)\n", cli_errstr(&cli1));
2899 /* Ensure size == 20. */
2900 if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
2901 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
2906 printf("(3) file size != 20\n");
2910 /* Now test if we can truncate a file opened for readonly. */
2912 fnum1 = cli_open(&cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
2914 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(&cli1));
2918 if (!cli_close(&cli1, fnum1)) {
2919 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2923 /* Ensure size == 0. */
2924 if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
2925 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
2930 printf("(3) file size != 0\n");
2933 printf("finished open test 3\n");
2935 cli_unlink(&cli1, fname);
2938 printf("testing ctemp\n");
2941 fnum1 = cli_ctemp(&cli1, "\\", &tmp_path);
2943 printf("ctemp failed (%s)\n", cli_errstr(&cli1));
2946 printf("ctemp gave path %s\n", tmp_path);
2947 cli_close(&cli1, fnum1);
2948 cli_unlink(&cli1, tmp_path);
2951 if (!close_connection(&cli1)) {
2958 static void list_fn(file_info *finfo, const char *name, void *state)
2964 test directory listing speed
2966 static BOOL run_dirtest(int dummy)
2969 static struct cli_state cli;
2972 BOOL correct = True;
2974 printf("starting directory test\n");
2976 if (!open_connection(&cli)) {
2980 cli_sockopt(&cli, sockops);
2983 for (i=0;i<numops;i++) {
2985 slprintf(fname, sizeof(fname), "%x", (int)random());
2986 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2988 fprintf(stderr,"Failed to open %s\n", fname);
2991 cli_close(&cli, fnum);
2996 printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
2997 printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
2998 printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
3000 printf("dirtest core %g seconds\n", end_timer() - t1);
3003 for (i=0;i<numops;i++) {
3005 slprintf(fname, sizeof(fname), "%x", (int)random());
3006 cli_unlink(&cli, fname);
3009 if (!close_connection(&cli)) {
3013 printf("finished dirtest\n");
3020 static double create_procs(BOOL (*fn)(int), BOOL *result)
3023 volatile pid_t *child_status;
3024 volatile BOOL *child_status_out;
3030 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
3031 if (!child_status) {
3032 printf("Failed to setup shared memory\n");
3036 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
3037 if (!child_status_out) {
3038 printf("Failed to setup result status shared memory\n");
3042 memset(child_status, 0, sizeof(pid_t)*nprocs);
3043 memset(child_status_out, True, sizeof(BOOL)*nprocs);
3047 for (i=0;i<nprocs;i++) {
3050 pid_t mypid = getpid();
3051 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
3053 slprintf(myname,sizeof(myname),"CLIENT%d", i);
3056 memset(¤t_cli, 0, sizeof(current_cli));
3057 if (open_connection(¤t_cli)) break;
3059 printf("pid %d failed to start\n", (int)getpid());
3065 child_status[i] = getpid();
3067 while (child_status[i]) msleep(2);
3069 child_status_out[i] = fn(i);
3076 for (i=0;i<nprocs;i++) {
3077 if (child_status[i]) synccount++;
3079 if (synccount == nprocs) break;
3081 } while (end_timer() < 30);
3083 if (synccount != nprocs) {
3084 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
3089 /* start the client load */
3092 for (i=0;i<nprocs;i++) {
3093 child_status[i] = 0;
3096 printf("%d clients started\n", nprocs);
3098 for (i=0;i<nprocs;i++) {
3099 waitpid(0, &status, 0);
3105 for (i=0;i<nprocs;i++) {
3106 if (!child_status_out[i]) {
3114 #define FLAG_MULTIPROC 1
3121 {"FDPASS", run_fdpasstest, 0},
3122 {"LOCK1", run_locktest1, 0},
3123 {"LOCK2", run_locktest2, 0},
3124 {"LOCK3", run_locktest3, 0},
3125 {"LOCK4", run_locktest4, 0},
3126 {"LOCK5", run_locktest5, 0},
3127 {"UNLINK", run_unlinktest, 0},
3128 {"BROWSE", run_browsetest, 0},
3129 {"ATTR", run_attrtest, 0},
3130 {"TRANS2", run_trans2test, 0},
3131 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
3132 {"TORTURE",run_torture, FLAG_MULTIPROC},
3133 {"RANDOMIPC", run_randomipc, 0},
3134 {"NEGNOWAIT", run_negprot_nowait, 0},
3135 {"NBW95", run_nbw95, 0},
3136 {"NBWNT", run_nbwnt, 0},
3137 {"OPLOCK1", run_oplock1, 0},
3138 {"OPLOCK2", run_oplock2, 0},
3139 {"OPLOCK3", run_oplock3, 0},
3140 {"DIR", run_dirtest, 0},
3141 {"DENY1", run_denytest1, 0},
3142 {"DENY2", run_denytest2, 0},
3143 {"TCON", run_tcon_test, 0},
3144 {"RW1", run_readwritetest, 0},
3145 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
3146 {"RW3", run_readwritelarge, 0},
3147 {"OPEN", run_opentest, 0},
3148 {"DELETE", run_deletetest, 0},
3149 {"W2K", run_w2ktest, 0},
3154 /****************************************************************************
3155 run a specified test or "ALL"
3156 ****************************************************************************/
3157 static BOOL run_test(char *name)
3163 if (strequal(name,"ALL")) {
3164 for (i=0;torture_ops[i].name;i++) {
3165 run_test(torture_ops[i].name);
3169 for (i=0;torture_ops[i].name;i++) {
3170 snprintf(randomfname, sizeof(randomfname), "\\XX%x",
3171 (unsigned)random());
3173 if (strequal(name, torture_ops[i].name)) {
3174 printf("Running %s\n", name);
3175 if (torture_ops[i].flags & FLAG_MULTIPROC) {
3176 t = create_procs(torture_ops[i].fn, &result);
3179 printf("TEST %s FAILED!\n", name);
3184 if (!torture_ops[i].fn(0)) {
3186 printf("TEST %s FAILED!\n", name);
3190 printf("%s took %g secs\n\n", name, t);
3197 static void usage(void)
3201 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
3203 printf("\t-d debuglevel\n");
3204 printf("\t-U user%%pass\n");
3205 printf("\t-N numprocs\n");
3206 printf("\t-n my_netbios_name\n");
3207 printf("\t-W workgroup\n");
3208 printf("\t-o num_operations\n");
3209 printf("\t-O socket_options\n");
3210 printf("\t-m maximum protocol\n");
3211 printf("\t-L use oplocks\n");
3214 printf("tests are:");
3215 for (i=0;torture_ops[i].name;i++) {
3216 printf(" %s", torture_ops[i].name);
3220 printf("default test is ALL\n");
3229 /****************************************************************************
3231 ****************************************************************************/
3232 int main(int argc,char *argv[])
3237 extern char *optarg;
3240 static pstring servicesf = CONFIGFILE;
3241 BOOL correct = True;
3245 #ifdef HAVE_SETBUFFER
3246 setbuffer(stdout, NULL, 0);
3249 lp_load(servicesf,True,False,False);
3256 for(p = argv[1]; *p; p++)
3260 if (strncmp(argv[1], "//", 2)) {
3264 fstrcpy(host, &argv[1][2]);
3265 p = strchr_m(&host[2],'/');
3270 fstrcpy(share, p+1);
3274 if (*username == 0 && getenv("LOGNAME")) {
3275 pstrcpy(username,getenv("LOGNAME"));
3282 fstrcpy(workgroup, lp_workgroup());
3284 while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:Ld:")) != EOF) {
3287 fstrcpy(workgroup,optarg);
3290 max_protocol = interpret_protocol(optarg, max_protocol);
3293 nprocs = atoi(optarg);
3296 numops = atoi(optarg);
3299 DEBUGLEVEL = atoi(optarg);
3308 fstrcpy(myname, optarg);
3311 pstrcpy(username,optarg);
3312 p = strchr_m(username,'%');
3315 pstrcpy(password, p+1);
3320 printf("Unknown option %c (%d)\n", (char)opt, opt);
3327 p = getpass("Password:");
3329 pstrcpy(password, p);
3334 printf("host=%s share=%s user=%s myname=%s\n",
3335 host, share, username, myname);
3338 correct = run_test("ALL");
3340 for (i=1;i<argc;i++) {
3341 if (!run_test(argv[i])) {