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(int line, 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 (line=%d)\n",
186 (int)eclass, (int)ecode, (int)nterr, line);
195 status = cli_nt_error(c);
197 if (nterr != status) {
198 printf("unexpected error code 0x%08x\n", status);
199 printf(" expected 0x%08x (line=%d)\n", nterr, line);
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(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) 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(__LINE__, &cli2, ERRDOS, ERRlock,
806 NT_STATUS_LOCK_NOT_GRANTED)) return False;
810 printf("Testing lock timeouts\n");
812 if (cli_lock(&cli2, fnum3, 0, 4, 10*1000, WRITE_LOCK)) {
813 printf("lock3 succeeded! This is a locking bug\n");
816 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock,
817 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
822 printf("error: This server appears not to support timed lock requests\n");
825 if (!cli_close(&cli1, fnum2)) {
826 printf("close1 failed (%s)\n", cli_errstr(&cli1));
830 if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
831 printf("lock4 succeeded! This is a locking bug\n");
834 if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock,
835 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
838 if (!cli_close(&cli1, fnum1)) {
839 printf("close2 failed (%s)\n", cli_errstr(&cli1));
843 if (!cli_close(&cli2, fnum3)) {
844 printf("close3 failed (%s)\n", cli_errstr(&cli2));
848 if (!cli_unlink(&cli1, fname)) {
849 printf("unlink failed (%s)\n", cli_errstr(&cli1));
854 if (!close_connection(&cli1)) {
858 if (!close_connection(&cli2)) {
862 printf("Passed locktest1\n");
867 checks for correct tconX support
869 static BOOL run_tcon_test(int dummy)
871 static struct cli_state cli1;
872 char *fname = "\\tcontest.tmp";
877 if (!open_connection(&cli1)) {
880 cli_sockopt(&cli1, sockops);
882 printf("starting tcontest\n");
884 cli_unlink(&cli1, fname);
886 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
889 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
895 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4)
897 printf("write failed (%s)", cli_errstr(&cli1));
901 if (!cli_send_tconX(&cli1, share, "?????",
902 password, strlen(password)+1)) {
903 printf("%s refused 2nd tree connect (%s)\n", host,
909 if (cli_write(&cli1, fnum1, 0, buf, 130, 4) == 4)
911 printf("write succeeded (%s)", cli_errstr(&cli1));
915 if (cli_close(&cli1, fnum1)) {
916 printf("close2 succeeded (%s)\n", cli_errstr(&cli1));
920 if (!cli_tdis(&cli1)) {
921 printf("tdis failed (%s)\n", cli_errstr(&cli1));
927 if (!cli_close(&cli1, fnum1)) {
928 printf("close2 failed (%s)\n", cli_errstr(&cli1));
932 if (!close_connection(&cli1)) {
936 printf("Passed tcontest\n");
942 This test checks that
944 1) the server supports multiple locking contexts on the one SMB
945 connection, distinguished by PID.
947 2) the server correctly fails overlapping locks made by the same PID (this
948 goes against POSIX behaviour, which is why it is tricky to implement)
950 3) the server denies unlock requests by an incorrect client PID
952 static BOOL run_locktest2(int dummy)
954 static struct cli_state cli;
955 char *fname = "\\lockt2.lck";
956 int fnum1, fnum2, fnum3;
959 if (!open_connection(&cli)) {
963 cli_sockopt(&cli, sockops);
965 printf("starting locktest2\n");
967 cli_unlink(&cli, fname);
971 fnum1 = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
973 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
977 fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
979 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli));
985 fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
987 printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli));
993 if (!cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
994 printf("lock1 failed (%s)\n", cli_errstr(&cli));
998 if (cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
999 printf("WRITE lock1 succeeded! This is a locking bug\n");
1002 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock,
1003 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1006 if (cli_lock(&cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1007 printf("WRITE lock2 succeeded! This is a locking bug\n");
1010 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock,
1011 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1014 if (cli_lock(&cli, fnum2, 0, 4, 0, READ_LOCK)) {
1015 printf("READ lock2 succeeded! This is a locking bug\n");
1018 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock,
1019 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1022 if (!cli_lock(&cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1023 printf("lock at 100 failed (%s)\n", cli_errstr(&cli));
1025 cli_setpid(&cli, 2);
1026 if (cli_unlock(&cli, fnum1, 100, 4)) {
1027 printf("unlock at 100 succeeded! This is a locking bug\n");
1031 if (cli_unlock(&cli, fnum1, 0, 4)) {
1032 printf("unlock1 succeeded! This is a locking bug\n");
1035 if (!check_error(__LINE__, &cli,
1036 ERRDOS, ERRnotlocked,
1037 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1040 if (cli_unlock(&cli, fnum1, 0, 8)) {
1041 printf("unlock2 succeeded! This is a locking bug\n");
1044 if (!check_error(__LINE__, &cli,
1045 ERRDOS, ERRnotlocked,
1046 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1049 if (cli_lock(&cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1050 printf("lock3 succeeded! This is a locking bug\n");
1053 if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1056 cli_setpid(&cli, 1);
1058 if (!cli_close(&cli, fnum1)) {
1059 printf("close1 failed (%s)\n", cli_errstr(&cli));
1063 if (!cli_close(&cli, fnum2)) {
1064 printf("close2 failed (%s)\n", cli_errstr(&cli));
1068 if (!cli_close(&cli, fnum3)) {
1069 printf("close3 failed (%s)\n", cli_errstr(&cli));
1073 if (!close_connection(&cli)) {
1077 printf("locktest2 finished\n");
1084 This test checks that
1086 1) the server supports the full offset range in lock requests
1088 static BOOL run_locktest3(int dummy)
1090 static struct cli_state cli1, cli2;
1091 char *fname = "\\lockt3.lck";
1092 int fnum1, fnum2, i;
1094 BOOL correct = True;
1096 #define NEXT_OFFSET offset += (~(uint32)0) / numops
1098 if (!open_connection(&cli1) || !open_connection(&cli2)) {
1101 cli_sockopt(&cli1, sockops);
1102 cli_sockopt(&cli2, sockops);
1104 printf("starting locktest3\n");
1106 cli_unlink(&cli1, fname);
1108 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1110 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1113 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1115 printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
1119 for (offset=i=0;i<numops;i++) {
1121 if (!cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1122 printf("lock1 %d failed (%s)\n",
1128 if (!cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1129 printf("lock2 %d failed (%s)\n",
1136 for (offset=i=0;i<numops;i++) {
1139 if (cli_lock(&cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1140 printf("error: lock1 %d succeeded!\n", i);
1144 if (cli_lock(&cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1145 printf("error: lock2 %d succeeded!\n", i);
1149 if (cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1150 printf("error: lock3 %d succeeded!\n", i);
1154 if (cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1155 printf("error: lock4 %d succeeded!\n", i);
1160 for (offset=i=0;i<numops;i++) {
1163 if (!cli_unlock(&cli1, fnum1, offset-1, 1)) {
1164 printf("unlock1 %d failed (%s)\n",
1170 if (!cli_unlock(&cli2, fnum2, offset-2, 1)) {
1171 printf("unlock2 %d failed (%s)\n",
1178 if (!cli_close(&cli1, fnum1)) {
1179 printf("close1 failed (%s)\n", cli_errstr(&cli1));
1183 if (!cli_close(&cli2, fnum2)) {
1184 printf("close2 failed (%s)\n", cli_errstr(&cli2));
1188 if (!cli_unlink(&cli1, fname)) {
1189 printf("unlink failed (%s)\n", cli_errstr(&cli1));
1193 if (!close_connection(&cli1)) {
1197 if (!close_connection(&cli2)) {
1201 printf("finished locktest3\n");
1206 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1207 printf("** "); correct = False; \
1211 looks at overlapping locks
1213 static BOOL run_locktest4(int dummy)
1215 static struct cli_state cli1, cli2;
1216 char *fname = "\\lockt4.lck";
1217 int fnum1, fnum2, f;
1220 BOOL correct = True;
1222 if (!open_connection(&cli1) || !open_connection(&cli2)) {
1226 cli_sockopt(&cli1, sockops);
1227 cli_sockopt(&cli2, sockops);
1229 printf("starting locktest4\n");
1231 cli_unlink(&cli1, fname);
1233 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1234 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1236 memset(buf, 0, sizeof(buf));
1238 if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1239 printf("Failed to create file\n");
1244 ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1245 cli_lock(&cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1246 EXPECTED(ret, False);
1247 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1249 ret = cli_lock(&cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1250 cli_lock(&cli1, fnum1, 12, 4, 0, READ_LOCK);
1251 EXPECTED(ret, True);
1252 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1254 ret = cli_lock(&cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1255 cli_lock(&cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1256 EXPECTED(ret, False);
1257 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1259 ret = cli_lock(&cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1260 cli_lock(&cli2, fnum2, 32, 4, 0, READ_LOCK);
1261 EXPECTED(ret, True);
1262 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1264 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1265 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1266 EXPECTED(ret, False);
1267 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1269 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1270 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 52, 4, 0, READ_LOCK));
1271 EXPECTED(ret, True);
1272 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1274 ret = cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1275 cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK);
1276 EXPECTED(ret, True);
1277 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1279 ret = cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1280 cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1281 EXPECTED(ret, False);
1282 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1284 ret = cli_lock(&cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1285 cli_lock(&cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1286 EXPECTED(ret, False);
1287 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1289 ret = cli_lock(&cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1290 cli_lock(&cli1, fnum1, 90, 4, 0, READ_LOCK);
1291 EXPECTED(ret, True);
1292 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1294 ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1295 (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 100, 4, 0, READ_LOCK));
1296 EXPECTED(ret, False);
1297 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1299 ret = cli_lock(&cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1300 cli_lock(&cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1301 cli_unlock(&cli1, fnum1, 110, 6);
1302 EXPECTED(ret, False);
1303 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1306 ret = cli_lock(&cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1307 (cli_read(&cli2, fnum2, buf, 120, 4) == 4);
1308 EXPECTED(ret, False);
1309 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1311 ret = cli_lock(&cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1312 (cli_write(&cli2, fnum2, 0, buf, 130, 4) == 4);
1313 EXPECTED(ret, False);
1314 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1317 ret = cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1318 cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1319 cli_unlock(&cli1, fnum1, 140, 4) &&
1320 cli_unlock(&cli1, fnum1, 140, 4);
1321 EXPECTED(ret, True);
1322 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1325 ret = cli_lock(&cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1326 cli_lock(&cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1327 cli_unlock(&cli1, fnum1, 150, 4) &&
1328 (cli_read(&cli2, fnum2, buf, 150, 4) == 4) &&
1329 !(cli_write(&cli2, fnum2, 0, buf, 150, 4) == 4) &&
1330 cli_unlock(&cli1, fnum1, 150, 4);
1331 EXPECTED(ret, True);
1332 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1334 ret = cli_lock(&cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1335 cli_unlock(&cli1, fnum1, 160, 4) &&
1336 (cli_write(&cli2, fnum2, 0, buf, 160, 4) == 4) &&
1337 (cli_read(&cli2, fnum2, buf, 160, 4) == 4);
1338 EXPECTED(ret, True);
1339 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1341 ret = cli_lock(&cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1342 cli_unlock(&cli1, fnum1, 170, 4) &&
1343 (cli_write(&cli2, fnum2, 0, buf, 170, 4) == 4) &&
1344 (cli_read(&cli2, fnum2, buf, 170, 4) == 4);
1345 EXPECTED(ret, True);
1346 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1348 ret = cli_lock(&cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1349 cli_lock(&cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1350 cli_unlock(&cli1, fnum1, 190, 4) &&
1351 !(cli_write(&cli2, fnum2, 0, buf, 190, 4) == 4) &&
1352 (cli_read(&cli2, fnum2, buf, 190, 4) == 4);
1353 EXPECTED(ret, True);
1354 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1356 cli_close(&cli1, fnum1);
1357 cli_close(&cli2, fnum2);
1358 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1359 f = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1360 ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1361 cli_lock(&cli1, f, 0, 1, 0, READ_LOCK) &&
1362 cli_close(&cli1, fnum1) &&
1363 ((fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1364 cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1365 cli_close(&cli1, f);
1366 EXPECTED(ret, True);
1367 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1370 cli_close(&cli1, fnum1);
1371 cli_close(&cli2, fnum2);
1372 cli_unlink(&cli1, fname);
1373 close_connection(&cli1);
1374 close_connection(&cli2);
1376 printf("finished locktest4\n");
1381 looks at lock upgrade/downgrade.
1383 static BOOL run_locktest5(int dummy)
1385 static struct cli_state cli1, cli2;
1386 char *fname = "\\lockt5.lck";
1387 int fnum1, fnum2, fnum3;
1390 BOOL correct = True;
1392 if (!open_connection(&cli1) || !open_connection(&cli2)) {
1396 cli_sockopt(&cli1, sockops);
1397 cli_sockopt(&cli2, sockops);
1399 printf("starting locktest5\n");
1401 cli_unlink(&cli1, fname);
1403 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1404 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
1405 fnum3 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1407 memset(buf, 0, sizeof(buf));
1409 if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1410 printf("Failed to create file\n");
1415 /* Check for NT bug... */
1416 ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1417 cli_lock(&cli1, fnum3, 0, 1, 0, READ_LOCK);
1418 cli_close(&cli1, fnum1);
1419 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1420 ret = cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1421 EXPECTED(ret, True);
1422 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1423 cli_close(&cli1, fnum1);
1424 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
1425 cli_unlock(&cli1, fnum3, 0, 1);
1427 ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1428 cli_lock(&cli1, fnum1, 1, 1, 0, READ_LOCK);
1429 EXPECTED(ret, True);
1430 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1432 ret = cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1433 EXPECTED(ret, False);
1435 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1437 /* Unlock the process 2 lock. */
1438 cli_unlock(&cli2, fnum2, 0, 4);
1440 ret = cli_lock(&cli1, fnum3, 0, 4, 0, READ_LOCK);
1441 EXPECTED(ret, False);
1443 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1445 /* Unlock the process 1 fnum3 lock. */
1446 cli_unlock(&cli1, fnum3, 0, 4);
1448 /* Stack 2 more locks here. */
1449 ret = cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1450 cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK);
1452 EXPECTED(ret, True);
1453 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1455 /* Unlock the first process lock, then check this was the WRITE lock that was
1458 ret = cli_unlock(&cli1, fnum1, 0, 4) &&
1459 cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
1461 EXPECTED(ret, True);
1462 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1464 /* Unlock the process 2 lock. */
1465 cli_unlock(&cli2, fnum2, 0, 4);
1467 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1469 ret = cli_unlock(&cli1, fnum1, 1, 1) &&
1470 cli_unlock(&cli1, fnum1, 0, 4) &&
1471 cli_unlock(&cli1, fnum1, 0, 4);
1473 EXPECTED(ret, True);
1474 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1476 /* Ensure the next unlock fails. */
1477 ret = cli_unlock(&cli1, fnum1, 0, 4);
1478 EXPECTED(ret, False);
1479 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1481 /* Ensure connection 2 can get a write lock. */
1482 ret = cli_lock(&cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1483 EXPECTED(ret, True);
1485 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1489 cli_close(&cli1, fnum1);
1490 cli_close(&cli2, fnum2);
1491 cli_unlink(&cli1, fname);
1492 if (!close_connection(&cli1)) {
1495 if (!close_connection(&cli2)) {
1499 printf("finished locktest5\n");
1506 this produces a matrix of deny mode behaviour
1508 static BOOL run_denytest1(int dummy)
1510 static struct cli_state cli1, cli2;
1512 int f, d1, d2, o1, o2, x=0;
1513 char *fnames[] = {"\\denytest1.exe", "\\denytest1.dat", NULL};
1518 {DENY_DOS, "DENY_DOS"},
1519 {DENY_ALL, "DENY_ALL"},
1520 {DENY_WRITE, "DENY_WRITE"},
1521 {DENY_READ, "DENY_READ"},
1522 {DENY_NONE, "DENY_NONE"},
1523 {DENY_FCB, "DENY_FCB"},
1530 {O_RDONLY, "O_RDONLY"},
1531 {O_WRONLY, "O_WRONLY"},
1533 BOOL correct = True;
1535 if (!open_connection(&cli1) || !open_connection(&cli2)) {
1538 cli_sockopt(&cli1, sockops);
1539 cli_sockopt(&cli2, sockops);
1541 printf("starting denytest1\n");
1543 for (f=0;fnames[f];f++) {
1544 cli_unlink(&cli1, fnames[f]);
1546 fnum1 = cli_open(&cli1, fnames[f], O_RDWR|O_CREAT, DENY_NONE);
1547 cli_write(&cli1, fnum1, 0, fnames[f], 0, strlen(fnames[f]));
1548 cli_close(&cli1, fnum1);
1550 for (d1=0;deny_modes[d1].name;d1++)
1551 for (o1=0;open_modes[o1].name;o1++)
1552 for (d2=0;deny_modes[d2].name;d2++)
1553 for (o2=0;open_modes[o2].name;o2++) {
1554 fnum1 = cli_open(&cli1, fnames[f],
1557 fnum2 = cli_open(&cli2, fnames[f],
1561 printf("%s %8s %10s %8s %10s ",
1563 open_modes[o1].name,
1564 deny_modes[d1].name,
1565 open_modes[o2].name,
1566 deny_modes[d2].name);
1570 } else if (fnum2 == -1) {
1573 if (cli_read(&cli2, fnum2, (void *)&x, 0, 1) == 1) {
1576 if (cli_write(&cli2, fnum2, 0, (void *)&x, 0, 1) == 1) {
1582 cli_close(&cli1, fnum1);
1583 cli_close(&cli2, fnum2);
1586 cli_unlink(&cli1, fnames[f]);
1589 if (!close_connection(&cli1)) {
1592 if (!close_connection(&cli2)) {
1596 printf("finshed denytest1\n");
1602 this produces a matrix of deny mode behaviour for two opens on the
1605 static BOOL run_denytest2(int dummy)
1607 static struct cli_state cli1;
1609 int f, d1, d2, o1, o2, x=0;
1610 char *fnames[] = {"\\denytest2.exe", "\\denytest2.dat", NULL};
1615 {DENY_DOS, "DENY_DOS"},
1616 {DENY_ALL, "DENY_ALL"},
1617 {DENY_WRITE, "DENY_WRITE"},
1618 {DENY_READ, "DENY_READ"},
1619 {DENY_NONE, "DENY_NONE"},
1620 {DENY_FCB, "DENY_FCB"},
1627 {O_RDONLY, "O_RDONLY"},
1628 {O_WRONLY, "O_WRONLY"},
1630 BOOL correct = True;
1632 if (!open_connection(&cli1)) {
1635 cli_sockopt(&cli1, sockops);
1637 printf("starting denytest2\n");
1639 for (f=0;fnames[f];f++) {
1640 cli_unlink(&cli1, fnames[f]);
1642 fnum1 = cli_open(&cli1, fnames[f], O_RDWR|O_CREAT, DENY_NONE);
1643 cli_write(&cli1, fnum1, 0, fnames[f], 0, strlen(fnames[f]));
1644 cli_close(&cli1, fnum1);
1646 for (d1=0;deny_modes[d1].name;d1++)
1647 for (o1=0;open_modes[o1].name;o1++)
1648 for (d2=0;deny_modes[d2].name;d2++)
1649 for (o2=0;open_modes[o2].name;o2++) {
1650 fnum1 = cli_open(&cli1, fnames[f],
1653 fnum2 = cli_open(&cli1, fnames[f],
1657 printf("%s %8s %10s %8s %10s ",
1659 open_modes[o1].name,
1660 deny_modes[d1].name,
1661 open_modes[o2].name,
1662 deny_modes[d2].name);
1666 } else if (fnum2 == -1) {
1669 if (cli_read(&cli1, fnum2, (void *)&x, 0, 1) == 1) {
1672 if (cli_write(&cli1, fnum2, 0, (void *)&x, 0, 1) == 1) {
1678 cli_close(&cli1, fnum1);
1679 cli_close(&cli1, fnum2);
1682 cli_unlink(&cli1, fnames[f]);
1685 if (!close_connection(&cli1)) {
1689 printf("finshed denytest2\n");
1694 test whether fnums and tids open on one VC are available on another (a major
1697 static BOOL run_fdpasstest(int dummy)
1699 static struct cli_state cli1, cli2, cli3;
1700 char *fname = "\\fdpass.tst";
1704 if (!open_connection(&cli1) || !open_connection(&cli2)) {
1707 cli_sockopt(&cli1, sockops);
1708 cli_sockopt(&cli2, sockops);
1710 printf("starting fdpasstest\n");
1712 cli_unlink(&cli1, fname);
1714 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1716 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
1720 if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
1721 printf("write failed (%s)\n", cli_errstr(&cli1));
1726 cli3.vuid = cli1.vuid;
1727 cli3.cnum = cli1.cnum;
1728 cli3.pid = cli1.pid;
1730 if (cli_read(&cli3, fnum1, buf, 0, 13) == 13) {
1731 printf("read succeeded! nasty security hole [%s]\n",
1736 cli_close(&cli1, fnum1);
1737 cli_unlink(&cli1, fname);
1739 close_connection(&cli1);
1740 close_connection(&cli2);
1742 printf("finished fdpasstest\n");
1748 This test checks that
1750 1) the server does not allow an unlink on a file that is open
1752 static BOOL run_unlinktest(int dummy)
1754 static struct cli_state cli;
1755 char *fname = "\\unlink.tst";
1757 BOOL correct = True;
1759 if (!open_connection(&cli)) {
1763 cli_sockopt(&cli, sockops);
1765 printf("starting unlink test\n");
1767 cli_unlink(&cli, fname);
1769 cli_setpid(&cli, 1);
1771 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1773 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
1777 if (cli_unlink(&cli, fname)) {
1778 printf("error: server allowed unlink on an open file\n");
1781 correct = check_error(__LINE__, &cli, ERRDOS, ERRbadshare,
1782 NT_STATUS_SHARING_VIOLATION);
1785 cli_close(&cli, fnum);
1786 cli_unlink(&cli, fname);
1788 if (!close_connection(&cli)) {
1792 printf("unlink test finished\n");
1799 test how many open files this server supports on the one socket
1801 static BOOL run_maxfidtest(int dummy)
1803 static struct cli_state cli;
1804 char *template = "\\maxfid.%d.%d";
1806 int fnums[0x11000], i;
1808 BOOL correct = True;
1813 printf("failed to connect\n");
1817 cli_sockopt(&cli, sockops);
1819 for (i=0; i<0x11000; i++) {
1820 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1821 if ((fnums[i] = cli_open(&cli, fname,
1822 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
1824 printf("open of %s failed (%s)\n",
1825 fname, cli_errstr(&cli));
1826 printf("maximum fnum is %d\n", i);
1833 printf("cleaning up\n");
1835 slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
1836 cli_close(&cli, fnums[i]);
1837 if (!cli_unlink(&cli, fname)) {
1838 printf("unlink of %s failed (%s)\n",
1839 fname, cli_errstr(&cli));
1846 printf("maxfid test finished\n");
1847 if (!close_connection(&cli)) {
1853 /* generate a random buffer */
1854 static void rand_buf(char *buf, int len)
1857 *buf = (char)sys_random();
1862 /* send smb negprot commands, not reading the response */
1863 static BOOL run_negprot_nowait(int dummy)
1866 static struct cli_state cli;
1867 BOOL correct = True;
1869 printf("starting negprot nowait test\n");
1871 if (!open_nbt_connection(&cli)) {
1875 for (i=0;i<50000;i++) {
1876 cli_negprot_send(&cli);
1879 if (!close_connection(&cli)) {
1883 printf("finished negprot nowait test\n");
1889 /* send random IPC commands */
1890 static BOOL run_randomipc(int dummy)
1892 char *rparam = NULL;
1896 int api, param_len, i;
1897 static struct cli_state cli;
1898 BOOL correct = True;
1901 printf("starting random ipc test\n");
1903 if (!open_connection(&cli)) {
1907 for (i=0;i<count;i++) {
1908 api = sys_random() % 500;
1909 param_len = (sys_random() % 64);
1911 rand_buf(param, param_len);
1916 param, param_len, 8,
1917 NULL, 0, BUFFER_SIZE,
1921 printf("%d/%d\r", i,count);
1924 printf("%d/%d\n", i, count);
1926 if (!close_connection(&cli)) {
1930 printf("finished random ipc test\n");
1937 static void browse_callback(const char *sname, uint32 stype,
1938 const char *comment, void *state)
1940 printf("\t%20.20s %08x %s\n", sname, stype, comment);
1946 This test checks the browse list code
1949 static BOOL run_browsetest(int dummy)
1951 static struct cli_state cli;
1952 BOOL correct = True;
1954 printf("starting browse test\n");
1956 if (!open_connection(&cli)) {
1960 printf("domain list:\n");
1961 cli_NetServerEnum(&cli, cli.server_domain,
1962 SV_TYPE_DOMAIN_ENUM,
1963 browse_callback, NULL);
1965 printf("machine list:\n");
1966 cli_NetServerEnum(&cli, cli.server_domain,
1968 browse_callback, NULL);
1970 if (!close_connection(&cli)) {
1974 printf("browse test finished\n");
1982 This checks how the getatr calls works
1984 static BOOL run_attrtest(int dummy)
1986 static struct cli_state cli;
1989 char *fname = "\\attrib.tst";
1990 BOOL correct = True;
1992 printf("starting attrib test\n");
1994 if (!open_connection(&cli)) {
1998 cli_unlink(&cli, fname);
1999 fnum = cli_open(&cli, fname,
2000 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2001 cli_close(&cli, fnum);
2002 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
2003 printf("getatr failed (%s)\n", cli_errstr(&cli));
2007 if (abs(t - time(NULL)) > 2) {
2008 printf("ERROR: SMBgetatr bug. time is %s",
2014 t2 = t-60*60*24; /* 1 day ago */
2016 if (!cli_setatr(&cli, fname, 0, t2)) {
2017 printf("setatr failed (%s)\n", cli_errstr(&cli));
2021 if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
2022 printf("getatr failed (%s)\n", cli_errstr(&cli));
2027 printf("ERROR: getatr/setatr bug. times are\n%s",
2029 printf("%s", ctime(&t2));
2033 cli_unlink(&cli, fname);
2035 if (!close_connection(&cli)) {
2039 printf("attrib test finished\n");
2046 This checks a couple of trans2 calls
2048 static BOOL run_trans2test(int dummy)
2050 static struct cli_state cli;
2053 time_t c_time, a_time, m_time, w_time, m_time2;
2054 char *fname = "\\trans2.tst";
2055 char *dname = "\\trans2";
2056 char *fname2 = "\\trans2\\trans2.tst";
2057 BOOL correct = True;
2059 printf("starting trans2 test\n");
2061 if (!open_connection(&cli)) {
2065 cli_unlink(&cli, fname);
2066 fnum = cli_open(&cli, fname,
2067 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2068 if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
2070 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
2073 cli_close(&cli, fnum);
2077 cli_unlink(&cli, fname);
2078 fnum = cli_open(&cli, fname,
2079 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2081 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
2084 cli_close(&cli, fnum);
2086 if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2087 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
2090 if (c_time != m_time) {
2091 printf("create time=%s", ctime(&c_time));
2092 printf("modify time=%s", ctime(&m_time));
2093 printf("This system appears to have sticky create times\n");
2096 if (a_time % (60*60) == 0) {
2097 printf("access time=%s", ctime(&a_time));
2098 printf("This system appears to set a midnight access time\n");
2102 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2103 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2109 cli_unlink(&cli, fname);
2110 fnum = cli_open(&cli, fname,
2111 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2112 cli_close(&cli, fnum);
2113 if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time,
2114 &w_time, &size, NULL, NULL)) {
2115 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2118 if (w_time < 60*60*24*2) {
2119 printf("write time=%s", ctime(&w_time));
2120 printf("This system appears to set a initial 0 write time\n");
2125 cli_unlink(&cli, fname);
2128 /* check if the server updates the directory modification time
2129 when creating a new file */
2130 if (!cli_mkdir(&cli, dname)) {
2131 printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
2135 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time,
2136 &w_time, &size, NULL, NULL)) {
2137 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2141 fnum = cli_open(&cli, fname2,
2142 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2143 cli_write(&cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2144 cli_close(&cli, fnum);
2145 if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2,
2146 &w_time, &size, NULL, NULL)) {
2147 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
2150 if (m_time2 == m_time) {
2151 printf("This system does not update directory modification times\n");
2155 cli_unlink(&cli, fname2);
2156 cli_rmdir(&cli, dname);
2158 if (!close_connection(&cli)) {
2162 printf("trans2 test finished\n");
2168 /****************************************************************************
2169 check for existance of a trans2 call
2170 ****************************************************************************/
2171 static BOOL scan_trans2(struct cli_state *cli, int op, int level)
2177 char *rparam=NULL, *rdata=NULL;
2180 SSVAL(param, 0, level);
2181 SSVAL(param, 2, level);
2182 SSVAL(param, 4, level);
2184 if (!cli_send_trans(cli, SMBtrans2,
2186 -1, 0, /* fid, flags */
2187 &setup, 1, 0, /* setup, length, max */
2188 param, param_len, 2, /* param, length, max */
2189 NULL, data_len, cli->max_xmit /* data, length, max */
2194 if (!cli_receive_trans(cli, SMBtrans2,
2195 &rparam, ¶m_len,
2196 &rdata, &data_len)) {
2197 printf("recv failed op=%d level=%d %s\n", op, level, cli_errstr(cli));
2201 if (rdata) free(rdata);
2202 if (rparam) free(rparam);
2207 static BOOL run_trans2_scan(int dummy)
2209 static struct cli_state cli;
2212 printf("starting trans2 scan test\n");
2214 if (!open_connection(&cli)) {
2218 for (op=1; op<200; op++) {
2219 for (level = 1; level < 300; level++) {
2220 scan_trans2(&cli, op, level);
2224 close_connection(&cli);
2226 printf("trans2 scan finished\n");
2233 This checks new W2K calls.
2236 static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
2239 BOOL correct = True;
2241 memset(buf, 0xff, sizeof(buf));
2243 if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
2244 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2247 printf("qfileinfo: level %d\n", level);
2248 dump_data(0, buf, 256);
2254 static BOOL run_w2ktest(int dummy)
2256 static struct cli_state cli;
2258 char *fname = "\\w2ktest\\w2k.tst";
2260 BOOL correct = True;
2262 printf("starting w2k test\n");
2264 if (!open_connection(&cli)) {
2268 fnum = cli_open(&cli, fname,
2269 O_RDWR | O_CREAT , DENY_NONE);
2271 for (level = 1004; level < 1040; level++) {
2272 new_trans(&cli, fnum, level);
2275 cli_close(&cli, fnum);
2277 if (!close_connection(&cli)) {
2281 printf("w2k test finished\n");
2288 this is a harness for some oplock tests
2290 static BOOL run_oplock1(int dummy)
2292 static struct cli_state cli1;
2293 char *fname = "\\lockt1.lck";
2295 BOOL correct = True;
2297 printf("starting oplock test 1\n");
2299 if (!open_connection(&cli1)) {
2303 cli_unlink(&cli1, fname);
2305 cli_sockopt(&cli1, sockops);
2307 cli1.use_oplocks = True;
2309 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2311 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2315 cli1.use_oplocks = False;
2317 cli_unlink(&cli1, fname);
2318 cli_unlink(&cli1, fname);
2320 if (!cli_close(&cli1, fnum1)) {
2321 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2325 if (!cli_unlink(&cli1, fname)) {
2326 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2330 if (!close_connection(&cli1)) {
2334 printf("finished oplock test 1\n");
2339 static BOOL run_oplock2(int dummy)
2341 static struct cli_state cli1, cli2;
2342 char *fname = "\\lockt2.lck";
2344 int saved_use_oplocks = use_oplocks;
2346 BOOL correct = True;
2347 volatile BOOL *shared_correct;
2349 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2350 *shared_correct = True;
2352 use_level_II_oplocks = True;
2355 printf("starting oplock test 2\n");
2357 if (!open_connection(&cli1)) {
2358 use_level_II_oplocks = False;
2359 use_oplocks = saved_use_oplocks;
2363 cli1.use_oplocks = True;
2364 cli1.use_level_II_oplocks = True;
2366 if (!open_connection(&cli2)) {
2367 use_level_II_oplocks = False;
2368 use_oplocks = saved_use_oplocks;
2372 cli2.use_oplocks = True;
2373 cli2.use_level_II_oplocks = True;
2375 cli_unlink(&cli1, fname);
2377 cli_sockopt(&cli1, sockops);
2378 cli_sockopt(&cli2, sockops);
2380 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2382 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2386 /* Don't need the globals any more. */
2387 use_level_II_oplocks = False;
2388 use_oplocks = saved_use_oplocks;
2392 fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
2394 printf("second open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2395 *shared_correct = False;
2401 if (!cli_close(&cli2, fnum2)) {
2402 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2403 *shared_correct = False;
2411 /* Ensure cli1 processes the break. */
2413 if (cli_read(&cli1, fnum1, buf, 0, 4) != 4) {
2414 printf("read on fnum1 failed (%s)\n", cli_errstr(&cli1));
2418 /* Should now be at level II. */
2419 /* Test if sending a write locks causes a break to none. */
2421 if (!cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2422 printf("lock failed (%s)\n", cli_errstr(&cli1));
2426 cli_unlock(&cli1, fnum1, 0, 4);
2430 if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2431 printf("lock failed (%s)\n", cli_errstr(&cli1));
2435 cli_unlock(&cli1, fnum1, 0, 4);
2439 cli_read(&cli1, fnum1, buf, 0, 4);
2442 if (cli_write(&cli1, fnum1, 0, buf, 0, 4) != 4) {
2443 printf("write on fnum1 failed (%s)\n", cli_errstr(&cli1));
2448 if (!cli_close(&cli1, fnum1)) {
2449 printf("close1 failed (%s)\n", cli_errstr(&cli1));
2455 if (!cli_unlink(&cli1, fname)) {
2456 printf("unlink failed (%s)\n", cli_errstr(&cli1));
2460 if (!close_connection(&cli1)) {
2464 if (!*shared_correct) {
2468 printf("finished oplock test 2\n");
2473 /* handler for oplock 3 tests */
2474 static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2476 printf("got oplock break fnum=%d level=%d\n",
2478 return cli_oplock_ack(cli, fnum, level);
2481 static BOOL run_oplock3(int dummy)
2483 static struct cli_state cli;
2484 char *fname = "\\oplockt3.dat";
2486 char buf[4] = "abcd";
2487 BOOL correct = True;
2488 volatile BOOL *shared_correct;
2490 shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
2491 *shared_correct = True;
2493 printf("starting oplock test 3\n");
2498 use_level_II_oplocks = True;
2499 if (!open_connection(&cli)) {
2500 *shared_correct = False;
2504 /* try to trigger a oplock break in parent */
2505 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2506 cli_write(&cli, fnum, 0, buf, 0, 4);
2512 use_level_II_oplocks = True;
2513 if (!open_connection(&cli)) {
2516 cli_oplock_handler(&cli, oplock3_handler);
2517 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2518 cli_write(&cli, fnum, 0, buf, 0, 4);
2519 cli_close(&cli, fnum);
2520 fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
2521 cli.timeout = 20000;
2522 cli_receive_smb(&cli);
2523 printf("finished oplock test 3\n");
2525 return (correct && *shared_correct);
2527 /* What are we looking for here? What's sucess and what's FAILURE? */
2533 Test delete on close semantics.
2535 static BOOL run_deletetest(int dummy)
2537 static struct cli_state cli1;
2538 static struct cli_state cli2;
2539 char *fname = "\\delete.file";
2541 BOOL correct = True;
2543 printf("starting delete test\n");
2545 if (!open_connection(&cli1)) {
2549 cli_sockopt(&cli1, sockops);
2551 /* Test 1 - this should *NOT* delete the file on close. */
2553 cli_setatr(&cli1, fname, 0, 0);
2554 cli_unlink(&cli1, fname);
2556 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2557 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, DELETE_ON_CLOSE_FLAG);
2560 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2564 if (!cli_close(&cli1, fnum1)) {
2565 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2569 fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
2571 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2575 if (!cli_close(&cli1, fnum1)) {
2576 printf("[1] close failed (%s)\n", cli_errstr(&cli1));
2580 printf("first delete on close test succeeded.\n");
2582 /* Test 2 - this should delete the file on close. */
2584 cli_setatr(&cli1, fname, 0, 0);
2585 cli_unlink(&cli1, fname);
2587 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS,
2588 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
2591 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2595 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2596 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2600 if (!cli_close(&cli1, fnum1)) {
2601 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2605 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2607 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
2608 if (!cli_close(&cli1, fnum1)) {
2609 printf("[2] close failed (%s)\n", cli_errstr(&cli1));
2612 cli_unlink(&cli1, fname);
2614 printf("second delete on close test succeeded.\n");
2618 cli_setatr(&cli1, fname, 0, 0);
2619 cli_unlink(&cli1, fname);
2621 fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
2622 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2625 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2629 /* This should fail with a sharing violation - open for delete is only compatible
2630 with SHARE_DELETE. */
2632 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2633 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0);
2636 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
2640 /* This should succeed. */
2642 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
2643 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2646 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2650 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2651 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2655 if (!cli_close(&cli1, fnum1)) {
2656 printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1));
2660 if (!cli_close(&cli1, fnum2)) {
2661 printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1));
2665 /* This should fail - file should no longer be there. */
2667 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2669 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
2670 if (!cli_close(&cli1, fnum1)) {
2671 printf("[3] close failed (%s)\n", cli_errstr(&cli1));
2673 cli_unlink(&cli1, fname);
2676 printf("third delete on close test succeeded.\n");
2679 cli_setatr(&cli1, fname, 0, 0);
2680 cli_unlink(&cli1, fname);
2682 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2683 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
2686 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2690 /* This should succeed. */
2691 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2692 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2694 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
2698 if (!cli_close(&cli1, fnum2)) {
2699 printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1));
2703 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2704 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
2708 /* This should fail - no more opens once delete on close set. */
2709 fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
2710 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2712 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
2715 printf("fourth delete on close test succeeded.\n");
2717 if (!cli_close(&cli1, fnum1)) {
2718 printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1));
2723 cli_setatr(&cli1, fname, 0, 0);
2724 cli_unlink(&cli1, fname);
2726 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
2728 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2732 /* This should fail - only allowed on NT opens with DELETE access. */
2734 if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2735 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
2739 if (!cli_close(&cli1, fnum1)) {
2740 printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1));
2744 printf("fifth delete on close test succeeded.\n");
2747 cli_setatr(&cli1, fname, 0, 0);
2748 cli_unlink(&cli1, fname);
2750 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
2751 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2752 FILE_OVERWRITE_IF, 0);
2755 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2759 /* This should fail - only allowed on NT opens with DELETE access. */
2761 if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
2762 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
2766 if (!cli_close(&cli1, fnum1)) {
2767 printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1));
2771 printf("sixth delete on close test succeeded.\n");
2774 cli_setatr(&cli1, fname, 0, 0);
2775 cli_unlink(&cli1, fname);
2777 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2778 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0);
2781 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2785 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2786 printf("[7] setting delete_on_close on file failed !\n");
2790 if (!cli_nt_delete_on_close(&cli1, fnum1, False)) {
2791 printf("[7] unsetting delete_on_close on file failed !\n");
2795 if (!cli_close(&cli1, fnum1)) {
2796 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2800 /* This next open should succeed - we reset the flag. */
2802 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2804 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2808 if (!cli_close(&cli1, fnum1)) {
2809 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
2813 printf("seventh delete on close test succeeded.\n");
2816 cli_setatr(&cli1, fname, 0, 0);
2817 cli_unlink(&cli1, fname);
2819 if (!open_connection(&cli2)) {
2820 printf("[8] failed to open second connection.\n");
2824 cli_sockopt(&cli1, sockops);
2826 fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2827 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
2830 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2834 fnum2 = cli_nt_create_full(&cli2, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
2835 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
2838 printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2842 if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
2843 printf("[8] setting delete_on_close on file failed !\n");
2847 if (!cli_close(&cli1, fnum1)) {
2848 printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1));
2852 if (!cli_close(&cli2, fnum2)) {
2853 printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2));
2857 /* This should fail.. */
2858 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
2860 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
2861 if (!cli_close(&cli1, fnum1)) {
2862 printf("[8] close failed (%s)\n", cli_errstr(&cli1));
2864 cli_unlink(&cli1, fname);
2867 printf("eighth delete on close test succeeded.\n");
2869 printf("finished delete test\n");
2871 cli_setatr(&cli1, fname, 0, 0);
2872 cli_unlink(&cli1, fname);
2874 if (!close_connection(&cli1)) {
2877 if (!close_connection(&cli2)) {
2884 Test open mode returns on read-only files.
2886 static BOOL run_opentest(int dummy)
2888 static struct cli_state cli1;
2889 char *fname = "\\readonly.file";
2893 BOOL correct = True;
2895 printf("starting open test\n");
2897 if (!open_connection(&cli1)) {
2901 cli_setatr(&cli1, fname, 0, 0);
2902 cli_unlink(&cli1, fname);
2904 cli_sockopt(&cli1, sockops);
2906 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2908 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2912 if (!cli_close(&cli1, fnum1)) {
2913 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2917 if (!cli_setatr(&cli1, fname, aRONLY, 0)) {
2918 printf("cli_setatr failed (%s)\n", cli_errstr(&cli1));
2922 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
2924 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2928 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
2929 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
2931 if (check_error(__LINE__, &cli1, ERRDOS, ERRnoaccess,
2932 NT_STATUS_ACCESS_DENIED)) {
2933 printf("correct error code ERRDOS/ERRnoaccess returned\n");
2936 printf("finished open test 1\n");
2938 cli_close(&cli1, fnum1);
2940 /* Now try not readonly and ensure ERRbadshare is returned. */
2942 cli_setatr(&cli1, fname, 0, 0);
2944 fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
2946 printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
2950 /* This will fail - but the error should be ERRshare. */
2951 fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
2953 if (check_error(__LINE__, &cli1, ERRDOS, ERRbadshare,
2954 NT_STATUS_SHARING_VIOLATION)) {
2955 printf("correct error code ERRDOS/ERRbadshare returned\n");
2958 if (!cli_close(&cli1, fnum1)) {
2959 printf("close2 failed (%s)\n", cli_errstr(&cli1));
2963 cli_unlink(&cli1, fname);
2965 printf("finished open test 2\n");
2967 /* Test truncate open disposition on file opened for read. */
2969 fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2971 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(&cli1));
2975 /* write 20 bytes. */
2977 memset(buf, '\0', 20);
2979 if (cli_write(&cli1, fnum1, 0, buf, 0, 20) != 20) {
2980 printf("write failed (%s)\n", cli_errstr(&cli1));
2984 if (!cli_close(&cli1, fnum1)) {
2985 printf("(3) close1 failed (%s)\n", cli_errstr(&cli1));
2989 /* Ensure size == 20. */
2990 if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
2991 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
2996 printf("(3) file size != 20\n");
3000 /* Now test if we can truncate a file opened for readonly. */
3002 fnum1 = cli_open(&cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3004 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(&cli1));
3008 if (!cli_close(&cli1, fnum1)) {
3009 printf("close2 failed (%s)\n", cli_errstr(&cli1));
3013 /* Ensure size == 0. */
3014 if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
3015 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
3020 printf("(3) file size != 0\n");
3023 printf("finished open test 3\n");
3025 cli_unlink(&cli1, fname);
3028 printf("testing ctemp\n");
3031 fnum1 = cli_ctemp(&cli1, "\\", &tmp_path);
3033 printf("ctemp failed (%s)\n", cli_errstr(&cli1));
3036 printf("ctemp gave path %s\n", tmp_path);
3037 cli_close(&cli1, fnum1);
3038 cli_unlink(&cli1, tmp_path);
3041 if (!close_connection(&cli1)) {
3048 static void list_fn(file_info *finfo, const char *name, void *state)
3054 test directory listing speed
3056 static BOOL run_dirtest(int dummy)
3059 static struct cli_state cli;
3062 BOOL correct = True;
3064 printf("starting directory test\n");
3066 if (!open_connection(&cli)) {
3070 cli_sockopt(&cli, sockops);
3073 for (i=0;i<numops;i++) {
3075 slprintf(fname, sizeof(fname), "%x", (int)random());
3076 fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
3078 fprintf(stderr,"Failed to open %s\n", fname);
3081 cli_close(&cli, fnum);
3086 printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
3087 printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
3088 printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
3090 printf("dirtest core %g seconds\n", end_timer() - t1);
3093 for (i=0;i<numops;i++) {
3095 slprintf(fname, sizeof(fname), "%x", (int)random());
3096 cli_unlink(&cli, fname);
3099 if (!close_connection(&cli)) {
3103 printf("finished dirtest\n");
3110 static double create_procs(BOOL (*fn)(int), BOOL *result)
3113 volatile pid_t *child_status;
3114 volatile BOOL *child_status_out;
3120 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
3121 if (!child_status) {
3122 printf("Failed to setup shared memory\n");
3126 child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
3127 if (!child_status_out) {
3128 printf("Failed to setup result status shared memory\n");
3132 memset(child_status, 0, sizeof(pid_t)*nprocs);
3133 memset(child_status_out, True, sizeof(BOOL)*nprocs);
3137 for (i=0;i<nprocs;i++) {
3140 pid_t mypid = getpid();
3141 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
3143 slprintf(myname,sizeof(myname),"CLIENT%d", i);
3146 memset(¤t_cli, 0, sizeof(current_cli));
3147 if (open_connection(¤t_cli)) break;
3149 printf("pid %d failed to start\n", (int)getpid());
3155 child_status[i] = getpid();
3157 while (child_status[i]) msleep(2);
3159 child_status_out[i] = fn(i);
3166 for (i=0;i<nprocs;i++) {
3167 if (child_status[i]) synccount++;
3169 if (synccount == nprocs) break;
3171 } while (end_timer() < 30);
3173 if (synccount != nprocs) {
3174 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
3179 /* start the client load */
3182 for (i=0;i<nprocs;i++) {
3183 child_status[i] = 0;
3186 printf("%d clients started\n", nprocs);
3188 for (i=0;i<nprocs;i++) {
3189 waitpid(0, &status, 0);
3195 for (i=0;i<nprocs;i++) {
3196 if (!child_status_out[i]) {
3204 #define FLAG_MULTIPROC 1
3211 {"FDPASS", run_fdpasstest, 0},
3212 {"LOCK1", run_locktest1, 0},
3213 {"LOCK2", run_locktest2, 0},
3214 {"LOCK3", run_locktest3, 0},
3215 {"LOCK4", run_locktest4, 0},
3216 {"LOCK5", run_locktest5, 0},
3217 {"UNLINK", run_unlinktest, 0},
3218 {"BROWSE", run_browsetest, 0},
3219 {"ATTR", run_attrtest, 0},
3220 {"TRANS2", run_trans2test, 0},
3221 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
3222 {"TORTURE",run_torture, FLAG_MULTIPROC},
3223 {"RANDOMIPC", run_randomipc, 0},
3224 {"NEGNOWAIT", run_negprot_nowait, 0},
3225 {"NBW95", run_nbw95, 0},
3226 {"NBWNT", run_nbwnt, 0},
3227 {"OPLOCK1", run_oplock1, 0},
3228 {"OPLOCK2", run_oplock2, 0},
3229 {"OPLOCK3", run_oplock3, 0},
3230 {"DIR", run_dirtest, 0},
3231 {"DENY1", run_denytest1, 0},
3232 {"DENY2", run_denytest2, 0},
3233 {"TCON", run_tcon_test, 0},
3234 {"RW1", run_readwritetest, 0},
3235 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
3236 {"RW3", run_readwritelarge, 0},
3237 {"OPEN", run_opentest, 0},
3238 {"DELETE", run_deletetest, 0},
3239 {"W2K", run_w2ktest, 0},
3240 {"TRANS2SCAN", run_trans2_scan, 0},
3245 /****************************************************************************
3246 run a specified test or "ALL"
3247 ****************************************************************************/
3248 static BOOL run_test(char *name)
3254 if (strequal(name,"ALL")) {
3255 for (i=0;torture_ops[i].name;i++) {
3256 run_test(torture_ops[i].name);
3260 for (i=0;torture_ops[i].name;i++) {
3261 snprintf(randomfname, sizeof(randomfname), "\\XX%x",
3262 (unsigned)random());
3264 if (strequal(name, torture_ops[i].name)) {
3265 printf("Running %s\n", name);
3266 if (torture_ops[i].flags & FLAG_MULTIPROC) {
3267 t = create_procs(torture_ops[i].fn, &result);
3270 printf("TEST %s FAILED!\n", name);
3275 if (!torture_ops[i].fn(0)) {
3277 printf("TEST %s FAILED!\n", name);
3281 printf("%s took %g secs\n\n", name, t);
3288 static void usage(void)
3292 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
3294 printf("\t-d debuglevel\n");
3295 printf("\t-U user%%pass\n");
3296 printf("\t-N numprocs\n");
3297 printf("\t-n my_netbios_name\n");
3298 printf("\t-W workgroup\n");
3299 printf("\t-o num_operations\n");
3300 printf("\t-O socket_options\n");
3301 printf("\t-m maximum protocol\n");
3302 printf("\t-L use oplocks\n");
3305 printf("tests are:");
3306 for (i=0;torture_ops[i].name;i++) {
3307 printf(" %s", torture_ops[i].name);
3311 printf("default test is ALL\n");
3320 /****************************************************************************
3322 ****************************************************************************/
3323 int main(int argc,char *argv[])
3328 extern char *optarg;
3331 static pstring servicesf = CONFIGFILE;
3332 BOOL correct = True;
3336 #ifdef HAVE_SETBUFFER
3337 setbuffer(stdout, NULL, 0);
3340 lp_load(servicesf,True,False,False);
3347 for(p = argv[1]; *p; p++)
3351 if (strncmp(argv[1], "//", 2)) {
3355 fstrcpy(host, &argv[1][2]);
3356 p = strchr_m(&host[2],'/');
3361 fstrcpy(share, p+1);
3365 if (*username == 0 && getenv("LOGNAME")) {
3366 pstrcpy(username,getenv("LOGNAME"));
3373 fstrcpy(workgroup, lp_workgroup());
3375 while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:Ld:")) != EOF) {
3378 fstrcpy(workgroup,optarg);
3381 max_protocol = interpret_protocol(optarg, max_protocol);
3384 nprocs = atoi(optarg);
3387 numops = atoi(optarg);
3390 DEBUGLEVEL = atoi(optarg);
3399 fstrcpy(myname, optarg);
3402 pstrcpy(username,optarg);
3403 p = strchr_m(username,'%');
3406 pstrcpy(password, p+1);
3411 printf("Unknown option %c (%d)\n", (char)opt, opt);
3418 p = getpass("Password:");
3420 pstrcpy(password, p);
3425 printf("host=%s share=%s user=%s myname=%s\n",
3426 host, share, username, myname);
3429 correct = run_test("ALL");
3431 for (i=1;i<argc;i++) {
3432 if (!run_test(argv[i])) {