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)
174 if (cli_is_dos_error(c)) {
178 /* Check DOS error */
180 cli_dos_error(c, &class, &num);
182 if (eclass != class || ecode != num) {
183 printf("unexpected error code class=%d code=%d\n",
184 (int)class, (int)num);
185 printf(" expected %d/%d %d\n",
186 (int)eclass, (int)ecode, (int)nterr);
195 status = cli_nt_error(c);
197 if (nterr != status) {
198 printf("unexpected error code 0x%08x\n", status);
199 printf(" expected 0x%08x\n", nterr);
208 static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
210 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
211 if (!check_error(c, ERRDOS, ERRlock, 0)) return False;
217 static BOOL rw_torture(struct cli_state *c)
219 char *lockfname = "\\torture.lck";
223 pid_t pid2, pid = getpid();
228 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
231 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
233 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
238 for (i=0;i<numops;i++) {
239 unsigned n = (unsigned)sys_random()%10;
241 printf("%d\r", i); fflush(stdout);
243 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
245 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
249 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
251 printf("open failed (%s)\n", cli_errstr(c));
256 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
257 printf("write failed (%s)\n", cli_errstr(c));
262 if (cli_write(c, fnum, 0, (char *)buf,
263 sizeof(pid)+(j*sizeof(buf)),
264 sizeof(buf)) != sizeof(buf)) {
265 printf("write failed (%s)\n", cli_errstr(c));
272 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
273 printf("read failed (%s)\n", cli_errstr(c));
278 printf("data corruption!\n");
282 if (!cli_close(c, fnum)) {
283 printf("close failed (%s)\n", cli_errstr(c));
287 if (!cli_unlink(c, fname)) {
288 printf("unlink failed (%s)\n", cli_errstr(c));
292 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
293 printf("unlock failed (%s)\n", cli_errstr(c));
299 cli_unlink(c, lockfname);
306 static BOOL run_torture(int dummy)
308 struct cli_state cli;
313 cli_sockopt(&cli, sockops);
315 ret = rw_torture(&cli);
317 if (!close_connection(&cli)) {
324 static BOOL rw_torture3(struct cli_state *c, char *lockfname)
331 unsigned countprev = 0;
336 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
338 SIVAL(buf, i, sys_random());
343 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
346 printf("first open read/write of %s failed (%s)\n",
347 lockfname, cli_errstr(c));
353 for (i = 0; i < 500 && fnum == -1; i++)
355 fnum = cli_open(c, lockfname, O_RDONLY,
360 printf("second open read-only of %s failed (%s)\n",
361 lockfname, cli_errstr(c));
367 for (count = 0; count < sizeof(buf); count += sent)
369 if (count >= countprev) {
370 printf("%d %8d\r", i, count);
373 countprev += (sizeof(buf) / 20);
378 sent = ((unsigned)sys_random()%(20))+ 1;
379 if (sent > sizeof(buf) - count)
381 sent = sizeof(buf) - count;
384 if (cli_write(c, fnum, 0, buf+count, count, sent) != sent) {
385 printf("write failed (%s)\n", cli_errstr(c));
391 sent = cli_read(c, fnum, buf_rd+count, count,
395 printf("read failed offset:%d size:%d (%s)\n",
396 count, sizeof(buf)-count,
403 if (memcmp(buf_rd+count, buf+count, sent) != 0)
405 printf("read/write compare failed\n");
406 printf("offset: %d req %d recvd %d\n",
407 count, sizeof(buf)-count, sent);
416 if (!cli_close(c, fnum)) {
417 printf("close failed (%s)\n", cli_errstr(c));
424 static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
426 char *lockfname = "\\torture.lck";
435 if (!cli_unlink(c1, lockfname)) {
436 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
439 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
442 printf("first open read/write of %s failed (%s)\n",
443 lockfname, cli_errstr(c1));
446 fnum2 = cli_open(c2, lockfname, O_RDONLY,
449 printf("second open read-only of %s failed (%s)\n",
450 lockfname, cli_errstr(c2));
451 cli_close(c1, fnum1);
455 for (i=0;i<numops;i++)
457 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
459 printf("%d\r", i); fflush(stdout);
462 generate_random_buffer(buf, buf_size, False);
464 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
465 printf("write failed (%s)\n", cli_errstr(c1));
469 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
470 printf("read failed (%s)\n", cli_errstr(c2));
471 printf("read %d, expected %d\n", bytes_read, buf_size);
475 if (memcmp(buf_rd, buf, buf_size) != 0)
477 printf("read/write compare failed\n");
482 if (!cli_close(c2, fnum2)) {
483 printf("close failed (%s)\n", cli_errstr(c2));
486 if (!cli_close(c1, fnum1)) {
487 printf("close failed (%s)\n", cli_errstr(c1));
491 if (!cli_unlink(c1, lockfname)) {
492 printf("unlink failed (%s)\n", cli_errstr(c1));
499 static BOOL run_readwritetest(int dummy)
501 static struct cli_state cli1, cli2;
504 if (!open_connection(&cli1) || !open_connection(&cli2)) {
507 cli_sockopt(&cli1, sockops);
508 cli_sockopt(&cli2, sockops);
510 printf("starting readwritetest\n");
512 test1 = rw_torture2(&cli1, &cli2);
513 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
515 test2 = rw_torture2(&cli1, &cli1);
516 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
518 if (!close_connection(&cli1)) {
522 if (!close_connection(&cli2)) {
526 return (test1 && test2);
529 static BOOL run_readwritemulti(int dummy)
531 static struct cli_state cli;
536 cli_sockopt(&cli, sockops);
538 printf("run_readwritemulti: fname %s\n", randomfname);
539 test = rw_torture3(&cli, randomfname);
541 if (!close_connection(&cli)) {
548 static BOOL run_readwritelarge(int dummy)
550 static struct cli_state cli1;
552 char *lockfname = "\\large.dat";
557 if (!open_connection(&cli1)) {
560 cli_sockopt(&cli1, sockops);
561 memset(buf,'\0',sizeof(buf));
563 cli1.max_xmit = 0x11000;
565 printf("starting readwritelarge\n");
567 cli_unlink(&cli1, lockfname);
569 fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
571 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
575 cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf));
577 if (!cli_close(&cli1, fnum1)) {
578 printf("close failed (%s)\n", cli_errstr(&cli1));
582 if (!cli_qpathinfo(&cli1, lockfname, NULL, NULL, NULL, &fsize, NULL)) {
583 printf("qpathinfo failed (%s)\n", cli_errstr(&cli1));
587 if (fsize == sizeof(buf))
588 printf("readwritelarge test 1 succeeded (size = %x)\n", fsize);
590 printf("readwritelarge test 1 failed (size = %x)\n", fsize);
594 if (!cli_unlink(&cli1, lockfname)) {
595 printf("unlink failed (%s)\n", cli_errstr(&cli1));
599 fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
601 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
605 cli_smbwrite(&cli1, fnum1, buf, 0, sizeof(buf));
607 if (!cli_close(&cli1, fnum1)) {
608 printf("close failed (%s)\n", cli_errstr(&cli1));
612 if (!close_connection(&cli1)) {
620 /* run a test that simulates an approximate netbench client load */
621 static BOOL run_netbench(int client)
623 struct cli_state cli;
634 cli_sockopt(&cli, sockops);
638 slprintf(cname,sizeof(fname), "CLIENT%d", client);
640 f = fopen("client.txt", "r");
643 perror("client.txt");
647 while (fgets(line, sizeof(line)-1, f)) {
650 line[strlen(line)-1] = 0;
652 /* printf("[%d] %s\n", line_count, line); */
654 all_string_sub(line,"CLIENT1", cname, sizeof(line));
656 for (i=0;i<20;i++) params[i] = "";
658 /* parse the command parameters */
659 params[0] = strtok(line," ");
661 while (params[i]) params[++i] = strtok(NULL," ");
667 if (strcmp(params[1],"REQUEST") == 0) {
668 if (!strcmp(params[0],"SMBopenX")) {
669 fstrcpy(fname, params[5]);
670 } else if (!strcmp(params[0],"SMBclose")) {
671 nb_close(atoi(params[3]));
672 } else if (!strcmp(params[0],"SMBmkdir")) {
674 } else if (!strcmp(params[0],"CREATE")) {
675 nb_create(params[3], atoi(params[5]));
676 } else if (!strcmp(params[0],"SMBrmdir")) {
678 } else if (!strcmp(params[0],"SMBunlink")) {
679 fstrcpy(fname, params[3]);
680 } else if (!strcmp(params[0],"SMBmv")) {
681 nb_rename(params[3], params[5]);
682 } else if (!strcmp(params[0],"SMBgetatr")) {
683 fstrcpy(fname, params[3]);
684 } else if (!strcmp(params[0],"SMBwrite")) {
685 nb_write(atoi(params[3]),
686 atoi(params[5]), atoi(params[7]));
687 } else if (!strcmp(params[0],"SMBwritebraw")) {
688 nb_write(atoi(params[3]),
689 atoi(params[7]), atoi(params[5]));
690 } else if (!strcmp(params[0],"SMBreadbraw")) {
691 nb_read(atoi(params[3]),
692 atoi(params[7]), atoi(params[5]));
693 } else if (!strcmp(params[0],"SMBread")) {
694 nb_read(atoi(params[3]),
695 atoi(params[5]), atoi(params[7]));
698 if (!strcmp(params[0],"SMBopenX")) {
699 if (!strncmp(params[2], "ERR", 3)) continue;
700 nb_open(fname, atoi(params[3]), atoi(params[5]));
701 } else if (!strcmp(params[0],"SMBgetatr")) {
702 if (!strncmp(params[2], "ERR", 3)) continue;
703 nb_stat(fname, atoi(params[3]));
704 } else if (!strcmp(params[0],"SMBunlink")) {
705 if (!strncmp(params[2], "ERR", 3)) continue;
712 slprintf(fname,sizeof(fname), "CLIENTS/CLIENT%d", client);
718 if (!close_connection(&cli)) {
726 /* run a test that simulates an approximate netbench w9X client load */
727 static BOOL run_nbw95(int dummy)
731 t = create_procs(run_netbench, &correct);
732 /* to produce a netbench result we scale accoding to the
733 netbench measured throughput for the run that produced the
734 sniff that was used to produce client.txt. That run used 2
735 clients and ran for 660 seconds to produce a result of
737 printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n",
738 132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t);
742 /* run a test that simulates an approximate netbench wNT client load */
743 static BOOL run_nbwnt(int dummy)
747 t = create_procs(run_netbench, &correct);
748 printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n",
749 132*nprocs/t, 0.5*0.5*nprocs*660/t, 2*nprocs*660/t);
756 This test checks for two things:
758 1) correct support for retaining locks over a close (ie. the server
759 must not use posix semantics)
760 2) support for lock timeouts
762 static BOOL run_locktest1(int dummy)
764 static struct cli_state cli1, cli2;
765 char *fname = "\\lockt1.lck";
766 int fnum1, fnum2, fnum3;
769 if (!open_connection(&cli1) || !open_connection(&cli2)) {
772 cli_sockopt(&cli1, sockops);
773 cli_sockopt(&cli2, sockops);
775 printf("starting locktest1\n");
777 cli_unlink(&cli1, fname);
779 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
781 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
784 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
786 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
789 fnum3 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
791 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2));
795 if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
796 printf("lock1 failed (%s)\n", cli_errstr(&cli1));
801 if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
802 printf("lock2 succeeded! This is a locking bug\n");
805 if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return False;
809 printf("Testing lock timeouts\n");
811 if (cli_lock(&cli2, fnum3, 0, 4, 10*1000, WRITE_LOCK)) {
812 printf("lock3 succeeded! This is a locking bug\n");
815 if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return False;
820 printf("error: This server appears not to support timed lock requests\n");
823 if (!cli_close(&cli1, fnum2)) {
824 printf("close1 failed (%s)\n", cli_errstr(&cli1));
828 if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
829 printf("lock4 succeeded! This is a locking bug\n");
832 if (!check_error(&cli2, ERRDOS, ERRlock, 0)) return False;
835 if (!cli_close(&cli1, fnum1)) {
836 printf("close2 failed (%s)\n", cli_errstr(&cli1));
840 if (!cli_close(&cli2, fnum3)) {
841 printf("close3 failed (%s)\n", cli_errstr(&cli2));
845 if (!cli_unlink(&cli1, fname)) {
846 printf("unlink failed (%s)\n", cli_errstr(&cli1));
851 if (!close_connection(&cli1)) {
855 if (!close_connection(&cli2)) {
859 printf("Passed locktest1\n");
864 checks for correct tconX support
866 static BOOL run_tcon_test(int dummy)
868 static struct cli_state cli1;
869 char *fname = "\\tcontest.tmp";
874 if (!open_connection(&cli1)) {
877 cli_sockopt(&cli1, sockops);
879 printf("starting tcontest\n");
881 cli_unlink(&cli1, fname);
883 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
886 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
892 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4)
894 printf("write failed (%s)", cli_errstr(&cli1));
898 if (!cli_send_tconX(&cli1, share, "?????",
899 password, strlen(password)+1)) {
900 printf("%s refused 2nd tree connect (%s)\n", host,
906 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) == 4)
908 printf("write succeeded (%s)", cli_errstr(&cli1));
912 if (cli_close(&cli1, fnum1)) {
913 printf("close2 succeeded (%s)\n", cli_errstr(&cli1));
917 if (!cli_tdis(&cli1)) {
918 printf("tdis failed (%s)\n", cli_errstr(&cli1));
924 if (!cli_close(&cli1, fnum1)) {
925 printf("close2 failed (%s)\n", cli_errstr(&cli1));
929 if (!close_connection(&cli1)) {
933 printf("Passed tcontest\n");
939 This test checks that
941 1) the server supports multiple locking contexts on the one SMB
942 connection, distinguished by PID.
944 2) the server correctly fails overlapping locks made by the same PID (this
945 goes against POSIX behaviour, which is why it is tricky to implement)
947 3) the server denies unlock requests by an incorrect client PID
949 static BOOL run_locktest2(int dummy)
951 static struct cli_state cli;
952 char *fname = "\\lockt2.lck";
953 int fnum1, fnum2, fnum3;
956 if (!open_connection(&cli)) {
960 cli_sockopt(&cli, sockops);
962 printf("starting locktest2\n");
964 cli_unlink(&cli, fname);
968 fnum1 = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
970 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
974 fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
976 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli));
982 fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
984 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli));
990 if (!cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
991 printf("lock1 failed (%s)\n", cli_errstr(&cli));
995 if (cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
996 printf("WRITE lock1 succeeded! This is a locking bug\n");
999 if (!check_error(&cli, ERRDOS, ERRlock, 0)) return False;
1002 if (cli_lock(&cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1003 printf("WRITE lock2 succeeded! This is a locking bug\n");
1006 if (!check_error(&cli, ERRDOS, ERRlock, 0)) return False;
1009 if (cli_lock(&cli, fnum2, 0, 4, 0, READ_LOCK)) {
1010 printf("READ lock2 succeeded! This is a locking bug\n");
1013 if (!check_error(&cli, ERRDOS, ERRlock, 0)) return False;
1016 if (!cli_lock(&cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1017 printf("lock at 100 failed (%s)\n", cli_errstr(&cli));
1019 cli_setpid(&cli, 2);
1020 if (cli_unlock(&cli, fnum1, 100, 4)) {
1021 printf("unlock at 100 succeeded! This is a locking bug\n");
1025 if (cli_unlock(&cli, fnum1, 0, 4)) {
1026 printf("unlock1 succeeded! This is a locking bug\n");
1029 if (!check_error(&cli, ERRDOS, ERRnotlocked, 0)) return False;
1032 if (cli_unlock(&cli, fnum1, 0, 8)) {
1033 printf("unlock2 succeeded! This is a locking bug\n");
1036 if (!check_error(&cli, ERRDOS, ERRnotlocked, 0)) return False;
1039 if (cli_lock(&cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1040 printf("lock3 succeeded! This is a locking bug\n");
1043 if (!check_error(&cli, ERRDOS, ERRlock, 0)) return False;
1046 cli_setpid(&cli, 1);
1048 if (!cli_close(&cli, fnum1)) {
1049 printf("close1 failed (%s)\n", cli_errstr(&cli));
1053 if (!cli_close(&cli, fnum2)) {
1054 printf("close2 failed (%s)\n", cli_errstr(&cli));
1058 if (!cli_close(&cli, fnum3)) {
1059 printf("close3 failed (%s)\n", cli_errstr(&cli));
1063 if (!close_connection(&cli)) {
1067 printf("locktest2 finished\n");
1074 This test checks that
1076 1) the server supports the full offset range in lock requests
1078 static BOOL run_locktest3(int dummy)
1080 static struct cli_state cli1, cli2;
1081 char *fname = "\\lockt3.lck";
1082 int fnum1, fnum2, i;
1084 BOOL correct = True;
1086 #define NEXT_OFFSET offset += (~(uint32)0) / numops
1088 if (!open_connection(&cli1) || !open_connection(&cli2)) {
1091 cli_sockopt(&cli1, sockops);
1092 cli_sockopt(&cli2, sockops);
1094 printf("starting locktest3\n");
1096 cli_unlink(&cli1, fname);
1098 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1100 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1103 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1105 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
1109 for (offset=i=0;i<numops;i++) {
1111 if (!cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1112 printf("lock1 %d failed (%s)\n",
1118 if (!cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1119 printf("lock2 %d failed (%s)\n",
1126 for (offset=i=0;i<numops;i++) {
1129 if (cli_lock(&cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1130 printf("error: lock1 %d succeeded!\n", i);
1134 if (cli_lock(&cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1135 printf("error: lock2 %d succeeded!\n", i);
1139 if (cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1140 printf("error: lock3 %d succeeded!\n", i);
1144 if (cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1145 printf("error: lock4 %d succeeded!\n", i);
1150 for (offset=i=0;i<numops;i++) {
1153 if (!cli_unlock(&cli1, fnum1, offset-1, 1)) {
1154 printf("unlock1 %d failed (%s)\n",
1160 if (!cli_unlock(&cli2, fnum2, offset-2, 1)) {
1161 printf("unlock2 %d failed (%s)\n",
1168 if (!cli_close(&cli1, fnum1)) {
1169 printf("close1 failed (%s)\n", cli_errstr(&cli1));
1173 if (!cli_close(&cli2, fnum2)) {
1174 printf("close2 failed (%s)\n", cli_errstr(&cli2));
1178 if (!cli_unlink(&cli1, fname)) {
1179 printf("unlink failed (%s)\n", cli_errstr(&cli1));
1183 if (!close_connection(&cli1)) {
1187 if (!close_connection(&cli2)) {
1191 printf("finished locktest3\n");
1196 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1197 printf("** "); correct = False; \
1201 looks at overlapping locks
1203 static BOOL run_locktest4(int dummy)
1205 static struct cli_state cli1, cli2;
1206 char *fname = "\\lockt4.lck";
1207 int fnum1, fnum2, f;
1210 BOOL correct = True;
1212 if (!open_connection(&cli1) || !open_connection(&cli2)) {
1216 cli_sockopt(&cli1, sockops);
1217 cli_sockopt(&cli2, sockops);
1219 printf("starting locktest4\n");
1221 cli_unlink(&cli1, fname);
1223 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1224 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1226 memset(buf, 0, sizeof(buf));
1228 if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1229 printf("Failed to create file\n");
1234 ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1235 cli_lock(&cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1236 EXPECTED(ret, False);
1237 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1239 ret = cli_lock(&cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1240 cli_lock(&cli1, fnum1, 12, 4, 0, READ_LOCK);
1241 EXPECTED(ret, True);
1242 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1244 ret = cli_lock(&cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1245 cli_lock(&cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1246 EXPECTED(ret, False);
1247 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1249 ret = cli_lock(&cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1250 cli_lock(&cli2, fnum2, 32, 4, 0, READ_LOCK);
1251 EXPECTED(ret, True);
1252 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1254 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1255 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1256 EXPECTED(ret, False);
1257 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1259 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1260 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 52, 4, 0, READ_LOCK));
1261 EXPECTED(ret, True);
1262 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1264 ret = cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1265 cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK);
1266 EXPECTED(ret, True);
1267 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1269 ret = cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1270 cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1271 EXPECTED(ret, False);
1272 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1274 ret = cli_lock(&cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1275 cli_lock(&cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1276 EXPECTED(ret, False);
1277 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1279 ret = cli_lock(&cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1280 cli_lock(&cli1, fnum1, 90, 4, 0, READ_LOCK);
1281 EXPECTED(ret, True);
1282 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1284 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1285 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 100, 4, 0, READ_LOCK));
1286 EXPECTED(ret, False);
1287 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1289 ret = cli_lock(&cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1290 cli_lock(&cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1291 cli_unlock(&cli1, fnum1, 110, 6);
1292 EXPECTED(ret, False);
1293 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1296 ret = cli_lock(&cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1297 (cli_read(&cli2, fnum2, buf, 120, 4) == 4);
1298 EXPECTED(ret, False);
1299 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1301 ret = cli_lock(&cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1302 (cli_write(&cli2, fnum2, 0, buf, 130, 4) == 4);
1303 EXPECTED(ret, False);
1304 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1307 ret = cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1308 cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1309 cli_unlock(&cli1, fnum1, 140, 4) &&
1310 cli_unlock(&cli1, fnum1, 140, 4);
1311 EXPECTED(ret, True);
1312 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1315 ret = cli_lock(&cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1316 cli_lock(&cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1317 cli_unlock(&cli1, fnum1, 150, 4) &&
1318 (cli_read(&cli2, fnum2, buf, 150, 4) == 4) &&
1319 !(cli_write(&cli2, fnum2, 0, buf, 150, 4) == 4) &&
1320 cli_unlock(&cli1, fnum1, 150, 4);
1321 EXPECTED(ret, True);
1322 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1324 ret = cli_lock(&cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1325 cli_unlock(&cli1, fnum1, 160, 4) &&
1326 (cli_write(&cli2, fnum2, 0, buf, 160, 4) == 4) &&
1327 (cli_read(&cli2, fnum2, buf, 160, 4) == 4);
1328 EXPECTED(ret, True);
1329 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1331 ret = cli_lock(&cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1332 cli_unlock(&cli1, fnum1, 170, 4) &&
1333 (cli_write(&cli2, fnum2, 0, buf, 170, 4) == 4) &&
1334 (cli_read(&cli2, fnum2, buf, 170, 4) == 4);
1335 EXPECTED(ret, True);
1336 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1338 ret = cli_lock(&cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1339 cli_lock(&cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1340 cli_unlock(&cli1, fnum1, 190, 4) &&
1341 !(cli_write(&cli2, fnum2, 0, buf, 190, 4) == 4) &&
1342 (cli_read(&cli2, fnum2, buf, 190, 4) == 4);
1343 EXPECTED(ret, True);
1344 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1346 cli_close(&cli1, fnum1);
1347 cli_close(&cli2, fnum2);
1348 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1349 f = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1350 ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1351 cli_lock(&cli1, f, 0, 1, 0, READ_LOCK) &&
1352 cli_close(&cli1, fnum1) &&
1353 ((fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1354 cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1355 cli_close(&cli1, f);
1356 EXPECTED(ret, True);
1357 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1360 cli_close(&cli1, fnum1);
1361 cli_close(&cli2, fnum2);
1362 cli_unlink(&cli1, fname);
1363 close_connection(&cli1);
1364 close_connection(&cli2);
1366 printf("finished locktest4\n");
1371 looks at lock upgrade/downgrade.
1373 static BOOL run_locktest5(int dummy)
1375 static struct cli_state cli1, cli2;
1376 char *fname = "\\lockt5.lck";
1377 int fnum1, fnum2, fnum3;
1380 BOOL correct = True;
1382 if (!open_connection(&cli1) || !open_connection(&cli2)) {
1386 cli_sockopt(&cli1, sockops);
1387 cli_sockopt(&cli2, sockops);
1389 printf("starting locktest5\n");
1391 cli_unlink(&cli1, fname);
1393 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1394 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1395 fnum3 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1397 memset(buf, 0, sizeof(buf));
1399 if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1400 printf("Failed to create file\n");
1405 /* Check for NT bug... */
1406 ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1407 cli_lock(&cli1, fnum3, 0, 1, 0, READ_LOCK);
1408 cli_close(&cli1, fnum1);
1409 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1410 ret = cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1411 EXPECTED(ret, True);
1412 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1413 cli_close(&cli1, fnum1);
1414 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1415 cli_unlock(&cli1, fnum3, 0, 1);
1417 ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1418 cli_lock(&cli1, fnum1, 1, 1, 0, READ_LOCK);
1419 EXPECTED(ret, True);
1420 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1422 ret = cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1423 EXPECTED(ret, False);
1425 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1427 /* Unlock the process 2 lock. */
1428 cli_unlock(&cli2, fnum2, 0, 4);
1430 ret = cli_lock(&cli1, fnum3, 0, 4, 0, READ_LOCK);
1431 EXPECTED(ret, False);
1433 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1435 /* Unlock the process 1 fnum3 lock. */
1436 cli_unlock(&cli1, fnum3, 0, 4);
1438 /* Stack 2 more locks here. */
1439 ret = cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1440 cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK);
1442 EXPECTED(ret, True);
1443 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1445 /* Unlock the first process lock, then check this was the WRITE lock that was
1448 ret = cli_unlock(&cli1, fnum1, 0, 4) &&
1449 cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1451 EXPECTED(ret, True);
1452 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1454 /* Unlock the process 2 lock. */
1455 cli_unlock(&cli2, fnum2, 0, 4);
1457 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1459 ret = cli_unlock(&cli1, fnum1, 1, 1) &&
1460 cli_unlock(&cli1, fnum1, 0, 4) &&
1461 cli_unlock(&cli1, fnum1, 0, 4);
1463 EXPECTED(ret, True);
1464 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1466 /* Ensure the next unlock fails. */
1467 ret = cli_unlock(&cli1, fnum1, 0, 4);
1468 EXPECTED(ret, False);
1469 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1471 /* Ensure connection 2 can get a write lock. */
1472 ret = cli_lock(&cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1473 EXPECTED(ret, True);
1475 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1479 cli_close(&cli1, fnum1);
1480 cli_close(&cli2, fnum2);
1481 cli_unlink(&cli1, fname);
1482 if (!close_connection(&cli1)) {
1485 if (!close_connection(&cli2)) {
1489 printf("finished locktest5\n");
1496 this produces a matrix of deny mode behaviour
1498 static BOOL run_denytest1(int dummy)
1500 static struct cli_state cli1, cli2;
1502 int f, d1, d2, o1, o2, x=0;
1503 char *fnames[] = {"\\denytest1.exe", "\\denytest1.dat", NULL};
1508 {DENY_DOS, "DENY_DOS"},
1509 {DENY_ALL, "DENY_ALL"},
1510 {DENY_WRITE, "DENY_WRITE"},
1511 {DENY_READ, "DENY_READ"},
1512 {DENY_NONE, "DENY_NONE"},
1513 {DENY_FCB, "DENY_FCB"},
1520 {O_RDONLY, "O_RDONLY"},
1521 {O_WRONLY, "O_WRONLY"},
1523 BOOL correct = True;
1525 if (!open_connection(&cli1) || !open_connection(&cli2)) {
1528 cli_sockopt(&cli1, sockops);
1529 cli_sockopt(&cli2, sockops);
1531 printf("starting denytest1\n");
1533 for (f=0;fnames[f];f++) {
1534 cli_unlink(&cli1, fnames[f]);
1536 fnum1 = cli_open(&cli1, fnames[f], O_RDWR|O_CREAT, DENY_NONE);
1537 cli_write(&cli1, fnum1, 0, fnames[f], 0, strlen(fnames[f]));
1538 cli_close(&cli1, fnum1);
1540 for (d1=0;deny_modes[d1].name;d1++)
1541 for (o1=0;open_modes[o1].name;o1++)
1542 for (d2=0;deny_modes[d2].name;d2++)
1543 for (o2=0;open_modes[o2].name;o2++) {
1544 fnum1 = cli_open(&cli1, fnames[f],
1547 fnum2 = cli_open(&cli2, fnames[f],
1551 printf("%s %8s %10s %8s %10s ",
1553 open_modes[o1].name,
1554 deny_modes[d1].name,
1555 open_modes[o2].name,
1556 deny_modes[d2].name);
1560 } else if (fnum2 == -1) {
1563 if (cli_read(&cli2, fnum2, (void *)&x, 0, 1) == 1) {
1566 if (cli_write(&cli2, fnum2, 0, (void *)&x, 0, 1) == 1) {
1572 cli_close(&cli1, fnum1);
1573 cli_close(&cli2, fnum2);
1576 cli_unlink(&cli1, fnames[f]);
1579 if (!close_connection(&cli1)) {
1582 if (!close_connection(&cli2)) {
1586 printf("finshed denytest1\n");
1592 this produces a matrix of deny mode behaviour for two opens on the
1595 static BOOL run_denytest2(int dummy)
1597 static struct cli_state cli1;
1599 int f, d1, d2, o1, o2, x=0;
1600 char *fnames[] = {"\\denytest2.exe", "\\denytest2.dat", NULL};
1605 {DENY_DOS, "DENY_DOS"},
1606 {DENY_ALL, "DENY_ALL"},
1607 {DENY_WRITE, "DENY_WRITE"},
1608 {DENY_READ, "DENY_READ"},
1609 {DENY_NONE, "DENY_NONE"},
1610 {DENY_FCB, "DENY_FCB"},
1617 {O_RDONLY, "O_RDONLY"},
1618 {O_WRONLY, "O_WRONLY"},
1620 BOOL correct = True;
1622 if (!open_connection(&cli1)) {
1625 cli_sockopt(&cli1, sockops);
1627 printf("starting denytest2\n");
1629 for (f=0;fnames[f];f++) {
1630 cli_unlink(&cli1, fnames[f]);
1632 fnum1 = cli_open(&cli1, fnames[f], O_RDWR|O_CREAT, DENY_NONE);
1633 cli_write(&cli1, fnum1, 0, fnames[f], 0, strlen(fnames[f]));
1634 cli_close(&cli1, fnum1);
1636 for (d1=0;deny_modes[d1].name;d1++)
1637 for (o1=0;open_modes[o1].name;o1++)
1638 for (d2=0;deny_modes[d2].name;d2++)
1639 for (o2=0;open_modes[o2].name;o2++) {
1640 fnum1 = cli_open(&cli1, fnames[f],
1643 fnum2 = cli_open(&cli1, fnames[f],
1647 printf("%s %8s %10s %8s %10s ",
1649 open_modes[o1].name,
1650 deny_modes[d1].name,
1651 open_modes[o2].name,
1652 deny_modes[d2].name);
1656 } else if (fnum2 == -1) {
1659 if (cli_read(&cli1, fnum2, (void *)&x, 0, 1) == 1) {
1662 if (cli_write(&cli1, fnum2, 0, (void *)&x, 0, 1) == 1) {
1668 cli_close(&cli1, fnum1);
1669 cli_close(&cli1, fnum2);
1672 cli_unlink(&cli1, fnames[f]);
1675 if (!close_connection(&cli1)) {
1679 printf("finshed denytest2\n");
1684 test whether fnums and tids open on one VC are available on another (a major
1687 static BOOL run_fdpasstest(int dummy)
1689 static struct cli_state cli1, cli2, cli3;
1690 char *fname = "\\fdpass.tst";
1694 if (!open_connection(&cli1) || !open_connection(&cli2)) {
1697 cli_sockopt(&cli1, sockops);
1698 cli_sockopt(&cli2, sockops);
1700 printf("starting fdpasstest\n");
1702 cli_unlink(&cli1, fname);
1704 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1706 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1710 if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
1711 printf("write failed (%s)\n", cli_errstr(&cli1));
1716 cli3.vuid = cli1.vuid;
1717 cli3.cnum = cli1.cnum;
1718 cli3.pid = cli1.pid;
1720 if (cli_read(&cli3, fnum1, buf, 0, 13) == 13) {
1721 printf("read succeeded! nasty security hole [%s]\n",
1726 cli_close(&cli1, fnum1);
1727 cli_unlink(&cli1, fname);
1729 close_connection(&cli1);
1730 close_connection(&cli2);
1732 printf("finished fdpasstest\n");
1738 This test checks that
1740 1) the server does not allow an unlink on a file that is open
1742 static BOOL run_unlinktest(int dummy)
1744 static struct cli_state cli;
1745 char *fname = "\\unlink.tst";
1747 BOOL correct = True;
1749 if (!open_connection(&cli)) {
1753 cli_sockopt(&cli, sockops);
1755 printf("starting unlink test\n");
1757 cli_unlink(&cli, fname);
1759 cli_setpid(&cli, 1);
1761 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1763 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1767 if (cli_unlink(&cli, fname)) {
1768 printf("error: server allowed unlink on an open file\n");
1772 cli_close(&cli, fnum);
1773 cli_unlink(&cli, fname);
1775 if (!close_connection(&cli)) {
1779 printf("unlink test finished\n");
1786 test how many open files this server supports on the one socket
1788 static BOOL run_maxfidtest(int dummy)
1790 static struct cli_state cli;
1791 char *template = "\\maxfid.%d.%d";
1795 BOOL correct = True;
1800 printf("failed to connect\n");
1804 cli_sockopt(&cli, sockops);
1808 slprintf(fname,sizeof(fname)-1,template, fnum,(int)getpid());
1809 if (cli_open(&cli, fname,
1810 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE) ==
1812 printf("open of %s failed (%s)\n",
1813 fname, cli_errstr(&cli));
1814 printf("maximum fnum is %d\n", fnum);
1818 if (fnum % 100 == 0) printf("%d\r", fnum);
1820 printf("%d\n", fnum);
1822 printf("cleaning up\n");
1825 slprintf(fname,sizeof(fname)-1,template, fnum,(int)getpid());
1826 cli_close(&cli, fnum);
1827 if (!cli_unlink(&cli, fname)) {
1828 printf("unlink of %s failed (%s)\n",
1829 fname, cli_errstr(&cli));
1834 printf("maxfid test finished\n");
1835 if (!close_connection(&cli)) {
1841 /* generate a random buffer */
1842 static void rand_buf(char *buf, int len)
1845 *buf = (char)sys_random();
1850 /* send smb negprot commands, not reading the response */
1851 static BOOL run_negprot_nowait(int dummy)
1854 static struct cli_state cli;
1855 BOOL correct = True;
1857 printf("starting negprot nowait test\n");
1859 if (!open_nbt_connection(&cli)) {
1863 for (i=0;i<50000;i++) {
1864 cli_negprot_send(&cli);
1867 if (!close_connection(&cli)) {
1871 printf("finished negprot nowait test\n");
1877 /* send random IPC commands */
1878 static BOOL run_randomipc(int dummy)
1880 char *rparam = NULL;
1884 int api, param_len, i;
1885 static struct cli_state cli;
1886 BOOL correct = True;
1888 printf("starting random ipc test\n");
1890 if (!open_connection(&cli)) {
1894 for (i=0;i<50000;i++) {
1895 api = sys_random() % 500;
1896 param_len = (sys_random() % 64);
1898 rand_buf(param, param_len);
1903 param, param_len, 8,
1904 NULL, 0, BUFFER_SIZE,
1909 if (!close_connection(&cli)) {
1913 printf("finished random ipc test\n");
1920 static void browse_callback(const char *sname, uint32 stype,
1921 const char *comment, void *state)
1923 printf("\t%20.20s %08x %s\n", sname, stype, comment);
1929 This test checks the browse list code
1932 static BOOL run_browsetest(int dummy)
1934 static struct cli_state cli;
1935 BOOL correct = True;
1937 printf("starting browse test\n");
1939 if (!open_connection(&cli)) {
1943 printf("domain list:\n");
1944 cli_NetServerEnum(&cli, cli.server_domain,
1945 SV_TYPE_DOMAIN_ENUM,
1946 browse_callback, NULL);
1948 printf("machine list:\n");
1949 cli_NetServerEnum(&cli, cli.server_domain,
1951 browse_callback, NULL);
1953 if (!close_connection(&cli)) {
1957 printf("browse test finished\n");
1965 This checks how the getatr calls works
1967 static BOOL run_attrtest(int dummy)
1969 static struct cli_state cli;
1972 char *fname = "\\attrib.tst";
1973 BOOL correct = True;
1975 printf("starting attrib test\n");
1977 if (!open_connection(&cli)) {
1981 cli_unlink(&cli, fname);
1982 fnum = cli_open(&cli, fname,
1983 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
1984 cli_close(&cli, fnum);
1985 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
1986 printf("getatr failed (%s)\n", cli_errstr(&cli));
1990 if (abs(t - time(NULL)) > 2) {
1991 printf("ERROR: SMBgetatr bug. time is %s",
1997 t2 = t-60*60*24; /* 1 day ago */
1999 if (!cli_setatr(&cli, fname, 0, t2)) {
2000 printf("setatr failed (%s)\n", cli_errstr(&cli));
2004 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
2005 printf("getatr failed (%s)\n", cli_errstr(&cli));
2010 printf("ERROR: getatr/setatr bug. times are\n%s",
2012 printf("%s", ctime(&t2));
2016 cli_unlink(&cli, fname);
2018 if (!close_connection(&cli)) {
2022 printf("attrib test finished\n");
2029 This checks a couple of trans2 calls
2031 static BOOL run_trans2test(int dummy)
2033 static struct cli_state cli;
2036 time_t c_time, a_time, m_time, w_time, m_time2;
2037 char *fname = "\\trans2.tst";
2038 char *dname = "\\trans2";
2039 char *fname2 = "\\trans2\\trans2.tst";
2040 BOOL correct = True;
2042 printf("starting trans2 test\n");
2044 if (!open_connection(&cli)) {
2048 cli_unlink(&cli, fname);
2049 fnum = cli_open(&cli, fname,
2050 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2051 if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
2053 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
2056 cli_close(&cli, fnum);
2060 cli_unlink(&cli, fname);
2061 fnum = cli_open(&cli, fname,
2062 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2063 cli_close(&cli, fnum);
2065 if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2066 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
2069 if (c_time != m_time) {
2070 printf("create time=%s", ctime(&c_time));
2071 printf("modify time=%s", ctime(&m_time));
2072 printf("This system appears to have sticky create times\n");
2075 if (a_time % (60*60) == 0) {
2076 printf("access time=%s", ctime(&a_time));
2077 printf("This system appears to set a midnight access time\n");
2081 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2082 printf("ERROR: totally incorrect times - maybe word reversed?\n");
2088 cli_unlink(&cli, fname);
2089 fnum = cli_open(&cli, fname,
2090 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2091 cli_close(&cli, fnum);
2092 if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time,
2093 &w_time, &size, NULL, NULL)) {
2094 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2097 if (w_time < 60*60*24*2) {
2098 printf("write time=%s", ctime(&w_time));
2099 printf("This system appears to set a initial 0 write time\n");
2104 cli_unlink(&cli, fname);
2107 /* check if the server updates the directory modification time
2108 when creating a new file */
2109 if (!cli_mkdir(&cli, dname)) {
2110 printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
2114 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time,
2115 &w_time, &size, NULL, NULL)) {
2116 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2120 fnum = cli_open(&cli, fname2,
2121 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2122 cli_write(&cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2123 cli_close(&cli, fnum);
2124 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2,
2125 &w_time, &size, NULL, NULL)) {
2126 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2129 if (m_time2 == m_time) {
2130 printf("This system does not update directory modification times\n");
2134 cli_unlink(&cli, fname2);
2135 cli_rmdir(&cli, dname);
2137 if (!close_connection(&cli)) {
2141 printf("trans2 test finished\n");
2147 This checks new W2K calls.
2150 static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
2153 BOOL correct = True;
2155 memset(buf, 0xff, sizeof(buf));
2157 if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
2158 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2161 printf("qfileinfo: level %d\n", level);
2162 dump_data(0, buf, 256);
2168 static BOOL run_w2ktest(int dummy)
2170 static struct cli_state cli;
2172 char *fname = "\\w2ktest\\w2k.tst";
2174 BOOL correct = True;
2176 printf("starting w2k test\n");
2178 if (!open_connection(&cli)) {
2182 fnum = cli_open(&cli, fname,
2183 O_RDWR | O_CREAT , DENY_NONE);
2185 for (level = 1004; level < 1040; level++) {
2186 if (!new_trans(&cli, fnum, level)) {
2191 cli_close(&cli, fnum);
2193 if (!close_connection(&cli)) {
2197 printf("w2k test finished\n");
2204 this is a harness for some oplock tests
2206 static BOOL run_oplock1(int dummy)
2208 static struct cli_state cli1;
2209 char *fname = "\\lockt1.lck";
2211 BOOL correct = True;
2213 printf("starting oplock test 1\n");
2215 if (!open_connection(&cli1)) {
2219 cli_unlink(&cli1, fname);
2221 cli_sockopt(&cli1, sockops);
2223 cli1.use_oplocks = True;
2225 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2227 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2231 cli1.use_oplocks = False;
2233 cli_unlink(&cli1, fname);
2234 cli_unlink(&cli1, fname);
2236 if (!cli_close(&cli1, fnum1)) {
2237 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2241 if (!cli_unlink(&cli1, fname)) {
2242 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2246 if (!close_connection(&cli1)) {
2250 printf("finished oplock test 1\n");
2255 static BOOL run_oplock2(int dummy)
2257 static struct cli_state cli1, cli2;
2258 char *fname = "\\lockt2.lck";
2260 int saved_use_oplocks = use_oplocks;
2262 BOOL correct = True;
2263 volatile BOOL *shared_correct;
2265 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2266 *shared_correct = True;
2268 use_level_II_oplocks = True;
2271 printf("starting oplock test 2\n");
2273 if (!open_connection(&cli1)) {
2274 use_level_II_oplocks = False;
2275 use_oplocks = saved_use_oplocks;
2279 cli1.use_oplocks = True;
2280 cli1.use_level_II_oplocks = True;
2282 if (!open_connection(&cli2)) {
2283 use_level_II_oplocks = False;
2284 use_oplocks = saved_use_oplocks;
2288 cli2.use_oplocks = True;
2289 cli2.use_level_II_oplocks = True;
2291 cli_unlink(&cli1, fname);
2293 cli_sockopt(&cli1, sockops);
2294 cli_sockopt(&cli2, sockops);
2296 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2298 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2302 /* Don't need the globals any more. */
2303 use_level_II_oplocks = False;
2304 use_oplocks = saved_use_oplocks;
2308 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
2310 printf("second open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2311 *shared_correct = False;
2317 if (!cli_close(&cli2, fnum2)) {
2318 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2319 *shared_correct = False;
2327 /* Ensure cli1 processes the break. */
2329 if (cli_read(&cli1, fnum1, buf, 0, 4) != 4) {
2330 printf("read on fnum1 failed (%s)\n", cli_errstr(&cli1));
2334 /* Should now be at level II. */
2335 /* Test if sending a write locks causes a break to none. */
2337 if (!cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2338 printf("lock failed (%s)\n", cli_errstr(&cli1));
2342 cli_unlock(&cli1, fnum1, 0, 4);
2346 if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2347 printf("lock failed (%s)\n", cli_errstr(&cli1));
2351 cli_unlock(&cli1, fnum1, 0, 4);
2355 cli_read(&cli1, fnum1, buf, 0, 4);
2358 if (cli_write(&cli1, fnum1, 0, buf, 0, 4) != 4) {
2359 printf("write on fnum1 failed (%s)\n", cli_errstr(&cli1));
2364 if (!cli_close(&cli1, fnum1)) {
2365 printf("close1 failed (%s)\n", cli_errstr(&cli1));
2371 if (!cli_unlink(&cli1, fname)) {
2372 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2376 if (!close_connection(&cli1)) {
2380 if (!*shared_correct) {
2384 printf("finished oplock test 2\n");
2389 /* handler for oplock 3 tests */
2390 static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2392 printf("got oplock break fnum=%d level=%d\n",
2394 return cli_oplock_ack(cli, fnum, level);
2397 static BOOL run_oplock3(int dummy)
2399 static struct cli_state cli;
2400 char *fname = "\\oplockt3.dat";
2402 char buf[4] = "abcd";
2403 BOOL correct = True;
2404 volatile BOOL *shared_correct;
2406 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2407 *shared_correct = True;
2409 printf("starting oplock test 3\n");
2414 use_level_II_oplocks = True;
2415 if (!open_connection(&cli)) {
2416 *shared_correct = False;
2420 /* try to trigger a oplock break in parent */
2421 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2422 cli_write(&cli, fnum, 0, buf, 0, 4);
2428 use_level_II_oplocks = True;
2429 if (!open_connection(&cli)) {
2432 cli_oplock_handler(&cli, oplock3_handler);
2433 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2434 cli_write(&cli, fnum, 0, buf, 0, 4);
2435 cli_close(&cli, fnum);
2436 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2437 cli.timeout = 20000;
2438 cli_receive_smb(&cli);
2439 printf("finished oplock test 3\n");
2441 return (correct && *shared_correct);
2443 /* What are we looking for here? What's sucess and what's FAILURE? */
2449 Test delete on close semantics.
2451 static BOOL run_deletetest(int dummy)
2453 static struct cli_state cli1;
2454 static struct cli_state cli2;
2455 char *fname = "\\delete.file";
2457 BOOL correct = True;
2459 printf("starting delete test\n");
2461 if (!open_connection(&cli1)) {
2465 cli_sockopt(&cli1, sockops);
2467 /* Test 1 - this should *NOT* delete the file on close. */
2469 cli_setatr(&cli1, fname, 0, 0);
2470 cli_unlink(&cli1, fname);
2472 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2473 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, DELETE_ON_CLOSE_FLAG);
2476 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2480 if (!cli_close(&cli1, fnum1)) {
2481 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2485 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
2487 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2491 if (!cli_close(&cli1, fnum1)) {
2492 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2496 printf("first delete on close test succeeded.\n");
2498 /* Test 2 - this should delete the file on close. */
2500 cli_setatr(&cli1, fname, 0, 0);
2501 cli_unlink(&cli1, fname);
2503 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS,
2504 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
2507 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2511 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2512 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2516 if (!cli_close(&cli1, fnum1)) {
2517 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2521 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2523 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2524 if (!cli_close(&cli1, fnum1)) {
2525 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2528 cli_unlink(&cli1, fname);
2530 printf("second delete on close test succeeded.\n");
2534 cli_setatr(&cli1, fname, 0, 0);
2535 cli_unlink(&cli1, fname);
2537 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2538 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2541 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2545 /* This should fail with a sharing violation - open for delete is only compatible
2546 with SHARE_DELETE. */
2548 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2549 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0);
2552 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2556 /* This should succeed. */
2558 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2559 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2562 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2566 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2567 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2571 if (!cli_close(&cli1, fnum1)) {
2572 printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1));
2576 if (!cli_close(&cli1, fnum2)) {
2577 printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1));
2581 /* This should fail - file should no longer be there. */
2583 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2585 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2586 if (!cli_close(&cli1, fnum1)) {
2587 printf("[3] close failed (%s)\n", cli_errstr(&cli1));
2589 cli_unlink(&cli1, fname);
2592 printf("third delete on close test succeeded.\n");
2595 cli_setatr(&cli1, fname, 0, 0);
2596 cli_unlink(&cli1, fname);
2598 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2599 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2602 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2606 /* This should succeed. */
2607 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2608 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2610 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2614 if (!cli_close(&cli1, fnum2)) {
2615 printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1));
2619 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2620 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2624 /* This should fail - no more opens once delete on close set. */
2625 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2626 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2628 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2631 printf("fourth delete on close test succeeded.\n");
2633 if (!cli_close(&cli1, fnum1)) {
2634 printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1));
2639 cli_setatr(&cli1, fname, 0, 0);
2640 cli_unlink(&cli1, fname);
2642 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
2644 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2648 /* This should fail - only allowed on NT opens with DELETE access. */
2650 if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2651 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2655 if (!cli_close(&cli1, fnum1)) {
2656 printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1));
2660 printf("fifth delete on close test succeeded.\n");
2663 cli_setatr(&cli1, fname, 0, 0);
2664 cli_unlink(&cli1, fname);
2666 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2667 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2668 FILE_OVERWRITE_IF, 0);
2671 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2675 /* This should fail - only allowed on NT opens with DELETE access. */
2677 if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2678 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2682 if (!cli_close(&cli1, fnum1)) {
2683 printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1));
2687 printf("sixth delete on close test succeeded.\n");
2690 cli_setatr(&cli1, fname, 0, 0);
2691 cli_unlink(&cli1, fname);
2693 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2694 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0);
2697 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2701 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2702 printf("[7] setting delete_on_close on file failed !\n");
2706 if (!cli_nt_delete_on_close(&cli1, fnum1, False)) {
2707 printf("[7] unsetting delete_on_close on file failed !\n");
2711 if (!cli_close(&cli1, fnum1)) {
2712 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2716 /* This next open should succeed - we reset the flag. */
2718 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2720 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2724 if (!cli_close(&cli1, fnum1)) {
2725 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2729 printf("seventh delete on close test succeeded.\n");
2732 cli_setatr(&cli1, fname, 0, 0);
2733 cli_unlink(&cli1, fname);
2735 if (!open_connection(&cli2)) {
2736 printf("[8] failed to open second connection.\n");
2740 cli_sockopt(&cli1, sockops);
2742 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2743 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
2746 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2750 fnum2 = cli_nt_create_full(&cli2, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2751 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2754 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2758 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2759 printf("[8] setting delete_on_close on file failed !\n");
2763 if (!cli_close(&cli1, fnum1)) {
2764 printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1));
2768 if (!cli_close(&cli2, fnum2)) {
2769 printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2));
2773 /* This should fail.. */
2774 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2776 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2777 if (!cli_close(&cli1, fnum1)) {
2778 printf("[8] close failed (%s)\n", cli_errstr(&cli1));
2780 cli_unlink(&cli1, fname);
2783 printf("eighth delete on close test succeeded.\n");
2785 printf("finished delete test\n");
2787 cli_setatr(&cli1, fname, 0, 0);
2788 cli_unlink(&cli1, fname);
2790 if (!close_connection(&cli1)) {
2793 if (!close_connection(&cli2)) {
2800 Test open mode returns on read-only files.
2802 static BOOL run_opentest(int dummy)
2804 static struct cli_state cli1;
2805 char *fname = "\\readonly.file";
2809 BOOL correct = True;
2811 printf("starting open test\n");
2813 if (!open_connection(&cli1)) {
2817 cli_setatr(&cli1, fname, 0, 0);
2818 cli_unlink(&cli1, fname);
2820 cli_sockopt(&cli1, sockops);
2822 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2824 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2828 if (!cli_close(&cli1, fnum1)) {
2829 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2833 if (!cli_setatr(&cli1, fname, aRONLY, 0)) {
2834 printf("cli_setatr failed (%s)\n", cli_errstr(&cli1));
2838 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
2840 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2844 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
2845 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
2847 if (check_error(&cli1, ERRDOS, ERRnoaccess, 0)) {
2848 printf("correct error code ERRDOS/ERRnoaccess returned\n");
2851 printf("finished open test 1\n");
2853 cli_close(&cli1, fnum1);
2855 /* Now try not readonly and ensure ERRbadshare is returned. */
2857 cli_setatr(&cli1, fname, 0, 0);
2859 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
2861 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2865 /* This will fail - but the error should be ERRshare. */
2866 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
2868 if (check_error(&cli1, ERRDOS, ERRbadshare, 0)) {
2869 printf("correct error code ERRDOS/ERRbadshare returned\n");
2872 if (!cli_close(&cli1, fnum1)) {
2873 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2877 cli_unlink(&cli1, fname);
2879 printf("finished open test 2\n");
2881 /* Test truncate open disposition on file opened for read. */
2883 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2885 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(&cli1));
2889 /* write 20 bytes. */
2891 memset(buf, '\0', 20);
2893 if (cli_write(&cli1, fnum1, 0, buf, 0, 20) != 20) {
2894 printf("write failed (%s)\n", cli_errstr(&cli1));
2898 if (!cli_close(&cli1, fnum1)) {
2899 printf("(3) close1 failed (%s)\n", cli_errstr(&cli1));
2903 /* Ensure size == 20. */
2904 if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
2905 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
2910 printf("(3) file size != 20\n");
2914 /* Now test if we can truncate a file opened for readonly. */
2916 fnum1 = cli_open(&cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
2918 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(&cli1));
2922 if (!cli_close(&cli1, fnum1)) {
2923 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2927 /* Ensure size == 0. */
2928 if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
2929 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
2934 printf("(3) file size != 0\n");
2937 printf("finished open test 3\n");
2939 cli_unlink(&cli1, fname);
2942 printf("testing ctemp\n");
2945 fnum1 = cli_ctemp(&cli1, "\\", &tmp_path);
2947 printf("ctemp failed (%s)\n", cli_errstr(&cli1));
2950 printf("ctemp gave path %s\n", tmp_path);
2951 cli_close(&cli1, fnum1);
2952 cli_unlink(&cli1, tmp_path);
2955 if (!close_connection(&cli1)) {
2962 static void list_fn(file_info *finfo, const char *name, void *state)
2968 test directory listing speed
2970 static BOOL run_dirtest(int dummy)
2973 static struct cli_state cli;
2976 BOOL correct = True;
2978 printf("starting directory test\n");
2980 if (!open_connection(&cli)) {
2984 cli_sockopt(&cli, sockops);
2987 for (i=0;i<numops;i++) {
2989 slprintf(fname, sizeof(fname), "%x", (int)random());
2990 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2992 fprintf(stderr,"Failed to open %s\n", fname);
2995 cli_close(&cli, fnum);
3000 printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
3001 printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
3002 printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
3004 printf("dirtest core %g seconds\n", end_timer() - t1);
3007 for (i=0;i<numops;i++) {
3009 slprintf(fname, sizeof(fname), "%x", (int)random());
3010 cli_unlink(&cli, fname);
3013 if (!close_connection(&cli)) {
3017 printf("finished dirtest\n");
3024 static double create_procs(BOOL (*fn)(int), BOOL *result)
3027 volatile pid_t *child_status;
3028 volatile BOOL *child_status_out;
3034 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
3035 if (!child_status) {
3036 printf("Failed to setup shared memory\n");
3040 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
3041 if (!child_status_out) {
3042 printf("Failed to setup result status shared memory\n");
3046 memset(child_status, 0, sizeof(pid_t)*nprocs);
3047 memset(child_status_out, True, sizeof(BOOL)*nprocs);
3051 for (i=0;i<nprocs;i++) {
3054 pid_t mypid = getpid();
3055 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
3057 slprintf(myname,sizeof(myname),"CLIENT%d", i);
3060 memset(¤t_cli, 0, sizeof(current_cli));
3061 if (open_connection(¤t_cli)) break;
3063 printf("pid %d failed to start\n", (int)getpid());
3069 child_status[i] = getpid();
3071 while (child_status[i]) msleep(2);
3073 child_status_out[i] = fn(i);
3080 for (i=0;i<nprocs;i++) {
3081 if (child_status[i]) synccount++;
3083 if (synccount == nprocs) break;
3085 } while (end_timer() < 30);
3087 if (synccount != nprocs) {
3088 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
3093 /* start the client load */
3096 for (i=0;i<nprocs;i++) {
3097 child_status[i] = 0;
3100 printf("%d clients started\n", nprocs);
3102 for (i=0;i<nprocs;i++) {
3103 waitpid(0, &status, 0);
3109 for (i=0;i<nprocs;i++) {
3110 if (!child_status_out[i]) {
3118 #define FLAG_MULTIPROC 1
3125 {"FDPASS", run_fdpasstest, 0},
3126 {"LOCK1", run_locktest1, 0},
3127 {"LOCK2", run_locktest2, 0},
3128 {"LOCK3", run_locktest3, 0},
3129 {"LOCK4", run_locktest4, 0},
3130 {"LOCK5", run_locktest5, 0},
3131 {"UNLINK", run_unlinktest, 0},
3132 {"BROWSE", run_browsetest, 0},
3133 {"ATTR", run_attrtest, 0},
3134 {"TRANS2", run_trans2test, 0},
3135 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
3136 {"TORTURE",run_torture, FLAG_MULTIPROC},
3137 {"RANDOMIPC", run_randomipc, 0},
3138 {"NEGNOWAIT", run_negprot_nowait, 0},
3139 {"NBW95", run_nbw95, 0},
3140 {"NBWNT", run_nbwnt, 0},
3141 {"OPLOCK1", run_oplock1, 0},
3142 {"OPLOCK2", run_oplock2, 0},
3143 {"OPLOCK3", run_oplock3, 0},
3144 {"DIR", run_dirtest, 0},
3145 {"DENY1", run_denytest1, 0},
3146 {"DENY2", run_denytest2, 0},
3147 {"TCON", run_tcon_test, 0},
3148 {"RW1", run_readwritetest, 0},
3149 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
3150 {"RW3", run_readwritelarge, 0},
3151 {"OPEN", run_opentest, 0},
3152 {"DELETE", run_deletetest, 0},
3153 {"W2K", run_w2ktest, 0},
3158 /****************************************************************************
3159 run a specified test or "ALL"
3160 ****************************************************************************/
3161 static BOOL run_test(char *name)
3167 if (strequal(name,"ALL")) {
3168 for (i=0;torture_ops[i].name;i++) {
3169 run_test(torture_ops[i].name);
3173 for (i=0;torture_ops[i].name;i++) {
3174 snprintf(randomfname, sizeof(randomfname), "\\XX%x",
3175 (unsigned)random());
3177 if (strequal(name, torture_ops[i].name)) {
3178 printf("Running %s\n", name);
3179 if (torture_ops[i].flags & FLAG_MULTIPROC) {
3180 t = create_procs(torture_ops[i].fn, &result);
3183 printf("TEST %s FAILED!\n", name);
3188 if (!torture_ops[i].fn(0)) {
3190 printf("TEST %s FAILED!\n", name);
3194 printf("%s took %g secs\n\n", name, t);
3201 static void usage(void)
3205 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
3207 printf("\t-d debuglevel\n");
3208 printf("\t-U user%%pass\n");
3209 printf("\t-N numprocs\n");
3210 printf("\t-n my_netbios_name\n");
3211 printf("\t-W workgroup\n");
3212 printf("\t-o num_operations\n");
3213 printf("\t-O socket_options\n");
3214 printf("\t-m maximum protocol\n");
3215 printf("\t-L use oplocks\n");
3218 printf("tests are:");
3219 for (i=0;torture_ops[i].name;i++) {
3220 printf(" %s", torture_ops[i].name);
3224 printf("default test is ALL\n");
3233 /****************************************************************************
3235 ****************************************************************************/
3236 int main(int argc,char *argv[])
3241 extern char *optarg;
3244 static pstring servicesf = CONFIGFILE;
3245 BOOL correct = True;
3249 #ifdef HAVE_SETBUFFER
3250 setbuffer(stdout, NULL, 0);
3253 lp_load(servicesf,True,False,False);
3260 for(p = argv[1]; *p; p++)
3264 if (strncmp(argv[1], "//", 2)) {
3268 fstrcpy(host, &argv[1][2]);
3269 p = strchr_m(&host[2],'/');
3274 fstrcpy(share, p+1);
3278 if (*username == 0 && getenv("LOGNAME")) {
3279 pstrcpy(username,getenv("LOGNAME"));
3286 fstrcpy(workgroup, lp_workgroup());
3288 while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:Ld:")) != EOF) {
3291 fstrcpy(workgroup,optarg);
3294 max_protocol = interpret_protocol(optarg, max_protocol);
3297 nprocs = atoi(optarg);
3300 numops = atoi(optarg);
3303 DEBUGLEVEL = atoi(optarg);
3312 fstrcpy(myname, optarg);
3315 pstrcpy(username,optarg);
3316 p = strchr_m(username,'%');
3319 pstrcpy(password, p+1);
3324 printf("Unknown option %c (%d)\n", (char)opt, opt);
3331 p = getpass("Password:");
3333 pstrcpy(password, p);
3338 printf("host=%s share=%s user=%s myname=%s\n",
3339 host, share, username, myname);
3342 correct = run_test("ALL");
3344 for (i=1;i<argc;i++) {
3345 if (!run_test(argv[i])) {