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
;
138 extern struct in_addr ipzero
;
142 make_nmb_name(&calling
, myname
, 0x0);
143 make_nmb_name(&called
, host
, 0x20);
147 if (!cli_initialise(c
) || !cli_connect(c
, host
, &ip
)) {
148 printf("Failed to connect with %s\n", host
);
152 c
->timeout
= 120000; /* set a really long timeout (2 minutes) */
153 if (use_oplocks
) c
->use_oplocks
= True
;
154 if (use_level_II_oplocks
) c
->use_level_II_oplocks
= True
;
156 if (!cli_session_request(c
, &calling
, &called
)) {
157 printf("%s rejected the session\n",host
);
165 static BOOL
open_connection(struct cli_state
*c
)
169 if (!open_nbt_connection(c
)) {
173 if (!cli_negprot(c
)) {
174 printf("%s rejected the negprot (%s)\n",host
, cli_errstr(c
));
179 if (!cli_session_setup(c
, username
,
180 password
, strlen(password
),
181 password
, strlen(password
),
183 printf("%s rejected the sessionsetup (%s)\n", host
, cli_errstr(c
));
188 if (!cli_send_tconX(c
, share
, "?????",
189 password
, strlen(password
)+1)) {
190 printf("%s refused tree connect (%s)\n", host
, cli_errstr(c
));
198 static BOOL
close_connection(struct cli_state
*c
)
202 printf("tdis failed (%s)\n", cli_errstr(c
));
212 /* check if the server produced the expected error code */
213 static BOOL
check_error(struct cli_state
*c
,
214 uint8 eclass
, uint32 ecode
, uint32 nterr
)
219 (void)cli_dos_error(c
, &class, &num
);
220 if ((eclass
!= class || ecode
!= num
) &&
221 num
!= (nterr
&0xFFFFFF)) {
222 printf("unexpected error code class=%d code=%d\n",
223 (int)class, (int)num
);
224 printf(" expected %d/%d %d\n",
225 (int)eclass
, (int)ecode
, (int)nterr
);
232 static BOOL
wait_lock(struct cli_state
*c
, int fnum
, uint32 offset
, uint32 len
)
234 while (!cli_lock(c
, fnum
, offset
, len
, -1, WRITE_LOCK
)) {
235 if (!check_error(c
, ERRDOS
, ERRlock
, 0)) return False
;
241 static BOOL
rw_torture(struct cli_state
*c
)
243 char *lockfname
= "\\torture.lck";
247 pid_t pid2
, pid
= getpid();
252 fnum2
= cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
255 fnum2
= cli_open(c
, lockfname
, O_RDWR
, DENY_NONE
);
257 printf("open of %s failed (%s)\n", lockfname
, cli_errstr(c
));
262 for (i
=0;i
<numops
;i
++) {
263 unsigned n
= (unsigned)sys_random()%10;
265 printf("%d\r", i
); fflush(stdout
);
267 slprintf(fname
, sizeof(fstring
) - 1, "\\torture.%u", n
);
269 if (!wait_lock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
273 fnum
= cli_open(c
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_ALL
);
275 printf("open failed (%s)\n", cli_errstr(c
));
280 if (cli_write(c
, fnum
, 0, (char *)&pid
, 0, sizeof(pid
)) != sizeof(pid
)) {
281 printf("write failed (%s)\n", cli_errstr(c
));
286 if (cli_write(c
, fnum
, 0, (char *)buf
,
287 sizeof(pid
)+(j
*sizeof(buf
)),
288 sizeof(buf
)) != sizeof(buf
)) {
289 printf("write failed (%s)\n", cli_errstr(c
));
296 if (cli_read(c
, fnum
, (char *)&pid2
, 0, sizeof(pid
)) != sizeof(pid
)) {
297 printf("read failed (%s)\n", cli_errstr(c
));
302 printf("data corruption!\n");
306 if (!cli_close(c
, fnum
)) {
307 printf("close failed (%s)\n", cli_errstr(c
));
311 if (!cli_unlink(c
, fname
)) {
312 printf("unlink failed (%s)\n", cli_errstr(c
));
316 if (!cli_unlock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
317 printf("unlock failed (%s)\n", cli_errstr(c
));
323 cli_unlink(c
, lockfname
);
330 static BOOL
run_torture(int dummy
)
332 struct cli_state cli
;
337 cli_sockopt(&cli
, sockops
);
339 ret
= rw_torture(&cli
);
341 if (!close_connection(&cli
)) {
348 static BOOL
rw_torture3(struct cli_state
*c
, char *lockfname
)
355 unsigned countprev
= 0;
360 for (i
= 0; i
< sizeof(buf
); i
+= sizeof(uint32
))
362 SIVAL(buf
, i
, sys_random());
367 fnum
= cli_open(c
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
370 printf("first open read/write of %s failed (%s)\n",
371 lockfname
, cli_errstr(c
));
377 for (i
= 0; i
< 500 && fnum
== -1; i
++)
379 fnum
= cli_open(c
, lockfname
, O_RDONLY
,
384 printf("second open read-only of %s failed (%s)\n",
385 lockfname
, cli_errstr(c
));
391 for (count
= 0; count
< sizeof(buf
); count
+= sent
)
393 if (count
>= countprev
) {
394 printf("%d %8d\r", i
, count
);
397 countprev
+= (sizeof(buf
) / 20);
402 sent
= ((unsigned)sys_random()%(20))+ 1;
403 if (sent
> sizeof(buf
) - count
)
405 sent
= sizeof(buf
) - count
;
408 if (cli_write(c
, fnum
, 0, buf
+count
, count
, sent
) != sent
) {
409 printf("write failed (%s)\n", cli_errstr(c
));
415 sent
= cli_read(c
, fnum
, buf_rd
+count
, count
,
419 printf("read failed offset:%d size:%d (%s)\n",
420 count
, sizeof(buf
)-count
,
427 if (memcmp(buf_rd
+count
, buf
+count
, sent
) != 0)
429 printf("read/write compare failed\n");
430 printf("offset: %d req %d recvd %d\n",
431 count
, sizeof(buf
)-count
, sent
);
440 if (!cli_close(c
, fnum
)) {
441 printf("close failed (%s)\n", cli_errstr(c
));
448 static BOOL
rw_torture2(struct cli_state
*c1
, struct cli_state
*c2
)
450 char *lockfname
= "\\torture.lck";
459 if (!cli_unlink(c1
, lockfname
)) {
460 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1
));
463 fnum1
= cli_open(c1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
466 printf("first open read/write of %s failed (%s)\n",
467 lockfname
, cli_errstr(c1
));
470 fnum2
= cli_open(c2
, lockfname
, O_RDONLY
,
473 printf("second open read-only of %s failed (%s)\n",
474 lockfname
, cli_errstr(c2
));
475 cli_close(c1
, fnum1
);
479 for (i
=0;i
<numops
;i
++)
481 size_t buf_size
= ((unsigned)sys_random()%(sizeof(buf
)-1))+ 1;
483 printf("%d\r", i
); fflush(stdout
);
486 generate_random_buffer(buf
, buf_size
, False
);
488 if (cli_write(c1
, fnum1
, 0, buf
, 0, buf_size
) != buf_size
) {
489 printf("write failed (%s)\n", cli_errstr(c1
));
493 if ((bytes_read
= cli_read(c2
, fnum2
, buf_rd
, 0, buf_size
)) != buf_size
) {
494 printf("read failed (%s)\n", cli_errstr(c2
));
495 printf("read %d, expected %d\n", bytes_read
, buf_size
);
499 if (memcmp(buf_rd
, buf
, buf_size
) != 0)
501 printf("read/write compare failed\n");
506 if (!cli_close(c2
, fnum2
)) {
507 printf("close failed (%s)\n", cli_errstr(c2
));
510 if (!cli_close(c1
, fnum1
)) {
511 printf("close failed (%s)\n", cli_errstr(c1
));
515 if (!cli_unlink(c1
, lockfname
)) {
516 printf("unlink failed (%s)\n", cli_errstr(c1
));
523 static BOOL
run_readwritetest(int dummy
)
525 static struct cli_state cli1
, cli2
;
528 if (!open_connection(&cli1
) || !open_connection(&cli2
)) {
531 cli_sockopt(&cli1
, sockops
);
532 cli_sockopt(&cli2
, sockops
);
534 printf("starting readwritetest\n");
536 test1
= rw_torture2(&cli1
, &cli2
);
537 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1
));
539 test2
= rw_torture2(&cli1
, &cli1
);
540 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2
));
542 if (!close_connection(&cli1
)) {
546 if (!close_connection(&cli2
)) {
550 return (test1
&& test2
);
553 static BOOL
run_readwritemulti(int dummy
)
555 static struct cli_state cli
;
560 cli_sockopt(&cli
, sockops
);
562 printf("run_readwritemulti: fname %s\n", randomfname
);
563 test
= rw_torture3(&cli
, randomfname
);
565 if (!close_connection(&cli
)) {
572 static BOOL
run_readwritelarge(int dummy
)
574 static struct cli_state cli1
;
576 char *lockfname
= "\\large.dat";
581 if (!open_connection(&cli1
)) {
584 cli_sockopt(&cli1
, sockops
);
585 memset(buf
,'\0',sizeof(buf
));
587 cli1
.max_xmit
= 0x11000;
589 printf("starting readwritelarge\n");
591 cli_unlink(&cli1
, lockfname
);
593 fnum1
= cli_open(&cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
);
595 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(&cli1
));
599 cli_write(&cli1
, fnum1
, 0, buf
, 0, sizeof(buf
));
601 if (!cli_close(&cli1
, fnum1
)) {
602 printf("close failed (%s)\n", cli_errstr(&cli1
));
606 if (!cli_qpathinfo(&cli1
, lockfname
, NULL
, NULL
, NULL
, &fsize
, NULL
)) {
607 printf("qpathinfo failed (%s)\n", cli_errstr(&cli1
));
611 if (fsize
== sizeof(buf
))
612 printf("readwritelarge test 1 succeeded (size = %x)\n", fsize
);
614 printf("readwritelarge test 1 failed (size = %x)\n", fsize
);
618 if (!cli_unlink(&cli1
, lockfname
)) {
619 printf("unlink failed (%s)\n", cli_errstr(&cli1
));
623 fnum1
= cli_open(&cli1
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
, DENY_NONE
);
625 printf("open read/write of %s failed (%s)\n", lockfname
, cli_errstr(&cli1
));
629 cli_smbwrite(&cli1
, fnum1
, buf
, 0, sizeof(buf
));
631 if (!cli_close(&cli1
, fnum1
)) {
632 printf("close failed (%s)\n", cli_errstr(&cli1
));
636 if (!close_connection(&cli1
)) {
644 /* run a test that simulates an approximate netbench client load */
645 static BOOL
run_netbench(int client
)
647 struct cli_state cli
;
658 cli_sockopt(&cli
, sockops
);
662 slprintf(cname
,sizeof(fname
), "CLIENT%d", client
);
664 f
= fopen("client.txt", "r");
667 perror("client.txt");
671 while (fgets(line
, sizeof(line
)-1, f
)) {
674 line
[strlen(line
)-1] = 0;
676 /* printf("[%d] %s\n", line_count, line); */
678 all_string_sub(line
,"CLIENT1", cname
, sizeof(line
));
680 for (i
=0;i
<20;i
++) params
[i
] = "";
682 /* parse the command parameters */
683 params
[0] = strtok(line
," ");
685 while (params
[i
]) params
[++i
] = strtok(NULL
," ");
691 if (strcmp(params
[1],"REQUEST") == 0) {
692 if (!strcmp(params
[0],"SMBopenX")) {
693 fstrcpy(fname
, params
[5]);
694 } else if (!strcmp(params
[0],"SMBclose")) {
695 nb_close(atoi(params
[3]));
696 } else if (!strcmp(params
[0],"SMBmkdir")) {
698 } else if (!strcmp(params
[0],"CREATE")) {
699 nb_create(params
[3], atoi(params
[5]));
700 } else if (!strcmp(params
[0],"SMBrmdir")) {
702 } else if (!strcmp(params
[0],"SMBunlink")) {
703 fstrcpy(fname
, params
[3]);
704 } else if (!strcmp(params
[0],"SMBmv")) {
705 nb_rename(params
[3], params
[5]);
706 } else if (!strcmp(params
[0],"SMBgetatr")) {
707 fstrcpy(fname
, params
[3]);
708 } else if (!strcmp(params
[0],"SMBwrite")) {
709 nb_write(atoi(params
[3]),
710 atoi(params
[5]), atoi(params
[7]));
711 } else if (!strcmp(params
[0],"SMBwritebraw")) {
712 nb_write(atoi(params
[3]),
713 atoi(params
[7]), atoi(params
[5]));
714 } else if (!strcmp(params
[0],"SMBreadbraw")) {
715 nb_read(atoi(params
[3]),
716 atoi(params
[7]), atoi(params
[5]));
717 } else if (!strcmp(params
[0],"SMBread")) {
718 nb_read(atoi(params
[3]),
719 atoi(params
[5]), atoi(params
[7]));
722 if (!strcmp(params
[0],"SMBopenX")) {
723 if (!strncmp(params
[2], "ERR", 3)) continue;
724 nb_open(fname
, atoi(params
[3]), atoi(params
[5]));
725 } else if (!strcmp(params
[0],"SMBgetatr")) {
726 if (!strncmp(params
[2], "ERR", 3)) continue;
727 nb_stat(fname
, atoi(params
[3]));
728 } else if (!strcmp(params
[0],"SMBunlink")) {
729 if (!strncmp(params
[2], "ERR", 3)) continue;
736 slprintf(fname
,sizeof(fname
), "CLIENTS/CLIENT%d", client
);
742 if (!close_connection(&cli
)) {
750 /* run a test that simulates an approximate netbench w9X client load */
751 static BOOL
run_nbw95(int dummy
)
755 t
= create_procs(run_netbench
, &correct
);
756 /* to produce a netbench result we scale accoding to the
757 netbench measured throughput for the run that produced the
758 sniff that was used to produce client.txt. That run used 2
759 clients and ran for 660 seconds to produce a result of
761 printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n",
762 132*nprocs
/t
, 0.5*0.5*nprocs
*660/t
, 2*nprocs
*660/t
);
766 /* run a test that simulates an approximate netbench wNT client load */
767 static BOOL
run_nbwnt(int dummy
)
771 t
= create_procs(run_netbench
, &correct
);
772 printf("Throughput %g MB/sec (NB=%g MB/sec %g MBit/sec)\n",
773 132*nprocs
/t
, 0.5*0.5*nprocs
*660/t
, 2*nprocs
*660/t
);
780 This test checks for two things:
782 1) correct support for retaining locks over a close (ie. the server
783 must not use posix semantics)
784 2) support for lock timeouts
786 static BOOL
run_locktest1(int dummy
)
788 static struct cli_state cli1
, cli2
;
789 char *fname
= "\\lockt1.lck";
790 int fnum1
, fnum2
, fnum3
;
793 if (!open_connection(&cli1
) || !open_connection(&cli2
)) {
796 cli_sockopt(&cli1
, sockops
);
797 cli_sockopt(&cli2
, sockops
);
799 printf("starting locktest1\n");
801 cli_unlink(&cli1
, fname
);
803 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
805 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
808 fnum2
= cli_open(&cli1
, fname
, O_RDWR
, DENY_NONE
);
810 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
813 fnum3
= cli_open(&cli2
, fname
, O_RDWR
, DENY_NONE
);
815 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(&cli2
));
819 if (!cli_lock(&cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
820 printf("lock1 failed (%s)\n", cli_errstr(&cli1
));
825 if (cli_lock(&cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
826 printf("lock2 succeeded! This is a locking bug\n");
829 if (!check_error(&cli2
, ERRDOS
, ERRlock
, 0)) return False
;
833 printf("Testing lock timeouts\n");
835 if (cli_lock(&cli2
, fnum3
, 0, 4, 10*1000, WRITE_LOCK
)) {
836 printf("lock3 succeeded! This is a locking bug\n");
839 if (!check_error(&cli2
, ERRDOS
, ERRlock
, 0)) return False
;
844 printf("error: This server appears not to support timed lock requests\n");
847 if (!cli_close(&cli1
, fnum2
)) {
848 printf("close1 failed (%s)\n", cli_errstr(&cli1
));
852 if (cli_lock(&cli2
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
853 printf("lock4 succeeded! This is a locking bug\n");
856 if (!check_error(&cli2
, ERRDOS
, ERRlock
, 0)) return False
;
859 if (!cli_close(&cli1
, fnum1
)) {
860 printf("close2 failed (%s)\n", cli_errstr(&cli1
));
864 if (!cli_close(&cli2
, fnum3
)) {
865 printf("close3 failed (%s)\n", cli_errstr(&cli2
));
869 if (!cli_unlink(&cli1
, fname
)) {
870 printf("unlink failed (%s)\n", cli_errstr(&cli1
));
875 if (!close_connection(&cli1
)) {
879 if (!close_connection(&cli2
)) {
883 printf("Passed locktest1\n");
888 checks for correct tconX support
890 static BOOL
run_tcon_test(int dummy
)
892 static struct cli_state cli1
;
893 char *fname
= "\\tcontest.tmp";
898 if (!open_connection(&cli1
)) {
901 cli_sockopt(&cli1
, sockops
);
903 printf("starting tcontest\n");
905 cli_unlink(&cli1
, fname
);
907 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
910 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
916 if (cli_write(&cli1
, fnum1
, 0, buf
, 130, 4) != 4)
918 printf("write failed (%s)", cli_errstr(&cli1
));
922 if (!cli_send_tconX(&cli1
, share
, "?????",
923 password
, strlen(password
)+1)) {
924 printf("%s refused 2nd tree connect (%s)\n", host
,
930 if (cli_write(&cli1
, fnum1
, 0, buf
, 130, 4) == 4)
932 printf("write succeeded (%s)", cli_errstr(&cli1
));
936 if (cli_close(&cli1
, fnum1
)) {
937 printf("close2 succeeded (%s)\n", cli_errstr(&cli1
));
941 if (!cli_tdis(&cli1
)) {
942 printf("tdis failed (%s)\n", cli_errstr(&cli1
));
948 if (!cli_close(&cli1
, fnum1
)) {
949 printf("close2 failed (%s)\n", cli_errstr(&cli1
));
953 if (!close_connection(&cli1
)) {
957 printf("Passed tcontest\n");
963 This test checks that
965 1) the server supports multiple locking contexts on the one SMB
966 connection, distinguished by PID.
968 2) the server correctly fails overlapping locks made by the same PID (this
969 goes against POSIX behaviour, which is why it is tricky to implement)
971 3) the server denies unlock requests by an incorrect client PID
973 static BOOL
run_locktest2(int dummy
)
975 static struct cli_state cli
;
976 char *fname
= "\\lockt2.lck";
977 int fnum1
, fnum2
, fnum3
;
980 if (!open_connection(&cli
)) {
984 cli_sockopt(&cli
, sockops
);
986 printf("starting locktest2\n");
988 cli_unlink(&cli
, fname
);
992 fnum1
= cli_open(&cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
994 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli
));
998 fnum2
= cli_open(&cli
, fname
, O_RDWR
, DENY_NONE
);
1000 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(&cli
));
1004 cli_setpid(&cli
, 2);
1006 fnum3
= cli_open(&cli
, fname
, O_RDWR
, DENY_NONE
);
1008 printf("open3 of %s failed (%s)\n", fname
, cli_errstr(&cli
));
1012 cli_setpid(&cli
, 1);
1014 if (!cli_lock(&cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1015 printf("lock1 failed (%s)\n", cli_errstr(&cli
));
1019 if (cli_lock(&cli
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
1020 printf("WRITE lock1 succeeded! This is a locking bug\n");
1023 if (!check_error(&cli
, ERRDOS
, ERRlock
, 0)) return False
;
1026 if (cli_lock(&cli
, fnum2
, 0, 4, 0, WRITE_LOCK
)) {
1027 printf("WRITE lock2 succeeded! This is a locking bug\n");
1030 if (!check_error(&cli
, ERRDOS
, ERRlock
, 0)) return False
;
1033 if (cli_lock(&cli
, fnum2
, 0, 4, 0, READ_LOCK
)) {
1034 printf("READ lock2 succeeded! This is a locking bug\n");
1037 if (!check_error(&cli
, ERRDOS
, ERRlock
, 0)) return False
;
1040 if (!cli_lock(&cli
, fnum1
, 100, 4, 0, WRITE_LOCK
)) {
1041 printf("lock at 100 failed (%s)\n", cli_errstr(&cli
));
1043 cli_setpid(&cli
, 2);
1044 if (cli_unlock(&cli
, fnum1
, 100, 4)) {
1045 printf("unlock at 100 succeeded! This is a locking bug\n");
1049 if (cli_unlock(&cli
, fnum1
, 0, 4)) {
1050 printf("unlock1 succeeded! This is a locking bug\n");
1053 if (!check_error(&cli
, ERRDOS
, ERRnotlocked
, 0)) return False
;
1056 if (cli_unlock(&cli
, fnum1
, 0, 8)) {
1057 printf("unlock2 succeeded! This is a locking bug\n");
1060 if (!check_error(&cli
, ERRDOS
, ERRnotlocked
, 0)) return False
;
1063 if (cli_lock(&cli
, fnum3
, 0, 4, 0, WRITE_LOCK
)) {
1064 printf("lock3 succeeded! This is a locking bug\n");
1067 if (!check_error(&cli
, ERRDOS
, ERRlock
, 0)) return False
;
1070 cli_setpid(&cli
, 1);
1072 if (!cli_close(&cli
, fnum1
)) {
1073 printf("close1 failed (%s)\n", cli_errstr(&cli
));
1077 if (!cli_close(&cli
, fnum2
)) {
1078 printf("close2 failed (%s)\n", cli_errstr(&cli
));
1082 if (!cli_close(&cli
, fnum3
)) {
1083 printf("close3 failed (%s)\n", cli_errstr(&cli
));
1087 if (!close_connection(&cli
)) {
1091 printf("locktest2 finished\n");
1098 This test checks that
1100 1) the server supports the full offset range in lock requests
1102 static BOOL
run_locktest3(int dummy
)
1104 static struct cli_state cli1
, cli2
;
1105 char *fname
= "\\lockt3.lck";
1106 int fnum1
, fnum2
, i
;
1108 BOOL correct
= True
;
1110 #define NEXT_OFFSET offset += (~(uint32)0) / numops
1112 if (!open_connection(&cli1
) || !open_connection(&cli2
)) {
1115 cli_sockopt(&cli1
, sockops
);
1116 cli_sockopt(&cli2
, sockops
);
1118 printf("starting locktest3\n");
1120 cli_unlink(&cli1
, fname
);
1122 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1124 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
1127 fnum2
= cli_open(&cli2
, fname
, O_RDWR
, DENY_NONE
);
1129 printf("open2 of %s failed (%s)\n", fname
, cli_errstr(&cli2
));
1133 for (offset
=i
=0;i
<numops
;i
++) {
1135 if (!cli_lock(&cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1136 printf("lock1 %d failed (%s)\n",
1142 if (!cli_lock(&cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1143 printf("lock2 %d failed (%s)\n",
1150 for (offset
=i
=0;i
<numops
;i
++) {
1153 if (cli_lock(&cli1
, fnum1
, offset
-2, 1, 0, WRITE_LOCK
)) {
1154 printf("error: lock1 %d succeeded!\n", i
);
1158 if (cli_lock(&cli2
, fnum2
, offset
-1, 1, 0, WRITE_LOCK
)) {
1159 printf("error: lock2 %d succeeded!\n", i
);
1163 if (cli_lock(&cli1
, fnum1
, offset
-1, 1, 0, WRITE_LOCK
)) {
1164 printf("error: lock3 %d succeeded!\n", i
);
1168 if (cli_lock(&cli2
, fnum2
, offset
-2, 1, 0, WRITE_LOCK
)) {
1169 printf("error: lock4 %d succeeded!\n", i
);
1174 for (offset
=i
=0;i
<numops
;i
++) {
1177 if (!cli_unlock(&cli1
, fnum1
, offset
-1, 1)) {
1178 printf("unlock1 %d failed (%s)\n",
1184 if (!cli_unlock(&cli2
, fnum2
, offset
-2, 1)) {
1185 printf("unlock2 %d failed (%s)\n",
1192 if (!cli_close(&cli1
, fnum1
)) {
1193 printf("close1 failed (%s)\n", cli_errstr(&cli1
));
1197 if (!cli_close(&cli2
, fnum2
)) {
1198 printf("close2 failed (%s)\n", cli_errstr(&cli2
));
1202 if (!cli_unlink(&cli1
, fname
)) {
1203 printf("unlink failed (%s)\n", cli_errstr(&cli1
));
1207 if (!close_connection(&cli1
)) {
1211 if (!close_connection(&cli2
)) {
1215 printf("finished locktest3\n");
1220 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1221 printf("** "); correct = False; \
1225 looks at overlapping locks
1227 static BOOL
run_locktest4(int dummy
)
1229 static struct cli_state cli1
, cli2
;
1230 char *fname
= "\\lockt4.lck";
1231 int fnum1
, fnum2
, f
;
1234 BOOL correct
= True
;
1236 if (!open_connection(&cli1
) || !open_connection(&cli2
)) {
1240 cli_sockopt(&cli1
, sockops
);
1241 cli_sockopt(&cli2
, sockops
);
1243 printf("starting locktest4\n");
1245 cli_unlink(&cli1
, fname
);
1247 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1248 fnum2
= cli_open(&cli2
, fname
, O_RDWR
, DENY_NONE
);
1250 memset(buf
, 0, sizeof(buf
));
1252 if (cli_write(&cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1253 printf("Failed to create file\n");
1258 ret
= cli_lock(&cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
1259 cli_lock(&cli1
, fnum1
, 2, 4, 0, WRITE_LOCK
);
1260 EXPECTED(ret
, False
);
1261 printf("the same process %s set overlapping write locks\n", ret
?"can":"cannot");
1263 ret
= cli_lock(&cli1
, fnum1
, 10, 4, 0, READ_LOCK
) &&
1264 cli_lock(&cli1
, fnum1
, 12, 4, 0, READ_LOCK
);
1265 EXPECTED(ret
, True
);
1266 printf("the same process %s set overlapping read locks\n", ret
?"can":"cannot");
1268 ret
= cli_lock(&cli1
, fnum1
, 20, 4, 0, WRITE_LOCK
) &&
1269 cli_lock(&cli2
, fnum2
, 22, 4, 0, WRITE_LOCK
);
1270 EXPECTED(ret
, False
);
1271 printf("a different connection %s set overlapping write locks\n", ret
?"can":"cannot");
1273 ret
= cli_lock(&cli1
, fnum1
, 30, 4, 0, READ_LOCK
) &&
1274 cli_lock(&cli2
, fnum2
, 32, 4, 0, READ_LOCK
);
1275 EXPECTED(ret
, True
);
1276 printf("a different connection %s set overlapping read locks\n", ret
?"can":"cannot");
1278 ret
= (cli_setpid(&cli1
, 1), cli_lock(&cli1
, fnum1
, 40, 4, 0, WRITE_LOCK
)) &&
1279 (cli_setpid(&cli1
, 2), cli_lock(&cli1
, fnum1
, 42, 4, 0, WRITE_LOCK
));
1280 EXPECTED(ret
, False
);
1281 printf("a different pid %s set overlapping write locks\n", ret
?"can":"cannot");
1283 ret
= (cli_setpid(&cli1
, 1), cli_lock(&cli1
, fnum1
, 50, 4, 0, READ_LOCK
)) &&
1284 (cli_setpid(&cli1
, 2), cli_lock(&cli1
, fnum1
, 52, 4, 0, READ_LOCK
));
1285 EXPECTED(ret
, True
);
1286 printf("a different pid %s set overlapping read locks\n", ret
?"can":"cannot");
1288 ret
= cli_lock(&cli1
, fnum1
, 60, 4, 0, READ_LOCK
) &&
1289 cli_lock(&cli1
, fnum1
, 60, 4, 0, READ_LOCK
);
1290 EXPECTED(ret
, True
);
1291 printf("the same process %s set the same read lock twice\n", ret
?"can":"cannot");
1293 ret
= cli_lock(&cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
) &&
1294 cli_lock(&cli1
, fnum1
, 70, 4, 0, WRITE_LOCK
);
1295 EXPECTED(ret
, False
);
1296 printf("the same process %s set the same write lock twice\n", ret
?"can":"cannot");
1298 ret
= cli_lock(&cli1
, fnum1
, 80, 4, 0, READ_LOCK
) &&
1299 cli_lock(&cli1
, fnum1
, 80, 4, 0, WRITE_LOCK
);
1300 EXPECTED(ret
, False
);
1301 printf("the same process %s overlay a read lock with a write lock\n", ret
?"can":"cannot");
1303 ret
= cli_lock(&cli1
, fnum1
, 90, 4, 0, WRITE_LOCK
) &&
1304 cli_lock(&cli1
, fnum1
, 90, 4, 0, READ_LOCK
);
1305 EXPECTED(ret
, True
);
1306 printf("the same process %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1308 ret
= (cli_setpid(&cli1
, 1), cli_lock(&cli1
, fnum1
, 100, 4, 0, WRITE_LOCK
)) &&
1309 (cli_setpid(&cli1
, 2), cli_lock(&cli1
, fnum1
, 100, 4, 0, READ_LOCK
));
1310 EXPECTED(ret
, False
);
1311 printf("a different pid %s overlay a write lock with a read lock\n", ret
?"can":"cannot");
1313 ret
= cli_lock(&cli1
, fnum1
, 110, 4, 0, READ_LOCK
) &&
1314 cli_lock(&cli1
, fnum1
, 112, 4, 0, READ_LOCK
) &&
1315 cli_unlock(&cli1
, fnum1
, 110, 6);
1316 EXPECTED(ret
, False
);
1317 printf("the same process %s coalesce read locks\n", ret
?"can":"cannot");
1320 ret
= cli_lock(&cli1
, fnum1
, 120, 4, 0, WRITE_LOCK
) &&
1321 (cli_read(&cli2
, fnum2
, buf
, 120, 4) == 4);
1322 EXPECTED(ret
, False
);
1323 printf("this server %s strict write locking\n", ret
?"doesn't do":"does");
1325 ret
= cli_lock(&cli1
, fnum1
, 130, 4, 0, READ_LOCK
) &&
1326 (cli_write(&cli2
, fnum2
, 0, buf
, 130, 4) == 4);
1327 EXPECTED(ret
, False
);
1328 printf("this server %s strict read locking\n", ret
?"doesn't do":"does");
1331 ret
= cli_lock(&cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1332 cli_lock(&cli1
, fnum1
, 140, 4, 0, READ_LOCK
) &&
1333 cli_unlock(&cli1
, fnum1
, 140, 4) &&
1334 cli_unlock(&cli1
, fnum1
, 140, 4);
1335 EXPECTED(ret
, True
);
1336 printf("this server %s do recursive read locking\n", ret
?"does":"doesn't");
1339 ret
= cli_lock(&cli1
, fnum1
, 150, 4, 0, WRITE_LOCK
) &&
1340 cli_lock(&cli1
, fnum1
, 150, 4, 0, READ_LOCK
) &&
1341 cli_unlock(&cli1
, fnum1
, 150, 4) &&
1342 (cli_read(&cli2
, fnum2
, buf
, 150, 4) == 4) &&
1343 !(cli_write(&cli2
, fnum2
, 0, buf
, 150, 4) == 4) &&
1344 cli_unlock(&cli1
, fnum1
, 150, 4);
1345 EXPECTED(ret
, True
);
1346 printf("this server %s do recursive lock overlays\n", ret
?"does":"doesn't");
1348 ret
= cli_lock(&cli1
, fnum1
, 160, 4, 0, READ_LOCK
) &&
1349 cli_unlock(&cli1
, fnum1
, 160, 4) &&
1350 (cli_write(&cli2
, fnum2
, 0, buf
, 160, 4) == 4) &&
1351 (cli_read(&cli2
, fnum2
, buf
, 160, 4) == 4);
1352 EXPECTED(ret
, True
);
1353 printf("the same process %s remove a read lock using write locking\n", ret
?"can":"cannot");
1355 ret
= cli_lock(&cli1
, fnum1
, 170, 4, 0, WRITE_LOCK
) &&
1356 cli_unlock(&cli1
, fnum1
, 170, 4) &&
1357 (cli_write(&cli2
, fnum2
, 0, buf
, 170, 4) == 4) &&
1358 (cli_read(&cli2
, fnum2
, buf
, 170, 4) == 4);
1359 EXPECTED(ret
, True
);
1360 printf("the same process %s remove a write lock using read locking\n", ret
?"can":"cannot");
1362 ret
= cli_lock(&cli1
, fnum1
, 190, 4, 0, WRITE_LOCK
) &&
1363 cli_lock(&cli1
, fnum1
, 190, 4, 0, READ_LOCK
) &&
1364 cli_unlock(&cli1
, fnum1
, 190, 4) &&
1365 !(cli_write(&cli2
, fnum2
, 0, buf
, 190, 4) == 4) &&
1366 (cli_read(&cli2
, fnum2
, buf
, 190, 4) == 4);
1367 EXPECTED(ret
, True
);
1368 printf("the same process %s remove the first lock first\n", ret
?"does":"doesn't");
1370 cli_close(&cli1
, fnum1
);
1371 cli_close(&cli2
, fnum2
);
1372 fnum1
= cli_open(&cli1
, fname
, O_RDWR
, DENY_NONE
);
1373 f
= cli_open(&cli1
, fname
, O_RDWR
, DENY_NONE
);
1374 ret
= cli_lock(&cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
1375 cli_lock(&cli1
, f
, 0, 1, 0, READ_LOCK
) &&
1376 cli_close(&cli1
, fnum1
) &&
1377 ((fnum1
= cli_open(&cli1
, fname
, O_RDWR
, DENY_NONE
)) != -1) &&
1378 cli_lock(&cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
1379 cli_close(&cli1
, f
);
1380 EXPECTED(ret
, True
);
1381 printf("the server %s have the NT byte range lock bug\n", !ret
?"does":"doesn't");
1384 cli_close(&cli1
, fnum1
);
1385 cli_close(&cli2
, fnum2
);
1386 cli_unlink(&cli1
, fname
);
1387 close_connection(&cli1
);
1388 close_connection(&cli2
);
1390 printf("finished locktest4\n");
1395 looks at lock upgrade/downgrade.
1397 static BOOL
run_locktest5(int dummy
)
1399 static struct cli_state cli1
, cli2
;
1400 char *fname
= "\\lockt5.lck";
1401 int fnum1
, fnum2
, fnum3
;
1404 BOOL correct
= True
;
1406 if (!open_connection(&cli1
) || !open_connection(&cli2
)) {
1410 cli_sockopt(&cli1
, sockops
);
1411 cli_sockopt(&cli2
, sockops
);
1413 printf("starting locktest5\n");
1415 cli_unlink(&cli1
, fname
);
1417 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1418 fnum2
= cli_open(&cli2
, fname
, O_RDWR
, DENY_NONE
);
1419 fnum3
= cli_open(&cli1
, fname
, O_RDWR
, DENY_NONE
);
1421 memset(buf
, 0, sizeof(buf
));
1423 if (cli_write(&cli1
, fnum1
, 0, buf
, 0, sizeof(buf
)) != sizeof(buf
)) {
1424 printf("Failed to create file\n");
1429 /* Check for NT bug... */
1430 ret
= cli_lock(&cli1
, fnum1
, 0, 8, 0, READ_LOCK
) &&
1431 cli_lock(&cli1
, fnum3
, 0, 1, 0, READ_LOCK
);
1432 cli_close(&cli1
, fnum1
);
1433 fnum1
= cli_open(&cli1
, fname
, O_RDWR
, DENY_NONE
);
1434 ret
= cli_lock(&cli1
, fnum1
, 7, 1, 0, WRITE_LOCK
);
1435 EXPECTED(ret
, True
);
1436 printf("this server %s the NT locking bug\n", ret
? "doesn't have" : "has");
1437 cli_close(&cli1
, fnum1
);
1438 fnum1
= cli_open(&cli1
, fname
, O_RDWR
, DENY_NONE
);
1439 cli_unlock(&cli1
, fnum3
, 0, 1);
1441 ret
= cli_lock(&cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
) &&
1442 cli_lock(&cli1
, fnum1
, 1, 1, 0, READ_LOCK
);
1443 EXPECTED(ret
, True
);
1444 printf("the same process %s overlay a write with a read lock\n", ret
?"can":"cannot");
1446 ret
= cli_lock(&cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
1447 EXPECTED(ret
, False
);
1449 printf("a different processs %s get a read lock on the first process lock stack\n", ret
?"can":"cannot");
1451 /* Unlock the process 2 lock. */
1452 cli_unlock(&cli2
, fnum2
, 0, 4);
1454 ret
= cli_lock(&cli1
, fnum3
, 0, 4, 0, READ_LOCK
);
1455 EXPECTED(ret
, False
);
1457 printf("the same processs on a different fnum %s get a read lock\n", ret
?"can":"cannot");
1459 /* Unlock the process 1 fnum3 lock. */
1460 cli_unlock(&cli1
, fnum3
, 0, 4);
1462 /* Stack 2 more locks here. */
1463 ret
= cli_lock(&cli1
, fnum1
, 0, 4, 0, READ_LOCK
) &&
1464 cli_lock(&cli1
, fnum1
, 0, 4, 0, READ_LOCK
);
1466 EXPECTED(ret
, True
);
1467 printf("the same process %s stack read locks\n", ret
?"can":"cannot");
1469 /* Unlock the first process lock, then check this was the WRITE lock that was
1472 ret
= cli_unlock(&cli1
, fnum1
, 0, 4) &&
1473 cli_lock(&cli2
, fnum2
, 0, 4, 0, READ_LOCK
);
1475 EXPECTED(ret
, True
);
1476 printf("the first unlock removes the %s lock\n", ret
?"WRITE":"READ");
1478 /* Unlock the process 2 lock. */
1479 cli_unlock(&cli2
, fnum2
, 0, 4);
1481 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1483 ret
= cli_unlock(&cli1
, fnum1
, 1, 1) &&
1484 cli_unlock(&cli1
, fnum1
, 0, 4) &&
1485 cli_unlock(&cli1
, fnum1
, 0, 4);
1487 EXPECTED(ret
, True
);
1488 printf("the same process %s unlock the stack of 4 locks\n", ret
?"can":"cannot");
1490 /* Ensure the next unlock fails. */
1491 ret
= cli_unlock(&cli1
, fnum1
, 0, 4);
1492 EXPECTED(ret
, False
);
1493 printf("the same process %s count the lock stack\n", !ret
?"can":"cannot");
1495 /* Ensure connection 2 can get a write lock. */
1496 ret
= cli_lock(&cli2
, fnum2
, 0, 4, 0, WRITE_LOCK
);
1497 EXPECTED(ret
, True
);
1499 printf("a different processs %s get a write lock on the unlocked stack\n", ret
?"can":"cannot");
1503 cli_close(&cli1
, fnum1
);
1504 cli_close(&cli2
, fnum2
);
1505 cli_unlink(&cli1
, fname
);
1506 if (!close_connection(&cli1
)) {
1509 if (!close_connection(&cli2
)) {
1513 printf("finished locktest5\n");
1520 this produces a matrix of deny mode behaviour
1522 static BOOL
run_denytest1(int dummy
)
1524 static struct cli_state cli1
, cli2
;
1526 int f
, d1
, d2
, o1
, o2
, x
=0;
1527 char *fnames
[] = {"\\denytest1.exe", "\\denytest1.dat", NULL
};
1532 {DENY_DOS
, "DENY_DOS"},
1533 {DENY_ALL
, "DENY_ALL"},
1534 {DENY_WRITE
, "DENY_WRITE"},
1535 {DENY_READ
, "DENY_READ"},
1536 {DENY_NONE
, "DENY_NONE"},
1537 {DENY_FCB
, "DENY_FCB"},
1544 {O_RDONLY
, "O_RDONLY"},
1545 {O_WRONLY
, "O_WRONLY"},
1547 BOOL correct
= True
;
1549 if (!open_connection(&cli1
) || !open_connection(&cli2
)) {
1552 cli_sockopt(&cli1
, sockops
);
1553 cli_sockopt(&cli2
, sockops
);
1555 printf("starting denytest1\n");
1557 for (f
=0;fnames
[f
];f
++) {
1558 cli_unlink(&cli1
, fnames
[f
]);
1560 fnum1
= cli_open(&cli1
, fnames
[f
], O_RDWR
|O_CREAT
, DENY_NONE
);
1561 cli_write(&cli1
, fnum1
, 0, fnames
[f
], 0, strlen(fnames
[f
]));
1562 cli_close(&cli1
, fnum1
);
1564 for (d1
=0;deny_modes
[d1
].name
;d1
++)
1565 for (o1
=0;open_modes
[o1
].name
;o1
++)
1566 for (d2
=0;deny_modes
[d2
].name
;d2
++)
1567 for (o2
=0;open_modes
[o2
].name
;o2
++) {
1568 fnum1
= cli_open(&cli1
, fnames
[f
],
1571 fnum2
= cli_open(&cli2
, fnames
[f
],
1575 printf("%s %8s %10s %8s %10s ",
1577 open_modes
[o1
].name
,
1578 deny_modes
[d1
].name
,
1579 open_modes
[o2
].name
,
1580 deny_modes
[d2
].name
);
1584 } else if (fnum2
== -1) {
1587 if (cli_read(&cli2
, fnum2
, (void *)&x
, 0, 1) == 1) {
1590 if (cli_write(&cli2
, fnum2
, 0, (void *)&x
, 0, 1) == 1) {
1596 cli_close(&cli1
, fnum1
);
1597 cli_close(&cli2
, fnum2
);
1600 cli_unlink(&cli1
, fnames
[f
]);
1603 if (!close_connection(&cli1
)) {
1606 if (!close_connection(&cli2
)) {
1610 printf("finshed denytest1\n");
1616 this produces a matrix of deny mode behaviour for two opens on the
1619 static BOOL
run_denytest2(int dummy
)
1621 static struct cli_state cli1
;
1623 int f
, d1
, d2
, o1
, o2
, x
=0;
1624 char *fnames
[] = {"\\denytest2.exe", "\\denytest2.dat", NULL
};
1629 {DENY_DOS
, "DENY_DOS"},
1630 {DENY_ALL
, "DENY_ALL"},
1631 {DENY_WRITE
, "DENY_WRITE"},
1632 {DENY_READ
, "DENY_READ"},
1633 {DENY_NONE
, "DENY_NONE"},
1634 {DENY_FCB
, "DENY_FCB"},
1641 {O_RDONLY
, "O_RDONLY"},
1642 {O_WRONLY
, "O_WRONLY"},
1644 BOOL correct
= True
;
1646 if (!open_connection(&cli1
)) {
1649 cli_sockopt(&cli1
, sockops
);
1651 printf("starting denytest2\n");
1653 for (f
=0;fnames
[f
];f
++) {
1654 cli_unlink(&cli1
, fnames
[f
]);
1656 fnum1
= cli_open(&cli1
, fnames
[f
], O_RDWR
|O_CREAT
, DENY_NONE
);
1657 cli_write(&cli1
, fnum1
, 0, fnames
[f
], 0, strlen(fnames
[f
]));
1658 cli_close(&cli1
, fnum1
);
1660 for (d1
=0;deny_modes
[d1
].name
;d1
++)
1661 for (o1
=0;open_modes
[o1
].name
;o1
++)
1662 for (d2
=0;deny_modes
[d2
].name
;d2
++)
1663 for (o2
=0;open_modes
[o2
].name
;o2
++) {
1664 fnum1
= cli_open(&cli1
, fnames
[f
],
1667 fnum2
= cli_open(&cli1
, fnames
[f
],
1671 printf("%s %8s %10s %8s %10s ",
1673 open_modes
[o1
].name
,
1674 deny_modes
[d1
].name
,
1675 open_modes
[o2
].name
,
1676 deny_modes
[d2
].name
);
1680 } else if (fnum2
== -1) {
1683 if (cli_read(&cli1
, fnum2
, (void *)&x
, 0, 1) == 1) {
1686 if (cli_write(&cli1
, fnum2
, 0, (void *)&x
, 0, 1) == 1) {
1692 cli_close(&cli1
, fnum1
);
1693 cli_close(&cli1
, fnum2
);
1696 cli_unlink(&cli1
, fnames
[f
]);
1699 if (!close_connection(&cli1
)) {
1703 printf("finshed denytest2\n");
1708 test whether fnums and tids open on one VC are available on another (a major
1711 static BOOL
run_fdpasstest(int dummy
)
1713 static struct cli_state cli1
, cli2
, cli3
;
1714 char *fname
= "\\fdpass.tst";
1718 if (!open_connection(&cli1
) || !open_connection(&cli2
)) {
1721 cli_sockopt(&cli1
, sockops
);
1722 cli_sockopt(&cli2
, sockops
);
1724 printf("starting fdpasstest\n");
1726 cli_unlink(&cli1
, fname
);
1728 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
1730 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
1734 if (cli_write(&cli1
, fnum1
, 0, "hello world\n", 0, 13) != 13) {
1735 printf("write failed (%s)\n", cli_errstr(&cli1
));
1740 cli3
.vuid
= cli1
.vuid
;
1741 cli3
.cnum
= cli1
.cnum
;
1742 cli3
.pid
= cli1
.pid
;
1744 if (cli_read(&cli3
, fnum1
, buf
, 0, 13) == 13) {
1745 printf("read succeeded! nasty security hole [%s]\n",
1750 cli_close(&cli1
, fnum1
);
1751 cli_unlink(&cli1
, fname
);
1753 close_connection(&cli1
);
1754 close_connection(&cli2
);
1756 printf("finished fdpasstest\n");
1760 /*test multiple users over a single tcp connection*/
1761 /*test multiple users over a single tcp connection ~~~~~~~~~~~~~~~~~~~~~~~~~~*/
1762 /*test multiple users over a single tcp connection*/
1765 typedef struct subtaboid
{
1767 struct subtaboid
*next
;
1776 typedef struct taboid
{
1778 int owner
, share
, as_user
;
1782 SUBTABOID
*subtaboids
[2];
1786 static void init_TABOID(TABOID
*t
, int owner
, int share
, int as_user
)
1788 memset( t
, '\0', sizeof(*t
));
1791 t
->as_user
= as_user
;
1794 static BOOL
run_vusertest_op_null(TABOID
*t
)
1799 static BOOL
run_vusertest_report_full(
1800 const char *operation
,
1801 const char *sub_operation
,
1812 "%8s[%s]:%10s file %10s user %10s(%5d). share %10s tid %5d owner %10s(%5d). fnum %5d was %5d (%s).",
1814 failure
?"FAILURE":"SUCCESS",
1816 vusers
[t
->owner
].fname
,
1817 vusers
[t
->as_user
].username
,
1818 /*vusers[t->as_user].vuid,*/
1819 vusers
[t
->as_user
].cli
.vuid
,
1821 /*vusers[t->owner].per_tid[t->share].tid,*/
1822 vusers
[t
->as_user
].cli
.cnum
,
1823 vusers
[t
->owner
].username
,
1824 /*vusers[t->owner].vuid,*/
1825 vusers
[t
->owner
].cli
.vuid
,
1826 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
],
1827 vusers
[t
->as_user
].per_tid
[t
->share
].backup_fnum
[t
->owner
],
1828 failure
?cli_errstr(&vusers
[t
->as_user
].cli
):""
1832 printf("%s\n", *buf
);
1837 static BOOL
run_vusertest_report(
1838 const char *operation
,
1839 const char *sub_operation
,
1846 return run_vusertest_report_full(operation
, sub_operation
, failure
, True
, &buf
, t
);
1849 static BOOL
run_vusertest_report_failure(
1850 const char *operation
,
1851 const char *sub_operation
,
1857 return run_vusertest_report_full(operation
, sub_operation
, True
, True
, &buf
, t
);
1860 static BOOL
run_vusertest_report_success(
1861 const char *operation
,
1862 const char *sub_operation
,
1868 return run_vusertest_report_full(operation
, sub_operation
, False
, True
, &buf
, t
);
1871 static BOOL
run_vusertest_op_init(TABOID
*t
)
1876 vusers
[t
->owner
].fname
[0] = '\0';
1878 vusers
[t
->owner
].vuid
= 0;
1879 vusers
[t
->owner
].vuid_valid
= False
;
1880 vusers
[t
->owner
].files_valid
= False
;
1882 for(i
= 0; i
< sizeof(vusers
[t
->owner
].per_tid
)/sizeof(vusers
[t
->owner
].per_tid
[0]); i
++) {
1884 vusers
[t
->owner
].per_tid
[i
].tid
= 0;
1885 vusers
[t
->owner
].per_tid
[i
].tid_valid
= False
;
1887 for(j
= 0; j
< sizeof(vusers
[t
->owner
].per_tid
[i
].fnum
)/sizeof(vusers
[t
->owner
].per_tid
[i
].fnum
[0]); j
++) {
1889 vusers
[t
->owner
].per_tid
[i
].fnum
[j
] = vusers
[t
->owner
].per_tid
[i
].backup_fnum
[j
] = -1;
1896 static BOOL
run_vusertest_op_create(TABOID
*t
)
1899 BOOL should_work
= (vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
&& vusers
[t
->as_user
].vuid_valid
);
1901 snprintf(vusers
[t
->owner
].fname
, sizeof(vusers
[t
->owner
].fname
), "muserconn_%d", t
->owner
);
1903 vusers
[t
->as_user
].cli
.cnum
= vusers
[t
->owner
].per_tid
[t
->share
].tid
;
1905 if(!cli_unlink(&vusers
[t
->as_user
].cli
, vusers
[t
->owner
].fname
)) {
1907 run_vusertest_report_failure("CREATE", "unlink", t
);
1909 return should_work
?False
:True
;
1912 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
] =
1913 cli_open(&vusers
[t
->as_user
].cli
, vusers
[t
->owner
].fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
1915 if (vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
] == -1) {
1917 run_vusertest_report_failure("CREATE", "create", t
);
1919 return should_work
?False
:True
;
1922 run_vusertest_report_success("CREATE", "created", t
);
1924 vusers
[t
->as_user
].files_valid
= True
; /*not true for all!*/
1926 return should_work
?True
:False
;
1929 static BOOL
run_vusertest_op_write(TABOID
*t
)
1932 BOOL should_work
= (
1933 vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
&&
1934 vusers
[t
->as_user
].vuid_valid
&&
1935 vusers
[t
->as_user
].files_valid
1941 vusers
[t
->as_user
].cli
.cnum
= vusers
[t
->owner
].per_tid
[t
->share
].tid
;
1943 run_vusertest_report_full("WRITE", "write 2", False
, False
, &msg
, t
);
1945 msglen
= strlen(msg
)+1;
1947 if (cli_write(&vusers
[t
->as_user
].cli
,
1948 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
], 0, (char *)&msglen
, 0, sizeof(msglen
)) != sizeof(msglen
)) {
1950 run_vusertest_report_failure("WRITE", "write 1", t
);
1952 return should_work
?False
:True
;
1955 if (cli_write(&vusers
[t
->as_user
].cli
,
1956 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
], 0, msg
, sizeof(msglen
), msglen
) != msglen
) {
1958 run_vusertest_report_failure("WRITE", "write 2", t
);
1960 return should_work
?False
:True
;
1963 run_vusertest_report_success("WRITE", "write", t
);
1965 return should_work
?True
:False
;
1968 static BOOL
run_vusertest_op_create_and_write(TABOID
*t
)
1973 if(!run_vusertest_op_create(t
)) {
1978 if(!run_vusertest_op_write(t
)) {
1986 static BOOL
run_vusertest_op_openr(TABOID
*t
)
1989 BOOL should_work
= (vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
&& vusers
[t
->as_user
].vuid_valid
);
1991 vusers
[t
->as_user
].cli
.cnum
= vusers
[t
->owner
].per_tid
[t
->share
].tid
;
1993 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
] =
1994 cli_open(&vusers
[t
->as_user
].cli
, vusers
[t
->owner
].fname
, O_RDONLY
, DENY_NONE
);
1996 if (vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
] == -1) {
1998 run_vusertest_report_failure("OPENR", "open", t
);
2000 return should_work
?False
:True
;
2003 run_vusertest_report_success("OPENR", "open", t
);
2005 vusers
[t
->as_user
].files_valid
= True
; /*not true for all!*/
2007 return should_work
?True
:False
;
2010 static BOOL
run_vusertest_op_read(TABOID
*t
)
2016 BOOL should_work
= (
2017 vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
&&
2018 vusers
[t
->as_user
].vuid_valid
&&
2019 vusers
[t
->as_user
].files_valid
&&
2020 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
] != -1
2023 vusers
[t
->as_user
].cli
.cnum
= vusers
[t
->owner
].per_tid
[t
->share
].tid
;
2025 if (cli_read(&vusers
[t
->as_user
].cli
,
2026 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
], (char *)&msglen
, 0, sizeof(msglen
)) != sizeof(msglen
)) {
2028 run_vusertest_report_failure("READ", "read 1", t
);
2030 return should_work
?False
:True
;
2033 if (cli_read(&vusers
[t
->as_user
].cli
,
2034 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
], msg
, sizeof(msglen
), msglen
) != msglen
) {
2036 run_vusertest_report_failure("READ", "read 2", t
);
2038 return should_work
?False
:True
;
2041 run_vusertest_report_success("READ", "read", t
);
2043 return should_work
?True
:False
;
2046 static BOOL
run_vusertest_op_openr_and_read(TABOID
*t
)
2051 if(!run_vusertest_op_openr(t
)) {
2056 if(!run_vusertest_op_read(t
)) {
2064 static BOOL
run_vusertest_op_backup_open_fids(TABOID
*t
)
2067 memcpy(vusers
[t
->as_user
].per_tid
[t
->share
].backup_fnum
,
2068 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
,
2069 sizeof(vusers
[t
->as_user
].per_tid
[t
->share
].fnum
));
2074 static BOOL
run_vusertest_op_close(TABOID
*t
)
2077 BOOL should_work
= (
2079 vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
&&
2080 vusers
[t
->as_user
].vuid_valid
&&
2081 vusers
[t
->as_user
].files_valid
2085 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
] == -1 &&
2086 vusers
[t
->as_user
].per_tid
[t
->share
].backup_fnum
[t
->owner
] == -1
2090 BOOL ret
= should_work
?True
:False
;
2092 vusers
[t
->as_user
].cli
.cnum
= vusers
[t
->owner
].per_tid
[t
->share
].tid
;
2094 if(vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
] != -1) {
2096 if(!cli_close(&vusers
[t
->as_user
].cli
, vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
])) {
2098 run_vusertest_report_failure("CLOSE", "close", t
);
2100 ret
= should_work
?False
:True
;
2103 run_vusertest_report_success("CLOSE", "close", t
);
2106 vusers
[t
->as_user
].per_tid
[t
->share
].fnum
[t
->owner
] = -1;
2109 if(vusers
[t
->as_user
].per_tid
[t
->share
].backup_fnum
[t
->owner
] != -1 &&
2110 vusers
[t
->as_user
].per_tid
[t
->share
].backup_fnum
[t
->owner
] != 0) {
2112 if(!cli_close(&vusers
[t
->as_user
].cli
, vusers
[t
->as_user
].per_tid
[t
->share
].backup_fnum
[t
->owner
])) {
2114 run_vusertest_report_failure("CLOSE", "close backup", t
);
2116 ret
= should_work
?False
:True
;
2120 run_vusertest_report_success("CLOSE", "close backup", t
);
2123 vusers
[t
->as_user
].per_tid
[t
->share
].backup_fnum
[t
->owner
] = -1;
2129 static BOOL
run_vusertest_op_tcon(TABOID
*t
)
2132 BOOL should_work
= (vusers
[t
->as_user
].vuid_valid
);
2134 vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
= False
;
2136 if (!cli_send_tconX(&vusers
[t
->as_user
].cli
,
2139 vusers
[t
->as_user
].password
,
2140 strlen(vusers
[t
->as_user
].password
)+1)) {
2142 run_vusertest_report_failure("TCON", "tcon", t
);
2144 return should_work
?False
:True
;
2147 vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
= True
;
2148 vusers
[t
->owner
].per_tid
[t
->share
].tid
= vusers
[t
->as_user
].cli
.cnum
;
2150 run_vusertest_report_success("TCON", "tcon", t
);
2152 return should_work
?True
:False
;
2155 static BOOL
run_vusertest_op_tdis(TABOID
*t
)
2158 BOOL should_work
= (vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
&& vusers
[t
->as_user
].vuid_valid
);
2161 if(!vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
) {
2167 vusers
[t
->as_user
].cli
.cnum
= vusers
[t
->owner
].per_tid
[t
->share
].tid
;
2169 if(!cli_tdis(&vusers
[t
->as_user
].cli
)) {
2171 run_vusertest_report_failure("TDIS", "tdis", t
);
2173 return should_work
?False
:True
;
2176 run_vusertest_report_success("TDIS", "tdis", t
);
2178 vusers
[t
->owner
].per_tid
[t
->share
].tid_valid
= False
;
2180 return should_work
?True
:False
;
2183 static BOOL
run_vusertest_op_ulogon(TABOID
*t
)
2186 vusers
[t
->owner
].cli
= *seed
;
2188 vusers
[t
->owner
].vuid_valid
= False
;
2190 if (!cli_session_setup(&vusers
[t
->owner
].cli
,
2191 vusers
[t
->owner
].username
,
2192 vusers
[t
->owner
].password
,
2193 strlen(vusers
[t
->owner
].password
),
2194 vusers
[t
->owner
].password
,
2195 strlen(vusers
[t
->owner
].password
),
2199 run_vusertest_report_failure("ULOGON", "logon", t
);
2204 run_vusertest_report_success("ULOGON", "logon", t
);
2206 vusers
[t
->owner
].vuid_valid
= True
;
2207 vusers
[t
->owner
].vuid
= vusers
[t
->owner
].cli
.vuid
;
2212 static BOOL
run_vusertest_op_ulogoff(TABOID
*t
)
2215 BOOL should_work
= (vusers
[t
->owner
].vuid_valid
);
2218 if(!vusers
[t
->owner
].vuid_valid
) {
2224 if(!cli_ulogoff(&vusers
[t
->owner
].cli
)) {
2226 run_vusertest_report_failure("ULOGOFF", "logoff", t
);
2228 return should_work
?False
:True
;
2231 run_vusertest_report_success("ULOGOFF", "logoff", t
);
2233 vusers
[t
->owner
].vuid_valid
= False
;
2234 vusers
[t
->owner
].files_valid
= False
;
2236 return should_work
?True
:False
;
2239 /***********************************************************/
2240 /***********************************************************/
2242 static BOOL
run_vusertest_owner_op(BOOL (*op
)(TABOID
*t
))
2249 for(; owner
< nusers
; owner
++) {
2252 init_TABOID(&t
, owner
, 0, owner
);
2257 printf("^^^^^^^^^^^^^^^^\n");
2264 static BOOL
run_vusertest_owner_share_op(BOOL (*op
)(TABOID
*t
))
2271 for(; owner
< nusers
; owner
++) {
2275 for(; share
< nshares
; share
++) {
2278 init_TABOID( &t
, owner
, share
, owner
);
2283 printf("^^^^^^^^^^^^^^^^\n");
2291 static BOOL
run_vusertest_owner_share_preop_user_op(
2292 BOOL (*preop
)(TABOID
*t
),
2293 BOOL (*op
)(TABOID
*t
),
2294 BOOL (*postop
)(TABOID
*t
)
2302 for(; owner
< nusers
; owner
++) {
2306 for(; share
< nshares
; share
++) {
2309 init_TABOID( &t
, owner
, share
, owner
);
2314 printf("^^^^^^^^^^^^^^^^\n");
2317 for(t
.as_user
= 0; t
.as_user
< nusers
; t
.as_user
++) {
2323 printf("^^^^^^^^^^^^^^^^\n");
2332 printf("^^^^^^^^^^^^^^^^\n");
2340 static BOOL
run_vusertest_owner_share_user_preop_op(
2341 BOOL (*preop
)(TABOID
*t
),
2342 BOOL (*op
)(TABOID
*t
),
2343 BOOL (*postop
)(TABOID
*t
)
2351 for(; owner
< nusers
; owner
++) {
2355 for(; share
< nshares
; share
++) {
2359 for(; as_user
< nusers
; as_user
++) {
2362 init_TABOID( &t
, owner
, share
, owner
);
2368 printf("^^^^^^^^^^^^^^^^\n");
2371 t
.as_user
= as_user
;
2378 printf("^^^^^^^^^^^^^^^^\n");
2388 printf("^^^^^^^^^^^^^^^^\n");
2399 #define VU_INIT (run_vusertest_owner_op(run_vusertest_op_init))
2401 #define VU_ULOGON (run_vusertest_owner_op(run_vusertest_op_ulogon))
2402 #define VU_ULOGOFF (run_vusertest_owner_op(run_vusertest_op_ulogoff))
2404 /*each user applies op to each of their shares*/
2406 #define VU_TCON (run_vusertest_owner_share_op(run_vusertest_op_tcon))
2407 #define VU_TDIS (run_vusertest_owner_share_op(run_vusertest_op_tdis))
2409 #define VU_CREATE_AND_WRITE (run_vusertest_owner_share_op(run_vusertest_op_create_and_write))
2410 #define VU_OPEN_AND_READ (run_vusertest_owner_share_op(run_vusertest_op_openr_and_read))
2411 #define VU_READ (run_vusertest_owner_share_op(run_vusertest_op_read))
2412 #define VU_FCLOSE (run_vusertest_owner_share_op(run_vusertest_op_close))
2413 #define VU_BACKUP_FIDS (run_vusertest_owner_share_op(run_vusertest_op_backup_open_fids))
2415 /*for u1 for u2 apply op as u2 on u1's tid*/
2417 #define VU_CROSS_READ (run_vusertest_owner_share_preop_user_op(run_vusertest_op_null,\
2418 run_vusertest_op_read,\
2419 run_vusertest_op_null))
2420 #define VU_CROSS_OPEN_AND_READ (run_vusertest_owner_share_preop_user_op(run_vusertest_op_null,\
2421 run_vusertest_op_openr_and_read,\
2422 run_vusertest_op_null))
2423 #define VU_CROSS_FCLOSE (run_vusertest_owner_share_preop_user_op(run_vusertest_op_null,\
2424 run_vusertest_op_close,\
2425 run_vusertest_op_null))
2427 #define VU_TCON_TDIS_OPEN_AND_READ (run_vusertest_owner_share_user_preop_op(run_vusertest_op_tcon,\
2428 run_vusertest_op_tdis,\
2429 run_vusertest_op_openr_and_read))
2434 Check relationship between:
2438 session logoff (Samba closes all files for vuid)
2440 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)
2442 1. can a user access a tid connected by another
2446 u2 opens file on u1's tid
2450 2. can one user disconnect a tid connected by another
2454 connect u1's tid as u1
2455 disconnect u1's tid as u2;
2456 open and read files as u1
2460 2a. does a disconnect by another invalidate the tid for the original connector
2462 3. does a disconnect invalidate a tid with no files open on it
2467 open and read files on u1's tid
2470 4. does a disconnect invalidate a tid with files open on it
2475 open and read files on u1's tid as u1
2478 5. does a disconnect invalidate files open on a tid.
2483 read files on u1's tid as u1
2486 6. can a user session exist with no tid and no open files
2500 7. does a logoff invalidate a tid with no files open on it
2505 open and read files on u1's tid
2511 open and read files on u1's tid
2514 8. does a logoff invalidate a tid with files open on it
2519 open and read files on u1's tid
2524 open and read files on u1's tid
2527 9. does a logoff invalidate a fid.
2532 read files on u1's tid
2537 read files on u1's tid
2541 10. does a logoff invalidate a vuid.
2545 11. can a connection survive close files, close tids, logoff users
2549 disconnect u1's tids
2563 static BOOL
run_vusertest(int dummy
)
2569 seed
= &vusers
[0].cli
;
2573 printf("\nopen nbt connection\n");
2575 if (!open_nbt_connection(seed
)) {
2580 cli_sockopt(seed
, sockops
);
2582 printf("\nnegotiate protocol\n");
2584 /*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*/
2586 if (!cli_negprot(seed
)) {
2587 printf("%s rejected the negprot (%s)\n",host
, cli_errstr(seed
));
2592 printf("\nnegotiate protocol again.\n");
2594 if (!cli_negprot(seed
)) {
2596 printf("%s rejected a second negprot (%s)\n",host
, cli_errstr(seed
));
2598 printf("\nshutdown client\n");
2604 printf("\nopen new nbt session\n");
2606 if (!open_nbt_connection(seed
)) {
2611 cli_sockopt(seed
, sockops
);
2613 printf("\nre negotiate protocol\n");
2615 if (!cli_negprot(seed
)) {
2616 printf("%s rejected the negprot (%s)\n",host
, cli_errstr(seed
));
2622 printf("starting vusertest with %d users and %d shares.\n", nusers
, nshares
);
2624 /***********************************************************/
2625 /***********************************************************/
2627 printf("\ninitialise\n\n");
2631 printf("initialisation failed.\n");
2635 printf("\nsetup sessions\n\n");
2639 printf("setup sessions failed.\n");
2643 printf("\nconnect to shares\n\n");
2647 printf("connect to shares failed.\n");
2651 /***********************************************************/
2652 /***********************************************************/
2656 char *test
= "create and write files";
2659 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2663 if(!VU_CREATE_AND_WRITE
) {
2665 printf("%s failed.\n", test
);
2676 printf("TEST FAILED.\n");
2681 /***********************************************************/
2682 /***********************************************************/
2685 char *test
= "can a user access a tid connected by another?";
2689 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2693 if(!VU_CROSS_OPEN_AND_READ
) {
2698 if(!VU_CROSS_FCLOSE
) {
2705 printf("TEST FAILED.\n");
2710 /***********************************************************/
2711 /***********************************************************/
2714 char *test
= "can one user disconnect a tid connected by another.\n2a does disconnect by another invalidate tid for all?";
2718 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2722 if(!VU_TCON_TDIS_OPEN_AND_READ
) {
2727 if(!VU_CROSS_FCLOSE
) {
2734 printf("TEST FAILED.\n");
2739 /***********************************************************/
2740 /***********************************************************/
2744 char *test
= "does a disconnect invalidate a tid with no files open on it?";
2748 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2762 if(!VU_OPEN_AND_READ
) {
2774 printf("TEST FAILED.\n");
2779 /***********************************************************/
2780 /***********************************************************/
2784 char *test
= "does a disconnect invalidate a tid with files open on it?";
2788 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2797 if(!VU_OPEN_AND_READ
) {
2807 if(!VU_OPEN_AND_READ
) {
2819 printf("TEST FAILED.\n");
2824 /***********************************************************/
2825 /***********************************************************/
2829 char *test
= "does a disconnect invalidate files open on a tid?";
2833 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2842 if(!VU_OPEN_AND_READ
) {
2869 printf("TEST FAILED.\n");
2874 /***********************************************************/
2875 /***********************************************************/
2879 char *test
= "can a user session exist with no tid and no open files?";
2883 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2897 if(!VU_OPEN_AND_READ
) {
2904 printf("TEST FAILED.\n");
2909 /***********************************************************/
2910 /***********************************************************/
2914 char *test
= "does a logoff invalidate a tid with no files open on it?";
2918 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2932 if(!VU_OPEN_AND_READ
) {
2947 if(!VU_OPEN_AND_READ
) {
2969 printf("TEST FAILED.\n");
2974 /***********************************************************/
2975 /***********************************************************/
2978 char *test
= "does a logoff invalidate a tid with files open on it?";
2982 printf("\nTEST:%d %s\n\n", testcnt
, test
);
2986 if(!VU_OPEN_AND_READ
) {
2996 if(!VU_OPEN_AND_READ
) {
3006 if(!VU_OPEN_AND_READ
) {
3028 printf("TEST FAILED.\n");
3033 /***********************************************************/
3034 /***********************************************************/
3037 char *test
= "does a logoff invalidate a fid?";
3040 printf("\nTEST:%d %s\n\n", testcnt
, test
);
3044 if(!VU_OPEN_AND_READ
) {
3086 printf("TEST FAILED.\n");
3091 /***********************************************************/
3092 /***********************************************************/
3094 printf("\nTEST:%d does a logoff invalidate a vuid? see 8.\n\n", testcnt
);
3098 /***********************************************************/
3099 /***********************************************************/
3102 char *test
= "can a connection survive close files, disconnect tids, logoff users?";
3105 printf("\nTEST:%d %s\n\n", testcnt
, test
);
3134 if(!VU_OPEN_AND_READ
) {
3141 printf("TEST FAILED.\n");
3146 /***********************************************************/
3147 /***********************************************************/
3150 char *test
= "clean up.";
3153 printf("\nTEST:%s\n\n", test
);
3155 if(!VU_CROSS_FCLOSE
) {
3172 printf("TEST FAILED.\n");
3179 printf("finished vusertest.\n");
3184 This test checks that
3186 1) the server does not allow an unlink on a file that is open
3188 static BOOL
run_unlinktest(int dummy
)
3190 static struct cli_state cli
;
3191 char *fname
= "\\unlink.tst";
3193 BOOL correct
= True
;
3195 if (!open_connection(&cli
)) {
3199 cli_sockopt(&cli
, sockops
);
3201 printf("starting unlink test\n");
3203 cli_unlink(&cli
, fname
);
3205 cli_setpid(&cli
, 1);
3207 fnum
= cli_open(&cli
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
3209 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli
));
3213 if (cli_unlink(&cli
, fname
)) {
3214 printf("error: server allowed unlink on an open file\n");
3218 cli_close(&cli
, fnum
);
3219 cli_unlink(&cli
, fname
);
3221 if (!close_connection(&cli
)) {
3225 printf("unlink test finished\n");
3232 test how many open files this server supports on the one socket
3234 static BOOL
run_maxfidtest(int dummy
)
3236 static struct cli_state cli
;
3237 char *template = "\\maxfid.%d.%d";
3241 BOOL correct
= True
;
3246 printf("failed to connect\n");
3250 cli_sockopt(&cli
, sockops
);
3254 slprintf(fname
,sizeof(fname
)-1,template, fnum
,(int)getpid());
3255 if (cli_open(&cli
, fname
,
3256 O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
) ==
3258 printf("open of %s failed (%s)\n",
3259 fname
, cli_errstr(&cli
));
3260 printf("maximum fnum is %d\n", fnum
);
3264 if (fnum
% 100 == 0) printf("%d\r", fnum
);
3266 printf("%d\n", fnum
);
3268 printf("cleaning up\n");
3271 slprintf(fname
,sizeof(fname
)-1,template, fnum
,(int)getpid());
3272 cli_close(&cli
, fnum
);
3273 if (!cli_unlink(&cli
, fname
)) {
3274 printf("unlink of %s failed (%s)\n",
3275 fname
, cli_errstr(&cli
));
3280 printf("maxfid test finished\n");
3281 if (!close_connection(&cli
)) {
3287 /* generate a random buffer */
3288 static void rand_buf(char *buf
, int len
)
3291 *buf
= (char)sys_random();
3296 /* send smb negprot commands, not reading the response */
3297 static BOOL
run_negprot_nowait(int dummy
)
3300 static struct cli_state cli
;
3301 BOOL correct
= True
;
3303 printf("starting negprot nowait test\n");
3305 if (!open_nbt_connection(&cli
)) {
3309 for (i
=0;i
<50000;i
++) {
3310 cli_negprot_send(&cli
);
3313 if (!close_connection(&cli
)) {
3317 printf("finished negprot nowait test\n");
3323 /* send random IPC commands */
3324 static BOOL
run_randomipc(int dummy
)
3326 char *rparam
= NULL
;
3330 int api
, param_len
, i
;
3331 static struct cli_state cli
;
3332 BOOL correct
= True
;
3334 printf("starting random ipc test\n");
3336 if (!open_connection(&cli
)) {
3340 for (i
=0;i
<50000;i
++) {
3341 api
= sys_random() % 500;
3342 param_len
= (sys_random() % 64);
3344 rand_buf(param
, param_len
);
3349 param
, param_len
, 8,
3350 NULL
, 0, BUFFER_SIZE
,
3355 if (!close_connection(&cli
)) {
3359 printf("finished random ipc test\n");
3366 static void browse_callback(const char *sname
, uint32 stype
,
3367 const char *comment
, void *state
)
3369 printf("\t%20.20s %08x %s\n", sname
, stype
, comment
);
3375 This test checks the browse list code
3378 static BOOL
run_browsetest(int dummy
)
3380 static struct cli_state cli
;
3381 BOOL correct
= True
;
3383 printf("starting browse test\n");
3385 if (!open_connection(&cli
)) {
3389 printf("domain list:\n");
3390 cli_NetServerEnum(&cli
, cli
.server_domain
,
3391 SV_TYPE_DOMAIN_ENUM
,
3392 browse_callback
, NULL
);
3394 printf("machine list:\n");
3395 cli_NetServerEnum(&cli
, cli
.server_domain
,
3397 browse_callback
, NULL
);
3399 if (!close_connection(&cli
)) {
3403 printf("browse test finished\n");
3411 This checks how the getatr calls works
3413 static BOOL
run_attrtest(int dummy
)
3415 static struct cli_state cli
;
3418 char *fname
= "\\attrib.tst";
3419 BOOL correct
= True
;
3421 printf("starting attrib test\n");
3423 if (!open_connection(&cli
)) {
3427 cli_unlink(&cli
, fname
);
3428 fnum
= cli_open(&cli
, fname
,
3429 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
3430 cli_close(&cli
, fnum
);
3431 if (!cli_getatr(&cli
, fname
, NULL
, NULL
, &t
)) {
3432 printf("getatr failed (%s)\n", cli_errstr(&cli
));
3436 if (abs(t
- time(NULL
)) > 2) {
3437 printf("ERROR: SMBgetatr bug. time is %s",
3443 t2
= t
-60*60*24; /* 1 day ago */
3445 if (!cli_setatr(&cli
, fname
, 0, t2
)) {
3446 printf("setatr failed (%s)\n", cli_errstr(&cli
));
3450 if (!cli_getatr(&cli
, fname
, NULL
, NULL
, &t
)) {
3451 printf("getatr failed (%s)\n", cli_errstr(&cli
));
3456 printf("ERROR: getatr/setatr bug. times are\n%s",
3458 printf("%s", ctime(&t2
));
3462 cli_unlink(&cli
, fname
);
3464 if (!close_connection(&cli
)) {
3468 printf("attrib test finished\n");
3475 This checks a couple of trans2 calls
3477 static BOOL
run_trans2test(int dummy
)
3479 static struct cli_state cli
;
3482 time_t c_time
, a_time
, m_time
, w_time
, m_time2
;
3483 char *fname
= "\\trans2.tst";
3484 char *dname
= "\\trans2";
3485 char *fname2
= "\\trans2\\trans2.tst";
3486 BOOL correct
= True
;
3488 printf("starting trans2 test\n");
3490 if (!open_connection(&cli
)) {
3494 cli_unlink(&cli
, fname
);
3495 fnum
= cli_open(&cli
, fname
,
3496 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
3497 if (!cli_qfileinfo(&cli
, fnum
, NULL
, &size
, &c_time
, &a_time
, &m_time
,
3499 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli
));
3502 cli_close(&cli
, fnum
);
3506 cli_unlink(&cli
, fname
);
3507 fnum
= cli_open(&cli
, fname
,
3508 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
3510 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli
));
3513 cli_close(&cli
, fnum
);
3515 if (!cli_qpathinfo(&cli
, fname
, &c_time
, &a_time
, &m_time
, &size
, NULL
)) {
3516 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli
));
3519 if (c_time
!= m_time
) {
3520 printf("create time=%s", ctime(&c_time
));
3521 printf("modify time=%s", ctime(&m_time
));
3522 printf("This system appears to have sticky create times\n");
3525 if (a_time
% (60*60) == 0) {
3526 printf("access time=%s", ctime(&a_time
));
3527 printf("This system appears to set a midnight access time\n");
3531 if (abs(m_time
- time(NULL
)) > 60*60*24*7) {
3532 printf("ERROR: totally incorrect times - maybe word reversed?\n");
3538 cli_unlink(&cli
, fname
);
3539 fnum
= cli_open(&cli
, fname
,
3540 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
3541 cli_close(&cli
, fnum
);
3542 if (!cli_qpathinfo2(&cli
, fname
, &c_time
, &a_time
, &m_time
,
3543 &w_time
, &size
, NULL
, NULL
)) {
3544 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli
));
3547 if (w_time
< 60*60*24*2) {
3548 printf("write time=%s", ctime(&w_time
));
3549 printf("This system appears to set a initial 0 write time\n");
3554 cli_unlink(&cli
, fname
);
3557 /* check if the server updates the directory modification time
3558 when creating a new file */
3559 if (!cli_mkdir(&cli
, dname
)) {
3560 printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli
));
3564 if (!cli_qpathinfo2(&cli
, "\\trans2\\", &c_time
, &a_time
, &m_time
,
3565 &w_time
, &size
, NULL
, NULL
)) {
3566 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli
));
3570 fnum
= cli_open(&cli
, fname2
,
3571 O_RDWR
| O_CREAT
| O_TRUNC
, DENY_NONE
);
3572 cli_write(&cli
, fnum
, 0, (char *)&fnum
, 0, sizeof(fnum
));
3573 cli_close(&cli
, fnum
);
3574 if (!cli_qpathinfo2(&cli
, "\\trans2\\", &c_time
, &a_time
, &m_time2
,
3575 &w_time
, &size
, NULL
, NULL
)) {
3576 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli
));
3579 if (m_time2
== m_time
) {
3580 printf("This system does not update directory modification times\n");
3584 cli_unlink(&cli
, fname2
);
3585 cli_rmdir(&cli
, dname
);
3587 if (!close_connection(&cli
)) {
3591 printf("trans2 test finished\n");
3597 This checks new W2K calls.
3600 static BOOL
new_trans(struct cli_state
*pcli
, int fnum
, int level
)
3603 BOOL correct
= True
;
3605 memset(buf
, 0xff, sizeof(buf
));
3607 if (!cli_qfileinfo_test(pcli
, fnum
, level
, buf
)) {
3608 printf("ERROR: qfileinfo (%d) failed (%s)\n", level
, cli_errstr(pcli
));
3611 printf("qfileinfo: level %d\n", level
);
3612 dump_data(0, buf
, 256);
3618 /****************************************************************************
3619 Set or clear the delete on close flag.
3620 ****************************************************************************/
3622 int cli_setfileinfo_test(struct cli_state
*cli
, int fnum
, int level
, char *data
, int data_len
)
3625 uint16 setup
= TRANSACT2_SETFILEINFO
;
3627 char *rparam
=NULL
, *rdata
=NULL
;
3629 memset(param
, 0, param_len
);
3630 SSVAL(param
,0,fnum
);
3631 SSVAL(param
,2,level
);
3633 if (!cli_send_trans(cli
, SMBtrans2
,
3635 -1, 0, /* fid, flags */
3636 &setup
, 1, 0, /* setup, length, max */
3637 param
, param_len
, 2, /* param, length, max */
3638 data
, data_len
, cli
->max_xmit
/* data, length, max */
3643 if (!cli_receive_trans(cli
, SMBtrans2
,
3644 &rparam
, ¶m_len
,
3645 &rdata
, &data_len
)) {
3649 if (rdata
) free(rdata
);
3650 if (rparam
) free(rparam
);
3655 static BOOL
run_w2ktest(int dummy
)
3657 static struct cli_state cli
;
3659 char *fname
= "\\w2ktest\\w2k.tst";
3660 char *fname1
= "\\w2ktest\\w2k.dir";
3663 BOOL correct
= True
;
3665 printf("starting w2k test\n");
3667 if (!open_connection(&cli
)) {
3671 fnum
= cli_open(&cli
, fname
,
3672 O_RDWR
| O_CREAT
, DENY_NONE
);
3674 for (level
= 1004; level
< 1040; level
++) {
3675 new_trans(&cli
, fnum
, level
);
3678 cli_close(&cli
, fnum
);
3679 cli_unlink(&cli
, fname
);
3681 /* Check the strange 1013 setinfo call. */
3682 cli_mkdir(&cli
, fname1
);
3683 fnum
= cli_nt_create_full( &cli
, fname1
, 0x60080, 0, 7,
3687 if (!cli_setfileinfo_test( &cli
, fnum
, 1013, &data
, 1)) {
3688 printf("setfileinfo test 1 failed with %s\n", cli_errstr(&cli
));
3691 if (!cli_setfileinfo_test( &cli
, fnum
, 1013, &data
, 1)) {
3692 printf("setfileinfo test 2 failed with %s\n", cli_errstr(&cli
));
3695 cli_close(&cli
, fnum
);
3696 cli_rmdir(&cli
, fname1
);
3698 fnum
= cli_open(&cli
, fname
, O_RDWR
| O_CREAT
, DENY_NONE
);
3700 cli_write(&cli
, fnum
, 0, (char *)&data
, 0, sizeof(data
));
3701 cli_close(&cli
, fnum
);
3704 fnum
= cli_open(&cli
, fname
, O_RDWR
, DENY_NONE
);
3705 if (cli_read(&cli
, fnum
, &data
, 0, 1) != 1) {
3706 printf("x test 2 failed with %s\n", cli_errstr(&cli
));
3708 cli_close(&cli
, fnum
);
3709 cli_unlink(&cli
, fname
);
3711 if (!close_connection(&cli
)) {
3715 printf("w2k test finished\n");
3722 this is a harness for some oplock tests
3724 static BOOL
run_oplock1(int dummy
)
3726 static struct cli_state cli1
;
3727 char *fname
= "\\lockt1.lck";
3729 BOOL correct
= True
;
3731 printf("starting oplock test 1\n");
3733 if (!open_connection(&cli1
)) {
3737 cli_unlink(&cli1
, fname
);
3739 cli_sockopt(&cli1
, sockops
);
3741 cli1
.use_oplocks
= True
;
3743 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
3745 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
3749 cli1
.use_oplocks
= False
;
3751 cli_unlink(&cli1
, fname
);
3752 cli_unlink(&cli1
, fname
);
3754 if (!cli_close(&cli1
, fnum1
)) {
3755 printf("close2 failed (%s)\n", cli_errstr(&cli1
));
3759 if (!cli_unlink(&cli1
, fname
)) {
3760 printf("unlink failed (%s)\n", cli_errstr(&cli1
));
3764 if (!close_connection(&cli1
)) {
3768 printf("finished oplock test 1\n");
3773 static BOOL
run_oplock2(int dummy
)
3775 static struct cli_state cli1
, cli2
;
3776 char *fname
= "\\lockt2.lck";
3778 int saved_use_oplocks
= use_oplocks
;
3780 BOOL correct
= True
;
3781 volatile BOOL
*shared_correct
;
3783 shared_correct
= (volatile BOOL
*)shm_setup(sizeof(BOOL
));
3784 *shared_correct
= True
;
3786 use_level_II_oplocks
= True
;
3789 printf("starting oplock test 2\n");
3791 if (!open_connection(&cli1
)) {
3792 use_level_II_oplocks
= False
;
3793 use_oplocks
= saved_use_oplocks
;
3797 cli1
.use_oplocks
= True
;
3798 cli1
.use_level_II_oplocks
= True
;
3800 if (!open_connection(&cli2
)) {
3801 use_level_II_oplocks
= False
;
3802 use_oplocks
= saved_use_oplocks
;
3806 cli2
.use_oplocks
= True
;
3807 cli2
.use_level_II_oplocks
= True
;
3809 cli_unlink(&cli1
, fname
);
3811 cli_sockopt(&cli1
, sockops
);
3812 cli_sockopt(&cli2
, sockops
);
3814 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
3816 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
3820 /* Don't need the globals any more. */
3821 use_level_II_oplocks
= False
;
3822 use_oplocks
= saved_use_oplocks
;
3826 fnum2
= cli_open(&cli2
, fname
, O_RDWR
, DENY_NONE
);
3828 printf("second open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
3829 *shared_correct
= False
;
3835 if (!cli_close(&cli2
, fnum2
)) {
3836 printf("close2 failed (%s)\n", cli_errstr(&cli1
));
3837 *shared_correct
= False
;
3845 /* Ensure cli1 processes the break. */
3847 if (cli_read(&cli1
, fnum1
, buf
, 0, 4) != 4) {
3848 printf("read on fnum1 failed (%s)\n", cli_errstr(&cli1
));
3852 /* Should now be at level II. */
3853 /* Test if sending a write locks causes a break to none. */
3855 if (!cli_lock(&cli1
, fnum1
, 0, 4, 0, READ_LOCK
)) {
3856 printf("lock failed (%s)\n", cli_errstr(&cli1
));
3860 cli_unlock(&cli1
, fnum1
, 0, 4);
3864 if (!cli_lock(&cli1
, fnum1
, 0, 4, 0, WRITE_LOCK
)) {
3865 printf("lock failed (%s)\n", cli_errstr(&cli1
));
3869 cli_unlock(&cli1
, fnum1
, 0, 4);
3873 cli_read(&cli1
, fnum1
, buf
, 0, 4);
3876 if (cli_write(&cli1
, fnum1
, 0, buf
, 0, 4) != 4) {
3877 printf("write on fnum1 failed (%s)\n", cli_errstr(&cli1
));
3882 if (!cli_close(&cli1
, fnum1
)) {
3883 printf("close1 failed (%s)\n", cli_errstr(&cli1
));
3889 if (!cli_unlink(&cli1
, fname
)) {
3890 printf("unlink failed (%s)\n", cli_errstr(&cli1
));
3894 if (!close_connection(&cli1
)) {
3898 if (!*shared_correct
) {
3902 printf("finished oplock test 2\n");
3909 Test delete on close semantics.
3911 static BOOL
run_deletetest(int dummy
)
3913 static struct cli_state cli1
;
3914 static struct cli_state cli2
;
3915 char *fname
= "\\delete.file";
3917 BOOL correct
= True
;
3919 printf("starting delete test\n");
3921 if (!open_connection(&cli1
)) {
3925 cli_sockopt(&cli1
, sockops
);
3927 /* Test 1 - this should *NOT* delete the file on close. */
3929 cli_setatr(&cli1
, fname
, 0, 0);
3930 cli_unlink(&cli1
, fname
);
3932 fnum1
= cli_nt_create_full(&cli1
, fname
, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3933 FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, DELETE_ON_CLOSE_FLAG
);
3936 printf("[1] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
3940 if (!cli_close(&cli1
, fnum1
)) {
3941 printf("[1] close failed (%s)\n", cli_errstr(&cli1
));
3945 fnum1
= cli_open(&cli1
, fname
, O_RDWR
, DENY_NONE
);
3947 printf("[1] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
3951 if (!cli_close(&cli1
, fnum1
)) {
3952 printf("[1] close failed (%s)\n", cli_errstr(&cli1
));
3956 printf("first delete on close test succeeded.\n");
3958 /* Test 2 - this should delete the file on close. */
3960 cli_setatr(&cli1
, fname
, 0, 0);
3961 cli_unlink(&cli1
, fname
);
3963 fnum1
= cli_nt_create_full(&cli1
, fname
, GENERIC_ALL_ACCESS
,
3964 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_NONE
, FILE_OVERWRITE_IF
, 0);
3967 printf("[2] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
3971 if (!cli_nt_delete_on_close(&cli1
, fnum1
, True
)) {
3972 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1
));
3976 if (!cli_close(&cli1
, fnum1
)) {
3977 printf("[2] close failed (%s)\n", cli_errstr(&cli1
));
3981 fnum1
= cli_open(&cli1
, fname
, O_RDONLY
, DENY_NONE
);
3983 printf("[2] open of %s succeeded should have been deleted on close !\n", fname
);
3984 if (!cli_close(&cli1
, fnum1
)) {
3985 printf("[2] close failed (%s)\n", cli_errstr(&cli1
));
3988 cli_unlink(&cli1
, fname
);
3990 printf("second delete on close test succeeded.\n");
3994 cli_setatr(&cli1
, fname
, 0, 0);
3995 cli_unlink(&cli1
, fname
);
3997 fnum1
= cli_nt_create_full(&cli1
, fname
, GENERIC_ALL_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
3998 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0);
4001 printf("[3] open - 1 of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4005 /* This should fail with a sharing violation - open for delete is only compatible
4006 with SHARE_DELETE. */
4008 fnum2
= cli_nt_create_full(&cli1
, fname
, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4009 FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OPEN
, 0);
4012 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname
);
4016 /* This should succeed. */
4018 fnum2
= cli_nt_create_full(&cli1
, fname
, GENERIC_READ_ACCESS
, FILE_ATTRIBUTE_NORMAL
,
4019 FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0);
4022 printf("[3] open - 2 of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4026 if (!cli_nt_delete_on_close(&cli1
, fnum1
, True
)) {
4027 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1
));
4031 if (!cli_close(&cli1
, fnum1
)) {
4032 printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1
));
4036 if (!cli_close(&cli1
, fnum2
)) {
4037 printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1
));
4041 /* This should fail - file should no longer be there. */
4043 fnum1
= cli_open(&cli1
, fname
, O_RDONLY
, DENY_NONE
);
4045 printf("[3] open of %s succeeded should have been deleted on close !\n", fname
);
4046 if (!cli_close(&cli1
, fnum1
)) {
4047 printf("[3] close failed (%s)\n", cli_errstr(&cli1
));
4049 cli_unlink(&cli1
, fname
);
4052 printf("third delete on close test succeeded.\n");
4055 cli_setatr(&cli1
, fname
, 0, 0);
4056 cli_unlink(&cli1
, fname
);
4058 fnum1
= cli_nt_create_full(&cli1
, fname
, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4059 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
, FILE_OVERWRITE_IF
, 0);
4062 printf("[4] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4066 /* This should succeed. */
4067 fnum2
= cli_nt_create_full(&cli1
, fname
, GENERIC_READ_ACCESS
,
4068 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0);
4070 printf("[4] open - 2 of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4074 if (!cli_close(&cli1
, fnum2
)) {
4075 printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1
));
4079 if (!cli_nt_delete_on_close(&cli1
, fnum1
, True
)) {
4080 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1
));
4084 /* This should fail - no more opens once delete on close set. */
4085 fnum2
= cli_nt_create_full(&cli1
, fname
, GENERIC_READ_ACCESS
,
4086 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0);
4088 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname
);
4091 printf("fourth delete on close test succeeded.\n");
4093 if (!cli_close(&cli1
, fnum1
)) {
4094 printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1
));
4099 cli_setatr(&cli1
, fname
, 0, 0);
4100 cli_unlink(&cli1
, fname
);
4102 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
4104 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4108 /* This should fail - only allowed on NT opens with DELETE access. */
4110 if (cli_nt_delete_on_close(&cli1
, fnum1
, True
)) {
4111 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4115 if (!cli_close(&cli1
, fnum1
)) {
4116 printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1
));
4120 printf("fifth delete on close test succeeded.\n");
4123 cli_setatr(&cli1
, fname
, 0, 0);
4124 cli_unlink(&cli1
, fname
);
4126 fnum1
= cli_nt_create_full(&cli1
, fname
, FILE_READ_DATA
|FILE_WRITE_DATA
,
4127 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
,
4128 FILE_OVERWRITE_IF
, 0);
4131 printf("[6] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4135 /* This should fail - only allowed on NT opens with DELETE access. */
4137 if (cli_nt_delete_on_close(&cli1
, fnum1
, True
)) {
4138 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4142 if (!cli_close(&cli1
, fnum1
)) {
4143 printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1
));
4147 printf("sixth delete on close test succeeded.\n");
4150 cli_setatr(&cli1
, fname
, 0, 0);
4151 cli_unlink(&cli1
, fname
);
4153 fnum1
= cli_nt_create_full(&cli1
, fname
, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4154 FILE_ATTRIBUTE_NORMAL
, 0, FILE_OVERWRITE_IF
, 0);
4157 printf("[7] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4161 if (!cli_nt_delete_on_close(&cli1
, fnum1
, True
)) {
4162 printf("[7] setting delete_on_close on file failed !\n");
4166 if (!cli_nt_delete_on_close(&cli1
, fnum1
, False
)) {
4167 printf("[7] unsetting delete_on_close on file failed !\n");
4171 if (!cli_close(&cli1
, fnum1
)) {
4172 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1
));
4176 /* This next open should succeed - we reset the flag. */
4178 fnum1
= cli_open(&cli1
, fname
, O_RDONLY
, DENY_NONE
);
4180 printf("[5] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4184 if (!cli_close(&cli1
, fnum1
)) {
4185 printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1
));
4189 printf("seventh delete on close test succeeded.\n");
4192 cli_setatr(&cli1
, fname
, 0, 0);
4193 cli_unlink(&cli1
, fname
);
4195 if (!open_connection(&cli2
)) {
4196 printf("[8] failed to open second connection.\n");
4200 cli_sockopt(&cli1
, sockops
);
4202 fnum1
= cli_nt_create_full(&cli1
, fname
, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4203 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OVERWRITE_IF
, 0);
4206 printf("[8] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4210 fnum2
= cli_nt_create_full(&cli2
, fname
, FILE_READ_DATA
|FILE_WRITE_DATA
|DELETE_ACCESS
,
4211 FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
|FILE_SHARE_WRITE
|FILE_SHARE_DELETE
, FILE_OPEN
, 0);
4214 printf("[8] open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4218 if (!cli_nt_delete_on_close(&cli1
, fnum1
, True
)) {
4219 printf("[8] setting delete_on_close on file failed !\n");
4223 if (!cli_close(&cli1
, fnum1
)) {
4224 printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1
));
4228 if (!cli_close(&cli2
, fnum2
)) {
4229 printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2
));
4233 /* This should fail.. */
4234 fnum1
= cli_open(&cli1
, fname
, O_RDONLY
, DENY_NONE
);
4236 printf("[8] open of %s succeeded should have been deleted on close !\n", fname
);
4237 if (!cli_close(&cli1
, fnum1
)) {
4238 printf("[8] close failed (%s)\n", cli_errstr(&cli1
));
4240 cli_unlink(&cli1
, fname
);
4243 printf("eighth delete on close test succeeded.\n");
4245 printf("finished delete test\n");
4247 cli_setatr(&cli1
, fname
, 0, 0);
4248 cli_unlink(&cli1
, fname
);
4250 if (!close_connection(&cli1
)) {
4253 if (!close_connection(&cli2
)) {
4260 Test open mode returns on read-only files.
4262 static BOOL
run_opentest(int dummy
)
4264 static struct cli_state cli1
;
4265 char *fname
= "\\readonly.file";
4271 BOOL correct
= True
;
4273 printf("starting open test\n");
4275 if (!open_connection(&cli1
)) {
4279 cli_setatr(&cli1
, fname
, 0, 0);
4280 cli_unlink(&cli1
, fname
);
4282 cli_sockopt(&cli1
, sockops
);
4284 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
4286 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4290 if (!cli_close(&cli1
, fnum1
)) {
4291 printf("close2 failed (%s)\n", cli_errstr(&cli1
));
4295 if (!cli_setatr(&cli1
, fname
, aRONLY
, 0)) {
4296 printf("cli_setatr failed (%s)\n", cli_errstr(&cli1
));
4300 fnum1
= cli_open(&cli1
, fname
, O_RDONLY
, DENY_WRITE
);
4302 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4306 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4307 fnum2
= cli_open(&cli1
, fname
, O_RDWR
, DENY_ALL
);
4309 cli_dos_error( &cli1
, &eclass
, &errnum
);
4311 if (eclass
!= ERRDOS
|| errnum
!= ERRnoaccess
) {
4312 printf("wrong error code (%x,%x) = %s\n", (unsigned int)eclass
,
4313 (unsigned int)errnum
, cli_errstr(&cli1
) );
4316 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4320 printf("finished open test 1\n");
4322 cli_close(&cli1
, fnum1
);
4324 /* Now try not readonly and ensure ERRbadshare is returned. */
4326 cli_setatr(&cli1
, fname
, 0, 0);
4328 fnum1
= cli_open(&cli1
, fname
, O_RDONLY
, DENY_WRITE
);
4330 printf("open of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4334 /* This will fail - but the error should be ERRshare. */
4335 fnum2
= cli_open(&cli1
, fname
, O_RDWR
, DENY_ALL
);
4337 cli_dos_error( &cli1
, &eclass
, &errnum
);
4339 if (eclass
!= ERRDOS
|| errnum
!= ERRbadshare
) {
4340 printf("wrong error code (%x,%x) = %s\n", (unsigned int)eclass
,
4341 (unsigned int)errnum
, cli_errstr(&cli1
) );
4344 printf("correct error code ERRDOS/ERRbadshare returned\n");
4347 if (!cli_close(&cli1
, fnum1
)) {
4348 printf("close2 failed (%s)\n", cli_errstr(&cli1
));
4352 cli_unlink(&cli1
, fname
);
4354 printf("finished open test 2\n");
4356 /* Test truncate open disposition on file opened for read. */
4358 fnum1
= cli_open(&cli1
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
4360 printf("(3) open (1) of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4364 /* write 20 bytes. */
4366 memset(buf
, '\0', 20);
4368 if (cli_write(&cli1
, fnum1
, 0, buf
, 0, 20) != 20) {
4369 printf("write failed (%s)\n", cli_errstr(&cli1
));
4373 if (!cli_close(&cli1
, fnum1
)) {
4374 printf("(3) close1 failed (%s)\n", cli_errstr(&cli1
));
4378 /* Ensure size == 20. */
4379 if (!cli_getatr(&cli1
, fname
, NULL
, &fsize
, NULL
)) {
4380 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1
));
4385 printf("(3) file size != 20\n");
4389 /* Now test if we can truncate a file opened for readonly. */
4391 fnum1
= cli_open(&cli1
, fname
, O_RDONLY
|O_TRUNC
, DENY_NONE
);
4393 printf("(3) open (2) of %s failed (%s)\n", fname
, cli_errstr(&cli1
));
4397 if (!cli_close(&cli1
, fnum1
)) {
4398 printf("close2 failed (%s)\n", cli_errstr(&cli1
));
4402 /* Ensure size == 0. */
4403 if (!cli_getatr(&cli1
, fname
, NULL
, &fsize
, NULL
)) {
4404 printf("(3) getatr failed (%s)\n", cli_errstr(&cli1
));
4409 printf("(3) file size != 0\n");
4412 printf("finished open test 3\n");
4414 cli_unlink(&cli1
, fname
);
4417 printf("testing ctemp\n");
4420 fnum1
= cli_ctemp(&cli1
, "\\", &tmp_path
);
4422 printf("ctemp failed (%s)\n", cli_errstr(&cli1
));
4425 printf("ctemp gave path %s\n", tmp_path
);
4426 cli_close(&cli1
, fnum1
);
4427 cli_unlink(&cli1
, tmp_path
);
4430 if (!close_connection(&cli1
)) {
4437 static void list_fn(file_info
*finfo
, const char *name
, void *state
)
4443 test directory listing speed
4445 static BOOL
run_dirtest(int dummy
)
4448 static struct cli_state cli
;
4451 BOOL correct
= True
;
4453 printf("starting directory test\n");
4455 if (!open_connection(&cli
)) {
4459 cli_sockopt(&cli
, sockops
);
4462 for (i
=0;i
<numops
;i
++) {
4464 slprintf(fname
, sizeof(fname
), "%x", (int)random());
4465 fnum
= cli_open(&cli
, fname
, O_RDWR
|O_CREAT
, DENY_NONE
);
4467 fprintf(stderr
,"Failed to open %s\n", fname
);
4470 cli_close(&cli
, fnum
);
4475 printf("Matched %d\n", cli_list(&cli
, "a*.*", 0, list_fn
, NULL
));
4476 printf("Matched %d\n", cli_list(&cli
, "b*.*", 0, list_fn
, NULL
));
4477 printf("Matched %d\n", cli_list(&cli
, "xyzabc", 0, list_fn
, NULL
));
4479 printf("dirtest core %g seconds\n", end_timer() - t1
);
4482 for (i
=0;i
<numops
;i
++) {
4484 slprintf(fname
, sizeof(fname
), "%x", (int)random());
4485 cli_unlink(&cli
, fname
);
4488 if (!close_connection(&cli
)) {
4492 printf("finished dirtest\n");
4497 static double create_procs(BOOL (*fn
)(int), BOOL
*result
)
4500 volatile pid_t
*child_status
;
4501 volatile BOOL
*child_status_out
;
4507 child_status
= (volatile pid_t
*)shm_setup(sizeof(pid_t
)*nprocs
);
4508 if (!child_status
) {
4509 printf("Failed to setup shared memory\n");
4513 child_status_out
= (volatile BOOL
*)shm_setup(sizeof(BOOL
)*nprocs
);
4514 if (!child_status_out
) {
4515 printf("Failed to setup result status shared memory\n");
4519 memset(child_status
, 0, sizeof(pid_t
)*nprocs
);
4520 memset(child_status_out
, True
, sizeof(BOOL
)*nprocs
);
4524 for (i
=0;i
<nprocs
;i
++) {
4527 pid_t mypid
= getpid();
4528 sys_srandom(((int)mypid
) ^ ((int)time(NULL
)));
4530 slprintf(myname
,sizeof(myname
),"CLIENT%d", i
);
4533 memset(¤t_cli
, 0, sizeof(current_cli
));
4534 if (open_connection(¤t_cli
)) break;
4536 printf("pid %d failed to start\n", (int)getpid());
4542 child_status
[i
] = getpid();
4544 while (child_status
[i
]) msleep(2);
4546 child_status_out
[i
] = fn(i
);
4553 for (i
=0;i
<nprocs
;i
++) {
4554 if (child_status
[i
]) synccount
++;
4556 if (synccount
== nprocs
) break;
4558 } while (end_timer() < 30);
4560 if (synccount
!= nprocs
) {
4561 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs
, synccount
);
4566 /* start the client load */
4569 for (i
=0;i
<nprocs
;i
++) {
4570 child_status
[i
] = 0;
4573 printf("%d clients started\n", nprocs
);
4575 for (i
=0;i
<nprocs
;i
++) {
4576 waitpid(0, &status
, 0);
4582 for (i
=0;i
<nprocs
;i
++) {
4583 if (!child_status_out
[i
]) {
4591 #define FLAG_MULTIPROC (1<<0)
4592 #define FLAG_MULTIUSER (1<<1)
4593 #define FLAG_MULTISHARE (1<<2)
4594 #define FLAG_PROBE (1<<3)
4601 {"FDPASS", run_fdpasstest
, 0},
4602 {"LOCK1", run_locktest1
, 0},
4603 {"LOCK2", run_locktest2
, 0},
4604 {"LOCK3", run_locktest3
, 0},
4605 {"LOCK4", run_locktest4
, 0},
4606 {"LOCK5", run_locktest5
, 0},
4607 {"UNLINK", run_unlinktest
, 0},
4608 {"BROWSE", run_browsetest
, 0},
4609 {"ATTR", run_attrtest
, 0},
4610 {"TRANS2", run_trans2test
, 0},
4611 {"MAXFID", run_maxfidtest
, FLAG_MULTIPROC
},
4612 {"TORTURE",run_torture
, FLAG_MULTIPROC
},
4613 {"RANDOMIPC", run_randomipc
, 0},
4614 {"NEGNOWAIT", run_negprot_nowait
, 0},
4615 {"NBW95", run_nbw95
, 0},
4616 {"NBWNT", run_nbwnt
, 0},
4617 {"OPLOCK1", run_oplock1
, 0},
4618 {"OPLOCK2", run_oplock2
, 0},
4619 {"DIR", run_dirtest
, 0},
4620 {"DENY1", run_denytest1
, 0},
4621 {"DENY2", run_denytest2
, 0},
4622 {"TCON", run_tcon_test
, 0},
4623 {"RW1", run_readwritetest
, 0},
4624 {"RW2", run_readwritemulti
, FLAG_MULTIPROC
},
4625 {"RW3", run_readwritelarge
, 0},
4626 {"OPEN", run_opentest
, 0},
4627 {"DELETE", run_deletetest
, 0},
4628 {"W2K", run_w2ktest
, 0},
4629 {"VU", run_vusertest
, FLAG_MULTIUSER
| FLAG_MULTISHARE
},
4634 /****************************************************************************
4635 run a specified test or "ALL"
4636 ****************************************************************************/
4638 static BOOL
get_test_flags(char *name
, BOOL
*flags
) {
4642 BOOL all
= strequal(name
,"ALL") == 0;
4644 for (i
=0;torture_ops
[i
].name
;i
++) {
4646 if (all
|| strequal(name
, torture_ops
[i
].name
)) {
4648 *flags
|= torture_ops
[i
].flags
;
4660 static BOOL
run_test(char *name
)
4666 if (strequal(name
,"ALL")) {
4667 for (i
=0;torture_ops
[i
].name
;i
++) {
4668 run_test(torture_ops
[i
].name
);
4672 for (i
=0;torture_ops
[i
].name
;i
++) {
4673 snprintf(randomfname
, sizeof(randomfname
), "\\XX%x",
4674 (unsigned)random());
4676 if (strequal(name
, torture_ops
[i
].name
)) {
4677 printf("Running %s\n", name
);
4678 if (torture_ops
[i
].flags
& FLAG_MULTIPROC
) {
4679 t
= create_procs(torture_ops
[i
].fn
, &result
);
4682 printf("TEST %s FAILED!\n", name
);
4687 if (!torture_ops
[i
].fn(0)) {
4689 printf("TEST %s FAILED!\n", name
);
4693 printf("%s took %g secs\n\n", name
, t
);
4700 static void usage(void)
4704 printf("Usage: smbtorture //server/share[,share...] <options> TEST1 TEST2 ...\n");
4706 printf("\t-d debuglevel\n");
4707 printf("\t-U user%%pass\n");
4708 printf("\t-u user%%pass[,user%%pass...]\n");
4709 printf("\t-N numprocs\n");
4710 printf("\t-n my_netbios_name\n");
4711 printf("\t-W workgroup\n");
4712 printf("\t-o num_operations\n");
4713 printf("\t-O socket_options\n");
4714 printf("\t-m maximum protocol\n");
4715 printf("\t-L use oplocks\n");
4718 printf("tests are:");
4719 for (i
=0;torture_ops
[i
].name
;i
++) {
4720 printf(" %s", torture_ops
[i
].name
);
4724 printf("default test is ALL\n");
4729 static BOOL
split_password_from_username(char *username
, char *password
) {
4731 char * pp
= strchr(username
,'%');
4734 pstrcpy(password
, pp
+1);
4741 static BOOL
extract_users(char *user_list
) {
4743 const char *separators
= ",";
4745 char *p
= strtok(user_list
, separators
);
4747 while(p
&& nusers
< MAX_USERS
) {
4749 vusers
[nusers
].username
[0] = '\0';
4750 vusers
[nusers
].password
[0] = '\0';
4751 vusers
[nusers
].gotpass
= False
;
4753 pstrcpy(vusers
[nusers
].username
, p
);
4755 vusers
[nusers
].gotpass
= split_password_from_username(vusers
[nusers
].username
, vusers
[nusers
].password
);
4759 p
= strtok(NULL
, separators
);
4765 static BOOL
extract_shares(char *share_list
) {
4767 const char *separators
= ",";
4769 char *p
= strtok(share_list
, separators
);
4771 while(p
&& nshares
< MAX_TIDS
) {
4773 pstrcpy(shares
[nshares
], p
);
4777 p
= strtok(NULL
, separators
);
4783 /****************************************************************************
4785 ****************************************************************************/
4787 int main(int argc
,char *argv
[])
4792 BOOL
*gotpass
= &vusers
[0].gotpass
;
4793 extern char *optarg
;
4796 static pstring servicesf
= CONFIGFILE
;
4797 BOOL correct
= True
;
4803 #ifdef HAVE_SETBUFFER
4804 setbuffer(stdout
, NULL
, 0);
4806 charset_initialise();
4808 codepage_initialise(lp_client_code_page());
4810 codepage_initialise(lp_client_code_page());
4812 lp_load(servicesf
,True
,False
,False
);
4819 for(p
= argv
[1]; *p
; p
++)
4823 if (strncmp(argv
[1], "//", 2)) {
4827 fstrcpy(host
, &argv
[1][2]);
4828 p
= strchr(&host
[2],'/');
4834 fstrcpy(share_list
, p
+1);
4838 if (*username
== 0 && getenv("LOGNAME")) {
4840 pstrcpy(username
,getenv("LOGNAME"));
4846 fstrcpy(workgroup
, lp_workgroup());
4848 while ((opt
= getopt(argc
, argv
, "hW:U:u:n:N:O:o:m:Ld:")) != EOF
) {
4851 fstrcpy(workgroup
,optarg
);
4854 max_protocol
= interpret_protocol(optarg
, max_protocol
);
4857 nprocs
= atoi(optarg
);
4860 numops
= atoi(optarg
);
4863 DEBUGLEVEL
= atoi(optarg
);
4872 fstrcpy(myname
, optarg
);
4875 pstrcpy(username
,optarg
);
4876 *gotpass
= split_password_from_username(username
, password
);
4879 pstrcpy(user_list
, optarg
);
4880 if(!extract_users(user_list
)) {
4885 printf("Unknown option %c (%d)\n", (char)opt
, opt
);
4891 get_test_flags("ALL", &test_flags
);
4893 for (i
=1;i
<argc
;i
++) {
4895 get_test_flags(argv
[i
], &test_flags
);
4901 snprintf(s
, sizeof(s
), "Password for user %s:", username
);
4904 pstrcpy(password
, p
);
4909 extract_shares(share_list
);
4911 if(test_flags
& FLAG_MULTIUSER
) {
4915 /*generate another user from the one that is already specified*/
4917 vusers
[nusers
] = vusers
[nusers
-1];
4922 for(i
= 1; i
< nusers
; i
++) {
4926 if(vusers
[i
].gotpass
) {
4931 snprintf(s
, sizeof(s
), "Password for user %s:", vusers
[i
].username
);
4936 pstrcpy(vusers
[i
].password
, p
);
4937 vusers
[i
].gotpass
= True
;
4942 user_list
[0] = '\0';
4944 for(i
= 0; i
< nusers
; i
++) {
4946 if(!vusers
[i
].gotpass
) {
4953 fstrcat(user_list
, ", ");
4956 fstrcat(user_list
, vusers
[i
].username
);
4959 printf("host=%s shares=%s users=%s myname=%s\n", host
, share_list
, user_list
, myname
);
4962 correct
= run_test("ALL");
4964 for (i
=1;i
<argc
;i
++) {
4965 if (!run_test(argv
[i
])) {