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.
28 #define MAX_FIDS_PER_TID MAX_USERS
30 struct cli_state
*seed
;
32 typedef struct test_vuser
{
50 int fnum
[MAX_FIDS_PER_TID
];
51 int backup_fnum
[MAX_FIDS_PER_TID
];
60 } errtab
; /*keep a list of known errors to reduce noise*/
63 static fstring shares
[MAX_TIDS
];
64 static TEST_VUSERS vusers
[MAX_USERS
];
66 static fstring host
, workgroup
, myname
;
67 static char *username
= vusers
[0].username
;
68 static char *password
= vusers
[0].password
;
69 static char *share
= shares
[0];
71 static int max_protocol
= PROTOCOL_NT1
;
72 static char *sockops
="TCP_NODELAY";
73 static int nprocs
=1, numops
=100;
74 static int nusers
=1, nshares
=0;
75 static int procnum
; /* records process count number when forking */
76 static struct cli_state current_cli
;
77 static fstring randomfname
;
78 static BOOL use_oplocks
;
79 static BOOL use_level_II_oplocks
;
81 static double create_procs(BOOL (*fn
)(int), BOOL
*result
);
83 static struct timeval tp1
,tp2
;
85 static void start_timer(void)
87 gettimeofday(&tp1
,NULL
);
90 static double end_timer(void)
92 gettimeofday(&tp2
,NULL
);
93 return((tp2
.tv_sec
- tp1
.tv_sec
) +
94 (tp2
.tv_usec
- tp1
.tv_usec
)*1.0e-6);
98 /* return a pointer to a anonymous shared memory segment of size "size"
99 which will persist across fork() but will disappear when all processes
102 The memory is not zeroed
104 This function uses system5 shared memory. It takes advantage of a property
105 that the memory is not destroyed if it is attached when the id is removed
107 static void *shm_setup(int size
)
112 shmid
= shmget(IPC_PRIVATE
, size
, SHM_R
| SHM_W
);
114 printf("can't get shared memory\n");
117 ret
= (void *)shmat(shmid
, 0, 0);
118 if (!ret
|| ret
== (void *)-1) {
119 printf("can't attach to shared memory\n");
122 /* the following releases the ipc, but note that this process
123 and all its children will still have access to the memory, its
124 just that the shmid is no longer valid for other shm calls. This
125 means we don't leave behind lots of shm segments after we exit
127 See Stevens "advanced programming in unix env" for details
129 shmctl(shmid
, IPC_RMID
, 0);
134 static BOOL
open_nbt_connection(struct cli_state
*c
)
136 struct nmb_name called
, calling
;
141 make_nmb_name(&calling
, myname
, 0x0);
142 make_nmb_name(&called
, host
, 0x20);
146 if (!cli_initialise(c
) || !cli_connect(c
, host
, &ip
)) {
147 printf("Failed to connect with %s\n", host
);
151 c
->timeout
= 120000; /* set a really long timeout (2 minutes) */
152 if (use_oplocks
) c
->use_oplocks
= True
;
153 if (use_level_II_oplocks
) c
->use_level_II_oplocks
= True
;
155 if (!cli_session_request(c
, &calling
, &called
)) {
156 printf("%s rejected the session\n",host
);
164 static BOOL
open_connection(struct cli_state
*c
)
168 if (!open_nbt_connection(c
)) {
172 if (!cli_negprot(c
)) {
173 printf("%s rejected the negprot (%s)\n",host
, cli_errstr(c
));
178 if (!cli_session_setup(c
, username
,
179 password
, strlen(password
),
180 password
, strlen(password
),
182 printf("%s rejected the sessionsetup (%s)\n", host
, cli_errstr(c
));
187 if (!cli_send_tconX(c
, share
, "?????",
188 password
, strlen(password
)+1)) {
189 printf("%s refused tree connect (%s)\n", host
, cli_errstr(c
));
197 static BOOL
close_connection(struct cli_state
*c
)
201 printf("tdis failed (%s)\n", cli_errstr(c
));
211 /* check if the server produced the expected error code */
212 static BOOL
check_error(struct cli_state
*c
,
213 uint8 eclass
, uint32 ecode
, uint32 nterr
)
218 (void)cli_dos_error(c
, &class, &num
);
219 if ((eclass
!= class || ecode
!= num
) &&
220 num
!= (nterr
&0xFFFFFF)) {
221 printf("unexpected error code class=%d code=%d\n",
222 (int)class, (int)num
);
223 printf(" expected %d/%d %d\n",
224 (int)eclass
, (int)ecode
, (int)nterr
);
231 static BOOL
wait_lock(struct cli_state
*c
, int fnum
, uint32 offset
, uint32 len
)
233 while (!cli_lock(c
, fnum
, offset
, len
, -1, WRITE_LOCK
)) {
234 if (!check_error(c
, ERRDOS
, ERRlock
, 0)) return False
;
240 static BOOL
rw_torture(struct cli_state
*c
)
242 char *lockfname
= "\\torture.lck";
246 pid_t pid2
, pid
= getpid();
251 fnum2
= cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
254 fnum2
= cli_open(c
, lockfname
, O_RDWR
, DENY_NONE
);
256 printf("open of %s failed (%s)\n", lockfname
, cli_errstr(c
));
261 for (i
=0;i
<numops
;i
++) {
262 unsigned n
= (unsigned)sys_random()%10;
264 printf("%d\r", i
); fflush(stdout
);
266 slprintf(fname
, sizeof(fstring
) - 1, "\\torture.%u", n
);
268 if (!wait_lock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
272 fnum
= cli_open(c
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_ALL
);
274 printf("open failed (%s)\n", cli_errstr(c
));
279 if (cli_write(c
, fnum
, 0, (char *)&pid
, 0, sizeof(pid
)) != sizeof(pid
)) {
280 printf("write failed (%s)\n", cli_errstr(c
));
285 if (cli_write(c
, fnum
, 0, (char *)buf
,
286 sizeof(pid
)+(j
*sizeof(buf
)),
287 sizeof(buf
)) != sizeof(buf
)) {
288 printf("write failed (%s)\n", cli_errstr(c
));
295 if (cli_read(c
, fnum
, (char *)&pid2
, 0, sizeof(pid
)) != sizeof(pid
)) {
296 printf("read failed (%s)\n", cli_errstr(c
));
301 printf("data corruption!\n");
305 if (!cli_close(c
, fnum
)) {
306 printf("close failed (%s)\n", cli_errstr(c
));
310 if (!cli_unlink(c
, fname
)) {
311 printf("unlink failed (%s)\n", cli_errstr(c
));
315 if (!cli_unlock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
316 printf("unlock failed (%s)\n", cli_errstr(c
));
322 cli_unlink(c
, lockfname
);
329 static BOOL
run_torture(int dummy
)
331 struct cli_state cli
;
336 cli_sockopt(&cli
, sockops
);
338 ret
= rw_torture(&cli
);
340 if (!close_connection(&cli
)) {
347 static BOOL
rw_torture3(struct cli_state
*c
, char *lockfname
)
354 unsigned countprev
= 0;
359 for (i
= 0; i
< sizeof(buf
); i
+= sizeof(uint32
))
361 SIVAL(buf
, i
, sys_random());
366 fnum
= cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
369 printf("first open read/write of %s failed (%s)\n",
370 lockfname
, cli_errstr(c
));
376 for (i
= 0; i
< 500 && fnum
== -1; i
++)
378 fnum
= cli_open(c
, lockfname
, O_RDONLY
,
383 printf("second open read-only of %s failed (%s)\n",
384 lockfname
, cli_errstr(c
));
390 for (count
= 0; count
< sizeof(buf
); count
+= sent
)
392 if (count
>= countprev
) {
393 printf("%d %8d\r", i
, count
);
396 countprev
+= (sizeof(buf
) / 20);
401 sent
= ((unsigned)sys_random()%(20))+ 1;
402 if (sent
> sizeof(buf
) - count
)
404 sent
= sizeof(buf
) - count
;
407 if (cli_write(c
, fnum
, 0, buf
+count
, count
, sent
) != sent
) {
408 printf("write failed (%s)\n", cli_errstr(c
));
414 sent
= cli_read(c
, fnum
, buf_rd
+count
, count
,
418 printf("read failed offset:%d size:%d (%s)\n",
419 count
, sizeof(buf
)-count
,
426 if (memcmp(buf_rd
+count
, buf
+count
, sent
) != 0)
428 printf("read/write compare failed\n");
429 printf("offset: %d req %d recvd %d\n",
430 count
, sizeof(buf
)-count
, sent
);
439 if (!cli_close(c
, fnum
)) {
440 printf("close failed (%s)\n", cli_errstr(c
));
447 static BOOL
rw_torture2(struct cli_state
*c1
, struct cli_state
*c2
)
449 char *lockfname
= "\\torture.lck";
458 if (!cli_unlink(c1
, lockfname
)) {
459 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1
));
462 fnum1
= cli_open(c1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
465 printf("first open read/write of %s failed (%s)\n",
466 lockfname
, cli_errstr(c1
));
469 fnum2
= cli_open(c2
, lockfname
, O_RDONLY
,
472 printf("second open read-only of %s failed (%s)\n",
473 lockfname
, cli_errstr(c2
));
474 cli_close(c1
, fnum1
);
478 for (i
=0;i
<numops
;i
++)
480 size_t buf_size
= ((unsigned)sys_random()%(sizeof(buf
)-1))+ 1;
482 printf("%d\r", i
); fflush(stdout
);
485 generate_random_buffer(buf
, buf_size
, False
);
487 if (cli_write(c1
, fnum1
, 0, buf
, 0, buf_size
) != buf_size
) {
488 printf("write failed (%s)\n", cli_errstr(c1
));
492 if ((bytes_read
= cli_read(c2
, fnum2
, buf_rd
, 0, buf_size
)) != buf_size
) {
493 printf("read failed (%s)\n", cli_errstr(c2
));
494 printf("read %d, expected %d\n", bytes_read
, buf_size
);
498 if (memcmp(buf_rd
, buf
, buf_size
) != 0)
500 printf("read/write compare failed\n");
505 if (!cli_close(c2
, fnum2
)) {
506 printf("close failed (%s)\n", cli_errstr(c2
));
509 if (!cli_close(c1
, fnum1
)) {
510 printf("close failed (%s)\n", cli_errstr(c1
));
514 if (!cli_unlink(c1
, lockfname
)) {
515 printf("unlink failed (%s)\n", cli_errstr(c1
));
522 static BOOL
run_readwritetest(int dummy
)
524 static struct cli_state cli1
, cli2
;
527 if (!open_connection(&cli1
) || !open_connection(&cli2
)) {
530 cli_sockopt(&cli1
, sockops
);
531 cli_sockopt(&cli2
, sockops
);
533 printf("starting readwritetest\n");
535 test1
= rw_torture2(&cli1
, &cli2
);
536 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1
));
538 test2
= rw_torture2(&cli1
, &cli1
);
539 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2
));
541 if (!close_connection(&cli1
)) {
545 if (!close_connection(&cli2
)) {
549 return (test1
&& test2
);
552 static BOOL
run_readwritemulti(int dummy
)
554 static struct cli_state cli
;
559 cli_sockopt(&cli
, sockops
);
561 printf("run_readwritemulti: fname %s\n", randomfname
);
562 test
= rw_torture3(&cli
, randomfname
);
564 if (!close_connection(&cli
)) {
571 static BOOL
run_readwritelarge(int dummy
)
573 static struct cli_state cli1
;
575 char *lockfname
= "\\large.dat";
580 if (!open_connection(&cli1
)) {
583 cli_sockopt(&cli1
, sockops
);
584 memset(buf
,'\0',sizeof(buf
));
586 cli1
.max_xmit
= 0x11000;
588 printf("starting readwritelarge\n");
590 cli_unlink(&cli1
, lockfname
);
592 fnum1
= cli_open(&cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
);
594 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(&cli1
));
598 cli_write(&cli1
, fnum1
, 0, buf
, 0, sizeof(buf
));
600 if (!cli_close(&cli1
, fnum1
)) {
601 printf("close failed (%s)\n", cli_errstr(&cli1
));
605 if (!cli_qpathinfo(&cli1
, lockfname
, NULL
, NULL
, NULL
, &fsize
, NULL
)) {
606 printf("qpathinfo failed (%s)\n", cli_errstr(&cli1
));
610 if (fsize
== sizeof(buf
))
611 printf("readwritelarge test 1 succeeded (size = %x)\n", fsize
);
613 printf("readwritelarge test 1 failed (size = %x)\n", fsize
);
617 if (!cli_unlink(&cli1
, lockfname
)) {
618 printf("unlink failed (%s)\n", cli_errstr(&cli1
));
622 fnum1
= cli_open(&cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
);
624 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(&cli1
));
628 cli_smbwrite(&cli1
, fnum1
, buf
, 0, sizeof(buf
));
630 if (!cli_close(&cli1
, fnum1
)) {
631 printf("close failed (%s)\n", cli_errstr(&cli1
));
635 if (!close_connection(&cli1
)) {
643 /* run a test that simulates an approximate netbench client load */
644 static BOOL
run_netbench(int client
)
646 struct cli_state cli
;
657 cli_sockopt(&cli
, sockops
);
661 slprintf(cname
,sizeof(fname
), "CLIENT%d", client
);
663 f
= fopen("client.txt", "r");
666 perror("client.txt");
670 while (fgets(line
, sizeof(line
)-1, f
)) {
673 line
[strlen(line
)-1] = 0;
675 /* printf("[%d] %s\n", line_count, line); */
677 all_string_sub(line
,"CLIENT1", cname
, sizeof(line
));
679 for (i
=0;i
<20;i
++) params
[i
] = "";
681 /* parse the command parameters */
682 params
[0] = strtok(line
," ");
684 while (params
[i
]) params
[++i
] = strtok(NULL
," ");
690 if (strcmp(params
[1],"REQUEST") == 0) {
691 if (!strcmp(params
[0],"SMBopenX")) {
692 fstrcpy(fname
, params
[5]);
693 } else if (!strcmp(params
[0],"SMBclose")) {
694 nb_close(atoi(params
[3]));
695 } else if (!strcmp(params
[0],"SMBmkdir")) {
697 } else if (!strcmp(params
[0],"CREATE")) {
698 nb_create(params
[3], atoi(params
[5]));
699 } else if (!strcmp(params
[0],"SMBrmdir")) {
701 } else if (!strcmp(params
[0],"SMBunlink")) {
702 fstrcpy(fname
, params
[3]);
703 } else if (!strcmp(params
[0],"SMBmv")) {
704 nb_rename(params
[3], params
[5]);
705 } else if (!strcmp(params
[0],"SMBgetatr")) {
706 fstrcpy(fname
, params
[3]);
707 } else if (!strcmp(params
[0],"SMBwrite")) {
708 nb_write(atoi(params
[3]),
709 atoi(params
[5]), atoi(params
[7]));
710 } else if (!strcmp(params
[0],"SMBwritebraw")) {
711 nb_write(atoi(params
[3]),
712 atoi(params
[7]), atoi(params
[5]));
713 } else if (!strcmp(params
[0],"SMBreadbraw")) {
714 nb_read(atoi(params
[3]),
715 atoi(params
[7]), atoi(params
[5]));
716 } else if (!strcmp(params
[0],"SMBread")) {
717 nb_read(atoi(params
[3]),
718 atoi(params
[5]), atoi(params
[7]));
721 if (!strcmp(params
[0],"SMBopenX")) {
722 if (!strncmp(params
[2], "ERR", 3)) continue;
723 nb_open(fname
, atoi(params
[3]), atoi(params
[5]));
724 } else if (!strcmp(params
[0],"SMBgetatr")) {
725 if (!strncmp(params
[2], "ERR", 3)) continue;
726 nb_stat(fname
, atoi(params
[3]));
727 } else if (!strcmp(params
[0],"SMBunlink")) {
728 if (!strncmp(params
[2], "ERR", 3)) continue;
735 slprintf(fname
,sizeof(fname
), "CLIENTS/CLIENT%d", client
);
741 if (!close_connection(&cli
)) {
749 /* run a test that simulates an approximate netbench w9X client load */
750 static BOOL
run_nbw95(int dummy
)
754 t
= create_procs(run_netbench
, &correct
);
755 /* to produce a netbench result we scale accoding to the
756 netbench measured throughput for the run that produced the
757 sniff that was used to produce client.txt. That run used 2
758 clients and ran for 660 seconds to produce a result of
760 printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n",
761 132*nprocs
/t
, 0.5*0.5*nprocs
*660/t
, 2*nprocs
*660/t
);
765 /* run a test that simulates an approximate netbench wNT client load */
766 static BOOL
run_nbwnt(int dummy
)
770 t
= create_procs(run_netbench
, &correct
);
771 printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n",
772 132*nprocs
/t
, 0.5*0.5*nprocs
*660/t
, 2*nprocs
*660/t
);
779 This test checks for two things:
781 1) correct support for retaining locks over a close (ie. the server
782 must not use posix semantics)
783 2) support for lock timeouts
785 static BOOL
run_locktest1(int dummy
)
787 static struct cli_state cli1
, cli2
;
788 char *fname
= "\\lockt1.lck";
789 int fnum1
, fnum2
, fnum3
;
792 if (!open_connection(&cli1
) || !open_connection(&cli2
)) {
795 cli_sockopt(&cli1
, sockops
);
796 cli_sockopt(&cli2
, sockops
);
798 printf("starting locktest1\n");
800 cli_unlink(&cli1
, fname
);
802 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
804 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
807 fnum2
= cli_open(&cli1
, fname
, O_RDWR
, DENY_NONE
);
809 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
812 fnum3
= cli_open(&cli2
, fname
, O_RDWR
, DENY_NONE
);
814 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(&cli2
));
818 if (!cli_lock(&cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
819 printf("lock1 failed (%s)\n", cli_errstr(&cli1
));
824 if (cli_lock(&cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
825 printf("lock2 succeeded! This is a locking bug\n");
828 if (!check_error(&cli2
, ERRDOS
, ERRlock
, 0)) return False
;
832 printf("Testing lock timeouts\n");
834 if (cli_lock(&cli2
, fnum3
, 0, 4, 10*1000, WRITE_LOCK
)) {
835 printf("lock3 succeeded! This is a locking bug\n");
838 if (!check_error(&cli2
, ERRDOS
, ERRlock
, 0)) return False
;
843 printf("error: This server appears not to support timed lock requests\n");
846 if (!cli_close(&cli1
, fnum2
)) {
847 printf("close1 failed (%s)\n", cli_errstr(&cli1
));
851 if (cli_lock(&cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
852 printf("lock4 succeeded! This is a locking bug\n");
855 if (!check_error(&cli2
, ERRDOS
, ERRlock
, 0)) return False
;
858 if (!cli_close(&cli1
, fnum1
)) {
859 printf("close2 failed (%s)\n", cli_errstr(&cli1
));
863 if (!cli_close(&cli2
, fnum3
)) {
864 printf("close3 failed (%s)\n", cli_errstr(&cli2
));
868 if (!cli_unlink(&cli1
, fname
)) {
869 printf("unlink failed (%s)\n", cli_errstr(&cli1
));
874 if (!close_connection(&cli1
)) {
878 if (!close_connection(&cli2
)) {
882 printf("Passed locktest1\n");
887 checks for correct tconX support
889 static BOOL
run_tcon_test(int dummy
)
891 static struct cli_state cli1
;
892 char *fname
= "\\tcontest.tmp";
897 if (!open_connection(&cli1
)) {
900 cli_sockopt(&cli1
, sockops
);
902 printf("starting tcontest\n");
904 cli_unlink(&cli1
, fname
);
906 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
909 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
915 if (cli_write(&cli1
, fnum1
, 0, buf
, 130, 4) != 4)
917 printf("write failed (%s)", cli_errstr(&cli1
));
921 if (!cli_send_tconX(&cli1
, share
, "?????",
922 password
, strlen(password
)+1)) {
923 printf("%s refused 2nd tree connect (%s)\n", host
,
929 if (cli_write(&cli1
, fnum1
, 0, buf
, 130, 4) == 4)
931 printf("write succeeded (%s)", cli_errstr(&cli1
));
935 if (cli_close(&cli1
, fnum1
)) {
936 printf("close2 succeeded (%s)\n", cli_errstr(&cli1
));
940 if (!cli_tdis(&cli1
)) {
941 printf("tdis failed (%s)\n", cli_errstr(&cli1
));
947 if (!cli_close(&cli1
, fnum1
)) {
948 printf("close2 failed (%s)\n", cli_errstr(&cli1
));
952 if (!close_connection(&cli1
)) {
956 printf("Passed tcontest\n");
962 This test checks that
964 1) the server supports multiple locking contexts on the one SMB
965 connection, distinguished by PID.
967 2) the server correctly fails overlapping locks made by the same PID (this
968 goes against POSIX behaviour, which is why it is tricky to implement)
970 3) the server denies unlock requests by an incorrect client PID
972 static BOOL
run_locktest2(int dummy
)
974 static struct cli_state cli
;
975 char *fname
= "\\lockt2.lck";
976 int fnum1
, fnum2
, fnum3
;
979 if (!open_connection(&cli
)) {
983 cli_sockopt(&cli
, sockops
);
985 printf("starting locktest2\n");
987 cli_unlink(&cli
, fname
);
991 fnum1
= cli_open(&cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
993 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli
));
997 fnum2
= cli_open(&cli
, fname
, O_RDWR
, DENY_NONE
);
999 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(&cli
));
1003 cli_setpid(&cli
, 2);
1005 fnum3
= cli_open(&cli
, fname
, O_RDWR
, DENY_NONE
);
1007 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(&cli
));
1011 cli_setpid(&cli
, 1);
1013 if (!cli_lock(&cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1014 printf("lock1 failed (%s)\n", cli_errstr(&cli
));
1018 if (cli_lock(&cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1019 printf("WRITE lock1 succeeded! This is a locking bug\n");
1022 if (!check_error(&cli
, ERRDOS
, ERRlock
, 0)) return False
;
1025 if (cli_lock(&cli
, fnum2
, 0, 4, 0, WRITE_LOCK
)) {
1026 printf("WRITE lock2 succeeded! This is a locking bug\n");
1029 if (!check_error(&cli
, ERRDOS
, ERRlock
, 0)) return False
;
1032 if (cli_lock(&cli
, fnum2
, 0, 4, 0, READ_LOCK
)) {
1033 printf("READ lock2 succeeded! This is a locking bug\n");
1036 if (!check_error(&cli
, ERRDOS
, ERRlock
, 0)) return False
;
1039 if (!cli_lock(&cli
, fnum1
, 100, 4, 0, WRITE_LOCK
)) {
1040 printf("lock at 100 failed (%s)\n", cli_errstr(&cli
));
1042 cli_setpid(&cli
, 2);
1043 if (cli_unlock(&cli
, fnum1
, 100, 4)) {
1044 printf("unlock at 100 succeeded! This is a locking bug\n");
1048 if (cli_unlock(&cli
, fnum1
, 0, 4)) {
1049 printf("unlock1 succeeded! This is a locking bug\n");
1052 if (!check_error(&cli
, ERRDOS
, ERRnotlocked
, 0)) return False
;
1055 if (cli_unlock(&cli
, fnum1
, 0, 8)) {
1056 printf("unlock2 succeeded! This is a locking bug\n");
1059 if (!check_error(&cli
, ERRDOS
, ERRnotlocked
, 0)) return False
;
1062 if (cli_lock(&cli
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1063 printf("lock3 succeeded! This is a locking bug\n");
1066 if (!check_error(&cli
, ERRDOS
, ERRlock
, 0)) return False
;
1069 cli_setpid(&cli
, 1);
1071 if (!cli_close(&cli
, fnum1
)) {
1072 printf("close1 failed (%s)\n", cli_errstr(&cli
));
1076 if (!cli_close(&cli
, fnum2
)) {
1077 printf("close2 failed (%s)\n", cli_errstr(&cli
));
1081 if (!cli_close(&cli
, fnum3
)) {
1082 printf("close3 failed (%s)\n", cli_errstr(&cli
));
1086 if (!close_connection(&cli
)) {
1090 printf("locktest2 finished\n");
1097 This test checks that
1099 1) the server supports the full offset range in lock requests
1101 static BOOL
run_locktest3(int dummy
)
1103 static struct cli_state cli1
, cli2
;
1104 char *fname
= "\\lockt3.lck";
1105 int fnum1
, fnum2
, i
;
1107 BOOL correct
= True
;
1109 #define NEXT_OFFSET offset += (~(uint32)0) / numops
1111 if (!open_connection(&cli1
) || !open_connection(&cli2
)) {
1114 cli_sockopt(&cli1
, sockops
);
1115 cli_sockopt(&cli2
, sockops
);
1117 printf("starting locktest3\n");
1119 cli_unlink(&cli1
, fname
);
1121 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1123 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
1126 fnum2
= cli_open(&cli2
, fname
, O_RDWR
, DENY_NONE
);
1128 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(&cli2
));
1132 for (offset
=i
=0;i
<numops
;i
++) {
1134 if (!cli_lock(&cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1135 printf("lock1 %d failed (%s)\n",
1141 if (!cli_lock(&cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1142 printf("lock2 %d failed (%s)\n",
1149 for (offset
=i
=0;i
<numops
;i
++) {
1152 if (cli_lock(&cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
)) {
1153 printf("error: lock1 %d succeeded!\n", i
);
1157 if (cli_lock(&cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
)) {
1158 printf("error: lock2 %d succeeded!\n", i
);
1162 if (cli_lock(&cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1163 printf("error: lock3 %d succeeded!\n", i
);
1167 if (cli_lock(&cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1168 printf("error: lock4 %d succeeded!\n", i
);
1173 for (offset
=i
=0;i
<numops
;i
++) {
1176 if (!cli_unlock(&cli1
, fnum1
, offset
-1, 1)) {
1177 printf("unlock1 %d failed (%s)\n",
1183 if (!cli_unlock(&cli2
, fnum2
, offset
-2, 1)) {
1184 printf("unlock2 %d failed (%s)\n",
1191 if (!cli_close(&cli1
, fnum1
)) {
1192 printf("close1 failed (%s)\n", cli_errstr(&cli1
));
1196 if (!cli_close(&cli2
, fnum2
)) {
1197 printf("close2 failed (%s)\n", cli_errstr(&cli2
));
1201 if (!cli_unlink(&cli1
, fname
)) {
1202 printf("unlink failed (%s)\n", cli_errstr(&cli1
));
1206 if (!close_connection(&cli1
)) {
1210 if (!close_connection(&cli2
)) {
1214 printf("finished locktest3\n");
1219 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1220 printf("** "); correct = False; \
1224 looks at overlapping locks
1226 static BOOL
run_locktest4(int dummy
)
1228 static struct cli_state cli1
, cli2
;
1229 char *fname
= "\\lockt4.lck";
1230 int fnum1
, fnum2
, f
;
1233 BOOL correct
= True
;
1235 if (!open_connection(&cli1
) || !open_connection(&cli2
)) {
1239 cli_sockopt(&cli1
, sockops
);
1240 cli_sockopt(&cli2
, sockops
);
1242 printf("starting locktest4\n");
1244 cli_unlink(&cli1
, fname
);
1246 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1247 fnum2
= cli_open(&cli2
, fname
, O_RDWR
, DENY_NONE
);
1249 memset(buf
, 0, sizeof(buf
));
1251 if (cli_write(&cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1252 printf("Failed to create file\n");
1257 ret
= cli_lock(&cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
1258 cli_lock(&cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
);
1259 EXPECTED(ret
, False
);
1260 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
1262 ret
= cli_lock(&cli1
, fnum1
, 10, 4, 0, READ_LOCK
) &&
1263 cli_lock(&cli1
, fnum1
, 12, 4, 0, READ_LOCK
);
1264 EXPECTED(ret
, True
);
1265 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
1267 ret
= cli_lock(&cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
) &&
1268 cli_lock(&cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
);
1269 EXPECTED(ret
, False
);
1270 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
1272 ret
= cli_lock(&cli1
, fnum1
, 30, 4, 0, READ_LOCK
) &&
1273 cli_lock(&cli2
, fnum2
, 32, 4, 0, READ_LOCK
);
1274 EXPECTED(ret
, True
);
1275 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
1277 ret
= (cli_setpid(&cli1
, 1), cli_lock(&cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
)) &&
1278 (cli_setpid(&cli1
, 2), cli_lock(&cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
));
1279 EXPECTED(ret
, False
);
1280 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
1282 ret
= (cli_setpid(&cli1
, 1), cli_lock(&cli1
, fnum1
, 50, 4, 0, READ_LOCK
)) &&
1283 (cli_setpid(&cli1
, 2), cli_lock(&cli1
, fnum1
, 52, 4, 0, READ_LOCK
));
1284 EXPECTED(ret
, True
);
1285 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
1287 ret
= cli_lock(&cli1
, fnum1
, 60, 4, 0, READ_LOCK
) &&
1288 cli_lock(&cli1
, fnum1
, 60, 4, 0, READ_LOCK
);
1289 EXPECTED(ret
, True
);
1290 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
1292 ret
= cli_lock(&cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
) &&
1293 cli_lock(&cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
);
1294 EXPECTED(ret
, False
);
1295 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
1297 ret
= cli_lock(&cli1
, fnum1
, 80, 4, 0, READ_LOCK
) &&
1298 cli_lock(&cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
);
1299 EXPECTED(ret
, False
);
1300 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
1302 ret
= cli_lock(&cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
) &&
1303 cli_lock(&cli1
, fnum1
, 90, 4, 0, READ_LOCK
);
1304 EXPECTED(ret
, True
);
1305 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1307 ret
= (cli_setpid(&cli1
, 1), cli_lock(&cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
)) &&
1308 (cli_setpid(&cli1
, 2), cli_lock(&cli1
, fnum1
, 100, 4, 0, READ_LOCK
));
1309 EXPECTED(ret
, False
);
1310 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1312 ret
= cli_lock(&cli1
, fnum1
, 110, 4, 0, READ_LOCK
) &&
1313 cli_lock(&cli1
, fnum1
, 112, 4, 0, READ_LOCK
) &&
1314 cli_unlock(&cli1
, fnum1
, 110, 6);
1315 EXPECTED(ret
, False
);
1316 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
1319 ret
= cli_lock(&cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
) &&
1320 (cli_read(&cli2
, fnum2
, buf
, 120, 4) == 4);
1321 EXPECTED(ret
, False
);
1322 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
1324 ret
= cli_lock(&cli1
, fnum1
, 130, 4, 0, READ_LOCK
) &&
1325 (cli_write(&cli2
, fnum2
, 0, buf
, 130, 4) == 4);
1326 EXPECTED(ret
, False
);
1327 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
1330 ret
= cli_lock(&cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1331 cli_lock(&cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1332 cli_unlock(&cli1
, fnum1
, 140, 4) &&
1333 cli_unlock(&cli1
, fnum1
, 140, 4);
1334 EXPECTED(ret
, True
);
1335 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
1338 ret
= cli_lock(&cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
) &&
1339 cli_lock(&cli1
, fnum1
, 150, 4, 0, READ_LOCK
) &&
1340 cli_unlock(&cli1
, fnum1
, 150, 4) &&
1341 (cli_read(&cli2
, fnum2
, buf
, 150, 4) == 4) &&
1342 !(cli_write(&cli2
, fnum2
, 0, buf
, 150, 4) == 4) &&
1343 cli_unlock(&cli1
, fnum1
, 150, 4);
1344 EXPECTED(ret
, True
);
1345 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
1347 ret
= cli_lock(&cli1
, fnum1
, 160, 4, 0, READ_LOCK
) &&
1348 cli_unlock(&cli1
, fnum1
, 160, 4) &&
1349 (cli_write(&cli2
, fnum2
, 0, buf
, 160, 4) == 4) &&
1350 (cli_read(&cli2
, fnum2
, buf
, 160, 4) == 4);
1351 EXPECTED(ret
, True
);
1352 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
1354 ret
= cli_lock(&cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
) &&
1355 cli_unlock(&cli1
, fnum1
, 170, 4) &&
1356 (cli_write(&cli2
, fnum2
, 0, buf
, 170, 4) == 4) &&
1357 (cli_read(&cli2
, fnum2
, buf
, 170, 4) == 4);
1358 EXPECTED(ret
, True
);
1359 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
1361 ret
= cli_lock(&cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
) &&
1362 cli_lock(&cli1
, fnum1
, 190, 4, 0, READ_LOCK
) &&
1363 cli_unlock(&cli1
, fnum1
, 190, 4) &&
1364 !(cli_write(&cli2
, fnum2
, 0, buf
, 190, 4) == 4) &&
1365 (cli_read(&cli2
, fnum2
, buf
, 190, 4) == 4);
1366 EXPECTED(ret
, True
);
1367 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
1369 cli_close(&cli1
, fnum1
);
1370 cli_close(&cli2
, fnum2
);
1371 fnum1
= cli_open(&cli1
, fname
, O_RDWR
, DENY_NONE
);
1372 f
= cli_open(&cli1
, fname
, O_RDWR
, DENY_NONE
);
1373 ret
= cli_lock(&cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
1374 cli_lock(&cli1
, f
, 0, 1, 0, READ_LOCK
) &&
1375 cli_close(&cli1
, fnum1
) &&
1376 ((fnum1
= cli_open(&cli1
, fname
, O_RDWR
, DENY_NONE
)) != -1) &&
1377 cli_lock(&cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
1378 cli_close(&cli1
, f
);
1379 EXPECTED(ret
, True
);
1380 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
1383 cli_close(&cli1
, fnum1
);
1384 cli_close(&cli2
, fnum2
);
1385 cli_unlink(&cli1
, fname
);
1386 close_connection(&cli1
);
1387 close_connection(&cli2
);
1389 printf("finished locktest4\n");
1394 looks at lock upgrade/downgrade.
1396 static BOOL
run_locktest5(int dummy
)
1398 static struct cli_state cli1
, cli2
;
1399 char *fname
= "\\lockt5.lck";
1400 int fnum1
, fnum2
, fnum3
;
1403 BOOL correct
= True
;
1405 if (!open_connection(&cli1
) || !open_connection(&cli2
)) {
1409 cli_sockopt(&cli1
, sockops
);
1410 cli_sockopt(&cli2
, sockops
);
1412 printf("starting locktest5\n");
1414 cli_unlink(&cli1
, fname
);
1416 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1417 fnum2
= cli_open(&cli2
, fname
, O_RDWR
, DENY_NONE
);
1418 fnum3
= cli_open(&cli1
, fname
, O_RDWR
, DENY_NONE
);
1420 memset(buf
, 0, sizeof(buf
));
1422 if (cli_write(&cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1423 printf("Failed to create file\n");
1428 /* Check for NT bug... */
1429 ret
= cli_lock(&cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
1430 cli_lock(&cli1
, fnum3
, 0, 1, 0, READ_LOCK
);
1431 cli_close(&cli1
, fnum1
);
1432 fnum1
= cli_open(&cli1
, fname
, O_RDWR
, DENY_NONE
);
1433 ret
= cli_lock(&cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
1434 EXPECTED(ret
, True
);
1435 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
1436 cli_close(&cli1
, fnum1
);
1437 fnum1
= cli_open(&cli1
, fname
, O_RDWR
, DENY_NONE
);
1438 cli_unlock(&cli1
, fnum3
, 0, 1);
1440 ret
= cli_lock(&cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
1441 cli_lock(&cli1
, fnum1
, 1, 1, 0, READ_LOCK
);
1442 EXPECTED(ret
, True
);
1443 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
1445 ret
= cli_lock(&cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
1446 EXPECTED(ret
, False
);
1448 printf("a different processs %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
1450 /* Unlock the process 2 lock. */
1451 cli_unlock(&cli2
, fnum2
, 0, 4);
1453 ret
= cli_lock(&cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
1454 EXPECTED(ret
, False
);
1456 printf("the same processs on a different fnum %s get a read lock\n", ret
?"can":"cannot");
1458 /* Unlock the process 1 fnum3 lock. */
1459 cli_unlock(&cli1
, fnum3
, 0, 4);
1461 /* Stack 2 more locks here. */
1462 ret
= cli_lock(&cli1
, fnum1
, 0, 4, 0, READ_LOCK
) &&
1463 cli_lock(&cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
1465 EXPECTED(ret
, True
);
1466 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
1468 /* Unlock the first process lock, then check this was the WRITE lock that was
1471 ret
= cli_unlock(&cli1
, fnum1
, 0, 4) &&
1472 cli_lock(&cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
1474 EXPECTED(ret
, True
);
1475 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
1477 /* Unlock the process 2 lock. */
1478 cli_unlock(&cli2
, fnum2
, 0, 4);
1480 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1482 ret
= cli_unlock(&cli1
, fnum1
, 1, 1) &&
1483 cli_unlock(&cli1
, fnum1
, 0, 4) &&
1484 cli_unlock(&cli1
, fnum1
, 0, 4);
1486 EXPECTED(ret
, True
);
1487 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
1489 /* Ensure the next unlock fails. */
1490 ret
= cli_unlock(&cli1
, fnum1
, 0, 4);
1491 EXPECTED(ret
, False
);
1492 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
1494 /* Ensure connection 2 can get a write lock. */
1495 ret
= cli_lock(&cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
1496 EXPECTED(ret
, True
);
1498 printf("a different processs %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
1502 cli_close(&cli1
, fnum1
);
1503 cli_close(&cli2
, fnum2
);
1504 cli_unlink(&cli1
, fname
);
1505 if (!close_connection(&cli1
)) {
1508 if (!close_connection(&cli2
)) {
1512 printf("finished locktest5\n");
1519 this produces a matrix of deny mode behaviour
1521 static BOOL
run_denytest1(int dummy
)
1523 static struct cli_state cli1
, cli2
;
1525 int f
, d1
, d2
, o1
, o2
, x
=0;
1526 char *fnames
[] = {"\\denytest1.exe", "\\denytest1.dat", NULL
};
1531 {DENY_DOS
, "DENY_DOS"},
1532 {DENY_ALL
, "DENY_ALL"},
1533 {DENY_WRITE
, "DENY_WRITE"},
1534 {DENY_READ
, "DENY_READ"},
1535 {DENY_NONE
, "DENY_NONE"},
1536 {DENY_FCB
, "DENY_FCB"},
1543 {O_RDONLY
, "O_RDONLY"},
1544 {O_WRONLY
, "O_WRONLY"},
1546 BOOL correct
= True
;
1548 if (!open_connection(&cli1
) || !open_connection(&cli2
)) {
1551 cli_sockopt(&cli1
, sockops
);
1552 cli_sockopt(&cli2
, sockops
);
1554 printf("starting denytest1\n");
1556 for (f
=0;fnames
[f
];f
++) {
1557 cli_unlink(&cli1
, fnames
[f
]);
1559 fnum1
= cli_open(&cli1
, fnames
[f
], O_RDWR
|O_CREAT
, DENY_NONE
);
1560 cli_write(&cli1
, fnum1
, 0, fnames
[f
], 0, strlen(fnames
[f
]));
1561 cli_close(&cli1
, fnum1
);
1563 for (d1
=0;deny_modes
[d1
].name
;d1
++)
1564 for (o1
=0;open_modes
[o1
].name
;o1
++)
1565 for (d2
=0;deny_modes
[d2
].name
;d2
++)
1566 for (o2
=0;open_modes
[o2
].name
;o2
++) {
1567 fnum1
= cli_open(&cli1
, fnames
[f
],
1570 fnum2
= cli_open(&cli2
, fnames
[f
],
1574 printf("%s %8s %10s %8s %10s ",
1576 open_modes
[o1
].name
,
1577 deny_modes
[d1
].name
,
1578 open_modes
[o2
].name
,
1579 deny_modes
[d2
].name
);
1583 } else if (fnum2
== -1) {
1586 if (cli_read(&cli2
, fnum2
, (void *)&x
, 0, 1) == 1) {
1589 if (cli_write(&cli2
, fnum2
, 0, (void *)&x
, 0, 1) == 1) {
1595 cli_close(&cli1
, fnum1
);
1596 cli_close(&cli2
, fnum2
);
1599 cli_unlink(&cli1
, fnames
[f
]);
1602 if (!close_connection(&cli1
)) {
1605 if (!close_connection(&cli2
)) {
1609 printf("finshed denytest1\n");
1615 this produces a matrix of deny mode behaviour for two opens on the
1618 static BOOL
run_denytest2(int dummy
)
1620 static struct cli_state cli1
;
1622 int f
, d1
, d2
, o1
, o2
, x
=0;
1623 char *fnames
[] = {"\\denytest2.exe", "\\denytest2.dat", NULL
};
1628 {DENY_DOS
, "DENY_DOS"},
1629 {DENY_ALL
, "DENY_ALL"},
1630 {DENY_WRITE
, "DENY_WRITE"},
1631 {DENY_READ
, "DENY_READ"},
1632 {DENY_NONE
, "DENY_NONE"},
1633 {DENY_FCB
, "DENY_FCB"},
1640 {O_RDONLY
, "O_RDONLY"},
1641 {O_WRONLY
, "O_WRONLY"},
1643 BOOL correct
= True
;
1645 if (!open_connection(&cli1
)) {
1648 cli_sockopt(&cli1
, sockops
);
1650 printf("starting denytest2\n");
1652 for (f
=0;fnames
[f
];f
++) {
1653 cli_unlink(&cli1
, fnames
[f
]);
1655 fnum1
= cli_open(&cli1
, fnames
[f
], O_RDWR
|O_CREAT
, DENY_NONE
);
1656 cli_write(&cli1
, fnum1
, 0, fnames
[f
], 0, strlen(fnames
[f
]));
1657 cli_close(&cli1
, fnum1
);
1659 for (d1
=0;deny_modes
[d1
].name
;d1
++)
1660 for (o1
=0;open_modes
[o1
].name
;o1
++)
1661 for (d2
=0;deny_modes
[d2
].name
;d2
++)
1662 for (o2
=0;open_modes
[o2
].name
;o2
++) {
1663 fnum1
= cli_open(&cli1
, fnames
[f
],
1666 fnum2
= cli_open(&cli1
, fnames
[f
],
1670 printf("%s %8s %10s %8s %10s ",
1672 open_modes
[o1
].name
,
1673 deny_modes
[d1
].name
,
1674 open_modes
[o2
].name
,
1675 deny_modes
[d2
].name
);
1679 } else if (fnum2
== -1) {
1682 if (cli_read(&cli1
, fnum2
, (void *)&x
, 0, 1) == 1) {
1685 if (cli_write(&cli1
, fnum2
, 0, (void *)&x
, 0, 1) == 1) {
1691 cli_close(&cli1
, fnum1
);
1692 cli_close(&cli1
, fnum2
);
1695 cli_unlink(&cli1
, fnames
[f
]);
1698 if (!close_connection(&cli1
)) {
1702 printf("finshed denytest2\n");
1707 test whether fnums and tids open on one VC are available on another (a major
1710 static BOOL
run_fdpasstest(int dummy
)
1712 static struct cli_state cli1
, cli2
, cli3
;
1713 char *fname
= "\\fdpass.tst";
1717 if (!open_connection(&cli1
) || !open_connection(&cli2
)) {
1720 cli_sockopt(&cli1
, sockops
);
1721 cli_sockopt(&cli2
, sockops
);
1723 printf("starting fdpasstest\n");
1725 cli_unlink(&cli1
, fname
);
1727 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1729 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
1733 if (cli_write(&cli1
, fnum1
, 0, "hello world\n", 0, 13) != 13) {
1734 printf("write failed (%s)\n", cli_errstr(&cli1
));
1739 cli3
.vuid
= cli1
.vuid
;
1740 cli3
.cnum
= cli1
.cnum
;
1741 cli3
.pid
= cli1
.pid
;
1743 if (cli_read(&cli3
, fnum1
, buf
, 0, 13) == 13) {
1744 printf("read succeeded! nasty security hole [%s]\n",
1749 cli_close(&cli1
, fnum1
);
1750 cli_unlink(&cli1
, fname
);
1752 close_connection(&cli1
);
1753 close_connection(&cli2
);
1755 printf("finished fdpasstest\n");
1759 /*test multiple users over a single tcp connection*/
1760 /*test multiple users over a single tcp connection ~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1761 /*test multiple users over a single tcp connection*/
1764 typedef struct subtaboid
{
1766 struct subtaboid
*next
;
1775 typedef struct taboid
{
1777 int owner
, share
, as_user
;
1781 SUBTABOID
*subtaboids
[2];
1785 static void init_TABOID(TABOID
*t
, int owner
, int share
, int as_user
)
1787 memset( t
, '\0', sizeof(*t
));
1790 t
->as_user
= as_user
;
1793 static BOOL
run_vusertest_op_null(TABOID
*t
)
1798 static BOOL
run_vusertest_report_full(
1799 const char *operation
,
1800 const char *sub_operation
,
1811 "%8s[%s]:%10s file %10s user %10s(%5d). share %10s tid %5d owner %10s(%5d). fnum %5d was %5d (%s).",
1813 failure
?"FAILURE":"SUCCESS",
1815 vusers
[t
->owner
].fname
,
1816 vusers
[t
->as_user
].username
,
1817 /*vusers[t->as_user].vuid,*/
1818 vusers
[t
->as_user
].cli
.vuid
,
1820 /*vusers[t->owner].per_tid[t->share].tid,*/
1821 vusers
[t
->as_user
].cli
.cnum
,
1822 vusers
[t
->owner
].username
,
1823 /*vusers[t->owner].vuid,*/
1824 vusers
[t
->owner
].cli
.vuid
,
1825 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
],
1826 vusers
[t
->as_user
].per_tid
[t
->share
].backup_fnum
[t
->owner
],
1827 failure
?cli_errstr(&vusers
[t
->as_user
].cli
):""
1831 printf("%s\n", *buf
);
1836 static BOOL
run_vusertest_report(
1837 const char *operation
,
1838 const char *sub_operation
,
1845 return run_vusertest_report_full(operation
, sub_operation
, failure
, True
, &buf
, t
);
1848 static BOOL
run_vusertest_report_failure(
1849 const char *operation
,
1850 const char *sub_operation
,
1856 return run_vusertest_report_full(operation
, sub_operation
, True
, True
, &buf
, t
);
1859 static BOOL
run_vusertest_report_success(
1860 const char *operation
,
1861 const char *sub_operation
,
1867 return run_vusertest_report_full(operation
, sub_operation
, False
, True
, &buf
, t
);
1870 static BOOL
run_vusertest_op_init(TABOID
*t
)
1875 vusers
[t
->owner
].fname
[0] = '\0';
1877 vusers
[t
->owner
].vuid
= 0;
1878 vusers
[t
->owner
].vuid_valid
= False
;
1879 vusers
[t
->owner
].files_valid
= False
;
1881 for(i
= 0; i
< sizeof(vusers
[t
->owner
].per_tid
)/sizeof(vusers
[t
->owner
].per_tid
[0]); i
++) {
1883 vusers
[t
->owner
].per_tid
[i
].tid
= 0;
1884 vusers
[t
->owner
].per_tid
[i
].tid_valid
= False
;
1886 for(j
= 0; j
< sizeof(vusers
[t
->owner
].per_tid
[i
].fnum
)/sizeof(vusers
[t
->owner
].per_tid
[i
].fnum
[0]); j
++) {
1888 vusers
[t
->owner
].per_tid
[i
].fnum
[j
] = vusers
[t
->owner
].per_tid
[i
].backup_fnum
[j
] = -1;
1895 static BOOL
run_vusertest_op_create(TABOID
*t
)
1898 BOOL should_work
= (vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
&& vusers
[t
->as_user
].vuid_valid
);
1900 snprintf(vusers
[t
->owner
].fname
, sizeof(vusers
[t
->owner
].fname
), "muserconn_%d", t
->owner
);
1902 vusers
[t
->as_user
].cli
.cnum
= vusers
[t
->owner
].per_tid
[t
->share
].tid
;
1904 if(!cli_unlink(&vusers
[t
->as_user
].cli
, vusers
[t
->owner
].fname
)) {
1906 run_vusertest_report_failure("CREATE", "unlink", t
);
1908 return should_work
?False
:True
;
1911 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
] =
1912 cli_open(&vusers
[t
->as_user
].cli
, vusers
[t
->owner
].fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
1914 if (vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
] == -1) {
1916 run_vusertest_report_failure("CREATE", "create", t
);
1918 return should_work
?False
:True
;
1921 run_vusertest_report_success("CREATE", "created", t
);
1923 vusers
[t
->as_user
].files_valid
= True
; /*not true for all!*/
1925 return should_work
?True
:False
;
1928 static BOOL
run_vusertest_op_write(TABOID
*t
)
1931 BOOL should_work
= (
1932 vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
&&
1933 vusers
[t
->as_user
].vuid_valid
&&
1934 vusers
[t
->as_user
].files_valid
1940 vusers
[t
->as_user
].cli
.cnum
= vusers
[t
->owner
].per_tid
[t
->share
].tid
;
1942 run_vusertest_report_full("WRITE", "write 2", False
, False
, &msg
, t
);
1944 msglen
= strlen(msg
)+1;
1946 if (cli_write(&vusers
[t
->as_user
].cli
,
1947 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
], 0, (char *)&msglen
, 0, sizeof(msglen
)) != sizeof(msglen
)) {
1949 run_vusertest_report_failure("WRITE", "write 1", t
);
1951 return should_work
?False
:True
;
1954 if (cli_write(&vusers
[t
->as_user
].cli
,
1955 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
], 0, msg
, sizeof(msglen
), msglen
) != msglen
) {
1957 run_vusertest_report_failure("WRITE", "write 2", t
);
1959 return should_work
?False
:True
;
1962 run_vusertest_report_success("WRITE", "write", t
);
1964 return should_work
?True
:False
;
1967 static BOOL
run_vusertest_op_create_and_write(TABOID
*t
)
1972 if(!run_vusertest_op_create(t
)) {
1977 if(!run_vusertest_op_write(t
)) {
1985 static BOOL
run_vusertest_op_openr(TABOID
*t
)
1988 BOOL should_work
= (vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
&& vusers
[t
->as_user
].vuid_valid
);
1990 vusers
[t
->as_user
].cli
.cnum
= vusers
[t
->owner
].per_tid
[t
->share
].tid
;
1992 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
] =
1993 cli_open(&vusers
[t
->as_user
].cli
, vusers
[t
->owner
].fname
, O_RDONLY
, DENY_NONE
);
1995 if (vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
] == -1) {
1997 run_vusertest_report_failure("OPENR", "open", t
);
1999 return should_work
?False
:True
;
2002 run_vusertest_report_success("OPENR", "open", t
);
2004 vusers
[t
->as_user
].files_valid
= True
; /*not true for all!*/
2006 return should_work
?True
:False
;
2009 static BOOL
run_vusertest_op_read(TABOID
*t
)
2015 BOOL should_work
= (
2016 vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
&&
2017 vusers
[t
->as_user
].vuid_valid
&&
2018 vusers
[t
->as_user
].files_valid
&&
2019 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
] != -1
2022 vusers
[t
->as_user
].cli
.cnum
= vusers
[t
->owner
].per_tid
[t
->share
].tid
;
2024 if (cli_read(&vusers
[t
->as_user
].cli
,
2025 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
], (char *)&msglen
, 0, sizeof(msglen
)) != sizeof(msglen
)) {
2027 run_vusertest_report_failure("READ", "read 1", t
);
2029 return should_work
?False
:True
;
2032 if (cli_read(&vusers
[t
->as_user
].cli
,
2033 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
], msg
, sizeof(msglen
), msglen
) != msglen
) {
2035 run_vusertest_report_failure("READ", "read 2", t
);
2037 return should_work
?False
:True
;
2040 run_vusertest_report_success("READ", "read", t
);
2042 return should_work
?True
:False
;
2045 static BOOL
run_vusertest_op_openr_and_read(TABOID
*t
)
2050 if(!run_vusertest_op_openr(t
)) {
2055 if(!run_vusertest_op_read(t
)) {
2063 static BOOL
run_vusertest_op_backup_open_fids(TABOID
*t
)
2066 memcpy(vusers
[t
->as_user
].per_tid
[t
->share
].backup_fnum
,
2067 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
,
2068 sizeof(vusers
[t
->as_user
].per_tid
[t
->share
].fnum
));
2073 static BOOL
run_vusertest_op_close(TABOID
*t
)
2076 BOOL should_work
= (
2078 vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
&&
2079 vusers
[t
->as_user
].vuid_valid
&&
2080 vusers
[t
->as_user
].files_valid
2084 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
] == -1 &&
2085 vusers
[t
->as_user
].per_tid
[t
->share
].backup_fnum
[t
->owner
] == -1
2089 BOOL ret
= should_work
?True
:False
;
2091 vusers
[t
->as_user
].cli
.cnum
= vusers
[t
->owner
].per_tid
[t
->share
].tid
;
2093 if(vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
] != -1) {
2095 if(!cli_close(&vusers
[t
->as_user
].cli
, vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
])) {
2097 run_vusertest_report_failure("CLOSE", "close", t
);
2099 ret
= should_work
?False
:True
;
2102 run_vusertest_report_success("CLOSE", "close", t
);
2105 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
] = -1;
2108 if(vusers
[t
->as_user
].per_tid
[t
->share
].backup_fnum
[t
->owner
] != -1 &&
2109 vusers
[t
->as_user
].per_tid
[t
->share
].backup_fnum
[t
->owner
] != 0) {
2111 if(!cli_close(&vusers
[t
->as_user
].cli
, vusers
[t
->as_user
].per_tid
[t
->share
].backup_fnum
[t
->owner
])) {
2113 run_vusertest_report_failure("CLOSE", "close backup", t
);
2115 ret
= should_work
?False
:True
;
2119 run_vusertest_report_success("CLOSE", "close backup", t
);
2122 vusers
[t
->as_user
].per_tid
[t
->share
].backup_fnum
[t
->owner
] = -1;
2128 static BOOL
run_vusertest_op_tcon(TABOID
*t
)
2131 BOOL should_work
= (vusers
[t
->as_user
].vuid_valid
);
2133 vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
= False
;
2135 if (!cli_send_tconX(&vusers
[t
->as_user
].cli
,
2138 vusers
[t
->as_user
].password
,
2139 strlen(vusers
[t
->as_user
].password
)+1)) {
2141 run_vusertest_report_failure("TCON", "tcon", t
);
2143 return should_work
?False
:True
;
2146 vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
= True
;
2147 vusers
[t
->owner
].per_tid
[t
->share
].tid
= vusers
[t
->as_user
].cli
.cnum
;
2149 run_vusertest_report_success("TCON", "tcon", t
);
2151 return should_work
?True
:False
;
2154 static BOOL
run_vusertest_op_tdis(TABOID
*t
)
2157 BOOL should_work
= (vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
&& vusers
[t
->as_user
].vuid_valid
);
2160 if(!vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
) {
2166 vusers
[t
->as_user
].cli
.cnum
= vusers
[t
->owner
].per_tid
[t
->share
].tid
;
2168 if(!cli_tdis(&vusers
[t
->as_user
].cli
)) {
2170 run_vusertest_report_failure("TDIS", "tdis", t
);
2172 return should_work
?False
:True
;
2175 run_vusertest_report_success("TDIS", "tdis", t
);
2177 vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
= False
;
2179 return should_work
?True
:False
;
2182 static BOOL
run_vusertest_op_ulogon(TABOID
*t
)
2185 vusers
[t
->owner
].cli
= *seed
;
2187 vusers
[t
->owner
].vuid_valid
= False
;
2189 if (!cli_session_setup(&vusers
[t
->owner
].cli
,
2190 vusers
[t
->owner
].username
,
2191 vusers
[t
->owner
].password
,
2192 strlen(vusers
[t
->owner
].password
),
2193 vusers
[t
->owner
].password
,
2194 strlen(vusers
[t
->owner
].password
),
2198 run_vusertest_report_failure("ULOGON", "logon", t
);
2203 run_vusertest_report_success("ULOGON", "logon", t
);
2205 vusers
[t
->owner
].vuid_valid
= True
;
2206 vusers
[t
->owner
].vuid
= vusers
[t
->owner
].cli
.vuid
;
2211 static BOOL
run_vusertest_op_ulogoff(TABOID
*t
)
2214 BOOL should_work
= (vusers
[t
->owner
].vuid_valid
);
2217 if(!vusers
[t
->owner
].vuid_valid
) {
2223 if(!cli_ulogoff(&vusers
[t
->owner
].cli
)) {
2225 run_vusertest_report_failure("ULOGOFF", "logoff", t
);
2227 return should_work
?False
:True
;
2230 run_vusertest_report_success("ULOGOFF", "logoff", t
);
2232 vusers
[t
->owner
].vuid_valid
= False
;
2233 vusers
[t
->owner
].files_valid
= False
;
2235 return should_work
?True
:False
;
2238 /***********************************************************/
2239 /***********************************************************/
2241 static BOOL
run_vusertest_owner_op(BOOL (*op
)(TABOID
*t
))
2248 for(; owner
< nusers
; owner
++) {
2251 init_TABOID(&t
, owner
, 0, owner
);
2256 printf("^^^^^^^^^^^^^^^^\n");
2263 static BOOL
run_vusertest_owner_share_op(BOOL (*op
)(TABOID
*t
))
2270 for(; owner
< nusers
; owner
++) {
2274 for(; share
< nshares
; share
++) {
2277 init_TABOID( &t
, owner
, share
, owner
);
2282 printf("^^^^^^^^^^^^^^^^\n");
2290 static BOOL
run_vusertest_owner_share_preop_user_op(
2291 BOOL (*preop
)(TABOID
*t
),
2292 BOOL (*op
)(TABOID
*t
),
2293 BOOL (*postop
)(TABOID
*t
)
2301 for(; owner
< nusers
; owner
++) {
2305 for(; share
< nshares
; share
++) {
2308 init_TABOID( &t
, owner
, share
, owner
);
2313 printf("^^^^^^^^^^^^^^^^\n");
2316 for(t
.as_user
= 0; t
.as_user
< nusers
; t
.as_user
++) {
2322 printf("^^^^^^^^^^^^^^^^\n");
2331 printf("^^^^^^^^^^^^^^^^\n");
2339 static BOOL
run_vusertest_owner_share_user_preop_op(
2340 BOOL (*preop
)(TABOID
*t
),
2341 BOOL (*op
)(TABOID
*t
),
2342 BOOL (*postop
)(TABOID
*t
)
2350 for(; owner
< nusers
; owner
++) {
2354 for(; share
< nshares
; share
++) {
2358 for(; as_user
< nusers
; as_user
++) {
2361 init_TABOID( &t
, owner
, share
, owner
);
2367 printf("^^^^^^^^^^^^^^^^\n");
2370 t
.as_user
= as_user
;
2377 printf("^^^^^^^^^^^^^^^^\n");
2387 printf("^^^^^^^^^^^^^^^^\n");
2398 #define VU_INIT (run_vusertest_owner_op(run_vusertest_op_init))
2400 #define VU_ULOGON (run_vusertest_owner_op(run_vusertest_op_ulogon))
2401 #define VU_ULOGOFF (run_vusertest_owner_op(run_vusertest_op_ulogoff))
2403 /*each user applies op to each of their shares*/
2405 #define VU_TCON (run_vusertest_owner_share_op(run_vusertest_op_tcon))
2406 #define VU_TDIS (run_vusertest_owner_share_op(run_vusertest_op_tdis))
2408 #define VU_CREATE_AND_WRITE (run_vusertest_owner_share_op(run_vusertest_op_create_and_write))
2409 #define VU_OPEN_AND_READ (run_vusertest_owner_share_op(run_vusertest_op_openr_and_read))
2410 #define VU_READ (run_vusertest_owner_share_op(run_vusertest_op_read))
2411 #define VU_FCLOSE (run_vusertest_owner_share_op(run_vusertest_op_close))
2412 #define VU_BACKUP_FIDS (run_vusertest_owner_share_op(run_vusertest_op_backup_open_fids))
2414 /*for u1 for u2 apply op as u2 on u1's tid*/
2416 #define VU_CROSS_READ (run_vusertest_owner_share_preop_user_op(run_vusertest_op_null,\
2417 run_vusertest_op_read,\
2418 run_vusertest_op_null))
2419 #define VU_CROSS_OPEN_AND_READ (run_vusertest_owner_share_preop_user_op(run_vusertest_op_null,\
2420 run_vusertest_op_openr_and_read,\
2421 run_vusertest_op_null))
2422 #define VU_CROSS_FCLOSE (run_vusertest_owner_share_preop_user_op(run_vusertest_op_null,\
2423 run_vusertest_op_close,\
2424 run_vusertest_op_null))
2426 #define VU_TCON_TDIS_OPEN_AND_READ (run_vusertest_owner_share_user_preop_op(run_vusertest_op_tcon,\
2427 run_vusertest_op_tdis,\
2428 run_vusertest_op_openr_and_read))
2433 Check relationship between:
2437 session logoff (Samba closes all files for vuid)
2439 tree disconnection (Samba set conn->used to False then calls close_cnum(conn, vuid), this flushes dir cache, closes files on the conn, frees the conn structure)
2441 1. can a user access a tid connected by another
2445 u2 opens file on u1's tid
2449 2. can one user disconnect a tid connected by another
2453 connect u1's tid as u1
2454 disconnect u1's tid as u2;
2455 open and read files as u1
2459 2a. does a disconnect by another invalidate the tid for the original connector
2461 3. does a disconnect invalidate a tid with no files open on it
2466 open and read files on u1's tid
2469 4. does a disconnect invalidate a tid with files open on it
2474 open and read files on u1's tid as u1
2477 5. does a disconnect invalidate files open on a tid.
2482 read files on u1's tid as u1
2485 6. can a user session exist with no tid and no open files
2499 7. does a logoff invalidate a tid with no files open on it
2504 open and read files on u1's tid
2510 open and read files on u1's tid
2513 8. does a logoff invalidate a tid with files open on it
2518 open and read files on u1's tid
2523 open and read files on u1's tid
2526 9. does a logoff invalidate a fid.
2531 read files on u1's tid
2536 read files on u1's tid
2540 10. does a logoff invalidate a vuid.
2544 11. can a connection survive close files, close tids, logoff users
2548 disconnect u1's tids
2562 static BOOL
run_vusertest(int dummy
)
2568 seed
= &vusers
[0].cli
;
2572 printf("\nopen nbt connection\n");
2574 if (!open_nbt_connection(seed
)) {
2579 cli_sockopt(seed
, sockops
);
2581 printf("\nnegotiate protocol\n");
2583 /*the CIFS spec says this should be done only once on a VC and W2K doesn't like it more than once. Samba doesn't mind*/
2585 if (!cli_negprot(seed
)) {
2586 printf("%s rejected the negprot (%s)\n",host
, cli_errstr(seed
));
2591 printf("\nnegotiate protocol again.\n");
2593 if (!cli_negprot(seed
)) {
2595 printf("%s rejected a second negprot (%s)\n",host
, cli_errstr(seed
));
2597 printf("\nshutdown client\n");
2603 printf("\nopen new nbt session\n");
2605 if (!open_nbt_connection(seed
)) {
2610 cli_sockopt(seed
, sockops
);
2612 printf("\nre negotiate protocol\n");
2614 if (!cli_negprot(seed
)) {
2615 printf("%s rejected the negprot (%s)\n",host
, cli_errstr(seed
));
2621 printf("starting vusertest with %d users and %d shares.\n", nusers
, nshares
);
2623 /***********************************************************/
2624 /***********************************************************/
2626 printf("\ninitialise\n\n");
2630 printf("initialisation failed.\n");
2634 printf("\nsetup sessions\n\n");
2638 printf("setup sessions failed.\n");
2642 printf("\nconnect to shares\n\n");
2646 printf("connect to shares failed.\n");
2650 /***********************************************************/
2651 /***********************************************************/
2655 char *test
= "create and write files";
2658 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2662 if(!VU_CREATE_AND_WRITE
) {
2664 printf("%s failed.\n", test
);
2675 printf("TEST FAILED.\n");
2680 /***********************************************************/
2681 /***********************************************************/
2684 char *test
= "can a user access a tid connected by another?";
2688 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2692 if(!VU_CROSS_OPEN_AND_READ
) {
2697 if(!VU_CROSS_FCLOSE
) {
2704 printf("TEST FAILED.\n");
2709 /***********************************************************/
2710 /***********************************************************/
2713 char *test
= "can one user disconnect a tid connected by another.\n2a does disconnect by another invalidate tid for all?";
2717 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2721 if(!VU_TCON_TDIS_OPEN_AND_READ
) {
2726 if(!VU_CROSS_FCLOSE
) {
2733 printf("TEST FAILED.\n");
2738 /***********************************************************/
2739 /***********************************************************/
2743 char *test
= "does a disconnect invalidate a tid with no files open on it?";
2747 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2761 if(!VU_OPEN_AND_READ
) {
2773 printf("TEST FAILED.\n");
2778 /***********************************************************/
2779 /***********************************************************/
2783 char *test
= "does a disconnect invalidate a tid with files open on it?";
2787 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2796 if(!VU_OPEN_AND_READ
) {
2806 if(!VU_OPEN_AND_READ
) {
2818 printf("TEST FAILED.\n");
2823 /***********************************************************/
2824 /***********************************************************/
2828 char *test
= "does a disconnect invalidate files open on a tid?";
2832 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2841 if(!VU_OPEN_AND_READ
) {
2868 printf("TEST FAILED.\n");
2873 /***********************************************************/
2874 /***********************************************************/
2878 char *test
= "can a user session exist with no tid and no open files?";
2882 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2896 if(!VU_OPEN_AND_READ
) {
2903 printf("TEST FAILED.\n");
2908 /***********************************************************/
2909 /***********************************************************/
2913 char *test
= "does a logoff invalidate a tid with no files open on it?";
2917 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2931 if(!VU_OPEN_AND_READ
) {
2946 if(!VU_OPEN_AND_READ
) {
2968 printf("TEST FAILED.\n");
2973 /***********************************************************/
2974 /***********************************************************/
2977 char *test
= "does a logoff invalidate a tid with files open on it?";
2981 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2985 if(!VU_OPEN_AND_READ
) {
2995 if(!VU_OPEN_AND_READ
) {
3005 if(!VU_OPEN_AND_READ
) {
3027 printf("TEST FAILED.\n");
3032 /***********************************************************/
3033 /***********************************************************/
3036 char *test
= "does a logoff invalidate a fid?";
3039 printf("\nTEST:%d %s\n\n", testcnt
, test
);
3043 if(!VU_OPEN_AND_READ
) {
3085 printf("TEST FAILED.\n");
3090 /***********************************************************/
3091 /***********************************************************/
3093 printf("\nTEST:%d does a logoff invalidate a vuid? see 8.\n\n", testcnt
);
3097 /***********************************************************/
3098 /***********************************************************/
3101 char *test
= "can a connection survive close files, disconnect tids, logoff users?";
3104 printf("\nTEST:%d %s\n\n", testcnt
, test
);
3133 if(!VU_OPEN_AND_READ
) {
3140 printf("TEST FAILED.\n");
3145 /***********************************************************/
3146 /***********************************************************/
3149 char *test
= "clean up.";
3152 printf("\nTEST:%s\n\n", test
);
3154 if(!VU_CROSS_FCLOSE
) {
3171 printf("TEST FAILED.\n");
3178 printf("finished vusertest.\n");
3183 This test checks that
3185 1) the server does not allow an unlink on a file that is open
3187 static BOOL
run_unlinktest(int dummy
)
3189 static struct cli_state cli
;
3190 char *fname
= "\\unlink.tst";
3192 BOOL correct
= True
;
3194 if (!open_connection(&cli
)) {
3198 cli_sockopt(&cli
, sockops
);
3200 printf("starting unlink test\n");
3202 cli_unlink(&cli
, fname
);
3204 cli_setpid(&cli
, 1);
3206 fnum
= cli_open(&cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
3208 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli
));
3212 if (cli_unlink(&cli
, fname
)) {
3213 printf("error: server allowed unlink on an open file\n");
3217 cli_close(&cli
, fnum
);
3218 cli_unlink(&cli
, fname
);
3220 if (!close_connection(&cli
)) {
3224 printf("unlink test finished\n");
3231 test how many open files this server supports on the one socket
3233 static BOOL
run_maxfidtest(int dummy
)
3235 static struct cli_state cli
;
3236 char *template = "\\maxfid.%d.%d";
3240 BOOL correct
= True
;
3245 printf("failed to connect\n");
3249 cli_sockopt(&cli
, sockops
);
3253 slprintf(fname
,sizeof(fname
)-1,template, fnum
,(int)getpid());
3254 if (cli_open(&cli
, fname
,
3255 O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
) ==
3257 printf("open of %s failed (%s)\n",
3258 fname
, cli_errstr(&cli
));
3259 printf("maximum fnum is %d\n", fnum
);
3263 if (fnum
% 100 == 0) printf("%d\r", fnum
);
3265 printf("%d\n", fnum
);
3267 printf("cleaning up\n");
3270 slprintf(fname
,sizeof(fname
)-1,template, fnum
,(int)getpid());
3271 cli_close(&cli
, fnum
);
3272 if (!cli_unlink(&cli
, fname
)) {
3273 printf("unlink of %s failed (%s)\n",
3274 fname
, cli_errstr(&cli
));
3279 printf("maxfid test finished\n");
3280 if (!close_connection(&cli
)) {
3286 /* generate a random buffer */
3287 static void rand_buf(char *buf
, int len
)
3290 *buf
= (char)sys_random();
3295 /* send smb negprot commands, not reading the response */
3296 static BOOL
run_negprot_nowait(int dummy
)
3299 static struct cli_state cli
;
3300 BOOL correct
= True
;
3302 printf("starting negprot nowait test\n");
3304 if (!open_nbt_connection(&cli
)) {
3308 for (i
=0;i
<50000;i
++) {
3309 cli_negprot_send(&cli
);
3312 if (!close_connection(&cli
)) {
3316 printf("finished negprot nowait test\n");
3322 /* send random IPC commands */
3323 static BOOL
run_randomipc(int dummy
)
3325 char *rparam
= NULL
;
3329 int api
, param_len
, i
;
3330 static struct cli_state cli
;
3331 BOOL correct
= True
;
3333 printf("starting random ipc test\n");
3335 if (!open_connection(&cli
)) {
3339 for (i
=0;i
<50000;i
++) {
3340 api
= sys_random() % 500;
3341 param_len
= (sys_random() % 64);
3343 rand_buf(param
, param_len
);
3348 param
, param_len
, 8,
3349 NULL
, 0, BUFFER_SIZE
,
3354 if (!close_connection(&cli
)) {
3358 printf("finished random ipc test\n");
3365 static void browse_callback(const char *sname
, uint32 stype
,
3366 const char *comment
, void *state
)
3368 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
3374 This test checks the browse list code
3377 static BOOL
run_browsetest(int dummy
)
3379 static struct cli_state cli
;
3380 BOOL correct
= True
;
3382 printf("starting browse test\n");
3384 if (!open_connection(&cli
)) {
3388 printf("domain list:\n");
3389 cli_NetServerEnum(&cli
, cli
.server_domain
,
3390 SV_TYPE_DOMAIN_ENUM
,
3391 browse_callback
, NULL
);
3393 printf("machine list:\n");
3394 cli_NetServerEnum(&cli
, cli
.server_domain
,
3396 browse_callback
, NULL
);
3398 if (!close_connection(&cli
)) {
3402 printf("browse test finished\n");
3410 This checks how the getatr calls works
3412 static BOOL
run_attrtest(int dummy
)
3414 static struct cli_state cli
;
3417 char *fname
= "\\attrib.tst";
3418 BOOL correct
= True
;
3420 printf("starting attrib test\n");
3422 if (!open_connection(&cli
)) {
3426 cli_unlink(&cli
, fname
);
3427 fnum
= cli_open(&cli
, fname
,
3428 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
3429 cli_close(&cli
, fnum
);
3430 if (!cli_getatr(&cli
, fname
, NULL
, NULL
, &t
)) {
3431 printf("getatr failed (%s)\n", cli_errstr(&cli
));
3435 if (abs(t
- time(NULL
)) > 2) {
3436 printf("ERROR: SMBgetatr bug. time is %s",
3442 t2
= t
-60*60*24; /* 1 day ago */
3444 if (!cli_setatr(&cli
, fname
, 0, t2
)) {
3445 printf("setatr failed (%s)\n", cli_errstr(&cli
));
3449 if (!cli_getatr(&cli
, fname
, NULL
, NULL
, &t
)) {
3450 printf("getatr failed (%s)\n", cli_errstr(&cli
));
3455 printf("ERROR: getatr/setatr bug. times are\n%s",
3457 printf("%s", ctime(&t2
));
3461 cli_unlink(&cli
, fname
);
3463 if (!close_connection(&cli
)) {
3467 printf("attrib test finished\n");
3474 This checks a couple of trans2 calls
3476 static BOOL
run_trans2test(int dummy
)
3478 static struct cli_state cli
;
3481 time_t c_time
, a_time
, m_time
, w_time
, m_time2
;
3482 char *fname
= "\\trans2.tst";
3483 char *dname
= "\\trans2";
3484 char *fname2
= "\\trans2\\trans2.tst";
3485 BOOL correct
= True
;
3487 printf("starting trans2 test\n");
3489 if (!open_connection(&cli
)) {
3493 cli_unlink(&cli
, fname
);
3494 fnum
= cli_open(&cli
, fname
,
3495 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
3496 if (!cli_qfileinfo(&cli
, fnum
, NULL
, &size
, &c_time
, &a_time
, &m_time
,
3498 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli
));
3501 cli_close(&cli
, fnum
);
3505 cli_unlink(&cli
, fname
);
3506 fnum
= cli_open(&cli
, fname
,
3507 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
3509 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli
));
3512 cli_close(&cli
, fnum
);
3514 if (!cli_qpathinfo(&cli
, fname
, &c_time
, &a_time
, &m_time
, &size
, NULL
)) {
3515 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli
));
3518 if (c_time
!= m_time
) {
3519 printf("create time=%s", ctime(&c_time
));
3520 printf("modify time=%s", ctime(&m_time
));
3521 printf("This system appears to have sticky create times\n");
3524 if (a_time
% (60*60) == 0) {
3525 printf("access time=%s", ctime(&a_time
));
3526 printf("This system appears to set a midnight access time\n");
3530 if (abs(m_time
- time(NULL
)) > 60*60*24*7) {
3531 printf("ERROR: totally incorrect times - maybe word reversed?\n");
3537 cli_unlink(&cli
, fname
);
3538 fnum
= cli_open(&cli
, fname
,
3539 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
3540 cli_close(&cli
, fnum
);
3541 if (!cli_qpathinfo2(&cli
, fname
, &c_time
, &a_time
, &m_time
,
3542 &w_time
, &size
, NULL
, NULL
)) {
3543 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli
));
3546 if (w_time
< 60*60*24*2) {
3547 printf("write time=%s", ctime(&w_time
));
3548 printf("This system appears to set a initial 0 write time\n");
3553 cli_unlink(&cli
, fname
);
3556 /* check if the server updates the directory modification time
3557 when creating a new file */
3558 if (!cli_mkdir(&cli
, dname
)) {
3559 printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli
));
3563 if (!cli_qpathinfo2(&cli
, "\\trans2\\", &c_time
, &a_time
, &m_time
,
3564 &w_time
, &size
, NULL
, NULL
)) {
3565 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli
));
3569 fnum
= cli_open(&cli
, fname2
,
3570 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
3571 cli_write(&cli
, fnum
, 0, (char *)&fnum
, 0, sizeof(fnum
));
3572 cli_close(&cli
, fnum
);
3573 if (!cli_qpathinfo2(&cli
, "\\trans2\\", &c_time
, &a_time
, &m_time2
,
3574 &w_time
, &size
, NULL
, NULL
)) {
3575 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli
));
3578 if (m_time2
== m_time
) {
3579 printf("This system does not update directory modification times\n");
3583 cli_unlink(&cli
, fname2
);
3584 cli_rmdir(&cli
, dname
);
3586 if (!close_connection(&cli
)) {
3590 printf("trans2 test finished\n");
3596 This checks new W2K calls.
3599 static BOOL
new_trans(struct cli_state
*pcli
, int fnum
, int level
)
3602 BOOL correct
= True
;
3604 memset(buf
, 0xff, sizeof(buf
));
3606 if (!cli_qfileinfo_test(pcli
, fnum
, level
, buf
)) {
3607 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
, cli_errstr(pcli
));
3610 printf("qfileinfo: level %d\n", level
);
3611 dump_data(0, buf
, 256);
3617 /****************************************************************************
3618 Set or clear the delete on close flag.
3619 ****************************************************************************/
3621 int cli_setfileinfo_test(struct cli_state
*cli
, int fnum
, int level
, char *data
, int data_len
)
3624 uint16 setup
= TRANSACT2_SETFILEINFO
;
3626 char *rparam
=NULL
, *rdata
=NULL
;
3628 memset(param
, 0, param_len
);
3629 SSVAL(param
,0,fnum
);
3630 SSVAL(param
,2,level
);
3632 if (!cli_send_trans(cli
, SMBtrans2
,
3634 -1, 0, /* fid, flags */
3635 &setup
, 1, 0, /* setup, length, max */
3636 param
, param_len
, 2, /* param, length, max */
3637 data
, data_len
, cli
->max_xmit
/* data, length, max */
3642 if (!cli_receive_trans(cli
, SMBtrans2
,
3643 &rparam
, ¶m_len
,
3644 &rdata
, &data_len
)) {
3654 static BOOL
run_w2ktest(int dummy
)
3656 static struct cli_state cli
;
3658 char *fname
= "\\w2ktest\\w2k.tst";
3659 char *fname1
= "\\w2ktest\\w2k.dir";
3662 BOOL correct
= True
;
3664 printf("starting w2k test\n");
3666 if (!open_connection(&cli
)) {
3670 fnum
= cli_open(&cli
, fname
,
3671 O_RDWR
| O_CREAT
, DENY_NONE
);
3673 for (level
= 1004; level
< 1040; level
++) {
3674 new_trans(&cli
, fnum
, level
);
3677 cli_close(&cli
, fnum
);
3678 cli_unlink(&cli
, fname
);
3680 /* Check the strange 1013 setinfo call. */
3681 cli_mkdir(&cli
, fname1
);
3682 fnum
= cli_nt_create_full( &cli
, fname1
, 0x60080, 0, 7,
3686 if (!cli_setfileinfo_test( &cli
, fnum
, 1013, &data
, 1)) {
3687 printf("setfileinfo test 1 failed with %s\n", cli_errstr(&cli
));
3690 if (!cli_setfileinfo_test( &cli
, fnum
, 1013, &data
, 1)) {
3691 printf("setfileinfo test 2 failed with %s\n", cli_errstr(&cli
));
3694 cli_close(&cli
, fnum
);
3695 cli_rmdir(&cli
, fname1
);
3697 fnum
= cli_open(&cli
, fname
, O_RDWR
| O_CREAT
, DENY_NONE
);
3699 cli_write(&cli
, fnum
, 0, (char *)&data
, 0, sizeof(data
));
3700 cli_close(&cli
, fnum
);
3703 fnum
= cli_open(&cli
, fname
, O_RDWR
, DENY_NONE
);
3704 if (cli_read(&cli
, fnum
, &data
, 0, 1) != 1) {
3705 printf("x test 2 failed with %s\n", cli_errstr(&cli
));
3707 cli_close(&cli
, fnum
);
3708 cli_unlink(&cli
, fname
);
3710 if (!close_connection(&cli
)) {
3714 printf("w2k test finished\n");
3721 this is a harness for some oplock tests
3723 static BOOL
run_oplock1(int dummy
)
3725 static struct cli_state cli1
;
3726 char *fname
= "\\lockt1.lck";
3728 BOOL correct
= True
;
3730 printf("starting oplock test 1\n");
3732 if (!open_connection(&cli1
)) {
3736 cli_unlink(&cli1
, fname
);
3738 cli_sockopt(&cli1
, sockops
);
3740 cli1
.use_oplocks
= True
;
3742 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
3744 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
3748 cli1
.use_oplocks
= False
;
3750 cli_unlink(&cli1
, fname
);
3751 cli_unlink(&cli1
, fname
);
3753 if (!cli_close(&cli1
, fnum1
)) {
3754 printf("close2 failed (%s)\n", cli_errstr(&cli1
));
3758 if (!cli_unlink(&cli1
, fname
)) {
3759 printf("unlink failed (%s)\n", cli_errstr(&cli1
));
3763 if (!close_connection(&cli1
)) {
3767 printf("finished oplock test 1\n");
3772 static BOOL
run_oplock2(int dummy
)
3774 static struct cli_state cli1
, cli2
;
3775 char *fname
= "\\lockt2.lck";
3777 int saved_use_oplocks
= use_oplocks
;
3779 BOOL correct
= True
;
3780 volatile BOOL
*shared_correct
;
3782 shared_correct
= (volatile BOOL
*)shm_setup(sizeof(BOOL
));
3783 *shared_correct
= True
;
3785 use_level_II_oplocks
= True
;
3788 printf("starting oplock test 2\n");
3790 if (!open_connection(&cli1
)) {
3791 use_level_II_oplocks
= False
;
3792 use_oplocks
= saved_use_oplocks
;
3796 cli1
.use_oplocks
= True
;
3797 cli1
.use_level_II_oplocks
= True
;
3799 if (!open_connection(&cli2
)) {
3800 use_level_II_oplocks
= False
;
3801 use_oplocks
= saved_use_oplocks
;
3805 cli2
.use_oplocks
= True
;
3806 cli2
.use_level_II_oplocks
= True
;
3808 cli_unlink(&cli1
, fname
);
3810 cli_sockopt(&cli1
, sockops
);
3811 cli_sockopt(&cli2
, sockops
);
3813 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
3815 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
3819 /* Don't need the globals any more. */
3820 use_level_II_oplocks
= False
;
3821 use_oplocks
= saved_use_oplocks
;
3825 fnum2
= cli_open(&cli2
, fname
, O_RDWR
, DENY_NONE
);
3827 printf("second open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
3828 *shared_correct
= False
;
3834 if (!cli_close(&cli2
, fnum2
)) {
3835 printf("close2 failed (%s)\n", cli_errstr(&cli1
));
3836 *shared_correct
= False
;
3844 /* Ensure cli1 processes the break. */
3846 if (cli_read(&cli1
, fnum1
, buf
, 0, 4) != 4) {
3847 printf("read on fnum1 failed (%s)\n", cli_errstr(&cli1
));
3851 /* Should now be at level II. */
3852 /* Test if sending a write locks causes a break to none. */
3854 if (!cli_lock(&cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) {
3855 printf("lock failed (%s)\n", cli_errstr(&cli1
));
3859 cli_unlock(&cli1
, fnum1
, 0, 4);
3863 if (!cli_lock(&cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
3864 printf("lock failed (%s)\n", cli_errstr(&cli1
));
3868 cli_unlock(&cli1
, fnum1
, 0, 4);
3872 cli_read(&cli1
, fnum1
, buf
, 0, 4);
3875 if (cli_write(&cli1
, fnum1
, 0, buf
, 0, 4) != 4) {
3876 printf("write on fnum1 failed (%s)\n", cli_errstr(&cli1
));
3881 if (!cli_close(&cli1
, fnum1
)) {
3882 printf("close1 failed (%s)\n", cli_errstr(&cli1
));
3888 if (!cli_unlink(&cli1
, fname
)) {
3889 printf("unlink failed (%s)\n", cli_errstr(&cli1
));
3893 if (!close_connection(&cli1
)) {
3897 if (!*shared_correct
) {
3901 printf("finished oplock test 2\n");
3908 Test delete on close semantics.
3910 static BOOL
run_deletetest(int dummy
)
3912 static struct cli_state cli1
;
3913 static struct cli_state cli2
;
3914 char *fname
= "\\delete.file";
3916 BOOL correct
= True
;
3918 printf("starting delete test\n");
3920 if (!open_connection(&cli1
)) {
3924 cli_sockopt(&cli1
, sockops
);
3926 /* Test 1 - this should *NOT* delete the file on close. */
3928 cli_setatr(&cli1
, fname
, 0, 0);
3929 cli_unlink(&cli1
, fname
);
3931 fnum1
= cli_nt_create_full(&cli1
, fname
, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3932 FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, DELETE_ON_CLOSE_FLAG
);
3935 printf("[1] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
3939 if (!cli_close(&cli1
, fnum1
)) {
3940 printf("[1] close failed (%s)\n", cli_errstr(&cli1
));
3944 fnum1
= cli_open(&cli1
, fname
, O_RDWR
, DENY_NONE
);
3946 printf("[1] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
3950 if (!cli_close(&cli1
, fnum1
)) {
3951 printf("[1] close failed (%s)\n", cli_errstr(&cli1
));
3955 printf("first delete on close test succeeded.\n");
3957 /* Test 2 - this should delete the file on close. */
3959 cli_setatr(&cli1
, fname
, 0, 0);
3960 cli_unlink(&cli1
, fname
);
3962 fnum1
= cli_nt_create_full(&cli1
, fname
, GENERIC_ALL_ACCESS
,
3963 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0);
3966 printf("[2] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
3970 if (!cli_nt_delete_on_close(&cli1
, fnum1
, True
)) {
3971 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1
));
3975 if (!cli_close(&cli1
, fnum1
)) {
3976 printf("[2] close failed (%s)\n", cli_errstr(&cli1
));
3980 fnum1
= cli_open(&cli1
, fname
, O_RDONLY
, DENY_NONE
);
3982 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
3983 if (!cli_close(&cli1
, fnum1
)) {
3984 printf("[2] close failed (%s)\n", cli_errstr(&cli1
));
3987 cli_unlink(&cli1
, fname
);
3989 printf("second delete on close test succeeded.\n");
3993 cli_setatr(&cli1
, fname
, 0, 0);
3994 cli_unlink(&cli1
, fname
);
3996 fnum1
= cli_nt_create_full(&cli1
, fname
, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3997 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0);
4000 printf("[3] open - 1 of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4004 /* This should fail with a sharing violation - open for delete is only compatible
4005 with SHARE_DELETE. */
4007 fnum2
= cli_nt_create_full(&cli1
, fname
, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4008 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, 0);
4011 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
4015 /* This should succeed. */
4017 fnum2
= cli_nt_create_full(&cli1
, fname
, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4018 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0);
4021 printf("[3] open - 2 of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4025 if (!cli_nt_delete_on_close(&cli1
, fnum1
, True
)) {
4026 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1
));
4030 if (!cli_close(&cli1
, fnum1
)) {
4031 printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1
));
4035 if (!cli_close(&cli1
, fnum2
)) {
4036 printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1
));
4040 /* This should fail - file should no longer be there. */
4042 fnum1
= cli_open(&cli1
, fname
, O_RDONLY
, DENY_NONE
);
4044 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
4045 if (!cli_close(&cli1
, fnum1
)) {
4046 printf("[3] close failed (%s)\n", cli_errstr(&cli1
));
4048 cli_unlink(&cli1
, fname
);
4051 printf("third delete on close test succeeded.\n");
4054 cli_setatr(&cli1
, fname
, 0, 0);
4055 cli_unlink(&cli1
, fname
);
4057 fnum1
= cli_nt_create_full(&cli1
, fname
, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4058 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0);
4061 printf("[4] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4065 /* This should succeed. */
4066 fnum2
= cli_nt_create_full(&cli1
, fname
, GENERIC_READ_ACCESS
,
4067 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0);
4069 printf("[4] open - 2 of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4073 if (!cli_close(&cli1
, fnum2
)) {
4074 printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1
));
4078 if (!cli_nt_delete_on_close(&cli1
, fnum1
, True
)) {
4079 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1
));
4083 /* This should fail - no more opens once delete on close set. */
4084 fnum2
= cli_nt_create_full(&cli1
, fname
, GENERIC_READ_ACCESS
,
4085 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0);
4087 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
4090 printf("fourth delete on close test succeeded.\n");
4092 if (!cli_close(&cli1
, fnum1
)) {
4093 printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1
));
4098 cli_setatr(&cli1
, fname
, 0, 0);
4099 cli_unlink(&cli1
, fname
);
4101 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
4103 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4107 /* This should fail - only allowed on NT opens with DELETE access. */
4109 if (cli_nt_delete_on_close(&cli1
, fnum1
, True
)) {
4110 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4114 if (!cli_close(&cli1
, fnum1
)) {
4115 printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1
));
4119 printf("fifth delete on close test succeeded.\n");
4122 cli_setatr(&cli1
, fname
, 0, 0);
4123 cli_unlink(&cli1
, fname
);
4125 fnum1
= cli_nt_create_full(&cli1
, fname
, FILE_READ_DATA
|FILE_WRITE_DATA
,
4126 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4127 FILE_OVERWRITE_IF
, 0);
4130 printf("[6] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4134 /* This should fail - only allowed on NT opens with DELETE access. */
4136 if (cli_nt_delete_on_close(&cli1
, fnum1
, True
)) {
4137 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4141 if (!cli_close(&cli1
, fnum1
)) {
4142 printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1
));
4146 printf("sixth delete on close test succeeded.\n");
4149 cli_setatr(&cli1
, fname
, 0, 0);
4150 cli_unlink(&cli1
, fname
);
4152 fnum1
= cli_nt_create_full(&cli1
, fname
, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4153 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
, 0);
4156 printf("[7] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4160 if (!cli_nt_delete_on_close(&cli1
, fnum1
, True
)) {
4161 printf("[7] setting delete_on_close on file failed !\n");
4165 if (!cli_nt_delete_on_close(&cli1
, fnum1
, False
)) {
4166 printf("[7] unsetting delete_on_close on file failed !\n");
4170 if (!cli_close(&cli1
, fnum1
)) {
4171 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1
));
4175 /* This next open should succeed - we reset the flag. */
4177 fnum1
= cli_open(&cli1
, fname
, O_RDONLY
, DENY_NONE
);
4179 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4183 if (!cli_close(&cli1
, fnum1
)) {
4184 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1
));
4188 printf("seventh delete on close test succeeded.\n");
4191 cli_setatr(&cli1
, fname
, 0, 0);
4192 cli_unlink(&cli1
, fname
);
4194 if (!open_connection(&cli2
)) {
4195 printf("[8] failed to open second connection.\n");
4199 cli_sockopt(&cli1
, sockops
);
4201 fnum1
= cli_nt_create_full(&cli1
, fname
, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4202 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, 0);
4205 printf("[8] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4209 fnum2
= cli_nt_create_full(&cli2
, fname
, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4210 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0);
4213 printf("[8] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4217 if (!cli_nt_delete_on_close(&cli1
, fnum1
, True
)) {
4218 printf("[8] setting delete_on_close on file failed !\n");
4222 if (!cli_close(&cli1
, fnum1
)) {
4223 printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1
));
4227 if (!cli_close(&cli2
, fnum2
)) {
4228 printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2
));
4232 /* This should fail.. */
4233 fnum1
= cli_open(&cli1
, fname
, O_RDONLY
, DENY_NONE
);
4235 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
4236 if (!cli_close(&cli1
, fnum1
)) {
4237 printf("[8] close failed (%s)\n", cli_errstr(&cli1
));
4239 cli_unlink(&cli1
, fname
);
4242 printf("eighth delete on close test succeeded.\n");
4244 printf("finished delete test\n");
4246 cli_setatr(&cli1
, fname
, 0, 0);
4247 cli_unlink(&cli1
, fname
);
4249 if (!close_connection(&cli1
)) {
4252 if (!close_connection(&cli2
)) {
4259 Test open mode returns on read-only files.
4261 static BOOL
run_opentest(int dummy
)
4263 static struct cli_state cli1
;
4264 char *fname
= "\\readonly.file";
4270 BOOL correct
= True
;
4272 printf("starting open test\n");
4274 if (!open_connection(&cli1
)) {
4278 cli_setatr(&cli1
, fname
, 0, 0);
4279 cli_unlink(&cli1
, fname
);
4281 cli_sockopt(&cli1
, sockops
);
4283 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
4285 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4289 if (!cli_close(&cli1
, fnum1
)) {
4290 printf("close2 failed (%s)\n", cli_errstr(&cli1
));
4294 if (!cli_setatr(&cli1
, fname
, aRONLY
, 0)) {
4295 printf("cli_setatr failed (%s)\n", cli_errstr(&cli1
));
4299 fnum1
= cli_open(&cli1
, fname
, O_RDONLY
, DENY_WRITE
);
4301 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4305 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4306 fnum2
= cli_open(&cli1
, fname
, O_RDWR
, DENY_ALL
);
4308 cli_dos_error( &cli1
, &eclass
, &errnum
);
4310 if (eclass
!= ERRDOS
|| errnum
!= ERRnoaccess
) {
4311 printf("wrong error code (%x,%x) = %s\n", (unsigned int)eclass
,
4312 (unsigned int)errnum
, cli_errstr(&cli1
) );
4315 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4319 printf("finished open test 1\n");
4321 cli_close(&cli1
, fnum1
);
4323 /* Now try not readonly and ensure ERRbadshare is returned. */
4325 cli_setatr(&cli1
, fname
, 0, 0);
4327 fnum1
= cli_open(&cli1
, fname
, O_RDONLY
, DENY_WRITE
);
4329 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4333 /* This will fail - but the error should be ERRshare. */
4334 fnum2
= cli_open(&cli1
, fname
, O_RDWR
, DENY_ALL
);
4336 cli_dos_error( &cli1
, &eclass
, &errnum
);
4338 if (eclass
!= ERRDOS
|| errnum
!= ERRbadshare
) {
4339 printf("wrong error code (%x,%x) = %s\n", (unsigned int)eclass
,
4340 (unsigned int)errnum
, cli_errstr(&cli1
) );
4343 printf("correct error code ERRDOS/ERRbadshare returned\n");
4346 if (!cli_close(&cli1
, fnum1
)) {
4347 printf("close2 failed (%s)\n", cli_errstr(&cli1
));
4351 cli_unlink(&cli1
, fname
);
4353 printf("finished open test 2\n");
4355 /* Test truncate open disposition on file opened for read. */
4357 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
4359 printf("(3) open (1) of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4363 /* write 20 bytes. */
4365 memset(buf
, '\0', 20);
4367 if (cli_write(&cli1
, fnum1
, 0, buf
, 0, 20) != 20) {
4368 printf("write failed (%s)\n", cli_errstr(&cli1
));
4372 if (!cli_close(&cli1
, fnum1
)) {
4373 printf("(3) close1 failed (%s)\n", cli_errstr(&cli1
));
4377 /* Ensure size == 20. */
4378 if (!cli_getatr(&cli1
, fname
, NULL
, &fsize
, NULL
)) {
4379 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1
));
4384 printf("(3) file size != 20\n");
4388 /* Now test if we can truncate a file opened for readonly. */
4390 fnum1
= cli_open(&cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
);
4392 printf("(3) open (2) of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4396 if (!cli_close(&cli1
, fnum1
)) {
4397 printf("close2 failed (%s)\n", cli_errstr(&cli1
));
4401 /* Ensure size == 0. */
4402 if (!cli_getatr(&cli1
, fname
, NULL
, &fsize
, NULL
)) {
4403 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1
));
4408 printf("(3) file size != 0\n");
4411 printf("finished open test 3\n");
4413 cli_unlink(&cli1
, fname
);
4416 printf("testing ctemp\n");
4419 fnum1
= cli_ctemp(&cli1
, "\\", &tmp_path
);
4421 printf("ctemp failed (%s)\n", cli_errstr(&cli1
));
4424 printf("ctemp gave path %s\n", tmp_path
);
4425 cli_close(&cli1
, fnum1
);
4426 cli_unlink(&cli1
, tmp_path
);
4429 if (!close_connection(&cli1
)) {
4436 static void list_fn(file_info
*finfo
, const char *name
, void *state
)
4442 test directory listing speed
4444 static BOOL
run_dirtest(int dummy
)
4447 static struct cli_state cli
;
4450 BOOL correct
= True
;
4452 printf("starting directory test\n");
4454 if (!open_connection(&cli
)) {
4458 cli_sockopt(&cli
, sockops
);
4461 for (i
=0;i
<numops
;i
++) {
4463 slprintf(fname
, sizeof(fname
), "%x", (int)random());
4464 fnum
= cli_open(&cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
4466 fprintf(stderr
,"Failed to open %s\n", fname
);
4469 cli_close(&cli
, fnum
);
4474 printf("Matched %d\n", cli_list(&cli
, "a*.*", 0, list_fn
, NULL
));
4475 printf("Matched %d\n", cli_list(&cli
, "b*.*", 0, list_fn
, NULL
));
4476 printf("Matched %d\n", cli_list(&cli
, "xyzabc", 0, list_fn
, NULL
));
4478 printf("dirtest core %g seconds\n", end_timer() - t1
);
4481 for (i
=0;i
<numops
;i
++) {
4483 slprintf(fname
, sizeof(fname
), "%x", (int)random());
4484 cli_unlink(&cli
, fname
);
4487 if (!close_connection(&cli
)) {
4491 printf("finished dirtest\n");
4496 static double create_procs(BOOL (*fn
)(int), BOOL
*result
)
4499 volatile pid_t
*child_status
;
4500 volatile BOOL
*child_status_out
;
4506 child_status
= (volatile pid_t
*)shm_setup(sizeof(pid_t
)*nprocs
);
4507 if (!child_status
) {
4508 printf("Failed to setup shared memory\n");
4512 child_status_out
= (volatile BOOL
*)shm_setup(sizeof(BOOL
)*nprocs
);
4513 if (!child_status_out
) {
4514 printf("Failed to setup result status shared memory\n");
4518 memset(child_status
, 0, sizeof(pid_t
)*nprocs
);
4519 memset(child_status_out
, True
, sizeof(BOOL
)*nprocs
);
4523 for (i
=0;i
<nprocs
;i
++) {
4526 pid_t mypid
= getpid();
4527 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
4529 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
4532 memset(¤t_cli
, 0, sizeof(current_cli
));
4533 if (open_connection(¤t_cli
)) break;
4535 printf("pid %d failed to start\n", (int)getpid());
4541 child_status
[i
] = getpid();
4543 while (child_status
[i
] && end_timer() < 5) msleep(2);
4545 child_status_out
[i
] = fn(i
);
4552 for (i
=0;i
<nprocs
;i
++) {
4553 if (child_status
[i
]) synccount
++;
4555 if (synccount
== nprocs
) break;
4557 } while (end_timer() < 30);
4559 if (synccount
!= nprocs
) {
4560 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs
, synccount
);
4565 /* start the client load */
4568 for (i
=0;i
<nprocs
;i
++) {
4569 child_status
[i
] = 0;
4572 printf("%d clients started\n", nprocs
);
4574 for (i
=0;i
<nprocs
;i
++) {
4575 waitpid(0, &status
, 0);
4581 for (i
=0;i
<nprocs
;i
++) {
4582 if (!child_status_out
[i
]) {
4590 #define FLAG_MULTIPROC (1<<0)
4591 #define FLAG_MULTIUSER (1<<1)
4592 #define FLAG_MULTISHARE (1<<2)
4593 #define FLAG_PROBE (1<<3)
4600 {"FDPASS", run_fdpasstest
, 0},
4601 {"LOCK1", run_locktest1
, 0},
4602 {"LOCK2", run_locktest2
, 0},
4603 {"LOCK3", run_locktest3
, 0},
4604 {"LOCK4", run_locktest4
, 0},
4605 {"LOCK5", run_locktest5
, 0},
4606 {"UNLINK", run_unlinktest
, 0},
4607 {"BROWSE", run_browsetest
, 0},
4608 {"ATTR", run_attrtest
, 0},
4609 {"TRANS2", run_trans2test
, 0},
4610 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
4611 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
4612 {"RANDOMIPC", run_randomipc
, 0},
4613 {"NEGNOWAIT", run_negprot_nowait
, 0},
4614 {"NBW95", run_nbw95
, 0},
4615 {"NBWNT", run_nbwnt
, 0},
4616 {"OPLOCK1", run_oplock1
, 0},
4617 {"OPLOCK2", run_oplock2
, 0},
4618 {"DIR", run_dirtest
, 0},
4619 {"DENY1", run_denytest1
, 0},
4620 {"DENY2", run_denytest2
, 0},
4621 {"TCON", run_tcon_test
, 0},
4622 {"RW1", run_readwritetest
, 0},
4623 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
4624 {"RW3", run_readwritelarge
, 0},
4625 {"OPEN", run_opentest
, 0},
4626 {"DELETE", run_deletetest
, 0},
4627 {"W2K", run_w2ktest
, 0},
4628 {"VU", run_vusertest
, FLAG_MULTIUSER
| FLAG_MULTISHARE
},
4633 /****************************************************************************
4634 run a specified test or "ALL"
4635 ****************************************************************************/
4637 static BOOL
get_test_flags(char *name
, BOOL
*flags
) {
4641 BOOL all
= strequal(name
,"ALL") == 0;
4643 for (i
=0;torture_ops
[i
].name
;i
++) {
4645 if (all
|| strequal(name
, torture_ops
[i
].name
)) {
4647 *flags
|= torture_ops
[i
].flags
;
4659 static BOOL
run_test(char *name
)
4665 if (strequal(name
,"ALL")) {
4666 for (i
=0;torture_ops
[i
].name
;i
++) {
4667 run_test(torture_ops
[i
].name
);
4671 for (i
=0;torture_ops
[i
].name
;i
++) {
4672 snprintf(randomfname
, sizeof(randomfname
), "\\XX%x",
4673 (unsigned)random());
4675 if (strequal(name
, torture_ops
[i
].name
)) {
4676 printf("Running %s\n", name
);
4677 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
4678 t
= create_procs(torture_ops
[i
].fn
, &result
);
4681 printf("TEST %s FAILED!\n", name
);
4686 if (!torture_ops
[i
].fn(0)) {
4688 printf("TEST %s FAILED!\n", name
);
4692 printf("%s took %g secs\n\n", name
, t
);
4699 static void usage(void)
4703 printf("Usage: smbtorture //server/share[,share...] <options> TEST1 TEST2 ...\n");
4705 printf("\t-d debuglevel\n");
4706 printf("\t-U user%%pass\n");
4707 printf("\t-u user%%pass[,user%%pass...]\n");
4708 printf("\t-N numprocs\n");
4709 printf("\t-n my_netbios_name\n");
4710 printf("\t-W workgroup\n");
4711 printf("\t-o num_operations\n");
4712 printf("\t-O socket_options\n");
4713 printf("\t-m maximum protocol\n");
4714 printf("\t-L use oplocks\n");
4717 printf("tests are:");
4718 for (i
=0;torture_ops
[i
].name
;i
++) {
4719 printf(" %s", torture_ops
[i
].name
);
4723 printf("default test is ALL\n");
4728 static BOOL
split_password_from_username(char *username
, char *password
) {
4730 char * pp
= strchr(username
,'%');
4733 pstrcpy(password
, pp
+1);
4740 static BOOL
extract_users(char *user_list
) {
4742 const char *separators
= ",";
4744 char *p
= strtok(user_list
, separators
);
4746 while(p
&& nusers
< MAX_USERS
) {
4748 vusers
[nusers
].username
[0] = '\0';
4749 vusers
[nusers
].password
[0] = '\0';
4750 vusers
[nusers
].gotpass
= False
;
4752 pstrcpy(vusers
[nusers
].username
, p
);
4754 vusers
[nusers
].gotpass
= split_password_from_username(vusers
[nusers
].username
, vusers
[nusers
].password
);
4758 p
= strtok(NULL
, separators
);
4764 static BOOL
extract_shares(char *share_list
) {
4766 const char *separators
= ",";
4768 char *p
= strtok(share_list
, separators
);
4770 while(p
&& nshares
< MAX_TIDS
) {
4772 pstrcpy(shares
[nshares
], p
);
4776 p
= strtok(NULL
, separators
);
4782 /****************************************************************************
4784 ****************************************************************************/
4786 int main(int argc
,char *argv
[])
4791 BOOL
*gotpass
= &vusers
[0].gotpass
;
4792 extern char *optarg
;
4795 static pstring servicesf
= CONFIGFILE
;
4796 BOOL correct
= True
;
4802 #ifdef HAVE_SETBUFFER
4803 setbuffer(stdout
, NULL
, 0);
4805 charset_initialise();
4807 codepage_initialise(lp_client_code_page());
4809 codepage_initialise(lp_client_code_page());
4811 lp_load(servicesf
,True
,False
,False
);
4818 for(p
= argv
[1]; *p
; p
++)
4822 if (strncmp(argv
[1], "//", 2)) {
4826 fstrcpy(host
, &argv
[1][2]);
4827 p
= strchr(&host
[2],'/');
4833 fstrcpy(share_list
, p
+1);
4837 if (*username
== 0 && getenv("LOGNAME")) {
4839 pstrcpy(username
,getenv("LOGNAME"));
4845 fstrcpy(workgroup
, lp_workgroup());
4847 while ((opt
= getopt(argc
, argv
, "hW:U:u:n:N:O:o:m:Ld:")) != EOF
) {
4850 fstrcpy(workgroup
,optarg
);
4853 max_protocol
= interpret_protocol(optarg
, max_protocol
);
4856 nprocs
= atoi(optarg
);
4859 numops
= atoi(optarg
);
4862 DEBUGLEVEL
= atoi(optarg
);
4871 fstrcpy(myname
, optarg
);
4874 pstrcpy(username
,optarg
);
4875 *gotpass
= split_password_from_username(username
, password
);
4878 pstrcpy(user_list
, optarg
);
4879 if(!extract_users(user_list
)) {
4884 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
4890 get_test_flags("ALL", &test_flags
);
4892 for (i
=1;i
<argc
;i
++) {
4894 get_test_flags(argv
[i
], &test_flags
);
4900 snprintf(s
, sizeof(s
), "Password for user %s:", username
);
4903 pstrcpy(password
, p
);
4908 extract_shares(share_list
);
4910 if(test_flags
& FLAG_MULTIUSER
) {
4914 /*generate another user from the one that is already specified*/
4916 vusers
[nusers
] = vusers
[nusers
-1];
4921 for(i
= 1; i
< nusers
; i
++) {
4925 if(vusers
[i
].gotpass
) {
4930 snprintf(s
, sizeof(s
), "Password for user %s:", vusers
[i
].username
);
4935 pstrcpy(vusers
[i
].password
, p
);
4936 vusers
[i
].gotpass
= True
;
4941 user_list
[0] = '\0';
4943 for(i
= 0; i
< nusers
; i
++) {
4945 if(!vusers
[i
].gotpass
) {
4952 fstrcat(user_list
, ", ");
4955 fstrcat(user_list
, vusers
[i
].username
);
4958 printf("host=%s shares=%s users=%s myname=%s\n", host
, share_list
, user_list
, myname
);
4961 correct
= run_test("ALL");
4963 for (i
=1;i
<argc
;i
++) {
4964 if (!run_test(argv
[i
])) {